diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000000000000000000000000000000000000..8255437e27dbb028763a02b953b2ed35d0e2a847 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,3 @@ +[build] +target = "aarch64-tx2.json" +rustflags = ["-C", "llvm-args=-global-isel=false"] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e12c3a506d43c118e59d078c93ceb60b07839c95 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +run* +/.vscode +upload_release +upload +upload_update +.idea +build/ diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000000000000000000000000000000000000..c68b04da5d6f368b31038c790a3162ab16727787 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,3 @@ +max_width = 120 +attr_fn_like_width = 70 +reorder_imports = false diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..3ced8b6a53b3a5b948b66c97cc32df704110e8ce --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "rust_shyper" +version = "0.1.0" +authors = [ + "Siran Li ", + "Ce Mo ", + "Keyang Hu ", + "Bo Jiang ", + "Lei Wang ", +] +edition = "2021" +description = "A Reliable Embedded Hypervisor Supporting VM Migration and Hypervisor Live-Update" +build = "build.rs" +license = "MulanPSL-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[profile.dev] +panic = "abort" + +[profile.release] +lto = true +panic = "abort" +debug = true + +[dependencies] +vm-fdt = { git = "https://github.com/OhmR/vm-fdt" } +#nostd_async = "0.6.0" +#woke = "0.0.2" +fdt = { path = "libfdt-binding" } +log = { version = "0.4", features = [ + "max_level_trace", + "release_max_level_info", +] } +#volatile = "0.4.4" +spin = { version = "0.9.4", features = ["use_ticket_mutex"] } +cortex-a = "7.4.0" +buddy_system_allocator = "0.8.0" + +[dependencies.tock-registers] +version = "0.7.0" +default-features = false +features = ["register_types"] + +[features] +tx2 = [] +qemu = [] +pi4 = [] +update = [] +ramdisk = [] +static-config = [] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..9e32cdef1625daed25cf365c865f01050877cff3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,127 @@ + 木兰宽松许可证, 第2版 + + 木兰宽松许可证, 第2版 + 2020年1月 http://license.coscl.org.cn/MulanPSL2 + + + 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: + + 0. 定义 + + “软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 + + “贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 + + “贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 + + “法人实体”是指提交贡献的机构及其“关联实体”。 + + “关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 + + 1. 授予版权许可 + + 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 + + 2. 授予专利许可 + + 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 + + 3. 无商标许可 + + “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 + + 4. 分发限制 + + 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 + + 5. 免责声明与责任限制 + + “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 + + 6. 语言 + “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 + + 条款结束 + + 如何将木兰宽松许可证,第2版,应用到您的软件 + + 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: + + 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; + + 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; + + 3, 请将如下声明文本放入每个源文件的头部注释中。 + + Copyright (c) [Year] [name of copyright holder] + [Software Name] is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + + + Mulan Permissive Software License,Version 2 + + Mulan Permissive Software License,Version 2 (Mulan PSL v2) + January 2020 http://license.coscl.org.cn/MulanPSL2 + + Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: + + 0. Definition + + Software means the program and related documents which are licensed under this License and comprise all Contribution(s). + + Contribution means the copyrightable work licensed by a particular Contributor under this License. + + Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. + + Legal Entity means the entity making a Contribution and all its Affiliates. + + Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. + + 1. Grant of Copyright License + + Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. + + 2. Grant of Patent License + + Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. + + 3. No Trademark License + + No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. + + 4. Distribution Restriction + + You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. + + 5. Disclaimer of Warranty and Limitation of Liability + + THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 6. Language + + THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. + + END OF THE TERMS AND CONDITIONS + + How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software + + To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: + + i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; + + ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package; + + iii Attach the statement to the appropriate annotated syntax at the beginning of each source file. + + + Copyright (c) [Year] [name of copyright holder] + [Software Name] is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..896afdf894a4f535d0303b036b3cac52e0615982 --- /dev/null +++ b/Makefile @@ -0,0 +1,97 @@ +# Path +DISK = /home/ohmr/work/hypervisor/disk-img/disk.img + +# Compile +ARCH ?= aarch64 +BUILD_STD = core,alloc + +# Toolchain +TOOLCHAIN=aarch64-linux-gnu +QEMU = /usr/share/qemu/bin/qemu-system-aarch64 +GDB = ${TOOLCHAIN}-gdb +OBJDUMP = ${TOOLCHAIN}-objdump + +IMAGE=rust_shyper + +qemu_debug: + cargo build -Z build-std=${BUILD_STD} --target aarch64-qemu.json --features qemu + ${OBJDUMP} --demangle -d target/aarch64-qemu/debug/${IMAGE} > target/aarch64-qemu/debug/t.txt + +qemu_release: + cargo build -Z build-std=${BUILD_STD} --target aarch64-qemu.json --features qemu --release + ${OBJDUMP} --demangle -d target/aarch64-qemu/release/${IMAGE} > target/aarch64-qemu/release/t.txt + +tx2: + cargo build -Z build-std=${BUILD_STD} --target aarch64-tx2.json --features tx2 + bash upload + ${OBJDUMP} --demangle -d target/aarch64-tx2/debug/${IMAGE} > target/aarch64-tx2/debug/t.txt + +tx2_release: + cargo build -Z build-std=${BUILD_STD} --target aarch64-tx2.json --features tx2 --release + bash upload_release + ${OBJDUMP} --demangle -d target/aarch64-tx2/release/${IMAGE} > target/aarch64-tx2/release/t.txt + +tx2_ramdisk: + cargo build -Z build-std=${BUILD_STD} --target aarch64-tx2.json --features "tx2 ramdisk" --release + bash upload_release + ${OBJDUMP} --demangle -d target/aarch64-tx2/release/${IMAGE} > target/aarch64-tx2/release/t.txt + +tx2_update: + cargo build -Z build-std=${BUILD_STD} --target aarch64-tx2-update.json --features "tx2 update" --release + bash upload_update + ${OBJDUMP} --demangle -d target/aarch64-tx2-update/release/${IMAGE} > target/aarch64-tx2-update/release/update.txt + +pi4_release: + cargo build -Z build-std=${BUILD_STD} --target aarch64-pi4.json --features pi4 --release + bash pi4_upload_release + ${OBJDUMP} --demangle -d target/aarch64-pi4/release/${IMAGE} > target/aarch64-pi4/release/t.txt + +run: + ${QEMU} \ + -machine virt,virtualization=on,gic-version=2\ + -drive file=${DISK},if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \ + -m 8g \ + -cpu cortex-a57 \ + -smp 8 \ + -kernel target/aarch64/debug/${IMAGE} \ + -global virtio-mmio.force-legacy=false \ + -serial stdio \ + -serial tcp:127.0.0.1:12345 \ + -serial tcp:127.0.0.1:12346 \ + -display none + +run_release: + ${QEMU} \ + -machine virt,virtualization=on,gic-version=2\ + -drive file=${DISK},if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \ + -m 8g \ + -cpu cortex-a57 \ + -smp 8 \ + -kernel target/aarch64/release/${IMAGE} \ + -global virtio-mmio.force-legacy=false \ + -serial stdio \ + -serial tcp:127.0.0.1:12345 \ + -serial tcp:127.0.0.1:12346 \ + -display none + +debug: + ${QEMU} \ + -machine virt,virtualization=on,gic-version=2\ + -drive file=${DISK},if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \ + -m 8g \ + -cpu cortex-a57 \ + -smp 8 \ + -kernel target/aarch64/debug/${IMAGE} \ + -global virtio-mmio.force-legacy=false \ + -serial stdio \ + -serial tcp:127.0.0.1:12345 \ + -serial tcp:127.0.0.1:12346 \ + -display none \ + -s -S + + +gdb: + ${GDB} -x gdb/aarch64.gdb + +clean: + cargo clean diff --git a/README.ch.md b/README.ch.md new file mode 100644 index 0000000000000000000000000000000000000000..ad5e285130f3b32c7f5f38bef57faa141fa787b7 --- /dev/null +++ b/README.ch.md @@ -0,0 +1,213 @@ +# Rust-Shyper + +A Reliable Embedded Hypervisor Supporting VM Migration and Hypervisor Live-Update + +**[English Version *README* click here](./README.md)** + +## 介绍 + +**Rust-Shyper** 是一个使用高级语言Rust编写的面向嵌入式场景的Type-1型虚拟机监视器(Hypervisor)。其设计目标在于提高资源利用率的同时,同时保障虚拟机实时性、隔离性与可靠性的需求。为达成上述目的,首先Rust-Shyper选用Rust作为编程语言,利用语言本身的安全特性提升代码质量,从语言层面保障系统软件的可靠性。其次,为了保障虚拟机的隔离性需求,Rust-Shyper针对CPU、中断、设备、内存等公共资源实现了有效的隔离策略,保证了同一资源被不同虚拟机共享的同时,虚拟机无法越界访问不属于当前虚拟机的资源。另外,为了保障虚拟机实时性需求,Rust-Shyper实现了中断部分直通机制以及中介传递设备模型,有效缩减虚拟化对实时性能的影响。最后,为了进一步保障监视器可靠性,本文实现了虚拟机迁移(VM migration)以及监视器动态升级(Hypervisor Live-update)两种热更新机制修复虚拟机监视器可能存在的代码漏洞。 + +## 目前支持的硬件平台 + +下表是目前Rust-Shyper已经支持(或正在开发中)的硬件平台: + +**aarch64** +- [x] NVIDIA Jetson TX2 +- [x] Raspberry Pi 4 Model B +- [ ] QEMU (still work in progress) + +## 如何编译 + +只需要使用`make`工具即可 + +```bash +make +``` + +例如, `make tx2_release` 是编译包含优化Rust-Shyper的TX2版本。具体可查看Makefile文件。 + +主要注意的是,请在编译前,根据需求编辑管理虚拟机(MVM)的配置文件。该文件的路径是 src/config/\_def.rs. + +**MVM的需求** + +MVM 是一个可以通过Hypervisor提供的私有特权接口来监控其他虚拟机状态的特权虚拟机,通常情况是一个Linux。我们为MVM实现了一个单独的Linux内核模块。通过改内核模块,MVM可以发起Hypercall来实现诸如虚拟机配置、虚拟机迁移、Hypervisor动态升级等功能。 + +通常情况下,MVM仅允许存在一个,且MVM会独占0号核心。 + +该内核模块在如下系统作为MVM时,经测试可以正常运行:Rpi Linux5.4.Y (for Raspberry Pi 4 Model B) 和 NVIDIA L4T 32.6.1 (for Jestion TX2). + +## 如何启动客户虚拟机(Guest VM) + +由boot-loader(如u-boot等)加载并启动Rust-Shyper镜像。Rust-Shyper完成初始化后,会自动启动MVM。 + +登录到MVM中,按照如下步骤,就可以配置并启动客户虚拟机了。 + +**Step 1**: 安装内核模块 + +```bash +insmod tools/shyper.ko +``` + +**Step 2**: 启动shyper-cli守护进程 + +注:shyper-cli是Rust-Shyper配套的一个简单的命令行工具,以二进制的形式提供在tools目录下,其编译的目标平台为aarch64。 + +```bash +# mediated-cfg.json is optional +sudo tools/shyper system daemon [mediated-cfg.json] & +``` + +**Step 3**: 通过配置文件来配置一个客户虚拟机 + +```bash +sudo tools/shyper vm config +``` + +**客户虚拟机配置文件的模板**如下: + +``` +{ + "name": "guest-os-1", + "type": "VM_T_LINUX", + "cmdline": "earlycon console=hvc0,115200n8 root=/dev/vda rw audit=0", + "image": { + "kernel_filename": "", + "kernel_load_ipa": "0x80080000", + "kernel_entry_point": "0x80080000", + "device_tree_filename": "-", + "device_tree_load_ipa": "0x80000000", + "ramdisk_filename": "initrd.gz", + "ramdisk_load_ipa": "0" + }, + "memory": { + "region": [ + { + "ipa_start": "0x80000000", + "length": "0x40000000" + } + ] + }, + "cpu": { + "num": 1, + "allocate_bitmap": "0b0100", + "master": 2 + }, + "emulated_device": { + "emulated_device_list": [ + { + "name": "intc@8000000", + "base_ipa": "0x8000000", + "length": "0x1000", + "irq_id": 0, + "type": "EMU_DEVICE_T_GICD" + }, + { + "name": "virtio_blk@a000000", + "base_ipa": "0xa000000", + "length": "0x1000", + "irq_id": 48, + "cfg_num": 2, + "cfg_list": [ + 0, + 209715200 + ], + "type": "EMU_DEVICE_T_VIRTIO_BLK_MEDIATED" + }, + { + "name": "virtio_net@a001000", + "base_ipa": "0xa001000", + "length": "0x1000", + "irq_id": 49, + "cfg_num": 6, + "cfg_list": [ + "0x74", + "0x56", + "0xaa", + "0x0f", + "0x47", + "0xd1" + ], + "type": "EMU_DEVICE_T_VIRTIO_NET" + }, + { + "name": "virtio_console@a002000", + "base_ipa": "0xa002000", + "length": "0x1000", + "irq_id": 50, + "cfg_num": 2, + "cfg_list": [ + "0", + "0xa002000" + ], + "type": "EMU_DEVICE_T_VIRTIO_CONSOLE" + } + ] + }, + "passthrough_device": { + "passthrough_device_list": [ + { + "name": "gicv", + "base_pa": "0x3886000", + "base_ipa": "0x8010000", + "length": "0x2000", + "irq_num": 1, + "irq_list": [ + 27 + ] + } + ] + }, + "dtb_device": { + "dtb_device_list": [ + { + "name": "gicd", + "type": "DTB_DEVICE_T_GICD", + "irq_num": 0, + "irq_list": [], + "addr_region_ipa": "0x8000000", + "addr_region_length": "0x1000" + }, + { + "name": "gicc", + "type": "DTB_DEVICE_T_GICC", + "irq_num": 0, + "irq_list": [], + "addr_region_ipa": "0x8010000", + "addr_region_length": "0x2000" + } + ] + } +} +``` + +**Step 4**: 启动客户虚拟机 + +```bash +sudo tools/shyper vm boot +``` + +然后就可以和客户虚拟机进行交互了 + +## 参考文献 + +1. Li, Siran, et al. "VM Migration and Live-Update for Reliable Embedded Hypervisor." Dependable Software Engineering. Theories, Tools, and Applications: 8th International Symposium, SETTA 2022, Beijing, China, October 27-29, 2022, Proceedings. Cham: Springer Nature Switzerland, 2022. + + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 +5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index aee5682071296e74907f904c9ed50f6f151b3d0e..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# rust_shyper - -#### Description -Rust-Shyper is an embedded type-1 hypervisor built with Rust, which has both high performance and high reliability. We have proposed low overhead VM migration and hypervisor live-update mechanisms to enable Rust-Shyper to tolerate hardware faults at runtime and dynamically fix hypervisor bugs. - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 9d4fed133f2d34519540c96e2dac1cef5a2c438c..6a54de668332fe2ce5527fc1a44edcb2e40a8929 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,208 @@ -# rust_shyper +# Rust-Shyper -#### 介绍 -Rust-Shyper is an embedded type-1 hypervisor built with Rust, which has both high performance and high reliability. We have proposed low overhead VM migration and hypervisor live-update mechanisms to enable Rust-Shyper to tolerate hardware faults at runtime and dynamically fix hypervisor bugs. +A Reliable Embedded Hypervisor Supporting VM Migration and Hypervisor Live-Update -#### 软件架构 -软件架构说明 +**中文版说明[*README*](./README.ch.md)** +## Introduction -#### 安装教程 +**Rust-Shyper** is an embedded type-1 hypervisor built with Rust, which has both high performance and high reliability. We have proposed low overhead VM migration and hypervisor live-update mechanisms to enable Rust-Shyper to tolerate hardware faults at runtime and dynamically fix hypervisor bugs. -1. xxxx -2. xxxx -3. xxxx +Rust-Shyper can offer strong isolation between VMs and provides differentiated services for mixed-criticality systems. Rust-Shyper offers differentiated services for different VMs. Memory is statically assigned using 2-stage translation; virtual interrupts are managed by hypervisor through GIC; for device models, emulated devices, virtio devices and pass-through devices are offered; and it implements vCPU scheduling for shared physical CPU cores. For real-time virtualization, we apply GIC partial pass-though (GPPT) to minimize interrupt latency in virtualized environments. For critical VMs, physical CPUs are assigned to vCPU 1-1 to guarantee the real-time performance. -#### 使用说明 +## Supported Platforms -1. xxxx -2. xxxx -3. xxxx +The list of supported (and work in progress) platforms is presented below: -#### 参与贡献 +**aarch64** +- [x] NVIDIA Jetson TX2 +- [x] Raspberry Pi 4 Model B +- [ ] QEMU (still work in progress) -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +## How to Build +Simply run `make` -#### 特技 +```bash +make +``` -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +For example, `make tx2_release` is to build Rust-Shyper for TX2 with opimization. + +Note that please edit the MVM profile in src/config/\_def.rs according to your requirements. + +**MVM Requirements** + +MVM is a privileged VM that can monitor the status of other VMs through privileged interfaces provided by the hypervisor. We implement a dedicated Linux kernel module for MVM. Through this module, MVM can make a hypercall to realize specific functions, such as VM configuration, VM migration and hypervisor live-update. Generally, there is only one MVM, and it will monopolize core 0. + +The kernel module on Rpi Linux5.4.Y (for Raspberry Pi 4 Model B) and NVIDIA L4T 32.6.1 (for Jestion TX2) as MVM has been tested. + +## How to Run Guest VM + +When starting Rust-Shyper, the MVM will boot automatically. Logging on to the MVM (a Linux priviledged VM), then can we configure and start the Guest VMs. + +**Step 1**: Install the kernel module + +```bash +insmod tools/shyper.ko +``` + +**Step 2**: Start the shyper-cli daemon + +```bash +# mediated-cfg.json is optional +sudo tools/shyper system daemon [mediated-cfg.json] & +``` + +**Step 3**: Configure a VM through profile + +```bash +sudo tools/shyper vm config +``` + +**Guest VM Configuration Profile Template** is as follow: + +``` +{ + "name": "guest-os-1", + "type": "VM_T_LINUX", + "cmdline": "earlycon console=hvc0,115200n8 root=/dev/vda rw audit=0", + "image": { + "kernel_filename": "", + "kernel_load_ipa": "0x80080000", + "kernel_entry_point": "0x80080000", + "device_tree_filename": "-", + "device_tree_load_ipa": "0x80000000", + "ramdisk_filename": "initrd.gz", + "ramdisk_load_ipa": "0" + }, + "memory": { + "region": [ + { + "ipa_start": "0x80000000", + "length": "0x40000000" + } + ] + }, + "cpu": { + "num": 1, + "allocate_bitmap": "0b0100", + "master": 2 + }, + "emulated_device": { + "emulated_device_list": [ + { + "name": "intc@8000000", + "base_ipa": "0x8000000", + "length": "0x1000", + "irq_id": 0, + "type": "EMU_DEVICE_T_GICD" + }, + { + "name": "virtio_blk@a000000", + "base_ipa": "0xa000000", + "length": "0x1000", + "irq_id": 48, + "cfg_num": 2, + "cfg_list": [ + 0, + 209715200 + ], + "type": "EMU_DEVICE_T_VIRTIO_BLK_MEDIATED" + }, + { + "name": "virtio_net@a001000", + "base_ipa": "0xa001000", + "length": "0x1000", + "irq_id": 49, + "cfg_num": 6, + "cfg_list": [ + "0x74", + "0x56", + "0xaa", + "0x0f", + "0x47", + "0xd1" + ], + "type": "EMU_DEVICE_T_VIRTIO_NET" + }, + { + "name": "virtio_console@a002000", + "base_ipa": "0xa002000", + "length": "0x1000", + "irq_id": 50, + "cfg_num": 2, + "cfg_list": [ + "0", + "0xa002000" + ], + "type": "EMU_DEVICE_T_VIRTIO_CONSOLE" + } + ] + }, + "passthrough_device": { + "passthrough_device_list": [ + { + "name": "gicv", + "base_pa": "0x3886000", + "base_ipa": "0x8010000", + "length": "0x2000", + "irq_num": 1, + "irq_list": [ + 27 + ] + } + ] + }, + "dtb_device": { + "dtb_device_list": [ + { + "name": "gicd", + "type": "DTB_DEVICE_T_GICD", + "irq_num": 0, + "irq_list": [], + "addr_region_ipa": "0x8000000", + "addr_region_length": "0x1000" + }, + { + "name": "gicc", + "type": "DTB_DEVICE_T_GICC", + "irq_num": 0, + "irq_list": [], + "addr_region_ipa": "0x8010000", + "addr_region_length": "0x2000" + } + ] + } +} +``` + +**Step 4**: Boot the Guest VM + +```bash +sudo tools/shyper vm boot +``` + +then you can interact with the guest VM. + +## References + +1. Li, Siran, et al. "VM Migration and Live-Update for Reliable Embedded Hypervisor." Dependable Software Engineering. Theories, Tools, and Applications: 8th International Symposium, SETTA 2022, Beijing, China, October 27-29, 2022, Proceedings. Cham: Springer Nature Switzerland, 2022. + + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/aarch64-pi4.json b/aarch64-pi4.json new file mode 100644 index 0000000000000000000000000000000000000000..85aebdf0860f77bb66364065be97c85a1b4d5fd7 --- /dev/null +++ b/aarch64-pi4.json @@ -0,0 +1,25 @@ +{ + "arch": "aarch64", + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "disable-redzone": true, + "executables": true, + "features": "+v8a,+strict-align,-neon,-fp-armv8", + "is-builtin": false, + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "linker-is-gnu": true, + "pre-link-args": { + "ld.lld": [ + "-Tsrc/linkers/aarch64-pi4.ld" + ] + }, + "llvm-target": "aarch64-unknown-none", + "max-atomic-width": 128, + "os": "none", + "panic-strategy": "abort", + "relocation-model": "static", + "code-model": "large", + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64" +} \ No newline at end of file diff --git a/aarch64-qemu.json b/aarch64-qemu.json new file mode 100644 index 0000000000000000000000000000000000000000..cb1fff6bc0a0161d51fcca774bca288dd03c6279 --- /dev/null +++ b/aarch64-qemu.json @@ -0,0 +1,35 @@ +{ + "abi-blacklist": [ + "stdcall", + "fastcall", + "vectorcall", + "thiscall", + "win64", + "sysv64" + ], + "arch": "aarch64", + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "disable-redzone": true, + "env": "", + "executables": true, + "features": "+v8a,+strict-align,-neon,-fp-armv8", + "is-builtin": false, + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "linker-is-gnu": true, + "pre-link-args": { + "ld.lld": [ + "-Tsrc/linkers/aarch64-qemu.ld" + ] + }, + "llvm-target": "aarch64-unknown-none", + "max-atomic-width": 128, + "os": "none", + "panic-strategy": "abort", + "relocation-model": "static", + "code-model": "large", + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64", + "vendor": "" +} \ No newline at end of file diff --git a/aarch64-tx2-update.json b/aarch64-tx2-update.json new file mode 100644 index 0000000000000000000000000000000000000000..a12ee6ba2f54f11b22ffa5c078334afbece9b219 --- /dev/null +++ b/aarch64-tx2-update.json @@ -0,0 +1,25 @@ +{ + "arch": "aarch64", + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "disable-redzone": true, + "executables": true, + "features": "+v8a,+strict-align,-neon,-fp-armv8", + "is-builtin": false, + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "linker-is-gnu": true, + "pre-link-args": { + "ld.lld": [ + "-Tsrc/linkers/aarch64-tx2-update.ld" + ] + }, + "llvm-target": "aarch64-unknown-none", + "max-atomic-width": 128, + "os": "none", + "panic-strategy": "abort", + "relocation-model": "static", + "code-model": "large", + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64" +} \ No newline at end of file diff --git a/aarch64-tx2.json b/aarch64-tx2.json new file mode 100644 index 0000000000000000000000000000000000000000..b05790a7a15a5602a3d0e9a6d7dbb0460e3176a7 --- /dev/null +++ b/aarch64-tx2.json @@ -0,0 +1,26 @@ +{ + "arch": "aarch64", + "cpu": "cortex-a57", + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "disable-redzone": true, + "executables": true, + "features": "+v8a,+strict-align,-neon,-fp-armv8", + "is-builtin": false, + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "linker-is-gnu": true, + "pre-link-args": { + "ld.lld": [ + "-Tsrc/linkers/aarch64-tx2.ld" + ] + }, + "llvm-target": "aarch64-unknown-none", + "max-atomic-width": 128, + "os": "none", + "panic-strategy": "abort", + "relocation-model": "static", + "code-model": "large", + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64" +} \ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..788a65507057a9e42e3c8e82cdce110381b4761e --- /dev/null +++ b/build.rs @@ -0,0 +1,21 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use std::env::var; +use std::process::Command; + +fn main() { + println!("cargo:rustc-link-search=native={}/lib", var("PWD").unwrap()); + println!("cargo:rustc-link-lib=static=fdt-binding"); + // note: add error checking yourself. + let output = Command::new("date").arg("+\"%Y-%m-%d %H:%M:%S %Z\"").output().unwrap(); + let build_time = String::from_utf8(output.stdout).unwrap(); + println!("cargo:rustc-env=BUILD_TIME={}", build_time); +} diff --git a/dts/c_car.dts b/dts/c_car.dts new file mode 100644 index 0000000000000000000000000000000000000000..0dc784a4078e9ccb061ab28c22a2f7717c472da7 --- /dev/null +++ b/dts/c_car.dts @@ -0,0 +1,17680 @@ +/dts-v1/; + +/ { + nvidia,fastboot-usb-pid = <0xee16>; + compatible = "nvidia,quill", "nvidia,p2597-0000+p3310-1000", "nvidia,tegra186"; + nvidia,proc-boardid = "3310:0000:A0"; + nvidia,fastboot-usb-vid = <0x955>; + serial-number = "1421920042248"; + nvidia,dtbbuildtime = "Apr 8 2021", "15:27:51"; + model = "quill"; + nvidia,dtsfilename = "arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dts"; + interrupt-parent = <0x1>; + #address-cells = <0x2>; + #size-cells = <0x2>; + nvidia,boardids = "3310:0000:A0"; + + mttcan1-ivc { + compatible = "bosch,mttcan-ivc"; + status = "disabled"; + mboxes = <0x41 0x4>; + }; + + watchdog@30c0000 { + nvidia,shutdown-timeout = <0x96>; + compatible = "nvidia,tegra-wdt-t18x"; + nvidia,watchdog-index = <0x0>; + nvidia,expiry-count = <0x5>; + nvidia,disable-debug-reset; + nvidia,extend-watchdog-suspend; + status = "okay"; + interrupts = <0x0 0x7 0x4 0x0 0x8 0x4>; + nvidia,timer-index = <0x7>; + phandle = <0xfd>; + reg = <0x0 0x30c0000 0x0 0x10000 0x0 0x3020000 0x0 0x10000 0x0 0x3010000 0x0 0x10000>; + linux,phandle = <0xfd>; + nvidia,enable-on-init; + timeout-sec = <0x78>; + }; + + cpuidle { + compatible = "nvidia,tegra18x-cpuidle"; + status = "okay"; + }; + + ether_qos_virt_test@2490000 { + compatible = "synopsys,dwc_eqos_virt_test"; + status = "disabled"; + reg = <0x0 0x2490000 0x0 0x10000 0x0 0x24a0000 0x0 0x10000>; + }; + + i2c@3190000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x56 0x10 0x10d 0x10 0xdd>; + resets = <0x10 0x16>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1c 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x92>; + reg = <0x0 0x3190000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x186a0>; + dmas = <0x25 0x1a 0x25 0x1a>; + reset-names = "i2c"; + linux,phandle = <0x92>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + aconnect@2a41000 { + power-domains = <0x1f 0x0>; + compatible = "nvidia,tegra210-aconnect"; + clocks = <0x10 0x69 0x10 0x68>; + clock-names = "ape", "apb2ape"; + ranges; + status = "okay"; + #address-cells = <0x2>; + #size-cells = <0x2>; + + ahub { + assigned-clock-parents = <0x10 0x10d>; + compatible = "nvidia,tegra186-axbar"; + wakeup-disable; + clocks = <0x10 0x57 0x10 0xf6 0x10 0x68 0x10 0x69>; + clock-names = "ahub", "parent", "apb2ape", "xbar.ape"; + ranges; + status = "okay"; + #address-cells = <0x2>; + assigned-clock-rates = <0x2b3bb55>; + #size-cells = <0x2>; + assigned-clocks = <0x10 0x57>; + phandle = <0xb8>; + reg = <0x0 0x2900800 0x0 0x800>; + linux,phandle = <0xb8>; + + adx@2903a00 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x2>; + status = "okay"; + phandle = <0x1ad>; + reg = <0x0 0x2903a00 0x0 0x100>; + linux,phandle = <0x1ad>; + }; + + dspk@2905100 { + nvidia,ahub-dspk-id = <0x1>; + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra186-dspk"; + clocks = <0x10 0x99 0x10 0xf6 0x10 0xfe>; + clock-names = "dspk", "pll_a_out0", "sync_dspk"; + status = "okay"; + assigned-clock-rates = <0xbb8000>; + assigned-clocks = <0x10 0x99>; + phandle = <0xcf>; + reg = <0x0 0x2905100 0x0 0x100 0x0 0x2431000 0x0 0x1f0>; + linux,phandle = <0xcf>; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x8 0xfff 0x441 0x1 0x0 0xfff 0x441>; + }; + }; + }; + + mvc@290a200 { + compatible = "nvidia,tegra210-mvc"; + nvidia,ahub-mvc-id = <0x1>; + status = "okay"; + phandle = <0x1b6>; + reg = <0x0 0x290a200 0x0 0x200>; + linux,phandle = <0x1b6>; + }; + + afc@2907100 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x1>; + status = "okay"; + phandle = <0x1b0>; + reg = <0x0 0x2907100 0x0 0x100>; + linux,phandle = <0x1b0>; + }; + + i2s@2901200 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x2b 0x10 0xf6 0x10 0x26b 0x10 0xf9 0x10 0x26b>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x2b>; + phandle = <0xbd>; + nvidia,ahub-i2s-id = <0x2>; + reg = <0x0 0x2901200 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xbd>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + adx@2903800 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x0>; + status = "okay"; + phandle = <0x1ab>; + reg = <0x0 0x2903800 0x0 0x100>; + linux,phandle = <0x1ab>; + }; + + dmic@2904000 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x7a 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x0>; + assigned-clocks = <0x10 0x7a>; + phandle = <0xc5>; + reg = <0x0 0x2904000 0x0 0x100>; + linux,phandle = <0xc5>; + }; + + afc@2907400 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x4>; + status = "okay"; + phandle = <0x1b3>; + reg = <0x0 0x2907400 0x0 0x100>; + linux,phandle = <0x1b3>; + }; + + i2s@2901500 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x9a 0x10 0xf6 0x10 0x26e 0x10 0xfc 0x10 0x26e>; + fsync-width = <0x0>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x9a>; + phandle = <0xc3>; + nvidia,ahub-i2s-id = <0x5>; + reg = <0x0 0x2901500 0x0 0x100>; + pinctrl-0; + bclk-ratio = <0x4>; + linux,phandle = <0xc3>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + sfc@2902200 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x1>; + phandle = <0x1a2>; + reg = <0x0 0x2902200 0x0 0x200>; + linux,phandle = <0x1a2>; + }; + + dmic@2904300 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x97 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x3>; + assigned-clocks = <0x10 0x97>; + phandle = <0xcb>; + reg = <0x0 0x2904300 0x0 0x100>; + linux,phandle = <0xcb>; + }; + + amixer@290bb00 { + nvidia,ahub-amixer-id = <0x0>; + compatible = "nvidia,tegra210-amixer"; + status = "okay"; + phandle = <0x1a6>; + reg = <0x0 0x290bb00 0x0 0x800>; + linux,phandle = <0x1a6>; + }; + + iqc@290e000 { + compatible = "nvidia,tegra210-iqc"; + clocks = <0x10 0x6a>; + clock-names = "iqc"; + status = "okay"; + phandle = <0x1b7>; + reg = <0x0 0x290e000 0x0 0x200>; + nvidia,ahub-iqc-id = <0x0>; + linux,phandle = <0x1b7>; + }; + + amx@2903000 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x0>; + status = "okay"; + phandle = <0x1a7>; + reg = <0x0 0x2903000 0x0 0x100>; + linux,phandle = <0x1a7>; + }; + + dspk@2905000 { + nvidia,ahub-dspk-id = <0x0>; + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra186-dspk"; + clocks = <0x10 0x98 0x10 0xf6 0x10 0xfd>; + clock-names = "dspk", "pll_a_out0", "sync_dspk"; + status = "okay"; + assigned-clock-rates = <0xbb8000>; + assigned-clocks = <0x10 0x98>; + phandle = <0xcd>; + reg = <0x0 0x2905000 0x0 0x100>; + linux,phandle = <0xcd>; + }; + + amx@2903300 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x3>; + status = "okay"; + phandle = <0x1aa>; + reg = <0x0 0x2903300 0x0 0x100>; + linux,phandle = <0x1aa>; + }; + + afc@2907000 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x0>; + status = "okay"; + phandle = <0x1af>; + reg = <0x0 0x2907000 0x0 0x100>; + linux,phandle = <0x1af>; + }; + + i2s@2901100 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x2a 0x10 0xf6 0x10 0x26a 0x10 0xf8 0x10 0x26a>; + fsync-width = <0x0>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x2a>; + phandle = <0xbb>; + nvidia,ahub-i2s-id = <0x1>; + reg = <0x0 0x2901100 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xbb>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + arad@290e400 { + compatible = "nvidia,tegra186-arad"; + status = "okay"; + nvidia,ahub-arad-id = <0x0>; + phandle = <0x1b9>; + reg = <0x0 0x290e400 0x0 0x400>; + linux,phandle = <0x1b9>; + }; + + afc@2907300 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x3>; + status = "okay"; + phandle = <0x1b2>; + reg = <0x0 0x2907300 0x0 0x100>; + linux,phandle = <0x1b2>; + }; + + i2s@2901400 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x55 0x10 0xf6 0x10 0x26d 0x10 0xfb 0x10 0x26d>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x55>; + phandle = <0xc1>; + nvidia,ahub-i2s-id = <0x4>; + reg = <0x0 0x2901400 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xc1>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + dmic@2904200 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x96 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x2>; + assigned-clocks = <0x10 0x96>; + phandle = <0xc9>; + reg = <0x0 0x2904200 0x0 0x100 0x0 0xc303000 0x0 0x1f0>; + linux,phandle = <0xc9>; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x28 0xffff 0x6441 0x1 0x30 0xffff 0x6441>; + }; + }; + }; + + spkprot@2908c00 { + compatible = "nvidia,tegra210-spkprot"; + nvidia,ahub-spkprot-id = <0x0>; + status = "okay"; + phandle = <0x1a5>; + reg = <0x0 0x2908c00 0x0 0x400>; + linux,phandle = <0x1a5>; + }; + + admaif@290f000 { + compatible = "nvidia,tegra186-admaif"; + clocks = <0x10 0x57>; + dma-buffer-size = <0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000>; + clock-names = "ahub"; + status = "okay"; + dma-names = "rx1", "tx1", "rx2", "tx2", "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", "rx9", "tx9", "rx10", "tx10", "rx11", "tx11", "rx12", "tx12", "rx13", "tx13", "rx14", "tx14", "rx15", "tx15", "rx16", "tx16", "rx17", "tx17", "rx18", "tx18", "rx19", "tx19", "rx20", "tx20"; + phandle = <0x1a0>; + reg = <0x0 0x290f000 0x0 0x1000>; + dmas = <0x5f 0x1 0x5f 0x1 0x5f 0x2 0x5f 0x2 0x5f 0x3 0x5f 0x3 0x5f 0x4 0x5f 0x4 0x5f 0x5 0x5f 0x5 0x5f 0x6 0x5f 0x6 0x5f 0x7 0x5f 0x7 0x5f 0x8 0x5f 0x8 0x5f 0x9 0x5f 0x9 0x5f 0xa 0x5f 0xa 0x5f 0xb 0x5f 0xb 0x5f 0xc 0x5f 0xc 0x5f 0xd 0x5f 0xd 0x5f 0xe 0x5f 0xe 0x5f 0xf 0x5f 0xf 0x5f 0x10 0x5f 0x10 0x5f 0x11 0x5f 0x11 0x5f 0x12 0x5f 0x12 0x5f 0x13 0x5f 0x13 0x5f 0x14 0x5f 0x14>; + linux,phandle = <0x1a0>; + }; + + sfc@2902400 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x2>; + phandle = <0x1a3>; + reg = <0x0 0x2902400 0x0 0x200>; + linux,phandle = <0x1a3>; + }; + + mvc@290a000 { + compatible = "nvidia,tegra210-mvc"; + nvidia,ahub-mvc-id = <0x0>; + status = "okay"; + phandle = <0x1b5>; + reg = <0x0 0x290a000 0x0 0x200>; + linux,phandle = <0x1b5>; + }; + + amx@2903200 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x2>; + status = "okay"; + phandle = <0x1a9>; + reg = <0x0 0x2903200 0x0 0x100>; + linux,phandle = <0x1a9>; + }; + + i2s@2901000 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x4f 0x10 0xf6 0x10 0x269 0x10 0xf7 0x10 0x269>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x4f>; + phandle = <0xb9>; + nvidia,ahub-i2s-id = <0x0>; + reg = <0x0 0x2901000 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xb9>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + adx@2903b00 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x3>; + status = "okay"; + phandle = <0x1ae>; + reg = <0x0 0x2903b00 0x0 0x100>; + linux,phandle = <0x1ae>; + }; + + afc@2907200 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x2>; + status = "okay"; + phandle = <0x1b1>; + reg = <0x0 0x2907200 0x0 0x100>; + linux,phandle = <0x1b1>; + }; + + i2s@2901300 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x54 0x10 0xf6 0x10 0x26c 0x10 0xfa 0x10 0x26c>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x54>; + phandle = <0xbf>; + nvidia,ahub-i2s-id = <0x3>; + reg = <0x0 0x2901300 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xbf>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + adx@2903900 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x1>; + status = "okay"; + phandle = <0x1ac>; + reg = <0x0 0x2903900 0x0 0x100>; + linux,phandle = <0x1ac>; + }; + + sfc@2902000 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x0>; + phandle = <0x1a1>; + reg = <0x0 0x2902000 0x0 0x200>; + linux,phandle = <0x1a1>; + }; + + dmic@2904100 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x7b 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x1>; + assigned-clocks = <0x10 0x7b>; + phandle = <0xc7>; + reg = <0x0 0x2904100 0x0 0x100>; + linux,phandle = <0xc7>; + }; + + ahc@290b900 { + compatible = "nvidia,tegra186-ahc"; + status = "okay"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x38 0x4 0x0>; + phandle = <0x1ba>; + reg = <0x0 0x290b900 0x0 0x200>; + linux,phandle = <0x1ba>; + }; + + afc@2907500 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x5>; + status = "okay"; + phandle = <0x1b4>; + reg = <0x0 0x2907500 0x0 0x100>; + linux,phandle = <0x1b4>; + }; + + asrc@2910000 { + compatible = "nvidia,tegra186-asrc"; + nvidia,ahub-asrc-id = <0x0>; + status = "okay"; + phandle = <0x1b8>; + reg = <0x0 0x2910000 0x0 0x2000>; + linux,phandle = <0x1b8>; + }; + + ope@2908000 { + compatible = "nvidia,tegra210-ope"; + status = "okay"; + phandle = <0x1bb>; + reg = <0x0 0x2908000 0x0 0x100 0x0 0x2908100 0x0 0x100 0x0 0x2908200 0x0 0x200>; + linux,phandle = <0x1bb>; + nvidia,ahub-ope-id = <0x0>; + + peq@2908100 { + status = "okay"; + }; + + mbdrc@2908200 { + status = "okay"; + }; + }; + + sfc@2902600 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x3>; + phandle = <0x1a4>; + reg = <0x0 0x2902600 0x0 0x200>; + linux,phandle = <0x1a4>; + }; + + amx@2903100 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x1>; + status = "okay"; + phandle = <0x1a8>; + reg = <0x0 0x2903100 0x0 0x100>; + linux,phandle = <0x1a8>; + }; + }; + + rtcpu@2993000 { + compatible = "nvidia,tegra186-ape-ivc"; + clocks = <0x10 0x69 0x10 0x68 0x10 0x8b 0x10 0x8a>; + resets = <0x10 0xbf>; + reg-names = "ape-evp", "ape-amisc", "ast-cpu"; + nvidia,autosuspend-delay-ms = <0x1388>; + clock-names = "ape", "apb2ape", "adspneon", "adsp"; + status = "disabled"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x3e 0x4 0x0 0x0 0x3f 0x4 0x0 0x0 0x54 0x4 0x0 0x0 0x1f 0x4 0x4 0x0 0x30 0x4 0x4 0x0 0x44 0x4 0x4 0x0 0x45 0x4 0x4 0x0 0x47 0x4 0x4 0x0 0x46 0x4 0x4 0x0 0x48 0x4 0x4 0x0 0x49 0x4 0x4 0x0 0x4a 0x4 0x4 0x0 0x4b 0x4 0x4 0x0 0x4e 0x4 0x4 0x0 0x4f 0x4 0x4 0x0 0x50 0x4 0x4 0x0 0x53 0x4 0x4 0x0 0x52 0x4 0x4>; + nvidia,trace = <0x5c 0x4 0x40200000 0x80000>; + nvidia,ivc-channels = <0x5d 0x2 0x40000000 0x10000>; + phandle = <0x19d>; + iommu-group-id = <0x3>; + reg = <0x0 0x2993000 0x0 0x1000 0x0 0x2990000 0x0 0x800 0x0 0x2994000 0x0 0x2000>; + iommus = <0x11 0x2d>; + reset-names = "adsp-all"; + linux,phandle = <0x19d>; + interrupt-names = "adsp-wfi", "adsp-wfe", "wdt-remote"; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + device = <0x5e>; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + nvidia,hsp-shared-mailbox = <0x5e 0x1 0x5e 0x6>; + }; + }; + + agic-controller@2a41000 { + compatible = "nvidia,tegra186-agic"; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "okay"; + #interrupt-cells = <0x4>; + interrupts = <0x0 0x91 0xf04>; + phandle = <0x5b>; + reg = <0x0 0x2a41000 0x0 0x1000 0x0 0x2a42000 0x0 0x2000>; + linux,phandle = <0x5b>; + interrupt-controller; + }; + + agic-controller@2a51000 { + compatible = "nvidia,tegra186-agic"; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "disabled"; + #interrupt-cells = <0x4>; + interrupts = <0x0 0x92 0xf04>; + phandle = <0x19e>; + reg = <0x0 0x2a51000 0x0 0x1000 0x0 0x2a52000 0x0 0x2000>; + linux,phandle = <0x19e>; + interrupt-controller; + }; + + tegra-hsp@29a0000 { + compatible = "nvidia,tegra186-hsp"; + status = "disabled"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x20 0x4 0x0 0x0 0x21 0x4 0x0 0x0 0x22 0x4 0x0 0x0 0x23 0x4 0x0 0x0 0x24 0x4 0x0 0x0 0x25 0x4 0x0 0x0 0x26 0x4 0x0 0x0 0x27 0x4 0x0 0x0 0x28 0x4 0x0 0x0 0x29 0x4 0x0 0x0 0x2a 0x4 0x0 0x0 0x2b 0x4 0x0 0x0 0x2c 0x4 0x0 0x0 0x2d 0x4 0x0 0x0 0x2e 0x4 0x0 0x0 0x2f 0x4 0x0 0x0 0x30 0x4 0x4 0x0 0x31 0x4 0x0 0x0 0x32 0x4 0x0 0x0 0x33 0x4 0x0 0x0 0x34 0x4 0x0>; + phandle = <0x5e>; + reg = <0x0 0x29a0000 0x0 0x90000>; + linux,phandle = <0x5e>; + interrupt-names = "full0", "full1", "full2", "full3", "full4", "full5", "full6", "full7", "empty0", "empty1", "empty2", "empty3", "empty4", "empty5", "empty6", "empty7", "adsp-shared0", "shared1", "shared2", "shared3", "shared4"; + }; + + adsp_audio { + nvidia,adma_ch_cnt = <0x10>; + compatible = "nvidia,tegra186-adsp-audio"; + wakeup-disable; + clocks = <0x10 0x57 0x10 0x69 0x10 0x68>; + num-plugin = <0x5>; + nvidia,adma_ch_start = <0x10>; + clock-names = "ahub", "ape", "apb2ape"; + compr-ops = <0x1>; + status = "okay"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x10 0x4 0x4 0x0 0x11 0x4 0x4 0x0 0x12 0x4 0x4 0x0 0x13 0x4 0x4 0x0 0x14 0x4 0x4 0x0 0x15 0x4 0x4 0x0 0x16 0x4 0x4 0x0 0x17 0x4 0x4 0x0 0x18 0x4 0x4 0x0 0x19 0x4 0x4 0x0 0x1a 0x4 0x4 0x0 0x1b 0x4 0x4 0x0 0x1c 0x4 0x4 0x0 0x1d 0x4 0x4 0x0 0x1e 0x4 0x4 0x0 0x1f 0x4 0x4>; + phandle = <0x1bc>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommus = <0x11 0x1e>; + linux,phandle = <0x1bc>; + + plugin-info-4 { + plugin-name = "aac-dec1"; + widget-name = "AAC-DEC1"; + firmware-name = "nvaacdec.elf"; + }; + + plugin-info-2 { + plugin-name = "spkprot"; + widget-name = "SPKPROT-SW"; + firmware-name = "nvspkprot.elf"; + }; + + plugin-info-5 { + plugin-name = "aec"; + widget-name = "AEC"; + firmware-name = "nvoice.elf"; + }; + + plugin-info-3 { + plugin-name = "src"; + widget-name = "SRC"; + firmware-name = "nvsrc.elf"; + }; + + plugin-info-1 { + plugin-name = "mp3-dec1"; + widget-name = "MP3-DEC1"; + firmware-name = "nvmp3dec.elf"; + }; + }; + + agic-controller@2a61000 { + compatible = "nvidia,tegra186-agic"; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "disabled"; + #interrupt-cells = <0x4>; + interrupts = <0x0 0x93 0xf04>; + phandle = <0x19f>; + reg = <0x0 0x2a61000 0x0 0x1000 0x0 0x2a62000 0x0 0x2000>; + linux,phandle = <0x19f>; + interrupt-controller; + }; + + adsp@2993000 { + compatible = "nvidia,tegra18x-adsp"; + clocks = <0x10 0x8b 0x10 0x8a 0x10 0x111>; + resets = <0x10 0xbf>; + dma-mask = <0x0 0x5e000000>; + clock-names = "adspneon", "adsp", "aclk"; + status = "okay"; + nvidia,adsp_mem = <0x5ef00000 0x1000000 0x5f700000 0x800000 0x3f813000 0x5000 0x5fd00000 0x200000>; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x29 0x4 0x0 0x0 0x20 0x4 0x0 0x0 0x53 0x4 0x0 0x0 0x3e 0x4 0x0 0x0 0x39 0x4 0x0 0x0 0x41 0x4 0x0 0x0 0x28 0x4 0x4 0x0 0x21 0x4 0x4 0x0 0x22 0x4 0x4 0x0 0x4e 0x4 0x4 0x0 0x4f 0x4 0x4 0x0 0x50 0x4 0x4 0x0 0x4b 0x4 0x4>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + reg = <0x0 0x2993000 0x0 0x1000 0x0 0x2990000 0x0 0x2000 0x0 0x0 0x0 0x1 0x0 0x290c800 0x0 0x1 0x0 0x29b0000 0x0 0x90000 0x0 0x40000000 0x0 0xc0000000 0x0 0x0 0x0 0x1>; + iommus = <0x11 0x1e>; + nvidia,adsp_unit_fpga_reset = <0x7f00040 0x40>; + reset-names = "adspall"; + nvidia,adsp_os_secload; + nvidia,adsp-evp-base = <0x2993700 0x40>; + }; + + adma@2930000 { + #dma-cells = <0x1>; + compatible = "nvidia,tegra186-adma"; + clocks = <0x10 0x57>; + clock-names = "d_audio"; + status = "okay"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x0 0x4 0x0 0x0 0x1 0x4 0x0 0x0 0x2 0x4 0x0 0x0 0x3 0x4 0x0 0x0 0x4 0x4 0x0 0x0 0x5 0x4 0x0 0x0 0x6 0x4 0x0 0x0 0x7 0x4 0x0 0x0 0x8 0x4 0x0 0x0 0x9 0x4 0x0 0x0 0xa 0x4 0x0 0x0 0xb 0x4 0x0 0x0 0xc 0x4 0x0 0x0 0xd 0x4 0x0 0x0 0xe 0x4 0x0 0x0 0xf 0x4 0x0 0x0 0x10 0x4 0x0 0x0 0x11 0x4 0x0 0x0 0x12 0x4 0x0 0x0 0x13 0x4 0x0 0x0 0x14 0x4 0x0 0x0 0x15 0x4 0x0 0x0 0x16 0x4 0x0 0x0 0x17 0x4 0x0 0x0 0x18 0x4 0x0 0x0 0x19 0x4 0x0 0x0 0x1a 0x4 0x0 0x0 0x1b 0x4 0x0 0x0 0x1c 0x4 0x0 0x0 0x1d 0x4 0x0 0x0 0x1e 0x4 0x0 0x0 0x1f 0x4 0x0>; + phandle = <0x5f>; + reg = <0x0 0x2930000 0x0 0x50000 0x0 0x29f0000 0x0 0x10>; + linux,phandle = <0x5f>; + }; + }; + + generic_pwm_tachometer { + compatible = "generic-pwm-tachometer"; + status = "okay"; + pwms = <0xb2 0x0 0xf4240>; + }; + + sdhci@3400000 { + nvidia,ddr-tap-delay = <0xb>; + nvidia,en-periodic-calib; + cap-mmc-highspeed; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x34 0x10 0x10d 0x10 0x80>; + cap-sd-highspeed; + nvidia,cd-wakeup-capable; + resets = <0x10 0x21>; + pinctrl-1 = <0x1a>; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + pll_source = "pll_p"; + cd-gpios = <0x1b 0x7d 0x0>; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "okay"; + nvidia,max-tap-delay = <0x88>; + interrupts = <0x0 0x3e 0x4>; + bus-width = <0x4>; + ddr-trim-delay = <0x5>; + phandle = <0x100>; + tap-delay = <0xb>; + reg = <0x0 0x3400000 0x0 0x210>; + iommus = <0x11 0x1a>; + pinctrl-0 = <0x19>; + mmc-ocr-mask = <0x3>; + compad-vref-1v8 = <0x2>; + trim-delay = <0x5>; + pwrdet-support; + reset-names = "sdhci"; + cd-inverted; + vmmc-supply = <0x1d>; + uhs-mask = <0x8>; + linux,phandle = <0x100>; + ignore-pm-notify; + wp-inverted; + compad-vref-3v3 = <0x1>; + vqmmc-supply = <0x1c>; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + max-clk-limit = <0xc28cb00>; + wp-gpios = <0x1b 0x7c 0x0>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000503>; + }; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr12 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr25 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + }; + }; + + mttcan@c310000 { + gpio_can_stb = <0x28 0x28 0x0>; + compatible = "nvidia,tegra186-mttcan"; + clocks = <0x10 0xd2 0x10 0xd3 0x10 0x214>; + resets = <0x10 0x3c>; + reg-names = "can-regs", "glue-regs", "msg-ram"; + clock-names = "can", "can_host", "pllaon"; + rx-config = <0x40 0x40 0x40>; + pll_source = "pllaon"; + mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>; + status = "okay"; + interrupts = <0x0 0x28 0x4>; + phandle = <0x1d6>; + reg = <0x0 0xc310000 0x0 0x400 0x0 0xc311000 0x0 0x32 0x0 0xc312000 0x0 0x1000>; + gpio_can_en = <0x28 0x29 0x0>; + reset-names = "can"; + linux,phandle = <0x1d6>; + tx-config = <0x0 0x10 0x0 0x40>; + }; + + aon_spi@c260000 { + compatible = "nvidia,tegra186-aon-spi"; + bus-number = <0x1>; + status = "disabled"; + #address-cells = <0x1>; + mboxes = <0x41 0x2>; + #size-cells = <0x0>; + phandle = <0x187>; + linux,phandle = <0x187>; + spi-max-frequency = <0xb71b00>; + }; + + rtc@c2a0000 { + compatible = "nvidia,tegra18-rtc"; + status = "okay"; + interrupt-parent = <0x3a>; + interrupts = <0x0 0xa 0x4>; + reg = <0x0 0xc2a0000 0x0 0x100>; + }; + + sdhci@3440000 { + nvidia,ddr-tap-delay = <0xb>; + nvidia,en-periodic-calib; + cap-mmc-highspeed; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x4c 0x10 0x10d 0x10 0x80>; + cap-sd-highspeed; + resets = <0x10 0x23>; + pinctrl-1 = <0x15>; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + pll_source = "pll_p"; + only-1-8-v; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "okay"; + nvidia,max-tap-delay = <0x88>; + interrupts = <0x0 0x40 0x4>; + bus-width = <0x4>; + ddr-trim-delay = <0x5>; + phandle = <0xf9>; + tap-delay = <0xb>; + force-non-removable-rescan; + reg = <0x0 0x3440000 0x0 0x210>; + pinctrl-0 = <0x14>; + mmc-ocr-mask = <0x0>; + compad-vref-1v8 = <0x2>; + trim-delay = <0x5>; + pwrdet-support; + reset-names = "sdhci"; + vmmc-supply = <0x12>; + uhs-mask = <0x8>; + linux,phandle = <0xf9>; + non-removable; + ignore-pm-notify; + compad-vref-3v3 = <0x1>; + vqmmc-supply = <0x16>; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + max-clk-limit = <0xc28cb00>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x50b0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr12 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr25 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20006a76>; + }; + }; + }; + + miscreg@00100000 { + compatible = "nvidia,tegra186-miscreg"; + status = "disabled"; + reg = <0x0 0x100000 0x0 0xf000 0x0 0x10f000 0x0 0x1000>; + }; + + // virtio_blk1@f0a000000 { + // compatible = "virtio,mmio"; + // dma-coherent; + // interrupts = <0x0 0x10c 0x1>; + // reg = <0xf 0xa000000 0x0 0x400>; + // }; + + reserved-memory { + ranges; + #address-cells = <0x2>; + #size-cells = <0x2>; + + fb0_carveout { + reg-names = "surface", "lut"; + no-map; + phandle = <0x80>; + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + linux,phandle = <0x80>; + }; + + ramoops_carveout { + compatible = "nvidia,ramoops"; + alignment = <0x0 0x10000>; + status = "disabled"; + no-map; + phandle = <0x1cc>; + reg = <0x2 0x75880000 0x0 0x200000>; + linux,phandle = <0x1cc>; + }; + + vpr-carveout { + reusable; + alignment = <0x0 0x400000>; + alloc-ranges = <0x0 0x80000000 0x0 0x70000000>; + phandle = <0x96>; + linux,phandle = <0x96>; + }; + + fb1_carveout { + reg-names = "surface", "lut"; + no-map; + phandle = <0x81>; + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + linux,phandle = <0x81>; + }; + + fb2_carveout { + reg-names = "surface", "lut"; + no-map; + phandle = <0x82>; + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + linux,phandle = <0x82>; + }; + + generic_carveout { + compatible = "nvidia,generic_carveout"; + alignment = <0x0 0x100000>; + alloc-ranges = <0x0 0x0 0x1 0x0>; + status = "disabled"; + no-map; + size = <0x0 0x0>; + phandle = <0x95>; + linux,phandle = <0x95>; + }; + }; + + pwm@32c0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbe 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x67>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x189>; + reg = <0x0 0x32c0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x189>; + #pwm-cells = <0x2>; + }; + + // virtio_net@f0a001000 { + // compatible = "virtio,mmio"; + // dma-coherent; + // interrupts = <0x0 0x10b 0x1>; + // reg = <0xf 0xa001000 0x0 0x400>; + // }; + + tegra_safety_ivc { + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0x60>; + linux,phandle = <0x60>; + + cmdresp@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-safety-cmd-resp"; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0x0 0x8000>; + }; + + hb@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-safety-hb"; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x1>; + reg = <0x500 0x8500>; + }; + }; + + replicator@0x8040000 { + compatible = "arm,coresight-replicator"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8040000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + reg = <0x1>; + + endpoint { + remote-endpoint = <0xdf>; + phandle = <0xe3>; + linux,phandle = <0xe3>; + }; + }; + + port@2 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe0>; + phandle = <0xe2>; + slave-mode; + linux,phandle = <0xe2>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xde>; + phandle = <0xe4>; + linux,phandle = <0xe4>; + }; + }; + }; + }; + + max16984-cdp { + compatible = "maxim,max16984-tegra186-cdp-phy"; + status = "disabled"; + phandle = <0x1d0>; + #phy-cells = <0x1>; + linux,phandle = <0x1d0>; + }; + + sound_ref { + dma-mask = <0x0 0x5e000000>; + status = "disabled"; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommus = <0x11 0x1e>; + }; + + bcmdhd_pcie_wlan { + nv_path = "/vendor/firmware/nvram_4359_b1.txt"; + compatible = "android,bcmdhd_pcie_wlan"; + fw_path = "/vendor/firmware/fw_bcmdhd.bin"; + status = "disabled"; + interrupt-parent = <0x28>; + interrupts = <0x3b 0x14>; + phandle = <0x1e5>; + linux,phandle = <0x1e5>; + wlan-pwr-gpio = <0x1b 0x68 0x0>; + }; + + sce@b000000 { + compatible = "nvidia,tegra186-safety-ivc"; + reg-names = "ast-cpu", "ast-dma"; + status = "disabled"; + nvidia,ivc-channels = <0x60 0x2 0x90000000 0x10000>; + phandle = <0x1bd>; + reg = <0x0 0xb040000 0x0 0x10000 0x0 0xb050000 0x0 0x10000>; + iommus = <0x11 0x1f>; + linux,phandle = <0x1bd>; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + nvidia,hsp-shared-mailbox = <0x58 0x1 0x58 0x6>; + }; + }; + + pmc-iopower { + vddio-cam-supply = <0x3d>; + vddio-sdmmc1-hv-supply = <0x1c>; + vddio-spi-supply = <0x3d>; + compatible = "nvidia,tegra186-pmc-iopower"; + vddio-pex-ctrl-supply = <0x3d>; + vddio-conn-supply = <0x3d>; + pad-names = "ufs", "dbg", "spi", "audio-hv", "ao-hv", "dmic-hv", "sdmmc1-hv", "sdmmc2-hv", "sdmmc3-hv", "dsia", "dsib", "dsic", "dsid", "hdmi-dp0", "hdmi-dp1"; + vddio-sdmmc4-supply = <0x3d>; + vddio-ddr1-supply = <0xb4>; + vddio-mipi-bias-supply = <0x3c>; + vddio-ddr0-supply = <0xb4>; + vddio-audio-supply = <0x3d>; + vddio-sdmmc2-hv-supply = <0x13>; + vddio-uart-supply = <0x3d>; + status = "okay"; + vddio-dbg-supply = <0x3d>; + vddio-ufs-supply = <0x3d>; + vddio-audio-hv-supply = <0x3d>; + vddio-edp-supply = <0x3d>; + vddio-dmic-hv-supply = <0x3d>; + phandle = <0x1d2>; + vddio-sys-supply = <0x3d>; + vddio-sdmmc3-hv-supply = <0x16>; + pad-controllers = <0xb3 0x34 0xa 0x29 0x1 0x35 0xd 0x24 0x25 0x27 0xf 0x10 0x11 0x12 0x18 0x19>; + linux,phandle = <0x1d2>; + vddio-ao-hv-supply = <0xb5>; + vddio-ao-supply = <0x3d>; + }; + + ptm@9840000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x4>; + status = "okay"; + phandle = <0x1d8>; + reg = <0x0 0x9840000 0x0 0x1000>; + linux,phandle = <0x1d8>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd6>; + linux,phandle = <0xd6>; + }; + }; + }; + + actmon@d230000 { + nvidia,sample_period = [14]; + compatible = "nvidia,tegra186-cactmon"; + clocks = <0x10 0xc9>; + resets = <0x10 0x0>; + clock-names = "actmon"; + status = "okay"; + #address-cells = <0x2>; + interrupts = <0x0 0xd2 0x4>; + #size-cells = <0x2>; + reg = <0x0 0xd230000 0x0 0x1000>; + reset-names = "actmon_rst"; + + mc_all { + nvidia,suspend_freq = <0x31ce0>; + nvidia,boost_up_threshold = <0x1e>; + nvidia,up_wmark_window = [03]; + nvidia,boost_down_coef = <0x32>; + nvidia,count_weight = <0x200>; + nvidia,max_dram_channels = [04]; + nvidia,boost_down_threshold = <0x14>; + nvidia,type = <0x1>; + nvidia,down_wmark_window = [02]; + nvidia,reg_offs = <0x100>; + status = "okay"; + nvidia,boost_up_coef = <0xc8>; + #address-cells = <0x1>; + #size-cells = <0x0>; + nvidia,avg_window_log2 = [06]; + nvidia,irq_mask = <0x2>; + nvidia,boost_freq_step = <0x31ce0>; + }; + }; + + nvpmodel { + compatible = "nvidia,nvpmodel"; + status = "okay"; + }; + + tegra-hsp@c150000 { + compatible = "nvidia,tegra186-hsp"; + status = "okay"; + interrupts = <0x0 0x85 0x4 0x0 0x86 0x4 0x0 0x87 0x4 0x0 0x88 0x4>; + phandle = <0xe8>; + reg = <0x0 0xc150000 0x0 0x90000>; + linux,phandle = <0xe8>; + interrupt-names = "shared1", "shared2", "shared3", "shared4"; + }; + + pwm@3290000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbc 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x64>; + clock-names = "pwm", "parent", "slow-parent"; + status = "okay"; + phandle = <0x188>; + reg = <0x0 0x3290000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x188>; + #pwm-cells = <0x2>; + }; + + arm-pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0x0 0x140 0x4 0x0 0x141 0x4 0x0 0x128 0x4 0x0 0x129 0x4 0x0 0x12a 0x4 0x0 0x12b 0x4>; + interrupt-affinity = <0x2 0x3 0x4 0x5 0x6 0x7>; + }; + + axi2apb@23b0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23b0000 0x0 0x1000>; + }; + + tegra186-pm-irq { + compatible = "nvidia,tegra186-pm-irq"; + #interrupt-cells = <0x3>; + interrupt-parent = <0x1>; + phandle = <0x3a>; + linux,phandle = <0x3a>; + interrupt-controller; + }; + + axip2p@2130000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2130000 0x0 0x1000>; + }; + + xotg { + compatible = "nvidia,tegra186-xotg"; + otg-rev = <0x300>; + phy-names = "otg-usb2"; + extcon-cable-names = "id", "vbus"; + status = "okay"; + interrupts = <0x0 0xa7 0x4>; + adp-disable; + phandle = <0xab>; + extcon-cables = <0xa0 0x1 0xa0 0x0>; + phys = <0xa1 0x10>; + #extcon-cells = <0x1>; + linux,phandle = <0xab>; + }; + + vm_service { + compatible = "shyper"; + interrupts = <0x0 0x100 0x1>; + }; + + pmc@c370000 { + compatible = "nvidia,tegra186-aowake"; + status = "okay"; + phandle = <0x1d1>; + nvidia,invert-interrupt; + reg = <0x0 0xc370000 0x0 0x600>; + linux,phandle = <0x1d1>; + }; + + gpio-keys { + compatible = "gpio-keys"; + gpio-keys,name = "gpio-keys"; + + volume_up { + gpios = <0x28 0x39 0x1>; + label = "Volume Up"; + linux,code = <0x73>; + }; + + power { + gpios = <0x28 0x38 0x1>; + label = "Power"; + gpio-key,wakeup; + linux,code = <0x74>; + }; + + volume_down { + gpios = <0x28 0x3a 0x1>; + label = "Volume Down"; + linux,code = <0x72>; + }; + }; + + serial@3110000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0x38 0x10 0x10d>; + resets = <0x10 0x30>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "NILL"; + interrupts = <0x0 0x71 0x4>; + dma-names = "rx", "tx"; + phandle = <0x18d>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3110000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x9 0x25 0x9>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x18d>; + }; + + chipid@100000 { + compatible = "nvidia,tegra186-chipid"; + status = "disabled"; + reg = <0x0 0x100000 0x0 0x10000>; + }; + + power-domain { + compatible = "tegra-power-domains"; + + disc-pd { + compatible = "nvidia,tegra186-disc-pd"; + partition-id = <0x4>; + phandle = <0x197>; + linux,phandle = <0x197>; + #power-domain-cells = <0x0>; + }; + + adsp-pd { + power-domains = <0x45>; + compatible = "nvidia,tegra186-adsp-pd"; + phandle = <0x193>; + linux,phandle = <0x193>; + is_off; + #power-domain-cells = <0x0>; + }; + + ape-pd { + compatible = "nvidia,tegra186-ape-pd"; + clocks = <0x10 0x69 0x10 0x68 0x10 0x8a 0x10 0x111>; + clock-names = "ape", "apb2ape", "adsp", "aclk"; + partition-id = <0x0>; + phandle = <0x45>; + linux,phandle = <0x45>; + is_off; + #power-domain-cells = <0x0>; + }; + + xusba-pd { + compatible = "nvidia,tegra186-xusba-pd"; + partition-id = <0xd>; + phandle = <0x198>; + linux,phandle = <0x198>; + #power-domain-cells = <0x0>; + }; + + disb-pd { + compatible = "nvidia,tegra186-disb-pd"; + partition-id = <0x3>; + phandle = <0x196>; + linux,phandle = <0x196>; + #power-domain-cells = <0x0>; + }; + + sata-pd { + compatible = "nvidia,tegra186-sata-pd"; + partition-id = <0xa>; + phandle = <0x195>; + linux,phandle = <0x195>; + #power-domain-cells = <0x0>; + }; + + xusbc-pd { + compatible = "nvidia,tegra186-xusbc-pd"; + partition-id = <0xf>; + phandle = <0x19a>; + linux,phandle = <0x19a>; + #power-domain-cells = <0x0>; + }; + + disa-pd { + compatible = "nvidia,tegra186-disa-pd"; + partition-id = <0x2>; + phandle = <0x94>; + linux,phandle = <0x94>; + #power-domain-cells = <0x0>; + }; + + pcie-pd { + compatible = "nvidia,tegra186-pcie-pd"; + partition-id = <0x9>; + phandle = <0x194>; + linux,phandle = <0x194>; + is_off; + #power-domain-cells = <0x0>; + }; + + xusbb-pd { + compatible = "nvidia,tegra186-xusbb-pd"; + partition-id = <0xe>; + phandle = <0x199>; + linux,phandle = <0x199>; + #power-domain-cells = <0x0>; + }; + }; + + bpmp_i2c { + compatible = "nvidia,tegra186-bpmp-i2c"; + adapter = <0x5>; + status = "okay"; + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0x17c>; + linux,phandle = <0x17c>; + + spmic@3c { + maxim,avoid-power-off-commands; + compatible = "maxim,max77620"; + maxim,hot-die-threshold-temp = <0x1adb0>; + #thermal-sensor-cells = <0x0>; + gpio-controller; + maxim,enable-clock32k-out; + #interrupt-cells = <0x2>; + interrupt-parent = <0x3a>; + maxim,system-pmic-power-off; + interrupts = <0x0 0xd1 0x0>; + phandle = <0x22>; + reg = <0x3c>; + #gpio-cells = <0x2>; + pinctrl-0 = <0x3b>; + linux,phandle = <0x22>; + pinctrl-names = "default"; + interrupt-controller; + + spmic_gpio_input { + gpios = <0x5 0x0 0x6 0x0>; + gpio-hog; + label = "spmic_gpio_input_5", "spmic_gpio_input_6"; + input; + }; + + backup-battery { + backup-battery-output-resister = <0x64>; + status = "disabled"; + backup-battery-charging-current = <0x64>; + backup-battery-charging-voltage = <0x2dc6c0>; + }; + + pinmux@0 { + phandle = <0x3b>; + linux,phandle = <0x3b>; + + pin_gpio6 { + pins = "gpio6"; + function = "gpio"; + drive-push-pull = <0x1>; + }; + + pin_gpio4 { + pins = "gpio4"; + function = "32k-out1"; + drive-push-pull = <0x1>; + }; + + pin_gpio2 { + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x7>; + maxim,active-fps-power-down-slot = <0x1>; + pins = "gpio2"; + status = "disabled"; + function = "fps-out"; + }; + + pin_gpio0 { + pins = "gpio0"; + function = "gpio"; + }; + + pin_gpio7 { + pins = "gpio7"; + function = "gpio"; + drive-push-pull = <0x1>; + }; + + pin_gpio5 { + pins = "gpio5"; + function = "gpio"; + drive-push-pull = <0x0>; + }; + + pin_gpio3 { + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x1>; + maxim,active-fps-power-down-slot = <0x7>; + pins = "gpio3"; + status = "disabled"; + function = "fps-out"; + }; + + pin_gpio1 { + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x1>; + maxim,active-fps-power-down-slot = <0x3>; + pins = "gpio1"; + function = "fps-out"; + }; + }; + + fps { + + fps0 { + maxim,fps-event-source = <0x0>; + shutdown-fps-time-period-us = <0x280>; + }; + + fps1 { + maxim,fps-event-source = <0x1>; + device-state-on-disabled-event = <0x0>; + shutdown-fps-time-period-us = <0x280>; + }; + + fps2 { + maxim,fps-event-source = <0x0>; + maxim,shutdonw-fps-time-period-us = <0x280>; + }; + }; + + watchdog { + maxim,wdt-clear-time = <0xd>; + maxim,wdt-timeout = <0x10>; + status = "disabled"; + phandle = <0xfe>; + linux,phandle = <0xfe>; + }; + + regulators { + in-ldo6-supply = <0x12>; + in-ldo7-8-supply = <0x3c>; + in-ldo4-supply = <0x12>; + + ldo8 { + maxim,active-fps-source = <0x4>; + phandle = <0x10d>; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "dvdd-pex"; + linux,phandle = <0x10d>; + }; + + ldo6 { + maxim,active-fps-source = <0x3>; + regulator-boot-on; + maxim,ramp-rate-setting = <0x186a0>; + phandle = <0x10c>; + regulator-always-on; + regulator-name = "spmic-ldo6"; + linux,phandle = <0x10c>; + regulator-ramp-delay = <0x186a0>; + }; + + sd2 { + regulator-enable-ramp-delay = <0xfa0>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x0>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x7>; + regulator-init-mode = <0x2>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x5208>; + phandle = <0x12>; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-name = "vdd-1v8"; + linux,phandle = <0x12>; + regulator-ramp-delay = <0x1c2>; + }; + + ldo4 { + regulator-enable-ramp-delay = <0x1a>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x1>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x7>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-disable-ramp-delay = <0x672>; + phandle = <0x17e>; + regulator-always-on; + regulator-name = "vdd-rtc"; + linux,phandle = <0x17e>; + regulator-ramp-delay = <0x80e8>; + }; + + sd0 { + regulator-enable-ramp-delay = <0x116>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x5>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x2>; + regulator-init-mode = <0x2>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x255a8>; + phandle = <0xb4>; + regulator-always-on; + regulator-name = "vddio-ddr"; + linux,phandle = <0xb4>; + regulator-ramp-delay = <0xf5a>; + }; + + ldo2 { + regulator-enable-ramp-delay = <0x98>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x6>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-disable-ramp-delay = <0x36b0>; + phandle = <0xb5>; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-name = "vddio-3v3"; + linux,phandle = <0xb5>; + regulator-ramp-delay = <0x4e20>; + }; + + ldo0 { + regulator-enable-ramp-delay = <0x3e8>; + maxim,active-fps-source = <0x3>; + maxim,active-fps-power-up-slot = <0x3>; + maxim,active-fps-power-down-slot = <0x3>; + maxim,ramp-rate-setting = <0x186a0>; + phandle = <0x10e>; + regulator-name = "spmic-ldo0"; + linux,phandle = <0x10e>; + regulator-ramp-delay = <0x186a0>; + }; + + ldo7 { + regulator-enable-ramp-delay = <0x5f>; + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x4>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-disable-ramp-delay = <0x3a98>; + phandle = <0x89>; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-always-on; + regulator-name = "vdd-pex-1v00"; + linux,phandle = <0x89>; + regulator-ramp-delay = <0x2710>; + }; + + sd3 { + regulator-enable-ramp-delay = <0x23e>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x6>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x9c40>; + phandle = <0x13>; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-name = "vdd-3v3-sys"; + linux,phandle = <0x13>; + regulator-ramp-delay = <0x157c>; + }; + + ldo5 { + regulator-enable-ramp-delay = <0x135>; + maxim,active-fps-source = <0x4>; + maxim,active-fps-power-up-slot = <0x0>; + maxim,active-fps-power-down-slot = <0x7>; + maxim,ramp-rate-setting = <0x1388>; + regulator-disable-ramp-delay = <0x3e80>; + phandle = <0x16>; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "avdd-ts-hv"; + linux,phandle = <0x16>; + regulator-ramp-delay = <0x20e>; + }; + + sd1 { + regulator-enable-ramp-delay = <0xd3>; + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x3>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + regulator-init-mode = <0x2>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x9c40>; + phandle = <0x3c>; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x124f80>; + regulator-always-on; + regulator-name = "avdd_dsi_csi"; + linux,phandle = <0x3c>; + regulator-ramp-delay = <0x157c>; + }; + + ldo3 { + regulator-enable-ramp-delay = <0xa0>; + maxim,active-fps-source = <0x3>; + maxim,active-fps-power-up-slot = <0x0>; + maxim,active-fps-power-down-slot = <0x7>; + maxim,ramp-rate-setting = <0x1388>; + regulator-disable-ramp-delay = <0x3e80>; + phandle = <0x1c>; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vddio-sdmmc1"; + linux,phandle = <0x1c>; + regulator-ramp-delay = <0x3e8>; + }; + + ldo1 { + regulator-enable-ramp-delay = <0x3e8>; + maxim,active-fps-source = <0x4>; + maxim,ramp-rate-setting = <0x186a0>; + phandle = <0x17d>; + regulator-name = "spmic-ldo1"; + linux,phandle = <0x17d>; + regulator-ramp-delay = <0x186a0>; + }; + }; + }; + }; + + axip2p@2170000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2170000 0x0 0x1000>; + }; + + i2c@c240000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xda 0x10 0x10d 0x10 0xdd>; + resets = <0x10 0x14>; + scl-gpio = <0x28 0x30 0x0>; + sda-gpio = <0x28 0x31 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1a 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x175>; + reg = <0x0 0xc240000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x16 0x25 0x16>; + reset-names = "i2c"; + linux,phandle = <0x175>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + ak8963@0d { + compatible = "ak,ak89xx"; + magnetic_field_matrix = [01 00 00 00 01 00 00 00 01]; + status = "disabled"; + phandle = <0x111>; + reg = <0xd>; + linux,phandle = <0x111>; + }; + + i2cmux@70 { + vcc-pullup-supply = <0x26>; + compatible = "nxp,pca9546"; + status = "disabled"; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2e>; + phandle = <0x10f>; + reg = <0x70>; + linux,phandle = <0x10f>; + + i2c@0 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0>; + + tas2552.9-0040@40 { + compatible = "ti,tas2552"; + iovdd-supply = <0x2e>; + phandle = <0x117>; + reg = <0x40>; + vbat-supply = <0x26>; + avdd-supply = <0x2f>; + tas2552,pdm_edge_select = <0x0>; + linux,phandle = <0x117>; + }; + + tas2552.9-0041@41 { + compatible = "ti,tas2552"; + iovdd-supply = <0x2e>; + phandle = <0x119>; + reg = <0x41>; + vbat-supply = <0x26>; + avdd-supply = <0x2f>; + tas2552,pdm_edge_select = <0x1>; + linux,phandle = <0x119>; + }; + }; + + i2c@3 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x3>; + + rt5659.12-001a@1a { + gpios = <0x1b 0x4d 0x0>; + compatible = "realtek,rt5658"; + realtek,dmic1-data-pin = <0x2>; + status = "disabled"; + phandle = <0x11b>; + reg = <0x1a>; + realtek,jd-src = <0x1>; + linux,phandle = <0x11b>; + }; + }; + + i2c@1 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x1>; + + ina3221x@41 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x41>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_1V8_AUD"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_5V_AUD"; + ti,shunt-resistor-mohm = <0x1>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_3V3_AUD"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + ina3221x@42 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x42>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_3V3_GYRO"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_3V3_GPS"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_3V3_NFC"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + ina3221x@40 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x40>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_1V8"; + ti,shunt-resistor-mohm = <0x1>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_5V"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_3V3"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + }; + + i2c@2 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x2>; + }; + }; + + rt5659.1-001a@1a { + gpios = <0x1b 0x4d 0x0>; + compatible = "realtek,rt5658"; + realtek,dmic1-data-pin = <0x2>; + status = "disabled"; + phandle = <0x11a>; + reg = <0x1a>; + realtek,jd-src = <0x1>; + linux,phandle = <0x11a>; + }; + + lp8556-backlight-s-wqxga-10-1@2c { + compatible = "ti,lp8556"; + init-brt = [ff]; + pwm-period = <0x9ce1>; + dev-ctrl = [80]; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + disable-on-kernel-charging; + pwm-names = "lp8556"; + status = "disabled"; + bl-name = "pwm-backlight"; + phandle = <0x11d>; + reg = <0x2c>; + pwms = <0x27 0x0 0x9ce1>; + linux,phandle = <0x11d>; + }; + + ov23850_c@36 { + compatible = "nvidia,ov23850"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "7.3998"; + iovdd-reg = "vif"; + vcmvdd-reg = "vvcm"; + vdig-supply = <0x2a>; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x1b 0x89 0x0>; + phandle = <0x136>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x6a 0x0>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x136>; + vif-supply = <0x2b>; + physical_h = "5.5998"; + vvcm-suply = <0x2c>; + + mode0 { + line_length = "5922"; + active_w = "5632"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "600000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "15.5"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = "270"; + min_gain_val = "1.0"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + csi_pixel_bit_depth = "10"; + min_framerate = "3.09135"; + max_framerate = "30"; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + active_h = "3168"; + max_exp_time = "323094"; + mclk_multiplier = "25"; + min_exp_time = "19.74"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x2d>; + bus-width = <0x4>; + phandle = <0x139>; + linux,phandle = <0x139>; + }; + }; + }; + }; + + bmp280@77 { + compatible = "bmp,bmpX80"; + status = "disabled"; + phandle = <0x112>; + reg = <0x77>; + linux,phandle = <0x112>; + }; + + icm20628@68 { + compatible = "invensense,mpu6xxx"; + gyroscope_matrix = [01 00 00 00 01 00 00 00 01]; + vlogic-supply = <0x13>; + gyroscope_uncalibrated_disable = <0x1>; + status = "disabled"; + interrupt-parent = <0x28>; + interrupts = <0x2a 0x1>; + phandle = <0x110>; + quaternion_disable = <0x1>; + vdd-supply = <0x13>; + reg = <0x68>; + accelerometer_matrix = [01 00 00 00 01 00 00 00 01]; + geomagnetic_rotation_vector_disable = <0x1>; + linux,phandle = <0x110>; + }; + + bmi160@69 { + compatible = "bmi,bmi160"; + gyroscope_matrix = [01 00 00 00 01 00 00 00 01]; + vdd_IO-supply = <0x13>; + gyroscope_delay_us_min = <0x4e2>; + status = "disabled"; + interrupt-parent = <0x28>; + interrupts = <0x2a 0x1>; + accelerometer_delay_us_min = <0x4e2>; + vdd-supply = <0x13>; + reg = <0x69>; + accelerometer_matrix = [01 00 00 00 01 00 00 00 01]; + }; + + iqs263@44 { + status = "disabled"; + phandle = <0x17b>; + linux,phandle = <0x17b>; + }; + + gpio@20 { + compatible = "ti,tca6416"; + gpio-controller; + status = "disabled"; + vcc-supply = <0x26>; + phandle = <0xea>; + reg = <0x20>; + #gpio-cells = <0x2>; + linux,phandle = <0xea>; + }; + + cm32180@48 { + compatible = "capella,cm32180"; + light_uncalibrated_hi = <0x17318>; + light_calibrated_hi = <0x1ab3f0>; + gpio_irq = <0x1b 0x44 0x1>; + status = "disabled"; + phandle = <0x113>; + light_uncalibrated_lo = <0x1>; + reg = <0x48>; + light_calibrated_lo = <0x96>; + linux,phandle = <0x113>; + }; + }; + + roc-flush@e080000 { + compatible = "nvidia,tegra186-roc-flush"; + status = "disabled"; + reg = <0x0 0xe080000 0x0 0x10000>; + }; + + cpufreq@e070000 { + compatible = "nvidia,tegra18x-cpufreq"; + nvidia,enable-autocc3 = <0x0 0x1 0x1 0x1>; + cpu_emc_map = <0x79e00 0x31ce0 0x9f600 0x639c0 0x15ae00 0xa2800 0x1d4c00 0x1c7910>; + nvidia,autocc3-freq = <0x0 0x0 0x1 0x0>; + status = "okay"; + reg = <0x0 0xe000000 0x0 0x80000>; + }; + + i2c@3160000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x2f 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x13>; + scl-gpio = <0x1b 0x15 0x0>; + sda-gpio = <0x1b 0x16 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x19 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x106>; + reg = <0x0 0x3160000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x15 0x25 0x15>; + reset-names = "i2c"; + linux,phandle = <0x106>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + ina3221x@43 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x43>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_3V3_SYS_M2"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_3V3_IO_SLP"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_1V8_IO"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + tps65132@3e { + compatible = "ti,tps65132"; + status = "disabled"; + phandle = <0x11c>; + reg = <0x3e>; + linux,phandle = <0x11c>; + + outn { + enable-active-high; + phandle = <0x87>; + regulator-min-microvolt = <0x3d0900>; + regulator-max-microvolt = <0x5b8d80>; + ti,disable-active-discharge; + regulator-name = "outn"; + linux,phandle = <0x87>; + }; + + outp { + enable-active-high; + phandle = <0x86>; + regulator-min-microvolt = <0x3d0900>; + regulator-max-microvolt = <0x5b8d80>; + regulator-name = "outp"; + linux,phandle = <0x86>; + }; + }; + + ina3221x@41 { + compatible = "ti,ina3221x"; + #io-channel-cells = <0x1>; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0xf1>; + reg = <0x41>; + linux,phandle = <0xf1>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_SYS_DDR"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_IN"; + ti,shunt-resistor-mohm = <0x14>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_SYS_CPU"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + gpio@21 { + compatible = "ti,tca6408"; + gpio-controller; + status = "disabled"; + vcc-supply = <0x26>; + phandle = <0x40>; + reg = <0x21>; + #gpio-cells = <0x2>; + linux,phandle = <0x40>; + + vpp-vmm-rails { + gpios = <0x2 0x0>; + gpio-hog; + label = "vmm-en-rail"; + output-high; + }; + }; + + gpio@74 { + compatible = "ti,tca9539"; + gpio-controller; + vcc-supply = <0x26>; + phandle = <0xe9>; + reg = <0x74>; + #gpio-cells = <0x2>; + linux,phandle = <0xe9>; + + touch-rails { + gpios = <0x1 0x0 0x2 0x0>; + gpio-hog; + label = "touch-rail-1", "touch-rail-2"; + output-high; + }; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + compatible = "ti,lp8557"; + init-brt = [ff]; + bl-curve = <0x0 0x1 0x1 0x2 0x2 0x3 0x3 0x4 0x4 0x5 0x5 0x6 0x7 0x7 0x8 0x8 0x9 0x9 0xa 0xa 0xb 0xb 0xc 0xc 0xd 0xe 0xe 0xf 0xf 0x10 0x10 0x11 0x11 0x12 0x12 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x18 0x18 0x19 0x19 0x1a 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1e 0x1e 0x1f 0x1f 0x20 0x21 0x21 0x22 0x22 0x23 0x23 0x24 0x24 0x25 0x25 0x26 0x26 0x27 0x28 0x28 0x29 0x29 0x2a 0x2a 0x2b 0x2b 0x2c 0x2c 0x2d 0x2e 0x2e 0x2f 0x2f 0x30 0x30 0x31 0x31 0x32 0x32 0x33 0x34 0x34 0x35 0x35 0x36 0x36 0x37 0x37 0x38 0x38 0x39 0x39 0x3a 0x3b 0x3b 0x3c 0x3c 0x3d 0x3d 0x3e 0x3e 0x3f 0x3f 0x40 0x41 0x41 0x42 0x42 0x43 0x43 0x44 0x44 0x45 0x45 0x46 0x46 0x47 0x48 0x48 0x49 0x49 0x4a 0x4a 0x4b 0x4b 0x4c 0x4c 0x4d 0x4e 0x4e 0x4f 0x4f 0x50 0x50 0x51 0x51 0x52 0x52 0x53 0x53 0x54 0x55 0x55 0x56 0x56 0x57 0x57 0x58 0x58 0x59 0x59 0x5a 0x5c 0x5e 0x60 0x61 0x63 0x65 0x67 0x69 0x6b 0x6d 0x6e 0x70 0x72 0x74 0x76 0x78 0x7a 0x7b 0x7d 0x7f 0x81 0x83 0x85 0x86 0x88 0x8a 0x8c 0x8e 0x90 0x92 0x93 0x95 0x97 0x99 0x9b 0x9d 0x9f 0xa0 0xa2 0xa4 0xa6 0xa8 0xaa 0xac 0xad 0xaf 0xb1 0xb3 0xb5 0xb7 0xb9 0xba 0xbc 0xbe 0xc0 0xc2 0xc4 0xc6 0xc7 0xc9 0xcb 0xcd 0xcf 0xd1 0xd3 0xd4 0xd6 0xd8 0xda 0xdc 0xde 0xdf 0xe1 0xe3 0xe5 0xe7 0xe9 0xeb 0xec 0xee 0xf0 0xf2 0xf4 0xf6 0xf8 0xf9 0xfb 0xfd 0xff>; + pwm-period = <0x9ce1>; + dev-ctrl = [80]; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + disable-on-kernel-charging; + pwm-names = "lp8557"; + status = "disabled"; + bl-name = "pwm-backlight"; + phandle = <0xf3>; + reg = <0x2c>; + pwms = <0x27 0x0 0x9ce1>; + linux,phandle = <0xf3>; + power-supply = <0x26>; + + rom_14h { + rom-addr = [14]; + rom-val = [9f]; + }; + + rom_13h { + rom-addr = [13]; + rom-val = [01]; + }; + + rom_11h { + rom-addr = [11]; + rom-val = [05]; + }; + }; + + ina3221x@42 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x42>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_3V3_SYS"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_MUX"; + ti,shunt-resistor-mohm = <0x14>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_5V0_IO_SYS"; + ti,shunt-resistor-mohm = <0x5>; + reg = <0x1>; + }; + }; + + ina3221x@40 { + compatible = "ti,ina3221x"; + #io-channel-cells = <0x1>; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0xf0>; + reg = <0x40>; + linux,phandle = <0xf0>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_4V0_WIFI"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_SYS_GPU"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_SYS_SOC"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + gpio@77 { + compatible = "ti,tca9539"; + gpio-controller; + vcc-supply = <0x26>; + phandle = <0x8d>; + reg = <0x77>; + #gpio-cells = <0x2>; + linux,phandle = <0x8d>; + + lcd-bias-rails { + gpios = <0x4 0x0>; + gpio-hog; + label = "lcd-bias-en-rail"; + output-high; + }; + }; + }; + + serial@3150000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xc3 0x10 0x10d>; + resets = <0x10 0x6f>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "disabled"; + interrupts = <0x0 0x75 0x4>; + dma-names = "rx", "tx"; + phandle = <0x191>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3150000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0xc 0x25 0xc>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x191>; + }; + + tegra-hsp@3c00000 { + compatible = "nvidia,tegra186-hsp"; + status = "okay"; + interrupts = <0x0 0xb0 0x4 0x0 0x78 0x4 0x0 0x79 0x4 0x0 0x7a 0x4 0x0 0x7b 0x4 0x0 0x7c 0x4 0x0 0x7d 0x4 0x0 0x7e 0x4 0x0 0x7f 0x4>; + phandle = <0x1d5>; + reg = <0x0 0x3c00000 0x0 0xa0000>; + linux,phandle = <0x1d5>; + interrupt-names = "doorbell", "shared0", "shared1", "shared2", "shared3", "shared4", "shared5", "shared6", "shared7"; + }; + + xudc@3550000 { + compatible = "nvidia,tegra186-xudc"; + clocks = <0x10 0xf3 0x10 0x72 0x10 0xf2 0x10 0xf5>; + otg-controller = <0xab>; + iommu_sodev_map; + avdd-usb-supply = <0x13>; + phy-names = "usb2"; + extcon-cable-names = "vbus"; + status = "okay"; + nvidia,boost-cpu-freq = <0x4b0>; + interrupts = <0x0 0xa6 0x4>; + phandle = <0x1cf>; + extcon-cables = <0xa0 0x0>; + phys = <0x9e>; + reg = <0x0 0x3550000 0x0 0x8000 0x0 0x3558000 0x0 0x1000>; + iommus = <0x11 0x1c>; + nvidia,xusb-padctl = <0x9f>; + #extcon-cells = <0x1>; + linux,phandle = <0x1cf>; + charger-detector = <0xaf>; + }; + + iommu@12000000 { + compatible = "arm,mmu-500"; + #iommu-cells = <0x1>; + #global-interrupts = <0x2>; + status = "okay"; + interrupts = <0x0 0xaa 0x4 0x0 0xab 0x4>; + phandle = <0x11>; + reg = <0x0 0x12000000 0x0 0x1000000>; + linux,phandle = <0x11>; + suspend-save-reg = <0xc390868>; + + domains { + + xusb_host_domain { + address-space = <0x9a>; + sid-list = <0x1b>; + }; + + host1x2_domain { + address-space = <0x99>; + sid-list = <0x3a>; + }; + + sdmmc4a_domain { + address-space = <0x9a>; + sid-list = <0x17>; + }; + + host1x_client_domain { + address-space = <0x99>; + sid-list = <0x3 0x4 0x6 0x7 0x8 0x5 0xa 0xb 0x9 0x2 0x2b 0xc 0xd 0xe 0xf>; + }; + + sdmmc1a_domain { + address-space = <0x9a>; + sid-list = <0x1a>; + }; + + host1x1_domain { + address-space = <0x99>; + sid-list = <0x39>; + }; + + ufshci_domain { + address-space = <0x9a>; + sid-list = <0x15>; + }; + + host1x7_domain { + address-space = <0x99>; + sid-list = <0x3f>; + }; + + bpmp_domain { + address-space = <0x9a>; + sid-list = <0x32>; + }; + + sata2_domain { + address-space = <0x9a>; + sid-list = <0x1d>; + }; + + host1x0_domain { + address-space = <0x99>; + sid-list = <0x38>; + }; + + host1x6_domain { + address-space = <0x99>; + sid-list = <0x3e>; + }; + + sdmmc2a_domain { + address-space = <0x9a>; + sid-list = <0x19>; + }; + + gpu_domain { + address-space = <0x97>; + sid-list = <0x10>; + }; + + ape_domain { + address-space = <0x9b>; + sid-list = <0x1e 0x14>; + }; + + gpcdma_domain { + address-space = <0x9a>; + sid-list = <0x20>; + }; + + rtcpu_domain { + address-space = <0x9d>; + sid-list = <0x2a 0x2d>; + }; + + host1x5_domain { + address-space = <0x99>; + sid-list = <0x3d>; + }; + + hda_domain { + address-space = <0x9a>; + sid-list = <0x12>; + }; + + host1x4_domain { + address-space = <0x99>; + sid-list = <0x3c>; + }; + + xusb_dev_domain { + address-space = <0x9a>; + sid-list = <0x1c>; + }; + + sdmmc3a_domain { + address-space = <0x9a>; + sid-list = <0x18>; + }; + + aon_domain { + address-space = <0x9a>; + sid-list = <0x16>; + }; + + host1x_domain { + address-space = <0x98>; + sid-list = <0x1>; + }; + + smmu_test_domain { + address-space = <0x9a>; + sid-list = <0x33>; + }; + + afi_domain { + address-space = <0x9c>; + sid-list = <0x11>; + }; + + host1x3_domain { + address-space = <0x99>; + sid-list = <0x3b>; + }; + + sce_domain { + address-space = <0x9a>; + sid-list = <0x1f>; + }; + }; + + address-space-prop { + + camera { + iova-size = <0x0 0x20000000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0xa0000000>; + phandle = <0x9d>; + linux,phandle = <0x9d>; + }; + + gpu { + iova-size = <0x3ff 0xffefffff>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x0>; + iova-start = <0x0 0x100000>; + phandle = <0x97>; + linux,phandle = <0x97>; + }; + + pcie_as { + iova-size = <0x0 0xffffffff>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x80000000>; + phandle = <0x9c>; + linux,phandle = <0x9c>; + }; + + host1x_client { + iova-size = <0x1f 0xfffff000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x1000>; + phandle = <0x99>; + linux,phandle = <0x99>; + }; + + ape { + iova-size = <0x0 0x20000000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x40000000>; + phandle = <0x9b>; + linux,phandle = <0x9b>; + }; + + host1x { + iova-size = <0x0 0xfffff000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x1000>; + phandle = <0x98>; + linux,phandle = <0x98>; + }; + + common { + iova-size = <0x0 0x7ff00000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x80000000>; + phandle = <0x9a>; + linux,phandle = <0x9a>; + }; + }; + }; + + mods-simple-bus { + compatible = "simple-bus"; + device_type = "mods-simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + mods-clocks { + compatible = "nvidia,mods-clocks"; + clocks = <0x10 0x264 0x10 0x261 0x10 0x260 0x10 0x262 0x10 0x37 0x10 0x38 0x10 0xd7 0x10 0x4d 0x10 0xc2 0x10 0xc3 0x10 0xd8 0x10 0x57 0x10 0x68 0x10 0x69 0x10 0x4f 0x10 0x2a 0x10 0x2b 0x10 0x54 0x10 0x55 0x10 0x9a 0x10 0x7a 0x10 0x7b 0x10 0x96 0x10 0x97 0x10 0xdf 0x10 0x2c 0x10 0xee 0x10 0x98 0x10 0x99 0x10 0x6a 0x10 0x6b 0x10 0x7c 0x10 0xb4 0x10 0x33 0x10 0x32 0x10 0x59 0x10 0x5a 0x10 0x5b 0x10 0x49 0x10 0x63 0x10 0x64 0x10 0x65 0x10 0x84 0x10 0x31 0x10 0xde 0x10 0x2e 0x10 0x4a 0x10 0x2f 0x10 0xda 0x10 0x4b 0x10 0x56 0x10 0x30 0x10 0x7d 0x10 0xb6 0x10 0xdb 0x10 0xb7 0x10 0xdc 0x10 0xb8 0x10 0xb9 0x10 0xba 0x10 0x34 0x10 0x35 0x10 0x4c 0x10 0x36 0x10 0x80 0x10 0x6f 0x10 0x70 0x10 0x71 0x10 0x72 0x10 0xf2 0x10 0xf3 0x10 0xf4 0x10 0xf5 0x10 0x95 0x10 0xbb 0x10 0xbc 0x10 0xbd 0x10 0xe1 0x10 0xbe 0x10 0xbf 0x10 0xc0 0x10 0xc1 0x10 0x3a 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0xb2 0x10 0xb3 0x10 0x8c 0x10 0x8d 0x10 0x8e 0x10 0x8f 0x10 0x90 0x10 0x91 0x10 0x92 0x10 0x93 0x10 0x94 0x10 0x130 0x10 0x131 0x10 0xec 0x10 0x12e 0x10 0x12f 0x10 0xa6 0x10 0x10d 0x10 0x10e 0x10 0x204 0x10 0x11e 0x10 0x10f 0x10 0x20d 0x10 0xf6 0x10 0x120 0x10 0x201 0x10 0xb 0x10 0xc 0x10 0xd 0x10 0x209 0x10 0x20a 0x10 0x20c 0x10 0x6e 0x10 0x114 0x10 0x115 0x10 0x116 0x10 0x117 0x10 0x206 0x10 0x10b 0x10 0x207 0x10 0x210 0x10 0x20b 0x10 0x200 0x10 0x6c 0x10 0x6d 0x10 0x105 0x10 0x106 0x10 0x208 0x10 0x215 0x10 0x112 0x10 0x113>; + resets = <0x10 0x2f 0x10 0x30 0x10 0x31 0x10 0x32 0x10 0x84 0x10 0x6f 0x10 0x70 0x10 0x7b 0x10 0x3e 0x10 0x92 0x10 0x58 0x10 0x33 0x10 0x19 0x10 0xb 0x10 0xc 0x10 0xd 0x10 0x90 0x10 0x1f 0x10 0x81 0x10 0x28 0x10 0x29 0x10 0x2a 0x10 0x2b 0x10 0x13 0x10 0x14 0x10 0x15 0x10 0x16 0x10 0x17 0x10 0x18 0x10 0x51 0x10 0x52 0x10 0x53 0x10 0x4d 0x10 0x4e 0x10 0x4f 0x10 0x50 0x10 0x21 0x10 0x22 0x10 0x23 0x10 0x24 0x10 0x35 0x10 0x36 0x10 0x38 0x10 0x3a 0x10 0x63 0x10 0x64 0x10 0x65 0x10 0x66 0x10 0x67 0x10 0x68 0x10 0x69 0x10 0x6a 0x10 0x71 0x10 0x55 0x10 0x6d>; + clock-names = "osc", "clk_m", "clk_32k", "pll_ref", "uarta", "uartb", "uartc", "uartd", "uarte", "uartf", "uartg", "ahub", "apb2ape", "ape", "i2s1", "i2s2", "i2s3", "i2s4", "i2s5", "i2s6", "dmic1", "dmic2", "dmic3", "dmic4", "dmic5", "spdif_in", "spdif_out", "dspk1", "dspk2", "iqc1", "iqc2", "aud_mclk", "nvcsi", "vi", "isp", "extperiph1", "extperiph2", "extperiph3", "extperiph4", "sata", "sata_oob", "sata_iobist", "qspi", "spi1", "spi2", "spi3", "spi4", "i2c1", "i2c2", "i2c3", "i2c4", "i2c5", "i2c6", "i2c7", "i2c8", "i2c9", "i2c10", "i2c12", "i2c13", "i2c14", "sdmmc1", "sdmmc2", "sdmmc3", "sdmmc4", "sdmmc_legacy_tm", "xusb", "xusb_dev", "xusb_host", "xusb_ss", "xusb_core_ss", "xusb_core_dev", "xusb_falcon", "xusb_fs", "axi_cbb", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7", "pwm8", "emc", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "ufshc", "ufsdev_ref", "mphy_l0_rx_symb", "mphy_l0_rx_ls_bit", "mphy_l0_tx_symb", "mphy_l0_tx_ls_3xbit", "mphy_l0_rx_ana", "mphy_l1_rx_ana", "mphy_iobist", "mphy_tx_1mhz_ref", "mphy_core_pll_fixed", "uphy_pll0_pwrseq", "uphy_pll1_pwrseq", "pex_sata_usb_rx_byp", "pex_usb_pad0_mgmt", "pex_usb_pad1_mgmt", "tach", "pllp_out0", "pllp_out5", "pllp", "pllp_div8", "plla", "plla1", "pll_a_out0", "pll_a_out1", "pllc", "pllc_out_isp", "pllc_out_ve", "pllc_out_aon", "pllc2", "pllc3", "pllc4_vco", "pllc4_out", "pllc4_out0", "pllc4_out1", "pllc4_out2", "pllc4_out_mux", "pll_d", "pll_d_out1", "pll_d2", "pll_d3", "pll_dp", "plle", "pllrefe_out", "pllrefe_pll_ref", "pllrefe_out_gated", "pllrefe_out1", "pllrefe_vco", "pllu", "pllu_48M", "pllu_480M"; + status = "disabled"; + reset-names = "uarta", "uartb", "uartc", "uartd", "uarte", "uartf", "uartg", "ape", "dmic5", "aud_mclk", "nvcsi", "vi", "isp", "extperiph1", "extperiph2", "extperiph3", "extperiph4", "sata", "qspi", "spi1", "spi2", "spi3", "spi4", "i2c1", "i2c2", "i2c3", "i2c4", "i2c5", "i2c6", "i2c7", "i2c8", "i2c9", "i2c10", "i2c12", "i2c13", "i2c14", "sdmmc1", "sdmmc2", "sdmmc3", "sdmmc4", "xusb_dev", "xusb_host", "xusb_ss", "axi_cbb", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7", "pwm8", "ufshc", "mphy_iobist", "tach"; + }; + }; + + tegra_udrm { + compatible = "nvidia,tegra-udrm"; + phandle = <0x1e7>; + linux,phandle = <0x1e7>; + }; + + kfuse@0x3830000 { + compatible = "nvidia,tegra186-kfuse"; + clocks = <0x10 0x125>; + clock-names = "kfuse"; + status = "okay"; + reg = <0x0 0x3830000 0x0 0x10000>; + }; + + usb_cd { + compatible = "nvidia,tegra186-usb-cd"; + phy-names = "otg-phy"; + status = "okay"; + phandle = <0xaf>; + phys = <0x9e>; + nvidia,xusb-padctl = <0x9f>; + linux,phandle = <0xaf>; + }; + + eeprom-manager { + boardid-with-revision = <0xcee>; + boardid-with-config = <0xcee>; + data-size = <0x100>; + + bus@2 { + i2c-bus = <0x106>; + + eeprom@0 { + slave-address = <0x50>; + }; + }; + + bus@0 { + i2c-bus = <0x174>; + + eeprom@0 { + label = "cvm"; + slave-address = <0x50>; + }; + + eeprom@1 { + label = "cvb"; + slave-address = <0x57>; + }; + }; + + bus@3 { + i2c-bus = <0x59>; + + eeprom@0 { + label = "cam"; + slave-address = <0x54>; + enable-gpio = <0x2 0x9>; + }; + + eeprom@1 { + label = "cam"; + slave-address = <0x57>; + enable-gpio = <0x2 0x9>; + }; + }; + + bus@1 { + i2c-bus = <0x175>; + + eeprom@0 { + slave-address = <0x51>; + }; + }; + }; + + interrupt-controller@3881000 { + compatible = "arm,cortex-a15-gic"; + status = "okay"; + #interrupt-cells = <0x3>; + interrupts = <0x1 0x9 0xf04>; + phandle = <0x1>; + reg = <0x0 0x3881000 0x0 0x1000 0x0 0x3882000 0x0 0x2000>; + linux,phandle = <0x1>; + interrupt-controller; + }; + + pfsd { + pwm_id = <0x3>; + active_steps = <0xa>; + state_cap = <0x7>; + num_resources = <0x0>; + active_rrd = <0x28 0x2 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1>; + pwm_gpio = <0x28 0x16 0x1>; + status = "okay"; + step_time = <0x64>; + active_rru = <0x28 0x2 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1>; + active_rpm = <0x0 0x3e8 0x7d0 0xbb8 0xfa0 0x1388 0x1770 0x1b58 0x2710 0x2af8>; + pwm_period = <0xb116>; + phandle = <0xed>; + rpm_diff_tolerance = <0x2>; + active_pwm_max = <0x100>; + state_cap_lookup = <0x2 0x2 0x2 0x2 0x3 0x3 0x3 0x4 0x4 0x4>; + linux,phandle = <0xed>; + tach_period = <0x3e8>; + secret = <0x2f>; + }; + + tegra-serr { + compatible = "nvidia,tegra186"; + }; + + mc_sid@2c00000 { + compatible = "nvidia,tegra186-mc-sid"; + status = "okay"; + reg = <0x0 0x2c00000 0x0 0x10000 0x0 0x2c10000 0x0 0x10000>; + }; + + mttcan@c320000 { + gpio_can_stb = <0x28 0x2e 0x0>; + compatible = "nvidia,tegra186-mttcan"; + clocks = <0x10 0xd4 0x10 0xd5 0x10 0x214>; + resets = <0x10 0x3d>; + reg-names = "can-regs", "glue-regs", "msg-ram"; + clock-names = "can", "can_host", "pllaon"; + rx-config = <0x40 0x40 0x40>; + pll_source = "pllaon"; + mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>; + status = "okay"; + interrupts = <0x0 0x2a 0x4>; + phandle = <0x1d7>; + reg = <0x0 0xc320000 0x0 0x400 0x0 0xc321000 0x0 0x32 0x0 0xc322000 0x0 0x1000>; + gpio_can_en = <0x28 0x2f 0x0>; + reset-names = "can"; + linux,phandle = <0x1d7>; + tx-config = <0x0 0x10 0x0 0x40>; + }; + + mailbox@3538000 { + compatible = "nvidia,tegra186-xusb-mbox"; + #mbox-cells = <0x0>; + status = "okay"; + interrupts = <0x0 0xa4 0x4>; + phandle = <0xb0>; + reg = <0x0 0x3538000 0x0 0x1000>; + linux,phandle = <0xb0>; + }; + + ahci-sata@3507000 { + gpios = <0x22 0x7 0x0>; + power-domains = <0x1f 0xa>; + compatible = "nvidia,tegra186-ahci-sata"; + clocks = <0x10 0x63 0x10 0x64 0x10 0x204 0x10 0x10d>; + iommu_sodev_map; + resets = <0x10 0x1f 0x10 0x20>; + reg-names = "sata-ahci", "sata-config", "sata-ipfs", "sata-aux"; + pinctrl-1 = <0x21>; + clock-names = "sata", "sata-oob", "pllp", "pllp-uphy"; + status = "okay"; + interrupts = <0x0 0xc5 0x4>; + phandle = <0x105>; + nvidia,disable-features = "devslp", "dipm"; + reg = <0x0 0x3507000 0x0 0x2000 0x0 0x3501000 0x0 0x6000 0x0 0x3500000 0x0 0x1000 0x0 0x3a90000 0x0 0x10000>; + iommus = <0x11 0x1d>; + pinctrl-0 = <0x20>; + nvidia,link-flags = "min_power"; + reset-names = "sata", "sata-cold"; + linux,phandle = <0x105>; + pinctrl-names = "devslp_active", "devslp_pullup"; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x52c 0xffffffff 0x31ce0 0x1 0x338 0x10000000 0x10000000>; + }; + }; + }; + + tegra_skin_thermal { + io-channels = <0xf0 0x0 0xf0 0x1 0xf1 0x3>; + compatible = "nvidia,tegra-skin-thermal"; + io-channel-names = "gpu-voltage", "gpu-current", "vddin-power"; + #thermal-sensor-cells = <0x1>; + + power_feature@1 { + rc_k = <0x1>; + type = <0x1>; + resistance = <0x1>; + phandle = <0xf4>; + linux,phandle = <0xf4>; + #power-feature-cells = <0x1>; + }; + + skin-sensor@2 { + thermal-sensor = <0x2>; + hotspot-list = <0xf8>; + }; + + hotspot@2 { + offset = <0x3>; + rc_k = <0x1>; + phandle = <0xf8>; + power-features-list = <0xf2 0xf3 0xf4 0x2>; + reference-sensor = <0xf5>; + linux,phandle = <0xf8>; + }; + + skin-sensor@0 { + thermal-sensor = <0x0>; + hotspot-list = <0xf6 0xf7>; + }; + + hotspot@0 { + offset = <0x3>; + rc_k = <0x1>; + phandle = <0xf6>; + power-features-list = <0xf2 0xf3 0xf4 0x0 0xf4 0x1>; + reference-sensor = <0xf5>; + linux,phandle = <0xf6>; + }; + + power_feature@0 { + rc_k = <0x1>; + type = <0x0>; + resistance = <0x1>; + phandle = <0xf2>; + linux,phandle = <0xf2>; + #power-feature-cells = <0x1>; + }; + + skin-sensor@1 { + thermal-sensor = <0x1>; + hotspot-list = <0xf7>; + }; + + hotspot@1 { + offset = <0x3>; + rc_k = <0x1>; + phandle = <0xf7>; + power-features-list = <0xf2 0xf3>; + reference-sensor = <0xf5>; + linux,phandle = <0xf7>; + }; + }; + + tpiu@8060000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8060000 0x0 0x1000>; + + port { + + enpoint@0 { + remote-endpoint = <0xe3>; + phandle = <0xdf>; + slave-mode; + linux,phandle = <0xdf>; + }; + }; + }; + + xusb_padctl@3520000 { + pinctrl-5 = <0xa7>; + compatible = "nvidia,tegra18x-xusb-padctl"; + avdd_pll_erefeut-supply = <0x12>; + pinctrl-3 = <0xa5>; + resets = <0x10 0x37>; + reg-names = "padctl", "ao"; + pinctrl-1 = <0xa3>; + status = "okay"; + pinctrl-4 = <0xa6>; + phandle = <0x9f>; + vclamp_usb-supply = <0x12>; + pinctrl-2 = <0xa4>; + reg = <0x0 0x3520000 0x0 0x1000 0x0 0x3540000 0x0 0x1000>; + pinctrl-0 = <0xa2>; + reset-names = "padctl"; + avdd_usb-supply = <0x13>; + linux,phandle = <0x9f>; + pinctrl-names = "vbus_en0_default", "vbus_en1_default", "vbus_en0_sfio_tristate", "vbus_en1_sfio_tristate", "vbus_en0_sfio_passthrough", "vbus_en1_sfio_passthrough"; + + prod-settings { + #prod-cells = <0x4>; + + prod_c_hsic0 { + prod = <0x0 0x344 0x7f 0x2d>; + }; + + prod_c_utmi1 { + prod = <0x0 0xc8 0x1fe0000 0xcc0000>; + }; + + prod_c_bias { + prod = <0x0 0x284 0x38 0x38>; + }; + + prod_c_utmi2 { + prod = <0x0 0x108 0x1fe0000 0xcc0000>; + }; + + prod_c_utmi0 { + prod = <0x0 0x88 0x1fe0000 0xcc0000>; + }; + }; + + ports { + + usb3-0 { + status = "okay"; + nvidia,usb2-companion = <0x1>; + }; + + hsic-0 { + status = "disabled"; + }; + + usb2-2 { + vbus-supply = <0xaa>; + mode = "host"; + status = "okay"; + }; + + usb2-0 { + vbus-supply = <0xa8>; + mode = "otg"; + status = "okay"; + nvidia,oc-pin = <0x0>; + }; + + usb3-1 { + status = "disabled"; + nvidia,usb2-companion = <0x1>; + }; + + usb2-1 { + vbus-supply = <0xa9>; + mode = "host"; + status = "okay"; + nvidia,oc-pin = <0x1>; + }; + + usb3-2 { + status = "disabled"; + }; + }; + + pads { + + usb3 { + + lanes { + + usb3-0 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0xae>; + #phy-cells = <0x0>; + linux,phandle = <0xae>; + }; + + usb3-1 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0x108>; + #phy-cells = <0x0>; + linux,phandle = <0x108>; + }; + + usb3-2 { + status = "okay"; + nvidia,function = "xusb"; + #phy-cells = <0x0>; + }; + }; + }; + + hsic { + clocks = <0x10 0x86>; + clock-names = "trk"; + status = "disabled"; + + lanes { + + hsic-0 { + status = "disabled"; + #phy-cells = <0x0>; + }; + }; + }; + + usb2 { + clocks = <0x10 0x87>; + clock-names = "trk"; + + lanes { + + usb2-2 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0xad>; + #phy-cells = <0x0>; + linux,phandle = <0xad>; + }; + + usb2-0 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0x9e>; + #phy-cells = <0x0>; + linux,phandle = <0x9e>; + }; + + usb2-1 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0xac>; + #phy-cells = <0x0>; + linux,phandle = <0xac>; + }; + }; + }; + }; + }; + + tegra_cec { + compatible = "nvidia,tegra186-cec"; + clocks = <0x10 0x5e>; + clock-names = "cec"; + status = "okay"; + interrupts = <0x0 0xa2 0x4>; + reg = <0x0 0x3960000 0x0 0x1000>; + }; + + __symbols__ { + e3331_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + aon = "/aon@c160000"; + L2_A57 = "/cpus/l2-cache0"; + csi_chan0 = "/host1x/nvcsi@150c0000/channel@0"; + e2614_i2c_mux = "/i2c@c240000/i2cmux@70"; + vdd_hdmi = "/fixed-regulators/regulator@3"; + spdif_dit3 = "/spdif_dit/spdif-dit.3@3"; + cam_module3 = "/tegra-camera-platform/modules/module3"; + dsic_dpd_disable = "/pmc@c360000/dsic-dpd-disable"; + tegra_sce_ivc = "/sce-ivc-channels"; + tegra_dmic1 = "/aconnect@2a41000/ahub/dmic@2904000"; + en_vdd_vcm_2v8 = "/fixed-regulators/regulator@16"; + cam_module1_drivernode0 = "/tegra-camera-platform/modules/module1/drivernode0"; + tegra_amx3 = "/aconnect@2a41000/ahub/amx@2903200"; + e3333_vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + ptm_a57_0_out_port = "/ptm@9840000/port/endpoint"; + spmic_ldo4 = "/bpmp_i2c/spmic@3c/regulators/ldo4"; + tegra_xusb_padctl = "/pinctrl@3520000"; + liimx274_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + spdif_dit10 = "/spdif_dit/spdif-dit.10@a"; + disa_pd = "/power-domain/disa-pd"; + dp_aux_ch0_i2c = "/i2c@31b0000"; + e3333_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + tca6408_21 = "/i2c@3180000/tca6408@21"; + funnel_major_in_port3 = "/funnel_major@8010000/ports/port@4/endpoint"; + tegra_pmc_iopower = "/pmc-iopower"; + eqos_m40 = "/thermal-zones/GPU-therm/trips/eqos-m40@-40000"; + e3333_cam1 = "/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36"; + vpr = "/reserved-memory/vpr-carveout"; + head2 = "/host1x/nvdisplay@15220000"; + dsib_dpd_enable = "/pmc@c360000/dsib-dpd-enable"; + csi_chan0_port1 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1"; + intc = "/interrupt-controller@3881000"; + en_avdd_disp_3v3 = "/fixed-regulators/regulator@8"; + panel_s_edp_uhdtv_15_6_bl = "/backlight/panel-s-edp-uhdtv-15-6-bl"; + ina3221x_40 = "/i2c@3160000/ina3221x@40"; + e3333_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + tegra_asrc = "/aconnect@2a41000/ahub/asrc@2910000"; + tca9546_70 = "/i2c@3180000/tca9546@70"; + gpio_i2c_0_74 = "/i2c@3160000/gpio@74"; + liimx185_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + xusb_padctl = "/xusb_padctl@3520000"; + tegra_i2s1 = "/aconnect@2a41000/ahub/i2s@2901000"; + dspk_2_dai_link = "/sound/nvidia,dai-link-13"; + denver_1 = "/cpus/cpu@1"; + panel_s_wuxga_8_0 = "/host1x/dsi/panel-s-wuxga-8-0"; + cpu_a57_1 = "/cpus/cpu@3"; + cam_module4_drivernode1 = "/tegra-camera-platform/modules/module4/drivernode1"; + spi2 = "/spi@3230000"; + sdmmc2_e_33V_enable = "/pmc@c360000/sdmmc2_e_33V_enable"; + sdmmc2_e_33V_disable = "/pmc@c360000/sdmmc2_e_33V_disable"; + vdd_usb2_5v = "/fixed-regulators/regulator@17"; + tegra_pwm7 = "/pwm@32e0000"; + tegra_xusb_padctl_pinmux_default = "/pinctrl@3520000/pinmux"; + imx274_cam1 = "/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a"; + funnel_minor_in_port0 = "/funnel_minor@8820000/ports/port@2/endpoint"; + en_mdm_pwr_3v7 = "/fixed-regulators/regulator@9"; + vbus_en1_sfio_tristate_state = "/pinmux@2430000/vbus_en1_oc_tristate"; + gen1_i2c = "/i2c@3160000"; + csi_chan3_port1 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1"; + e2614_icm20628 = "/i2c@c240000/icm20628@68"; + vi_port2 = "/host1x/vi@15700000/ports/port@2"; + eqos_m5 = "/thermal-zones/GPU-therm/trips/eqos-m5@-5000"; + aotag = "/thermal-zones/AO-therm"; + tegra_safety_ivc = "/tegra_safety_ivc"; + spdif_dit1 = "/spdif_dit/spdif-dit.1@1"; + e3323_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + cam_module1 = "/tegra-camera-platform/modules/module1"; + pf_iio_ina3221 = "/tegra_skin_thermal/power_feature@1"; + liimx274_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + host1x_ctx7 = "/host1x/ctx7"; + tegra_amx1 = "/aconnect@2a41000/ahub/amx@2903000"; + e3333_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + tegra_iqc1 = "/aconnect@2a41000/ahub/iqc@290e000"; + sdmmc3 = "/sdhci@3440000"; + lp8556_backlight = "/i2c@c240000/lp8556-backlight-s-wqxga-10-1@2c"; + ufs_dpd_disable = "/pmc@c360000/dpd-disable"; + spmic_ldo2 = "/bpmp_i2c/spmic@3c/regulators/ldo2"; + pcie_pd = "/power-domain/pcie-pd"; + tegra_aon_gpio = "/gpio@c2f0000"; + eqos_p65 = "/thermal-zones/GPU-therm/trips/eqos-p65@65000"; + uartf = "/serial@3150000"; + hdmi_dp1_dpd_enable = "/pmc@c360000/hdmi-dp1-dpd-enable"; + funnel_major_out_port0 = "/funnel_major@8010000/ports/port@0/endpoint"; + replicator_out_port1 = "/replicator@0x8040000/ports/port@1/endpoint"; + bpmpthermal = "/bpmp/bpmpthermal"; + funnel_major_in_port1 = "/funnel_major@8010000/ports/port@2/endpoint"; + ptm_a57_2 = "/ptm@9a40000"; + head0 = "/host1x/nvdisplay@15200000"; + liimx185_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + tegra_xotg = "/xotg"; + sor1_hdmi_display = "/host1x/sor1/hdmi-display"; + tegra_dspk1 = "/aconnect@2a41000/ahub/dspk@2905000"; + ser_b = "/i2c@3180000/tca9546@70/i2c@0/max9295_b@60"; + e3322_csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + fb2_reserved = "/reserved-memory/fb2_carveout"; + dsi = "/host1x/dsi"; + spi0 = "/spi@3210000"; + gen9_i2c = "/i2c@31e0000"; + sor0_dp_display = "/host1x/sor/dp-display"; + csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + tegra_wdt = "/watchdog@30c0000"; + csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + tegra_pwm5 = "/pwm@32c0000"; + e3333_ov5693_out5 = "/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36/ports/port@0/endpoint"; + xusbb_pd = "/power-domain/xusbb-pd"; + A57_CORE_POWER_STATES = "/cpus/a57_core_power_states"; + dser = "/i2c@3180000/tca9546@70/i2c@0/max9296@48"; + e3323_ov23850_out0 = "/i2c@3180000/ov23850_a@10/ports/port@0/endpoint"; + tegra_afc5 = "/aconnect@2a41000/ahub/afc@2907400"; + vi_port0 = "/host1x/vi@15700000/ports/port@0"; + e3322_cam4 = "/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + eqos_tx_tri_state_idle = "/pinmux@2430000/eqos_idle"; + tegra_adx4 = "/aconnect@2a41000/ahub/adx@2903b00"; + e3326_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + tegra_xhci = "/xhci@3530000"; + host1x_ctx5 = "/host1x/ctx5"; + DENVER_C7 = "/cpus/denver_core_power_states/c7"; + sdmmc1 = "/sdhci@3400000"; + spmic_ldo0 = "/bpmp_i2c/spmic@3c/regulators/ldo0"; + dsid_dpd_disable = "/pmc@c360000/dsid-dpd-disable"; + imx390_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + e3322_imx219_out5 = "/i2c@3180000/tca9548@77/i2c@5/imx219_f@10/ports/port@0/endpoint"; + cam_module2_drivernode0 = "/tegra-camera-platform/modules/module2/drivernode0"; + tegra_amixer = "/aconnect@2a41000/ahub/amixer@290bb00"; + ape_hsp = "/aconnect@2a41000/tegra-hsp@29a0000"; + eqos_cool_dev = "/ether_qos@2490000/eqos-cool-dev"; + uartd = "/serial@3130000"; + pwr_i2c = "/bpmp_i2c"; + imx390_cam1 = "/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + tegra_sce = "/rtcpu@b000000"; + ptm_a57_0 = "/ptm@9840000"; + tegra_mvc1 = "/aconnect@2a41000/ahub/mvc@290a000"; + e3323_cam0 = "/i2c@3180000/ov23850_a@10"; + dsic_dpd_enable = "/pmc@c360000/dsic-dpd-enable"; + sce_hsp = "/tegra-hsp@b150000"; + dummy_cool_dev = "/dummy-cool-dev"; + vdd_fan = "/fixed-regulators/regulator@13"; + vdd_1v8_aud2 = "/fixed-regulators/regulator@200"; + e3322_csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + tegra_ext_cdp = "/max16984-cdp"; + funnel_bccplex_in_port0 = "/funnel_bccplex@9010000/ports/port@1/endpoint"; + csi_base = "/host1x/nvcsi@150c0000"; + e2614_gps_wake = "/gps_wake"; + dpaux0 = "/host1x/dpaux@155c0000"; + e3322_csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + pwm_fan_shared_data = "/pfsd"; + pinmux = "/pinmux@2430000"; + csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + camera_as = "/iommu@12000000/address-space-prop/camera"; + csi_chan5 = "/host1x/nvcsi@150c0000/channel@5"; + cam_module0_drivernode1 = "/tegra-camera-platform/modules/module0/drivernode1"; + csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + tegra_pwm3 = "/pwm@32a0000"; + qspi6 = "/spi@3270000"; + cam_module5_drivernode1 = "/tegra-camera-platform/modules/module5/drivernode1"; + tegra_udrm = "/tegra_udrm"; + spdif_dit8 = "/spdif_dit/spdif-dit.8@8"; + tegra_ufs = "/ufshci@2450000"; + sdmmc3_e_33V_enable = "/pmc@c360000/sdmmc3_e_33V_enable"; + mipical_prod_c_dphy_dsi_soc_a01 = "/mipical/prod-settings/prod_c_dphy_dsi/soc_a01"; + e3333_ov5693_out3 = "/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36/ports/port@0/endpoint"; + spmic_sd2 = "/bpmp_i2c/spmic@3c/regulators/sd2"; + pcie_as = "/iommu@12000000/address-space-prop/pcie_as"; + vi_base = "/host1x/vi@15700000"; + tegra_afc3 = "/aconnect@2a41000/ahub/afc@2907200"; + mipical_prod_c_cphy_csi_soc_a01 = "/mipical/prod-settings/prod_c_cphy_csi/soc_a01"; + dp_aux_ch1_i2c = "/i2c@3190000"; + e3322_cam2 = "/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + csi_chan2_port0 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0"; + e3333_csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + tegra_adx2 = "/aconnect@2a41000/ahub/adx@2903900"; + e3323_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + host1x_ctx3 = "/host1x/ctx3"; + liimx274_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + en_vdd_cam_1v2 = "/fixed-regulators/regulator@12"; + imx390_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + sdmmc3_e_33V_disable = "/pmc@c360000/sdmmc3_e_33V_disable"; + tegra_xudc = "/xudc@3550000"; + e3322_imx219_out3 = "/i2c@3180000/tca9548@77/i2c@3/imx219_d@10/ports/port@0/endpoint"; + A57_C7 = "/cpus/a57_core_power_states/c7"; + sor1 = "/host1x/sor1"; + e3326_ov5693_out0 = "/i2c@3180000/ov5693_c@36/ports/port@0/endpoint"; + imx390_imx390_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b/ports/port@0/endpoint"; + uartb = "/serial@3110000"; + tegra_ope1 = "/aconnect@2a41000/ahub/ope@2908000"; + e3322_vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + tegra_i2s6 = "/aconnect@2a41000/ahub/i2s@2901500"; + ptm_a57_1_out_port = "/ptm@9940000/port/endpoint"; + spmic_default = "/bpmp_i2c/spmic@3c/pinmux@0"; + vdd_3v3 = "/fixed-regulators/regulator@14"; + tegra_adsp_audio = "/aconnect@2a41000/adsp_audio"; + generic_reserved = "/reserved-memory/generic_carveout"; + csi_chan5_port0 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0"; + hdr40_i2c1 = "/i2c@c240000"; + tegra_sfc4 = "/aconnect@2a41000/ahub/sfc@2902600"; + pf_backlight = "/tegra_skin_thermal/power_feature@0"; + e3322_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + tegra_sound = "/sound"; + disc_pd = "/power-domain/disc-pd"; + xusb_mbox = "/mailbox@3538000"; + vpp_lcd = "/i2c@3160000/tps65132@3e/outp"; + gen2_i2c = "/i2c@c240000"; + e3322_csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + liimx274_imx274_out1 = "/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a/ports/port@0/endpoint"; + adsp_pd = "/power-domain/adsp-pd"; + e3323_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + rt565x_dai_link = "/sound/nvidia,dai-link-1"; + csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + csi_chan3 = "/host1x/nvcsi@150c0000/channel@3"; + csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + tegra_pwm1 = "/pwm@3280000"; + spdif_dit6 = "/spdif_dit/spdif-dit.6@6"; + ser_prim = "/i2c@3180000/tca9546@70/i2c@0/max9295_prim@62"; + sor1_dp_display = "/host1x/sor1/dp-display"; + tegra_dmic4 = "/aconnect@2a41000/ahub/dmic@2904300"; + e3333_ov5693_out1 = "/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36/ports/port@0/endpoint"; + mttcan0 = "/mttcan@c310000"; + spmic_sd0 = "/bpmp_i2c/spmic@3c/regulators/sd0"; + hdr40_snd_link_i2s = "/sound/nvidia,dai-link-1"; + spmic_ldo7 = "/bpmp_i2c/spmic@3c/regulators/ldo7"; + ape_pd = "/power-domain/ape-pd"; + tegra_spkprot = "/aconnect@2a41000/ahub/spkprot@2908c00"; + hdr40_vdd_3v3 = "/fixed-regulators/regulator@14"; + tegra_sata = "/ahci-sata@3507000"; + tegra_afc1 = "/aconnect@2a41000/ahub/afc@2907000"; + spdif_dit13 = "/spdif_dit/spdif-dit.13@d"; + e3322_cam0 = "/i2c@3180000/tca9548@77/i2c@0/imx219_a@10"; + e3333_csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + tegra_tmp451 = "/i2c@c250000/temp-sensor@4c"; + etr_in_port = "/etr@8050000/port/endpoint@0"; + e3333_cam4 = "/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36"; + csi_chan1_port1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1"; + host1x_ctx1 = "/host1x/ctx1"; + tegra_pinctrl = "/pinmux@2430000"; + tegra_axbar = "/aconnect@2a41000/ahub"; + e3322_imx219_out1 = "/i2c@3180000/tca9548@77/i2c@1/imx219_b@10/ports/port@0/endpoint"; + e3333_csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + vdd_usb1_5v = "/fixed-regulators/regulator@5"; + cam_module3_drivernode0 = "/tegra-camera-platform/modules/module3/drivernode0"; + devslp_pullup_state = "/pinmux@2430000/devslp_pullup"; + hdr40_vdd_5v0 = "/fixed-regulators/regulator@0"; + gpio_i2c_0_77 = "/i2c@3160000/gpio@77"; + e3322_vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + tegra_i2s4 = "/aconnect@2a41000/ahub/i2s@2901300"; + e3331_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + hs1 = "/tegra_skin_thermal/hotspot@1"; + liimx185_imx185_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a/ports/port@0/endpoint"; + funnel_bccplex_out_port0 = "/funnel_bccplex@9010000/ports/port@0/endpoint"; + tegra_agic_2 = "/aconnect@2a41000/agic-controller@2a61000"; + tegra_sfc2 = "/aconnect@2a41000/ahub/sfc@2902200"; + csi_chan4_port1 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1"; + dsid_dpd_enable = "/pmc@c360000/dsid-dpd-enable"; + e3322_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + imx390_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + tegra_aowake = "/pmc@c370000"; + vi_port5 = "/host1x/vi@15700000/ports/port@5"; + csi_chan1 = "/host1x/nvcsi@150c0000/channel@1"; + e2614_tas2552_l = "/i2c@c240000/i2cmux@70/i2c@0/tas2552.9-0041@41"; + spdif_dit4 = "/spdif_dit/spdif-dit.4@4"; + cam_module4 = "/tegra-camera-platform/modules/module4"; + e2614_gpio_i2c_1_20 = "/i2c@c240000/gpio@20"; + tegra_vi = "/host1x/vi@15700000"; + tegra_dmic2 = "/aconnect@2a41000/ahub/dmic@2904100"; + cam_module1_drivernode1 = "/tegra-camera-platform/modules/module1/drivernode1"; + tegra_amx4 = "/aconnect@2a41000/ahub/amx@2903300"; + e3333_vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + tegra_pcie = "/pcie-controller@10003000"; + soft_wdt = "/soft_watchdog"; + spmic_ldo5 = "/bpmp_i2c/spmic@3c/regulators/ldo5"; + dsi_dpd_enable = "/pmc@c360000/dsi-dpd-enable"; + spmic = "/bpmp_i2c/spmic@3c"; + spdif_dit11 = "/spdif_dit/spdif-dit.11@b"; + e2614_bmp280 = "/i2c@c240000/bmp280@77"; + e3333_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + e3333_cam2 = "/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36"; + vdd_1v8_ap = "/fixed-regulators/regulator@101"; + DENVER_C1 = "/cpus/denver_core_power_states/c1"; + aon_spi = "/aon_spi@c260000"; + vdd_bl_en = "/fixed-regulators/regulator@18"; + panel_s_wqxga_10_1 = "/host1x/dsi/panel-s-wqxga-10-1"; + lp8557_backlight = "/i2c@3160000/lp8557-backlight-s-wuxga-8-0@2c"; + max9295_ser0 = "/i2c@3180000/tca9546@70/i2c@0/max9295_a@40"; + ina3221x_41 = "/i2c@3160000/ina3221x@41"; + en_vdd_ts_hv_3v3 = "/fixed-regulators/regulator@7"; + e3333_csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + spmic_wdt = "/bpmp_i2c/spmic@3c/watchdog"; + e3322_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + tegra_i2s2 = "/aconnect@2a41000/ahub/i2s@2901100"; + cpu_a57_2 = "/cpus/cpu@4"; + xusba_pd = "/power-domain/xusba-pd"; + spi3 = "/spi@3240000"; + dsi_dpd_disable = "/pmc@c360000/dsi-dpd-disable"; + aon_hsp = "/tegra-hsp@c150000"; + hdmi_dp0_dpd_disable = "/pmc@c360000/hdmi-dp0-dpd-disable"; + tegra_pwm8 = "/pwm@32f0000"; + ufs_dpd_enable = "/pmc@c360000/dpd-enable"; + bcm4354 = "/bcmdhd_wlan"; + en_vdd_cam_hv_2v8 = "/fixed-regulators/regulator@11"; + e2614_ak8963 = "/i2c@c240000/ak8963@0d"; + cam_i2c = "/i2c@3180000"; + ape_as = "/iommu@12000000/address-space-prop/ape"; + fb0_reserved = "/reserved-memory/fb0_carveout"; + tca9548_77 = "/i2c@3180000/tca9548@77"; + iopad_default = "/pmc@c360000/iopad-defaults"; + vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + replicator_in_port0 = "/replicator@0x8040000/ports/port@2/endpoint"; + vi_port3 = "/host1x/vi@15700000/ports/port@3"; + vbus_en0_default_state = "/pinmux@2430000/vbus_en0_default"; + spdif_dit2 = "/spdif_dit/spdif-dit.2@2"; + funnel_minor_out_port0 = "/funnel_minor@8820000/ports/port@0/endpoint"; + cam_module2 = "/tegra-camera-platform/modules/module2"; + tegra_amx2 = "/aconnect@2a41000/ahub/amx@2903100"; + e3333_vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + CPU_COST_DENVER = "/energy-costs/core-cost0"; + dis_vdd_1v2 = "/fixed-regulators/regulator@15"; + sdmmc4 = "/sdhci@3460000"; + spmic_ldo3 = "/bpmp_i2c/spmic@3c/regulators/ldo3"; + ptm_bpmp_out_port = "/ptm_bpmp@8a1c000/port/endpoint"; + liimx274_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e2614_cm32180 = "/i2c@c240000/cm32180@48"; + e3326_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e2614_tas2552_r = "/i2c@c240000/i2cmux@70/i2c@0/tas2552.9-0040@40"; + vbus_id_extcon = "/external-connection/extcon@1"; + uartg = "/serial@c290000"; + funnel_major_in_port2 = "/funnel_major@8010000/ports/port@3/endpoint"; + e3333_cam0 = "/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36"; + ptm_a57_3 = "/ptm@9b40000"; + head1 = "/host1x/nvdisplay@15210000"; + host1x_as = "/iommu@12000000/address-space-prop/host1x"; + IPI = "/interrupt-controller"; + csi_chan0_port0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0"; + en_vdd_sys = "/fixed-regulators/regulator@118"; + A57_C1 = "/cpus/a57_core_power_states/c1"; + tegra_dspk2 = "/aconnect@2a41000/ahub/dspk@2905100"; + e3333_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3322_csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + denver_0 = "/cpus/cpu@0"; + cpu_a57_0 = "/cpus/cpu@2"; + cam_module4_drivernode0 = "/tegra-camera-platform/modules/module4/drivernode0"; + spi1 = "/spi@c260000"; + ramoops_reserved = "/reserved-memory/ramoops_carveout"; + csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + tegra_pwm6 = "/pwm@32d0000"; + tegra_car = "/clock@5000000"; + imx274_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + ptm_a57_2_out_port = "/ptm@9a40000/port/endpoint"; + e2614_rt5658_i2c3 = "/i2c@c240000/i2cmux@70/i2c@3/rt5659.12-001a@1a"; + e3323_ov23850_out1 = "/i2c@c240000/ov23850_c@36/ports/port@0/endpoint"; + tegra_afc6 = "/aconnect@2a41000/ahub/afc@2907500"; + max9296_dser = "/i2c@3180000/tca9546@70/i2c@0/max9296@48"; + csi_chan3_port0 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0"; + vi_port1 = "/host1x/vi@15700000/ports/port@1"; + e3322_cam5 = "/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + gen7_i2c = "/i2c@31c0000"; + bpmp = "/bpmp"; + spdif_dit0 = "/spdif_dit/spdif-dit.0@0"; + tegra_rtcpu_sce_trace = "/tegra-rtcpu-sce-trace"; + e3323_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + cam_module0 = "/tegra-camera-platform/modules/module0"; + liimx274_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + host1x_ctx6 = "/host1x/ctx6"; + adma = "/aconnect@2a41000/adma@2930000"; + en_vdd_disp_1v8 = "/fixed-regulators/regulator@10"; + e3333_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + panel_s_wuxga_8_0_bl = "/backlight/panel-s-wuxga-8-0-bl"; + tpiu_in_port = "/tpiu@8060000/port/enpoint@0"; + sdmmc2 = "/sdhci@3420000"; + spmic_ldo1 = "/bpmp_i2c/spmic@3c/regulators/ldo1"; + cam_module2_drivernode1 = "/tegra-camera-platform/modules/module2/drivernode1"; + tcp = "/tegra-camera-platform"; + host1x = "/host1x"; + vbus_en0_sfio_passthrough_state = "/pinmux@2430000/vbus_en0_oc_passthrough"; + uarte = "/serial@3140000"; + tegra_usb_cd = "/usb_cd"; + replicator_out_port0 = "/replicator@0x8040000/ports/port@0/endpoint"; + funnel_major_in_port0 = "/funnel_major@8010000/ports/port@1/endpoint"; + vbus_en0_sfio_tristate_state = "/pinmux@2430000/vbus_en0_oc_tristate"; + pinmux_default = "/pinmux@2430000/common"; + ptm_a57_1 = "/ptm@9940000"; + panel_s_edp_uhdtv_15_6 = "/host1x/sor/panel-s-edp-uhdtv-15-6"; + tegra_mvc2 = "/aconnect@2a41000/ahub/mvc@290a200"; + common_as = "/iommu@12000000/address-space-prop/common"; + disb_pd = "/power-domain/disb-pd"; + e3323_cam1 = "/i2c@c240000/ov23850_c@36"; + host1x_client_as = "/iommu@12000000/address-space-prop/host1x_client"; + sata_pd = "/power-domain/sata-pd"; + ser_a = "/i2c@3180000/tca9546@70/i2c@0/max9295_a@40"; + e3322_csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + thermal_fan_est_shared_data = "/tfesd"; + tegra_rtcpu_ape_trace = "/tegra-rtcpu-ape-trace"; + funnel_bccplex_in_port1 = "/funnel_bccplex@9010000/ports/port@2/endpoint"; + etf_in_port = "/etf@8030000/ports/port@0/endpoint"; + panel_s_wqxga_10_1_bl = "/backlight/panel-s-wqxga-10-1-bl"; + dpaux1 = "/host1x/dpaux@15040000"; + csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + tegra_pwm4 = "/pwm@c340000"; + spdif_dit9 = "/spdif_dit/spdif-dit.9@9"; + tegra_agic = "/aconnect@2a41000/agic-controller@2a41000"; + gpcdma = "/dma@2600000"; + e2614_rt5658 = "/i2c@c240000/rt5659.1-001a@1a"; + hdmi_dp1_dpd_disable = "/pmc@c360000/hdmi-dp1-dpd-disable"; + e3333_ov5693_out4 = "/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36/ports/port@0/endpoint"; + tegra_tachometer = "/tachometer@39c0000"; + spmic_sd3 = "/bpmp_i2c/spmic@3c/regulators/sd3"; + tegra_afc4 = "/aconnect@2a41000/ahub/afc@2907300"; + L2_DENVER = "/cpus/l2-cache1"; + e3322_cam3 = "/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + csi_chan2_port1 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1"; + tegra_adx3 = "/aconnect@2a41000/ahub/adx@2903a00"; + e3323_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + host1x_ctx4 = "/host1x/ctx4"; + DENVER_C6 = "/cpus/denver_core_power_states/c6"; + liimx274_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + vdd_usb0_5v = "/fixed-regulators/regulator@4"; + smmu_test = "/smmu_test"; + dspk_1_dai_link = "/sound/nvidia,dai-link-12"; + imx390_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + imx390_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e3322_imx219_out4 = "/i2c@3180000/tca9548@77/i2c@4/imx219_e@10/ports/port@0/endpoint"; + imx390_imx390_out1 = "/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c/ports/port@0/endpoint"; + tegra_safety = "/sce@b000000"; + uartc = "/serial@c280000"; + en_vdd_cam = "/fixed-regulators/regulator@2"; + panel_a_edp_1080p_14_0_bl = "/backlight/panel-a-edp-1080p-14-0-bl"; + e3322_vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + battery_reg = "/fixed-regulators/regulator@0"; + imx390_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b"; + tegra_admaif = "/aconnect@2a41000/ahub/admaif@290f000"; + disp_imp_table = "/host1x/disp_imp_table"; + vbus_en1_default_state = "/pinmux@2430000/vbus_en1_default"; + e3326_cam0 = "/i2c@3180000/ov5693_c@36"; + bcm4359 = "/bcmdhd_pcie_wlan"; + CPU_COST_A57 = "/energy-costs/core-cost1"; + csi_chan5_port1 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1"; + e3322_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + etf_out_port = "/etf@8030000/ports/port@1/endpoint"; + pm_irq = "/tegra186-pm-irq"; + e3322_csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + e3323_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + dsib_dpd_disable = "/pmc@c360000/dsib-dpd-disable"; + csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + csi_chan4 = "/host1x/nvcsi@150c0000/channel@4"; + cam_module0_drivernode0 = "/tegra-camera-platform/modules/module0/drivernode0"; + csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + phy0 = "/ether_qos@2490000/mdio/ethernet-phy@0"; + tegra_pwm2 = "/pwm@3290000"; + cam_module5_drivernode0 = "/tegra-camera-platform/modules/module5/drivernode0"; + spdif_dit7 = "/spdif_dit/spdif-dit.7@7"; + eqos_tx_tri_state_default = "/pinmux@2430000/eqos_default"; + dma_test = "/dma_test"; + e3333_ov5693_out2 = "/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36/ports/port@0/endpoint"; + mttcan1 = "/mttcan@c320000"; + spmic_sd1 = "/bpmp_i2c/spmic@3c/regulators/sd1"; + spmic_ldo8 = "/bpmp_i2c/spmic@3c/regulators/ldo8"; + vmm_lcd = "/i2c@3160000/tps65132@3e/outn"; + tegra_afc2 = "/aconnect@2a41000/ahub/afc@2907100"; + sdmmc1_e_33V_disable = "/pmc@c360000/sdmmc1_e_33V_disable"; + e3322_cam1 = "/i2c@3180000/tca9548@77/i2c@1/imx219_b@10"; + xusbc_pd = "/power-domain/xusbc-pd"; + gpio_i2c_0_21 = "/i2c@3160000/gpio@21"; + e3333_csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + tegra_adx1 = "/aconnect@2a41000/ahub/adx@2903800"; + Tboard_tegra = "/thermal-zones/Tboard_tegra"; + e3333_cam5 = "/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36"; + fb1_reserved = "/reserved-memory/fb1_carveout"; + host1x_ctx2 = "/host1x/ctx2"; + tegra_arad = "/aconnect@2a41000/ahub/arad@290e400"; + lic = "/interrupt-controller@3000000"; + tegra_ahc = "/aconnect@2a41000/ahub/ahc@290b900"; + e3322_imx219_out2 = "/i2c@3180000/tca9548@77/i2c@2/imx219_c@10/ports/port@0/endpoint"; + sor0 = "/host1x/sor"; + e3333_csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + sdmmc1_e_33V_enable = "/pmc@c360000/sdmmc1_e_33V_enable"; + cam_module3_drivernode1 = "/tegra-camera-platform/modules/module3/drivernode1"; + uarta = "/serial@3100000"; + e3322_vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + tegra_i2s5 = "/aconnect@2a41000/ahub/i2s@2901400"; + hs2 = "/tegra_skin_thermal/hotspot@2"; + DENVER_CORE_POWER_STATES = "/cpus/denver_core_power_states"; + e2614_iqs263 = "/i2c@c240000/iqs263@44"; + liimx185_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3331_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx318_a@10"; + hdr40_i2c0 = "/i2c@3160000"; + tegra_sfc3 = "/aconnect@2a41000/ahub/sfc@2902400"; + mipical_prod_c_dphy_csi_soc_a01 = "/mipical/prod-settings/prod_c_dphy_csi/soc_a01"; + e3326_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + e3322_csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + imx390_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + liimx274_imx274_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a/ports/port@0/endpoint"; + gen8_i2c = "/i2c@c250000"; + hsp_top = "/tegra-hsp@3c00000"; + csi_chan2 = "/host1x/nvcsi@150c0000/channel@2"; + en_vdd_sdcard1 = "/fixed-regulators/regulator@1"; + spdif_dit5 = "/spdif_dit/spdif-dit.5@5"; + cam_module5 = "/tegra-camera-platform/modules/module5"; + tegra_dmic3 = "/aconnect@2a41000/ahub/dmic@2904200"; + e3333_ov5693_out0 = "/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36/ports/port@0/endpoint"; + e3333_vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + eqos_p100 = "/thermal-zones/GPU-therm/trips/eqos-p100@100000"; + spmic_ldo6 = "/bpmp_i2c/spmic@3c/regulators/ldo6"; + gpu_as = "/iommu@12000000/address-space-prop/gpu"; + hdmi_dp0_dpd_enable = "/pmc@c360000/hdmi-dp0-dpd-enable"; + spdif_dit12 = "/spdif_dit/spdif-dit.12@c"; + die_temp_thresh = "/thermal-zones/PMIC-Die/trips/hot-die"; + Tdiode_tegra = "/thermal-zones/Tdiode_tegra"; + ptm_a57_3_out_port = "/ptm@9b40000/port/endpoint"; + e3333_csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + sor0_hdmi_display = "/host1x/sor/hdmi-display"; + e3333_cam3 = "/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36"; + csi_chan1_port0 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0"; + host1x_ctx0 = "/host1x/ctx0"; + pca9570_a_24 = "/i2c@3180000/tca9546@70/i2c@0/pca9570_a@24"; + eqos_p30 = "/thermal-zones/GPU-therm/trips/eqos-p30@30000"; + tegra_main_gpio = "/gpio@2200000"; + e3331_imx318_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx318_a@10/ports/port@0/endpoint"; + stm_out_port = "/stm@8070000/port/endpoint"; + se = "/se_elp@3ad0000"; + e3322_imx219_out0 = "/i2c@3180000/tca9548@77/i2c@0/imx219_a@10/ports/port@0/endpoint"; + max9295_ser1 = "/i2c@3180000/tca9546@70/i2c@0/max9295_b@60"; + tegra_pmc = "/pmc@c360000"; + e3333_csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + e3322_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + tegra_i2s3 = "/aconnect@2a41000/ahub/i2s@2901200"; + en_vdd_ts_1v8 = "/fixed-regulators/regulator@6"; + hs0 = "/tegra_skin_thermal/hotspot@0"; + e3331_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + max9295_prim = "/i2c@3180000/tca9546@70/i2c@0/max9295_prim@62"; + panel_a_edp_1080p_14_0 = "/host1x/sor/panel-a-edp-1080p-14-0"; + cpu_a57_3 = "/cpus/cpu@5"; + smmu = "/iommu@12000000"; + tegra_ape = "/aconnect@2a41000/rtcpu@2993000"; + vbus_en1_sfio_passthrough_state = "/pinmux@2430000/vbus_en1_oc_passthrough"; + tegra_agic_1 = "/aconnect@2a41000/agic-controller@2a51000"; + imx185_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a"; + tegra_sfc1 = "/aconnect@2a41000/ahub/sfc@2902000"; + tegra_ape_ivc = "/ape-ivc-channels"; + csi_chan4_port0 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0"; + e3322_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + devslp_active_state = "/pinmux@2430000/devslp_active"; + vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + vi_port4 = "/host1x/vi@15700000/ports/port@4"; + }; + + pwm@32d0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbf 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x68>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x18a>; + reg = <0x0 0x32d0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x18a>; + #pwm-cells = <0x2>; + }; + + pinctrl@3520000 { + pinctrl-5 = <0xa2>; + compatible = "nvidia,tegra186-xusb-padctl"; + clocks = <0x10 0x6f 0x10 0x215 0x10 0x87 0x10 0x86>; + avdd_pll_erefeut-supply = <0x12>; + pinctrl-3 = <0xa6>; + resets = <0x10 0x37>; + reg-names = "padctl", "ao"; + pinctrl-1 = <0xa4>; + vbus-3-supply = <0x26>; + clock-names = "xusb_clk", "utmipll", "usb2_trk", "hsic_trk"; + vbus-2-supply = <0xaa>; + vddio-hsic-supply = <0x26>; + pinctrl-6 = <0xa3>; + status = "okay"; + interrupts = <0x0 0xa7 0x4>; + vbus-1-supply = <0xa9>; + mbox-names = "xusb"; + mboxes = <0xb0>; + pinctrl-4 = <0xa7>; + phandle = <0xa1>; + vclamp_usb-supply = <0x12>; + pinctrl-2 = <0xa5>; + vbus-0-supply = <0xa8>; + reg = <0x0 0x3520000 0x0 0x1000 0x0 0x3540000 0x0 0x1000>; + pinctrl-0 = <0xb1>; + reset-names = "padctl_rst"; + avdd_usb-supply = <0x13>; + #phy-cells = <0x1>; + linux,phandle = <0xa1>; + pinctrl-names = "default", "vbus_en0_sfio_tristate", "vbus_en1_sfio_tristate", "vbus_en0_sfio_passthrough", "vbus_en1_sfio_passthrough", "vbus_en0_default", "vbus_en1_default"; + + pinmux { + phandle = <0xb1>; + linux,phandle = <0xb1>; + + e3325-usb3-std-A-SS { + nvidia,lanes = "usb3-0"; + nvidia,port-cap = <0x1>; + status = "disabled"; + }; + + usb2-micro-AB { + nvidia,lanes = "otg-0"; + nvidia,port-cap = <0x3>; + nvidia,function = "xusb"; + nvidia,oc-pin = <0x0>; + }; + + usb2-std-A-port2 { + nvidia,lanes = "otg-1"; + nvidia,port-cap = <0x1>; + nvidia,function = "xusb"; + nvidia,oc-pin = <0x1>; + }; + + usb3-std-A-port2 { + nvidia,lanes = "usb3-1"; + nvidia,port-cap = <0x1>; + nvidia,oc-pin = <0x1>; + }; + + e3325-usb3-std-A-HS { + nvidia,lanes = "otg-2"; + nvidia,port-cap = <0x1>; + status = "disabled"; + nvidia,function = "xusb"; + }; + }; + }; + + pinmux@2430000 { + compatible = "nvidia,tegra186-pinmux"; + status = "okay"; + phandle = <0xb7>; + reg = <0x0 0x2430000 0x0 0x15000 0x0 0xc300000 0x0 0x4000>; + pinctrl-0 = <0x1e>; + #gpio-range-cells = <0x3>; + linux,phandle = <0xb7>; + pinctrl-names = "default"; + + vbus_en1_oc_passthrough { + phandle = <0xa7>; + linux,phandle = <0xa7>; + + usb_vbus_en1_pl5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,tristate = <0x0>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + + eqos_idle { + phandle = <0x42>; + linux,phandle = <0x42>; + + eqos { + nvidia,pins = "eqos_td3_pe4", "eqos_td2_pe3", "eqos_td1_pe2", "eqos_td0_pe1", "eqos_txc_pe0", "eqos_tx_ctl_pe5"; + nvidia,tristate = <0x1>; + }; + }; + + devslp_active { + phandle = <0x20>; + linux,phandle = <0x20>; + + sata { + nvidia,enable-input = <0x0>; + nvidia,pins = "pex_l2_clkreq_n_pa6"; + nvidia,lpdr = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "sata"; + nvidia,pull = <0x0>; + }; + }; + + vbus_en0_default { + phandle = <0xa2>; + linux,phandle = <0xa2>; + + usb_vbus_en0_pl4 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "rsvd1"; + }; + }; + + devslp_pullup { + phandle = <0x21>; + linux,phandle = <0x21>; + + sata { + nvidia,pins = "pex_l2_clkreq_n_pa6"; + nvidia,function = "sata"; + nvidia,pull = <0x2>; + }; + }; + + eqos_default { + phandle = <0x43>; + linux,phandle = <0x43>; + + eqos { + nvidia,pins = "eqos_td3_pe4", "eqos_td2_pe3", "eqos_td1_pe2", "eqos_td0_pe1", "eqos_txc_pe0", "eqos_tx_ctl_pe5"; + nvidia,tristate = <0x0>; + }; + }; + + vbus_en0_oc_passthrough { + phandle = <0xa6>; + linux,phandle = <0xa6>; + + usb_vbus_en0_pl4 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,tristate = <0x0>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + + vbus_en0_oc_tristate { + phandle = <0xa4>; + linux,phandle = <0xa4>; + + usb_vbus_en0_pl4 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,tristate = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + + vbus_en1_default { + phandle = <0xa3>; + linux,phandle = <0xa3>; + + usb_vbus_en1_pl5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "rsvd1"; + }; + }; + + common { + phandle = <0x1e>; + linux,phandle = <0x1e>; + + gpio_edp2_pp5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "gpio_edp2_pp5"; + nvidia,tristate = <0x1>; + status = "okay"; + nvidia,pull = <0x2>; + }; + + gpio_edp3_pp6 { + nvidia,enable-input = <0x0>; + nvidia,pins = "gpio_edp3_pp6"; + nvidia,tristate = <0x0>; + status = "okay"; + nvidia,pull = <0x0>; + }; + }; + + vbus_en1_oc_tristate { + phandle = <0xa5>; + linux,phandle = <0xa5>; + + usb_vbus_en1_pl5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,tristate = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + }; + + soft_watchdog { + compatible = "softdog-platform"; + status = "disabled"; + phandle = <0xff>; + linux,phandle = <0xff>; + }; + + energy-costs { + + core-cost0 { + idle-cost-data = <0x80>; + phandle = <0xb>; + busy-cost-data = <0x400 0x400>; + linux,phandle = <0xb>; + }; + + core-cost1 { + idle-cost-data = <0x80>; + phandle = <0xe>; + busy-cost-data = <0x2f0 0x400>; + linux,phandle = <0xe>; + }; + }; + + ptm@9b40000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x7>; + status = "okay"; + phandle = <0x1db>; + reg = <0x0 0x9b40000 0x0 0x1000>; + linux,phandle = <0x1db>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd9>; + linux,phandle = <0xd9>; + }; + }; + }; + + pwm@c340000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xe1>; + resets = <0x10 0x66>; + clock-names = "pwm"; + status = "okay"; + phandle = <0xec>; + reg = <0x0 0xc340000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0xec>; + #pwm-cells = <0x2>; + }; + + axip2p@2100000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2100000 0x0 0x1000>; + }; + + spi@3230000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0x2e 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x2a>; + clock-names = "spi", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p", "clk_m"; + status = "disabled"; + #address-cells = <0x1>; + interrupts = <0x0 0x26 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x184>; + reg = <0x0 0x3230000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x11 0x25 0x11>; + reset-names = "spi"; + linux,phandle = <0x184>; + }; + + hda@3510000 { + compatible = "nvidia,tegra30-hda"; + clocks = <0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + resets = <0x10 0xf 0x10 0x10 0x10 0x11>; + clock-names = "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + status = "okay"; + interrupts = <0x0 0xa1 0x4>; + reg = <0x0 0x3510000 0x0 0x10000>; + iommus = <0x11 0x12>; + reset-names = "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + }; + + psci { + compatible = "arm,psci-1.0"; + cpu_suspend = <0xc4000001>; + cpu_on = <0xc4000003>; + status = "okay"; + cpu_off = <0x84000002>; + method = "smc"; + }; + + i2c@31a0000 { + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + firmware { + + android { + compatible = "android,firmware"; + serialno = "1421920042248"; + hardware = "quill"; + + fstab { + compatible = "android,fstab"; + + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/3460000.sdhci/by-name/vendor"; + type = "ext4"; + fsmgr_flags = "wait,avb"; + mnt_flags = "ro"; + }; + + odm { + compatible = "android,odm"; + dev = "/dev/block/platform/3460000.sdhci/by-name/odm"; + type = "ext4"; + fsmgr_flags = "wait,avb"; + mnt_flags = "ro"; + }; + }; + + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,kernel,kernel-dtb,kernel-dtbo,APP,vendor,SOS"; + }; + }; + }; + + axi2apb@23c0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23c0000 0x0 0x1000>; + }; + + xhci@3530000 { + compatible = "nvidia,tegra186-xhci"; + clocks = <0x10 0x71 0x10 0xf4 0x10 0x72 0x10 0xf2 0x10 0x261 0x10 0xf5 0x10 0x215 0x10 0x261 0x10 0x200>; + otg-controller = <0xab>; + iommu_sodev_map; + clock-names = "xusb_host", "xusb_falcon_src", "xusb_ss", "xusb_ss_src", "xusb_hs_src", "xusb_fs_src", "pll_u_480m", "clk_m", "pll_e"; + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0"; + avdd_pll_utmip-supply = <0x12>; + extcon-cable-names = "id"; + hvdd_usb-supply = <0x12>; + status = "okay"; + interrupt-parent = <0x3a>; + interrupts = <0x0 0xa3 0x4 0x0 0xa4 0x4 0x0 0xa7 0x4>; + phandle = <0x107>; + extcon-cables = <0xa0 0x1>; + phys = <0x9e 0xac 0xad 0xae>; + reg = <0x0 0x3530000 0x0 0x8000 0x0 0x3538000 0x0 0x1000>; + iommus = <0x11 0x1b>; + nvidia,boost_cpu_freq = <0x4b0>; + nvidia,xusb-padctl = <0x9f>; + #extcon-cells = <0x1>; + linux,phandle = <0x107>; + avddio_usb-supply = <0x13>; + }; + + axip2p@2140000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2140000 0x0 0x1000>; + }; + + bluedroid_pm { + compatible = "nvidia,tegra-bluedroid_pm"; + id = <0x0>; + interrupt-parent = <0x28>; + interrupts = <0x3c 0x1>; + bluedroid_pm,ext-wake-gpio = <0x1b 0xa4 0x0>; + phandle = <0x10b>; + avdd-supply = <0x26>; + linux,phandle = <0x10b>; + bluedroid_pm,host-wake-gpio = <0x28 0x3c 0x0>; + dvdd-supply = <0x12>; + bluedroid_pm,reset-gpio = <0x1b 0x3d 0x0>; + }; + + spi@3270000 { + compatible = "nvidia,tegra186-qspi"; + clocks = <0x10 0x84 0x10 0x135 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x81>; + clock-names = "qspi", "qspi_out", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p"; + status = "disabled"; + #address-cells = <0x1>; + interrupts = <0x0 0x23 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x186>; + reg = <0x0 0x3270000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x5 0x25 0x5>; + reset-names = "qspi"; + linux,phandle = <0x186>; + + prod-settings { + + prod { + prod = <0x4 0x7cff 0x0>; + }; + }; + }; + + tfesd { + polling_period = <0x44c>; + tzp_governor_name = "pid_thermal_gov"; + toffset = <0x0>; + phandle = <0xef>; + ndevs = <0x3>; + linux,phandle = <0xef>; + cdev_type = "pwm-fan"; + secret = <0x25>; + + dev2 { + coeffs = <0x1e 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + dev_data = "MCPU-therm"; + }; + + dev3 { + coeffs = <0x28 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + dev_data = "GPU-therm"; + }; + + dev1 { + coeffs = <0x1e 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + dev_data = "BCPU-therm"; + }; + }; + + tegra-pmc-blink-pwm { + compatible = "nvidia,tegra210-pmc-blink-pwm"; + status = "disabled"; + }; + + i2c@31e0000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xb7 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x53>; + scl-gpio = <0x1b 0x5a 0x0>; + sda-gpio = <0x1b 0x5b 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x21 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x180>; + reg = <0x0 0x31e0000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x1f 0x25 0x1f>; + reset-names = "i2c"; + linux,phandle = <0x180>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + axip2p@2180000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2180000 0x0 0x1000>; + }; + + i2c@c250000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xdb 0x10 0x10d 0x10 0xdd>; + resets = <0x10 0x52>; + scl-gpio = <0x28 0x18 0x0>; + sda-gpio = <0x28 0x19 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x20 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x174>; + reg = <0x0 0xc250000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x0 0x25 0x0>; + reset-names = "i2c"; + linux,phandle = <0x174>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + temp-sensor@4c { + compatible = "ti,tmp451"; + extended-rage = <0x1>; + sensor-name = "tmp451-ext"; + supported-hwrev = <0x1>; + #thermal-sensor-cells = <0x1>; + offset = <0xffffffd4>; + conv-rate = <0x6>; + status = "okay"; + interrupt-parent = <0x28>; + temp-alert-gpio = <0x28 0x10 0x0>; + interrupts = <0x10 0x8>; + phandle = <0x53>; + vdd-supply = <0x3d>; + reg = <0x4c>; + linux,phandle = <0x53>; + + ext { + shutdown-limit = <0x6b>; + }; + + loc { + shutdown-limit = <0x6b>; + }; + }; + }; + + tegra-rtcpu-sce-trace { + nvidia,enable-printk; + nvidia,log-prefix = "[SCE]"; + phandle = <0x56>; + linux,phandle = <0x56>; + nvidia,interval-ms = <0x32>; + }; + + fixed-regulators { + compatible = "simple-bus"; + device_type = "fixed-regulators"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + regulator@3 { + regulator-enable-ramp-delay = <0x2e9>; + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0xc 0x1>; + regulator-disable-ramp-delay = <0x12110>; + phandle = <0x8a>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x3>; + regulator-max-microvolt = <0x4c4b40>; + regulator-always-on; + regulator-name = "vdd-hdmi"; + linux,phandle = <0x8a>; + }; + + regulator@200 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xea 0xb 0x1>; + status = "disabled"; + phandle = <0x2f>; + regulator-min-microvolt = <0x1b7740>; + reg = <0xc8>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vdd-1v8-aud2"; + linux,phandle = <0x2f>; + }; + + regulator@18 { + compatible = "regulator-fixed-sync"; + phandle = <0x88>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x12>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vdd-sys-bl"; + linux,phandle = <0x88>; + }; + + regulator@1 { + regulator-enable-ramp-delay = <0x460>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x1b 0x7e 0x0>; + regulator-disable-ramp-delay = <0x4074>; + phandle = <0x1d>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x1>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "en-vdd-sd"; + linux,phandle = <0x1d>; + }; + + regulator@16 { + compatible = "regulator-fixed-sync"; + enable-active-high; + phandle = <0x2c>; + regulator-min-microvolt = <0x2ab980>; + reg = <0x10>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "en-vdd-vcm-2v8"; + linux,phandle = <0x2c>; + }; + + regulator@14 { + compatible = "regulator-fixed-sync"; + phandle = <0x2e>; + regulator-min-microvolt = <0x325aa0>; + reg = <0xe>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vdd-3v3"; + linux,phandle = <0x2e>; + }; + + regulator@8 { + regulator-enable-ramp-delay = <0xd8>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0x3 0x0>; + regulator-disable-ramp-delay = <0xa7f8>; + phandle = <0x84>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x8>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "en-vdd-disp-3v3"; + linux,phandle = <0x84>; + }; + + regulator@12 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x8d 0xa 0x0>; + phandle = <0x34>; + regulator-min-microvolt = <0x124f80>; + reg = <0xc>; + regulator-max-microvolt = <0x124f80>; + regulator-name = "en-vdd-cam-1v2"; + linux,phandle = <0x34>; + }; + + regulator@6 { + regulator-enable-ramp-delay = <0xad>; + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0x1 0x1>; + regulator-disable-ramp-delay = <0x32c8>; + phandle = <0x3f>; + regulator-min-microvolt = <0x1b7740>; + reg = <0x6>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-name = "en-vdd-ts-1v8"; + linux,phandle = <0x3f>; + }; + + regulator@10 { + regulator-enable-ramp-delay = <0xb2>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0x9 0x1>; + regulator-disable-ramp-delay = <0x2710>; + phandle = <0x85>; + regulator-min-microvolt = <0x1b7740>; + reg = <0xa>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "en-vdd-disp-1v8"; + linux,phandle = <0x85>; + }; + + regulator@4 { + regulator-enable-ramp-delay = <0x3b1>; + compatible = "regulator-fixed-sync"; + gpio-open-drain; + enable-active-high; + gpio = <0x1b 0x5c 0x0>; + regulator-disable-ramp-delay = <0xa5a>; + phandle = <0xa8>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x4>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-usb0-5v"; + linux,phandle = <0xa8>; + }; + + regulator@2 { + regulator-enable-ramp-delay = <0x6c>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x8d 0x9 0x1>; + regulator-disable-ramp-delay = <0x4b0>; + phandle = <0x2b>; + regulator-min-microvolt = <0x1b7740>; + reg = <0x2>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "en-vdd-cam"; + linux,phandle = <0x2b>; + }; + + regulator@17 { + compatible = "regulator-fixed-sync"; + gpio = <0xe9 0x0 0x0>; + phandle = <0xaa>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x11>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-usb2-5v"; + linux,phandle = <0xaa>; + }; + + regulator@0 { + compatible = "regulator-fixed"; + phandle = <0x26>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x0>; + regulator-max-microvolt = <0x4c4b40>; + regulator-always-on; + regulator-name = "vdd-ac-bat"; + linux,phandle = <0x26>; + }; + + regulator@15 { + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0xa 0x1>; + phandle = <0x1df>; + regulator-min-microvolt = <0x124f80>; + reg = <0xf>; + regulator-max-microvolt = <0x124f80>; + regulator-always-on; + regulator-name = "dis-vdd-1v2"; + linux,phandle = <0x1df>; + }; + + regulator@9 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0x7 0x1>; + phandle = <0x1de>; + regulator-min-microvolt = <0x387520>; + reg = <0x9>; + regulator-max-microvolt = <0x387520>; + regulator-name = "en-mdm-pwr-3v7"; + linux,phandle = <0x1de>; + }; + + regulator@101 { + compatible = "regulator-fixed"; + regulator-boot-on; + phandle = <0x3d>; + regulator-min-microvolt = <0x1b7740>; + reg = <0x65>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-name = "vdd-1v8-ap"; + linux,phandle = <0x3d>; + }; + + regulator@13 { + compatible = "regulator-fixed-sync"; + gpio = <0xe9 0x4 0x0>; + phandle = <0xee>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0xd>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-fan"; + linux,phandle = <0xee>; + }; + + regulator@7 { + regulator-enable-ramp-delay = <0xf5>; + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0x2 0x1>; + regulator-disable-ramp-delay = <0xa7f8>; + phandle = <0x3e>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x7>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-name = "en-vdd-ts-hv-3v3"; + linux,phandle = <0x3e>; + }; + + regulator@11 { + regulator-enable-ramp-delay = <0x1388>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0xd 0x1>; + regulator-disable-ramp-delay = <0x153d8>; + phandle = <0x29>; + regulator-min-microvolt = <0x2ab980>; + reg = <0xb>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "en-vdd-cam-hv-2v8"; + linux,phandle = <0x29>; + }; + + regulator@5 { + regulator-enable-ramp-delay = <0x320>; + compatible = "regulator-fixed-sync"; + gpio-open-drain; + enable-active-high; + gpio = <0x1b 0x5d 0x0>; + regulator-disable-ramp-delay = <0x32c8>; + phandle = <0xa9>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x5>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-usb1-5v"; + linux,phandle = <0xa9>; + }; + + regulator@118 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x8d 0x3 0x1>; + phandle = <0x2a>; + regulator-min-microvolt = <0x124f80>; + reg = <0x76>; + regulator-max-microvolt = <0x124f80>; + regulator-name = "en-vdd-sys"; + linux,phandle = <0x2a>; + }; + }; + + aliases { + i2c3 = "/i2c@3190000"; + spi2 = "/spi@3230000"; + i2c1 = "/i2c@c240000"; + spi0 = "/spi@3210000"; + sdhci2 = "/sdhci@3440000"; + serial5 = "/serial@3150000"; + i2c8 = "/i2c@31e0000"; + sdhci0 = "/sdhci@3400000"; + serial3 = "/serial@3130000"; + i2c6 = "/i2c@31c0000"; + serial1 = "/serial@3110000"; + rtc0 = "/bpmp_i2c/spmic@3c"; + i2c4 = "/bpmp_i2c"; + spi3 = "/spi@3240000"; + i2c2 = "/i2c@3180000"; + spi1 = "/spi@c260000"; + i2c0 = "/i2c@3160000"; + sdhci3 = "/sdhci@3460000"; + serial6 = "/serial@c290000"; + sdhci1 = "/sdhci@3420000"; + serial4 = "/serial@3140000"; + i2c7 = "/i2c@c250000"; + spi6 = "/spi@3270000"; + serial2 = "/serial@c280000"; + rtc1 = "/rtc@c2a0000"; + i2c5 = "/i2c@31b0000"; + tegra-camera-rtcpu = "/rtcpu@b000000"; + spi4 = "/aon_spi@c260000"; + serial0 = "/serial@3100000"; + }; + + chosen { + ecid = "00000001646ca6c218000000010001c0"; + stdout-path = "/serial@3100000"; + bootargs = "earlycon=uart8250,mmio32,0x3100000 console=ttyS0,115200n8 root=/dev/sda1 rw audit=0 default_hugepagesz=32M hugepagesz=32M hugepages=4"; + nvidia,ether-mac = "48:b0:2d:0e:6e:9e"; + nvidia,bluetooth-mac = "48:b0:2d:0e:6e:9d"; + nvidia,wifi-mac = "48:b0:2d:0e:6e:9c"; + board-has-eeprom; + nvidia,tegra-joint_xpu_rail; + + reset { + + pmic-reset-reason { + reason = "RSTIN"; + register-value = "0x80"; + }; + + pmc-reset-reason { + reset-level = [30 00]; + reset-source = "SYS_RESET_N"; + }; + }; + + plugin-manager { + cvm = "3310-1000-D00"; + + odm-data { + disable-pmic-wdt = <0x1>; + no-battery = <0x1>; + enable-debug-console = <0x1>; + enable-xusb-on-uphy-lane0 = <0x1>; + normal-flashed = <0x1>; + disable-tegra-wdt = <0x1>; + enable-pcie-on-uphy-lane1 = <0x1>; + android-build = <0x1>; + enable-sata-on-uphy-lane5 = <0x1>; + enable-denver-wdt = <0x1>; + enable-pcie-on-uphy-lane4 = <0x1>; + disable-sdmmc-hwcq = <0x1>; + enable-pcie-on-uphy-lane2 = <0x1>; + }; + + chip-id { + A02P = <0x1>; + }; + + configs { + 3310-misc-config = <0x0>; + 3310-touch-config = <0x0>; + 3310-modem-config = <0x0>; + 3310-mem-type = <0x0>; + 3310-power-config = <0x0>; + 3310-display-config = <0x0>; + }; + + ids { + 3310-1000-D00 = "/i2c@c250000:module@0x50"; + 2597-0000-900 = "/i2c@c250000:module@0x57"; + 3310-1000-D00-K = <0x1>; + 3326-1000-000 = "/i2c@3180000:module@0x54"; + + connection { + + i2c@c250000 { + + module@0x50 { + 3310-1000-D00 = "/i2c@c250000:module@0x50"; + }; + + module@0x57 { + 2597-0000-900 = "/i2c@c250000:module@0x57"; + }; + }; + + i2c@3180000 { + + module@0x54 { + 3326-1000-000 = "/i2c@3180000:module@0x54"; + }; + }; + }; + }; + }; + }; + + external-connection { + compatible = "simple-bus"; + device_type = "external-connection"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + extcon@1 { + gpios = <0x1b 0x9f 0x0 0x22 0x0 0x0>; + compatible = "extcon-gpio-states"; + wakeup-source; + extcon-gpio,cable-states = <0x3 0x0 0x0 0x2 0x1 0x2 0x2 0x1>; + phandle = <0xa0>; + reg = <0x1>; + extcon-gpio,wait-for-gpio-scan = <0x0>; + #extcon-cells = <0x1>; + extcon-gpio,out-cable-names = <0x1 0x2 0x0>; + linux,phandle = <0xa0>; + extcon-gpio,name = "VBUS"; + }; + + disp-state { + compatible = "extcon-disp-state"; + #extcon-cells = <0x1>; + }; + }; + + axi2apb@2390000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2390000 0x0 0x1000>; + }; + + e3333_lens_ov5693@P5V27C { + min_focus_distance = "0.0"; + f_number = "2.0"; + hyper_focal = "0.0"; + aperture = "2.0"; + focal_length = "2.67"; + }; + + vivid-driver { + + instance0 { + + mode0 { + line_length = "2200"; + active_w = "1920"; + vert_front_porch = [34 00]; + horz_back_porch = "148"; + embedded_metadata_height = [31 00]; + pixel_t = "bayer_bggr10"; + pix_clk_hz = "74250000"; + max_gain_val = "256"; + vert_back_porch = "36"; + vert_sync = [35 00]; + readout_orientation = "90"; + min_gain_val = [31 00]; + tegra_sinterface = "host"; + min_framerate = [31 00]; + max_framerate = "30"; + horz_sync = "44"; + gain_factor = "16"; + framerate_factor = [31 00]; + active_h = "1080"; + max_exp_time = "999994"; + horz_front_porch = "88"; + min_exp_time = "34"; + }; + }; + }; + + serial@c280000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xd7 0x10 0x10d>; + resets = <0x10 0x31>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "NILL"; + interrupts = <0x0 0x72 0x4>; + dma-names = "rx", "tx"; + phandle = <0x18e>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0xc280000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x3 0x25 0x3>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x18e>; + }; + + ptm@9a40000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x6>; + status = "okay"; + phandle = <0x1da>; + reg = <0x0 0x9a40000 0x0 0x1000>; + linux,phandle = <0x1da>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd8>; + linux,phandle = <0xd8>; + }; + }; + }; + + tegra-rtcpu-ape-trace { + nvidia,enable-printk; + nvidia,log-prefix = "[APE]"; + phandle = <0x5c>; + linux,phandle = <0x5c>; + nvidia,interval-ms = <0x32>; + }; + + memory@90000000 { + device_type = "memory"; + reg = <0x0 0x90000000 0x0 0x60000000>; + }; + + cluster_clk_priv@e090000 { + compatible = "nvidia,t18x-cluster-clk-priv"; + status = "okay"; + #address-cells = <0x2>; + #size-cells = <0x2>; + reg = <0x0 0xe090000 0x0 0xfff0 0x0 0xe0a0000 0x0 0xfff0 0x0 0xe0b0000 0x0 0xfff0 0x0 0xe0c0000 0x0 0xfff0 0x0 0xe0d0000 0x0 0xfff0>; + }; + + plugin-manager { + status = "disabled"; + + fragement@1 { + odm-data = "disable-denver-wdt"; + + override@0 { + target = <0xb3>; + + _overlay_ { + nvidia,enable-halt-in-fiq; + }; + }; + }; + + fragment-500-pcie-config { + ids = ">=3310-1000-500"; + + override@0 { + target = <0x109>; + + _overlay_ { + + pci@2,0 { + nvidia,num-lanes = <0x0>; + }; + + pci@1,0 { + nvidia,num-lanes = <0x4>; + }; + + pci@3,0 { + nvidia,num-lanes = <0x1>; + }; + }; + }; + }; + + fragment-500-xusb-config { + ids = ">=3310-1000-500"; + + override@1 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "okay"; + nvidia,usb2-companion = <0x1>; + }; + + usb3-1 { + status = "disabled"; + }; + }; + }; + }; + + override@0 { + target = <0x107>; + + _overlay_ { + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0"; + phys = <0x9e 0xac 0xad 0xae>; + }; + }; + }; + + fragment-e3323@0 { + ids = "3323-1000-*"; + + override@11 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "e3323_bottom_CH06P1"; + status = "okay"; + position = "bottom"; + orientation = [33 00]; + }; + }; + + override@18 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@8 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@26 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@16 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x138>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@6 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3323_lens_ov23850@CH06P1/"; + }; + }; + + override@24 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + max_pixel_rate = <0xb71b0>; + num_csi_lanes = <0x8>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@14 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x124>; + + _overlay_ { + badge = "e3323_top_CH06P1"; + status = "okay"; + position = "top"; + orientation = [33 00]; + }; + }; + + override@22 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x64>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "ov23850 2-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov23850_a@10"; + }; + }; + + override@20 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@0 { + target = <0x135>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3323_lens_ov23850@CH06P1/"; + }; + }; + + override@25 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x5e 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@15 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x125>; + + _overlay_ { + devname = "ov23850 1-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@c240000/ov23850_c@36"; + }; + }; + + override@23 { + target = <0x6e>; + + _overlay_ { + remote-endpoint = <0x64>; + status = "okay"; + }; + }; + + override@13 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@3 { + target = <0x136>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x2d>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x139>; + status = "okay"; + bus-width = <0x4>; + }; + }; + }; + + fragement@8 { + odm-data = "enable-sdmmc-hwcq"; + + override@0 { + target = <0x101>; + + _overlay_ { + nvidia,enable-hwcq; + }; + }; + }; + + fragment-p3310-c00-pmic { + ids = ">=3310-1000-800"; + + override@0 { + target = <0x10c>; + + _overlay_ { + maxim,active-fps-source = <0x3>; + }; + }; + }; + + fragment-sdwake-p3310-1000-300 { + ids = ">=3310-1000-300"; + + override@102 { + target = <0x1d>; + + _overlay_ { + gpio = <0x1b 0x7e 0x0>; + }; + }; + + override@100 { + target = <0x1e>; + + _overlay_ { + + gpio_edp2_pp5 { + status = "okay"; + }; + + gpio_edp3_pp6 { + status = "okay"; + }; + }; + }; + + override@103 { + target = <0x100>; + + _overlay_ { + nvidia,cd-wakeup-capable; + cd-gpios = <0x1b 0x7d 0x0>; + }; + }; + + override@101 { + target = <0x1b>; + + _overlay_ { + + sdmmc-wake-support-input { + status = "okay"; + }; + + sdmmc-wake-support-output { + status = "okay"; + }; + }; + }; + }; + + fragment-e3326@0 { + ids = "3326-*"; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "e3326_front_P5V27C"; + status = "okay"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@14 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "ov5693 2-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov5693_c@36"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x134>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@0 { + target = <0x132>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@15 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3326_lens_ov5693@P5V27C/"; + }; + }; + }; + + fragement-pmon-p3310-1000-300 { + ids = ">=3310-1000-300", "3310-1000-200-F"; + + override@1 { + target = <0xf1>; + + _overlay_ { + + channel@2 { + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@0 { + ti,shunt-resistor-mohm = <0x5>; + }; + + channel@1 { + ti,shunt-resistor-mohm = <0xa>; + }; + }; + }; + + override@0 { + target = <0xf0>; + + _overlay_ { + + channel@0 { + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@1 { + ti,shunt-resistor-mohm = <0xa>; + }; + }; + }; + }; + + fragment-e3320-a01@1 { + ids = "3320-1000-100", "3320-1000-200"; + + overrides@4 { + target = <0x106>; + + _overlay_ { + + gpio@21 { + status = "okay"; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + status = "okay"; + }; + }; + }; + + overrides@2 { + target = <0x85>; + + _overlay_ { + gpio = <0x40 0x0 0x0>; + }; + }; + + overrides@3 { + target = <0xb6>; + + _overlay_ { + + dsi { + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + + overrides@1 { + target = <0x11c>; + + _overlay_ { + status = "okay"; + + outn { + ti,enable-gpio = <0x40 0x2 0x0>; + delete-target-property = "ti,disable-active-discharge"; + ti,active-discharge-gpio = <0x40 0x3 0x0>; + ti,active-discharge-time = <0x7d0>; + }; + + outp { + ti,enable-gpio = <0x8d 0x4 0x0>; + }; + }; + }; + }; + + fragement@6 { + odm-data = "mods-build"; + + override@1 { + target = <0xa1>; + + _overlay_ { + delete-target-property = "mboxes"; + }; + }; + + override@4 { + target = <0x100>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@2 { + target = <0x25>; + + _overlay_ { + nvidia,bypass-smmu; + }; + }; + + override@0 { + target = <0xb0>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@7 { + target = <0xb6>; + + _overlay_ { + + dsi { + nvidia,dsi-csi-loopback; + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + + nvdisplay@15210000 { + win-mask = <0xc>; + status = "okay"; + }; + + sor1 { + status = "okay"; + + hdmi-display { + status = "okay"; + }; + + dp-display { + status = "disabled"; + }; + }; + + nvdisplay@15220000 { + win-mask = <0x30>; + status = "okay"; + }; + + sor { + status = "okay"; + + hdmi-display { + status = "disabled"; + }; + + panel-s-edp-uhdtv-15-6 { + + smartdimmer { + status = "disabled"; + }; + }; + + dp-display { + status = "okay"; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + + nvdisplay@15200000 { + win-mask = <0x3>; + status = "okay"; + }; + }; + }; + + override@5 { + target = <0x101>; + + _overlay_ { + delete-target-property = "nvidia,enable-hwcq"; + }; + }; + + override@3 { + target = <0xf9>; + + _overlay_ { + status = "disabled"; + }; + }; + }; + + fragment-500-e3325-pcie { + odm-data = "enable-pcie-on-uphy-lane0"; + ids = ">=3310-1000-500"; + enable-override-on-all-matches; + + override@1 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "disabled"; + }; + }; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + pcie0_lane2_mux { + status = "okay"; + }; + }; + }; + + override@0 { + target = <0x107>; + + _overlay_ { + phy-names = "usb2-0", "usb2-1", "usb2-2"; + phys = <0x9e 0xac 0xad>; + }; + }; + }; + + fragement@4 { + odm-data = "enable-pmic-wdt", "enable-denver-wdt"; + + override@0 { + target = <0xff>; + + _overlay_ { + status = "disabled"; + }; + }; + }; + + fragment-e2614-b00@2 { + ids = "2614-0000-100"; + + overrides@0 { + target = <0x11b>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x115>; + + _overlay_ { + codec-dai = <0x11b>; + }; + }; + }; + + fragment-e3331@0 { + ids = "3331-*"; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + badge = "e3331_rear_22N02A"; + status = "okay"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + max_pixel_rate = <0x27100>; + num_csi_lanes = <0x3>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x3>; + }; + }; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + devname = "imx318 30-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx318_a@10"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "cam0-rst"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x172>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x173>; + status = "okay"; + bus-width = <0x3>; + }; + }; + }; + + fragment-p3310-c03 { + ids = ">=3310-1000-B00"; + + override@1 { + target = <0x10d>; + + _overlay_ { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "dvdd-pex"; + }; + }; + + override@2 { + target = <0x10e>; + + _overlay_ { + maxim,active-fps-source = <0x3>; + }; + }; + + override@3 { + target = <0x89>; + + _overlay_ { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + }; + }; + }; + + fragment-e3322@0 { + ids = "3322-*"; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@68 { + target = <0x39>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x6b>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@58 { + target = <0x159>; + + _overlay_ { + status = "okay"; + }; + }; + + override@48 { + target = <0x70>; + + _overlay_ { + remote-endpoint = <0x68>; + status = "okay"; + }; + }; + + override@38 { + target = <0x168>; + + _overlay_ { + status = "okay"; + }; + }; + + override@66 { + target = <0x15f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@28 { + target = <0x140>; + + _overlay_ { + badge = "e3322_centerright_P5V27C"; + status = "okay"; + position = "centerright"; + orientation = [31 00]; + }; + }; + + override@56 { + target = <0x157>; + + _overlay_ { + status = "okay"; + }; + }; + + override@18 { + target = <0x125>; + + _overlay_ { + devname = "imx219 31-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/imx219_b@10"; + }; + }; + + override@46 { + target = <0x37>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x67>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@712 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@8 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@36 { + target = <0x147>; + + _overlay_ { + status = "okay"; + }; + }; + + override@64 { + target = <0x15e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x6e>; + + _overlay_ { + remote-endpoint = <0x64>; + status = "okay"; + }; + }; + + override@54 { + target = <0x6a>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x71>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@16 { + target = <0x165>; + + _overlay_ { + status = "okay"; + }; + }; + + override@44 { + target = <0x14d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@72 { + target = <0x35>; + + _overlay_ { + + tca6408_21_input { + gpios = <0x6 0x0 0x7 0x0>; + gpio-hog; + status = "okay"; + label = "tca6408_21_input_6", "tca6408_21_input_7"; + input; + }; + + tca6408_21_outlow { + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + badge = "e3322_bottomleft_P5V27C"; + status = "okay"; + position = "bottomleft"; + orientation = [31 00]; + }; + }; + + override@34 { + target = <0x145>; + + _overlay_ { + status = "okay"; + }; + }; + + override@62 { + target = <0x15c>; + + _overlay_ { + devname = "imx219 35-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + }; + }; + + override@24 { + target = <0x2d>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x166>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@52 { + target = <0x154>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@42 { + target = <0x14c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@70 { + target = <0x72>; + + _overlay_ { + remote-endpoint = <0x6c>; + status = "okay"; + }; + }; + + override@4 { + target = <0x13b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@32 { + target = <0x66>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6f>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@60 { + target = <0x16a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@22 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@50 { + target = <0x152>; + + _overlay_ { + badge = "e3322_bottomright_P5V27C"; + status = "okay"; + position = "bottomright"; + orientation = [31 00]; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@40 { + target = <0x14a>; + + _overlay_ { + devname = "imx219 33-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + }; + }; + + override@69 { + target = <0x162>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0xc>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@30 { + target = <0x142>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@59 { + target = <0x71>; + + _overlay_ { + remote-endpoint = <0x6a>; + status = "okay"; + }; + }; + + override@20 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@49 { + target = <0x169>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@39 { + target = <0x149>; + + _overlay_ { + badge = "e3322_topleft_P5V27C"; + status = "okay"; + position = "topleft"; + orientation = [31 00]; + }; + }; + + override@67 { + target = <0x160>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@29 { + target = <0x141>; + + _overlay_ { + devname = "imx219 32-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + }; + }; + + override@57 { + target = <0x38>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x69>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@19 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@47 { + target = <0x150>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@37 { + target = <0x6f>; + + _overlay_ { + remote-endpoint = <0x66>; + status = "okay"; + }; + }; + + override@65 { + target = <0x6c>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x72>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@27 { + target = <0x167>; + + _overlay_ { + status = "okay"; + }; + }; + + override@55 { + target = <0x156>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x124>; + + _overlay_ { + badge = "e3322_centerleft_P5V27C"; + status = "okay"; + position = "centerleft"; + orientation = [31 00]; + }; + }; + + override@45 { + target = <0x14e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + devname = "imx219 30-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@0/imx219_a@10"; + }; + }; + + override@35 { + target = <0x36>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x65>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@63 { + target = <0x15d>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@25 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@53 { + target = <0x155>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@43 { + target = <0x68>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x70>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + gpios = <0x8d 0x0>; + gpio-hog; + status = "okay"; + label = "cam0-rst"; + output-high; + }; + + camera-control-output-low { + gpios = <0x88 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x163>; + + _overlay_ { + status = "okay"; + }; + }; + + override@33 { + target = <0x144>; + + _overlay_ { + status = "okay"; + }; + }; + + override@61 { + target = <0x15b>; + + _overlay_ { + badge = "e3322_topright_P5V27C"; + status = "okay"; + position = "topright"; + orientation = [31 00]; + }; + }; + + override@23 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@51 { + target = <0x153>; + + _overlay_ { + devname = "imx219 34-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x164>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@41 { + target = <0x14b>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@3 { + target = <0x35>; + + _overlay_ { + status = "okay"; + }; + }; + + override@31 { + target = <0x143>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x64>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x2>; + }; + }; + }; + + soc-prod-a01-fragment { + chip-id = "A01", "A01P"; + + override@1 { + target = <0xfb>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0xfc>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0xfa>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragement@2 { + odm-data = "enable-pmic-wdt"; + + override@0 { + target = <0xfe>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-e3325-xusb { + odm-data = "enable-xusb-on-uphy-lane0"; + ids = "<3310-1000-500"; + enable-override-on-all-matches; + + override@1 { + target = <0x107>; + + _overlay_ { + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0", "usb3-1"; + phys = <0x9e 0xac 0xad 0xae 0x108>; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + e3325_sdio_rst { + status = "okay"; + }; + + e3325_lane0_mux { + status = "okay"; + }; + }; + }; + + override@0 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "okay"; + }; + }; + }; + }; + + override@3 { + target = <0x109>; + + _overlay_ { + + pci@2,0 { + nvidia,num-lanes = <0x1>; + }; + + pci@1,0 { + nvidia,num-lanes = <0x2>; + }; + + pci@3,0 { + nvidia,num-lanes = <0x1>; + }; + }; + }; + }; + + fragment-p3310-c00-camera { + ids = ">=3310-1000-800", ">=3489-0000-200", ">=3489-0888-300"; + + override@1 { + target = <0x136>; + + _overlay_ { + pwdn-gpios = <0x1b 0x6a 0x0>; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x6a 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + }; + }; + + override@3 { + target = <0x13a>; + + _overlay_ { + pwdn-gpios = <0x1b 0x6a 0x0>; + }; + }; + }; + + fragment-imx390@0 { + ids = "LPRD-001"; + + override@11 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx390_rear"; + status = "okay"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@18 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@8 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x31>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@24 { + target = <0x32>; + + _overlay_ { + status = "okay"; + }; + }; + + override@14 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x61>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@4 { + target = <0x124>; + + _overlay_ { + badge = "imx390_front"; + status = "okay"; + position = "front"; + orientation = [31 00]; + }; + }; + + override@22 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x2>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x3d0900>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@12 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx390 30-001b"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b"; + }; + }; + + override@20 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x64>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x2>; + vc-id = <0x1>; + }; + }; + + override@0 { + target = <0x120>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x2d>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x63>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@9 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + vc-id = <0x0>; + }; + }; + + override@27 { + target = <0x33>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@25 { + target = <0x131>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x125>; + + _overlay_ { + devname = "imx390 30-001c"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + }; + }; + + override@23 { + target = <0x130>; + + _overlay_ { + vcc-pullup-supply = <0x26>; + status = "okay"; + }; + }; + + override@13 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@3 { + target = <0x123>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-p3310-c01 { + ids = ">=3310-1000-900"; + + override@1 { + target = <0x3b>; + + _overlay_ { + + pin_gpio2 { + status = "disabled"; + }; + + pin_gpio3 { + status = "disabled"; + }; + }; + }; + + override@0 { + target = <0x10c>; + + _overlay_ { + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + fragment-e3320-a00@1 { + ids = "3320-1000-000", "3320-1100-000"; + + overrides@2 { + target = <0xb6>; + + _overlay_ { + + dsi { + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + + overrides@3 { + target = <0x106>; + + _overlay_ { + + gpio@21 { + status = "okay"; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + status = "okay"; + }; + }; + }; + + overrides@1 { + target = <0x11c>; + + _overlay_ { + status = "okay"; + + outn { + ti,enable-gpio = <0x40 0x3 0x0>; + }; + + outp { + ti,enable-gpio = <0x40 0x2 0x0>; + }; + }; + }; + }; + + fragement@0 { + odm-data = "enable-denver-wdt"; + + override@0 { + target = <0xfd>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-comms-a00-chip { + ids = "<3310-1000-500"; + + override@1 { + target = <0x1b>; + + _overlay_ { + + wifi-wake-ap { + gpios = <0x10 0x0>; + status = "okay"; + }; + + wifi-enable { + gpios = <0xe 0x0>; + }; + }; + }; + + override@0 { + target = <0x10a>; + + _overlay_ { + pwr-retry-cnt = <0x0>; + interrupt-parent = <0x1b>; + interrupts = <0x10 0x14>; + delete-target-property = "wlan-pwr-gpio"; + sdhci-host = <0xf9>; + }; + }; + + override@3 { + target = <0x28>; + + _overlay_ { + + wifi-wake-ap { + status = "disabled"; + }; + }; + }; + }; + + fragement@9 { + odm-data = "enable-ufs-on-uphy-lane5"; + + override@1 { + target = <0x105>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@0 { + target = <0x104>; + + _overlay_ { + status = "okay"; + }; + }; + + override@3 { + target = <0x106>; + + _overlay_ { + + gpio@76 { + + sata_lane5_mux { + status = "disabled"; + }; + + ufs_lane5_mux { + status = "okay"; + }; + }; + }; + }; + }; + + fragment-e2614-common@0 { + ids = "2614-0000-*"; + + overrides@14 { + target = <0x110>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@8 { + target = <0x2f>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@12 { + target = <0x116>; + + _overlay_ { + cpu-dai-name = "DSPK2"; + codec-dai = <0x117>; + codec-dai-name = "tas2552-amplifier"; + cpu-dai = <0xcf>; + }; + }; + + overrides@6 { + target = <0x113>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@10 { + target = <0x114>; + + _overlay_ { + nvidia,num-codec-link = <0xd>; + nvidia,audio-routing = "x Headphone Jack", "x HPO L Playback", "x Headphone Jack", "x HPO R Playback", "x IN1P", "x Mic Jack", "x Int Spk", "x SPO Playback", "x DMIC L1", "x Int Mic", "x DMIC L2", "x Int Mic", "x DMIC R1", "x Int Mic", "x DMIC R2", "x Int Mic", "y Headphone", "y OUT", "y IN", "y Mic", "z Headphone", "z OUT", "z IN", "z Mic", "m Headphone", "m OUT", "m IN", "m Mic", "n Headphone", "n OUT", "n IN", "n Mic", "o Headphone", "o OUT", "o IN", "o Mic", "a IN", "a Mic", "b IN", "b Mic", "c IN", "c Mic", "d IN", "d Mic", "d1 Headphone", "d1 OUT", "d2 Headphone", "d2 OUT", "d3 Headphone", "d3 OUT"; + }; + }; + + overrides@4 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@17 { + target = <0x113>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@2 { + target = <0x110>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@15 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@0 { + target = <0x10f>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@13 { + target = <0x118>; + + _overlay_ { + cpu-dai-name = "DSPK2"; + codec-dai = <0x119>; + codec-dai-name = "tas2552-amplifier"; + cpu-dai = <0xcf>; + }; + }; + + overrides@11 { + target = <0x115>; + + _overlay_ { + codec-dai-name = "rt5659-aif1"; + link-name = "rt565x-playback"; + }; + }; + + overrides@5 { + target = <0x112>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@3 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@16 { + target = <0x112>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@1 { + target = <0xea>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-e2614-a00@1 { + ids = "2614-0000-000"; + + overrides@0 { + target = <0x11a>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x115>; + + _overlay_ { + codec-dai = <0x11a>; + }; + }; + }; + + fragment-p3310-c00-comm { + ids = ">=3310-1000-800"; + + override@0 { + target = <0x10b>; + + _overlay_ { + bluedroid_pm,reset-gpio = <0x1b 0x3d 0x0>; + }; + }; + }; + + fragment-imx274@0 { + ids = "LPRD-002002"; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx274_bottom_A6V26"; + status = "okay"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@18 { + target = <0x123>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x16d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@14 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx274 30-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x16f>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@0 { + target = <0x16e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x124>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x120>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@15 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + gpios = <0x8d 0x0>; + gpio-hog; + status = "okay"; + label = "cam0-rst"; + output-high; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + }; + + fragement-pmon-p3310-1000-800 { + ids = ">=3310-1000-800"; + + override@0 { + target = <0xf1>; + + _overlay_ { + + channel@2 { + ti,rail-name = "VDD_SYS_DDR"; + }; + + channel@0 { + ti,shunt-resistor-mohm = <0x14>; + }; + }; + }; + }; + + fragement@7 { + odm-data = "enable-high-speed-uart"; + + override@0 { + target = <0x103>; + + _overlay_ { + compatible = "nvidia,tegra186-hsuart"; + resets = <0x10 0x2f>; + early-print-console-channel; + reset-names = "serial"; + }; + }; + }; + + fragment-e1824-a00@3 { + ids = "1824-1100-001"; + + overrides@0 { + target = <0xb6>; + + _overlay_ { + + sor { + status = "okay"; + nvidia,active-panel = <0x11f>; + + panel-s-edp-uhdtv-15-6 { + nvidia,is_ext_dp_panel = <0x0>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + status = "okay"; + nvidia,en-vmm-vpp-with-i2c-config; + + smartdimmer { + status = "okay"; + }; + + disp-default-out { + nvidia,out-parent-clk = "plld3"; + }; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + }; + + fragment-e3333@0 { + ids = "3333-*"; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@68 { + target = <0x39>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x161>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@58 { + target = <0x159>; + + _overlay_ { + status = "okay"; + }; + }; + + override@48 { + target = <0x70>; + + _overlay_ { + remote-endpoint = <0x68>; + status = "okay"; + }; + }; + + override@38 { + target = <0x148>; + + _overlay_ { + status = "okay"; + }; + }; + + override@66 { + target = <0x15f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@28 { + target = <0x140>; + + _overlay_ { + badge = "e3333_centerright_P5V27C"; + status = "okay"; + position = "centerright"; + orientation = [31 00]; + }; + }; + + override@56 { + target = <0x157>; + + _overlay_ { + status = "okay"; + }; + }; + + override@18 { + target = <0x125>; + + _overlay_ { + devname = "ov5693 31-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36"; + }; + }; + + override@46 { + target = <0x37>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x14f>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@712 { + target = <0x28>; + + _overlay_ { + + camera-control-output-high { + status = "okay"; + }; + + camera-control-output-low { + status = "okay"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@8 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@36 { + target = <0x147>; + + _overlay_ { + status = "okay"; + }; + }; + + override@64 { + target = <0x15e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x6e>; + + _overlay_ { + remote-endpoint = <0x64>; + status = "okay"; + }; + }; + + override@54 { + target = <0x6a>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x71>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@16 { + target = <0x13a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@44 { + target = <0x14d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@72 { + target = <0x35>; + + _overlay_ { + + tca6408_21_input { + status = "disabled"; + }; + + tca6408_21_outlow { + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0 0x6 0x0 0x7 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5", "tca6408_21_outlow_6", "tca6408_21_outlow_7"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + badge = "e3333_bottomleft_P5V27C"; + status = "okay"; + position = "bottomleft"; + orientation = [31 00]; + }; + }; + + override@34 { + target = <0x145>; + + _overlay_ { + status = "okay"; + }; + }; + + override@62 { + target = <0x15c>; + + _overlay_ { + devname = "ov5693 35-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36"; + }; + }; + + override@24 { + target = <0x2d>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x13e>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@52 { + target = <0x154>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@42 { + target = <0x14c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@70 { + target = <0x72>; + + _overlay_ { + remote-endpoint = <0x6c>; + status = "okay"; + }; + }; + + override@4 { + target = <0x13b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@32 { + target = <0x66>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6f>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@60 { + target = <0x15a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@22 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@50 { + target = <0x152>; + + _overlay_ { + badge = "e3333_bottomright_P5V27C"; + status = "okay"; + position = "bottomright"; + orientation = [31 00]; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@40 { + target = <0x14a>; + + _overlay_ { + devname = "ov5693 33-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36"; + }; + }; + + override@69 { + target = <0x162>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + max_pixel_rate = <0x30d40>; + num_csi_lanes = <0xc>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@30 { + target = <0x142>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@59 { + target = <0x71>; + + _overlay_ { + remote-endpoint = <0x6a>; + status = "okay"; + }; + }; + + override@20 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@49 { + target = <0x151>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@39 { + target = <0x149>; + + _overlay_ { + badge = "e3333_topleft_P5V27C"; + status = "okay"; + position = "topleft"; + orientation = [31 00]; + }; + }; + + override@67 { + target = <0x160>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@29 { + target = <0x141>; + + _overlay_ { + devname = "ov5693 32-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36"; + }; + }; + + override@57 { + target = <0x38>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x158>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@19 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@47 { + target = <0x150>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@37 { + target = <0x6f>; + + _overlay_ { + remote-endpoint = <0x66>; + status = "okay"; + }; + }; + + override@65 { + target = <0x6c>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x72>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@27 { + target = <0x13f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@55 { + target = <0x156>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x124>; + + _overlay_ { + badge = "e3333_centerleft_P5V27C"; + status = "okay"; + position = "centerleft"; + orientation = [31 00]; + }; + }; + + override@45 { + target = <0x14e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@73 { + target = <0x59>; + + _overlay_ { + compatible = "nvidia,tegra186-i2c"; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + devname = "ov5693 30-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36"; + }; + }; + + override@35 { + target = <0x36>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x146>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@63 { + target = <0x15d>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@25 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@53 { + target = <0x155>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@43 { + target = <0x68>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x70>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x5e 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x13c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@33 { + target = <0x144>; + + _overlay_ { + status = "okay"; + }; + }; + + override@61 { + target = <0x15b>; + + _overlay_ { + badge = "e3333_topright_P5V27C"; + status = "okay"; + position = "topright"; + orientation = [31 00]; + }; + }; + + override@23 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@51 { + target = <0x153>; + + _overlay_ { + devname = "ov5693 34-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x13d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@41 { + target = <0x14b>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@3 { + target = <0x35>; + + _overlay_ { + status = "okay"; + }; + }; + + override@31 { + target = <0x143>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x64>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x2>; + }; + }; + }; + + fragment-imx185@0 { + ids = "LPRD-002001"; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx185_bottom_liimx185"; + status = "okay"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@18 { + target = <0x124>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x120>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@14 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx185 30-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x16c>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@0 { + target = <0x16b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x123>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@15 { + target = <0x16d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + }; + + fragment-e1639-sharp-25x16@2 { + ids = "1639-1000-001"; + + overrides@4 { + target = <0xb6>; + + _overlay_ { + + dsi { + status = "okay"; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + + overrides@2 { + target = <0x102>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@0 { + target = <0x11d>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@3 { + target = <0x11e>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x88>; + + _overlay_ { + regulator-boot-on; + enable-active-high; + gpio = <0x28 0xb 0x1>; + regulator-always-on; + }; + }; + }; + + fragment-imx274-dual@0 { + ids = "LPRD-dual-imx274-002"; + + override@11 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx274_bottom_A6V26"; + status = "okay"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@18 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@8 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@26 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + gpios = <0x8d 0x0 0x88 0x0>; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam1-rst"; + output-high; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@16 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x16f>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@6 { + target = <0x125>; + + _overlay_ { + devname = "imx274 31-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a"; + }; + }; + + override@24 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x8>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@14 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x170>; + + _overlay_ { + status = "okay"; + }; + }; + + override@22 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x64>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx274 30-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + }; + }; + + override@20 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0x16e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + + override@25 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x124>; + + _overlay_ { + badge = "imx274_top_A6V26"; + status = "okay"; + position = "top"; + orientation = [30 00]; + }; + }; + + override@23 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + + override@21 { + target = <0x2d>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x171>; + status = "okay"; + bus-width = <0x4>; + }; + }; + }; + + fragment-e3320-dp { + ids = ">=3320-1000-000", ">=3320-1100-000"; + + override@0 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15220000 { + status = "okay"; + }; + + sor { + status = "okay"; + + dp-display { + status = "okay"; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + }; + }; + }; + + fragement@10 { + odm-data = "enable-ufs-on-uphy-lane4"; + + override@1 { + target = <0x105>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@0 { + target = <0x104>; + + _overlay_ { + status = "okay"; + }; + }; + + override@3 { + target = <0x106>; + + _overlay_ { + + gpio@76 { + + pcie0_lane4_mux { + status = "disabled"; + }; + + ufs_lane4_mux { + status = "okay"; + }; + + sata_lane5_mux { + status = "disabled"; + }; + + ufs_lane5_mux { + status = "okay"; + }; + }; + }; + }; + }; + + fragment-devslp@0 { + ids = ">=3310-1000-200"; + + override@1 { + target = <0x3b>; + + _overlay_ { + + pin_gpio7 { + drive-push-pull = <0x1>; + }; + }; + }; + + override@0 { + target = <0x105>; + + _overlay_ { + gpios = <0x22 0x7 0x0>; + }; + }; + }; + }; + + combined-uart { + compatible = "nvidia,tegra186-combined-uart"; + status = "NILL"; + interrupts = <0x0 0x78 0x4>; + reg = <0x0 0x3c10000 0x0 0x4 0x0 0xc168000 0x0 0x4 0x0 0x3c00000 0x0 0x1000>; + }; + + sdhci@3420000 { + nvidia,ddr-tap-delay = <0xb>; + cap-mmc-highspeed; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x35 0x10 0x10d 0x10 0x80>; + mmc-ddr-1_8v; + cap-sd-highspeed; + resets = <0x10 0x22>; + pinctrl-1 = <0x18>; + nvidia,is-emmc; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + pll_source = "pll_p"; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "disabled"; + nvidia,max-tap-delay = <0x88>; + interrupts = <0x0 0x3f 0x4>; + bus-width = <0x8>; + ddr-trim-delay = <0x5>; + phandle = <0x17a>; + tap-delay = <0xb>; + reg = <0x0 0x3420000 0x0 0x210>; + iommus = <0x11 0x19>; + pinctrl-0 = <0x17>; + mmc-ocr-mask = <0x0>; + compad-vref-1v8 = <0x2>; + trim-delay = <0x5>; + pwrdet-support; + reset-names = "sdhci"; + vmmc-supply = <0x13>; + linux,phandle = <0x17a>; + non-removable; + ignore-pm-notify; + compad-vref-3v3 = <0x1>; + mmc-hs200-1_8v; + vqmmc-supply = <0x12>; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + max-clk-limit = <0xbebc200>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod { + prod = <0x100 0x1fff002e 0x50b0028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x5090000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs400 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + }; + }; + + // virtio_serial@f0a003000 { + // compatible = "virtio,mmio"; + // dma-coherent; + // interrupts = <0x0 0x10f 0x1>; + // reg = <0xf 0xa003000 0x0 0x400>; + // }; + + bthrot_cdev { + compatible = "nvidia,tegra18x-balanced-throttle"; + clocks = <0x10 0x242 0x10 0x243 0x10 0x136 0x10 0x3a>; + clock-names = "mcpu", "bcpu", "gpu", "emc"; + + skin_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x1d8760 0x1d8760 0x1314c4 0xffffffff 0x1d2658 0x1d2658 0x12cf9c 0xffffffff 0x1cc550 0x1cc550 0x128a74 0xffffffff 0x1c6448 0x1c6448 0x12454c 0xffffffff 0x1c0340 0x1c0340 0x120025 0xffffffff 0x1ba238 0x1ba238 0x11bafd 0xffffffff 0x1b4130 0x1b4130 0x1175d5 0xffffffff 0x1ae028 0x1ae028 0x1130ad 0xffffffff 0x1a7f20 0x1a7f20 0x10eb85 0xffffffff 0x1a1e18 0x1a1e18 0x10a65d 0xffffffff 0x19bd10 0x19bd10 0x106136 0xffffffff 0x195c08 0x195c08 0x101c0e 0xffffffff 0x18fb00 0x18fb00 0xfd6e6 0xffffffff 0x1899f8 0x1899f8 0xf91be 0xffffffff 0x1838f0 0x1838f0 0xf4c96 0xffffffff 0x17d7e8 0x17d7e8 0xf076e 0xffffffff 0x1776e0 0x1776e0 0xec246 0xffffffff 0x1715d8 0x1715d8 0xe7d1f 0xffffffff 0x16b4d0 0x16b4d0 0xe37f7 0xffffffff 0x1653c8 0x1653c8 0xdf2cf 0xffffffff 0x15f2c0 0x15f2c0 0xdada7 0xffffffff 0x1591b8 0x1591b8 0xd687f 0xffffffff 0x1530b0 0x1530b0 0xd2357 0xffffffff 0x14cfa8 0x14cfa8 0xcde30 0xffffffff 0x146ea0 0x146ea0 0xc9908 0xffffffff 0x140d98 0x140d98 0xc53e0 0xffffffff 0x13ac90 0x13ac90 0xc0eb8 0xffffffff 0x134b88 0x134b88 0xbc990 0xffffffff 0x12ea80 0x12ea80 0xb8468 0xffffffff 0x128978 0x128978 0xb3f40 0xffffffff 0x122870 0x122870 0xafa19 0xffffffff 0x11c768 0x11c768 0xab4f1 0xffffffff 0x116660 0x116660 0xa6fc9 0xffffffff 0x110558 0x110558 0xa2aa1 0xffffffff 0x10a450 0x10a450 0x9e579 0xffffffff 0x104348 0x104348 0x9a051 0xffffffff 0xfe240 0xfe240 0x95b2a 0xffffffff 0xf8138 0xf8138 0x91602 0xffffffff 0xf2030 0xf2030 0x8d0da 0xffffffff 0xebf28 0xebf28 0x88bb2 0xffffffff 0xe5e20 0xe5e20 0x8468a 0xffffffff 0xdfd18 0xdfd18 0x80162 0xffffffff 0xd9c10 0xd9c10 0x7bc3a 0xffffffff 0xd3b08 0xd3b08 0x77713 0xffffffff 0xcda00 0xcda00 0x731eb 0xffffffff 0xc78f8 0xc78f8 0x6ecc3 0xffffffff 0xc17f0 0xc17f0 0x6a79b 0xffffffff 0xbb6e8 0xbb6e8 0x66273 0xffffffff 0xb55e0 0xb55e0 0x61d4b 0xffffffff 0xaf4d8 0xaf4d8 0x5d824 0xffffffff 0xa93d0 0xa93d0 0x592fc 0xffffffff 0xa32c8 0xa32c8 0x54dd4 0xffffffff 0x9d1c0 0x9d1c0 0x508ac 0xffffffff 0x970b8 0x970b8 0x4c384 0xffffffff 0x90fb0 0x90fb0 0x47e5c 0xffffffff 0x8aea8 0x8aea8 0x43934 0xffffffff 0x84da0 0x84da0 0x3f40d 0xffffffff 0x7ec98 0x7ec98 0x3aee5 0xffffffff 0x78b90 0x78b90 0x369bd 0xffffffff 0x72a88 0x72a88 0x32495 0xffffffff 0x6c980 0x6c980 0x2df6d 0xffffffff 0x66878 0x66878 0x29a45 0xffffffff 0x60770 0x60770 0x2551e 0xffffffff 0x5a668 0x5a668 0x20ff6 0xffffffff 0x54560 0x54560 0x1cace 0xffffffff 0x4e458 0x4e458 0x185a6 0xffffffff>; + cooling-max-state = <0x42>; + #cooling-cells = <0x2>; + cdev-type = "skin-balanced"; + }; + + gpu_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x1d8760 0x1d8760 0x12b31c 0xffffffff 0x1d2658 0x1d2658 0x125ce2 0xffffffff 0x1cc550 0x1cc550 0x1206a9 0xffffffff 0x1c6448 0x1c6448 0x11b06f 0xffffffff 0x1c0340 0x1c0340 0x115a36 0xffffffff 0x1ba238 0x1ba238 0x1103fc 0xffffffff 0x1b4130 0x1b4130 0x10adc3 0xffffffff 0x1ae028 0x1ae028 0x105789 0xffffffff 0x1a7f20 0x1a7f20 0x100150 0xffffffff 0x1a1e18 0x1a1e18 0xfab16 0xffffffff 0x19bd10 0x19bd10 0xf54dd 0xffffffff 0x195c08 0x195c08 0xefea3 0xffffffff 0x18fb00 0x18fb00 0xea86a 0xffffffff 0x1899f8 0x1899f8 0xe5230 0xffffffff 0x1838f0 0x1838f0 0xdfbf7 0xffffffff 0x17d7e8 0x17d7e8 0xda5bd 0xffffffff 0x1776e0 0x1776e0 0xd4f84 0xffffffff 0x1715d8 0x1715d8 0xcf94a 0xffffffff 0x16b4d0 0x16b4d0 0xca310 0xffffffff 0x1653c8 0x1653c8 0xc4cd7 0xffffffff 0x15f2c0 0x15f2c0 0xbf69d 0xffffffff 0x1591b8 0x1591b8 0xba064 0xffffffff 0x1530b0 0x1530b0 0xb4a2a 0xffffffff 0x14cfa8 0x14cfa8 0xaf3f1 0xffffffff 0x146ea0 0x146ea0 0xa9db7 0xffffffff 0x140d98 0x140d98 0xa477e 0xffffffff 0x13ac90 0x13ac90 0x9f144 0xffffffff 0x134b88 0x134b88 0x99b0b 0xffffffff 0x12ea80 0x12ea80 0x944d1 0xffffffff 0x128978 0x128978 0x8ee98 0xffffffff 0x122870 0x122870 0x8985e 0xffffffff 0x11c768 0x11c768 0x84225 0xffffffff 0x116660 0x116660 0x7ebeb 0xffffffff 0x110558 0x110558 0x795b2 0xffffffff 0x10a450 0x10a450 0x73f78 0xffffffff 0x104348 0x104348 0x6e93e 0xffffffff 0xfe240 0xfe240 0x69305 0xffffffff 0xf8138 0xf8138 0x63ccb 0xffffffff 0xf2030 0xf2030 0x5e692 0xffffffff 0xebf28 0xebf28 0x59058 0xffffffff 0xe5e20 0xe5e20 0x53a1f 0xffffffff 0xdfd18 0xdfd18 0x4e3e5 0xffffffff 0xd9c10 0xd9c10 0x48dac 0xffffffff 0xd3b08 0xd3b08 0x43772 0xffffffff 0xcda00 0xcda00 0x3e139 0xffffffff 0xc78f8 0xc78f8 0x38aff 0xffffffff 0xc17f0 0xc17f0 0x334c6 0xffffffff 0xbb6e8 0xbb6e8 0x2de8c 0xffffffff 0xb55e0 0xb55e0 0x28853 0xffffffff 0xaf4d8 0xaf4d8 0x23219 0xffffffff 0xa93d0 0xa93d0 0x1dbe0 0xffffffff 0xa32c8 0xa32c8 0x185a6 0xffffffff>; + phandle = <0x52>; + cooling-max-state = <0x34>; + #cooling-cells = <0x2>; + linux,phandle = <0x52>; + cdev-type = "gpu-balanced"; + }; + + cpu_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x1d8760 0x1d8760 0xffffffff 0xffffffff 0x1d2658 0x1d2658 0xffffffff 0xffffffff 0x1cc550 0x1cc550 0xffffffff 0xffffffff 0x1c6448 0x1c6448 0xffffffff 0xffffffff 0x1c0340 0x1c0340 0xffffffff 0xffffffff 0x1ba238 0x1ba238 0xffffffff 0xffffffff 0x1b4130 0x1b4130 0xffffffff 0xffffffff 0x1ae028 0x1ae028 0xffffffff 0xffffffff 0x1a7f20 0x1a7f20 0xffffffff 0xffffffff 0x1a1e18 0x1a1e18 0xffffffff 0xffffffff 0x19bd10 0x19bd10 0x13d814 0xffffffff 0x195c08 0x195c08 0x1382cc 0xffffffff 0x18fb00 0x18fb00 0x132d84 0xffffffff 0x1899f8 0x1899f8 0x12d83d 0xffffffff 0x1838f0 0x1838f0 0x1282f5 0xffffffff 0x17d7e8 0x17d7e8 0x122dad 0xffffffff 0x1776e0 0x1776e0 0x11d865 0xffffffff 0x1715d8 0x1715d8 0x11831d 0xffffffff 0x16b4d0 0x16b4d0 0x112dd5 0xffffffff 0x1653c8 0x1653c8 0x10d88e 0xffffffff 0x15f2c0 0x15f2c0 0x108346 0xffffffff 0x1591b8 0x1591b8 0x102dfe 0xffffffff 0x1530b0 0x1530b0 0xfd8b6 0xffffffff 0x14cfa8 0x14cfa8 0xf836e 0xffffffff 0x146ea0 0x146ea0 0xf2e27 0xffffffff 0x140d98 0x140d98 0xed8df 0xffffffff 0x13ac90 0x13ac90 0xe8397 0xffffffff 0x134b88 0x134b88 0xe2e4f 0xffffffff 0x12ea80 0x12ea80 0xdd907 0xffffffff 0x128978 0x128978 0xd83bf 0xffffffff 0x122870 0x122870 0xd2e78 0xffffffff 0x11c768 0x11c768 0xcd930 0xffffffff 0x116660 0x116660 0xc83e8 0xffffffff 0x110558 0x110558 0xc2ea0 0xffffffff 0x10a450 0x10a450 0xbd958 0xffffffff 0x104348 0x104348 0xb8411 0xffffffff 0xfe240 0xfe240 0xb2ec9 0xffffffff 0xf8138 0xf8138 0xad981 0xffffffff 0xf2030 0xf2030 0xa8439 0xffffffff 0xebf28 0xebf28 0xa2ef1 0xffffffff 0xe5e20 0xe5e20 0x9d9a9 0xffffffff 0xdfd18 0xdfd18 0x98462 0xffffffff 0xd9c10 0xd9c10 0x92f1a 0xffffffff 0xd3b08 0xd3b08 0x8d9d2 0xffffffff 0xcda00 0xcda00 0x8848a 0xffffffff 0xc78f8 0xc78f8 0x82f42 0xffffffff 0xc17f0 0xc17f0 0x7d9fb 0xffffffff 0xbb6e8 0xbb6e8 0x784b3 0xffffffff 0xb55e0 0xb55e0 0x72f6b 0xffffffff 0xaf4d8 0xaf4d8 0x6da23 0xffffffff 0xa93d0 0xa93d0 0x684db 0xffffffff 0xa32c8 0xa32c8 0x62f93 0xffffffff 0x9d1c0 0x9d1c0 0x5da4c 0xffffffff 0x970b8 0x970b8 0x58504 0xffffffff 0x90fb0 0x90fb0 0x52fbc 0xffffffff 0x8aea8 0x8aea8 0x4da74 0xffffffff 0x84da0 0x84da0 0x4852c 0xffffffff 0x7ec98 0x7ec98 0x42fe5 0xffffffff 0x78b90 0x78b90 0x3da9d 0xffffffff 0x72a88 0x72a88 0x38555 0xffffffff 0x6c980 0x6c980 0x3300d 0xffffffff 0x66878 0x66878 0x2dac5 0xffffffff 0x60770 0x60770 0x2857d 0xffffffff 0x5a668 0x5a668 0x23036 0xffffffff 0x54560 0x54560 0x1daee 0xffffffff 0x4e458 0x4e458 0x185a6 0xffffffff>; + phandle = <0x49>; + cooling-max-state = <0x42>; + #cooling-cells = <0x2>; + linux,phandle = <0x49>; + cdev-type = "cpu-balanced"; + }; + + emergency_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x111ed0 0x111ed0 0x5f758 0x60ae0>; + phandle = <0x55>; + cooling-max-state = <0x1>; + #cooling-cells = <0x2>; + linux,phandle = <0x55>; + cdev-type = "emergency-balanced"; + }; + }; + + ufshci@2450000 { + compatible = "tegra,ufs_variant"; + clocks = <0x10 0x94 0x10 0x8e 0x10 0x93 0x10 0x90 0x10 0x8c 0x10 0x8f 0x10 0x8d 0x10 0x91 0x10 0x27a 0x10 0xb2 0x10 0xb3 0x10 0x10d 0x10 0x261>; + nvidia,enable-wlu-scsi-device-add; + resets = <0x10 0x56 0x10 0x57 0x10 0x94 0x10 0x95 0x10 0x93 0x10 0x71 0x10 0x72 0x10 0xc0>; + nvidia,max-pwm-gear = <0x4>; + nvidia,enable-x2-config; + nvidia,enable-hs-mode; + pinctrl-1 = <0x24>; + nvidia,max-hs-gear = <0x3>; + clock-names = "mphy_core_pll_fixed", "mphy_l0_tx_symb", "mphy_tx_1mhz_ref", "mphy_l0_rx_ana", "mphy_l0_rx_symb", "mphy_l0_tx_ls_3xbit", "mphy_l0_rx_ls_bit", "mphy_l1_rx_ana", "mphy_force_ls_mode", "ufshc", "ufsdev_ref", "pll_p", "clk_m"; + vccq-max-microamp = <0x0>; + nvidia,enable-rx-calib; + vcc-max-microamp = <0x0>; + nvidia,enable-hibern8-war; + status = "disabled"; + interrupts = <0x0 0x2c 0x4>; + vccq2-max-microamp = <0x0>; + phandle = <0x104>; + reg = <0x0 0x2450000 0x0 0x4000>; + iommus = <0x11 0x15>; + pinctrl-0 = <0x23>; + reset-names = "mphy-l0-rx-rst", "mphy-l0-tx-rst", "mphy-l1-rx-rst", "mphy-l1-tx-rst", "mphy-clk-ctl-rst", "ufs-rst", "ufs-axi-m-rst", "ufshc-lp-rst"; + linux,phandle = <0x104>; + nvidia,mask-fast-auto-mode; + pinctrl-names = "ufs_dpd_enable", "ufs_dpd_disable"; + + ufs_variant { + compatible = "tegra,ufs_variant"; + }; + }; + + pwm@32a0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbd 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x65>; + clock-names = "pwm", "parent", "slow-parent"; + status = "okay"; + phandle = <0xeb>; + reg = <0x0 0x32a0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0xeb>; + #pwm-cells = <0x2>; + }; + + thermal-zones { + status = "okay"; + + GPU-therm { + thermal-sensors = <0x47 0x6>; + polling-delay = <0x0>; + polling-delay-passive = <0xfa>; + status = "okay"; + + trips { + + eqos-m40@-40000 { + hysteresis = <0x1388>; + temperature = <0xffff63c0>; + type = "active"; + phandle = <0x4b>; + linux,phandle = <0x4b>; + }; + + eqos-p30@30000 { + hysteresis = <0x1388>; + temperature = <0x7530>; + type = "active"; + phandle = <0x4e>; + linux,phandle = <0x4e>; + }; + + trip_critical { + hysteresis = <0x0>; + temperature = <0x18894>; + type = "critical"; + writable; + }; + + eqos-p100@100000 { + hysteresis = <0x1388>; + temperature = <0x186a0>; + type = "active"; + phandle = <0x50>; + linux,phandle = <0x50>; + }; + + trip_bthrot { + hysteresis = <0x0>; + temperature = <0x1750c>; + type = "passive"; + phandle = <0x51>; + writable; + linux,phandle = <0x51>; + }; + + eqos-p65@65000 { + hysteresis = <0x1388>; + temperature = <0xfde8>; + type = "active"; + phandle = <0x4f>; + linux,phandle = <0x4f>; + }; + + eqos-m5@-5000 { + hysteresis = <0x1388>; + temperature = <0xffffec78>; + type = "active"; + phandle = <0x4d>; + linux,phandle = <0x4d>; + }; + }; + + cooling-maps { + + map_eqos_m5 { + trip = <0x4d>; + cooling-device = <0x4c 0x2 0x2>; + cdev-type = "tegra-eqos"; + }; + + map0 { + trip = <0x51>; + cooling-device = <0x52 0xffffffff 0xffffffff>; + cdev-type = "gpu-balanced"; + }; + + map_eqos_p30 { + trip = <0x4e>; + cooling-device = <0x4c 0x3 0x3>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_m40 { + trip = <0x4b>; + cooling-device = <0x4c 0x1 0x1>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_p65 { + trip = <0x4f>; + cooling-device = <0x4c 0x4 0x4>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_p100 { + trip = <0x50>; + cooling-device = <0x4c 0x5 0x5>; + cdev-type = "tegra-eqos"; + }; + }; + + thermal-zone-params { + governor-name = "step_wise"; + }; + }; + + AO-therm { + thermal-sensors = <0x47 0x6>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "disabled"; + phandle = <0xe7>; + linux,phandle = <0xe7>; + }; + + MCPU-therm { + thermal-sensors = <0x47 0x4>; + polling-delay = <0x0>; + polling-delay-passive = <0x1f4>; + status = "okay"; + + trips { + + trip_critical { + hysteresis = <0x0>; + temperature = <0x18894>; + type = "critical"; + writable; + }; + + trip_bthrot { + hysteresis = <0x0>; + temperature = <0x1750c>; + type = "passive"; + phandle = <0x4a>; + writable; + linux,phandle = <0x4a>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x4a>; + cooling-device = <0x49 0xffffffff 0xffffffff>; + cdev-type = "cpu-balanced"; + }; + }; + + thermal-zone-params { + governor-name = "step_wise"; + }; + }; + + BCPU-therm { + thermal-sensors = <0x47 0x2>; + polling-delay = <0x0>; + polling-delay-passive = <0x1f4>; + status = "okay"; + + trips { + + trip_critical { + hysteresis = <0x0>; + temperature = <0x18894>; + type = "critical"; + writable; + }; + + trip_bthrot { + hysteresis = <0x0>; + temperature = <0x1750c>; + type = "passive"; + phandle = <0x48>; + writable; + linux,phandle = <0x48>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x48>; + cooling-device = <0x49 0xffffffff 0xffffffff>; + cdev-type = "cpu-balanced"; + }; + }; + + thermal-zone-params { + governor-name = "step_wise"; + }; + }; + + PLL-therm { + thermal-sensors = <0x47 0x5>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "okay"; + }; + + PMIC-Die { + thermal-sensors = <0x22>; + polling-delay = <0x0>; + polling-delay-passive = <0x0>; + + trips { + + hot-die { + hysteresis = <0x0>; + temperature = <0x1d4c0>; + type = "active"; + phandle = <0x54>; + linux,phandle = <0x54>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x54>; + contribution = <0x64>; + cooling-device = <0x55 0xffffffff 0xffffffff>; + cdev-type = "emergency-balanced"; + }; + }; + }; + + Tboard_tegra { + thermal-sensors = <0x53 0x0>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "okay"; + phandle = <0xf5>; + linux,phandle = <0xf5>; + + trips { + + trip_critical { + hysteresis = <0x1>; + temperature = <0x1a1f8>; + type = "critical"; + }; + }; + + thermal-zone-params { + governor-name = "pid_thermal_gov"; + }; + }; + + Tdiode_tegra { + thermal-sensors = <0x53 0x1>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "okay"; + phandle = <0x19b>; + linux,phandle = <0x19b>; + + trips { + + trip_critical { + hysteresis = <0x0>; + temperature = <0x1a1f8>; + type = "critical"; + writable; + }; + }; + + thermal-zone-params { + governor-name = "pid_thermal_gov"; + }; + }; + }; + + aon@c160000 { + compatible = "nvidia,tegra186-aon"; + nvidia,ivc-rx-ss = <0x2>; + nvidia,ivc-dbg-enable-ss = <0x0>; + nvidia,hsp-shared-mailbox-names = "ivc-pair"; + nvidia,hsp-shared-mailbox = <0xe8 0x2>; + #mbox-cells = <0x1>; + status = "okay"; + nvidia,ivc-carveout-size-ss = <0x1>; + phandle = <0x41>; + nvidia,ivc-tx-ss = <0x3>; + reg = <0x0 0xc1a0000 0x0 0x40000>; + iommus = <0x11 0x16>; + linux,phandle = <0x41>; + nvidia,ivc-carveout-base-ss = <0x0>; + + ivc-channels@80000000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + + ivc_aon_echo@0 { + nvidia,frame-size = <0x40>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0x0 0x10000>; + }; + + ivc_can1@d000 { + nvidia,frame-size = <0x80>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0xd000 0x1d000>; + }; + + ivc_aon_spi@600 { + nvidia,frame-size = <0x6080>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x2>; + reg = <0x600 0x10600>; + }; + + ivc_aon_aondbg@480 { + nvidia,frame-size = <0x80>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x2>; + reg = <0x480 0x10480>; + }; + + ivc_can0@c780 { + nvidia,frame-size = <0x80>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0xc780 0x1c780>; + }; + + ivc_aon_shub@d880 { + nvidia,frame-size = <0x100>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x4>; + reg = <0xd880 0x1d880>; + }; + }; + }; + + sdhci@3460000 { + nvidia,ddr-tap-delay = <0x9>; + cap-mmc-highspeed; + nvidia,en-periodic-cflush; + nvidia,enable-hwcq; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x36 0x10 0x10d 0x10 0x114 0x10 0x80>; + mmc-ddr-1_8v; + cap-sd-highspeed; + resets = <0x10 0x24>; + nvidia,parent_clk_list = "pll_p", "pll_p", "pll_p", "pll_p", "pll_p", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0"; + nvidia,is-emmc; + nvidia,clk-en-before-freq-update; + clock-names = "sdmmc", "pll_p", "pll_c4_out0", "sdmmc_legacy_tm"; + pll_source = "pll_p", "pll_c4_out0"; + only-1-8-v; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "NILL"; + nvidia,max-tap-delay = <0x88>; + nvidia,enable-strobe-mode; + interrupts = <0x0 0x41 0x4>; + bus-width = <0x8>; + nvidia,periodic-cflush-to = <0x64>; + ddr-trim-delay = <0x5>; + mmc-hs400-1_8v; + phandle = <0x101>; + calib-1v8-offsets = <0x505>; + tap-delay = <0x9>; + mmc-hs400-enhanced-strobe; + reg = <0x0 0x3460000 0x0 0x210>; + iommus = <0x11 0x17>; + mmc-ocr-mask = <0x0>; + compad-vref-1v8 = <0x7>; + trim-delay = <0x5>; + reset-names = "sdhci"; + vmmc-supply = <0x13>; + uhs-mask = <0x0>; + linux,phandle = <0x101>; + nvidia,set-parent-clk; + non-removable; + ignore-pm-notify; + compad-vref-3v3 = <0x7>; + calib-3v3-offsets = <0x505>; + mmc-hs200-1_8v; + vqmmc-supply = <0x12>; + max-clk-limit = <0xbb288cc>; + + prod-settings { + #prod-cells = <0x3>; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x10c 0x3f00 0x3f00 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x5090000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000505>; + }; + + prod_c_hs533 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x2000 0x1e0 0xf 0x7 0x1e4 0x20000000 0x20000505>; + }; + + prod_c_hs400 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x10c 0x3f00 0x3f00 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000505>; + }; + }; + }; + + vi-bypass@15700000 { + compatible = "nvidia,tegra186-vi-bypass"; + status = "okay"; + }; + + etf@8030000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + clocks = <0x10 0xc4>; + coresight-default-sink; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8030000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe2>; + phandle = <0xe0>; + linux,phandle = <0xe0>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe1>; + phandle = <0xda>; + slave-mode; + linux,phandle = <0xda>; + }; + }; + }; + }; + + pwm@32e0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xc0 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x69>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x18b>; + reg = <0x0 0x32e0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x18b>; + #pwm-cells = <0x2>; + }; + + aondbg { + compatible = "nvidia,tegra186-aondbg"; + mboxes = <0x41 0x1>; + }; + + pwm-fan { + active_pwm = <0x0 0x50 0x78 0xa0 0xff 0xff 0xff 0xff 0xff 0xff>; + compatible = "pwm-fan"; + vdd-fan-supply = <0xee>; + status = "okay"; + shared_data = <0xed>; + pwms = <0xec 0x0 0xb116>; + #pwm-cells = <0x1>; + }; + + funnel_major@8010000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8010000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@3 { + reg = <0x2>; + + endpoint { + remote-endpoint = <0xdc>; + phandle = <0xe5>; + slave-mode; + linux,phandle = <0xe5>; + }; + }; + + port@1 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xdb>; + phandle = <0xd5>; + slave-mode; + linux,phandle = <0xd5>; + }; + }; + + port@4 { + reg = <0x3>; + + endpoint { + remote-endpoint = <0xdd>; + phandle = <0xd2>; + slave-mode; + linux,phandle = <0xd2>; + }; + }; + + port@2 { + reg = <0x1>; + + endpoint { + phandle = <0x1dd>; + slave-mode; + linux,phandle = <0x1dd>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xda>; + phandle = <0xe1>; + linux,phandle = <0xe1>; + }; + }; + }; + }; + + gps_wake { + compatible = "gps-wake"; + gps-wakeup-gpio = <0x1b 0x85 0x0>; + status = "disabled"; + gps-enable-gpio = <0xea 0x8 0x0>; + phandle = <0x1e6>; + linux,phandle = <0x1e6>; + }; + + tegra-carveouts { + compatible = "nvidia,carveouts-t18x"; + memory-region = <0x95 0x96>; + }; + + bpmp { + carveout-start = <0x77800000>; + compatible = "nvidia,tegra186-bpmp"; + carveout-size = <0x200000>; + status = "okay"; + phandle = <0x1f>; + reg = <0x0 0xd000000 0x0 0x800000 0x0 0x3004e000 0x0 0x1000 0x0 0x3004f000 0x0 0x1000>; + iommus = <0x11 0x32>; + linux,phandle = <0x1f>; + #power-domain-cells = <0x1>; + + bpmpthermal { + compatible = "nvidia,tegra186-bpmp-thermal"; + #thermal-sensor-cells = <0x1>; + status = "okay"; + phandle = <0x47>; + linux,phandle = <0x47>; + }; + }; + + axip2p@2110000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2110000 0x0 0x1000>; + }; + + spi@3240000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0x4a 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x2b>; + clock-names = "spi", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p", "clk_m"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x27 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x185>; + reg = <0x0 0x3240000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x12 0x25 0x12>; + reset-names = "spi"; + linux,phandle = <0x185>; + + spi@1 { + compatible = "spidev"; + reg = <0x1>; + spi-max-frequency = <0x1f78a40>; + + controller-data { + nvidia,tx-clk-tap-delay = <0x16>; + nvidia,enable-hw-based-cs; + nvidia,rx-clk-tap-delay = <0x8>; + }; + }; + + spi@0 { + compatible = "spidev"; + reg = <0x0>; + spi-max-frequency = <0x1f78a40>; + + controller-data { + nvidia,tx-clk-tap-delay = <0x16>; + nvidia,enable-hw-based-cs; + nvidia,rx-clk-tap-delay = <0x8>; + }; + }; + }; + + timer@3020000 { + compatible = "nvidia,tegra186-timer"; + wdt-count = <0x3>; + tmr-count = <0xa>; + status = "okay"; + interrupts = <0x0 0x0 0x4 0x0 0x1 0x4 0x0 0x2 0x4 0x0 0x3 0x4 0x0 0x4 0x4 0x0 0x5 0x4 0x0 0x6 0x4>; + reg = <0x0 0x3010000 0x0 0xe0000>; + clock-frequency = <0x124f800>; + }; + + host1x { + nvidia,nb-channels = <0x3c>; + compatible = "nvidia,tegra186-host1x", "simple-bus"; + clocks = <0x10 0x39 0x10 0xc9>; + wakeup_capable; + resets = <0x10 0x12>; + nvidia,nb-hw-pts = <0x240>; + clock-names = "host1x", "actmon"; + nvidia,ch-base = <0x0>; + ranges; + status = "okay"; + #address-cells = <0x2>; + interrupts = <0x0 0x109 0x4 0x0 0x107 0x4>; + nvidia,nb-pts = <0x23c>; + #size-cells = <0x2>; + phandle = <0xb6>; + nvidia,pts-base = <0x0>; + reg = <0x0 0x13e10000 0x0 0x10000 0x0 0x13e00000 0x0 0x10000 0x0 0x13ec0000 0x0 0x40000>; + iommus = <0x11 0x1 0x11 0x40 0x11 0x41 0x11 0x42 0x11 0x43 0x11 0x44 0x11 0x45 0x11 0x46 0x11 0x47>; + nvidia,vmid = <0x1>; + linux,phandle = <0xb6>; + + ctx3 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c1>; + iommus = <0x11 0x3b>; + linux,phandle = <0x1c1>; + }; + + nvdec@15480000 { + power-domains = <0x1f 0x6>; + compatible = "nvidia,tegra186-nvdec"; + clocks = <0x10 0x81 0x10 0x125>; + resets = <0x10 0x7d>; + clock-names = "nvdec", "kfuse"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15480000 0x0 0x40000>; + iommus = <0x11 0x6>; + }; + + tsec@15500000 { + compatible = "nvidia,tegra186-tsec"; + clocks = <0x10 0x51>; + resets = <0x10 0x2e>; + clock-names = "tsec"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15500000 0x0 0x40000>; + iommus = <0x11 0xa>; + }; + + dpaux@15040000 { + power-domains = <0x94>; + compatible = "nvidia,tegra186-dpaux1"; + clocks = <0x10 0x5f>; + resets = <0x10 0x7c>; + clock-names = "dpaux1"; + nvidia,dpaux-ctrlnum = <0x1>; + status = "okay"; + interrupts = <0x0 0xa0 0x4>; + phandle = <0x91>; + reg = <0x0 0x15040000 0x0 0x40000>; + reset-names = "dpaux1"; + linux,phandle = <0x91>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_dpaux_hdmi { + prod = <0x124 0x700 0x400>; + }; + + prod_c_dpaux_dp { + prod = <0x124 0x37fe 0x24c2>; + }; + }; + }; + + ctx1 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1bf>; + iommus = <0x11 0x39>; + linux,phandle = <0x1bf>; + }; + + dsi { + compatible = "nvidia,tegra186-dsi"; + clocks = <0x10 0x73 0x10 0x75 0x10 0x76 0x10 0x77 0x10 0xe7 0x10 0xe8 0x10 0xe9 0x10 0xea>; + resets = <0x10 0x6 0x10 0x7 0x10 0x3f 0x10 0x40 0x10 0x91>; + nvidia,enable-hs-clk-in-lp-mode = <0x1>; + clock-names = "dsi", "dsia_lp", "dsib", "dsib_lp", "dsic", "dsic_lp", "dsid", "dsid_lp"; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + phandle = <0x83>; + reg = <0x0 0x15300000 0x0 0x40000 0x0 0x15400000 0x0 0x40000 0x0 0x15900000 0x0 0x40000 0x0 0x15940000 0x0 0x40000 0x0 0x15880000 0x0 0x10000>; + reset-names = "dsia", "dsib", "dsic", "dsid", "dsi_padctrl"; + linux,phandle = <0x83>; + + prod-settings { + #prod-cells = <0x3>; + + dsi-padctrl-prod { + prod = <0x1c 0x7 0x0 0x20 0x1 0x0 0x24 0x3f0fc3f 0x0 0x28 0x333333 0x0 0x30 0xffffff 0x0 0x34 0xffffff 0x777777 0x4c 0x7 0x0 0x50 0x1 0x0 0x54 0x3f0fc3f 0x0 0x58 0x333333 0x0 0x60 0xffffff 0x0 0x64 0xffffff 0x777777 0x7c 0x7 0x0 0x80 0x1 0x0 0x84 0x3f0fc3f 0x0 0x88 0x333333 0x0 0x90 0xffffff 0x0 0x94 0xffffff 0x777777 0xac 0x7 0x0 0xb0 0x1 0x0 0xb4 0x3f0fc3f 0x0 0xb8 0x333333 0x0 0xc0 0xffffff 0x0 0xc4 0xffffff 0x777777>; + }; + }; + + panel-s-wuxga-8-0 { + nvidia,dsi-ganged-type = <0x1>; + compatible = "s,wuxga-8-0"; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-ganged-swap-links = <0x1>; + nvidia,dsi-refresh-rate = <0x3c>; + nvidia,dsi-video-burst-mode = <0x0>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-video-clock-mode = <0x0>; + nvidia,panel-bl-en-gpio = <0x28 0xb 0x1>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + nvidia,dsi-n-init-cmd = <0x3>; + nvidia,dsi-suspend-stop-stream-late = <0x1>; + nvidia,panel-en-gpio = <0x8d 0x4 0x1>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-init-cmd = <0x0 0x5 0x11 0x0 0x0 0x3 0xa 0x0 0x5 0x29 0x0 0x0>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-video-data-type = <0x0>; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + phandle = <0x102>; + nvidia,dsi-suspend-cmd = <0x0 0x5 0x28 0x0 0x0 0x3 0x3 0x0 0x5 0x10 0x0 0x0 0x3 0xa>; + nvidia,dsi-n-suspend-cmd = <0x4>; + nvidia,dsi-pkt-seq = <0x1 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff>; + nvidia,dsi-instance = <0x0>; + nvidia,dsi-panel-reset = <0x1>; + nvidia,default_color_space = <0x0>; + nvidia,en-vmm-vpp-with-i2c-config; + linux,phandle = <0x102>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,panel-bl-pwm-gpio = <0x28 0x8 0x1>; + + cmu { + nvidia,cmu-csc = <0x100 0x0 0x0 0x0 0x100 0x0 0x0 0x0 0x100>; + nvidia,cmu-lut2 = <0x0 0x1 0x2 0x2 0x3 0x4 0x5 0x6 0x6 0x7 0x8 0x9 0xa 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0xf 0x10 0x10 0x11 0x12 0x12 0x13 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x17 0x18 0x18 0x19 0x19 0x19 0x1a 0x1a 0x1b 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1d 0x1e 0x1e 0x1e 0x1f 0x1f 0x1f 0x20 0x20 0x20 0x21 0x21 0x21 0x22 0x22 0x22 0x22 0x23 0x23 0x23 0x24 0x24 0x24 0x25 0x25 0x25 0x25 0x26 0x26 0x26 0x26 0x27 0x27 0x27 0x28 0x28 0x28 0x28 0x29 0x29 0x29 0x29 0x2a 0x2a 0x2a 0x2a 0x2b 0x2b 0x2b 0x2b 0x2b 0x2c 0x2c 0x2c 0x2c 0x2d 0x2d 0x2d 0x2d 0x2e 0x2e 0x2e 0x2e 0x2e 0x2f 0x2f 0x2f 0x2f 0x30 0x30 0x30 0x30 0x30 0x31 0x31 0x31 0x31 0x31 0x32 0x32 0x32 0x32 0x32 0x33 0x33 0x33 0x33 0x33 0x34 0x34 0x34 0x34 0x34 0x35 0x35 0x35 0x35 0x35 0x36 0x36 0x36 0x36 0x36 0x37 0x37 0x37 0x37 0x37 0x37 0x38 0x38 0x38 0x38 0x38 0x39 0x39 0x39 0x39 0x39 0x39 0x3a 0x3a 0x3a 0x3a 0x3a 0x3a 0x3b 0x3b 0x3b 0x3b 0x3b 0x3b 0x3c 0x3c 0x3c 0x3c 0x3c 0x3c 0x3d 0x3d 0x3d 0x3d 0x3d 0x3d 0x3e 0x3e 0x3e 0x3e 0x3e 0x3e 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x40 0x40 0x40 0x40 0x40 0x40 0x40 0x41 0x41 0x41 0x41 0x41 0x41 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x44 0x44 0x44 0x44 0x44 0x44 0x44 0x45 0x45 0x45 0x45 0x45 0x45 0x45 0x46 0x46 0x46 0x46 0x46 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x49 0x49 0x49 0x49 0x49 0x49 0x49 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x63 0x63 0x63 0x63 0x63 0x63 0x63 0x64 0x65 0x65 0x66 0x67 0x67 0x68 0x69 0x69 0x6a 0x6b 0x6b 0x6c 0x6d 0x6d 0x6e 0x6f 0x6f 0x70 0x71 0x71 0x72 0x73 0x73 0x74 0x74 0x75 0x76 0x76 0x77 0x77 0x78 0x78 0x79 0x7a 0x7a 0x7b 0x7b 0x7c 0x7c 0x7d 0x7e 0x7e 0x7f 0x7f 0x80 0x80 0x81 0x81 0x82 0x82 0x83 0x83 0x84 0x84 0x85 0x85 0x86 0x86 0x87 0x87 0x88 0x88 0x89 0x89 0x8a 0x8a 0x8b 0x8b 0x8c 0x8c 0x8d 0x8d 0x8e 0x8e 0x8f 0x8f 0x90 0x90 0x91 0x91 0x91 0x92 0x92 0x93 0x93 0x94 0x94 0x95 0x95 0x96 0x96 0x96 0x97 0x97 0x98 0x98 0x99 0x99 0x99 0x9a 0x9a 0x9b 0x9b 0x9c 0x9c 0x9c 0x9d 0x9d 0x9e 0x9e 0x9e 0x9f 0x9f 0xa0 0xa0 0xa0 0xa1 0xa1 0xa2 0xa2 0xa2 0xa3 0xa3 0xa4 0xa4 0xa4 0xa5 0xa5 0xa6 0xa6 0xa6 0xa7 0xa7 0xa7 0xa8 0xa8 0xa9 0xa9 0xa9 0xaa 0xaa 0xaa 0xab 0xab 0xac 0xac 0xac 0xad 0xad 0xad 0xae 0xae 0xae 0xaf 0xaf 0xb0 0xb0 0xb0 0xb1 0xb1 0xb1 0xb2 0xb2 0xb2 0xb3 0xb3 0xb3 0xb4 0xb4 0xb4 0xb5 0xb5 0xb6 0xb6 0xb6 0xb7 0xb7 0xb7 0xb8 0xb8 0xb8 0xb9 0xb9 0xb9 0xba 0xba 0xba 0xbb 0xbb 0xbb 0xbc 0xbc 0xbc 0xbd 0xbd 0xbd 0xbd 0xbe 0xbe 0xbe 0xbf 0xbf 0xbf 0xc0 0xc0 0xc0 0xc1 0xc1 0xc1 0xc2 0xc2 0xc2 0xc3 0xc3 0xc3 0xc4 0xc4 0xc4 0xc4 0xc5 0xc5 0xc5 0xc6 0xc6 0xc6 0xc7 0xc7 0xc7 0xc8 0xc8 0xc8 0xc8 0xc9 0xc9 0xc9 0xca 0xca 0xca 0xca 0xcb 0xcb 0xcb 0xcc 0xcc 0xcc 0xcd 0xcd 0xcd 0xcd 0xce 0xce 0xce 0xcf 0xcf 0xcf 0xcf 0xd0 0xd0 0xd0 0xd1 0xd1 0xd1 0xd1 0xd2 0xd2 0xd2 0xd3 0xd3 0xd3 0xd3 0xd4 0xd4 0xd4 0xd5 0xd5 0xd5 0xd5 0xd6 0xd6 0xd6 0xd6 0xd7 0xd7 0xd7 0xd8 0xd8 0xd8 0xd8 0xd9 0xd9 0xd9 0xd9 0xda 0xda 0xda 0xdb 0xdb 0xdb 0xdb 0xdc 0xdc 0xdc 0xdc 0xdd 0xdd 0xdd 0xdd 0xde 0xde 0xde 0xdf 0xdf 0xdf 0xdf 0xe0 0xe0 0xe0 0xe0 0xe1 0xe1 0xe1 0xe1 0xe2 0xe2 0xe2 0xe2 0xe3 0xe3 0xe3 0xe3 0xe4 0xe4 0xe4 0xe4 0xe5 0xe5 0xe5 0xe5 0xe6 0xe6 0xe6 0xe6 0xe7 0xe7 0xe7 0xe7 0xe8 0xe8 0xe8 0xe8 0xe9 0xe9 0xe9 0xe9 0xea 0xea 0xea 0xea 0xeb 0xeb 0xeb 0xeb 0xec 0xec 0xec 0xec 0xed 0xed 0xed 0xed 0xee 0xee 0xee 0xee 0xef 0xef 0xef 0xef 0xf0 0xf0 0xf0 0xf0 0xf0 0xf1 0xf1 0xf1 0xf1 0xf2 0xf2 0xf2 0xf2 0xf3 0xf3 0xf3 0xf3 0xf4 0xf4 0xf4 0xf4 0xf4 0xf5 0xf5 0xf5 0xf5 0xf6 0xf6 0xf6 0xf6 0xf7 0xf7 0xf7 0xf7 0xf7 0xf8 0xf8 0xf8 0xf8 0xf9 0xf9 0xf9 0xf9 0xf9 0xfa 0xfa 0xfa 0xfa 0xfb 0xfb 0xfb 0xfb 0xfb 0xfc 0xfc 0xfc 0xfc 0xfd 0xfd 0xfd 0xfd 0xfd 0xfe 0xfe 0xfe 0xfe 0xff 0xff>; + }; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,turn-on-brightness = <0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "disabled"; + nvidia,smooth-k-incr = <0x4>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,turn-off-brightness = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,backlight_table = <0xff 0xf3 0xe8 0xde 0xd4 0xcb 0xc2 0xba 0xb3 0xab 0xa5 0x9e 0x98 0x92 0x8d 0x88 0x83 0x7e 0x7a 0x76 0x72 0x6e 0x6a 0x67 0x64 0x60 0x5d 0x5a 0x58 0x55 0x53 0x50 0x4e 0x4c 0x49 0x47 0x45 0x43 0x42 0x40 0x3e 0x3d 0x3b 0x3a 0x38 0x37 0x35 0x34 0x33 0x31 0x30>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,sw-update-delay = <0x0>; + nvidia,gain_table = <0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x4250 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x42b4 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x44e0 0x4304 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4660 0x4570 0x4318 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x4768 0x45e8 0x433c 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f0 0x482c 0x4644 0x4354 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a00 0x48c4 0x4688 0x4368 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4af4 0x4960 0x46e0 0x4388 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ca8 0x4ba8 0x49c0 0x4708 0x4390 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4db0 0x4c60 0x4a34 0x4748 0x43ac 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f48 0x4e78 0x4cd4 0x4a6c 0x475c 0x43ac 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x5060 0x4f44 0x4d60 0x4ac4 0x478c 0x43c0 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x5158 0x4ff8 0x4dd8 0x4b14 0x47b4 0x43d0 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5314 0x5238 0x5098 0x4e44 0x4b54 0x47d8 0x43dc 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5424 0x5300 0x5124 0x4ea4 0x4b90 0x47f8 0x43e8 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55b8 0x5518 0x53b4 0x51a4 0x4ef8 0x4bc4 0x4814 0x43f0 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x56dc 0x55f4 0x5458 0x5214 0x4f44 0x4bf0 0x4828 0x43f8 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x57e8 0x56bc 0x54e8 0x527c 0x4f88 0x4c18 0x483c 0x4400 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5990 0x58f4 0x579c 0x559c 0x5308 0x4ff4 0x4c64 0x486c 0x4414 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ab8 0x59d4 0x5840 0x5614 0x5358 0x5024 0x4c80 0x4878 0x4418 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5bd8 0x5ac4 0x5908 0x56b4 0x53d8 0x5084 0x4cc4 0x48a4 0x4428 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d68 0x5cd0 0x5b80 0x5990 0x5714 0x5418 0x50a8 0x4cd8 0x48ac 0x442c 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5e9c 0x5dd4 0x5c58 0x5a40 0x57a0 0x5484 0x50fc 0x4d10 0x48cc 0x443c 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x5fc4 0x5ecc 0x5d24 0x5ae8 0x5828 0x54ec 0x514c 0x4d48 0x48f0 0x4448 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x60c4 0x5f8c 0x5db4 0x5b50 0x586c 0x5518 0x5160 0x4d50 0x48f0 0x4448 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x6280 0x61cc 0x606c 0x5e6c 0x5be4 0x58e0 0x5574 0x51a4 0x4d80 0x490c 0x4454 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63ac 0x62cc 0x6140 0x5f1c 0x5c70 0x5950 0x55cc 0x51e4 0x4dac 0x4928 0x4460 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x64cc 0x63c0 0x6208 0x5fc0 0x5cf8 0x59bc 0x561c 0x5220 0x4dd4 0x4940 0x446c 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x65e0 0x64a4 0x62c8 0x605c 0x5d78 0x5a20 0x5668 0x525c 0x4dfc 0x4958 0x4474 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x679c 0x66e8 0x6584 0x6380 0x60f4 0x5df0 0x5a80 0x56b0 0x5290 0x4e20 0x4970 0x4480 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68c8 0x67e8 0x6654 0x642c 0x6180 0x5e60 0x5ad8 0x56f4 0x52c0 0x4e44 0x4984 0x4488 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x69ec 0x68d8 0x6720 0x64d4 0x6208 0x5ecc 0x5b2c 0x5734 0x52f0 0x4e60 0x4994 0x4490 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b80 0x6b00 0x69c0 0x67e0 0x6570 0x6288 0x5f30 0x5b7c 0x5770 0x531c 0x4e80 0x49a8 0x4494 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6cc4 0x6c24 0x6acc 0x68d0 0x6648 0x6344 0x5fd8 0x5c08 0x57e4 0x5378 0x4ec4 0x49d4 0x44ac 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6df8 0x6d28 0x6ba0 0x6980 0x66d8 0x63b8 0x6034 0x5c50 0x5818 0x539c 0x4edc 0x49e0 0x44b0 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f1c 0x6e1c 0x6c6c 0x6a28 0x6760 0x6428 0x6088 0x5c90 0x584c 0x53c0 0x4ef4 0x49ec 0x44b4 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x7034 0x6f04 0x6d30 0x6ac8 0x67e0 0x648c 0x60d8 0x5cd0 0x5878 0x53e0 0x4f08 0x49f8 0x44bc 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x7160 0x7014 0x6e24 0x6ba4 0x68a4 0x6538 0x616c 0x5d4c 0x58e0 0x5430 0x4f44 0x4a20 0x44cc 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7320 0x7264 0x70ec 0x6ed4 0x6c34 0x6918 0x6594 0x61b4 0x5d84 0x5908 0x544c 0x4f54 0x4a2c 0x44d0 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x745c 0x7384 0x71f0 0x6fc0 0x6d04 0x69d4 0x6638 0x6244 0x5dfc 0x5968 0x5498 0x4f90 0x4a50 0x44e0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x7580 0x7474 0x72b8 0x7064 0x6d88 0x6a3c 0x668c 0x6280 0x5e28 0x598c 0x54b0 0x4f9c 0x4a58 0x44e4 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x76b0 0x758c 0x73b4 0x7144 0x6e54 0x6af0 0x6728 0x6308 0x5e9c 0x59e8 0x54f8 0x4fd4 0x4a78 0x44f4 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x77c0 0x766c 0x746c 0x71d8 0x6ec8 0x6b4c 0x6770 0x6340 0x5ec4 0x5a04 0x550c 0x4fdc 0x4a80 0x44f8 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7990 0x78e4 0x7774 0x755c 0x72b0 0x6f88 0x6bf8 0x6804 0x63c0 0x5f30 0x5a5c 0x5550 0x5010 0x4aa0 0x4504 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ac0 0x79e0 0x7844 0x7604 0x7338 0x6ff4 0x6c48 0x6844 0x63ec 0x5f50 0x5a74 0x5560 0x5018 0x4aa4 0x4508 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7bf8 0x7afc 0x7940 0x76e8 0x7404 0x70ac 0x6cec 0x68d0 0x6468 0x5fb8 0x5ac8 0x55a0 0x5048 0x4ac4 0x4514 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d2c 0x7c10 0x7a3c 0x77cc 0x74d0 0x7160 0x6d8c 0x695c 0x64dc 0x601c 0x5b18 0x55e0 0x5078 0x4ae0 0x4524 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7e40 0x7cf4 0x7af4 0x785c 0x7544 0x71bc 0x6dd0 0x6990 0x6504 0x6034 0x5b28 0x55ec 0x507c 0x4ae4 0x4524 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x7ffc 0x7f68 0x7e00 0x7be4 0x7938 0x7608 0x7268 0x6e68 0x6a14 0x6574 0x6094 0x5b78 0x5628 0x50a8 0x4b00 0x4530>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x1>; + }; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x2>; + nvidia,out-yres = <0x870>; + nvidia,out-height = <0xac>; + nvidia,out-width = <0x6b>; + }; + + display-timings { + + 1200x1920-32-60Hz { + hsync-len = <0x1>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x6b>; + vfront-porch = <0x1f1>; + nvidia,v-ref-to-sync = <0xb>; + vsync-len = <0x1>; + vactive = <0x780>; + hback-porch = <0x14>; + clock-frequency = <0xb845d40>; + hactive = <0x4b0>; + vback-porch = <0x7>; + }; + }; + + nvdisp-cmu { + nvidia,cmu-lut = <0x6000 0x6000 0x6000 0x6191 0x6191 0x6191 0x6322 0x6322 0x6322 0x643b 0x643b 0x643b 0x64ba 0x64ba 0x64ba 0x6539 0x6539 0x6539 0x65b8 0x65b8 0x65b8 0x6637 0x6637 0x6637 0x66b6 0x66b6 0x66b6 0x6735 0x6735 0x6735 0x67b4 0x67b4 0x67b4 0x6826 0x6826 0x6826 0x687d 0x687d 0x687d 0x68d4 0x68d4 0x68d4 0x692b 0x692b 0x692b 0x6983 0x6983 0x6983 0x69da 0x69da 0x69da 0x6a31 0x6a31 0x6a31 0x6a88 0x6a88 0x6a88 0x6ae0 0x6ae0 0x6ae0 0x6b37 0x6b37 0x6b37 0x6b8e 0x6b8e 0x6b8e 0x6be5 0x6be5 0x6be5 0x6c28 0x6c28 0x6c28 0x6c5b 0x6c5b 0x6c5b 0x6c8e 0x6c8e 0x6c8e 0x6cc1 0x6cc1 0x6cc1 0x6cf4 0x6cf4 0x6cf4 0x6d27 0x6d27 0x6d27 0x6d5a 0x6d5a 0x6d5a 0x6d8d 0x6d8d 0x6d8d 0x6dbf 0x6dbf 0x6dbf 0x6df2 0x6df2 0x6df2 0x6e25 0x6e25 0x6e25 0x6e58 0x6e58 0x6e58 0x6e8b 0x6e8b 0x6e8b 0x6ebe 0x6ebe 0x6ebe 0x6ef1 0x6ef1 0x6ef1 0x6f24 0x6f24 0x6f24 0x6f57 0x6f57 0x6f57 0x6f8a 0x6f8a 0x6f8a 0x6fbd 0x6fbd 0x6fbd 0x6ff0 0x6ff0 0x6ff0 0x701a 0x701a 0x701a 0x7037 0x7037 0x7037 0x7053 0x7053 0x7053 0x706f 0x706f 0x706f 0x708c 0x708c 0x708c 0x70a8 0x70a8 0x70a8 0x70c5 0x70c5 0x70c5 0x70e1 0x70e1 0x70e1 0x70fe 0x70fe 0x70fe 0x711a 0x711a 0x711a 0x7136 0x7136 0x7136 0x7153 0x7153 0x7153 0x716f 0x716f 0x716f 0x718c 0x718c 0x718c 0x71a8 0x71a8 0x71a8 0x71c4 0x71c4 0x71c4 0x71e1 0x71e1 0x71e1 0x71fd 0x71fd 0x71fd 0x721a 0x721a 0x721a 0x7236 0x7236 0x7236 0x7253 0x7253 0x7253 0x726f 0x726f 0x726f 0x728b 0x728b 0x728b 0x72a8 0x72a8 0x72a8 0x72c4 0x72c4 0x72c4 0x72e1 0x72e1 0x72e1 0x72fd 0x72fd 0x72fd 0x731a 0x731a 0x731a 0x7336 0x7336 0x7336 0x7352 0x7352 0x7352 0x736f 0x736f 0x736f 0x738b 0x738b 0x738b 0x73a8 0x73a8 0x73a8 0x73c4 0x73c4 0x73c4 0x73e1 0x73e1 0x73e1 0x73fd 0x73fd 0x73fd 0x741b 0x741b 0x741b 0x743f 0x743f 0x743f 0x7463 0x7463 0x7463 0x7486 0x7486 0x7486 0x74aa 0x74aa 0x74aa 0x74ce 0x74ce 0x74ce 0x74f2 0x74f2 0x74f2 0x7516 0x7516 0x7516 0x753a 0x753a 0x753a 0x755d 0x755d 0x755d 0x7581 0x7581 0x7581 0x75a5 0x75a5 0x75a5 0x75c9 0x75c9 0x75c9 0x75ed 0x75ed 0x75ed 0x7611 0x7611 0x7611 0x7634 0x7634 0x7634 0x7658 0x7658 0x7658 0x767c 0x767c 0x767c 0x76a0 0x76a0 0x76a0 0x76c4 0x76c4 0x76c4 0x76e8 0x76e8 0x76e8 0x770b 0x770b 0x770b 0x772f 0x772f 0x772f 0x7753 0x7753 0x7753 0x7777 0x7777 0x7777 0x779b 0x779b 0x779b 0x77bf 0x77bf 0x77bf 0x77e2 0x77e2 0x77e2 0x7806 0x7806 0x7806 0x7825 0x7825 0x7825 0x7840 0x7840 0x7840 0x785b 0x785b 0x785b 0x7876 0x7876 0x7876 0x7891 0x7891 0x7891 0x78ac 0x78ac 0x78ac 0x78c7 0x78c7 0x78c7 0x78e2 0x78e2 0x78e2 0x78fd 0x78fd 0x78fd 0x7918 0x7918 0x7918 0x7933 0x7933 0x7933 0x794e 0x794e 0x794e 0x7969 0x7969 0x7969 0x7984 0x7984 0x7984 0x799f 0x799f 0x799f 0x79ba 0x79ba 0x79ba 0x79d5 0x79d5 0x79d5 0x79f0 0x79f0 0x79f0 0x7a0b 0x7a0b 0x7a0b 0x7a26 0x7a26 0x7a26 0x7a41 0x7a41 0x7a41 0x7a5c 0x7a5c 0x7a5c 0x7a77 0x7a77 0x7a77 0x7a92 0x7a92 0x7a92 0x7aad 0x7aad 0x7aad 0x7ac8 0x7ac8 0x7ac8 0x7ae3 0x7ae3 0x7ae3 0x7afe 0x7afe 0x7afe 0x7b19 0x7b19 0x7b19 0x7b34 0x7b34 0x7b34 0x7b4f 0x7b4f 0x7b4f 0x7b6a 0x7b6a 0x7b6a 0x7b85 0x7b85 0x7b85 0x7ba0 0x7ba0 0x7ba0 0x7bbb 0x7bbb 0x7bbb 0x7bd5 0x7bd5 0x7bd5 0x7bf0 0x7bf0 0x7bf0 0x7c0b 0x7c0b 0x7c0b 0x7c23 0x7c23 0x7c23 0x7c35 0x7c35 0x7c35 0x7c47 0x7c47 0x7c47 0x7c59 0x7c59 0x7c59 0x7c6b 0x7c6b 0x7c6b 0x7c7d 0x7c7d 0x7c7d 0x7c90 0x7c90 0x7c90 0x7ca2 0x7ca2 0x7ca2 0x7cb4 0x7cb4 0x7cb4 0x7cc6 0x7cc6 0x7cc6 0x7cd8 0x7cd8 0x7cd8 0x7cea 0x7cea 0x7cea 0x7cfc 0x7cfc 0x7cfc 0x7d0f 0x7d0f 0x7d0f 0x7d21 0x7d21 0x7d21 0x7d33 0x7d33 0x7d33 0x7d45 0x7d45 0x7d45 0x7d57 0x7d57 0x7d57 0x7d69 0x7d69 0x7d69 0x7d7b 0x7d7b 0x7d7b 0x7d8e 0x7d8e 0x7d8e 0x7da0 0x7da0 0x7da0 0x7db2 0x7db2 0x7db2 0x7dc4 0x7dc4 0x7dc4 0x7dd6 0x7dd6 0x7dd6 0x7de8 0x7de8 0x7de8 0x7dfa 0x7dfa 0x7dfa 0x7e0d 0x7e0d 0x7e0d 0x7e1f 0x7e1f 0x7e1f 0x7e31 0x7e31 0x7e31 0x7e43 0x7e43 0x7e43 0x7e55 0x7e55 0x7e55 0x7e67 0x7e67 0x7e67 0x7e79 0x7e79 0x7e79 0x7e8c 0x7e8c 0x7e8c 0x7e9e 0x7e9e 0x7e9e 0x7eb0 0x7eb0 0x7eb0 0x7ec2 0x7ec2 0x7ec2 0x7ed4 0x7ed4 0x7ed4 0x7ee6 0x7ee6 0x7ee6 0x7ef8 0x7ef8 0x7ef8 0x7f0b 0x7f0b 0x7f0b 0x7f1d 0x7f1d 0x7f1d 0x7f2f 0x7f2f 0x7f2f 0x7f41 0x7f41 0x7f41 0x7f53 0x7f53 0x7f53 0x7f65 0x7f65 0x7f65 0x7f77 0x7f77 0x7f77 0x7f8a 0x7f8a 0x7f8a 0x7f9c 0x7f9c 0x7f9c 0x7fae 0x7fae 0x7fae 0x7fc0 0x7fc0 0x7fc0 0x7fd2 0x7fd2 0x7fd2 0x7fe4 0x7fe4 0x7fe4 0x7ff7 0x7ff7 0x7ff7 0x8009 0x8009 0x8009 0x801b 0x801b 0x801b 0x802b 0x802b 0x802b 0x803a 0x803a 0x803a 0x804a 0x804a 0x804a 0x8059 0x8059 0x8059 0x8069 0x8069 0x8069 0x8078 0x8078 0x8078 0x8087 0x8087 0x8087 0x8097 0x8097 0x8097 0x80a6 0x80a6 0x80a6 0x80b6 0x80b6 0x80b6 0x80c5 0x80c5 0x80c5 0x80d5 0x80d5 0x80d5 0x80e4 0x80e4 0x80e4 0x80f4 0x80f4 0x80f4 0x8103 0x8103 0x8103 0x8112 0x8112 0x8112 0x8122 0x8122 0x8122 0x8131 0x8131 0x8131 0x8141 0x8141 0x8141 0x8150 0x8150 0x8150 0x8160 0x8160 0x8160 0x816f 0x816f 0x816f 0x817e 0x817e 0x817e 0x818e 0x818e 0x818e 0x819d 0x819d 0x819d 0x81ad 0x81ad 0x81ad 0x81bc 0x81bc 0x81bc 0x81cc 0x81cc 0x81cc 0x81db 0x81db 0x81db 0x81eb 0x81eb 0x81eb 0x81fa 0x81fa 0x81fa 0x8209 0x8209 0x8209 0x8219 0x8219 0x8219 0x8228 0x8228 0x8228 0x8238 0x8238 0x8238 0x8247 0x8247 0x8247 0x8257 0x8257 0x8257 0x8266 0x8266 0x8266 0x8275 0x8275 0x8275 0x8285 0x8285 0x8285 0x8294 0x8294 0x8294 0x82a4 0x82a4 0x82a4 0x82b3 0x82b3 0x82b3 0x82c3 0x82c3 0x82c3 0x82d2 0x82d2 0x82d2 0x82e2 0x82e2 0x82e2 0x82f1 0x82f1 0x82f1 0x8300 0x8300 0x8300 0x8310 0x8310 0x8310 0x831f 0x831f 0x831f 0x832f 0x832f 0x832f 0x833e 0x833e 0x833e 0x834e 0x834e 0x834e 0x835d 0x835d 0x835d 0x836c 0x836c 0x836c 0x837c 0x837c 0x837c 0x838b 0x838b 0x838b 0x839b 0x839b 0x839b 0x83aa 0x83aa 0x83aa 0x83ba 0x83ba 0x83ba 0x83c9 0x83c9 0x83c9 0x83d8 0x83d8 0x83d8 0x83e8 0x83e8 0x83e8 0x83f7 0x83f7 0x83f7 0x8407 0x8407 0x8407 0x8416 0x8416 0x8416 0x8425 0x8425 0x8425 0x8431 0x8431 0x8431 0x843d 0x843d 0x843d 0x8449 0x8449 0x8449 0x8455 0x8455 0x8455 0x8462 0x8462 0x8462 0x846e 0x846e 0x846e 0x847a 0x847a 0x847a 0x8486 0x8486 0x8486 0x8492 0x8492 0x8492 0x849e 0x849e 0x849e 0x84aa 0x84aa 0x84aa 0x84b6 0x84b6 0x84b6 0x84c2 0x84c2 0x84c2 0x84ce 0x84ce 0x84ce 0x84da 0x84da 0x84da 0x84e7 0x84e7 0x84e7 0x84f3 0x84f3 0x84f3 0x84ff 0x84ff 0x84ff 0x850b 0x850b 0x850b 0x8517 0x8517 0x8517 0x8523 0x8523 0x8523 0x852f 0x852f 0x852f 0x853b 0x853b 0x853b 0x8547 0x8547 0x8547 0x8553 0x8553 0x8553 0x855f 0x855f 0x855f 0x856c 0x856c 0x856c 0x8578 0x8578 0x8578 0x8584 0x8584 0x8584 0x8590 0x8590 0x8590 0x859c 0x859c 0x859c 0x85a8 0x85a8 0x85a8 0x85b4 0x85b4 0x85b4 0x85c0 0x85c0 0x85c0 0x85cc 0x85cc 0x85cc 0x85d8 0x85d8 0x85d8 0x85e4 0x85e4 0x85e4 0x85f0 0x85f0 0x85f0 0x85fd 0x85fd 0x85fd 0x8609 0x8609 0x8609 0x8615 0x8615 0x8615 0x8621 0x8621 0x8621 0x862d 0x862d 0x862d 0x8639 0x8639 0x8639 0x8645 0x8645 0x8645 0x8651 0x8651 0x8651 0x865d 0x865d 0x865d 0x8669 0x8669 0x8669 0x8675 0x8675 0x8675 0x8682 0x8682 0x8682 0x868e 0x868e 0x868e 0x869a 0x869a 0x869a 0x86a6 0x86a6 0x86a6 0x86b2 0x86b2 0x86b2 0x86be 0x86be 0x86be 0x86ca 0x86ca 0x86ca 0x86d6 0x86d6 0x86d6 0x86e2 0x86e2 0x86e2 0x86ee 0x86ee 0x86ee 0x86fa 0x86fa 0x86fa 0x8707 0x8707 0x8707 0x8713 0x8713 0x8713 0x871f 0x871f 0x871f 0x872b 0x872b 0x872b 0x8737 0x8737 0x8737 0x8743 0x8743 0x8743 0x874f 0x874f 0x874f 0x875b 0x875b 0x875b 0x8767 0x8767 0x8767 0x8773 0x8773 0x8773 0x877f 0x877f 0x877f 0x878b 0x878b 0x878b 0x8798 0x8798 0x8798 0x87a4 0x87a4 0x87a4 0x87b0 0x87b0 0x87b0 0x87bc 0x87bc 0x87bc 0x87c8 0x87c8 0x87c8 0x87d4 0x87d4 0x87d4 0x87e0 0x87e0 0x87e0 0x87ec 0x87ec 0x87ec 0x87f8 0x87f8 0x87f8 0x8804 0x8804 0x8804 0x8810 0x8810 0x8810 0x881d 0x881d 0x881d 0x8829 0x8829 0x8829 0x8834 0x8834 0x8834 0x883f 0x883f 0x883f 0x884b 0x884b 0x884b 0x8856 0x8856 0x8856 0x8862 0x8862 0x8862 0x886d 0x886d 0x886d 0x8879 0x8879 0x8879 0x8884 0x8884 0x8884 0x8890 0x8890 0x8890 0x889b 0x889b 0x889b 0x88a6 0x88a6 0x88a6 0x88b2 0x88b2 0x88b2 0x88bd 0x88bd 0x88bd 0x88c9 0x88c9 0x88c9 0x88d4 0x88d4 0x88d4 0x88e0 0x88e0 0x88e0 0x88eb 0x88eb 0x88eb 0x88f6 0x88f6 0x88f6 0x8902 0x8902 0x8902 0x890d 0x890d 0x890d 0x8919 0x8919 0x8919 0x8924 0x8924 0x8924 0x8930 0x8930 0x8930 0x893b 0x893b 0x893b 0x8947 0x8947 0x8947 0x8952 0x8952 0x8952 0x895d 0x895d 0x895d 0x8969 0x8969 0x8969 0x8974 0x8974 0x8974 0x8980 0x8980 0x8980 0x898b 0x898b 0x898b 0x8997 0x8997 0x8997 0x89a2 0x89a2 0x89a2 0x89ae 0x89ae 0x89ae 0x89b9 0x89b9 0x89b9 0x89c4 0x89c4 0x89c4 0x89d0 0x89d0 0x89d0 0x89db 0x89db 0x89db 0x89e7 0x89e7 0x89e7 0x89f2 0x89f2 0x89f2 0x89fe 0x89fe 0x89fe 0x8a09 0x8a09 0x8a09 0x8a15 0x8a15 0x8a15 0x8a20 0x8a20 0x8a20 0x8a2b 0x8a2b 0x8a2b 0x8a37 0x8a37 0x8a37 0x8a42 0x8a42 0x8a42 0x8a4e 0x8a4e 0x8a4e 0x8a59 0x8a59 0x8a59 0x8a65 0x8a65 0x8a65 0x8a70 0x8a70 0x8a70 0x8a7b 0x8a7b 0x8a7b 0x8a87 0x8a87 0x8a87 0x8a92 0x8a92 0x8a92 0x8a9e 0x8a9e 0x8a9e 0x8aa9 0x8aa9 0x8aa9 0x8ab5 0x8ab5 0x8ab5 0x8ac0 0x8ac0 0x8ac0 0x8acc 0x8acc 0x8acc 0x8ad7 0x8ad7 0x8ad7 0x8ae2 0x8ae2 0x8ae2 0x8aee 0x8aee 0x8aee 0x8af9 0x8af9 0x8af9 0x8b05 0x8b05 0x8b05 0x8b10 0x8b10 0x8b10 0x8b1c 0x8b1c 0x8b1c 0x8b27 0x8b27 0x8b27 0x8b33 0x8b33 0x8b33 0x8b3e 0x8b3e 0x8b3e 0x8b49 0x8b49 0x8b49 0x8b55 0x8b55 0x8b55 0x8b60 0x8b60 0x8b60 0x8b6c 0x8b6c 0x8b6c 0x8b77 0x8b77 0x8b77 0x8b83 0x8b83 0x8b83 0x8b8e 0x8b8e 0x8b8e 0x8b99 0x8b99 0x8b99 0x8ba5 0x8ba5 0x8ba5 0x8bb0 0x8bb0 0x8bb0 0x8bbc 0x8bbc 0x8bbc 0x8bc7 0x8bc7 0x8bc7 0x8bd3 0x8bd3 0x8bd3 0x8bde 0x8bde 0x8bde 0x8bea 0x8bea 0x8bea 0x8bf5 0x8bf5 0x8bf5 0x8c00 0x8c00 0x8c00 0x8c0c 0x8c0c 0x8c0c 0x8c17 0x8c17 0x8c17 0x8c23 0x8c23 0x8c23 0x8c2e 0x8c2e 0x8c2e 0x8c38 0x8c38 0x8c38 0x8c43 0x8c43 0x8c43 0x8c4d 0x8c4d 0x8c4d 0x8c58 0x8c58 0x8c58 0x8c62 0x8c62 0x8c62 0x8c6c 0x8c6c 0x8c6c 0x8c77 0x8c77 0x8c77 0x8c81 0x8c81 0x8c81 0x8c8c 0x8c8c 0x8c8c 0x8c96 0x8c96 0x8c96 0x8ca0 0x8ca0 0x8ca0 0x8cab 0x8cab 0x8cab 0x8cb5 0x8cb5 0x8cb5 0x8cc0 0x8cc0 0x8cc0 0x8cca 0x8cca 0x8cca 0x8cd4 0x8cd4 0x8cd4 0x8cdf 0x8cdf 0x8cdf 0x8ce9 0x8ce9 0x8ce9 0x8cf4 0x8cf4 0x8cf4 0x8cfe 0x8cfe 0x8cfe 0x8d09 0x8d09 0x8d09 0x8d13 0x8d13 0x8d13 0x8d1d 0x8d1d 0x8d1d 0x8d28 0x8d28 0x8d28 0x8d32 0x8d32 0x8d32 0x8d3d 0x8d3d 0x8d3d 0x8d47 0x8d47 0x8d47 0x8d51 0x8d51 0x8d51 0x8d5c 0x8d5c 0x8d5c 0x8d66 0x8d66 0x8d66 0x8d71 0x8d71 0x8d71 0x8d7b 0x8d7b 0x8d7b 0x8d85 0x8d85 0x8d85 0x8d90 0x8d90 0x8d90 0x8d9a 0x8d9a 0x8d9a 0x8da5 0x8da5 0x8da5 0x8daf 0x8daf 0x8daf 0x8db9 0x8db9 0x8db9 0x8dc4 0x8dc4 0x8dc4 0x8dce 0x8dce 0x8dce 0x8dd9 0x8dd9 0x8dd9 0x8de3 0x8de3 0x8de3 0x8ded 0x8ded 0x8ded 0x8df8 0x8df8 0x8df8 0x8e02 0x8e02 0x8e02 0x8e0d 0x8e0d 0x8e0d 0x8e17 0x8e17 0x8e17 0x8e22 0x8e22 0x8e22 0x8e2c 0x8e2c 0x8e2c 0x8e36 0x8e36 0x8e36 0x8e41 0x8e41 0x8e41 0x8e4b 0x8e4b 0x8e4b 0x8e56 0x8e56 0x8e56 0x8e60 0x8e60 0x8e60 0x8e6a 0x8e6a 0x8e6a 0x8e75 0x8e75 0x8e75 0x8e7f 0x8e7f 0x8e7f 0x8e8a 0x8e8a 0x8e8a 0x8e94 0x8e94 0x8e94 0x8e9e 0x8e9e 0x8e9e 0x8ea9 0x8ea9 0x8ea9 0x8eb3 0x8eb3 0x8eb3 0x8ebe 0x8ebe 0x8ebe 0x8ec8 0x8ec8 0x8ec8 0x8ed2 0x8ed2 0x8ed2 0x8edd 0x8edd 0x8edd 0x8ee7 0x8ee7 0x8ee7 0x8ef2 0x8ef2 0x8ef2 0x8efc 0x8efc 0x8efc 0x8f07 0x8f07 0x8f07 0x8f11 0x8f11 0x8f11 0x8f1b 0x8f1b 0x8f1b 0x8f26 0x8f26 0x8f26 0x8f30 0x8f30 0x8f30 0x8f3b 0x8f3b 0x8f3b 0x8f45 0x8f45 0x8f45 0x8f4f 0x8f4f 0x8f4f 0x8f5a 0x8f5a 0x8f5a 0x8f64 0x8f64 0x8f64 0x8f6f 0x8f6f 0x8f6f 0x8f79 0x8f79 0x8f79 0x8f83 0x8f83 0x8f83 0x8f8e 0x8f8e 0x8f8e 0x8f98 0x8f98 0x8f98 0x8fa3 0x8fa3 0x8fa3 0x8fad 0x8fad 0x8fad 0x8fb7 0x8fb7 0x8fb7 0x8fc2 0x8fc2 0x8fc2 0x8fcc 0x8fcc 0x8fcc 0x8fd7 0x8fd7 0x8fd7 0x8fe1 0x8fe1 0x8fe1 0x8feb 0x8feb 0x8feb 0x8ff6 0x8ff6 0x8ff6 0x9000 0x9000 0x9000 0x900b 0x900b 0x900b 0x9015 0x9015 0x9015 0x9020 0x9020 0x9020 0x902a 0x902a 0x902a 0x9034 0x9034 0x9034 0x903e 0x903e 0x903e 0x9048 0x9048 0x9048 0x9052 0x9052 0x9052 0x905c 0x905c 0x905c 0x9066 0x9066 0x9066 0x9070 0x9070 0x9070 0x907a 0x907a 0x907a 0x9084 0x9084 0x9084 0x908e 0x908e 0x908e 0x9098 0x9098 0x9098 0x90a2 0x90a2 0x90a2 0x90ac 0x90ac 0x90ac 0x90b6 0x90b6 0x90b6 0x90c0 0x90c0 0x90c0 0x90ca 0x90ca 0x90ca 0x90d4 0x90d4 0x90d4 0x90de 0x90de 0x90de 0x90e8 0x90e8 0x90e8 0x90f2 0x90f2 0x90f2 0x90fc 0x90fc 0x90fc 0x9106 0x9106 0x9106 0x9110 0x9110 0x9110 0x911a 0x911a 0x911a 0x9123 0x9123 0x9123 0x912d 0x912d 0x912d 0x9137 0x9137 0x9137 0x9141 0x9141 0x9141 0x914b 0x914b 0x914b 0x9155 0x9155 0x9155 0x915f 0x915f 0x915f 0x9169 0x9169 0x9169 0x9173 0x9173 0x9173 0x917d 0x917d 0x917d 0x9187 0x9187 0x9187 0x9191 0x9191 0x9191 0x919b 0x919b 0x919b 0x91a5 0x91a5 0x91a5 0x91af 0x91af 0x91af 0x91b9 0x91b9 0x91b9 0x91c3 0x91c3 0x91c3 0x91cd 0x91cd 0x91cd 0x91d7 0x91d7 0x91d7 0x91e1 0x91e1 0x91e1 0x91eb 0x91eb 0x91eb 0x91f5 0x91f5 0x91f5 0x91ff 0x91ff 0x91ff 0x9209 0x9209 0x9209 0x9213 0x9213 0x9213 0x921d 0x921d 0x921d 0x9227 0x9227 0x9227 0x9231 0x9231 0x9231 0x923b 0x923b 0x923b 0x9245 0x9245 0x9245 0x924f 0x924f 0x924f 0x9259 0x9259 0x9259 0x9263 0x9263 0x9263 0x926d 0x926d 0x926d 0x9277 0x9277 0x9277 0x9281 0x9281 0x9281 0x928b 0x928b 0x928b 0x9295 0x9295 0x9295 0x929f 0x929f 0x929f 0x92a8 0x92a8 0x92a8 0x92b2 0x92b2 0x92b2 0x92bc 0x92bc 0x92bc 0x92c6 0x92c6 0x92c6 0x92d0 0x92d0 0x92d0 0x92da 0x92da 0x92da 0x92e4 0x92e4 0x92e4 0x92ee 0x92ee 0x92ee 0x92f8 0x92f8 0x92f8 0x9302 0x9302 0x9302 0x930c 0x930c 0x930c 0x9316 0x9316 0x9316 0x9320 0x9320 0x9320 0x932a 0x932a 0x932a 0x9334 0x9334 0x9334 0x933e 0x933e 0x933e 0x9348 0x9348 0x9348 0x9352 0x9352 0x9352 0x935c 0x935c 0x935c 0x9366 0x9366 0x9366 0x9370 0x9370 0x9370 0x937a 0x937a 0x937a 0x9384 0x9384 0x9384 0x938e 0x938e 0x938e 0x9398 0x9398 0x9398 0x93a2 0x93a2 0x93a2 0x93ac 0x93ac 0x93ac 0x93b6 0x93b6 0x93b6 0x93c0 0x93c0 0x93c0 0x93ca 0x93ca 0x93ca 0x93d4 0x93d4 0x93d4 0x93de 0x93de 0x93de 0x93e8 0x93e8 0x93e8 0x93f2 0x93f2 0x93f2 0x93fc 0x93fc 0x93fc 0x9406 0x9406 0x9406 0x9410 0x9410 0x9410 0x941a 0x941a 0x941a 0x9423 0x9423 0x9423 0x942d 0x942d 0x942d 0x9437 0x9437 0x9437 0x9440 0x9440 0x9440 0x9449 0x9449 0x9449 0x9451 0x9451 0x9451 0x945a 0x945a 0x945a 0x9463 0x9463 0x9463 0x946c 0x946c 0x946c 0x9475 0x9475 0x9475 0x947e 0x947e 0x947e 0x9486 0x9486 0x9486 0x948f 0x948f 0x948f 0x9498 0x9498 0x9498 0x94a1 0x94a1 0x94a1 0x94aa 0x94aa 0x94aa 0x94b3 0x94b3 0x94b3 0x94bb 0x94bb 0x94bb 0x94c4 0x94c4 0x94c4 0x94cd 0x94cd 0x94cd 0x94d6 0x94d6 0x94d6 0x94df 0x94df 0x94df 0x94e8 0x94e8 0x94e8 0x94f0 0x94f0 0x94f0 0x94f9 0x94f9 0x94f9 0x9502 0x9502 0x9502 0x950b 0x950b 0x950b 0x9514 0x9514 0x9514 0x951d 0x951d 0x951d 0x9525 0x9525 0x9525 0x952e 0x952e 0x952e 0x9537 0x9537 0x9537 0x9540 0x9540 0x9540 0x9549 0x9549 0x9549 0x9552 0x9552 0x9552 0x955a 0x955a 0x955a 0x9563 0x9563 0x9563 0x956c 0x956c 0x956c 0x9575 0x9575 0x9575 0x957e 0x957e 0x957e 0x9587 0x9587 0x9587 0x958f 0x958f 0x958f 0x9598 0x9598 0x9598 0x95a1 0x95a1 0x95a1 0x95aa 0x95aa 0x95aa 0x95b3 0x95b3 0x95b3 0x95bc 0x95bc 0x95bc 0x95c4 0x95c4 0x95c4 0x95cd 0x95cd 0x95cd 0x95d6 0x95d6 0x95d6 0x95df 0x95df 0x95df 0x95e8 0x95e8 0x95e8 0x95f1 0x95f1 0x95f1 0x95f9 0x95f9 0x95f9 0x9602 0x9602 0x9602 0x960b 0x960b 0x960b 0x9614 0x9614 0x9614 0x961d 0x961d 0x961d 0x9626 0x9626 0x9626 0x962e 0x962e 0x962e 0x9637 0x9637 0x9637 0x9640 0x9640 0x9640 0x9649 0x9649 0x9649 0x9652 0x9652 0x9652 0x965b 0x965b 0x965b 0x9663 0x9663 0x9663 0x966c 0x966c 0x966c 0x9675 0x9675 0x9675 0x967e 0x967e 0x967e 0x9687 0x9687 0x9687 0x9690 0x9690 0x9690 0x9698 0x9698 0x9698 0x96a1 0x96a1 0x96a1 0x96aa 0x96aa 0x96aa 0x96b3 0x96b3 0x96b3 0x96bc 0x96bc 0x96bc 0x96c5 0x96c5 0x96c5 0x96cd 0x96cd 0x96cd 0x96d6 0x96d6 0x96d6 0x96df 0x96df 0x96df 0x96e8 0x96e8 0x96e8 0x96f1 0x96f1 0x96f1 0x96f9 0x96f9 0x96f9 0x9702 0x9702 0x9702 0x970b 0x970b 0x970b 0x9714 0x9714 0x9714 0x971d 0x971d 0x971d 0x9726 0x9726 0x9726 0x972e 0x972e 0x972e 0x9737 0x9737 0x9737 0x9740 0x9740 0x9740 0x9749 0x9749 0x9749 0x9752 0x9752 0x9752 0x975b 0x975b 0x975b 0x9763 0x9763 0x9763 0x976c 0x976c 0x976c 0x9775 0x9775 0x9775 0x977e 0x977e 0x977e 0x9787 0x9787 0x9787 0x9790 0x9790 0x9790 0x9798 0x9798 0x9798 0x97a1 0x97a1 0x97a1 0x97aa 0x97aa 0x97aa 0x97b3 0x97b3 0x97b3 0x97bc 0x97bc 0x97bc 0x97c5 0x97c5 0x97c5 0x97cd 0x97cd 0x97cd 0x97d6 0x97d6 0x97d6 0x97df 0x97df 0x97df 0x97e8 0x97e8 0x97e8 0x97f1 0x97f1 0x97f1 0x97fa 0x97fa 0x97fa 0x9802 0x9802 0x9802 0x980b 0x980b 0x980b 0x9814 0x9814 0x9814 0x981d 0x981d 0x981d 0x9826 0x9826 0x9826 0x982f 0x982f 0x982f 0x9837 0x9837 0x9837 0x983f 0x983f 0x983f 0x9847 0x9847 0x9847 0x984f 0x984f 0x984f 0x9857 0x9857 0x9857 0x985f 0x985f 0x985f 0x9867 0x9867 0x9867 0x986e 0x986e 0x986e 0x9876 0x9876 0x9876 0x987e 0x987e 0x987e 0x9886 0x9886 0x9886 0x988e 0x988e 0x988e 0x9896 0x9896 0x9896 0x989e 0x989e 0x989e 0x98a5 0x98a5 0x98a5 0x98ad 0x98ad 0x98ad 0x98b5 0x98b5 0x98b5 0x98bd 0x98bd 0x98bd 0x98c5 0x98c5 0x98c5 0x98cd 0x98cd 0x98cd 0x98d5 0x98d5 0x98d5 0x98dc 0x98dc 0x98dc 0x98e4 0x98e4 0x98e4 0x98ec 0x98ec 0x98ec 0x98f4 0x98f4 0x98f4 0x98fc 0x98fc 0x98fc 0x9904 0x9904 0x9904 0x990c 0x990c 0x990c 0x9913 0x9913 0x9913 0x991b 0x991b 0x991b 0x9923 0x9923 0x9923 0x992b 0x992b 0x992b 0x9933 0x9933 0x9933 0x993b 0x993b 0x993b 0x9943 0x9943 0x9943 0x994a 0x994a 0x994a 0x9952 0x9952 0x9952 0x995a 0x995a 0x995a 0x9962 0x9962 0x9962 0x996a 0x996a 0x996a 0x9972 0x9972 0x9972 0x997a 0x997a 0x997a 0x9981 0x9981 0x9981 0x9989 0x9989 0x9989 0x9991 0x9991 0x9991 0x9999 0x9999 0x9999 0x99a1 0x99a1 0x99a1 0x99a9 0x99a9 0x99a9 0x99b1 0x99b1 0x99b1 0x99b8 0x99b8 0x99b8 0x99c0 0x99c0 0x99c0 0x99c8 0x99c8 0x99c8 0x99d0 0x99d0 0x99d0 0x99d8 0x99d8 0x99d8 0x99e0 0x99e0 0x99e0 0x99e8 0x99e8 0x99e8 0x99ef 0x99ef 0x99ef 0x99f7 0x99f7 0x99f7 0x99ff 0x99ff 0x99ff 0x9a07 0x9a07 0x9a07 0x9a0f 0x9a0f 0x9a0f 0x9a17 0x9a17 0x9a17 0x9a1f 0x9a1f 0x9a1f 0x9a26 0x9a26 0x9a26 0x9a2e 0x9a2e 0x9a2e 0x9a36 0x9a36 0x9a36 0x9a3e 0x9a3e 0x9a3e 0x9a46 0x9a46 0x9a46 0x9a4e 0x9a4e 0x9a4e 0x9a56 0x9a56 0x9a56 0x9a5d 0x9a5d 0x9a5d 0x9a65 0x9a65 0x9a65 0x9a6d 0x9a6d 0x9a6d 0x9a75 0x9a75 0x9a75 0x9a7d 0x9a7d 0x9a7d 0x9a85 0x9a85 0x9a85 0x9a8d 0x9a8d 0x9a8d 0x9a94 0x9a94 0x9a94 0x9a9c 0x9a9c 0x9a9c 0x9aa4 0x9aa4 0x9aa4 0x9aac 0x9aac 0x9aac 0x9ab4 0x9ab4 0x9ab4 0x9abc 0x9abc 0x9abc 0x9ac4 0x9ac4 0x9ac4 0x9acb 0x9acb 0x9acb 0x9ad3 0x9ad3 0x9ad3 0x9adb 0x9adb 0x9adb 0x9ae3 0x9ae3 0x9ae3 0x9aeb 0x9aeb 0x9aeb 0x9af3 0x9af3 0x9af3 0x9afb 0x9afb 0x9afb 0x9b02 0x9b02 0x9b02 0x9b0a 0x9b0a 0x9b0a 0x9b12 0x9b12 0x9b12 0x9b1a 0x9b1a 0x9b1a 0x9b22 0x9b22 0x9b22 0x9b2a 0x9b2a 0x9b2a 0x9b32 0x9b32 0x9b32 0x9b39 0x9b39 0x9b39 0x9b41 0x9b41 0x9b41 0x9b49 0x9b49 0x9b49 0x9b51 0x9b51 0x9b51 0x9b59 0x9b59 0x9b59 0x9b61 0x9b61 0x9b61 0x9b69 0x9b69 0x9b69 0x9b70 0x9b70 0x9b70 0x9b78 0x9b78 0x9b78 0x9b80 0x9b80 0x9b80 0x9b88 0x9b88 0x9b88 0x9b90 0x9b90 0x9b90 0x9b98 0x9b98 0x9b98 0x9ba0 0x9ba0 0x9ba0 0x9ba7 0x9ba7 0x9ba7 0x9baf 0x9baf 0x9baf 0x9bb7 0x9bb7 0x9bb7 0x9bbf 0x9bbf 0x9bbf 0x9bc7 0x9bc7 0x9bc7 0x9bcf 0x9bcf 0x9bcf 0x9bd7 0x9bd7 0x9bd7 0x9bde 0x9bde 0x9bde 0x9be6 0x9be6 0x9be6 0x9bee 0x9bee 0x9bee 0x9bf6 0x9bf6 0x9bf6 0x9bfe 0x9bfe 0x9bfe 0x9c06 0x9c06 0x9c06 0x9c0e 0x9c0e 0x9c0e 0x9c15 0x9c15 0x9c15 0x9c1d 0x9c1d 0x9c1d 0x9c25 0x9c25 0x9c25 0x9c2d 0x9c2d 0x9c2d 0x9c35 0x9c35 0x9c35 0x9c3d 0x9c3d 0x9c3d 0x9c44 0x9c44 0x9c44 0x9c4b 0x9c4b 0x9c4b 0x9c53 0x9c53 0x9c53 0x9c5a 0x9c5a 0x9c5a 0x9c61 0x9c61 0x9c61 0x9c69 0x9c69 0x9c69 0x9c70 0x9c70 0x9c70 0x9c77 0x9c77 0x9c77 0x9c7f 0x9c7f 0x9c7f 0x9c86 0x9c86 0x9c86 0x9c8d 0x9c8d 0x9c8d 0x9c95 0x9c95 0x9c95 0x9c9c 0x9c9c 0x9c9c 0x9ca3 0x9ca3 0x9ca3 0x9cab 0x9cab 0x9cab 0x9cb2 0x9cb2 0x9cb2 0x9cb9 0x9cb9 0x9cb9 0x9cc1 0x9cc1 0x9cc1 0x9cc8 0x9cc8 0x9cc8 0x9ccf 0x9ccf 0x9ccf 0x9cd7 0x9cd7 0x9cd7 0x9cde 0x9cde 0x9cde 0x9ce5 0x9ce5 0x9ce5 0x9ced 0x9ced 0x9ced 0x9cf4 0x9cf4 0x9cf4 0x9cfb 0x9cfb 0x9cfb 0x9d03 0x9d03 0x9d03 0x9d0a 0x9d0a 0x9d0a 0x9d12 0x9d12 0x9d12 0x9d19 0x9d19 0x9d19 0x9d20 0x9d20 0x9d20 0x9d28 0x9d28 0x9d28 0x9d2f 0x9d2f 0x9d2f 0x9d36 0x9d36 0x9d36 0x9d3e 0x9d3e 0x9d3e 0x9d45 0x9d45 0x9d45 0x9d4c 0x9d4c 0x9d4c 0x9d54 0x9d54 0x9d54 0x9d5b 0x9d5b 0x9d5b 0x9d62 0x9d62 0x9d62 0x9d6a 0x9d6a 0x9d6a 0x9d71 0x9d71 0x9d71 0x9d78 0x9d78 0x9d78 0x9d80 0x9d80 0x9d80 0x9d87 0x9d87 0x9d87 0x9d8e 0x9d8e 0x9d8e 0x9d96 0x9d96 0x9d96 0x9d9d 0x9d9d 0x9d9d 0x9da4 0x9da4 0x9da4 0x9dac 0x9dac 0x9dac 0x9db3 0x9db3 0x9db3 0x9dba 0x9dba 0x9dba 0x9dc2 0x9dc2 0x9dc2 0x9dc9 0x9dc9 0x9dc9 0x9dd0 0x9dd0 0x9dd0 0x9dd8 0x9dd8 0x9dd8 0x9ddf 0x9ddf 0x9ddf 0x9de6 0x9de6 0x9de6 0x9dee 0x9dee 0x9dee 0x9df5 0x9df5 0x9df5 0x9dfc 0x9dfc 0x9dfc 0x9e04 0x9e04 0x9e04 0x9e0b 0x9e0b 0x9e0b 0x9e13 0x9e13 0x9e13 0x9e1a 0x9e1a 0x9e1a 0x9e21 0x9e21 0x9e21 0x9e29 0x9e29 0x9e29 0x9e30 0x9e30 0x9e30 0x9e37 0x9e37 0x9e37 0x9e3f 0x9e3f 0x9e3f 0x9e46 0x9e46 0x9e46 0x9e4d 0x9e4d 0x9e4d 0x9e55 0x9e55 0x9e55 0x9e5c 0x9e5c 0x9e5c 0x9e63 0x9e63 0x9e63 0x9e6b 0x9e6b 0x9e6b 0x9e72 0x9e72 0x9e72 0x9e79 0x9e79 0x9e79 0x9e81 0x9e81 0x9e81 0x9e88 0x9e88 0x9e88 0x9e8f 0x9e8f 0x9e8f 0x9e97 0x9e97 0x9e97 0x9e9e 0x9e9e 0x9e9e 0x9ea5 0x9ea5 0x9ea5 0x9ead 0x9ead 0x9ead 0x9eb4 0x9eb4 0x9eb4 0x9ebb 0x9ebb 0x9ebb 0x9ec3 0x9ec3 0x9ec3 0x9eca 0x9eca 0x9eca 0x9ed1 0x9ed1 0x9ed1 0x9ed9 0x9ed9 0x9ed9 0x9ee0 0x9ee0 0x9ee0 0x9ee7 0x9ee7 0x9ee7 0x9eef 0x9eef 0x9eef 0x9ef6 0x9ef6 0x9ef6 0x9efd 0x9efd 0x9efd 0x9f05 0x9f05 0x9f05 0x9f0c 0x9f0c 0x9f0c 0x9f14 0x9f14 0x9f14 0x9f1b 0x9f1b 0x9f1b 0x9f22 0x9f22 0x9f22 0x9f2a 0x9f2a 0x9f2a 0x9f31 0x9f31 0x9f31 0x9f38 0x9f38 0x9f38 0x9f40 0x9f40 0x9f40 0x9f47 0x9f47 0x9f47 0x9f4e 0x9f4e 0x9f4e 0x9f56 0x9f56 0x9f56 0x9f5d 0x9f5d 0x9f5d 0x9f64 0x9f64 0x9f64 0x9f6c 0x9f6c 0x9f6c 0x9f73 0x9f73 0x9f73 0x9f7a 0x9f7a 0x9f7a 0x9f82 0x9f82 0x9f82 0x9f89 0x9f89 0x9f89 0x9f90 0x9f90 0x9f90 0x9f98 0x9f98 0x9f98 0x9f9f 0x9f9f 0x9f9f 0x9fa6 0x9fa6 0x9fa6 0x9fae 0x9fae 0x9fae 0x9fb5 0x9fb5 0x9fb5 0x9fbc 0x9fbc 0x9fbc 0x9fc4 0x9fc4 0x9fc4 0x9fcb 0x9fcb 0x9fcb 0x9fd2 0x9fd2 0x9fd2 0x9fda 0x9fda 0x9fda 0x9fe1 0x9fe1 0x9fe1 0x9fe8 0x9fe8 0x9fe8 0x9ff0 0x9ff0 0x9ff0 0x9ff7 0x9ff7 0x9ff7 0x9fff 0x9fff 0x9fff>; + nvidia,panel-csc = <0xd581 0x2979 0xc5 0x0 0x831 0xcac1 0x20c 0x0 0x189 0x625 0xcc4a 0x0>; + }; + }; + + panel-s-wqxga-10-1 { + nvidia,dsi-ganged-type = <0x1>; + compatible = "s,wqxga-10-1"; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-refresh-rate = <0x3d>; + nvidia,dsi-lp00-pre-panel-wakeup = <0x1>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-video-clock-mode = <0x1>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + nvidia,dsi-n-init-cmd = <0x10>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-init-cmd = <0x0 0x29 0x3 0x0 0x0 0x10 0x0 0x2a 0x0 0x0 0x1 0x14 0x0 0x5 0x0 0x0 0x0 0x1 0x14 0x0 0x29 0x3 0x0 0x0 0x10 0x1 0x1 0x0 0x0 0x1 0x14 0x0 0x5 0x0 0x0 0x0 0x1 0x14 0x0 0x5 0x35 0x0 0x0 0x1 0x14 0x0 0x5 0x11 0x0 0x0 0x1 0x78 0x0 0x5 0x29 0x0 0x0 0x1 0x14 0x3 0x1 0x1 0x78>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-video-data-type = <0x1>; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + nvidia,dsi-rated-refresh-rate = <0x3c>; + phandle = <0x11e>; + nvidia,dsi-suspend-cmd = <0x0 0x5 0x28 0x0 0x0 0x1 0x32 0x0 0x5 0x10 0x0 0x0 0x1 0xc8 0x0 0x5 0x34 0x0 0x0 0x1 0x14>; + nvidia,dsi-n-suspend-cmd = <0x6>; + nvidia,dsi-instance = <0x0>; + nvidia,dsi-panel-reset = <0x1>; + nvidia,dsi-te-polarity-low = <0x1>; + linux,phandle = <0x11e>; + nvidia,dsi-suspend-aggr = <0x3>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,panel-bl-pwm-gpio = <0x28 0x8 0x1>; + + cmu { + nvidia,cmu-csc = <0x105 0x3d5 0x24 0x3ea 0x121 0x3c1 0x2 0xa 0xf4>; + nvidia,cmu-lut2 = <0x0 0x1 0x2 0x2 0x3 0x4 0x5 0x6 0x6 0x7 0x8 0x9 0xa 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0xf 0x10 0x10 0x11 0x12 0x12 0x13 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x17 0x18 0x18 0x19 0x19 0x19 0x1a 0x1a 0x1b 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1d 0x1e 0x1e 0x1e 0x1f 0x1f 0x1f 0x20 0x20 0x20 0x21 0x21 0x21 0x22 0x22 0x22 0x22 0x23 0x23 0x23 0x24 0x24 0x24 0x25 0x25 0x25 0x25 0x26 0x26 0x26 0x26 0x27 0x27 0x27 0x28 0x28 0x28 0x28 0x29 0x29 0x29 0x29 0x2a 0x2a 0x2a 0x2a 0x2b 0x2b 0x2b 0x2b 0x2b 0x2c 0x2c 0x2c 0x2c 0x2d 0x2d 0x2d 0x2d 0x2e 0x2e 0x2e 0x2e 0x2e 0x2f 0x2f 0x2f 0x2f 0x30 0x30 0x30 0x30 0x30 0x31 0x31 0x31 0x31 0x31 0x32 0x32 0x32 0x32 0x32 0x33 0x33 0x33 0x33 0x33 0x34 0x34 0x34 0x34 0x34 0x35 0x35 0x35 0x35 0x35 0x36 0x36 0x36 0x36 0x36 0x37 0x37 0x37 0x37 0x37 0x37 0x38 0x38 0x38 0x38 0x38 0x39 0x39 0x39 0x39 0x39 0x39 0x3a 0x3a 0x3a 0x3a 0x3a 0x3a 0x3b 0x3b 0x3b 0x3b 0x3b 0x3b 0x3c 0x3c 0x3c 0x3c 0x3c 0x3c 0x3d 0x3d 0x3d 0x3d 0x3d 0x3d 0x3e 0x3e 0x3e 0x3e 0x3e 0x3e 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x40 0x40 0x40 0x40 0x40 0x40 0x40 0x41 0x41 0x41 0x41 0x41 0x41 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x44 0x44 0x44 0x44 0x44 0x44 0x44 0x45 0x45 0x45 0x45 0x45 0x45 0x45 0x46 0x46 0x46 0x46 0x46 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x49 0x49 0x49 0x49 0x49 0x49 0x49 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x63 0x63 0x63 0x63 0x63 0x63 0x63 0x64 0x65 0x65 0x66 0x67 0x67 0x68 0x69 0x69 0x6a 0x6b 0x6b 0x6c 0x6d 0x6d 0x6e 0x6f 0x6f 0x70 0x71 0x71 0x72 0x73 0x73 0x74 0x74 0x75 0x76 0x76 0x77 0x77 0x78 0x78 0x79 0x7a 0x7a 0x7b 0x7b 0x7c 0x7c 0x7d 0x7e 0x7e 0x7f 0x7f 0x80 0x80 0x81 0x81 0x82 0x82 0x83 0x83 0x84 0x84 0x85 0x85 0x86 0x86 0x87 0x87 0x88 0x88 0x89 0x89 0x8a 0x8a 0x8b 0x8b 0x8c 0x8c 0x8d 0x8d 0x8e 0x8e 0x8f 0x8f 0x90 0x90 0x91 0x91 0x91 0x92 0x92 0x93 0x93 0x94 0x94 0x95 0x95 0x96 0x96 0x96 0x97 0x97 0x98 0x98 0x99 0x99 0x99 0x9a 0x9a 0x9b 0x9b 0x9c 0x9c 0x9c 0x9d 0x9d 0x9e 0x9e 0x9e 0x9f 0x9f 0xa0 0xa0 0xa0 0xa1 0xa1 0xa2 0xa2 0xa2 0xa3 0xa3 0xa4 0xa4 0xa4 0xa5 0xa5 0xa6 0xa6 0xa6 0xa7 0xa7 0xa7 0xa8 0xa8 0xa9 0xa9 0xa9 0xaa 0xaa 0xaa 0xab 0xab 0xac 0xac 0xac 0xad 0xad 0xad 0xae 0xae 0xae 0xaf 0xaf 0xb0 0xb0 0xb0 0xb1 0xb1 0xb1 0xb2 0xb2 0xb2 0xb3 0xb3 0xb3 0xb4 0xb4 0xb4 0xb5 0xb5 0xb6 0xb6 0xb6 0xb7 0xb7 0xb7 0xb8 0xb8 0xb8 0xb9 0xb9 0xb9 0xba 0xba 0xba 0xbb 0xbb 0xbb 0xbc 0xbc 0xbc 0xbd 0xbd 0xbd 0xbd 0xbe 0xbe 0xbe 0xbf 0xbf 0xbf 0xc0 0xc0 0xc0 0xc1 0xc1 0xc1 0xc2 0xc2 0xc2 0xc3 0xc3 0xc3 0xc4 0xc4 0xc4 0xc4 0xc5 0xc5 0xc5 0xc6 0xc6 0xc6 0xc7 0xc7 0xc7 0xc8 0xc8 0xc8 0xc8 0xc9 0xc9 0xc9 0xca 0xca 0xca 0xca 0xcb 0xcb 0xcb 0xcc 0xcc 0xcc 0xcd 0xcd 0xcd 0xcd 0xce 0xce 0xce 0xcf 0xcf 0xcf 0xcf 0xd0 0xd0 0xd0 0xd1 0xd1 0xd1 0xd1 0xd2 0xd2 0xd2 0xd3 0xd3 0xd3 0xd3 0xd4 0xd4 0xd4 0xd5 0xd5 0xd5 0xd5 0xd6 0xd6 0xd6 0xd6 0xd7 0xd7 0xd7 0xd8 0xd8 0xd8 0xd8 0xd9 0xd9 0xd9 0xd9 0xda 0xda 0xda 0xdb 0xdb 0xdb 0xdb 0xdc 0xdc 0xdc 0xdc 0xdd 0xdd 0xdd 0xdd 0xde 0xde 0xde 0xdf 0xdf 0xdf 0xdf 0xe0 0xe0 0xe0 0xe0 0xe1 0xe1 0xe1 0xe1 0xe2 0xe2 0xe2 0xe2 0xe3 0xe3 0xe3 0xe3 0xe4 0xe4 0xe4 0xe4 0xe5 0xe5 0xe5 0xe5 0xe6 0xe6 0xe6 0xe6 0xe7 0xe7 0xe7 0xe7 0xe8 0xe8 0xe8 0xe8 0xe9 0xe9 0xe9 0xe9 0xea 0xea 0xea 0xea 0xeb 0xeb 0xeb 0xeb 0xec 0xec 0xec 0xec 0xed 0xed 0xed 0xed 0xee 0xee 0xee 0xee 0xef 0xef 0xef 0xef 0xf0 0xf0 0xf0 0xf0 0xf0 0xf1 0xf1 0xf1 0xf1 0xf2 0xf2 0xf2 0xf2 0xf3 0xf3 0xf3 0xf3 0xf4 0xf4 0xf4 0xf4 0xf4 0xf5 0xf5 0xf5 0xf5 0xf6 0xf6 0xf6 0xf6 0xf7 0xf7 0xf7 0xf7 0xf7 0xf8 0xf8 0xf8 0xf8 0xf9 0xf9 0xf9 0xf9 0xf9 0xfa 0xfa 0xfa 0xfa 0xfb 0xfb 0xfb 0xfb 0xfb 0xfc 0xfc 0xfc 0xfc 0xfd 0xfd 0xfd 0xfd 0xfd 0xfe 0xfe 0xfe 0xfe 0xff 0xff>; + }; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,turn-on-brightness = <0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "disabled"; + nvidia,smooth-k-incr = <0x4>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,turn-off-brightness = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,sw-update-delay = <0x0>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x1>; + }; + + disp-default-out { + nvidia,out-xres = <0xa00>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-flags = <0x20>; + nvidia,out-type = <0x2>; + nvidia,out-yres = <0x640>; + nvidia,out-height = <0x87>; + nvidia,out-width = <0xd8>; + nvidia,out-rotation = <0xb4>; + }; + + display-timings { + + 2560x1600-32 { + hsync-len = <0x20>; + nvidia,h-ref-to-sync = <0x0>; + hfront-porch = <0x148>; + vfront-porch = <0x2>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x1>; + vactive = <0x640>; + hback-porch = <0x50>; + clock-frequency = <0x118a1cc0>; + hactive = <0xa00>; + vback-porch = <0x5>; + }; + }; + }; + + panel-null-dsi-hotplug { + nvidia,dsi-ganged-type = <0x1>; + compatible = "null,dsi-hotplug"; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-ganged-swap-links = <0x1>; + nvidia,dsi-video-burst-mode = <0x0>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-video-clock-mode = <0x0>; + nvidia,dsi-suspend-stop-stream-late = <0x1>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-video-data-type = <0x0>; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + nvidia,edid = <0xffffff 0xffffff00 0x10ac68a0 0x55344b31 0x1c160103 0x80351e78 0xea9265a6 0x55559f28 0xd5054a5 0x4b00714f 0x8180d1c0 0x1010101 0x1010101 0x101023a 0x80187138 0x2d40582c 0x4500132b 0x2100001e 0xff 0x573856 0x59393237 0x41314b34 0x550a0000 0xfc0044 0x454c4c20 0x53543234 0x32304c0a 0xfd 0x384c1e 0x5311000a 0x20202020 0x20200198>; + nvidia,dsi-pkt-seq = <0x1 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff>; + nvidia,dsi-instance = <0x0>; + nvidia,default_color_space = <0x0>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,dsi-hdmi-bridge = <0x1>; + + smartdimmer { + status = "disabled"; + }; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x2>; + nvidia,out-yres = <0x870>; + }; + + nvdisp-cmu { + nvidia,cmu-lut = <0x6000 0x6000 0x6000 0x6191 0x6191 0x6191 0x6322 0x6322 0x6322 0x643b 0x643b 0x643b 0x64ba 0x64ba 0x64ba 0x6539 0x6539 0x6539 0x65b8 0x65b8 0x65b8 0x6637 0x6637 0x6637 0x66b6 0x66b6 0x66b6 0x6735 0x6735 0x6735 0x67b4 0x67b4 0x67b4 0x6826 0x6826 0x6826 0x687d 0x687d 0x687d 0x68d4 0x68d4 0x68d4 0x692b 0x692b 0x692b 0x6983 0x6983 0x6983 0x69da 0x69da 0x69da 0x6a31 0x6a31 0x6a31 0x6a88 0x6a88 0x6a88 0x6ae0 0x6ae0 0x6ae0 0x6b37 0x6b37 0x6b37 0x6b8e 0x6b8e 0x6b8e 0x6be5 0x6be5 0x6be5 0x6c28 0x6c28 0x6c28 0x6c5b 0x6c5b 0x6c5b 0x6c8e 0x6c8e 0x6c8e 0x6cc1 0x6cc1 0x6cc1 0x6cf4 0x6cf4 0x6cf4 0x6d27 0x6d27 0x6d27 0x6d5a 0x6d5a 0x6d5a 0x6d8d 0x6d8d 0x6d8d 0x6dbf 0x6dbf 0x6dbf 0x6df2 0x6df2 0x6df2 0x6e25 0x6e25 0x6e25 0x6e58 0x6e58 0x6e58 0x6e8b 0x6e8b 0x6e8b 0x6ebe 0x6ebe 0x6ebe 0x6ef1 0x6ef1 0x6ef1 0x6f24 0x6f24 0x6f24 0x6f57 0x6f57 0x6f57 0x6f8a 0x6f8a 0x6f8a 0x6fbd 0x6fbd 0x6fbd 0x6ff0 0x6ff0 0x6ff0 0x701a 0x701a 0x701a 0x7037 0x7037 0x7037 0x7053 0x7053 0x7053 0x706f 0x706f 0x706f 0x708c 0x708c 0x708c 0x70a8 0x70a8 0x70a8 0x70c5 0x70c5 0x70c5 0x70e1 0x70e1 0x70e1 0x70fe 0x70fe 0x70fe 0x711a 0x711a 0x711a 0x7136 0x7136 0x7136 0x7153 0x7153 0x7153 0x716f 0x716f 0x716f 0x718c 0x718c 0x718c 0x71a8 0x71a8 0x71a8 0x71c4 0x71c4 0x71c4 0x71e1 0x71e1 0x71e1 0x71fd 0x71fd 0x71fd 0x721a 0x721a 0x721a 0x7236 0x7236 0x7236 0x7253 0x7253 0x7253 0x726f 0x726f 0x726f 0x728b 0x728b 0x728b 0x72a8 0x72a8 0x72a8 0x72c4 0x72c4 0x72c4 0x72e1 0x72e1 0x72e1 0x72fd 0x72fd 0x72fd 0x731a 0x731a 0x731a 0x7336 0x7336 0x7336 0x7352 0x7352 0x7352 0x736f 0x736f 0x736f 0x738b 0x738b 0x738b 0x73a8 0x73a8 0x73a8 0x73c4 0x73c4 0x73c4 0x73e1 0x73e1 0x73e1 0x73fd 0x73fd 0x73fd 0x741b 0x741b 0x741b 0x743f 0x743f 0x743f 0x7463 0x7463 0x7463 0x7486 0x7486 0x7486 0x74aa 0x74aa 0x74aa 0x74ce 0x74ce 0x74ce 0x74f2 0x74f2 0x74f2 0x7516 0x7516 0x7516 0x753a 0x753a 0x753a 0x755d 0x755d 0x755d 0x7581 0x7581 0x7581 0x75a5 0x75a5 0x75a5 0x75c9 0x75c9 0x75c9 0x75ed 0x75ed 0x75ed 0x7611 0x7611 0x7611 0x7634 0x7634 0x7634 0x7658 0x7658 0x7658 0x767c 0x767c 0x767c 0x76a0 0x76a0 0x76a0 0x76c4 0x76c4 0x76c4 0x76e8 0x76e8 0x76e8 0x770b 0x770b 0x770b 0x772f 0x772f 0x772f 0x7753 0x7753 0x7753 0x7777 0x7777 0x7777 0x779b 0x779b 0x779b 0x77bf 0x77bf 0x77bf 0x77e2 0x77e2 0x77e2 0x7806 0x7806 0x7806 0x7825 0x7825 0x7825 0x7840 0x7840 0x7840 0x785b 0x785b 0x785b 0x7876 0x7876 0x7876 0x7891 0x7891 0x7891 0x78ac 0x78ac 0x78ac 0x78c7 0x78c7 0x78c7 0x78e2 0x78e2 0x78e2 0x78fd 0x78fd 0x78fd 0x7918 0x7918 0x7918 0x7933 0x7933 0x7933 0x794e 0x794e 0x794e 0x7969 0x7969 0x7969 0x7984 0x7984 0x7984 0x799f 0x799f 0x799f 0x79ba 0x79ba 0x79ba 0x79d5 0x79d5 0x79d5 0x79f0 0x79f0 0x79f0 0x7a0b 0x7a0b 0x7a0b 0x7a26 0x7a26 0x7a26 0x7a41 0x7a41 0x7a41 0x7a5c 0x7a5c 0x7a5c 0x7a77 0x7a77 0x7a77 0x7a92 0x7a92 0x7a92 0x7aad 0x7aad 0x7aad 0x7ac8 0x7ac8 0x7ac8 0x7ae3 0x7ae3 0x7ae3 0x7afe 0x7afe 0x7afe 0x7b19 0x7b19 0x7b19 0x7b34 0x7b34 0x7b34 0x7b4f 0x7b4f 0x7b4f 0x7b6a 0x7b6a 0x7b6a 0x7b85 0x7b85 0x7b85 0x7ba0 0x7ba0 0x7ba0 0x7bbb 0x7bbb 0x7bbb 0x7bd5 0x7bd5 0x7bd5 0x7bf0 0x7bf0 0x7bf0 0x7c0b 0x7c0b 0x7c0b 0x7c23 0x7c23 0x7c23 0x7c35 0x7c35 0x7c35 0x7c47 0x7c47 0x7c47 0x7c59 0x7c59 0x7c59 0x7c6b 0x7c6b 0x7c6b 0x7c7d 0x7c7d 0x7c7d 0x7c90 0x7c90 0x7c90 0x7ca2 0x7ca2 0x7ca2 0x7cb4 0x7cb4 0x7cb4 0x7cc6 0x7cc6 0x7cc6 0x7cd8 0x7cd8 0x7cd8 0x7cea 0x7cea 0x7cea 0x7cfc 0x7cfc 0x7cfc 0x7d0f 0x7d0f 0x7d0f 0x7d21 0x7d21 0x7d21 0x7d33 0x7d33 0x7d33 0x7d45 0x7d45 0x7d45 0x7d57 0x7d57 0x7d57 0x7d69 0x7d69 0x7d69 0x7d7b 0x7d7b 0x7d7b 0x7d8e 0x7d8e 0x7d8e 0x7da0 0x7da0 0x7da0 0x7db2 0x7db2 0x7db2 0x7dc4 0x7dc4 0x7dc4 0x7dd6 0x7dd6 0x7dd6 0x7de8 0x7de8 0x7de8 0x7dfa 0x7dfa 0x7dfa 0x7e0d 0x7e0d 0x7e0d 0x7e1f 0x7e1f 0x7e1f 0x7e31 0x7e31 0x7e31 0x7e43 0x7e43 0x7e43 0x7e55 0x7e55 0x7e55 0x7e67 0x7e67 0x7e67 0x7e79 0x7e79 0x7e79 0x7e8c 0x7e8c 0x7e8c 0x7e9e 0x7e9e 0x7e9e 0x7eb0 0x7eb0 0x7eb0 0x7ec2 0x7ec2 0x7ec2 0x7ed4 0x7ed4 0x7ed4 0x7ee6 0x7ee6 0x7ee6 0x7ef8 0x7ef8 0x7ef8 0x7f0b 0x7f0b 0x7f0b 0x7f1d 0x7f1d 0x7f1d 0x7f2f 0x7f2f 0x7f2f 0x7f41 0x7f41 0x7f41 0x7f53 0x7f53 0x7f53 0x7f65 0x7f65 0x7f65 0x7f77 0x7f77 0x7f77 0x7f8a 0x7f8a 0x7f8a 0x7f9c 0x7f9c 0x7f9c 0x7fae 0x7fae 0x7fae 0x7fc0 0x7fc0 0x7fc0 0x7fd2 0x7fd2 0x7fd2 0x7fe4 0x7fe4 0x7fe4 0x7ff7 0x7ff7 0x7ff7 0x8009 0x8009 0x8009 0x801b 0x801b 0x801b 0x802b 0x802b 0x802b 0x803a 0x803a 0x803a 0x804a 0x804a 0x804a 0x8059 0x8059 0x8059 0x8069 0x8069 0x8069 0x8078 0x8078 0x8078 0x8087 0x8087 0x8087 0x8097 0x8097 0x8097 0x80a6 0x80a6 0x80a6 0x80b6 0x80b6 0x80b6 0x80c5 0x80c5 0x80c5 0x80d5 0x80d5 0x80d5 0x80e4 0x80e4 0x80e4 0x80f4 0x80f4 0x80f4 0x8103 0x8103 0x8103 0x8112 0x8112 0x8112 0x8122 0x8122 0x8122 0x8131 0x8131 0x8131 0x8141 0x8141 0x8141 0x8150 0x8150 0x8150 0x8160 0x8160 0x8160 0x816f 0x816f 0x816f 0x817e 0x817e 0x817e 0x818e 0x818e 0x818e 0x819d 0x819d 0x819d 0x81ad 0x81ad 0x81ad 0x81bc 0x81bc 0x81bc 0x81cc 0x81cc 0x81cc 0x81db 0x81db 0x81db 0x81eb 0x81eb 0x81eb 0x81fa 0x81fa 0x81fa 0x8209 0x8209 0x8209 0x8219 0x8219 0x8219 0x8228 0x8228 0x8228 0x8238 0x8238 0x8238 0x8247 0x8247 0x8247 0x8257 0x8257 0x8257 0x8266 0x8266 0x8266 0x8275 0x8275 0x8275 0x8285 0x8285 0x8285 0x8294 0x8294 0x8294 0x82a4 0x82a4 0x82a4 0x82b3 0x82b3 0x82b3 0x82c3 0x82c3 0x82c3 0x82d2 0x82d2 0x82d2 0x82e2 0x82e2 0x82e2 0x82f1 0x82f1 0x82f1 0x8300 0x8300 0x8300 0x8310 0x8310 0x8310 0x831f 0x831f 0x831f 0x832f 0x832f 0x832f 0x833e 0x833e 0x833e 0x834e 0x834e 0x834e 0x835d 0x835d 0x835d 0x836c 0x836c 0x836c 0x837c 0x837c 0x837c 0x838b 0x838b 0x838b 0x839b 0x839b 0x839b 0x83aa 0x83aa 0x83aa 0x83ba 0x83ba 0x83ba 0x83c9 0x83c9 0x83c9 0x83d8 0x83d8 0x83d8 0x83e8 0x83e8 0x83e8 0x83f7 0x83f7 0x83f7 0x8407 0x8407 0x8407 0x8416 0x8416 0x8416 0x8425 0x8425 0x8425 0x8431 0x8431 0x8431 0x843d 0x843d 0x843d 0x8449 0x8449 0x8449 0x8455 0x8455 0x8455 0x8462 0x8462 0x8462 0x846e 0x846e 0x846e 0x847a 0x847a 0x847a 0x8486 0x8486 0x8486 0x8492 0x8492 0x8492 0x849e 0x849e 0x849e 0x84aa 0x84aa 0x84aa 0x84b6 0x84b6 0x84b6 0x84c2 0x84c2 0x84c2 0x84ce 0x84ce 0x84ce 0x84da 0x84da 0x84da 0x84e7 0x84e7 0x84e7 0x84f3 0x84f3 0x84f3 0x84ff 0x84ff 0x84ff 0x850b 0x850b 0x850b 0x8517 0x8517 0x8517 0x8523 0x8523 0x8523 0x852f 0x852f 0x852f 0x853b 0x853b 0x853b 0x8547 0x8547 0x8547 0x8553 0x8553 0x8553 0x855f 0x855f 0x855f 0x856c 0x856c 0x856c 0x8578 0x8578 0x8578 0x8584 0x8584 0x8584 0x8590 0x8590 0x8590 0x859c 0x859c 0x859c 0x85a8 0x85a8 0x85a8 0x85b4 0x85b4 0x85b4 0x85c0 0x85c0 0x85c0 0x85cc 0x85cc 0x85cc 0x85d8 0x85d8 0x85d8 0x85e4 0x85e4 0x85e4 0x85f0 0x85f0 0x85f0 0x85fd 0x85fd 0x85fd 0x8609 0x8609 0x8609 0x8615 0x8615 0x8615 0x8621 0x8621 0x8621 0x862d 0x862d 0x862d 0x8639 0x8639 0x8639 0x8645 0x8645 0x8645 0x8651 0x8651 0x8651 0x865d 0x865d 0x865d 0x8669 0x8669 0x8669 0x8675 0x8675 0x8675 0x8682 0x8682 0x8682 0x868e 0x868e 0x868e 0x869a 0x869a 0x869a 0x86a6 0x86a6 0x86a6 0x86b2 0x86b2 0x86b2 0x86be 0x86be 0x86be 0x86ca 0x86ca 0x86ca 0x86d6 0x86d6 0x86d6 0x86e2 0x86e2 0x86e2 0x86ee 0x86ee 0x86ee 0x86fa 0x86fa 0x86fa 0x8707 0x8707 0x8707 0x8713 0x8713 0x8713 0x871f 0x871f 0x871f 0x872b 0x872b 0x872b 0x8737 0x8737 0x8737 0x8743 0x8743 0x8743 0x874f 0x874f 0x874f 0x875b 0x875b 0x875b 0x8767 0x8767 0x8767 0x8773 0x8773 0x8773 0x877f 0x877f 0x877f 0x878b 0x878b 0x878b 0x8798 0x8798 0x8798 0x87a4 0x87a4 0x87a4 0x87b0 0x87b0 0x87b0 0x87bc 0x87bc 0x87bc 0x87c8 0x87c8 0x87c8 0x87d4 0x87d4 0x87d4 0x87e0 0x87e0 0x87e0 0x87ec 0x87ec 0x87ec 0x87f8 0x87f8 0x87f8 0x8804 0x8804 0x8804 0x8810 0x8810 0x8810 0x881d 0x881d 0x881d 0x8829 0x8829 0x8829 0x8834 0x8834 0x8834 0x883f 0x883f 0x883f 0x884b 0x884b 0x884b 0x8856 0x8856 0x8856 0x8862 0x8862 0x8862 0x886d 0x886d 0x886d 0x8879 0x8879 0x8879 0x8884 0x8884 0x8884 0x8890 0x8890 0x8890 0x889b 0x889b 0x889b 0x88a6 0x88a6 0x88a6 0x88b2 0x88b2 0x88b2 0x88bd 0x88bd 0x88bd 0x88c9 0x88c9 0x88c9 0x88d4 0x88d4 0x88d4 0x88e0 0x88e0 0x88e0 0x88eb 0x88eb 0x88eb 0x88f6 0x88f6 0x88f6 0x8902 0x8902 0x8902 0x890d 0x890d 0x890d 0x8919 0x8919 0x8919 0x8924 0x8924 0x8924 0x8930 0x8930 0x8930 0x893b 0x893b 0x893b 0x8947 0x8947 0x8947 0x8952 0x8952 0x8952 0x895d 0x895d 0x895d 0x8969 0x8969 0x8969 0x8974 0x8974 0x8974 0x8980 0x8980 0x8980 0x898b 0x898b 0x898b 0x8997 0x8997 0x8997 0x89a2 0x89a2 0x89a2 0x89ae 0x89ae 0x89ae 0x89b9 0x89b9 0x89b9 0x89c4 0x89c4 0x89c4 0x89d0 0x89d0 0x89d0 0x89db 0x89db 0x89db 0x89e7 0x89e7 0x89e7 0x89f2 0x89f2 0x89f2 0x89fe 0x89fe 0x89fe 0x8a09 0x8a09 0x8a09 0x8a15 0x8a15 0x8a15 0x8a20 0x8a20 0x8a20 0x8a2b 0x8a2b 0x8a2b 0x8a37 0x8a37 0x8a37 0x8a42 0x8a42 0x8a42 0x8a4e 0x8a4e 0x8a4e 0x8a59 0x8a59 0x8a59 0x8a65 0x8a65 0x8a65 0x8a70 0x8a70 0x8a70 0x8a7b 0x8a7b 0x8a7b 0x8a87 0x8a87 0x8a87 0x8a92 0x8a92 0x8a92 0x8a9e 0x8a9e 0x8a9e 0x8aa9 0x8aa9 0x8aa9 0x8ab5 0x8ab5 0x8ab5 0x8ac0 0x8ac0 0x8ac0 0x8acc 0x8acc 0x8acc 0x8ad7 0x8ad7 0x8ad7 0x8ae2 0x8ae2 0x8ae2 0x8aee 0x8aee 0x8aee 0x8af9 0x8af9 0x8af9 0x8b05 0x8b05 0x8b05 0x8b10 0x8b10 0x8b10 0x8b1c 0x8b1c 0x8b1c 0x8b27 0x8b27 0x8b27 0x8b33 0x8b33 0x8b33 0x8b3e 0x8b3e 0x8b3e 0x8b49 0x8b49 0x8b49 0x8b55 0x8b55 0x8b55 0x8b60 0x8b60 0x8b60 0x8b6c 0x8b6c 0x8b6c 0x8b77 0x8b77 0x8b77 0x8b83 0x8b83 0x8b83 0x8b8e 0x8b8e 0x8b8e 0x8b99 0x8b99 0x8b99 0x8ba5 0x8ba5 0x8ba5 0x8bb0 0x8bb0 0x8bb0 0x8bbc 0x8bbc 0x8bbc 0x8bc7 0x8bc7 0x8bc7 0x8bd3 0x8bd3 0x8bd3 0x8bde 0x8bde 0x8bde 0x8bea 0x8bea 0x8bea 0x8bf5 0x8bf5 0x8bf5 0x8c00 0x8c00 0x8c00 0x8c0c 0x8c0c 0x8c0c 0x8c17 0x8c17 0x8c17 0x8c23 0x8c23 0x8c23 0x8c2e 0x8c2e 0x8c2e 0x8c38 0x8c38 0x8c38 0x8c43 0x8c43 0x8c43 0x8c4d 0x8c4d 0x8c4d 0x8c58 0x8c58 0x8c58 0x8c62 0x8c62 0x8c62 0x8c6c 0x8c6c 0x8c6c 0x8c77 0x8c77 0x8c77 0x8c81 0x8c81 0x8c81 0x8c8c 0x8c8c 0x8c8c 0x8c96 0x8c96 0x8c96 0x8ca0 0x8ca0 0x8ca0 0x8cab 0x8cab 0x8cab 0x8cb5 0x8cb5 0x8cb5 0x8cc0 0x8cc0 0x8cc0 0x8cca 0x8cca 0x8cca 0x8cd4 0x8cd4 0x8cd4 0x8cdf 0x8cdf 0x8cdf 0x8ce9 0x8ce9 0x8ce9 0x8cf4 0x8cf4 0x8cf4 0x8cfe 0x8cfe 0x8cfe 0x8d09 0x8d09 0x8d09 0x8d13 0x8d13 0x8d13 0x8d1d 0x8d1d 0x8d1d 0x8d28 0x8d28 0x8d28 0x8d32 0x8d32 0x8d32 0x8d3d 0x8d3d 0x8d3d 0x8d47 0x8d47 0x8d47 0x8d51 0x8d51 0x8d51 0x8d5c 0x8d5c 0x8d5c 0x8d66 0x8d66 0x8d66 0x8d71 0x8d71 0x8d71 0x8d7b 0x8d7b 0x8d7b 0x8d85 0x8d85 0x8d85 0x8d90 0x8d90 0x8d90 0x8d9a 0x8d9a 0x8d9a 0x8da5 0x8da5 0x8da5 0x8daf 0x8daf 0x8daf 0x8db9 0x8db9 0x8db9 0x8dc4 0x8dc4 0x8dc4 0x8dce 0x8dce 0x8dce 0x8dd9 0x8dd9 0x8dd9 0x8de3 0x8de3 0x8de3 0x8ded 0x8ded 0x8ded 0x8df8 0x8df8 0x8df8 0x8e02 0x8e02 0x8e02 0x8e0d 0x8e0d 0x8e0d 0x8e17 0x8e17 0x8e17 0x8e22 0x8e22 0x8e22 0x8e2c 0x8e2c 0x8e2c 0x8e36 0x8e36 0x8e36 0x8e41 0x8e41 0x8e41 0x8e4b 0x8e4b 0x8e4b 0x8e56 0x8e56 0x8e56 0x8e60 0x8e60 0x8e60 0x8e6a 0x8e6a 0x8e6a 0x8e75 0x8e75 0x8e75 0x8e7f 0x8e7f 0x8e7f 0x8e8a 0x8e8a 0x8e8a 0x8e94 0x8e94 0x8e94 0x8e9e 0x8e9e 0x8e9e 0x8ea9 0x8ea9 0x8ea9 0x8eb3 0x8eb3 0x8eb3 0x8ebe 0x8ebe 0x8ebe 0x8ec8 0x8ec8 0x8ec8 0x8ed2 0x8ed2 0x8ed2 0x8edd 0x8edd 0x8edd 0x8ee7 0x8ee7 0x8ee7 0x8ef2 0x8ef2 0x8ef2 0x8efc 0x8efc 0x8efc 0x8f07 0x8f07 0x8f07 0x8f11 0x8f11 0x8f11 0x8f1b 0x8f1b 0x8f1b 0x8f26 0x8f26 0x8f26 0x8f30 0x8f30 0x8f30 0x8f3b 0x8f3b 0x8f3b 0x8f45 0x8f45 0x8f45 0x8f4f 0x8f4f 0x8f4f 0x8f5a 0x8f5a 0x8f5a 0x8f64 0x8f64 0x8f64 0x8f6f 0x8f6f 0x8f6f 0x8f79 0x8f79 0x8f79 0x8f83 0x8f83 0x8f83 0x8f8e 0x8f8e 0x8f8e 0x8f98 0x8f98 0x8f98 0x8fa3 0x8fa3 0x8fa3 0x8fad 0x8fad 0x8fad 0x8fb7 0x8fb7 0x8fb7 0x8fc2 0x8fc2 0x8fc2 0x8fcc 0x8fcc 0x8fcc 0x8fd7 0x8fd7 0x8fd7 0x8fe1 0x8fe1 0x8fe1 0x8feb 0x8feb 0x8feb 0x8ff6 0x8ff6 0x8ff6 0x9000 0x9000 0x9000 0x900b 0x900b 0x900b 0x9015 0x9015 0x9015 0x9020 0x9020 0x9020 0x902a 0x902a 0x902a 0x9034 0x9034 0x9034 0x903e 0x903e 0x903e 0x9048 0x9048 0x9048 0x9052 0x9052 0x9052 0x905c 0x905c 0x905c 0x9066 0x9066 0x9066 0x9070 0x9070 0x9070 0x907a 0x907a 0x907a 0x9084 0x9084 0x9084 0x908e 0x908e 0x908e 0x9098 0x9098 0x9098 0x90a2 0x90a2 0x90a2 0x90ac 0x90ac 0x90ac 0x90b6 0x90b6 0x90b6 0x90c0 0x90c0 0x90c0 0x90ca 0x90ca 0x90ca 0x90d4 0x90d4 0x90d4 0x90de 0x90de 0x90de 0x90e8 0x90e8 0x90e8 0x90f2 0x90f2 0x90f2 0x90fc 0x90fc 0x90fc 0x9106 0x9106 0x9106 0x9110 0x9110 0x9110 0x911a 0x911a 0x911a 0x9123 0x9123 0x9123 0x912d 0x912d 0x912d 0x9137 0x9137 0x9137 0x9141 0x9141 0x9141 0x914b 0x914b 0x914b 0x9155 0x9155 0x9155 0x915f 0x915f 0x915f 0x9169 0x9169 0x9169 0x9173 0x9173 0x9173 0x917d 0x917d 0x917d 0x9187 0x9187 0x9187 0x9191 0x9191 0x9191 0x919b 0x919b 0x919b 0x91a5 0x91a5 0x91a5 0x91af 0x91af 0x91af 0x91b9 0x91b9 0x91b9 0x91c3 0x91c3 0x91c3 0x91cd 0x91cd 0x91cd 0x91d7 0x91d7 0x91d7 0x91e1 0x91e1 0x91e1 0x91eb 0x91eb 0x91eb 0x91f5 0x91f5 0x91f5 0x91ff 0x91ff 0x91ff 0x9209 0x9209 0x9209 0x9213 0x9213 0x9213 0x921d 0x921d 0x921d 0x9227 0x9227 0x9227 0x9231 0x9231 0x9231 0x923b 0x923b 0x923b 0x9245 0x9245 0x9245 0x924f 0x924f 0x924f 0x9259 0x9259 0x9259 0x9263 0x9263 0x9263 0x926d 0x926d 0x926d 0x9277 0x9277 0x9277 0x9281 0x9281 0x9281 0x928b 0x928b 0x928b 0x9295 0x9295 0x9295 0x929f 0x929f 0x929f 0x92a8 0x92a8 0x92a8 0x92b2 0x92b2 0x92b2 0x92bc 0x92bc 0x92bc 0x92c6 0x92c6 0x92c6 0x92d0 0x92d0 0x92d0 0x92da 0x92da 0x92da 0x92e4 0x92e4 0x92e4 0x92ee 0x92ee 0x92ee 0x92f8 0x92f8 0x92f8 0x9302 0x9302 0x9302 0x930c 0x930c 0x930c 0x9316 0x9316 0x9316 0x9320 0x9320 0x9320 0x932a 0x932a 0x932a 0x9334 0x9334 0x9334 0x933e 0x933e 0x933e 0x9348 0x9348 0x9348 0x9352 0x9352 0x9352 0x935c 0x935c 0x935c 0x9366 0x9366 0x9366 0x9370 0x9370 0x9370 0x937a 0x937a 0x937a 0x9384 0x9384 0x9384 0x938e 0x938e 0x938e 0x9398 0x9398 0x9398 0x93a2 0x93a2 0x93a2 0x93ac 0x93ac 0x93ac 0x93b6 0x93b6 0x93b6 0x93c0 0x93c0 0x93c0 0x93ca 0x93ca 0x93ca 0x93d4 0x93d4 0x93d4 0x93de 0x93de 0x93de 0x93e8 0x93e8 0x93e8 0x93f2 0x93f2 0x93f2 0x93fc 0x93fc 0x93fc 0x9406 0x9406 0x9406 0x9410 0x9410 0x9410 0x941a 0x941a 0x941a 0x9423 0x9423 0x9423 0x942d 0x942d 0x942d 0x9437 0x9437 0x9437 0x9440 0x9440 0x9440 0x9449 0x9449 0x9449 0x9451 0x9451 0x9451 0x945a 0x945a 0x945a 0x9463 0x9463 0x9463 0x946c 0x946c 0x946c 0x9475 0x9475 0x9475 0x947e 0x947e 0x947e 0x9486 0x9486 0x9486 0x948f 0x948f 0x948f 0x9498 0x9498 0x9498 0x94a1 0x94a1 0x94a1 0x94aa 0x94aa 0x94aa 0x94b3 0x94b3 0x94b3 0x94bb 0x94bb 0x94bb 0x94c4 0x94c4 0x94c4 0x94cd 0x94cd 0x94cd 0x94d6 0x94d6 0x94d6 0x94df 0x94df 0x94df 0x94e8 0x94e8 0x94e8 0x94f0 0x94f0 0x94f0 0x94f9 0x94f9 0x94f9 0x9502 0x9502 0x9502 0x950b 0x950b 0x950b 0x9514 0x9514 0x9514 0x951d 0x951d 0x951d 0x9525 0x9525 0x9525 0x952e 0x952e 0x952e 0x9537 0x9537 0x9537 0x9540 0x9540 0x9540 0x9549 0x9549 0x9549 0x9552 0x9552 0x9552 0x955a 0x955a 0x955a 0x9563 0x9563 0x9563 0x956c 0x956c 0x956c 0x9575 0x9575 0x9575 0x957e 0x957e 0x957e 0x9587 0x9587 0x9587 0x958f 0x958f 0x958f 0x9598 0x9598 0x9598 0x95a1 0x95a1 0x95a1 0x95aa 0x95aa 0x95aa 0x95b3 0x95b3 0x95b3 0x95bc 0x95bc 0x95bc 0x95c4 0x95c4 0x95c4 0x95cd 0x95cd 0x95cd 0x95d6 0x95d6 0x95d6 0x95df 0x95df 0x95df 0x95e8 0x95e8 0x95e8 0x95f1 0x95f1 0x95f1 0x95f9 0x95f9 0x95f9 0x9602 0x9602 0x9602 0x960b 0x960b 0x960b 0x9614 0x9614 0x9614 0x961d 0x961d 0x961d 0x9626 0x9626 0x9626 0x962e 0x962e 0x962e 0x9637 0x9637 0x9637 0x9640 0x9640 0x9640 0x9649 0x9649 0x9649 0x9652 0x9652 0x9652 0x965b 0x965b 0x965b 0x9663 0x9663 0x9663 0x966c 0x966c 0x966c 0x9675 0x9675 0x9675 0x967e 0x967e 0x967e 0x9687 0x9687 0x9687 0x9690 0x9690 0x9690 0x9698 0x9698 0x9698 0x96a1 0x96a1 0x96a1 0x96aa 0x96aa 0x96aa 0x96b3 0x96b3 0x96b3 0x96bc 0x96bc 0x96bc 0x96c5 0x96c5 0x96c5 0x96cd 0x96cd 0x96cd 0x96d6 0x96d6 0x96d6 0x96df 0x96df 0x96df 0x96e8 0x96e8 0x96e8 0x96f1 0x96f1 0x96f1 0x96f9 0x96f9 0x96f9 0x9702 0x9702 0x9702 0x970b 0x970b 0x970b 0x9714 0x9714 0x9714 0x971d 0x971d 0x971d 0x9726 0x9726 0x9726 0x972e 0x972e 0x972e 0x9737 0x9737 0x9737 0x9740 0x9740 0x9740 0x9749 0x9749 0x9749 0x9752 0x9752 0x9752 0x975b 0x975b 0x975b 0x9763 0x9763 0x9763 0x976c 0x976c 0x976c 0x9775 0x9775 0x9775 0x977e 0x977e 0x977e 0x9787 0x9787 0x9787 0x9790 0x9790 0x9790 0x9798 0x9798 0x9798 0x97a1 0x97a1 0x97a1 0x97aa 0x97aa 0x97aa 0x97b3 0x97b3 0x97b3 0x97bc 0x97bc 0x97bc 0x97c5 0x97c5 0x97c5 0x97cd 0x97cd 0x97cd 0x97d6 0x97d6 0x97d6 0x97df 0x97df 0x97df 0x97e8 0x97e8 0x97e8 0x97f1 0x97f1 0x97f1 0x97fa 0x97fa 0x97fa 0x9802 0x9802 0x9802 0x980b 0x980b 0x980b 0x9814 0x9814 0x9814 0x981d 0x981d 0x981d 0x9826 0x9826 0x9826 0x982f 0x982f 0x982f 0x9837 0x9837 0x9837 0x983f 0x983f 0x983f 0x9847 0x9847 0x9847 0x984f 0x984f 0x984f 0x9857 0x9857 0x9857 0x985f 0x985f 0x985f 0x9867 0x9867 0x9867 0x986e 0x986e 0x986e 0x9876 0x9876 0x9876 0x987e 0x987e 0x987e 0x9886 0x9886 0x9886 0x988e 0x988e 0x988e 0x9896 0x9896 0x9896 0x989e 0x989e 0x989e 0x98a5 0x98a5 0x98a5 0x98ad 0x98ad 0x98ad 0x98b5 0x98b5 0x98b5 0x98bd 0x98bd 0x98bd 0x98c5 0x98c5 0x98c5 0x98cd 0x98cd 0x98cd 0x98d5 0x98d5 0x98d5 0x98dc 0x98dc 0x98dc 0x98e4 0x98e4 0x98e4 0x98ec 0x98ec 0x98ec 0x98f4 0x98f4 0x98f4 0x98fc 0x98fc 0x98fc 0x9904 0x9904 0x9904 0x990c 0x990c 0x990c 0x9913 0x9913 0x9913 0x991b 0x991b 0x991b 0x9923 0x9923 0x9923 0x992b 0x992b 0x992b 0x9933 0x9933 0x9933 0x993b 0x993b 0x993b 0x9943 0x9943 0x9943 0x994a 0x994a 0x994a 0x9952 0x9952 0x9952 0x995a 0x995a 0x995a 0x9962 0x9962 0x9962 0x996a 0x996a 0x996a 0x9972 0x9972 0x9972 0x997a 0x997a 0x997a 0x9981 0x9981 0x9981 0x9989 0x9989 0x9989 0x9991 0x9991 0x9991 0x9999 0x9999 0x9999 0x99a1 0x99a1 0x99a1 0x99a9 0x99a9 0x99a9 0x99b1 0x99b1 0x99b1 0x99b8 0x99b8 0x99b8 0x99c0 0x99c0 0x99c0 0x99c8 0x99c8 0x99c8 0x99d0 0x99d0 0x99d0 0x99d8 0x99d8 0x99d8 0x99e0 0x99e0 0x99e0 0x99e8 0x99e8 0x99e8 0x99ef 0x99ef 0x99ef 0x99f7 0x99f7 0x99f7 0x99ff 0x99ff 0x99ff 0x9a07 0x9a07 0x9a07 0x9a0f 0x9a0f 0x9a0f 0x9a17 0x9a17 0x9a17 0x9a1f 0x9a1f 0x9a1f 0x9a26 0x9a26 0x9a26 0x9a2e 0x9a2e 0x9a2e 0x9a36 0x9a36 0x9a36 0x9a3e 0x9a3e 0x9a3e 0x9a46 0x9a46 0x9a46 0x9a4e 0x9a4e 0x9a4e 0x9a56 0x9a56 0x9a56 0x9a5d 0x9a5d 0x9a5d 0x9a65 0x9a65 0x9a65 0x9a6d 0x9a6d 0x9a6d 0x9a75 0x9a75 0x9a75 0x9a7d 0x9a7d 0x9a7d 0x9a85 0x9a85 0x9a85 0x9a8d 0x9a8d 0x9a8d 0x9a94 0x9a94 0x9a94 0x9a9c 0x9a9c 0x9a9c 0x9aa4 0x9aa4 0x9aa4 0x9aac 0x9aac 0x9aac 0x9ab4 0x9ab4 0x9ab4 0x9abc 0x9abc 0x9abc 0x9ac4 0x9ac4 0x9ac4 0x9acb 0x9acb 0x9acb 0x9ad3 0x9ad3 0x9ad3 0x9adb 0x9adb 0x9adb 0x9ae3 0x9ae3 0x9ae3 0x9aeb 0x9aeb 0x9aeb 0x9af3 0x9af3 0x9af3 0x9afb 0x9afb 0x9afb 0x9b02 0x9b02 0x9b02 0x9b0a 0x9b0a 0x9b0a 0x9b12 0x9b12 0x9b12 0x9b1a 0x9b1a 0x9b1a 0x9b22 0x9b22 0x9b22 0x9b2a 0x9b2a 0x9b2a 0x9b32 0x9b32 0x9b32 0x9b39 0x9b39 0x9b39 0x9b41 0x9b41 0x9b41 0x9b49 0x9b49 0x9b49 0x9b51 0x9b51 0x9b51 0x9b59 0x9b59 0x9b59 0x9b61 0x9b61 0x9b61 0x9b69 0x9b69 0x9b69 0x9b70 0x9b70 0x9b70 0x9b78 0x9b78 0x9b78 0x9b80 0x9b80 0x9b80 0x9b88 0x9b88 0x9b88 0x9b90 0x9b90 0x9b90 0x9b98 0x9b98 0x9b98 0x9ba0 0x9ba0 0x9ba0 0x9ba7 0x9ba7 0x9ba7 0x9baf 0x9baf 0x9baf 0x9bb7 0x9bb7 0x9bb7 0x9bbf 0x9bbf 0x9bbf 0x9bc7 0x9bc7 0x9bc7 0x9bcf 0x9bcf 0x9bcf 0x9bd7 0x9bd7 0x9bd7 0x9bde 0x9bde 0x9bde 0x9be6 0x9be6 0x9be6 0x9bee 0x9bee 0x9bee 0x9bf6 0x9bf6 0x9bf6 0x9bfe 0x9bfe 0x9bfe 0x9c06 0x9c06 0x9c06 0x9c0e 0x9c0e 0x9c0e 0x9c15 0x9c15 0x9c15 0x9c1d 0x9c1d 0x9c1d 0x9c25 0x9c25 0x9c25 0x9c2d 0x9c2d 0x9c2d 0x9c35 0x9c35 0x9c35 0x9c3d 0x9c3d 0x9c3d 0x9c44 0x9c44 0x9c44 0x9c4b 0x9c4b 0x9c4b 0x9c53 0x9c53 0x9c53 0x9c5a 0x9c5a 0x9c5a 0x9c61 0x9c61 0x9c61 0x9c69 0x9c69 0x9c69 0x9c70 0x9c70 0x9c70 0x9c77 0x9c77 0x9c77 0x9c7f 0x9c7f 0x9c7f 0x9c86 0x9c86 0x9c86 0x9c8d 0x9c8d 0x9c8d 0x9c95 0x9c95 0x9c95 0x9c9c 0x9c9c 0x9c9c 0x9ca3 0x9ca3 0x9ca3 0x9cab 0x9cab 0x9cab 0x9cb2 0x9cb2 0x9cb2 0x9cb9 0x9cb9 0x9cb9 0x9cc1 0x9cc1 0x9cc1 0x9cc8 0x9cc8 0x9cc8 0x9ccf 0x9ccf 0x9ccf 0x9cd7 0x9cd7 0x9cd7 0x9cde 0x9cde 0x9cde 0x9ce5 0x9ce5 0x9ce5 0x9ced 0x9ced 0x9ced 0x9cf4 0x9cf4 0x9cf4 0x9cfb 0x9cfb 0x9cfb 0x9d03 0x9d03 0x9d03 0x9d0a 0x9d0a 0x9d0a 0x9d12 0x9d12 0x9d12 0x9d19 0x9d19 0x9d19 0x9d20 0x9d20 0x9d20 0x9d28 0x9d28 0x9d28 0x9d2f 0x9d2f 0x9d2f 0x9d36 0x9d36 0x9d36 0x9d3e 0x9d3e 0x9d3e 0x9d45 0x9d45 0x9d45 0x9d4c 0x9d4c 0x9d4c 0x9d54 0x9d54 0x9d54 0x9d5b 0x9d5b 0x9d5b 0x9d62 0x9d62 0x9d62 0x9d6a 0x9d6a 0x9d6a 0x9d71 0x9d71 0x9d71 0x9d78 0x9d78 0x9d78 0x9d80 0x9d80 0x9d80 0x9d87 0x9d87 0x9d87 0x9d8e 0x9d8e 0x9d8e 0x9d96 0x9d96 0x9d96 0x9d9d 0x9d9d 0x9d9d 0x9da4 0x9da4 0x9da4 0x9dac 0x9dac 0x9dac 0x9db3 0x9db3 0x9db3 0x9dba 0x9dba 0x9dba 0x9dc2 0x9dc2 0x9dc2 0x9dc9 0x9dc9 0x9dc9 0x9dd0 0x9dd0 0x9dd0 0x9dd8 0x9dd8 0x9dd8 0x9ddf 0x9ddf 0x9ddf 0x9de6 0x9de6 0x9de6 0x9dee 0x9dee 0x9dee 0x9df5 0x9df5 0x9df5 0x9dfc 0x9dfc 0x9dfc 0x9e04 0x9e04 0x9e04 0x9e0b 0x9e0b 0x9e0b 0x9e13 0x9e13 0x9e13 0x9e1a 0x9e1a 0x9e1a 0x9e21 0x9e21 0x9e21 0x9e29 0x9e29 0x9e29 0x9e30 0x9e30 0x9e30 0x9e37 0x9e37 0x9e37 0x9e3f 0x9e3f 0x9e3f 0x9e46 0x9e46 0x9e46 0x9e4d 0x9e4d 0x9e4d 0x9e55 0x9e55 0x9e55 0x9e5c 0x9e5c 0x9e5c 0x9e63 0x9e63 0x9e63 0x9e6b 0x9e6b 0x9e6b 0x9e72 0x9e72 0x9e72 0x9e79 0x9e79 0x9e79 0x9e81 0x9e81 0x9e81 0x9e88 0x9e88 0x9e88 0x9e8f 0x9e8f 0x9e8f 0x9e97 0x9e97 0x9e97 0x9e9e 0x9e9e 0x9e9e 0x9ea5 0x9ea5 0x9ea5 0x9ead 0x9ead 0x9ead 0x9eb4 0x9eb4 0x9eb4 0x9ebb 0x9ebb 0x9ebb 0x9ec3 0x9ec3 0x9ec3 0x9eca 0x9eca 0x9eca 0x9ed1 0x9ed1 0x9ed1 0x9ed9 0x9ed9 0x9ed9 0x9ee0 0x9ee0 0x9ee0 0x9ee7 0x9ee7 0x9ee7 0x9eef 0x9eef 0x9eef 0x9ef6 0x9ef6 0x9ef6 0x9efd 0x9efd 0x9efd 0x9f05 0x9f05 0x9f05 0x9f0c 0x9f0c 0x9f0c 0x9f14 0x9f14 0x9f14 0x9f1b 0x9f1b 0x9f1b 0x9f22 0x9f22 0x9f22 0x9f2a 0x9f2a 0x9f2a 0x9f31 0x9f31 0x9f31 0x9f38 0x9f38 0x9f38 0x9f40 0x9f40 0x9f40 0x9f47 0x9f47 0x9f47 0x9f4e 0x9f4e 0x9f4e 0x9f56 0x9f56 0x9f56 0x9f5d 0x9f5d 0x9f5d 0x9f64 0x9f64 0x9f64 0x9f6c 0x9f6c 0x9f6c 0x9f73 0x9f73 0x9f73 0x9f7a 0x9f7a 0x9f7a 0x9f82 0x9f82 0x9f82 0x9f89 0x9f89 0x9f89 0x9f90 0x9f90 0x9f90 0x9f98 0x9f98 0x9f98 0x9f9f 0x9f9f 0x9f9f 0x9fa6 0x9fa6 0x9fa6 0x9fae 0x9fae 0x9fae 0x9fb5 0x9fb5 0x9fb5 0x9fbc 0x9fbc 0x9fbc 0x9fc4 0x9fc4 0x9fc4 0x9fcb 0x9fcb 0x9fcb 0x9fd2 0x9fd2 0x9fd2 0x9fda 0x9fda 0x9fda 0x9fe1 0x9fe1 0x9fe1 0x9fe8 0x9fe8 0x9fe8 0x9ff0 0x9ff0 0x9ff0 0x9ff7 0x9ff7 0x9ff7 0x9fff 0x9fff 0x9fff>; + nvidia,panel-csc = <0xd581 0x2979 0xc5 0x0 0x831 0xcac1 0x20c 0x0 0x189 0x625 0xcc4a 0x0>; + }; + }; + }; + + se@15830000 { + compatible = "nvidia,tegra186-se3-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "rsa"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15830000 0x0 0x10000>; + iommus = <0x11 0xe>; + opcode_addr = <0x604>; + }; + + isp@15600000 { + power-domains = <0x1f 0x5>; + compatible = "nvidia,tegra186-isp"; + clocks = <0x10 0x32>; + resets = <0x10 0x19>; + clock-names = "isp"; + status = "okay"; + interrupts = <0x0 0xcd 0x4>; + iommu-group-id = <0x1>; + reg = <0x0 0x15600000 0x0 0x40000>; + iommus = <0x11 0x5>; + }; + + nvdisplay@15210000 { + pinctrl-5 = <0x79>; + nvidia,fb-flags = <0x1>; + compatible = "nvidia,tegra186-dc"; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x206 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x10b 0x10 0x3a>; + pinctrl-3 = <0x77>; + nvidia,cmu-enable = <0x1>; + vdd_hdmi_5v0-supply = <0x8a>; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x5a>; + pinctrl-1 = <0x75>; + nvidia,dc-connector = <0x8b>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "pll_d", "plld2", "plld3", "pllp_display", "pll_d_out1", "disp2_emc"; + pinctrl-10 = <0x7e>; + pinctrl-8 = <0x7c>; + win-mask = <0x38>; + avdd_hdmi-supply = <0x89>; + pinctrl-6 = <0x7a>; + status = "okay"; + fb_reserved = <0x81>; + interrupts = <0x0 0x9a 0x4>; + pinctrl-4 = <0x78>; + nvidia,emc-clk-rate = <0x11e1a300>; + phandle = <0x1c7>; + iommu-group-id = <0x1>; + avdd_hdmi_pll-supply = <0x12>; + pinctrl-2 = <0x76>; + nvidia,dc-flags = <0x1>; + reg = <0x0 0x15210000 0x0 0x10000>; + iommus = <0x11 0x9>; + pinctrl-0 = <0x74>; + iommu-direct-regions = <0x80 0x81 0x82>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head1"; + pinctrl-11 = <0x7f>; + nvidia,fb-win = <0x3>; + pinctrl-9 = <0x7d>; + nvidia,dc-or-node = "/host1x/sor1"; + linux,phandle = <0x1c7>; + nvidia,dc-ctrlnum = <0x1>; + pinctrl-7 = <0x7b>; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + nvidia,fb-bpp = <0x20>; + }; + + sor1 { + nvidia,dpaux = <0x91>; + compatible = "nvidia,tegra186-sor1"; + clocks = <0x10 0x5d 0x10 0x27 0x10 0x268 0x10 0x129 0x10 0x20b 0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + resets = <0x10 0x6c 0x10 0xf 0x10 0x10 0x10 0x11>; + clock-names = "sor1_ref", "sor_safe", "sor1_pad_clkout", "sor1", "pll_dp", "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + status = "okay"; + nvidia,xbar-ctrl = <0x0 0x1 0x2 0x3 0x4>; + interrupts = <0x0 0x9e 0x4>; + phandle = <0x8b>; + nvidia,sor-ctrlnum = <0x1>; + reg = <0x0 0x15580000 0x0 0x40000>; + reset-names = "sor1", "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + nvidia,ddc-i2c-bus = <0x92>; + linux,phandle = <0x8b>; + nvidia,hpd-gpio = <0x1b 0x79 0x1>; + nvidia,active-panel = <0x93>; + + prod-settings { + #prod-cells = <0x3>; + prod_list_hdmi_soc = "prod_c_hdmi_0m_54m", "prod_c_hdmi_54m_111m", "prod_c_hdmi_111m_223m", "prod_c_hdmi_223m_300m", "prod_c_hdmi_300m_600m"; + + prod_c_75M { + prod = <0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_hdmi_111m_223m { + prod = <0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hbr2 { + prod = <0x590 0xf00000 0x400000>; + }; + + prod_c_rbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_hdmi_223m_300m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_0m_54m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_600M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_300M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_54M { + prod = <0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hdmi_54m_111m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_150M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_300m_600m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_dp { + prod = <0x58c 0xf0f0f10 0x5050310 0x590 0x3000100 0x100 0x594 0xf0000000 0x0 0x598 0x2ff0 0x2440 0x59c 0x401800 0x0 0x5a0 0x400000 0x400000 0x5a8 0xff000000 0x34000000 0x70 0xffffffff 0x0 0x180 0x1 0x1>; + }; + }; + + hdmi-display { + compatible = "hdmi,display"; + generic-infoframe-type = <0x87>; + status = "okay"; + phandle = <0x93>; + linux,phandle = <0x93>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld2"; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x2>; + nvidia,out-type = <0x1>; + nvidia,out-yres = <0x870>; + }; + }; + + dp-display { + compatible = "dp, display"; + nvidia,is_ext_dp_panel = <0x1>; + status = "disabled"; + phandle = <0x1cb>; + linux,phandle = <0x1cb>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld2"; + nvidia,out-order = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + nvidia,out-yres = <0x870>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + + display-timings { + + 1920x1080-32 { + hsync-len = <0x2c>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x58>; + vfront-porch = <0x4>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x5>; + vactive = <0x438>; + hback-porch = <0x94>; + clock-frequency = <0x8d9ee20>; + hactive = <0x780>; + vback-porch = <0x24>; + }; + + 720x480-32 { + hsync-len = <0x3e>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x10>; + vfront-porch = <0x9>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x6>; + vactive = <0x1e0>; + hback-porch = <0x3c>; + clock-frequency = <0x19bfcc0>; + hactive = <0x2d0>; + vback-porch = <0x1e>; + }; + }; + + lt-data { + + tegra-dp-pe-regs { + pc2_l0 = <0x0 0x8 0x12 0x24 0x1 0xe 0x1d 0x1 0x13 0x0>; + pc2_l3 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l1 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l2 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + }; + + tegra-dp-vs-regs { + pc2_l0 = <0x13 0x19 0x1e 0x28 0x1e 0x25 0x2d 0x28 0x32 0x39>; + pc2_l3 = <0x11 0x14 0x17 0x1f 0x19 0x1e 0x24 0x22 0x2a 0x32>; + pc2_l1 = <0x12 0x17 0x1b 0x25 0x1c 0x23 0x2a 0x25 0x2f 0x37>; + pc2_l2 = <0x12 0x16 0x1a 0x22 0x1b 0x20 0x27 0x24 0x2d 0x35>; + }; + + tegra-dp-pc-regs { + pc2_l0 = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + pc2_l3 = <0x5 0x9 0xb 0x12 0x9 0xd 0x12 0xb 0xf 0x12>; + pc2_l1 = <0x2 0x2 0x4 0x5 0x2 0x4 0x5 0x4 0x5 0x5>; + pc2_l2 = <0x4 0x5 0x8 0xb 0x5 0x9 0xb 0x8 0xa 0xb>; + }; + + tegra-dp-tx-pu { + pc2_l0 = <0x22 0x33 0x44 0x66 0x33 0x44 0x66 0x44 0x66 0x66>; + pc2_l3 = <0x22 0x22 0x22 0x44 0x33 0x33 0x44 0x44 0x44 0x66>; + pc2_l1 = <0x22 0x22 0x33 0x55 0x33 0x44 0x55 0x44 0x55 0x66>; + pc2_l2 = <0x22 0x22 0x33 0x44 0x33 0x33 0x44 0x44 0x55 0x66>; + }; + }; + }; + }; + + dc_common { + compatible = "nvidia,tegra_dc_common"; + nvidia,disp_imp_table = <0x73>; + nvidia,valid_heads = <0x3>; + reg = <0x0 0x15200000 0x0 0x30000>; + }; + + ctx6 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c4>; + iommus = <0x11 0x3e>; + linux,phandle = <0x1c4>; + }; + + tsecb@15100000 { + compatible = "nvidia,tegra186-tsec"; + clocks = <0x10 0x89>; + resets = <0x10 0x82>; + clock-names = "tsecb"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15100000 0x0 0x40000>; + iommus = <0x11 0xb>; + }; + + se@15840000 { + compatible = "nvidia,tegra186-se4-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "sha"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15840000 0x0 0x10000>; + iommus = <0x11 0xf>; + opcode_addr = <0x104>; + }; + + nvdisplay@15220000 { + pinctrl-5 = <0x79>; + nvidia,fb-flags = <0x1>; + compatible = "nvidia,tegra186-dc"; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x3a>; + pinctrl-3 = <0x77>; + nvidia,cmu-enable = <0x1>; + vdd_hdmi_5v0-supply = <0x26>; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x5b>; + pinctrl-1 = <0x75>; + vdd-dp-pad-supply = <0x26>; + nvidia,dc-connector = <0x8c>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "plld2", "plld3", "pllp_display", "disp3_emc"; + vdd-dp-pwr-supply = <0x26>; + pinctrl-10 = <0x7e>; + pinctrl-8 = <0x7c>; + win-mask = <0x0>; + pinctrl-6 = <0x7a>; + status = "disabled"; + fb_reserved = <0x82>; + interrupts = <0x0 0x9b 0x4>; + pinctrl-4 = <0x78>; + vdd-edp-sec-mode-supply = <0x26>; + nvidia,emc-clk-rate = <0x11e1a300>; + avdd-dp-pll-supply = <0x26>; + phandle = <0x1c8>; + iommu-group-id = <0x1>; + pinctrl-2 = <0x76>; + nvidia,dc-flags = <0x1>; + reg = <0x0 0x15220000 0x0 0x10000>; + iommus = <0x11 0x9>; + pinctrl-0 = <0x74>; + iommu-direct-regions = <0x80 0x81 0x82>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head2"; + pinctrl-11 = <0x7f>; + pinctrl-9 = <0x7d>; + nvidia,dc-or-node = "/host1x/sor"; + linux,phandle = <0x1c8>; + nvidia,dc-ctrlnum = <0x2>; + pinctrl-7 = <0x7b>; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + nvidia,fb-bpp = <0x20>; + }; + + ctx4 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c2>; + iommus = <0x11 0x3c>; + linux,phandle = <0x1c2>; + }; + + sor { + nvidia,dpaux = <0x8e>; + compatible = "nvidia,tegra186-sor"; + clocks = <0x10 0x61 0x10 0x27 0x10 0x267 0x10 0x128 0x10 0x20b 0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + resets = <0x10 0x27 0x10 0xf 0x10 0x10 0x10 0x11>; + clock-names = "sor0_ref", "sor_safe", "sor0_pad_clkout", "sor0", "pll_dp", "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + status = "disabled"; + nvidia,xbar-ctrl = <0x0 0x1 0x2 0x3 0x4>; + phandle = <0x8c>; + nvidia,sor-ctrlnum = <0x0>; + reg = <0x0 0x15540000 0x0 0x40000>; + reset-names = "sor0", "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + nvidia,ddc-i2c-bus = <0x8f>; + linux,phandle = <0x8c>; + nvidia,hpd-gpio = <0x1b 0x78 0x1>; + nvidia,active-panel = <0x90>; + + prod-settings { + #prod-cells = <0x3>; + prod_list_hdmi_soc = "prod_c_hdmi_0m_54m", "prod_c_hdmi_54m_111m", "prod_c_hdmi_111m_223m", "prod_c_hdmi_223m_300m", "prod_c_hdmi_300m_600m"; + + prod_c_75M { + prod = <0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_hdmi_111m_223m { + prod = <0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hbr2 { + prod = <0x590 0xf00000 0x400000>; + }; + + prod_c_rbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_hdmi_223m_300m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_0m_54m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_600M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_300M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_54M { + prod = <0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hdmi_54m_111m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_150M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_300m_600m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_dp { + prod = <0x58c 0xf0f0f10 0x5050310 0x590 0x3000100 0x100 0x594 0xf0000000 0x0 0x598 0x2ff0 0x2440 0x59c 0x401800 0x0 0x5a0 0x400000 0x400000 0x5a8 0xff000000 0x34000000 0x70 0xffffffff 0x0 0x180 0x1 0x1>; + }; + }; + + panel-a-edp-1080p-14-0 { + compatible = "a-edp,1080p-14-0"; + nvidia,tx-pu-disable = <0x1>; + status = "disabled"; + phandle = <0x1ca>; + linux,phandle = <0x1ca>; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "okay"; + nvidia,smooth-k-incr = <0x40>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x0>; + }; + + disp-default-out { + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "pll_d_out0"; + nvidia,out-order = <0x0>; + nvidia,out-depth = <0x12>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + }; + + hdmi-display { + compatible = "hdmi,display"; + generic-infoframe-type = <0x87>; + status = "disabled"; + phandle = <0x1c9>; + linux,phandle = <0x1c9>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld3"; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x2>; + nvidia,out-type = <0x1>; + nvidia,out-yres = <0x870>; + }; + }; + + panel-s-edp-uhdtv-15-6 { + compatible = "s-edp,uhdtv-15-6"; + nvidia,tx-pu-disable = <0x1>; + status = "disabled"; + phandle = <0x11f>; + linux,phandle = <0x11f>; + nvidia,panel-bl-pwm-gpio = <0x28 0xd 0x0>; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "disabled"; + nvidia,smooth-k-incr = <0x40>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x0>; + }; + + disp-default-out { + nvidia,out-xres = <0xf00>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "pll_d_out0"; + nvidia,out-order = <0x0>; + nvidia,out-depth = <0x18>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + nvidia,out-yres = <0x870>; + nvidia,out-height = <0xc2>; + nvidia,out-width = <0x15a>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + + display-timings { + + 3840x2160-32 { + hsync-len = <0x20>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x30>; + vfront-porch = <0x3>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x5>; + vactive = <0x870>; + hback-porch = <0x50>; + clock-frequency = <0x1f1e7610>; + hactive = <0xf00>; + vback-porch = <0x36>; + }; + }; + }; + + dp-display { + compatible = "dp, display"; + nvidia,is_ext_dp_panel = <0x1>; + status = "disabled"; + phandle = <0x90>; + linux,phandle = <0x90>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld3"; + nvidia,out-order = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + nvidia,out-yres = <0x870>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + + lt-data { + + tegra-dp-pe-regs { + pc2_l0 = <0x0 0x8 0x12 0x24 0x1 0xe 0x1d 0x1 0x13 0x0>; + pc2_l3 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l1 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l2 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + }; + + tegra-dp-vs-regs { + pc2_l0 = <0x13 0x19 0x1e 0x28 0x1e 0x25 0x2d 0x28 0x32 0x39>; + pc2_l3 = <0x11 0x14 0x17 0x1f 0x19 0x1e 0x24 0x22 0x2a 0x32>; + pc2_l1 = <0x12 0x17 0x1b 0x25 0x1c 0x23 0x2a 0x25 0x2f 0x37>; + pc2_l2 = <0x12 0x16 0x1a 0x22 0x1b 0x20 0x27 0x24 0x2d 0x35>; + }; + + tegra-dp-pc-regs { + pc2_l0 = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + pc2_l3 = <0x5 0x9 0xb 0x12 0x9 0xd 0x12 0xb 0xf 0x12>; + pc2_l1 = <0x2 0x2 0x4 0x5 0x2 0x4 0x5 0x4 0x5 0x5>; + pc2_l2 = <0x4 0x5 0x8 0xb 0x5 0x9 0xb 0x8 0xa 0xb>; + }; + + tegra-dp-tx-pu { + pc2_l0 = <0x22 0x33 0x44 0x66 0x33 0x44 0x66 0x44 0x66 0x66>; + pc2_l3 = <0x22 0x22 0x22 0x44 0x33 0x33 0x44 0x44 0x44 0x66>; + pc2_l1 = <0x22 0x22 0x33 0x55 0x33 0x44 0x55 0x44 0x55 0x66>; + pc2_l2 = <0x22 0x22 0x33 0x44 0x33 0x33 0x44 0x44 0x55 0x66>; + }; + }; + }; + }; + + ctx2 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c0>; + iommus = <0x11 0x3a>; + linux,phandle = <0x1c0>; + }; + + dpaux@155c0000 { + power-domains = <0x94>; + compatible = "nvidia,tegra186-dpaux"; + clocks = <0x10 0x60>; + resets = <0x10 0x5>; + clock-names = "dpaux"; + nvidia,dpaux-ctrlnum = <0x0>; + status = "disabled"; + interrupts = <0x0 0x9f 0x4>; + phandle = <0x8e>; + reg = <0x0 0x155c0000 0x0 0x40000>; + reset-names = "dpaux"; + linux,phandle = <0x8e>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_dpaux_hdmi { + prod = <0x124 0x700 0x400>; + }; + + prod_c_dpaux_dp { + prod = <0x124 0x37fe 0x24c2>; + }; + }; + }; + + se@15810000 { + compatible = "nvidia,tegra186-se1-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "drbg"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15810000 0x0 0x10000>; + iommus = <0x11 0xc>; + opcode_addr = <0x204>; + }; + + ctx0 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1be>; + iommus = <0x11 0x38>; + linux,phandle = <0x1be>; + }; + + nvcsi@150c0000 { + num-channels = <0x1>; + power-domains = <0x1f 0xb>; + compatible = "nvidia,tegra186-nvcsi"; + clocks = <0x10 0xb4 0x10 0xb5 0x10 0x20e 0x10 0x10d>; + resets = <0x10 0x58>; + num-ports = <0x6>; + clock-names = "nvcsi", "nvcsilp", "nvcsi_parent", "nvcsilp_parent"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x77 0x4>; + #size-cells = <0x0>; + phandle = <0x128>; + iommu-group-id = <0x1>; + reg = <0x0 0x150c0000 0x0 0x40000>; + iommus = <0x11 0x2>; + nvidia,csi_regulator = "avdd_dsi_csi"; + linux,phandle = <0x128>; + + channel@4 { + status = "disabled"; + phandle = <0x156>; + reg = <0x4>; + linux,phandle = <0x156>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x159>; + reg = <0x1>; + linux,phandle = <0x159>; + + endpoint@9 { + remote-endpoint = <0x6a>; + status = "disabled"; + phandle = <0x71>; + linux,phandle = <0x71>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x157>; + reg = <0x0>; + linux,phandle = <0x157>; + + endpoint@8 { + port-index = <0x4>; + remote-endpoint = <0x69>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x38>; + linux,phandle = <0x38>; + }; + }; + }; + }; + + channel@2 { + status = "disabled"; + phandle = <0x144>; + reg = <0x2>; + linux,phandle = <0x144>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x147>; + reg = <0x1>; + linux,phandle = <0x147>; + + endpoint@5 { + remote-endpoint = <0x66>; + status = "disabled"; + phandle = <0x6f>; + linux,phandle = <0x6f>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x145>; + reg = <0x0>; + linux,phandle = <0x145>; + + endpoint@4 { + port-index = <0x2>; + remote-endpoint = <0x65>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x36>; + linux,phandle = <0x36>; + }; + }; + }; + }; + + channel@0 { + status = "okay"; + phandle = <0x129>; + reg = <0x0>; + linux,phandle = <0x129>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "okay"; + phandle = <0x12b>; + reg = <0x1>; + linux,phandle = <0x12b>; + + endpoint@1 { + remote-endpoint = <0x62>; + status = "okay"; + phandle = <0x6d>; + linux,phandle = <0x6d>; + }; + }; + + port@0 { + status = "okay"; + phandle = <0x12a>; + reg = <0x0>; + linux,phandle = <0x12a>; + + endpoint@0 { + port-index = <0x2>; + remote-endpoint = <0x134>; + status = "okay"; + bus-width = <0x2>; + phandle = <0x30>; + linux,phandle = <0x30>; + }; + }; + }; + }; + + channel@5 { + status = "disabled"; + phandle = <0x15f>; + reg = <0x5>; + linux,phandle = <0x15f>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x162>; + reg = <0x1>; + linux,phandle = <0x162>; + + endpoint@11 { + remote-endpoint = <0x6c>; + status = "disabled"; + phandle = <0x72>; + linux,phandle = <0x72>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x160>; + reg = <0x0>; + linux,phandle = <0x160>; + + endpoint@10 { + port-index = <0x5>; + remote-endpoint = <0x6b>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x39>; + linux,phandle = <0x39>; + }; + }; + }; + }; + + channel@3 { + status = "disabled"; + phandle = <0x14d>; + reg = <0x3>; + linux,phandle = <0x14d>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x150>; + reg = <0x1>; + linux,phandle = <0x150>; + + endpoint@7 { + remote-endpoint = <0x68>; + status = "disabled"; + phandle = <0x70>; + linux,phandle = <0x70>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x14e>; + reg = <0x0>; + linux,phandle = <0x14e>; + + endpoint@6 { + port-index = <0x3>; + remote-endpoint = <0x67>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x37>; + linux,phandle = <0x37>; + }; + }; + }; + }; + + channel@1 { + status = "disabled"; + phandle = <0x12c>; + reg = <0x1>; + linux,phandle = <0x12c>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x12e>; + reg = <0x1>; + linux,phandle = <0x12e>; + + endpoint@3 { + remote-endpoint = <0x64>; + status = "disabled"; + phandle = <0x6e>; + linux,phandle = <0x6e>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x12d>; + reg = <0x0>; + linux,phandle = <0x12d>; + + endpoint@2 { + port-index = <0x0>; + remote-endpoint = <0x63>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x2d>; + linux,phandle = <0x2d>; + }; + }; + }; + }; + }; + + nvjpg@15380000 { + power-domains = <0x1f 0x7>; + compatible = "nvidia,tegra186-nvjpg"; + clocks = <0x10 0x82>; + resets = <0x10 0x7f>; + clock-names = "nvjpg"; + status = "okay"; + interrupts = <0x0 0xc6 0x4>; + iommu-group-id = <0x1>; + reg = <0x0 0x15380000 0x0 0x40000>; + iommus = <0x11 0x8>; + }; + + disp_imp_table { + num_settings = <0x6>; + status = "okay"; + phandle = <0x73>; + linux,phandle = <0x73>; + + disp_imp_settings_4 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0xc5c5e20>; + nvidia,total_disp_bw_without_catchup = <0x0 0x522d80>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0xc28cb00>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0x5a6568>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_2 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0x10d69ba0>; + nvidia,total_disp_bw_without_catchup = <0x0 0x9ab000>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x13d62000>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0xaa2828>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_0 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0x1550d920>; + nvidia,total_disp_bw_without_catchup = <0x0 0xe80800>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x27ac4000>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0xff3bd8>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_5 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0xa1f3f60>; + nvidia,total_disp_bw_without_catchup = <0x0 0x2b8180>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x6146580>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0x2fdb2c>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_3 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0xe997ce0>; + nvidia,total_disp_bw_without_catchup = <0x0 0x740400>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x13d62000>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0x7f9dec>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_1 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0x1313ba60>; + nvidia,total_disp_bw_without_catchup = <0x0 0xc15c00>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x1fa97800>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0xd4b200>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + }; + + ctx7 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c5>; + iommus = <0x11 0x3f>; + linux,phandle = <0x1c5>; + }; + + nvenc@154c0000 { + power-domains = <0x1f 0x8>; + compatible = "nvidia,tegra186-nvenc"; + clocks = <0x10 0x83>; + resets = <0x10 0x7e>; + clock-names = "nvenc"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x154c0000 0x0 0x40000>; + iommus = <0x11 0x7>; + }; + + se@15820000 { + compatible = "nvidia,tegra186-se2-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "aes", "cmac"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15820000 0x0 0x10000>; + iommus = <0x11 0xd>; + opcode_addr = <0x404>; + }; + + vic@15340000 { + power-domains = <0x1f 0xc>; + compatible = "nvidia,tegra186-vic"; + clocks = <0x10 0x7f>; + resets = <0x10 0x34>; + clock-names = "vic"; + status = "okay"; + interrupts = <0x0 0xce 0x4>; + iommu-group-id = <0x1>; + reg = <0x0 0x15340000 0x0 0x40000>; + iommus = <0x11 0x3>; + }; + + ctx5 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c3>; + iommus = <0x11 0x3d>; + linux,phandle = <0x1c3>; + }; + + vi@15700000 { + num-channels = <0x1>; + power-domains = <0x1f 0xb>; + compatible = "nvidia,tegra186-vi"; + clocks = <0x10 0x33 0x10 0xb4 0x10 0xb5>; + avdd_dsi_csi-supply = <0x3c>; + resets = <0x10 0x33 0x10 0x8f>; + clock-names = "vi", "nvcsi", "nvcsilp"; + status = "okay"; + interrupts = <0x0 0xc9 0x4 0x0 0xca 0x4 0x0 0xcb 0x4>; + phandle = <0x5a>; + iommu-group-id = <0x1>; + reg = <0x0 0x15700000 0x0 0x100000>; + iommus = <0x11 0x4>; + reset-names = "vi", "tsctnvi"; + linux,phandle = <0x5a>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@5 { + status = "disabled"; + phandle = <0x15e>; + reg = <0x5>; + linux,phandle = <0x15e>; + + endpoint { + port-index = <0x5>; + remote-endpoint = <0x72>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x6c>; + vc-id = <0x0>; + linux,phandle = <0x6c>; + }; + }; + + port@3 { + status = "disabled"; + phandle = <0x14c>; + reg = <0x3>; + linux,phandle = <0x14c>; + + endpoint { + port-index = <0x3>; + remote-endpoint = <0x70>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x68>; + vc-id = <0x0>; + linux,phandle = <0x68>; + }; + }; + + port@1 { + status = "disabled"; + phandle = <0x127>; + reg = <0x1>; + linux,phandle = <0x127>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x6e>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x64>; + vc-id = <0x0>; + linux,phandle = <0x64>; + }; + }; + + port@4 { + status = "disabled"; + phandle = <0x155>; + reg = <0x4>; + linux,phandle = <0x155>; + + endpoint { + port-index = <0x4>; + remote-endpoint = <0x71>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x6a>; + vc-id = <0x0>; + linux,phandle = <0x6a>; + }; + }; + + port@2 { + status = "disabled"; + phandle = <0x143>; + reg = <0x2>; + linux,phandle = <0x143>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x6f>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x66>; + vc-id = <0x0>; + linux,phandle = <0x66>; + }; + }; + + port@0 { + status = "okay"; + phandle = <0x126>; + reg = <0x0>; + linux,phandle = <0x126>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + phandle = <0x62>; + vc-id = <0x0>; + linux,phandle = <0x62>; + }; + }; + }; + }; + + nvdisplay@15200000 { + pinctrl-5 = <0x79>; + nvidia,fb-flags = <0x1>; + compatible = "nvidia,tegra186-dc"; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x206 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x10b 0x10 0x3a>; + pinctrl-3 = <0x77>; + nvidia,cmu-enable = <0x1>; + avdd_dsi_csi-supply = <0x3c>; + vdd_hdmi_5v0-supply = <0x8a>; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x59>; + outn-supply = <0x87>; + vdd_lcd_bl-supply = <0x26>; + pinctrl-1 = <0x75>; + nvidia,dc-connector = <0x83>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "pll_d", "plld2", "plld3", "pllp_display", "pll_d_out1", "disp1_emc"; + pinctrl-10 = <0x7e>; + pinctrl-8 = <0x7c>; + outp-supply = <0x86>; + win-mask = <0x7>; + avdd_hdmi-supply = <0x89>; + pinctrl-6 = <0x7a>; + status = "disabled"; + fb_reserved = <0x80>; + interrupts = <0x0 0x99 0x4>; + pinctrl-4 = <0x78>; + phandle = <0x1c6>; + iommu-group-id = <0x1>; + avdd_hdmi_pll-supply = <0x12>; + pinctrl-2 = <0x76>; + dvdd_lcd-supply = <0x85>; + nvidia,dc-flags = <0x1>; + reg = <0x0 0x15200000 0x0 0x10000>; + iommus = <0x11 0x9>; + pinctrl-0 = <0x74>; + iommu-direct-regions = <0x80 0x81 0x82>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head0"; + pinctrl-11 = <0x7f>; + nvidia,fb-win = <0x0>; + pinctrl-9 = <0x7d>; + nvidia,emc-rate = <0x11e1a300>; + nvidia,dc-or-node = "/host1x/dsi"; + linux,phandle = <0x1c6>; + nvidia,dc-ctrlnum = <0x0>; + vdd_lcd_bl_en-supply = <0x88>; + pinctrl-7 = <0x7b>; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + nvidia,fb-bpp = <0x20>; + avdd_lcd-supply = <0x84>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + status = "okay"; + interrupts = <0x1 0xd 0x3f08 0x1 0xe 0x3f08 0x1 0xb 0x3f08 0x1 0xa 0x3f08>; + }; + + i2c@31b0000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x7d 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x18>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1e 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x8f>; + reg = <0x0 0x31b0000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x186a0>; + dmas = <0x25 0x1e 0x25 0x1e>; + reset-names = "i2c"; + linux,phandle = <0x8f>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + axi2apb@23d0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23d0000 0x0 0x1000>; + }; + + gpio@2200000 { + compatible = "nvidia,tegra186-gpio"; + reg-names = "security", "gpio"; + gpio-controller; + gpio-ranges = <0xb7 0x0 0x0 0x90 0xb7 0x90 0x98 0x8 0xb7 0x98 0xb8 0x10 0xb7 0xa8 0xd8 0x18>; + status = "okay"; + #interrupt-cells = <0x2>; + interrupts = <0x0 0x2f 0x4 0x0 0x32 0x4 0x0 0x35 0x4 0x0 0x38 0x4 0x0 0x3b 0x4 0x0 0xb4 0x4>; + phandle = <0x1b>; + reg = <0x0 0x2200000 0x0 0x10000 0x0 0x2210000 0x0 0x10000>; + #gpio-cells = <0x2>; + linux,phandle = <0x1b>; + interrupt-controller; + + camera-control-output-high { + gpios = <0x8d 0x0>; + gpio-hog; + status = "disabled"; + label = "cam0-rst"; + output-high; + }; + + wifi_over_pcie { + gpios = <0x8c 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "wifi-over-pcie"; + }; + + sdmmc-wake-support-input { + gpios = <0x7d 0x0>; + gpio-hog; + status = "okay"; + label = "sdmmc-wake-input"; + input; + }; + + wifi-wake-ap { + gpio-hog; + status = "disabled"; + label = "wifi-wake-ap"; + input; + }; + + e3325_sdio_rst { + gpios = <0xe 0x0>; + gpio-hog; + status = "disabled"; + label = "e3325-sdio-rst"; + output-high; + }; + + wifi-enable { + gpios = <0x68 0x0>; + gpio-hog; + line-name = "wifi-enable"; + output-high; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x6a 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + + e3325_lane0_mux { + gpios = <0xc 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "e3325-lane0-mux"; + }; + + pcie0_lane2_mux { + gpios = <0x8b 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "pcie-lane2-mux"; + }; + + sdmmc-wake-support-output { + gpios = <0x7e 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "sdmmc-wake-output"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + + axip2p@2150000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2150000 0x0 0x1000>; + }; + + sce-ivc-channels { + phandle = <0x57>; + linux,phandle = <0x57>; + + ivccontrol@52c0 { + nvidia,frame-size = <0x140>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture-control"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture-control"; + }; + + ivccapture@72c0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture"; + }; + + dbg@7c00 { + nvidia,frame-size = <0x180>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-dbg"; + nvidia,service = "debug"; + }; + + echo@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-echo"; + nvidia,service = "echo"; + }; + + dbg@7e00 { + nvidia,frame-size = <0x2000>; + compatible = "nvidia,tegra186-camera-ivc-protocol-debug"; + nvidia,ivc-timeout = <0x32>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,test-timeout = <0x1388>; + nvidia,service = "debug"; + }; + + mods@32c0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-camera-ivc-protocol-mods"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,service = "mods"; + }; + + i2c@480 { + nvidia,frame-size = <0x80>; + compatible = "nvidia,tegra186-camera-ivc-rpc-i2c-single"; + device = <0x59>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x8>; + status = "okay"; + nvidia,version = <0x0>; + nvidia,service = "i2c-single"; + }; + + vinotify@12c0 { + nvidia,frame-size = <0x80>; + compatible = "nvidia,tegra186-camera-ivc-protocol-vinotify"; + device = <0x5a>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x40>; + nvidia,version = <0x0>; + nvidia,service = "vinotify"; + }; + }; + + serial@3130000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0x4d 0x10 0x10d>; + resets = <0x10 0x32>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "NILL"; + interrupts = <0x0 0x73 0x4>; + dma-names = "tx"; + phandle = <0x18f>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3130000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x13 0x25 0x13>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x18f>; + }; + + axip2p@2190000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2190000 0x0 0x1000>; + }; + + se_elp@3ad0000 { + compatible = "nvidia,tegra186-se-elp"; + clocks = <0x10 0x67>; + clock-names = "se"; + status = "okay"; + interrupts = <0x0 0x11b 0x4>; + phandle = <0x1d4>; + reg = <0x0 0x3ad0000 0x0 0x10000 0x0 0x3ae0000 0x0 0x10000>; + linux,phandle = <0x1d4>; + pka1-rsa-priority = <0x12c>; + }; + + gpio@c2f0000 { + compatible = "nvidia,tegra186-gpio-aon"; + reg-names = "security", "gpio"; + gpio-controller; + gpio-ranges = <0xb7 0x0 0x90 0x8 0xb7 0x8 0xa0 0x18 0xb7 0x20 0xc8 0x10 0xb7 0x30 0xf0 0x10>; + status = "okay"; + #interrupt-cells = <0x2>; + interrupts = <0x0 0x3c 0x4>; + phandle = <0x28>; + reg = <0x0 0xc2f0000 0x0 0x1000 0x0 0xc2f1000 0x0 0x1000>; + #gpio-cells = <0x2>; + linux,phandle = <0x28>; + interrupt-controller; + + camera-control-output-high { + status = "disabled"; + }; + + wifi-wake-ap { + gpios = <0x3b 0x0>; + gpio-hog; + label = "wifi-wake-ap"; + input; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + + mttcan0-ivc { + compatible = "bosch,mttcan-ivc"; + status = "disabled"; + mboxes = <0x41 0x3>; + }; + + i2c@3180000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x4b 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x15>; + scl-gpio = <0x1b 0x72 0x0>; + sda-gpio = <0x1b 0x73 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1b 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x59>; + reg = <0x0 0x3180000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x17 0x25 0x17>; + reset-names = "i2c"; + linux,phandle = <0x59>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + tca9548@77 { + force_bus_start = <0x1e>; + compatible = "nxp,pca9548"; + skip_mux_detect; + status = "disabled"; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2b>; + phandle = <0x13b>; + reg = <0x77>; + linux,phandle = <0x13b>; + + i2c@0 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0>; + + imx219_a@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x59>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1"; + dovdd-supply = <0x2b>; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x0 0x0>; + phandle = <0x163>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x163>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x164>; + linux,phandle = <0x164>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_a@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x13c>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x88 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x13c>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x13d>; + linux,phandle = <0x13d>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + i2c@5 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x5>; + + imx219_f@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x5a>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video5"; + avdd-reg = "vana"; + clock-names = "extperiph2"; + dovdd-supply = <0x2b>; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x5 0x0>; + phandle = <0x16a>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x16a>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x5>; + remote-endpoint = <0x39>; + bus-width = <0x2>; + phandle = <0x6b>; + linux,phandle = <0x6b>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_f@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video5"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x7 0x0>; + phandle = <0x15a>; + reg = <0x36>; + pwdn-gpios = <0x35 0x6 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x15a>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x5>; + remote-endpoint = <0x39>; + bus-width = <0x2>; + phandle = <0x161>; + linux,phandle = <0x161>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + i2c@3 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x3>; + + imx219_d@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x5a>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video3"; + avdd-reg = "vana"; + clock-names = "extperiph2"; + dovdd-supply = <0x2b>; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x3 0x0>; + phandle = <0x168>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x168>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x3>; + remote-endpoint = <0x37>; + bus-width = <0x2>; + phandle = <0x67>; + linux,phandle = <0x67>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_d@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video3"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x3 0x0>; + phandle = <0x148>; + reg = <0x36>; + pwdn-gpios = <0x35 0x2 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x148>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x3>; + remote-endpoint = <0x37>; + bus-width = <0x2>; + phandle = <0x14f>; + linux,phandle = <0x14f>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + i2c@1 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x1>; + + ov5693_b@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x89 0x0>; + phandle = <0x13a>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x6a 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x13a>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x1>; + remote-endpoint = <0x2d>; + bus-width = <0x2>; + phandle = <0x13e>; + linux,phandle = <0x13e>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + + imx219_b@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x59>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph1"; + dovdd-supply = <0x2b>; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x1 0x0>; + phandle = <0x165>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x165>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x1>; + remote-endpoint = <0x2d>; + bus-width = <0x2>; + phandle = <0x166>; + linux,phandle = <0x166>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + }; + + i2c@4 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x4>; + + ov5693_e@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video4"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x5 0x0>; + phandle = <0x151>; + reg = <0x36>; + pwdn-gpios = <0x35 0x4 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x151>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x4>; + remote-endpoint = <0x38>; + bus-width = <0x2>; + phandle = <0x158>; + linux,phandle = <0x158>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + + imx219_e@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x5a>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video4"; + avdd-reg = "vana"; + clock-names = "extperiph2"; + dovdd-supply = <0x2b>; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x4 0x0>; + phandle = <0x169>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x169>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x4>; + remote-endpoint = <0x38>; + bus-width = <0x2>; + phandle = <0x69>; + linux,phandle = <0x69>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + }; + + i2c@2 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x2>; + + imx219_c@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x59>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video2"; + avdd-reg = "vana"; + clock-names = "extperiph1"; + dovdd-supply = <0x2b>; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x2 0x0>; + phandle = <0x167>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x167>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x36>; + bus-width = <0x2>; + phandle = <0x65>; + linux,phandle = <0x65>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_c@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video2"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x1 0x0>; + phandle = <0x13f>; + reg = <0x36>; + pwdn-gpios = <0x35 0x0 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x13f>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x36>; + bus-width = <0x2>; + phandle = <0x146>; + linux,phandle = <0x146>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + }; + + ov23850_a@10 { + compatible = "nvidia,ov23850"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "7.3998"; + iovdd-reg = "vif"; + vcmvdd-reg = "vvcm"; + vdig-supply = <0x2a>; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x135>; + reg = <0x10>; + pwdn-gpios = <0x1b 0x88 0x0>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x135>; + vif-supply = <0x2b>; + physical_h = "5.5998"; + vvcm-suply = <0x2c>; + + mode0 { + line_length = "5922"; + active_w = "5632"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "600000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "15.5"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = "270"; + min_gain_val = "1.0"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + csi_pixel_bit_depth = "10"; + min_framerate = "3.09135"; + max_framerate = "30"; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + active_h = "3168"; + max_exp_time = "323094"; + mclk_multiplier = "25"; + min_exp_time = "19.74"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x4>; + phandle = <0x138>; + linux,phandle = <0x138>; + }; + }; + }; + }; + + tca6408@21 { + compatible = "ti,tca6408"; + gpio-controller; + status = "disabled"; + vcc-supply = <0x2b>; + phandle = <0x35>; + reg = <0x21>; + #gpio-cells = <0x2>; + linux,phandle = <0x35>; + + tca6408_21_input { + gpios = <0x6 0x0 0x7 0x0>; + gpio-hog; + status = "disabled"; + label = "tca6408_21_input_6", "tca6408_21_input_7"; + input; + }; + + tca6408_21_outlow { + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0>; + output-low; + gpio-hog; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + + tca9546@70 { + force_bus_start = <0x1e>; + compatible = "nxp,pca9546"; + vcc_lp = "vcc"; + skip_mux_detect = "yes"; + status = "disabled"; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2b>; + phandle = <0x130>; + reg = <0x70>; + linux,phandle = <0x130>; + vif-supply = <0x2b>; + + i2c@0 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0>; + + imx390_a@1b { + post_crop_frame_drop = [30 00]; + compatible = "nvidia,imx390"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx390"; + physical_w = "15.0"; + use_decibel_gain = "true"; + clock-names = "extperiph1", "pllp_grtba"; + def-addr = <0x1a>; + nvidia,gmsl-dser-device = <0x32>; + mclk = "extperiph1"; + nvidia,gmsl-ser-device = <0x31>; + status = "disabled"; + use_sensor_mode_id = "true"; + phandle = <0x120>; + reg = <0x1b>; + linux,phandle = <0x120>; + physical_h = "12.5"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2200"; + active_w = "1920"; + embedded_metadata_height = [30 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "300"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "30000000"; + default_exp_time = "33333"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + mclk_khz = "24000"; + vc_id = [30 00]; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + serdes_pix_clk_hz = "833333333"; + max_exp_time = "33333"; + min_exp_time = "59"; + }; + + gmsl-link { + streams = "ued-u1", "raw12"; + csi-mode = "1x4"; + num-lanes = <0x2>; + st-vc = <0x0>; + src-csi-port = [62 00]; + serdes-csi-link = [61 00]; + vc-id = <0x0>; + dst-csi-port = [61 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x61>; + vc-id = <0x0>; + linux,phandle = <0x61>; + }; + }; + }; + }; + + max9295_b@60 { + compatible = "nvidia,max9295"; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + phandle = <0x33>; + reg = <0x60>; + linux,phandle = <0x33>; + }; + + imx390_b@1c { + post_crop_frame_drop = [30 00]; + compatible = "nvidia,imx390"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx390"; + physical_w = "15.0"; + use_decibel_gain = "true"; + clock-names = "extperiph1", "pllp_grtba"; + def-addr = <0x1a>; + nvidia,gmsl-dser-device = <0x32>; + mclk = "extperiph1"; + nvidia,gmsl-ser-device = <0x33>; + status = "disabled"; + use_sensor_mode_id = "true"; + phandle = <0x123>; + reg = <0x1c>; + linux,phandle = <0x123>; + physical_h = "12.5"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "4400"; + active_w = "1920"; + embedded_metadata_height = [30 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "300"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "30000000"; + default_exp_time = "33333"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + mclk_khz = "24000"; + vc_id = [31 00]; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + serdes_pix_clk_hz = "833333333"; + max_exp_time = "33333"; + min_exp_time = "59"; + }; + + gmsl-link { + streams = "ued-u1", "raw12"; + csi-mode = "1x4"; + num-lanes = <0x2>; + st-vc = <0x0>; + src-csi-port = [62 00]; + serdes-csi-link = [62 00]; + vc-id = <0x1>; + dst-csi-port = [61 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x2d>; + bus-width = <0x2>; + phandle = <0x63>; + vc-id = <0x1>; + linux,phandle = <0x63>; + }; + }; + }; + }; + + imx318_a@10 { + compatible = "nvidia,imx318"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx318"; + has-eeprom; + physical_w = "6.811"; + iovdd-reg = "vif"; + vdig-supply = <0x2a>; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x172>; + reg = <0x10>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x172>; + vif-supply = <0x2b>; + physical_h = "5.254"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "5488"; + active_w = "5488"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "750000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [33 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "CPHY"; + mclk_khz = "24000"; + cil_settletime = "20"; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "4112"; + max_exp_time = "550385"; + mclk_multiplier = "31.25"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x3>; + phandle = <0x173>; + linux,phandle = <0x173>; + }; + }; + }; + }; + + imx274_a@1a { + compatible = "nvidia,imx274"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx274"; + has-eeprom; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + delayed_gain = "true"; + reset-gpios = <0x1b 0x8d 0x0>; + fuse_id_start_addr = <0x5b>; + phandle = <0x16e>; + reg = <0x1a>; + vana-supply = <0x29>; + linux,phandle = <0x16e>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3840"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "44400000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "2160"; + max_exp_time = "478696"; + mclk_multiplier = "24"; + min_exp_time = "44"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x4>; + phandle = <0x16f>; + linux,phandle = <0x16f>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1936"; + num_of_left_margin_pixels = [36 00]; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "38"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "15649"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [36 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "2264"; + max_exp_time = "15649"; + mclk_multiplier = "24"; + min_exp_time = "859"; + }; + + mode1 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "184611"; + mclk_multiplier = "24"; + min_exp_time = "58"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3856"; + num_of_left_margin_pixels = "12"; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "50"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "30000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "20480"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [30 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "4448"; + max_exp_time = "20480"; + mclk_multiplier = "24"; + min_exp_time = "864"; + }; + }; + + max9296@48 { + compatible = "nvidia,max9296"; + csi-mode = "2x4"; + vdd_cam_1v2-supply = <0x34>; + max-src = <0x2>; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x32>; + reg = <0x48>; + linux,phandle = <0x32>; + }; + + max9295_prim@62 { + compatible = "nvidia,max9295"; + is-prim-ser; + status = "disabled"; + phandle = <0x131>; + reg = <0x62>; + linux,phandle = <0x131>; + }; + + max9295_a@40 { + compatible = "nvidia,max9295"; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + phandle = <0x31>; + reg = <0x40>; + linux,phandle = <0x31>; + }; + + pca9570_a@24 { + compatible = "nvidia,pca9570"; + channel = [61 00]; + drive_ic = "DRV8838"; + status = "disabled"; + phandle = <0x16d>; + reg = <0x24>; + linux,phandle = <0x16d>; + }; + + imx185_a@1a { + post_crop_frame_drop = [30 00]; + compatible = "nvidia,imx185"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx185"; + physical_w = "15.0"; + use_decibel_gain = "true"; + devnode = "video0"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + delayed_gain = "true"; + reset-gpios = <0x1b 0x8d 0x0>; + use_sensor_mode_id = "true"; + phandle = <0x16b>; + reg = <0x1a>; + linux,phandle = <0x16b>; + physical_h = "12.5"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2200"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = [32 00]; + min_exp_time = "30"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x4>; + phandle = <0x16c>; + linux,phandle = <0x16c>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "2640"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "178200000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = "4.8"; + min_exp_time = "30"; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2640"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "89100000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = "2.4"; + min_exp_time = "30"; + }; + + mode4 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2200"; + control_point_y_0 = [30 00]; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "16"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_pwl"; + control_point_x_2 = "16384"; + num_lanes = [34 00]; + control_point_x_0 = [30 00]; + inherent_gain = [31 00]; + max_gain_val = "120"; + control_point_y_3 = "3712"; + min_hdr_ratio = "16"; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = "16"; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + control_point_y_1 = "2048"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + control_point_x_3 = "65536"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + control_point_x_1 = "2048"; + num_control_point = [34 00]; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = [32 00]; + control_point_y_2 = "2944"; + min_exp_time = "2433"; + }; + + mode2 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "2200"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "148500000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = [34 00]; + min_exp_time = "30"; + }; + }; + }; + + i2c@1 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x1>; + + imx274_c@1a { + compatible = "nvidia,imx274"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx274"; + has-eeprom; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + delayed_gain = "true"; + reset-gpios = <0x1b 0x88 0x0>; + fuse_id_start_addr = <0x63>; + phandle = <0x170>; + reg = <0x1a>; + vana-supply = <0x29>; + linux,phandle = <0x170>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3840"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "44400000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "2160"; + max_exp_time = "478696"; + mclk_multiplier = "24"; + min_exp_time = "44"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x2d>; + bus-width = <0x4>; + phandle = <0x171>; + linux,phandle = <0x171>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1936"; + num_of_left_margin_pixels = [36 00]; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "38"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "15649"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [36 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "2264"; + max_exp_time = "15649"; + mclk_multiplier = "24"; + min_exp_time = "859"; + }; + + mode1 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "184611"; + mclk_multiplier = "24"; + min_exp_time = "58"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3856"; + num_of_left_margin_pixels = "12"; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "50"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "30000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "20480"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [30 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "4448"; + max_exp_time = "20480"; + mclk_multiplier = "24"; + min_exp_time = "864"; + }; + }; + }; + }; + + ov5693_c@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "okay"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x132>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x88 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + vertical-flip = "true"; + linux,phandle = <0x132>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x134>; + linux,phandle = <0x134>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + thermal-fan-est { + compatible = "thermal-fan-est"; + active_hysteresis = <0x0 0x3a98 0x2328 0x2328 0x2710 0x0 0x0 0x0 0x0 0x0>; + num_resources = <0x0>; + shared_data = <0xef>; + active_trip_temps = <0x0 0xc738 0xee48 0x11558 0x14050 0x222e0 0x249f0 0x27100 0x29810 0x2bf20>; + trip_length = <0xa>; + }; + + smmu_test { + compatible = "nvidia,smmu_test"; + phandle = <0x1cd>; + iommus = <0x11 0x33>; + linux,phandle = <0x1cd>; + }; + + efuse@3820000 { + compatible = "nvidia,tegra186-efuse", "nvidia,tegra210-efuse"; + clocks = <0x10 0x0>; + clock-names = "fuse"; + status = "okay"; + reg = <0x0 0x3820000 0x0 0x600>; + nvidia,clock-always-on; + + efuse-burn { + compatible = "nvidia,tegra186-efuse-burn"; + clocks = <0x10 0x261>; + clock-names = "clk_m"; + nvidia,tz = <0xe7>; + status = "okay"; + nvidia,temp-range = <0xfa0 0x18a88>; + }; + }; + + sound { + assigned-clock-parents = <0x10 0x10f 0x10 0xf6>; + compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x"; + clocks = <0x10 0x10f 0x10 0xf6 0x10 0x7c>; + resets = <0x10 0x92>; + nvidia,num-codec-link = <0xc>; + dma-mask = <0x0 0x5e000000>; + nvidia,model = "tegra-snd-t186ref-mobile-rt565x"; + clock-names = "pll_a", "pll_a_out0", "extern1"; + nvidia,xbar = <0xb8>; + status = "okay"; + assigned-clocks = <0x10 0xf6 0x10 0x7c>; + phandle = <0x114>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + nvidia,audio-routing = "x Headphone", "x OUT", "x IN", "x Mic", "y Headphone", "y OUT", "y IN", "y Mic", "z Headphone", "z OUT", "z IN", "z Mic", "m Headphone", "m OUT", "m IN", "m Mic", "n Headphone", "n OUT", "n IN", "n Mic", "o Headphone", "o OUT", "o IN", "o Mic", "a IN", "a Mic", "b IN", "b Mic", "c IN", "c Mic", "d IN", "d Mic", "d1 Headphone", "d1 OUT", "d3 Headphone", "d3 OUT"; + mclk-fs = <0x100>; + iommus = <0x11 0x1e>; + reset-names = "extern1_rst"; + linux,phandle = <0x114>; + + nvidia,dai-link-8 { + cpu-dai-name = "DMIC2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc8>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [62 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc7>; + format = "i2s"; + link-name = "spdif-dit-8"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-6 { + cpu-dai-name = "I2S6"; + ignore_suspend; + num-channel = <0x1>; + codec-dai = <0xc4>; + srate = <0x1f40>; + tx-mask = <0xff>; + status = "okay"; + name-prefix = [6f 00]; + bitclock-inversion; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc3>; + rx-mask = <0xff>; + format = "dsp_a"; + link-name = "spdif-dit-6"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-13 { + cpu-dai-name = "DSPK2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xd1>; + srate = <0xbb80>; + status = "okay"; + name-prefix = "d2"; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcf>; + phandle = <0x118>; + format = "i2s"; + linux,phandle = <0x118>; + link-name = "dspk-playback-r"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-4 { + cpu-dai-name = "I2S4"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc0>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [6d 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xbf>; + format = "i2s"; + link-name = "spdif-dit-3"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-11 { + cpu-dai-name = "DSPK1"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xce>; + srate = <0xbb80>; + status = "okay"; + name-prefix = "d3"; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcd>; + format = "i2s"; + link-name = "dspk1-playback"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-2 { + cpu-dai-name = "I2S2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xbc>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [79 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xbb>; + format = "i2s"; + link-name = "spdif-dit-1"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-9 { + cpu-dai-name = "DMIC3"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xca>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [63 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc9>; + format = "i2s"; + link-name = "spdif-dit-9"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-7 { + cpu-dai-name = "DMIC1"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc6>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [61 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc5>; + format = "i2s"; + link-name = "spdif-dit-7"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-5 { + cpu-dai-name = "I2S5"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc2>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [6e 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc1>; + format = "i2s"; + link-name = "spdif-dit-4"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-12 { + cpu-dai-name = "DSPK2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xd0>; + srate = <0xbb80>; + status = "okay"; + name-prefix = "d1"; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcf>; + phandle = <0x116>; + format = "i2s"; + linux,phandle = <0x116>; + link-name = "dspk-playback-l"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-3 { + cpu-dai-name = "I2S3"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xbe>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [7a 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xbd>; + format = "i2s"; + link-name = "spdif-dit-2"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-10 { + cpu-dai-name = "DMIC4"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xcc>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [64 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcb>; + format = "i2s"; + link-name = "spdif-dit-10"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-1 { + cpu-dai-name = "I2S1"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xba>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [78 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xb9>; + phandle = <0x115>; + format = "i2s"; + linux,phandle = <0x115>; + link-name = "spdif-dit-0"; + bit-format = "s16_le"; + }; + }; + + interrupt-controller@3000000 { + compatible = "nvidia,tegra-gic"; + status = "disabled"; + phandle = <0x1d3>; + reg = <0x0 0x3000000 0x0 0x800 0x0 0x3000800 0x0 0x800 0x0 0x3001000 0x0 0x800 0x0 0x3001800 0x0 0x800 0x0 0x3002000 0x0 0x800 0x0 0x3002800 0x0 0x800 0x0 0x3003000 0x0 0x800 0x0 0x3003800 0x0 0x800 0x0 0x300f800 0x0 0x800>; + linux,phandle = <0x1d3>; + interrupt-controller; + }; + + tegra-virtual-camera-platform { + isp_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + + modules { + + module0 { + badge = "vivid_front_instance0"; + position = "front"; + orientation = [31 00]; + + drivernode0 { + devname = "tegra-vivid-000"; + pcl_id = "v4l2_sensor_virtual"; + proc-device-tree = "/proc/device-tree/vivid-driver/instances/instance0"; + }; + }; + }; + }; + + mc { + compatible = "nvidia,tegra-t18x-mc"; + ecc_int_mask = <0x1c00>; + int_mask = <0xf3140>; + status = "okay"; + interrupts = <0x0 0xdf 0x4 0x0 0xe0 0x4>; + reg-ranges = <0x1>; + reg = <0x0 0x2c10000 0x0 0x10000 0x0 0x2c20000 0x0 0x10000 0x0 0x2c30000 0x0 0x10000 0x0 0x2c40000 0x0 0x10000 0x0 0x2c50000 0x0 0x10000 0x0 0x2c60000 0x0 0x10000 0x0 0x2c70000 0x0 0x10000 0x0 0x2c80000 0x0 0x10000 0x0 0x2c90000 0x0 0x10000 0x0 0x2ca0000 0x0 0x10000>; + channels = <0x4>; + }; + + serial@c290000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xd8 0x10 0x10d>; + resets = <0x10 0x70>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "disabled"; + interrupts = <0x0 0x76 0x4>; + dma-names = "rx", "tx"; + phandle = <0x192>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0xc290000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x2 0x25 0x2>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x192>; + }; + + // virtio_blk2@f0a002000 { + // compatible = "virtio,mmio"; + // dma-coherent; + // interrupts = <0x0 0x10e 0x1>; + // reg = <0xf 0xa002000 0x0 0x400>; + // }; + + dummy-cool-dev { + compatible = "dummy-cooling-dev"; + status = "disabled"; + phandle = <0x1e4>; + #cooling-cells = <0x2>; + linux,phandle = <0x1e4>; + }; + + tachometer@39c0000 { + pulse-per-rev = <0x2>; + compatible = "nvidia,pwm-tegra186-tachometer"; + clocks = <0x10 0xa6>; + resets = <0x10 0x6d>; + clock-names = "tach"; + capture-window-length = <0x8>; + status = "okay"; + phandle = <0xb2>; + reg = <0x0 0x39c0000 0x0 0x10>; + reset-names = "tach"; + linux,phandle = <0xb2>; + #pwm-cells = <0x2>; + }; + + etr@8050000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8050000 0x0 0x1000>; + + port { + + endpoint@0 { + remote-endpoint = <0xe4>; + phandle = <0xde>; + slave-mode; + linux,phandle = <0xde>; + }; + }; + }; + + clock@5000000 { + compatible = "nvidia,tegra18x-car"; + #reset-cells = <0x1>; + status = "okay"; + #clock-cells = <0x1>; + phandle = <0x10>; + reg = <0x0 0x5000000 0x0 0x1000000>; + linux,phandle = <0x10>; + }; + + trusty { + compatible = "android,trusty-smc-v1"; + ranges; + status = "NILL"; + #address-cells = <0x2>; + #size-cells = <0x2>; + + fiq { + compatible = "android,trusty-fiq-v1"; + }; + + log { + compatible = "android,trusty-log-v1"; + }; + + irq { + interrupt-ranges = <0x0 0xf 0x0 0x10 0x1f 0x1 0x20 0x1ae 0x2>; + compatible = "android,trusty-irq-v1"; + interrupt-templates = <0x46 0x0 0x1 0x1 0x1 0x0 0x1 0x1 0x0 0x0>; + }; + + virtio { + compatible = "android,trusty-virtio-v1"; + }; + + ote { + compatible = "android,trusty-ote-v1"; + }; + }; + + tegra-hsp@b150000 { + compatible = "nvidia,tegra186-hsp"; + resets = <0x10 0xba>; + status = "okay"; + interrupts = <0x0 0x8d 0x4 0x0 0x8e 0x4 0x0 0x8f 0x4 0x0 0x90 0x4>; + phandle = <0x58>; + reg = <0x0 0xb150000 0x0 0x90000>; + reset-names = "hsp"; + linux,phandle = <0x58>; + interrupt-names = "shared1", "shared2", "shared3", "shared4"; + }; + + funnel_minor@8820000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8820000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@2 { + reg = <0x2>; + + endpoint { + remote-endpoint = <0xe6>; + phandle = <0xd4>; + slave-mode; + linux,phandle = <0xd4>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe5>; + phandle = <0xdc>; + linux,phandle = <0xdc>; + }; + }; + }; + }; + + rtcpu@b000000 { + nvidia,nb-channels = <0x2>; + compatible = "nvidia,tegra186-sce-ivc"; + clocks = <0x10 0xe6 0x10 0xe4>; + resets = <0x10 0xbb 0x10 0xb8 0x10 0xb5 0x10 0xb6 0x10 0xb7 0x10 0xb9 0x10 0xbc 0x10 0xbd 0x10 0xbe 0x10 0xb4 0x10 0xb3>; + nvidia,clock-rates = <0x6146580 0x6146580 0x6ddd000 0x1c3a9000>; + reg-names = "sce-evp", "sce-pm", "sce-cfg", "ast-cpu", "ast-dma"; + nvidia,autosuspend-delay-ms = <0x1388>; + nvidia,memory-bw = <0xffffffff>; + clock-names = "sce-apb", "sce-cpu-nic"; + nvidia,reset-group-2 = "sce-nreset", "sce-nsysporeset"; + nvidia,ch-base = <0x3c>; + status = "okay"; + interrupts = <0x0 0x10 0x4>; + nvidia,nb-pts = <0x4>; + nvidia,trace = <0x56 0x4 0x70100000 0x100000>; + nvidia,ivc-channels = <0x57 0x2 0x90000000 0x10000>; + phandle = <0x19c>; + nvidia,pts-base = <0x23c>; + iommu-resv-regions = <0x0 0x0 0x0 0xa0000000 0x0 0xc0000000 0xffffffff 0xffffffff>; + reg = <0x0 0xb000000 0x0 0x1000 0x0 0xb1f0000 0x0 0x40000 0x0 0xb230000 0x0 0x10000 0x0 0xb040000 0x0 0x10000 0x0 0xb050000 0x0 0x10000>; + iommus = <0x11 0x2a>; + reset-names = "tsctnsce", "sce-pm", "sce-dbgresetn", "sce-presetdbgn", "sce-actmon", "sce-dma", "sce-tke", "sce-gte", "sce-cfg", "sce-nreset", "sce-nsysporeset"; + linux,phandle = <0x19c>; + interrupt-names = "wdt-remote"; + nvidia,reset-group-1 = "tsctnsce", "sce-pm", "sce-dbgresetn", "sce-presetdbgn", "sce-actmon", "sce-dma", "sce-tke", "sce-gte", "sce-cfg"; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + nvidia,hsp-shared-mailbox = <0x58 0x1 0x58 0x6>; + }; + }; + + tegra-firmwares { + osl = "unavailable"; + mb1-bct = "unavailable"; + mb2 = "unavailable"; + status = "okay"; + qb = "unavailable"; + mb1 = "unavailable"; + }; + + nvdumper { + compatible = "nvidia,tegra186-nvdumper"; + status = "disabled"; + }; + + dma_test { + compatible = "nvidia,dma_test"; + phandle = <0x1ce>; + linux,phandle = <0x1ce>; + }; + + ape-ivc-channels { + phandle = <0x5d>; + linux,phandle = <0x5d>; + + ivccontrol@52c0 { + nvidia,frame-size = <0x140>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture-control"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture-control"; + }; + + ivccapture@72c0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture"; + }; + + dbg@7c00 { + nvidia,frame-size = <0x180>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-dbg"; + nvidia,service = "debug"; + }; + + echo@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-echo"; + nvidia,service = "echo"; + }; + + dbg@7e00 { + nvidia,frame-size = <0x2000>; + compatible = "nvidia,tegra186-camera-ivc-protocol-debug"; + nvidia,ivc-timeout = <0x32>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,test-timeout = <0x1388>; + nvidia,service = "debug"; + }; + + vinotify@12c0 { + nvidia,frame-size = <0x80>; + compatible = "nvidia,tegra186-camera-ivc-protocol-vinotify"; + device = <0x5a>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x40>; + nvidia,version = <0x0>; + nvidia,service = "vinotify"; + }; + }; + + spi@c260000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0xde 0x10 0x10d 0x10 0x264>; + resets = <0x10 0x29>; + clock-names = "spi", "pll_p", "osc"; + nvidia,clk-parents = "pll_p", "osc"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x25 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x183>; + reg = <0x0 0xc260000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x10 0x25 0x10>; + reset-names = "spi"; + linux,phandle = <0x183>; + spi-max-frequency = <0xb71b00>; + + prod-settings { + + prod_c_cs0 { + prod = <0x4 0xfc0 0x400>; + }; + }; + + spi-touch-sharp19x12@0 { + x-max = <0x2580>; + reset-gpio = <0x28 0x3 0x0>; + compatible = "sharp,lr388k7_ts"; + flip-y = <0x1>; + clock-sel-gpio = <0x40 0x1 0x0>; + y-max = <0x3c00>; + touch-num-max = <0xa>; + status = "okay"; + interrupt-parent = <0x28>; + interrupts = <0x2f 0x1>; + z-max = <0xffff>; + reg = <0x0>; + flip-x = <0x1>; + avdd-supply = <0x3e>; + platform-id = <0x1>; + irq-gpio = <0x28 0x2f 0x1>; + spi-max-frequency = <0xb71b00>; + dvdd-supply = <0x3f>; + }; + }; + + denver-pmu { + compatible = "nvidia,denver15-pmu"; + interrupts = <0x0 0x122 0x4>; + interrupt-affinity = <0x2>; + }; + + eqos_ape@2990000 { + compatible = "nvidia,tegra18x-eqos-ape"; + wakeup-disable; + clocks = <0x10 0x69 0x10 0xf6 0x10 0x10f>; + clock-names = "eqos_ape.ape", "pll_a_out0", "pll_a"; + status = "disabled"; + reg = <0x0 0x2990054 0x0 0x4 0x0 0x29900c0 0x0 0x28>; + }; + + mipical { + compatible = "nvidia, tegra186-mipical"; + clocks = <0x10 0x74 0x10 0x7e>; + resets = <0x10 0x1c>; + clock-names = "mipi_cal", "uart_fs_mipi_cal"; + status = "okay"; + reg = <0x0 0x3990000 0x0 0x10000>; + reset-names = "mipi_cal"; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_cphy_csi { + prod = <0x18 0xf81f 0x0 0x1c 0xf81f 0x0 0x20 0xf81f 0x0 0x24 0xf81f 0x0 0x28 0xf81f 0x0 0x2c 0xf81f 0x0>; + + soc_a01 { + prod = <0x18 0xf81f 0x8010 0x1c 0xf81f 0x8010 0x20 0xf81f 0x8010 0x24 0xf81f 0x8010 0x28 0xf81f 0x8010 0x2c 0xf81f 0x8010>; + status = "disabled"; + phandle = <0xfa>; + linux,phandle = <0xfa>; + }; + }; + + prod { + prod = <0x4 0x3f000012 0x2a000010 0x18 0x40000000 0x0 0x1c 0x40000000 0x0 0x20 0x40000000 0x0 0x24 0x40000000 0x0 0x28 0x40000000 0x0 0x2c 0x40000000 0x0 0x3c 0x1f00 0x200 0x40 0x1f00 0x200 0x44 0x1f00 0x200 0x48 0x1f00 0x200 0x5c 0x1 0x0 0x60 0xf0f0f 0x0 0x64 0xf0ffff5 0x10010 0x68 0x4000001f 0x0 0x6c 0x4000001f 0x0 0x74 0x4000001f 0x0 0x78 0x4000001f 0x0>; + }; + + prod_c_dphy_dsi { + prod = <0x3c 0x1f1f1f 0x0 0x40 0x1f1f1f 0x0 0x44 0x1f1f1f 0x0 0x48 0x1f1f1f 0x0 0x68 0x1f0000 0x70000 0x6c 0x1f0000 0x70000 0x74 0x1f0000 0x70000 0x78 0x1f0000 0x70000>; + + soc_a01 { + prod = <0x3c 0x1f1f1f 0x101010 0x40 0x1f1f1f 0x101010 0x44 0x1f1f1f 0x101010 0x48 0x1f1f1f 0x101010 0x68 0x1f0000 0x100000 0x6c 0x1f0000 0x100000 0x74 0x1f0000 0x100000 0x78 0x1f0000 0x100000>; + status = "disabled"; + phandle = <0xfc>; + linux,phandle = <0xfc>; + }; + }; + + prod_c_dphy_csi { + prod = <0x18 0xf81f 0x0 0x1c 0xf81f 0x0 0x20 0xf81f 0x0 0x24 0xf81f 0x0 0x28 0xf81f 0x0 0x2c 0xf81f 0x0>; + + soc_a01 { + prod = <0x18 0xf81f 0x8010 0x1c 0xf81f 0x8010 0x20 0xf81f 0x8010 0x24 0xf81f 0x8010 0x28 0xf81f 0x8010 0x2c 0xf81f 0x8010>; + status = "disabled"; + phandle = <0xfb>; + linux,phandle = <0xfb>; + }; + }; + }; + }; + + e3326_lens_ov5693@P5V27C { + min_focus_distance = "0.0"; + f_number = "2.0"; + hyper_focal = "0.0"; + aperture = "2.0"; + focal_length = "2.67"; + }; + + e3323_lens_ov23850@CH06P1 { + min_focus_distance = "10.0"; + f_number = "2.2"; + hyper_focal = "0.2"; + aperture = "2.2"; + focal_length = "4.73"; + }; + + tegra-camera-platform { + isp_bw_margin_pct = <0x19>; + compatible = "nvidia, tegra-camera-platform"; + max_pixel_rate = <0xb71b0>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + phandle = <0x12f>; + tpg_max_iso = <0x3bc400>; + vi_bw_margin_pct = <0x19>; + linux,phandle = <0x12f>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + + modules { + + module4 { + badge = "e3322_bottomright_A815P2"; + status = "disabled"; + phandle = <0x152>; + position = "bottomright"; + linux,phandle = <0x152>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x154>; + linux,phandle = <0x154>; + }; + + drivernode0 { + devname = "imx219 34-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + phandle = <0x153>; + linux,phandle = <0x153>; + }; + }; + + module2 { + badge = "e3322_centerright_A815P2"; + status = "disabled"; + phandle = <0x140>; + position = "centerright"; + linux,phandle = <0x140>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x142>; + linux,phandle = <0x142>; + }; + + drivernode0 { + devname = "imx219 32-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + phandle = <0x141>; + linux,phandle = <0x141>; + }; + }; + + module0 { + badge = "e3326_front_P5V27C"; + status = "okay"; + phandle = <0x121>; + position = "rear"; + linux,phandle = <0x121>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3326_lens_ov5693@P5V27C/"; + phandle = <0x133>; + linux,phandle = <0x133>; + }; + + drivernode0 { + devname = "ov5693 2-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov5693_c@36"; + phandle = <0x122>; + linux,phandle = <0x122>; + }; + }; + + module5 { + badge = "e3322_topright_A815P2"; + status = "disabled"; + phandle = <0x15b>; + position = "topright"; + linux,phandle = <0x15b>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x15d>; + linux,phandle = <0x15d>; + }; + + drivernode0 { + devname = "imx219 35-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + phandle = <0x15c>; + linux,phandle = <0x15c>; + }; + }; + + module3 { + badge = "e3322_topleft_A815P2"; + status = "disabled"; + phandle = <0x149>; + position = "topleft"; + linux,phandle = <0x149>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x14b>; + linux,phandle = <0x14b>; + }; + + drivernode0 { + devname = "imx219 33-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + phandle = <0x14a>; + linux,phandle = <0x14a>; + }; + }; + + module1 { + badge = "imx390_front"; + status = "disabled"; + phandle = <0x124>; + position = "front"; + linux,phandle = <0x124>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + phandle = <0x137>; + linux,phandle = <0x137>; + }; + + drivernode0 { + devname = "imx390 30-001c"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + phandle = <0x125>; + linux,phandle = <0x125>; + }; + }; + }; + }; + + aon_shub { + compatible = "nvidia,tegra186_aon_shub"; + status = "disabled"; + mboxes = <0x41 0x5>; + }; + + pwm@32f0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xc1 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x6a>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x18c>; + reg = <0x0 0x32f0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x18c>; + #pwm-cells = <0x2>; + }; + + cpus { + status = "disabled"; + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu@3 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x5>; + reg = <0x0 0x101>; + linux,phandle = <0x5>; + }; + + l2-cache1 { + compatible = "cache"; + cache-level = <0x2>; + cache-unified; + phandle = <0xa>; + linux,phandle = <0xa>; + }; + + cpu@1 { + compatible = "nvidia,denver", "arm,armv8"; + cpu-idle-states = <0x8 0x9>; + device_type = "cpu"; + sched-energy-costs = <0xb 0xb>; + capacity-dmips-mhz = <0x400>; + cpu-ipc = <0x400>; + next-level-cache = <0xa>; + enable-method = "psci"; + status = "NILL"; + phandle = <0x3>; + reg = <0x0 0x1>; + linux,phandle = <0x3>; + }; + + cpu-map { + + cluster1 { + + core0 { + cpu = <0x4>; + }; + + core3 { + cpu = <0x7>; + }; + + core1 { + cpu = <0x5>; + }; + + core2 { + cpu = <0x6>; + }; + }; + + cluster0 { + }; + }; + + cpu@4 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x6>; + reg = <0x0 0x102>; + linux,phandle = <0x6>; + }; + + a57_cluster_power_states { + compatible = "nvidia,tegra186-cpuidle-a57-cluster"; + + cc6 { + state-name = "Cluster powergate"; + power = <0x13>; + pmstate = <0x6>; + status = "okay"; + wakeup-latency-us = <0x15e>; + min-residency-us = <0x1388>; + }; + + cc7 { + state-name = "Cluster railgate"; + power = <0x5>; + pmstate = <0x7>; + status = "disabled"; + wakeup-latency-us = <0x50>; + min-residency-us = <0x320>; + }; + + cc1 { + state-name = "Cluster clock gated"; + power = <0x41>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + }; + }; + + denver_core_power_states { + compatible = "nvidia,tegra186-cpuidle-denver"; + phandle = <0x178>; + linux,phandle = <0x178>; + + c1 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Clock gated"; + power = <0x46>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + phandle = <0x179>; + linux,phandle = <0x179>; + min-residency-us = <0x1>; + }; + + c6 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Virtual core powergate"; + arm,psci-suspend-param = <0x6>; + power = <0x3c>; + pmstate = <0x6>; + status = "okay"; + wakeup-latency-us = <0xbe>; + phandle = <0x8>; + linux,phandle = <0x8>; + min-residency-us = <0xffffffff>; + }; + + c7 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Core powergate"; + arm,psci-suspend-param = <0x40000007>; + power = <0x3c>; + pmstate = <0x7>; + status = "okay"; + wakeup-latency-us = <0x230>; + phandle = <0x9>; + linux,phandle = <0x9>; + min-residency-us = <0xffffffff>; + }; + }; + + cpu@2 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x4>; + reg = <0x0 0x100>; + linux,phandle = <0x4>; + }; + + a57_core_power_states { + compatible = "nvidia,tegra186-cpuidle-a57"; + phandle = <0x176>; + linux,phandle = <0x176>; + + c1 { + compatible = "nvidia,tegra186-cpuidle-a57"; + state-name = "Clock gated"; + power = <0x46>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + phandle = <0x177>; + linux,phandle = <0x177>; + min-residency-us = <0x1>; + }; + + c7 { + compatible = "nvidia,tegra186-cpuidle-a57"; + state-name = "Core powergate"; + arm,psci-suspend-param = <0x40000007>; + power = <0x3c>; + pmstate = <0x7>; + status = "okay"; + wakeup-latency-us = <0x82>; + phandle = <0xc>; + linux,phandle = <0xc>; + min-residency-us = <0xffffffff>; + }; + }; + + l2-cache0 { + compatible = "cache"; + cache-level = <0x2>; + cache-unified; + phandle = <0xd>; + linux,phandle = <0xd>; + }; + + a57_crossover_thresholds { + compatible = "nvidia,tegra186-cpuidle-a57-thresholds"; + + thresholds { + crossover_cc1_cc6 = <0x1388>; + crossover_cc1_cc7 = <0x2bc>; + }; + }; + + cpu@0 { + compatible = "nvidia,denver", "arm,armv8"; + cpu-idle-states = <0x8 0x9>; + device_type = "cpu"; + sched-energy-costs = <0xb 0xb>; + capacity-dmips-mhz = <0x400>; + cpu-ipc = <0x400>; + next-level-cache = <0xa>; + enable-method = "psci"; + status = "NILL"; + phandle = <0x2>; + reg = <0x0 0x0>; + linux,phandle = <0x2>; + }; + + denver_cluster_power_states { + compatible = "nvidia,tegra186-cpuidle-denver-cluster"; + + cc6 { + state-name = "Cluster powergate"; + power = <0x13>; + pmstate = <0x6>; + status = "okay"; + wakeup-latency-us = <0x1c2>; + min-residency-us = <0x1388>; + }; + + cc7 { + state-name = "Cluster railgate"; + power = <0x5>; + pmstate = <0x7>; + status = "disabled"; + wakeup-latency-us = <0x50>; + min-residency-us = <0x320>; + }; + + cc1 { + state-name = "Cluster clock gated"; + power = <0x41>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + }; + }; + + denver_crossover_thresholds { + compatible = "nvidia,tegra186-cpuidle-denver-thresholds"; + + thresholds { + crossover_c1_c6 = <0x3e8>; + crossover_cc1_cc6 = <0x1388>; + crossover_cc1_cc7 = <0x4e20>; + }; + }; + + cpu@5 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x7>; + reg = <0x0 0x103>; + linux,phandle = <0x7>; + }; + }; + + spi@3210000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0x31 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x28>; + clock-names = "spi", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p", "clk_m"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x24 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x182>; + reg = <0x0 0x3210000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0xf 0x25 0xf>; + reset-names = "spi"; + linux,phandle = <0x182>; + }; + + dma@2600000 { + #dma-cells = <0x1>; + compatible = "nvidia,tegra186-gpcdma"; + resets = <0x10 0x46>; + nvidia,preallocated-descs = <0x20>; + status = "okay"; + interrupts = <0x0 0x4b 0x4 0x0 0x4c 0x4 0x0 0x4d 0x4 0x0 0x4e 0x4 0x0 0x4f 0x4 0x0 0x50 0x4 0x0 0x51 0x4 0x0 0x52 0x4 0x0 0x53 0x4 0x0 0x54 0x4 0x0 0x55 0x4 0x0 0x56 0x4 0x0 0x57 0x4 0x0 0x58 0x4 0x0 0x59 0x4 0x0 0x5a 0x4 0x0 0x5b 0x4 0x0 0x5c 0x4 0x0 0x5d 0x4 0x0 0x5e 0x4 0x0 0x5f 0x4 0x0 0x60 0x4 0x0 0x61 0x4 0x0 0x62 0x4 0x0 0x63 0x4 0x0 0x64 0x4 0x0 0x65 0x4 0x0 0x66 0x4 0x0 0x67 0x4 0x0 0x68 0x4 0x0 0x69 0x4 0x0 0x6a 0x4 0x0 0x6b 0x4>; + phandle = <0x25>; + reg = <0x0 0x2600000 0x0 0x210000>; + iommus = <0x11 0x20>; + reset-names = "gpcdma"; + linux,phandle = <0x25>; + nvidia,preallocate-sg = <0x20>; + }; + + backlight { + status = "okay"; + + panel-s-wuxga-8-0-bl { + compatible = "s,wuxga-8-0-bl"; + default-brightness = <0xbf>; + default-charge-brightness = <0x70>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + status = "disabled"; + phandle = <0x1e0>; + max-brightness = <0xff>; + pwms = <0x27 0x0 0x9ce1>; + linux,phandle = <0x1e0>; + }; + + panel-a-edp-1080p-14-0-bl { + compatible = "a-edp,1080p-14-0-bl"; + default-brightness = <0xe0>; + bl-measured = <0x0 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0x9 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0x10 0x11 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x2a 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xb0 0xb1 0xb2 0xb3 0xb4 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc2 0xc3 0xc4 0xc5 0xc6 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xe0 0xe1 0xe2 0xe3 0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xee 0xef 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xff>; + status = "disabled"; + phandle = <0x1e3>; + max-brightness = <0xff>; + pwms = <0x27 0x0 0xf4240>; + linux,phandle = <0x1e3>; + }; + + panel-s-wqxga-10-1-bl { + compatible = "s,wqxga-10-1-bl"; + default-brightness = <0xe0>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc6 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe8 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff>; + status = "disabled"; + phandle = <0x1e1>; + max-brightness = <0xff>; + pwms = <0x27 0x0 0xf4240>; + linux,phandle = <0x1e1>; + }; + + panel-s-edp-uhdtv-15-6-bl { + compatible = "s-edp,uhdtv-15-6-bl"; + default-brightness = <0xe0>; + status = "disabled"; + phandle = <0x1e2>; + max-brightness = <0xff>; + pwms = <0xeb 0x0 0x4c4b40>; + linux,phandle = <0x1e2>; + }; + }; + + pwm@3280000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbb 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x63>; + clock-names = "pwm", "parent", "slow-parent"; + status = "okay"; + phandle = <0x27>; + reg = <0x0 0x3280000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x27>; + #pwm-cells = <0x2>; + }; + + axi2apb@23a0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23a0000 0x0 0x1000>; + }; + + hsp_top { + status = "okay"; + }; + + bwmgr { + compatible = "nvidia,bwmgr"; + clocks = <0x10 0x3a>; + clock-names = "emc"; + status = "okay"; + }; + + axip2p@2120000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2120000 0x0 0x1000>; + }; + + ether_qos@2490000 { + phy-handle = <0x44>; + nvidia,rxq_enable_ctrl = <0x2 0x2 0x2 0x2>; + compatible = "nvidia,eqos"; + clocks = <0x10 0xa7 0x10 0xa8 0x10 0xef 0x10 0xf0 0x10 0x95>; + nvidia,csr_clock_speed = <0x19>; + vddio_enet-supply = <0x13>; + iommu_sodev_map; + resets = <0x10 0x45>; + nvidia,phy-max-frame-size = <0xa>; + vddio_sys_enet_bias-supply = <0x12>; + reg-names = "eqos_base"; + pinctrl-1 = <0x43>; + phy_pllvdd-supply = <0x3c>; + nvidia,brcm_phy_apd_mode; + nvidia,phy-reset-gpio = <0x1b 0x64 0x0>; + nvidia,pause_frames = <0x0>; + clock-names = "eqos_axi", "eqos_rx", "eqos_ptp_ref", "eqos_tx", "axi_cbb"; + nvidia,rx_riwt = <0x7c>; + phy_vdd_1v8-supply = <0x12>; + nvidia,ptp_ref_clock_speed = <0x7d>; + status = "okay"; + interrupts = <0x0 0xc2 0x4 0x0 0xc3 0x4 0x0 0xbe 0x4 0x0 0xba 0x4 0x0 0xbf 0x4 0x0 0xbb 0x4 0x0 0xc0 0x4 0x0 0xbc 0x4 0x0 0xc1 0x4 0x0 0xbd 0x4>; + phy_ovdd_rgmii-supply = <0x13>; + nvidia,chan_napi_quota = <0x40 0x40 0x40 0x40>; + nvidia,iso_bw = <0x14000>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + nvidia,local-mac-address = <0x0 0x0 0x0 0x0 0x0 0x0>; + reg = <0x0 0x2490000 0x0 0x10000>; + phy-mode = "rgmii"; + iommus = <0x11 0x14>; + pinctrl-0 = <0x42>; + reset-names = "eqos_rst"; + nvidia,use_tagged_ptp; + nvidia,ptp_dma_ch = <0x3>; + nvidia,eth_iso_enable = <0x1>; + pinctrl-names = "idle", "default"; + nvidia,queue_prio = <0x0 0x1 0x2 0x3>; + + mdio { + compatible = "nvidia,eqos-mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ethernet-phy@0 { + interrupt-parent = <0x1b>; + interrupts = <0x65 0x8>; + phandle = <0x44>; + reg = <0x0>; + linux,phandle = <0x44>; + }; + }; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x0 0x8800 0xdff7ffff 0x8000007>; + }; + }; + + eqos-cool-dev { + cooling-min-state = <0x0>; + phandle = <0x4c>; + cooling-max-state = <0x5>; + #cooling-cells = <0x2>; + linux,phandle = <0x4c>; + }; + }; + + pcie-controller@10003000 { + power-domains = <0x1f 0x9>; + hvdd-pex-pll-supply = <0x12>; + compatible = "nvidia,tegra186-pcie"; + clocks = <0x10 0x4 0x10 0x3 0x10 0x261 0x10 0x200>; + vddio-pexctl-aud-supply = <0x12>; + iommu_sodev_map; + resets = <0x10 0x1 0x10 0x1d 0x10 0x1e>; + reg-names = "pads", "afi", "cs"; + hvdd-pex-supply = <0x12>; + device_type = "pci"; + dvdd-pex-supply = <0x89>; + clock-names = "afi", "pex", "clk_m", "pll_e"; + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + ranges = <0x82000000 0x0 0x10000000 0x0 0x10000000 0x0 0x1000 0x82000000 0x0 0x10001000 0x0 0x10001000 0x0 0x1000 0x82000000 0x0 0x10004000 0x0 0x10004000 0x0 0x1000 0x81000000 0x0 0x0 0x0 0x40001000 0x0 0x10000 0x82000000 0x0 0x40100000 0x0 0x40100000 0x0 0x7f00000 0xc2000000 0x0 0x48000000 0x0 0x48000000 0x0 0x38000000>; + status = "okay"; + #interrupt-cells = <0x1>; + bus-range = <0x0 0xff>; + #address-cells = <0x3>; + interrupts = <0x0 0x48 0x4 0x0 0x49 0x4>; + interrupt-map = <0x0 0x0 0x0 0x0 0x1 0x0 0x48 0x4>; + #size-cells = <0x2>; + phandle = <0x109>; + reg = <0x0 0x10003000 0x0 0x800 0x0 0x10003800 0x0 0x800 0x0 0x40000000 0x0 0x1000>; + iommus = <0x11 0x11>; + reset-names = "afi", "pex", "pcie_x"; + linux,phandle = <0x109>; + interrupt-names = "intr", "msi"; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_pad { + prod = <0xc8 0xffffffff 0x80b880b8 0xcc 0xffffffff 0x480b8>; + }; + }; + + pci@2,0 { + nvidia,afi-ctl-offset = <0x118>; + assigned-addresses = <0x82001000 0x0 0x10001000 0x0 0x1000>; + device_type = "pci"; + nvidia,num-lanes = <0x0>; + ranges; + status = "disabled"; + #address-cells = <0x3>; + #size-cells = <0x2>; + reg = <0x1000 0x0 0x0 0x0 0x0>; + nvidia,disable-aspm-states = <0xf>; + }; + + pci@1,0 { + nvidia,afi-ctl-offset = <0x110>; + assigned-addresses = <0x82000800 0x0 0x10000000 0x0 0x1000>; + device_type = "pci"; + nvidia,num-lanes = <0x4>; + nvidia,disable-clock-request; + ranges; + status = "okay"; + #address-cells = <0x3>; + #size-cells = <0x2>; + reg = <0x800 0x0 0x0 0x0 0x0>; + nvidia,disable-aspm-states = <0xf>; + }; + + pci@3,0 { + nvidia,afi-ctl-offset = <0x19c>; + assigned-addresses = <0x82001800 0x0 0x10004000 0x0 0x1000>; + device_type = "pci"; + nvidia,num-lanes = <0x1>; + ranges; + status = "okay"; + #address-cells = <0x3>; + #size-cells = <0x2>; + reg = <0x1800 0x0 0x0 0x0 0x0>; + nvidia,disable-aspm-states = <0xf>; + }; + }; + + stm@8070000 { + compatible = "arm,coresight-stm", "arm,primecell"; + clocks = <0x10 0xc4>; + reg-names = "stm-base", "stm-stimulus-base"; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8070000 0x0 0x1000 0x0 0xa000000 0x0 0x180000>; + + port { + + endpoint { + remote-endpoint = <0xd2>; + phandle = <0xdd>; + linux,phandle = <0xdd>; + }; + }; + }; + + pmc@c360000 { + #padcontroller-cells = <0x1>; + compatible = "nvidia,tegra186-pmc"; + nvidia,restrict-voltage-switch; + status = "okay"; + phandle = <0xb3>; + reg = <0x0 0xc360000 0x0 0x400 0x0 0xc390000 0x0 0x2fff>; + pinctrl-0 = <0xf>; + linux,phandle = <0xb3>; + pinctrl-names = "default"; + + sdmmc2_e_33V_enable { + phandle = <0x17>; + linux,phandle = <0x17>; + + sdmmc2 { + pins = "sdmmc2-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + sdmmc2_e_33V_disable { + phandle = <0x18>; + linux,phandle = <0x18>; + + sdmmc2 { + pins = "sdmmc2-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + dsib-dpd-enable { + phandle = <0x77>; + linux,phandle = <0x77>; + + dsib-pad-lowpower-enable { + low-power-enable; + pins = "dsib"; + }; + }; + + hdmi-dp1-dpd-disable { + phandle = <0x7e>; + linux,phandle = <0x7e>; + + hdmi-dp1-pad-lowpower-disable { + pins = "hdmi-dp1"; + low-power-disable; + }; + }; + + sdmmc3_e_33V_enable { + phandle = <0x14>; + linux,phandle = <0x14>; + + sdmmc3 { + pins = "sdmmc3-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + dsib-dpd-disable { + phandle = <0x76>; + linux,phandle = <0x76>; + + dsib-pad-lowpower-disable { + pins = "dsib"; + low-power-disable; + }; + }; + + dsic-dpd-enable { + phandle = <0x79>; + linux,phandle = <0x79>; + + dsic-pad-lowpower-enable { + low-power-enable; + pins = "dsic"; + }; + }; + + sdmmc3_e_33V_disable { + phandle = <0x15>; + linux,phandle = <0x15>; + + sdmmc3 { + pins = "sdmmc3-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + dsic-dpd-disable { + phandle = <0x78>; + linux,phandle = <0x78>; + + dsic-pad-lowpower-disable { + pins = "dsic"; + low-power-disable; + }; + }; + + dpd-enable { + phandle = <0x23>; + linux,phandle = <0x23>; + + ufs { + low-power-enable; + pins = "ufs"; + }; + }; + + dsid-dpd-enable { + phandle = <0x7b>; + linux,phandle = <0x7b>; + + dsid-pad-lowpower-enable { + low-power-enable; + pins = "dsid"; + }; + }; + + hdmi-dp0-dpd-enable { + phandle = <0x7d>; + linux,phandle = <0x7d>; + + hdmi-dp0-pad-lowpower-enable { + low-power-enable; + pins = "hdmi-dp0"; + }; + }; + + iopad-defaults { + phandle = <0xf>; + linux,phandle = <0xf>; + + sdmmc-io-pads { + pins = "sdmmc1-hv", "sdmmc2-hv", "sdmmc3-hv"; + nvidia,enable-voltage-switching; + }; + }; + + dsi-dpd-enable { + phandle = <0x75>; + linux,phandle = <0x75>; + + dsi-pad-lowpower-enable { + low-power-enable; + pins = "dsi"; + }; + }; + + dpd-disable { + phandle = <0x24>; + linux,phandle = <0x24>; + + ufs { + pins = "ufs"; + low-power-disable; + }; + }; + + dsid-dpd-disable { + phandle = <0x7a>; + linux,phandle = <0x7a>; + + dsidpad-lowpower-disable { + pins = "dsid"; + low-power-disable; + }; + }; + + hdmi-dp1-dpd-enable { + phandle = <0x7f>; + linux,phandle = <0x7f>; + + hdmi-dp1-pad-lowpower-enable { + low-power-enable; + pins = "hdmi-dp1"; + }; + }; + + sdmmc1_e_33V_disable { + phandle = <0x1a>; + linux,phandle = <0x1a>; + + sdmmc1 { + pins = "sdmmc1-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + sdmmc1_e_33V_enable { + phandle = <0x19>; + linux,phandle = <0x19>; + + sdmmc1 { + pins = "sdmmc1-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + hdmi-dp0-dpd-disable { + phandle = <0x7c>; + linux,phandle = <0x7c>; + + hdmi-dp0-pad-lowpower-disable { + pins = "hdmi-dp0"; + low-power-disable; + }; + }; + + dsi-dpd-disable { + phandle = <0x74>; + linux,phandle = <0x74>; + + dsi-pad-lowpower-disable { + pins = "dsi"; + low-power-disable; + }; + }; + }; + + bcmdhd_wlan { + nv_path = "/vendor/firmware/nvram_quill_4354.txt"; + compatible = "android,bcmdhd_wlan"; + fw_path = "/vendor/firmware/fw_bcmdhd_4354.bin"; + pwr-retry-cnt = <0x5>; + status = "okay"; + interrupt-parent = <0x28>; + interrupts = <0x3b 0x14>; + phandle = <0x10a>; + linux,phandle = <0x10a>; + wlan-pwr-gpio = <0x1b 0x68 0x0>; + sdhci-host = <0xf9>; + }; + + generic-system-config { + compatible = "nvidia,tegra186-system-config"; + status = "disabled"; + }; + + hardwood { + compatible = "nvidia,denver-hardwood"; + interrupts = <0x0 0x18 0x4>; + }; + + funnel_bccplex@9010000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x9010000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + reg = <0x0>; + + endpoint { + phandle = <0x1dc>; + slave-mode; + linux,phandle = <0x1dc>; + }; + }; + + port@2 { + reg = <0x1>; + + endpoint { + remote-endpoint3 = <0xd9>; + remote-endpoint1 = <0xd7>; + remote-endpoint2 = <0xd8>; + phandle = <0xd3>; + remote-endpoint0 = <0xd6>; + slave-mode; + linux,phandle = <0xd3>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xd5>; + phandle = <0xdb>; + linux,phandle = <0xdb>; + }; + }; + }; + }; + + serial@3100000 { + compatible = "nvidia,tegra20-uart", "nvidia,tegra186-hsuart"; + clocks = <0x10 0x37 0x10 0x10d>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + console-port; + clock-names = "serial", "parent"; + sqa-automation-port; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "okay"; + interrupts = <0x0 0x70 0x4>; + dma-names = "rx", "tx"; + phandle = <0x103>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3100000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x8 0x25 0x8>; + reg-shift = <0x2>; + linux,phandle = <0x103>; + }; + + i2c@31c0000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xb6 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x51>; + scl-gpio = <0x1b 0x58 0x0>; + sda-gpio = <0x1b 0x59 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1f 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x17f>; + reg = <0x0 0x31c0000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x1b 0x25 0x1b>; + reset-names = "i2c"; + linux,phandle = <0x17f>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + axip2p@2160000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2160000 0x0 0x1000>; + }; + + lens_imx274@A6V26 { + min_focus_distance = "0.0"; + f_number = "2.0"; + hyper_focal = "0.0"; + aperture = "2.2"; + focal_length = "5.00"; + }; + + serial@3140000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xc2 0x10 0x10d>; + resets = <0x10 0x84>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "disabled"; + interrupts = <0x0 0x74 0x4>; + dma-names = "rx", "tx"; + phandle = <0x190>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3140000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x14 0x25 0x14>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x190>; + }; + + spdif_dit { + compatible = "simple-bus"; + device_type = "spdif-dit"; + status = "okay"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + spdif-dit.10@a { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xcc>; + reg = <0xa>; + linux,phandle = <0xcc>; + }; + + spdif-dit.0@0 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xba>; + reg = <0x0>; + linux,phandle = <0xba>; + }; + + spdif-dit.7@7 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc6>; + reg = <0x7>; + linux,phandle = <0xc6>; + }; + + spdif-dit.11@b { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xd0>; + reg = <0xb>; + linux,phandle = <0xd0>; + }; + + spdif-dit.1@1 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xbc>; + reg = <0x1>; + linux,phandle = <0xbc>; + }; + + spdif-dit.8@8 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc8>; + reg = <0x8>; + linux,phandle = <0xc8>; + }; + + spdif-dit.12@c { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xd1>; + reg = <0xc>; + linux,phandle = <0xd1>; + }; + + spdif-dit.2@2 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xbe>; + reg = <0x2>; + linux,phandle = <0xbe>; + }; + + spdif-dit.9@9 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xca>; + reg = <0x9>; + linux,phandle = <0xca>; + }; + + spdif-dit.13@d { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xce>; + reg = <0xd>; + linux,phandle = <0xce>; + }; + + spdif-dit.3@3 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc0>; + reg = <0x3>; + linux,phandle = <0xc0>; + }; + + spdif-dit.4@4 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc2>; + reg = <0x4>; + linux,phandle = <0xc2>; + }; + + spdif-dit.5@5 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0x181>; + reg = <0x5>; + linux,phandle = <0x181>; + }; + + spdif-dit.6@6 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc4>; + reg = <0x6>; + linux,phandle = <0xc4>; + }; + }; + + interrupt-controller { + compatible = "android,CustomIPI"; + #interrupt-cells = <0x1>; + phandle = <0x46>; + linux,phandle = <0x46>; + interrupt-controller; + }; + + ptm_bpmp@8a1c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8a1c000 0x0 0x1000>; + + port { + + endpoint { + remote-endpoint = <0xd4>; + phandle = <0xe6>; + linux,phandle = <0xe6>; + }; + }; + }; + + ptm@9940000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x5>; + status = "okay"; + phandle = <0x1d9>; + reg = <0x0 0x9940000 0x0 0x1000>; + linux,phandle = <0x1d9>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd7>; + linux,phandle = <0xd7>; + }; + }; + }; + + tegra_fiq_debugger { + compatible = "nvidia,fiq-debugger"; + interrupts = <0x0 0x11 0x4>; + use-console-port; + }; + + gp10b { + compatible = "nvidia,tegra186-gp10b", "nvidia,gp10b"; + clocks = <0x10 0x136 0x10 0x1>; + access-vpr-phys; + resets = <0x10 0xe>; + clock-names = "gpu", "gpu_sys"; + fuse-overrides = <0x228 0x9999>; + status = "okay"; + interrupts = <0x0 0x46 0x4 0x0 0x47 0x4>; + dma-noncont; + reg = <0x0 0x17000000 0x0 0x1000000 0x0 0x18000000 0x0 0x1000000 0x0 0x3b41000 0x0 0x1000>; + iommus = <0x11 0x10>; + nvidia,host1x = <0xb6>; + interrupt-names = "stall", "nonstall"; + }; +}; diff --git a/dts/pi4.dts b/dts/pi4.dts new file mode 100644 index 0000000000000000000000000000000000000000..37567e41a099ce2db94972c5ab20e96e090421bd --- /dev/null +++ b/dts/pi4.dts @@ -0,0 +1,2375 @@ +/dts-v1/; + +/memreserve/ 0x0000000000000000 0x0000000000080000; +/ { + compatible = "raspberrypi,4-model-b\0brcm,bcm2711"; + model = "Raspberry Pi 4 Model B"; + #address-cells = <0x02>; + #size-cells = <0x02>; + interrupt-parent = <0x01>; + + aliases { + serial0 = "/soc/serial@7e201400"; + // serial1 = "/soc/serial@7e201000"; + ethernet0 = "/scb/ethernet@7d580000"; + audio = "/soc/mailbox@7e00b840/bcm2835_audio"; + aux = "/soc/aux@7e215000"; + sound = "/soc/sound"; + soc = "/soc"; + dma = "/soc/dma@7e007000"; + watchdog = "/soc/watchdog@7e100000"; + random = "/soc/rng@7e104000"; + mailbox = "/soc/mailbox@7e00b880"; + gpio = "/soc/gpio@7e200000"; + // uart0 = "/soc/serial@7e201000"; + // uart1 = "/soc/serial@7e215040"; + // sdhost = "/soc/mmc@7e202000"; + // mmc = "/soc/mmc@7e300000"; + // mmc1 = "/soc/mmcnr@7e300000"; + // mmc0 = "/emmc2bus/emmc2@7e340000"; + i2s = "/soc/i2s@7e203000"; + i2c0 = "/soc/i2c0mux/i2c@0"; + i2c1 = "/soc/i2c@7e804000"; + i2c10 = "/soc/i2c0mux/i2c@1"; + spi0 = "/soc/spi@7e204000"; + spi1 = "/soc/spi@7e215080"; + spi2 = "/soc/spi@7e2150c0"; + usb = "/soc/usb@7e980000"; + leds = "/leds"; + fb = "/soc/fb"; + thermal = "/soc/avs-monitor@7d5d2000/thermal"; + axiperf = "/soc/axiperf"; + // mmc2 = "/soc/mmc@7e202000"; + i2c3 = "/soc/i2c@7e205600"; + i2c4 = "/soc/i2c@7e205800"; + i2c5 = "/soc/i2c@7e205a00"; + i2c6 = "/soc/i2c@7e205c00"; + pcie0 = "/scb/pcie@7d500000"; + // emmc2bus = "/emmc2bus"; + }; + + chosen { + // bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; + stdout-path = "serial0:115200n8"; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x01>; + ranges; + phandle = <0x3d>; + + linux,cma { + compatible = "shared-dma-pool"; + size = <0x4000000>; + reusable; + linux,cma-default; + alloc-ranges = <0x00 0x00 0x30000000>; + phandle = <0x3e>; + }; + }; + + thermal-zones { + + cpu-thermal { + polling-delay-passive = <0x00>; + polling-delay = <0x3e8>; + coefficients = <0xfffffe19 0x641b8>; + thermal-sensors = <0x02>; + phandle = <0x3f>; + + cooling-maps { + }; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges = <0x7e000000 0x00 0xfe000000 0x1800000 0x7c000000 0x00 0xfc000000 0x2000000 0x40000000 0x00 0xff800000 0x800000>; + dma-ranges = <0xc0000000 0x00 0x00 0x40000000>; + phandle = <0x40>; + + timer@7e003000 { + compatible = "brcm,bcm2835-system-timer"; + reg = <0x7e003000 0x1000>; + interrupts = <0x00 0x40 0x04 0x00 0x41 0x04 0x00 0x42 0x04 0x00 0x43 0x04>; + clock-frequency = <0xf4240>; + phandle = <0x41>; + }; + + txp@7e004000 { + compatible = "brcm,bcm2835-txp"; + reg = <0x7e004000 0x20>; + interrupts = <0x00 0x4b 0x04>; + status = "disabled"; + phandle = <0x42>; + }; + + cprman@7e101000 { + compatible = "brcm,bcm2711-cprman"; + #clock-cells = <0x01>; + reg = <0x7e101000 0x2000>; + clocks = <0x03 0x04 0x00 0x04 0x01 0x04 0x02 0x05 0x00 0x05 0x01 0x05 0x02>; + firmware = <0x06>; + phandle = <0x07>; + }; + + rng@7e104000 { + compatible = "brcm,bcm2711-rng200"; + reg = <0x7e104000 0x10>; + interrupts = <0x00 0x7d 0x04>; + status = "okay"; + phandle = <0x32>; + }; + + mailbox@7e00b880 { + compatible = "brcm,bcm2835-mbox"; + reg = <0x7e00b880 0x40>; + interrupts = <0x00 0x21 0x04>; + #mbox-cells = <0x00>; + phandle = <0x1f>; + }; + + gpio@7e200000 { + compatible = "brcm,bcm2711-gpio\0brcm,bcm2835-gpio"; + reg = <0x7e200000 0xb4>; + interrupts = <0x00 0x71 0x04 0x00 0x72 0x04>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + pinctrl-names = "default"; + phandle = <0x0e>; + + dpi_gpio0 { + brcm,pins = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>; + brcm,function = <0x06>; + phandle = <0x43>; + }; + + emmc_gpio22 { + brcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>; + brcm,function = <0x07>; + phandle = <0x44>; + }; + + emmc_gpio34 { + brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02 0x02 0x02 0x02 0x02>; + phandle = <0x45>; + }; + + emmc_gpio48 { + brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>; + brcm,function = <0x07>; + phandle = <0x21>; + }; + + gpclk0_gpio4 { + brcm,pins = <0x04>; + brcm,function = <0x04>; + phandle = <0x46>; + }; + + gpclk1_gpio5 { + brcm,pins = <0x05>; + brcm,function = <0x04>; + phandle = <0x47>; + }; + + gpclk1_gpio42 { + brcm,pins = <0x2a>; + brcm,function = <0x04>; + phandle = <0x48>; + }; + + gpclk1_gpio44 { + brcm,pins = <0x2c>; + brcm,function = <0x04>; + phandle = <0x49>; + }; + + gpclk2_gpio6 { + brcm,pins = <0x06>; + brcm,function = <0x04>; + phandle = <0x4a>; + }; + + gpclk2_gpio43 { + brcm,pins = <0x2b>; + brcm,function = <0x04>; + brcm,pull = <0x00>; + phandle = <0x4b>; + }; + + i2c0_gpio0 { + brcm,pins = <0x00 0x01>; + brcm,function = <0x04>; + phandle = <0x10>; + }; + + i2c0_gpio28 { + brcm,pins = <0x1c 0x1d>; + brcm,function = <0x04>; + phandle = <0x4c>; + }; + + i2c0_gpio44 { + brcm,pins = <0x2c 0x2d>; + brcm,function = <0x05>; + phandle = <0x11>; + }; + + i2c1_gpio2 { + brcm,pins = <0x02 0x03>; + brcm,function = <0x04>; + phandle = <0x4d>; + }; + + i2c1_gpio44 { + brcm,pins = <0x2c 0x2d>; + brcm,function = <0x06>; + phandle = <0x4e>; + }; + + jtag_gpio22 { + brcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>; + brcm,function = <0x03>; + phandle = <0x4f>; + }; + + pcm_gpio18 { + brcm,pins = <0x12 0x13 0x14 0x15>; + brcm,function = <0x04>; + phandle = <0x50>; + }; + + pcm_gpio28 { + brcm,pins = <0x1c 0x1d 0x1e 0x1f>; + brcm,function = <0x06>; + phandle = <0x51>; + }; + + sdhost_gpio48 { + brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>; + brcm,function = <0x04>; + phandle = <0x52>; + }; + + spi0_gpio7 { + brcm,pins = <0x07 0x08 0x09 0x0a 0x0b>; + brcm,function = <0x04>; + phandle = <0x53>; + }; + + spi0_gpio35 { + brcm,pins = <0x23 0x24 0x25 0x26 0x27>; + brcm,function = <0x04>; + phandle = <0x54>; + }; + + spi1_gpio16 { + brcm,pins = <0x10 0x11 0x12 0x13 0x14 0x15>; + brcm,function = <0x03>; + phandle = <0x55>; + }; + + spi2_gpio40 { + brcm,pins = <0x28 0x29 0x2a 0x2b 0x2c 0x2d>; + brcm,function = <0x03>; + phandle = <0x56>; + }; + + uart0_gpio14 { + brcm,pins = <0x0e 0x0f>; + brcm,function = <0x04>; + phandle = <0x57>; + }; + + uart0_ctsrts_gpio16 { + brcm,pins = <0x10 0x11>; + brcm,function = <0x07>; + phandle = <0x58>; + }; + + uart0_ctsrts_gpio30 { + brcm,pins = <0x1e 0x1f>; + brcm,function = <0x07>; + brcm,pull = <0x02 0x00>; + phandle = <0x59>; + }; + + uart0_gpio32 { + brcm,pins = <0x20 0x21>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02>; + phandle = <0x5a>; + }; + + uart0_gpio36 { + brcm,pins = <0x24 0x25>; + brcm,function = <0x06>; + phandle = <0x5b>; + }; + + uart0_ctsrts_gpio38 { + brcm,pins = <0x26 0x27>; + brcm,function = <0x06>; + phandle = <0x5c>; + }; + + uart1_gpio14 { + brcm,pins = <0x0e 0x0f>; + brcm,function = <0x02>; + phandle = <0x5d>; + }; + + uart1_ctsrts_gpio16 { + brcm,pins = <0x10 0x11>; + brcm,function = <0x02>; + phandle = <0x5e>; + }; + + uart1_gpio32 { + brcm,pins = <0x20 0x21>; + brcm,function = <0x02>; + phandle = <0x5f>; + }; + + uart1_ctsrts_gpio30 { + brcm,pins = <0x1e 0x1f>; + brcm,function = <0x02>; + phandle = <0x60>; + }; + + uart1_gpio40 { + brcm,pins = <0x28 0x29>; + brcm,function = <0x02>; + phandle = <0x61>; + }; + + uart1_ctsrts_gpio42 { + brcm,pins = <0x2a 0x2b>; + brcm,function = <0x02>; + phandle = <0x62>; + }; + + gpclk0_gpio49 { + phandle = <0x63>; + + pin-gpclk { + pins = "gpio49"; + function = "alt1"; + bias-disable; + }; + }; + + gpclk1_gpio50 { + phandle = <0x64>; + + pin-gpclk { + pins = "gpio50"; + function = "alt1"; + bias-disable; + }; + }; + + gpclk2_gpio51 { + phandle = <0x65>; + + pin-gpclk { + pins = "gpio51"; + function = "alt1"; + bias-disable; + }; + }; + + i2c0_gpio46 { + phandle = <0x66>; + + pin-sda { + function = "alt0"; + pins = "gpio46"; + bias-pull-up; + }; + + pin-scl { + function = "alt0"; + pins = "gpio47"; + bias-disable; + }; + }; + + i2c1_gpio46 { + phandle = <0x67>; + + pin-sda { + function = "alt1"; + pins = "gpio46"; + bias-pull-up; + }; + + pin-scl { + function = "alt1"; + pins = "gpio47"; + bias-disable; + }; + }; + + i2c3_gpio2 { + phandle = <0x68>; + + pin-sda { + function = "alt5"; + pins = "gpio2"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio3"; + bias-disable; + }; + }; + + i2c3_gpio4 { + phandle = <0x69>; + + pin-sda { + function = "alt5"; + pins = "gpio4"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio5"; + bias-disable; + }; + }; + + i2c4_gpio6 { + phandle = <0x6a>; + + pin-sda { + function = "alt5"; + pins = "gpio6"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio7"; + bias-disable; + }; + }; + + i2c4_gpio8 { + phandle = <0x6b>; + + pin-sda { + function = "alt5"; + pins = "gpio8"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio9"; + bias-disable; + }; + }; + + i2c5_gpio10 { + phandle = <0x6c>; + + pin-sda { + function = "alt5"; + pins = "gpio10"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio11"; + bias-disable; + }; + }; + + i2c5_gpio12 { + phandle = <0x6d>; + + pin-sda { + function = "alt5"; + pins = "gpio12"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio13"; + bias-disable; + }; + }; + + i2c6_gpio0 { + phandle = <0x6e>; + + pin-sda { + function = "alt5"; + pins = "gpio0"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio1"; + bias-disable; + }; + }; + + i2c6_gpio22 { + phandle = <0x6f>; + + pin-sda { + function = "alt5"; + pins = "gpio22"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio23"; + bias-disable; + }; + }; + + i2c_slave_gpio8 { + phandle = <0x70>; + + pins-i2c-slave { + pins = "gpio8\0gpio9\0gpio10\0gpio11"; + function = "alt3"; + }; + }; + + jtag_gpio48 { + phandle = <0x71>; + + pins-jtag { + pins = "gpio48\0gpio49\0gpio50\0gpio51\0gpio52\0gpio53"; + function = "alt4"; + }; + }; + + mii_gpio28 { + phandle = <0x72>; + + pins-mii { + pins = "gpio28\0gpio29\0gpio30\0gpio31"; + function = "alt4"; + }; + }; + + mii_gpio36 { + phandle = <0x73>; + + pins-mii { + pins = "gpio36\0gpio37\0gpio38\0gpio39"; + function = "alt5"; + }; + }; + + pcm_gpio50 { + phandle = <0x74>; + + pins-pcm { + pins = "gpio50\0gpio51\0gpio52\0gpio53"; + function = "alt2"; + }; + }; + + pwm0_0_gpio12 { + phandle = <0x75>; + + pin-pwm { + pins = "gpio12"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_0_gpio18 { + phandle = <0x76>; + + pin-pwm { + pins = "gpio18"; + function = "alt5"; + bias-disable; + }; + }; + + pwm1_0_gpio40 { + phandle = <0x19>; + + pin-pwm { + pins = "gpio40"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_1_gpio13 { + phandle = <0x77>; + + pin-pwm { + pins = "gpio13"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_1_gpio19 { + phandle = <0x78>; + + pin-pwm { + pins = "gpio19"; + function = "alt5"; + bias-disable; + }; + }; + + pwm1_1_gpio41 { + phandle = <0x1a>; + + pin-pwm { + pins = "gpio41"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_1_gpio45 { + phandle = <0x79>; + + pin-pwm { + pins = "gpio45"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_0_gpio52 { + phandle = <0x7a>; + + pin-pwm { + pins = "gpio52"; + function = "alt1"; + bias-disable; + }; + }; + + pwm0_1_gpio53 { + phandle = <0x7b>; + + pin-pwm { + pins = "gpio53"; + function = "alt1"; + bias-disable; + }; + }; + + rgmii_gpio35 { + phandle = <0x7c>; + + pin-start-stop { + pins = "gpio35"; + function = "alt4"; + }; + + pin-rx-ok { + pins = "gpio36"; + function = "alt4"; + }; + }; + + rgmii_irq_gpio34 { + phandle = <0x7d>; + + pin-irq { + pins = "gpio34"; + function = "alt5"; + }; + }; + + rgmii_irq_gpio39 { + phandle = <0x7e>; + + pin-irq { + pins = "gpio39"; + function = "alt4"; + }; + }; + + rgmii_mdio_gpio28 { + phandle = <0x7f>; + + pins-mdio { + pins = "gpio28\0gpio29"; + function = "alt5"; + }; + }; + + rgmii_mdio_gpio37 { + phandle = <0x80>; + + pins-mdio { + pins = "gpio37\0gpio38"; + function = "alt4"; + }; + }; + + spi0_gpio46 { + phandle = <0x81>; + + pins-spi { + pins = "gpio46\0gpio47\0gpio48\0gpio49"; + function = "alt2"; + }; + }; + + spi2_gpio46 { + phandle = <0x82>; + + pins-spi { + pins = "gpio46\0gpio47\0gpio48\0gpio49\0gpio50"; + function = "alt5"; + }; + }; + + spi3_gpio0 { + phandle = <0x83>; + + pins-spi { + pins = "gpio0\0gpio1\0gpio2\0gpio3"; + function = "alt3"; + }; + }; + + spi4_gpio4 { + phandle = <0x84>; + + pins-spi { + pins = "gpio4\0gpio5\0gpio6\0gpio7"; + function = "alt3"; + }; + }; + + spi5_gpio12 { + phandle = <0x85>; + + pins-spi { + pins = "gpio12\0gpio13\0gpio14\0gpio15"; + function = "alt3"; + }; + }; + + spi6_gpio18 { + phandle = <0x86>; + + pins-spi { + pins = "gpio18\0gpio19\0gpio20\0gpio21"; + function = "alt3"; + }; + }; + + uart2_gpio0 { + phandle = <0x87>; + + pin-tx { + pins = "gpio0"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio1"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart2_ctsrts_gpio2 { + phandle = <0x88>; + + pin-cts { + pins = "gpio2"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio3"; + function = "alt4"; + bias-disable; + }; + }; + + uart3_gpio4 { + phandle = <0x89>; + + pin-tx { + pins = "gpio4"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio5"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart3_ctsrts_gpio6 { + phandle = <0x8a>; + + pin-cts { + pins = "gpio6"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio7"; + function = "alt4"; + bias-disable; + }; + }; + + uart4_gpio8 { + phandle = <0x8b>; + + pin-tx { + pins = "gpio8"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio9"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart4_ctsrts_gpio10 { + phandle = <0x8c>; + + pin-cts { + pins = "gpio10"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio11"; + function = "alt4"; + bias-disable; + }; + }; + + uart5_gpio12 { + phandle = <0x8d>; + + pin-tx { + pins = "gpio12"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio13"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart5_ctsrts_gpio14 { + phandle = <0x8e>; + + pin-cts { + pins = "gpio14"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio15"; + function = "alt4"; + bias-disable; + }; + }; + + gpioout { + brcm,pins = <0x06>; + brcm,function = <0x01>; + phandle = <0x8f>; + }; + + alt0 { + brcm,pins = <0x04 0x05 0x07 0x08 0x09 0x0a 0x0b>; + brcm,function = <0x04>; + phandle = <0x90>; + }; + + dpi_18bit_gpio0 { + brcm,pins = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15>; + brcm,function = <0x06>; + phandle = <0x91>; + }; + + spi0_pins { + brcm,pins = <0x09 0x0a 0x0b>; + brcm,function = <0x04>; + phandle = <0x0c>; + }; + + spi0_cs_pins { + brcm,pins = <0x08 0x07>; + brcm,function = <0x01>; + phandle = <0x0d>; + }; + + spi3_pins { + brcm,pins = <0x01 0x02 0x03>; + brcm,function = <0x07>; + phandle = <0x92>; + }; + + spi3_cs_pins { + brcm,pins = <0x00 0x18>; + brcm,function = <0x01>; + phandle = <0x93>; + }; + + spi4_pins { + brcm,pins = <0x05 0x06 0x07>; + brcm,function = <0x07>; + phandle = <0x94>; + }; + + spi4_cs_pins { + brcm,pins = <0x04 0x19>; + brcm,function = <0x01>; + phandle = <0x95>; + }; + + spi5_pins { + brcm,pins = <0x0d 0x0e 0x0f>; + brcm,function = <0x07>; + phandle = <0x96>; + }; + + spi5_cs_pins { + brcm,pins = <0x0c 0x1a>; + brcm,function = <0x01>; + phandle = <0x97>; + }; + + spi6_pins { + brcm,pins = <0x13 0x14 0x15>; + brcm,function = <0x07>; + phandle = <0x98>; + }; + + spi6_cs_pins { + brcm,pins = <0x12 0x1b>; + brcm,function = <0x01>; + phandle = <0x99>; + }; + + i2c0 { + brcm,pins = <0x00 0x01>; + brcm,function = <0x04>; + brcm,pull = <0x02>; + phandle = <0x9a>; + }; + + i2c1 { + brcm,pins = <0x02 0x03>; + brcm,function = <0x04>; + brcm,pull = <0x02>; + phandle = <0x16>; + }; + + i2c3 { + brcm,pins = <0x04 0x05>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9b>; + }; + + i2c4 { + brcm,pins = <0x08 0x09>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9c>; + }; + + i2c5 { + brcm,pins = <0x0c 0x0d>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9d>; + }; + + i2c6 { + brcm,pins = <0x16 0x17>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9e>; + }; + + i2s { + brcm,pins = <0x12 0x13 0x14 0x15>; + brcm,function = <0x04>; + phandle = <0x0b>; + }; + + sdio_pins { + brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02 0x02 0x02 0x02 0x02>; + phandle = <0x22>; + }; + + bt_pins { + brcm,pins = [2d 00]; + brcm,function = <0x00>; + brcm,pull = <0x02>; + phandle = <0x09>; + }; + + uart0_pins { + brcm,pins = <0x20 0x21>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02>; + phandle = <0x08>; + }; + + uart1_pins { + brcm,pins; + brcm,function; + brcm,pull; + phandle = <0x14>; + }; + + uart2_pins { + brcm,pins = <0x00 0x01>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0x9f>; + }; + + uart3_pins { + brcm,pins = <0x04 0x05>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0xa0>; + }; + + uart4_pins { + brcm,pins = <0x08 0x09>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0xa1>; + }; + + uart5_pins { + brcm,pins = <0x0c 0x0d>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0xa2>; + }; + + audio_pins { + brcm,pins = <0x28 0x29>; + brcm,function = <0x04>; + phandle = <0x20>; + }; + }; + + serial@7e201400 { + compatible = "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; + reg = <0x7e201400 0x200>; + interrupts = <0x00 0x79 0x04>; + clocks = <0x07 0x13 0x07 0x14>; + clock-names = "uartclk\0apb_pclk"; + arm,primecell-periphid = <0x241011>; + // pinctrl-names = "default"; + // pinctrl-0 = <0x08 0x09>; + uart-has-rtscts; + status = "okay"; + cts-event-workaround; + phandle = <0x2a>; + }; + + // mmc@7e202000 { + // compatible = "brcm,bcm2835-sdhost"; + // reg = <0x7e202000 0x100>; + // interrupts = <0x00 0x78 0x04>; + // clocks = <0x07 0x14>; + // status = "disabled"; + // dmas = <0x0a 0x2000000d>; + // dma-names = "rx-tx"; + // bus-width = <0x04>; + // brcm,overclock-50 = <0x00>; + // brcm,pio-limit = <0x01>; + // phandle = <0x33>; + // }; + + i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; + reg = <0x7e203000 0x24>; + clocks = <0x07 0x1f>; + status = "disabled"; + #sound-dai-cells = <0x00>; + dmas = <0x0a 0x02 0x0a 0x03>; + dma-names = "tx\0rx"; + pinctrl-names = "default"; + pinctrl-0 = <0x0b>; + phandle = <0x2c>; + }; + + spi@7e204000 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204000 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + dmas = <0x0a 0x06 0x0a 0x07>; + dma-names = "tx\0rx"; + pinctrl-names = "default"; + pinctrl-0 = <0x0c 0x0d>; + cs-gpios = <0x0e 0x08 0x01 0x0e 0x07 0x01>; + phandle = <0x2d>; + + spidev@0 { + compatible = "spidev"; + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + spi-max-frequency = <0x7735940>; + phandle = <0xa3>; + }; + + spidev@1 { + compatible = "spidev"; + reg = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + spi-max-frequency = <0x7735940>; + phandle = <0xa4>; + }; + }; + + i2c@7e205000 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205000 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + clock-frequency = <0x186a0>; + phandle = <0x0f>; + }; + + i2c0mux { + compatible = "i2c-mux-pinctrl"; + #address-cells = <0x01>; + #size-cells = <0x00>; + i2c-parent = <0x0f>; + pinctrl-names = "i2c0\0i2c_csi_dsi"; + status = "disabled"; + pinctrl-0 = <0x10>; + pinctrl-1 = <0x11>; + phandle = <0x2e>; + + i2c@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0xa5>; + }; + + i2c@1 { + reg = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0xa6>; + }; + }; + + dpi@7e208000 { + compatible = "brcm,bcm2835-dpi"; + reg = <0x7e208000 0x8c>; + clocks = <0x07 0x14 0x07 0x2c>; + clock-names = "core\0pixel"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xa7>; + }; + + dsi@7e209000 { + compatible = "brcm,bcm2835-dsi0"; + reg = <0x7e209000 0x78>; + interrupts = <0x00 0x64 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + clocks = <0x07 0x20 0x07 0x2f 0x07 0x31>; + clock-names = "phy\0escape\0pixel"; + clock-output-names = "dsi0_byte\0dsi0_ddr2\0dsi0_ddr"; + status = "disabled"; + power-domains = <0x12 0x11>; + phandle = <0x04>; + }; + + aux@7e215000 { + compatible = "brcm,bcm2835-aux"; + #clock-cells = <0x01>; + reg = <0x7e215000 0x08>; + clocks = <0x07 0x14>; + phandle = <0x13>; + }; + + // serial@7e215040 { + // compatible = "brcm,bcm2835-aux-uart"; + // reg = <0x7e215040 0x40>; + // interrupts = <0x00 0x5d 0x04>; + // clocks = <0x13 0x00>; + // status = "okay"; + // pinctrl-names = "default"; + // pinctrl-0 = <0x14>; + // phandle = <0x2b>; + // }; + + spi@7e215080 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e215080 0x40>; + interrupts = <0x00 0x5d 0x04>; + clocks = <0x13 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xa8>; + }; + + spi@7e2150c0 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e2150c0 0x40>; + interrupts = <0x00 0x5d 0x04>; + clocks = <0x13 0x02>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xa9>; + }; + + pwm@7e20c000 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c000 0x28>; + clocks = <0x07 0x1e>; + assigned-clocks = <0x07 0x1e>; + assigned-clock-rates = <0x989680>; + #pwm-cells = <0x02>; + status = "disabled"; + phandle = <0xaa>; + }; + + hvs@7e400000 { + compatible = "brcm,bcm2835-hvs"; + reg = <0x7e400000 0x6000>; + interrupts = <0x00 0x61 0x04>; + clocks = <0x15 0x04>; + status = "disabled"; + phandle = <0xab>; + }; + + dsi@7e700000 { + compatible = "brcm,bcm2835-dsi1"; + reg = <0x7e700000 0x8c>; + interrupts = <0x00 0x6c 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + clocks = <0x07 0x23 0x07 0x30 0x07 0x32>; + clock-names = "phy\0escape\0pixel"; + clock-output-names = "dsi1_byte\0dsi1_ddr2\0dsi1_ddr"; + status = "disabled"; + power-domains = <0x12 0x12>; + phandle = <0x05>; + }; + + i2c@7e804000 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e804000 0x1000>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <0x16>; + clock-frequency = <0x186a0>; + phandle = <0x2f>; + }; + + vec@7e806000 { + compatible = "brcm,bcm2835-vec"; + reg = <0x7e806000 0x1000>; + clocks = <0x07 0x18>; + interrupts = <0x00 0x7b 0x04>; + status = "disabled"; + power-domains = <0x12 0x07>; + phandle = <0xac>; + }; + + usb@7e980000 { + compatible = "brcm,bcm2708-usb"; + reg = <0x7e980000 0x10000 0x7e00b200 0x200>; + interrupts = <0x00 0x49 0x04 0x00 0x28 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x17>; + clock-names = "otg"; + phys = <0x18>; + phy-names = "usb2-phy"; + power-domains = <0x12 0x06>; + interrupt-names = "usb\0soft"; + status = "disabled"; + phandle = <0xad>; + }; + + local_intc@40000000 { + compatible = "brcm,bcm2836-l1-intc"; + reg = <0x40000000 0x100>; + phandle = <0xae>; + }; + + avs-monitor@7d5d2000 { + compatible = "brcm,bcm2711-avs-monitor\0syscon\0simple-mfd"; + reg = <0x7d5d2000 0xf00>; + phandle = <0xaf>; + + thermal { + compatible = "brcm,bcm2711-thermal"; + #thermal-sensor-cells = <0x00>; + phandle = <0x02>; + }; + }; + + dma@7e007000 { + compatible = "brcm,bcm2835-dma"; + reg = <0x7e007000 0xb00>; + interrupts = <0x00 0x50 0x04 0x00 0x51 0x04 0x00 0x52 0x04 0x00 0x53 0x04 0x00 0x54 0x04 0x00 0x55 0x04 0x00 0x56 0x04 0x00 0x57 0x04 0x00 0x57 0x04 0x00 0x58 0x04 0x00 0x58 0x04>; + interrupt-names = "dma0\0dma1\0dma2\0dma3\0dma4\0dma5\0dma6\0dma7\0dma8\0dma9\0dma10"; + #dma-cells = <0x01>; + brcm,dma-channel-mask = <0x1f5>; + phandle = <0x0a>; + }; + + watchdog@7e100000 { + compatible = "brcm,bcm2835-pm\0brcm,bcm2835-pm-wdt"; + #power-domain-cells = <0x01>; + #reset-cells = <0x01>; + reg = <0x7e100000 0x114 0x7e00a000 0x24 0x7ec11000 0x20>; + clocks = <0x07 0x15 0x07 0x1d 0x07 0x17 0x07 0x16>; + clock-names = "v3d\0peri_image\0h264\0isp"; + system-power-controller; + phandle = <0x31>; + }; + + // serial@7e201400 { + // compatible = "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; + // reg = <0x7e201400 0x200>; + // interrupts = <0x00 0x79 0x04>; + // clocks = <0x07 0x13 0x07 0x14>; + // clock-names = "uartclk\0apb_pclk"; + // arm,primecell-periphid = <0x241011>; + // status = "disabled"; + // phandle = <0xb0>; + // }; + + // serial@7e201600 { + // compatible = "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; + // reg = <0x7e201600 0x200>; + // interrupts = <0x00 0x79 0x04>; + // clocks = <0x07 0x13 0x07 0x14>; + // clock-names = "uartclk\0apb_pclk"; + // arm,primecell-periphid = <0x241011>; + // status = "disabled"; + // phandle = <0xb1>; + // }; + + // serial@7e201800 { + // compatible = "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; + // reg = <0x7e201800 0x200>; + // interrupts = <0x00 0x79 0x04>; + // clocks = <0x07 0x13 0x07 0x14>; + // clock-names = "uartclk\0apb_pclk"; + // arm,primecell-periphid = <0x241011>; + // status = "disabled"; + // phandle = <0xb2>; + // }; + + // serial@7e201a00 { + // compatible = "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; + // reg = <0x7e201a00 0x200>; + // interrupts = <0x00 0x79 0x04>; + // clocks = <0x07 0x13 0x07 0x14>; + // clock-names = "uartclk\0apb_pclk"; + // arm,primecell-periphid = <0x241011>; + // status = "disabled"; + // phandle = <0xb3>; + // }; + + spi@7e204600 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204600 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb4>; + }; + + spi@7e204800 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204800 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb5>; + }; + + spi@7e204a00 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204a00 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb6>; + }; + + spi@7e204c00 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204c00 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb7>; + }; + + i2c@7e205600 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205600 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb8>; + }; + + i2c@7e205800 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205800 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb9>; + }; + + i2c@7e205a00 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205a00 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xba>; + }; + + i2c@7e205c00 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205c00 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xbb>; + }; + + pixelvalve@7e206000 { + compatible = "brcm,bcm2711-pixelvalve0"; + reg = <0x7e206000 0x100>; + interrupts = <0x00 0x6d 0x04>; + status = "disabled"; + phandle = <0xbc>; + }; + + pixelvalve@7e207000 { + compatible = "brcm,bcm2711-pixelvalve1"; + reg = <0x7e207000 0x100>; + interrupts = <0x00 0x6e 0x04>; + status = "disabled"; + phandle = <0xbd>; + }; + + pixelvalve@7e20a000 { + compatible = "brcm,bcm2711-pixelvalve2"; + reg = <0x7e20a000 0x100>; + interrupts = <0x00 0x65 0x04>; + status = "disabled"; + phandle = <0xbe>; + }; + + pwm@7e20c800 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c800 0x28>; + clocks = <0x07 0x1e>; + assigned-clocks = <0x07 0x1e>; + assigned-clock-rates = <0x989680>; + #pwm-cells = <0x02>; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <0x19 0x1a>; + phandle = <0xbf>; + }; + + pixelvalve@7e216000 { + compatible = "brcm,bcm2711-pixelvalve4"; + reg = <0x7e216000 0x100>; + interrupts = <0x00 0x6e 0x04>; + status = "disabled"; + phandle = <0xc0>; + }; + + pixelvalve@7ec12000 { + compatible = "brcm,bcm2711-pixelvalve3"; + reg = <0x7ec12000 0x100>; + interrupts = <0x00 0x6a 0x04>; + status = "disabled"; + phandle = <0xc1>; + }; + + clock@7ef00000 { + compatible = "brcm,brcm2711-dvp"; + reg = <0x7ef00000 0x10>; + clocks = <0x1b>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + phandle = <0x1c>; + }; + + hdmi@7ef00700 { + compatible = "brcm,bcm2711-hdmi0"; + reg = <0x7ef00700 0x300 0x7ef00300 0x200 0x7ef00f00 0x80 0x7ef00f80 0x80 0x7ef01b00 0x200 0x7ef01f00 0x400 0x7ef00200 0x80 0x7ef04300 0x100 0x7ef20000 0x100 0x7ef00100 0x30>; + reg-names = "hdmi\0dvp\0phy\0rm\0packet\0metadata\0csc\0cec\0hd\0intr2"; + clocks = <0x15 0x0d>; + clock-names = "hdmi"; + resets = <0x1c 0x00>; + ddc = <0x1d>; + dmas = <0x0a 0x0a>; + dma-names = "audio-rx"; + interrupts = <0x00 0x60 0x04>; + status = "disabled"; + phandle = <0xc2>; + }; + + i2c@7ef04500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef04500 0x100 0x7ef00b00 0x300>; + reg-names = "bsc\0auto-i2c"; + clock-frequency = <0x17cdc>; + status = "disabled"; + phandle = <0x1d>; + }; + + hdmi@7ef05700 { + compatible = "brcm,bcm2711-hdmi1"; + reg = <0x7ef05700 0x300 0x7ef05300 0x200 0x7ef05f00 0x80 0x7ef05f80 0x80 0x7ef06b00 0x200 0x7ef06f00 0x400 0x7ef00280 0x80 0x7ef09300 0x100 0x7ef20000 0x100 0x7ef00100 0x30>; + reg-names = "hdmi\0dvp\0phy\0rm\0packet\0metadata\0csc\0cec\0hd\0intr2"; + ddc = <0x1e>; + clocks = <0x15 0x0d>; + clock-names = "hdmi"; + resets = <0x1c 0x01>; + dmas = <0x0a 0x11>; + dma-names = "audio-rx"; + interrupts = <0x00 0x60 0x04>; + status = "disabled"; + phandle = <0xc3>; + }; + + i2c@7ef09500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef09500 0x100 0x7ef05b00 0x300>; + reg-names = "bsc\0auto-i2c"; + clock-frequency = <0x17cdc>; + status = "disabled"; + phandle = <0x1e>; + }; + + firmware { + compatible = "raspberrypi,bcm2835-firmware\0simple-bus"; + mboxes = <0x1f>; + dma-ranges; + phandle = <0x06>; + + gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; + #gpio-cells = <0x02>; + gpio-line-names = "BT_ON\0WL_ON\0PWR_LED_OFF\0GLOBAL_RESET\0VDD_SD_IO_SEL\0CAM_GPIO\0SD_PWR_ON\0SD_OC_N"; + status = "okay"; + phandle = <0x29>; + }; + }; + + power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <0x06>; + #power-domain-cells = <0x01>; + phandle = <0x12>; + }; + + // mailbox@7e00b840 { + // compatible = "brcm,bcm2711-vchiq"; + // reg = <0x7e00b840 0x3c>; + // interrupts = <0x00 0x22 0x04>; + // phandle = <0xc4>; + + // bcm2835_audio { + // compatible = "brcm,bcm2835-audio"; + // brcm,pwm-channels = <0x08>; + // status = "disabled"; + // pinctrl-names = "default"; + // pinctrl-0 = <0x20>; + // phandle = <0x30>; + // }; + // }; + + // mmc@7e300000 { + // compatible = "brcm,bcm2835-mmc\0brcm,bcm2835-sdhci"; + // reg = <0x7e300000 0x100>; + // interrupts = <0x00 0x7e 0x04>; + // clocks = <0x07 0x1c>; + // dmas = <0x0a 0x0b>; + // dma-names = "rx-tx"; + // brcm,overclock-50 = <0x00>; + // status = "disabled"; + // pinctrl-names = "default"; + // pinctrl-0 = <0x21>; + // bus-width = <0x04>; + // phandle = <0x34>; + // }; + + // mmcnr@7e300000 { + // compatible = "brcm,bcm2835-mmc\0brcm,bcm2835-sdhci"; + // reg = <0x7e300000 0x100>; + // interrupts = <0x00 0x7e 0x04>; + // clocks = <0x07 0x1c>; + // dmas = <0x0a 0x0b>; + // dma-names = "rx-tx"; + // brcm,overclock-50 = <0x00>; + // non-removable; + // status = "okay"; + // pinctrl-names = "default"; + // pinctrl-0 = <0x22>; + // bus-width = <0x04>; + // phandle = <0x35>; + // }; + + firmwarekms@7e600000 { + compatible = "raspberrypi,rpi-firmware-kms"; + reg = <0x7e600000 0x100>; + interrupts = <0x00 0x70 0x04>; + brcm,firmware = <0x06>; + status = "disabled"; + phandle = <0xc5>; + }; + + smi@7e600000 { + compatible = "brcm,bcm2835-smi"; + reg = <0x7e600000 0x100>; + interrupts = <0x00 0x70 0x04>; + clocks = <0x07 0x2a>; + assigned-clocks = <0x07 0x2a>; + assigned-clock-rates = <0x7735940>; + dmas = <0x0a 0x04>; + dma-names = "rx-tx"; + status = "disabled"; + phandle = <0xc6>; + }; + + csi@7e800000 { + compatible = "brcm,bcm2835-unicam"; + reg = <0x7e800000 0x800 0x7e802000 0x04>; + interrupts = <0x00 0x66 0x04>; + clocks = <0x07 0x2d>; + clock-names = "lp"; + power-domains = <0x12 0x0c>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + status = "disabled"; + phandle = <0xc7>; + }; + + csi@7e801000 { + compatible = "brcm,bcm2835-unicam"; + reg = <0x7e801000 0x800 0x7e802004 0x04>; + interrupts = <0x00 0x67 0x04>; + clocks = <0x07 0x2e>; + clock-names = "lp"; + power-domains = <0x12 0x0d>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + status = "disabled"; + phandle = <0xc8>; + + port { + + endpoint { + data-lanes = <0x01 0x02>; + }; + }; + }; + + axiperf { + compatible = "brcm,bcm2835-axiperf"; + reg = <0x7e009800 0x100 0x7ee08000 0x100>; + firmware = <0x06>; + status = "disabled"; + phandle = <0x36>; + }; + + gpiomem { + compatible = "brcm,bcm2835-gpiomem"; + reg = <0x7e200000 0x1000>; + }; + + fb { + compatible = "brcm,bcm2708-fb"; + firmware = <0x06>; + status = "okay"; + phandle = <0xc9>; + }; + + vcsm { + compatible = "raspberrypi,bcm2835-vcsm"; + firmware = <0x06>; + status = "okay"; + phandle = <0xca>; + }; + + sound { + status = "disabled"; + phandle = <0xcb>; + }; + }; + + clocks { + + clk-osc { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-output-names = "osc"; + clock-frequency = <0x337f980>; + phandle = <0x03>; + }; + + clk-usb { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-output-names = "otg"; + clock-frequency = <0x1c9c3800>; + phandle = <0x17>; + }; + }; + + phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0x00>; + phandle = <0x18>; + }; + + gpu { + compatible = "brcm,bcm2711-vc5"; + status = "disabled"; + phandle = <0xcc>; + }; + + clk-108M { + #clock-cells = <0x00>; + compatible = "fixed-clock"; + clock-frequency = <0x66ff300>; + clock-output-names = "108MHz-clock"; + phandle = <0x1b>; + }; + + firmware-clocks { + compatible = "raspberrypi,firmware-clocks"; + raspberrypi,firmware = <0x06>; + #clock-cells = <0x01>; + phandle = <0x15>; + }; + + //arm-pmu { + // compatible = "arm,cortex-a72-pmu\0arm,cortex-a15-pmu"; + // interrupts = <0x00 0x10 0x04 0x00 0x11 0x04 0x00 0x12 0x04 0x00 0x13 0x04>; + // interrupt-affinity = <0x23 0x24 0x25 0x26>; + //}; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf08 0x01 0x0e 0xf08 0x01 0x0b 0xf08 0x01 0x0a 0xf08>; + arm,cpu-registers-not-fw-configured; + }; + + cpus { + #address-cells = <0x01>; + #size-cells = <0x00>; + + cpu@0 { + reg = <0x0>; + compatible = "arm,cortex-a72"; + device_type = "cpu"; + enable-method = "psci"; + phandle = <0x23>; + }; + cpu@1 { + reg = <0x1>; + compatible = "arm,cortex-a72"; + device_type = "cpu"; + enable-method = "psci"; + phandle = <0x24>; + }; + cpu@2 { + reg = <0x2>; + compatible = "arm,cortex-a72"; + device_type = "cpu"; + enable-method = "psci"; + phandle = <0x25>; + }; + cpu@3 { + reg = <0x3>; + compatible = "arm,cortex-a72"; + device_type = "cpu"; + enable-method = "psci"; + phandle = <0x26>; + }; + }; + + scb { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x7c000000 0x00 0xfc000000 0x00 0x3800000 0x00 0x40000000 0x00 0xff800000 0x00 0x800000 0x06 0x00 0x06 0x00 0x00 0x40000000 0x00 0x00 0x00 0x00 0x00 0xfc000000>; + dma-ranges = <0x00 0x00 0x00 0x00 0x00 0xfc000000 0x01 0x00 0x01 0x00 0x01 0x00>; + phandle = <0xce>; + + pcie@7d500000 { + compatible = "brcm,bcm2711-pcie"; + reg = <0x00 0x7d500000 0x00 0x9310>; + device_type = "pci"; + #address-cells = <0x03>; + #interrupt-cells = <0x01>; + #size-cells = <0x02>; + interrupts = <0x00 0x94 0x04 0x00 0x94 0x04>; + interrupt-names = "pcie\0msi"; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x01 0x00 0x8f 0x04>; + msi-controller; + msi-parent = <0x27>; + ranges = <0x2000000 0x00 0xf8000000 0x06 0x00 0x00 0x4000000>; + dma-ranges = <0x2000000 0x00 0x00 0x00 0x00 0x00 0xc0000000>; + brcm,enable-ssc; + phandle = <0x27>; + }; + + ethernet@7d580000 { + compatible = "brcm,bcm2711-genet-v5\0brcm,genet-v5"; + reg = <0x00 0x7d580000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + interrupts = <0x00 0x9d 0x04 0x00 0x9e 0x04>; + status = "okay"; + phy-handle = <0x28>; + phy-mode = "rgmii-rxid"; + phandle = <0xcf>; + // printenv in u-boot and put ethaddr below + local-mac-address = [dc a6 32 74 0a 64]; + mdio@e14 { + compatible = "brcm,genet-mdio-v5"; + reg = <0xe14 0x08>; + reg-names = "mdio"; + #address-cells = <0x00>; + #size-cells = <0x01>; + phandle = <0xd0>; + + ethernet-phy@1 { + reg = <0x01>; + led-modes = <0x00 0x08>; + phandle = <0x28>; + }; + }; + }; + + dma@7e007b00 { + compatible = "brcm,bcm2711-dma"; + reg = <0x00 0x7e007b00 0x00 0x400>; + interrupts = <0x00 0x59 0x04 0x00 0x5a 0x04 0x00 0x5b 0x04 0x00 0x5c 0x04>; + interrupt-names = "dma11\0dma12\0dma13\0dma14"; + #dma-cells = <0x01>; + brcm,dma-channel-mask = <0x7000>; + phandle = <0x3a>; + }; + + xhci@7e9c0000 { + compatible = "generic-xhci"; + status = "disabled"; + reg = <0x00 0x7e9c0000 0x00 0x100000>; + interrupts = <0x00 0xb0 0x04>; + phandle = <0xd1>; + }; + + hevc-decoder@7eb00000 { + compatible = "raspberrypi,rpivid-hevc-decoder"; + reg = <0x00 0x7eb00000 0x00 0x10000>; + status = "okay"; + }; + + rpivid-local-intc@7eb10000 { + compatible = "raspberrypi,rpivid-local-intc"; + reg = <0x00 0x7eb10000 0x00 0x1000>; + status = "okay"; + interrupts = <0x00 0x62 0x04>; + }; + + h264-decoder@7eb20000 { + compatible = "raspberrypi,rpivid-h264-decoder"; + reg = <0x00 0x7eb20000 0x00 0x10000>; + status = "okay"; + }; + + vp9-decoder@7eb30000 { + compatible = "raspberrypi,rpivid-vp9-decoder"; + reg = <0x00 0x7eb30000 0x00 0x10000>; + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + phandle = <0xd2>; + + act { + label = "led0"; + default-state = "keep"; + linux,default-trigger = "mmc0"; + gpios = <0x0e 0x2a 0x00>; + phandle = <0x38>; + }; + + pwr { + label = "led1"; + gpios = <0x29 0x02 0x01>; + linux,default-trigger = "default-on"; + phandle = <0x39>; + }; + }; + + // memory@0 { + // device_type = "memory"; + // reg = <0x00 0x00 0x00>; + // }; + + // sd_io_1v8_reg { + // compatible = "regulator-gpio"; + // regulator-name = "vdd-sd-io"; + // regulator-min-microvolt = <0x1b7740>; + // regulator-max-microvolt = <0x325aa0>; + // regulator-boot-on; + // regulator-always-on; + // regulator-settling-time-us = <0x1388>; + // gpios = <0x29 0x04 0x00>; + // states = <0x1b7740 0x01 0x325aa0 0x00>; + // status = "okay"; + // phandle = <0x3b>; + // }; + + __overrides__ { + cam0-pwdn-ctrl; + cam0-pwdn; + cam0-led-ctrl; + cam0-led; + cache_line_size; + uart0 = "\0\0\0*status"; + uart1 = "\0\0\0+status"; + i2s = "\0\0\0,status"; + spi = "\0\0\0-status"; + i2c0 = [00 00 00 0f 73 74 61 74 75 73 00 00 00 00 2e 73 74 61 74 75 73 00]; + i2c1 = "\0\0\0/status"; + i2c0_baudrate = [00 00 00 0f 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00]; + i2c1_baudrate = "\0\0\0/clock-frequency:0"; + audio = "\0\0\00status"; + watchdog = "\0\0\01status"; + random = "\0\0\02status"; + // sd_overclock = "\0\0\03brcm,overclock-50:0"; + // sd_force_pio = "\0\0\03brcm,force-pio?"; + // sd_pio_limit = "\0\0\03brcm,pio-limit:0"; + // sd_debug = "\0\0\03brcm,debug"; + // sdio_overclock = "\0\0\04brcm,overclock-50:0\0\0\0\05brcm,overclock-50:0"; + axiperf = "\0\0\06status"; + arm_freq; + // sd_poll_once = "\0\0\07non-removable?"; + act_led_gpio = "\0\0\08gpios:4"; + act_led_activelow = "\0\0\08gpios:8"; + act_led_trigger = "\0\0\08linux,default-trigger"; + pwr_led_gpio = "\0\0\09gpios:4"; + pwr_led_activelow = "\0\0\09gpios:8"; + pwr_led_trigger = "\0\0\09linux,default-trigger"; + eth_led0 = "\0\0\0(led-modes:0"; + eth_led1 = "\0\0\0(led-modes:4"; + spi_dma4 = <0x2d 0x646d6173 0x3a303d00 0x3a 0x2d 0x646d6173 0x3a383d00 0x3a>; + }; + + fixedregulator_3v3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <0x325aa0>; + regulator-min-microvolt = <0x325aa0>; + regulator-name = "3v3"; + phandle = <0xd3>; + }; + + fixedregulator_5v0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <0x4c4b40>; + regulator-min-microvolt = <0x4c4b40>; + regulator-name = "5v0"; + phandle = <0xd4>; + }; + + v3dbus { + compatible = "simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x02>; + ranges = <0x7c500000 0x00 0xfc500000 0x00 0x3300000 0x40000000 0x00 0xff800000 0x00 0x800000>; + dma-ranges = <0x00 0x00 0x00 0x04 0x00>; + phandle = <0xd5>; + + v3d@7ec04000 { + compatible = "brcm,2711-v3d"; + reg = <0x7ec00000 0x00 0x4000 0x7ec04000 0x00 0x4000>; + reg-names = "hub\0core0"; + power-domains = <0x31 0x01>; + resets = <0x31 0x00>; + clocks = <0x15 0x05>; + clocks-names = "v3d"; + interrupts = <0x00 0x4a 0x04>; + status = "disabled"; + phandle = <0xd6>; + }; + }; + + // emmc2bus { + // compatible = "simple-bus"; + // #address-cells = <0x02>; + // #size-cells = <0x01>; + // ranges = <0x00 0x7e000000 0x00 0xfe000000 0x1800000>; + // dma-ranges = <0x00 0xc0000000 0x00 0x00 0x40000000>; + // phandle = <0xd7>; + + // emmc2@7e340000 { + // compatible = "brcm,bcm2711-emmc2"; + // status = "okay"; + // interrupts = <0x00 0x7e 0x04>; + // clocks = <0x07 0x33>; + // reg = <0x00 0x7e340000 0x100>; + // vqmmc-supply = <0x3b>; + // broken-cd; + // vmmc-supply = <0x3c>; + // phandle = <0x37>; + // }; + // }; + + // sd_vcc_reg { + // compatible = "regulator-fixed"; + // regulator-name = "vcc-sd"; + // regulator-min-microvolt = <0x325aa0>; + // regulator-max-microvolt = <0x325aa0>; + // regulator-boot-on; + // enable-active-high; + // gpio = <0x29 0x06 0x00>; + // phandle = <0x3c>; + // }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + status = "okay"; + }; + + interrupt-controller@40041000 { + interrupt-controller; + #interrupt-cells = <0x03>; + compatible = "arm,gic-400"; + reg = <0x00 0x40041000 0x00 0x1000 0x0 0x40042000 0x00 0x2000>; + phandle = <0x01>; + }; + + // __symbols__ { + // rmem = "/reserved-memory"; + // cma = "/reserved-memory/linux,cma"; + // cpu_thermal = "/thermal-zones/cpu-thermal"; + // soc = "/soc"; + // system_timer = "/soc/timer@7e003000"; + // txp = "/soc/txp@7e004000"; + // clocks = "/soc/cprman@7e101000"; + // random = "/soc/rng@7e104000"; + // mailbox = "/soc/mailbox@7e00b880"; + // gpio = "/soc/gpio@7e200000"; + // dpi_gpio0 = "/soc/gpio@7e200000/dpi_gpio0"; + // emmc_gpio22 = "/soc/gpio@7e200000/emmc_gpio22"; + // emmc_gpio34 = "/soc/gpio@7e200000/emmc_gpio34"; + // emmc_gpio48 = "/soc/gpio@7e200000/emmc_gpio48"; + // gpclk0_gpio4 = "/soc/gpio@7e200000/gpclk0_gpio4"; + // gpclk1_gpio5 = "/soc/gpio@7e200000/gpclk1_gpio5"; + // gpclk1_gpio42 = "/soc/gpio@7e200000/gpclk1_gpio42"; + // gpclk1_gpio44 = "/soc/gpio@7e200000/gpclk1_gpio44"; + // gpclk2_gpio6 = "/soc/gpio@7e200000/gpclk2_gpio6"; + // gpclk2_gpio43 = "/soc/gpio@7e200000/gpclk2_gpio43"; + // i2c0_gpio0 = "/soc/gpio@7e200000/i2c0_gpio0"; + // i2c0_gpio28 = "/soc/gpio@7e200000/i2c0_gpio28"; + // i2c0_gpio44 = "/soc/gpio@7e200000/i2c0_gpio44"; + // i2c1_gpio2 = "/soc/gpio@7e200000/i2c1_gpio2"; + // i2c1_gpio44 = "/soc/gpio@7e200000/i2c1_gpio44"; + // jtag_gpio22 = "/soc/gpio@7e200000/jtag_gpio22"; + // pcm_gpio18 = "/soc/gpio@7e200000/pcm_gpio18"; + // pcm_gpio28 = "/soc/gpio@7e200000/pcm_gpio28"; + // sdhost_gpio48 = "/soc/gpio@7e200000/sdhost_gpio48"; + // spi0_gpio7 = "/soc/gpio@7e200000/spi0_gpio7"; + // spi0_gpio35 = "/soc/gpio@7e200000/spi0_gpio35"; + // spi1_gpio16 = "/soc/gpio@7e200000/spi1_gpio16"; + // spi2_gpio40 = "/soc/gpio@7e200000/spi2_gpio40"; + // uart0_gpio14 = "/soc/gpio@7e200000/uart0_gpio14"; + // uart0_ctsrts_gpio16 = "/soc/gpio@7e200000/uart0_ctsrts_gpio16"; + // uart0_ctsrts_gpio30 = "/soc/gpio@7e200000/uart0_ctsrts_gpio30"; + // uart0_gpio32 = "/soc/gpio@7e200000/uart0_gpio32"; + // uart0_gpio36 = "/soc/gpio@7e200000/uart0_gpio36"; + // uart0_ctsrts_gpio38 = "/soc/gpio@7e200000/uart0_ctsrts_gpio38"; + // uart1_gpio14 = "/soc/gpio@7e200000/uart1_gpio14"; + // uart1_ctsrts_gpio16 = "/soc/gpio@7e200000/uart1_ctsrts_gpio16"; + // uart1_gpio32 = "/soc/gpio@7e200000/uart1_gpio32"; + // uart1_ctsrts_gpio30 = "/soc/gpio@7e200000/uart1_ctsrts_gpio30"; + // uart1_gpio40 = "/soc/gpio@7e200000/uart1_gpio40"; + // uart1_ctsrts_gpio42 = "/soc/gpio@7e200000/uart1_ctsrts_gpio42"; + // gpclk0_gpio49 = "/soc/gpio@7e200000/gpclk0_gpio49"; + // gpclk1_gpio50 = "/soc/gpio@7e200000/gpclk1_gpio50"; + // gpclk2_gpio51 = "/soc/gpio@7e200000/gpclk2_gpio51"; + // i2c0_gpio46 = "/soc/gpio@7e200000/i2c0_gpio46"; + // i2c1_gpio46 = "/soc/gpio@7e200000/i2c1_gpio46"; + // i2c3_gpio2 = "/soc/gpio@7e200000/i2c3_gpio2"; + // i2c3_gpio4 = "/soc/gpio@7e200000/i2c3_gpio4"; + // i2c4_gpio6 = "/soc/gpio@7e200000/i2c4_gpio6"; + // i2c4_gpio8 = "/soc/gpio@7e200000/i2c4_gpio8"; + // i2c5_gpio10 = "/soc/gpio@7e200000/i2c5_gpio10"; + // i2c5_gpio12 = "/soc/gpio@7e200000/i2c5_gpio12"; + // i2c6_gpio0 = "/soc/gpio@7e200000/i2c6_gpio0"; + // i2c6_gpio22 = "/soc/gpio@7e200000/i2c6_gpio22"; + // i2c_slave_gpio8 = "/soc/gpio@7e200000/i2c_slave_gpio8"; + // jtag_gpio48 = "/soc/gpio@7e200000/jtag_gpio48"; + // mii_gpio28 = "/soc/gpio@7e200000/mii_gpio28"; + // mii_gpio36 = "/soc/gpio@7e200000/mii_gpio36"; + // pcm_gpio50 = "/soc/gpio@7e200000/pcm_gpio50"; + // pwm0_0_gpio12 = "/soc/gpio@7e200000/pwm0_0_gpio12"; + // pwm0_0_gpio18 = "/soc/gpio@7e200000/pwm0_0_gpio18"; + // pwm1_0_gpio40 = "/soc/gpio@7e200000/pwm1_0_gpio40"; + // pwm0_1_gpio13 = "/soc/gpio@7e200000/pwm0_1_gpio13"; + // pwm0_1_gpio19 = "/soc/gpio@7e200000/pwm0_1_gpio19"; + // pwm1_1_gpio41 = "/soc/gpio@7e200000/pwm1_1_gpio41"; + // pwm0_1_gpio45 = "/soc/gpio@7e200000/pwm0_1_gpio45"; + // pwm0_0_gpio52 = "/soc/gpio@7e200000/pwm0_0_gpio52"; + // pwm0_1_gpio53 = "/soc/gpio@7e200000/pwm0_1_gpio53"; + // rgmii_gpio35 = "/soc/gpio@7e200000/rgmii_gpio35"; + // rgmii_irq_gpio34 = "/soc/gpio@7e200000/rgmii_irq_gpio34"; + // rgmii_irq_gpio39 = "/soc/gpio@7e200000/rgmii_irq_gpio39"; + // rgmii_mdio_gpio28 = "/soc/gpio@7e200000/rgmii_mdio_gpio28"; + // rgmii_mdio_gpio37 = "/soc/gpio@7e200000/rgmii_mdio_gpio37"; + // spi0_gpio46 = "/soc/gpio@7e200000/spi0_gpio46"; + // spi2_gpio46 = "/soc/gpio@7e200000/spi2_gpio46"; + // spi3_gpio0 = "/soc/gpio@7e200000/spi3_gpio0"; + // spi4_gpio4 = "/soc/gpio@7e200000/spi4_gpio4"; + // spi5_gpio12 = "/soc/gpio@7e200000/spi5_gpio12"; + // spi6_gpio18 = "/soc/gpio@7e200000/spi6_gpio18"; + // uart2_gpio0 = "/soc/gpio@7e200000/uart2_gpio0"; + // uart2_ctsrts_gpio2 = "/soc/gpio@7e200000/uart2_ctsrts_gpio2"; + // uart3_gpio4 = "/soc/gpio@7e200000/uart3_gpio4"; + // uart3_ctsrts_gpio6 = "/soc/gpio@7e200000/uart3_ctsrts_gpio6"; + // uart4_gpio8 = "/soc/gpio@7e200000/uart4_gpio8"; + // uart4_ctsrts_gpio10 = "/soc/gpio@7e200000/uart4_ctsrts_gpio10"; + // uart5_gpio12 = "/soc/gpio@7e200000/uart5_gpio12"; + // uart5_ctsrts_gpio14 = "/soc/gpio@7e200000/uart5_ctsrts_gpio14"; + // gpioout = "/soc/gpio@7e200000/gpioout"; + // alt0 = "/soc/gpio@7e200000/alt0"; + // dpi_18bit_gpio0 = "/soc/gpio@7e200000/dpi_18bit_gpio0"; + // spi0_pins = "/soc/gpio@7e200000/spi0_pins"; + // spi0_cs_pins = "/soc/gpio@7e200000/spi0_cs_pins"; + // spi3_pins = "/soc/gpio@7e200000/spi3_pins"; + // spi3_cs_pins = "/soc/gpio@7e200000/spi3_cs_pins"; + // spi4_pins = "/soc/gpio@7e200000/spi4_pins"; + // spi4_cs_pins = "/soc/gpio@7e200000/spi4_cs_pins"; + // spi5_pins = "/soc/gpio@7e200000/spi5_pins"; + // spi5_cs_pins = "/soc/gpio@7e200000/spi5_cs_pins"; + // spi6_pins = "/soc/gpio@7e200000/spi6_pins"; + // spi6_cs_pins = "/soc/gpio@7e200000/spi6_cs_pins"; + // i2c0_pins = "/soc/gpio@7e200000/i2c0"; + // i2c1_pins = "/soc/gpio@7e200000/i2c1"; + // i2c3_pins = "/soc/gpio@7e200000/i2c3"; + // i2c4_pins = "/soc/gpio@7e200000/i2c4"; + // i2c5_pins = "/soc/gpio@7e200000/i2c5"; + // i2c6_pins = "/soc/gpio@7e200000/i2c6"; + // i2s_pins = "/soc/gpio@7e200000/i2s"; + // sdio_pins = "/soc/gpio@7e200000/sdio_pins"; + // bt_pins = "/soc/gpio@7e200000/bt_pins"; + // uart0_pins = "/soc/gpio@7e200000/uart0_pins"; + // uart1_pins = "/soc/gpio@7e200000/uart1_pins"; + // uart2_pins = "/soc/gpio@7e200000/uart2_pins"; + // uart3_pins = "/soc/gpio@7e200000/uart3_pins"; + // uart4_pins = "/soc/gpio@7e200000/uart4_pins"; + // uart5_pins = "/soc/gpio@7e200000/uart5_pins"; + // audio_pins = "/soc/gpio@7e200000/audio_pins"; + // uart0 = "/soc/serial@7e201000"; + // sdhost = "/soc/mmc@7e202000"; + // i2s = "/soc/i2s@7e203000"; + // spi0 = "/soc/spi@7e204000"; + // spi = "/soc/spi@7e204000"; + // spidev0 = "/soc/spi@7e204000/spidev@0"; + // spidev1 = "/soc/spi@7e204000/spidev@1"; + // i2c0if = "/soc/i2c@7e205000"; + // i2c0mux = "/soc/i2c0mux"; + // i2c0 = "/soc/i2c0mux/i2c@0"; + // i2c_csi_dsi = "/soc/i2c0mux/i2c@1"; + // dpi = "/soc/dpi@7e208000"; + // dsi0 = "/soc/dsi@7e209000"; + // aux = "/soc/aux@7e215000"; + // uart1 = "/soc/serial@7e215040"; + // spi1 = "/soc/spi@7e215080"; + // spi2 = "/soc/spi@7e2150c0"; + // pwm = "/soc/pwm@7e20c000"; + // hvs = "/soc/hvs@7e400000"; + // dsi1 = "/soc/dsi@7e700000"; + // i2c1 = "/soc/i2c@7e804000"; + // vec = "/soc/vec@7e806000"; + // usb = "/soc/usb@7e980000"; + // local_intc = "/soc/local_intc@40000000"; + // gicv2 = "/soc/interrupt-controller@40041000"; + // avs_monitor = "/soc/avs-monitor@7d5d2000"; + // thermal = "/soc/avs-monitor@7d5d2000/thermal"; + // dma = "/soc/dma@7e007000"; + // watchdog = "/soc/watchdog@7e100000"; + // pm = "/soc/watchdog@7e100000"; + // uart2 = "/soc/serial@7e201400"; + // uart3 = "/soc/serial@7e201600"; + // uart4 = "/soc/serial@7e201800"; + // uart5 = "/soc/serial@7e201a00"; + // spi3 = "/soc/spi@7e204600"; + // spi4 = "/soc/spi@7e204800"; + // spi5 = "/soc/spi@7e204a00"; + // spi6 = "/soc/spi@7e204c00"; + // i2c3 = "/soc/i2c@7e205600"; + // i2c4 = "/soc/i2c@7e205800"; + // i2c5 = "/soc/i2c@7e205a00"; + // i2c6 = "/soc/i2c@7e205c00"; + // pixelvalve0 = "/soc/pixelvalve@7e206000"; + // pixelvalve1 = "/soc/pixelvalve@7e207000"; + // pixelvalve2 = "/soc/pixelvalve@7e20a000"; + // pwm1 = "/soc/pwm@7e20c800"; + // pixelvalve4 = "/soc/pixelvalve@7e216000"; + // pixelvalve3 = "/soc/pixelvalve@7ec12000"; + // dvp = "/soc/clock@7ef00000"; + // hdmi0 = "/soc/hdmi@7ef00700"; + // ddc0 = "/soc/i2c@7ef04500"; + // hdmi1 = "/soc/hdmi@7ef05700"; + // ddc1 = "/soc/i2c@7ef09500"; + // firmware = "/soc/firmware"; + // expgpio = "/soc/firmware/gpio"; + // power = "/soc/power"; + // vchiq = "/soc/mailbox@7e00b840"; + // audio = "/soc/mailbox@7e00b840/bcm2835_audio"; + // sdhci = "/soc/mmc@7e300000"; + // mmc = "/soc/mmc@7e300000"; + // mmcnr = "/soc/mmcnr@7e300000"; + // firmwarekms = "/soc/firmwarekms@7e600000"; + // smi = "/soc/smi@7e600000"; + // csi0 = "/soc/csi@7e800000"; + // csi1 = "/soc/csi@7e801000"; + // axiperf = "/soc/axiperf"; + // fb = "/soc/fb"; + // vcsm = "/soc/vcsm"; + // sound = "/soc/sound"; + // clk_osc = "/clocks/clk-osc"; + // clk_usb = "/clocks/clk-usb"; + // usbphy = "/phy"; + // vc4 = "/gpu"; + // clk_108MHz = "/clk-108M"; + // firmware_clocks = "/firmware-clocks"; + // cpus = "/cpus"; + // cpu0 = "/cpus/cpu@0"; + // cpu1 = "/cpus/cpu@1"; + // cpu2 = "/cpus/cpu@2"; + // cpu3 = "/cpus/cpu@3"; + // scb = "/scb"; + // pcie0 = "/scb/pcie@7d500000"; + // genet = "/scb/ethernet@7d580000"; + // genet_mdio = "/scb/ethernet@7d580000/mdio@e14"; + // phy1 = "/scb/ethernet@7d580000/mdio@e14/ethernet-phy@1"; + // dma40 = "/scb/dma@7e007b00"; + // xhci = "/scb/xhci@7e9c0000"; + // leds = "/leds"; + // act_led = "/leds/act"; + // pwr_led = "/leds/pwr"; + // sd_io_1v8_reg = "/sd_io_1v8_reg"; + // vdd_3v3_reg = "/fixedregulator_3v3"; + // vdd_5v0_reg = "/fixedregulator_5v0"; + // v3dbus = "/v3dbus"; + // v3d = "/v3dbus/v3d@7ec04000"; + // emmc2bus = "/emmc2bus"; + // emmc2 = "/emmc2bus/emmc2@7e340000"; + // sd_vcc_reg = "/sd_vcc_reg"; + // }; +}; diff --git a/dts/rust_car.dts b/dts/rust_car.dts new file mode 100644 index 0000000000000000000000000000000000000000..f7c3ba3a36ed3525cea7f337ed80c198063dc52b --- /dev/null +++ b/dts/rust_car.dts @@ -0,0 +1,17651 @@ +/dts-v1/; + +/ { + serial-number = "1422420073060"; + compatible = "nvidia,quill", "nvidia,p2597-0000+p3310-1000", "nvidia,tegra186"; + interrupt-parent = <0x1>; + #address-cells = <0x2>; + #size-cells = <0x2>; + model = "quill"; + nvidia,dtsfilename = "arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dts"; + nvidia,boardids = "3310:0000:A0"; + nvidia,proc-boardid = "3310:0000:A0"; + nvidia,fastboot-usb-vid = <0x955>; + nvidia,fastboot-usb-pid = <0xee16>; + nvidia,dtbbuildtime = "Apr 8 2021", "15:27:51"; + + vm_service { + interrupts = <0x0 0x20 0x1>; + compatible = "shyper"; + }; + + memory@90000000 { + reg = <0x0 0x90000000 0x0 0x60000000 0x0 0xf0200000 0x1 0x0>; + device_type = "memory"; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + status = "disabled"; + + a57_core_power_states { + compatible = "nvidia,tegra186-cpuidle-a57"; + linux,phandle = <0x176>; + phandle = <0x176>; + + c1 { + compatible = "nvidia,tegra186-cpuidle-a57"; + state-name = "Clock gated"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + power = <0x46>; + pmstate = <0x1>; + status = "okay"; + linux,phandle = <0x177>; + phandle = <0x177>; + }; + + c7 { + compatible = "nvidia,tegra186-cpuidle-a57"; + state-name = "Core powergate"; + wakeup-latency-us = <0x82>; + min-residency-us = <0xffffffff>; + power = <0x3c>; + pmstate = <0x7>; + arm,psci-suspend-param = <0x40000007>; + status = "okay"; + linux,phandle = <0xc>; + phandle = <0xc>; + }; + }; + + a57_cluster_power_states { + compatible = "nvidia,tegra186-cpuidle-a57-cluster"; + + cc1 { + state-name = "Cluster clock gated"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + power = <0x41>; + pmstate = <0x1>; + status = "okay"; + }; + + cc6 { + state-name = "Cluster powergate"; + wakeup-latency-us = <0x15e>; + min-residency-us = <0x1388>; + power = <0x13>; + pmstate = <0x6>; + status = "okay"; + }; + + cc7 { + state-name = "Cluster railgate"; + wakeup-latency-us = <0x50>; + min-residency-us = <0x320>; + power = <0x5>; + pmstate = <0x7>; + status = "disabled"; + }; + }; + + a57_crossover_thresholds { + compatible = "nvidia,tegra186-cpuidle-a57-thresholds"; + + thresholds { + crossover_cc1_cc6 = <0x1388>; + crossover_cc1_cc7 = <0x2bc>; + }; + }; + + denver_core_power_states { + compatible = "nvidia,tegra186-cpuidle-denver"; + linux,phandle = <0x178>; + phandle = <0x178>; + + c1 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Clock gated"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + power = <0x46>; + pmstate = <0x1>; + status = "okay"; + linux,phandle = <0x179>; + phandle = <0x179>; + }; + + c6 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Virtual core powergate"; + wakeup-latency-us = <0xbe>; + min-residency-us = <0xffffffff>; + power = <0x3c>; + pmstate = <0x6>; + arm,psci-suspend-param = <0x6>; + status = "okay"; + linux,phandle = <0x8>; + phandle = <0x8>; + }; + + c7 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Core powergate"; + wakeup-latency-us = <0x230>; + min-residency-us = <0xffffffff>; + power = <0x3c>; + pmstate = <0x7>; + arm,psci-suspend-param = <0x40000007>; + status = "okay"; + linux,phandle = <0x9>; + phandle = <0x9>; + }; + }; + + denver_cluster_power_states { + compatible = "nvidia,tegra186-cpuidle-denver-cluster"; + + cc1 { + state-name = "Cluster clock gated"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + power = <0x41>; + pmstate = <0x1>; + status = "okay"; + }; + + cc6 { + state-name = "Cluster powergate"; + wakeup-latency-us = <0x1c2>; + min-residency-us = <0x1388>; + power = <0x13>; + pmstate = <0x6>; + status = "okay"; + }; + + cc7 { + state-name = "Cluster railgate"; + wakeup-latency-us = <0x50>; + min-residency-us = <0x320>; + power = <0x5>; + pmstate = <0x7>; + status = "disabled"; + }; + }; + + denver_crossover_thresholds { + compatible = "nvidia,tegra186-cpuidle-denver-thresholds"; + + thresholds { + crossover_c1_c6 = <0x3e8>; + crossover_cc1_cc6 = <0x1388>; + crossover_cc1_cc7 = <0x4e20>; + }; + }; + + cpu-map { + + cluster0 { + }; + + cluster1 { + + core0 { + cpu = <0x4>; + }; + + core1 { + cpu = <0x5>; + }; + + core2 { + cpu = <0x6>; + }; + + core3 { + cpu = <0x7>; + }; + }; + }; + + cpu@0 { + device_type = "cpu"; + compatible = "nvidia,denver", "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + cpu-idle-states = <0x8 0x9>; + cpu-ipc = <0x400>; + next-level-cache = <0xa>; + capacity-dmips-mhz = <0x400>; + sched-energy-costs = <0xb 0xb>; + status = "NILL"; + linux,phandle = <0x2>; + phandle = <0x2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "nvidia,denver", "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + cpu-idle-states = <0x8 0x9>; + cpu-ipc = <0x400>; + next-level-cache = <0xa>; + capacity-dmips-mhz = <0x400>; + sched-energy-costs = <0xb 0xb>; + status = "NILL"; + linux,phandle = <0x3>; + phandle = <0x3>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + cpu-idle-states = <0xc>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + capacity-dmips-mhz = <0x2f0>; + sched-energy-costs = <0xe 0xe>; + status = "okay"; + linux,phandle = <0x4>; + phandle = <0x4>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + reg = <0x0 0x101>; + enable-method = "psci"; + cpu-idle-states = <0xc>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + capacity-dmips-mhz = <0x2f0>; + sched-energy-costs = <0xe 0xe>; + status = "okay"; + linux,phandle = <0x5>; + phandle = <0x5>; + }; + + cpu@4 { + device_type = "cpu"; + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + reg = <0x0 0x102>; + enable-method = "psci"; + cpu-idle-states = <0xc>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + capacity-dmips-mhz = <0x2f0>; + sched-energy-costs = <0xe 0xe>; + status = "okay"; + linux,phandle = <0x6>; + phandle = <0x6>; + }; + + cpu@5 { + device_type = "cpu"; + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + reg = <0x0 0x103>; + enable-method = "psci"; + cpu-idle-states = <0xc>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + capacity-dmips-mhz = <0x2f0>; + sched-energy-costs = <0xe 0xe>; + status = "okay"; + linux,phandle = <0x7>; + phandle = <0x7>; + }; + + l2-cache0 { + compatible = "cache"; + cache-unified; + cache-level = <0x2>; + linux,phandle = <0xd>; + phandle = <0xd>; + }; + + l2-cache1 { + compatible = "cache"; + cache-unified; + cache-level = <0x2>; + linux,phandle = <0xa>; + phandle = <0xa>; + }; + }; + + arm-pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0x0 0x140 0x4 0x0 0x141 0x4 0x0 0x128 0x4 0x0 0x129 0x4 0x0 0x12a 0x4 0x0 0x12b 0x4>; + interrupt-affinity = <0x2 0x3 0x4 0x5 0x6 0x7>; + }; + + denver-pmu { + compatible = "nvidia,denver15-pmu"; + interrupts = <0x0 0x122 0x4>; + interrupt-affinity = <0x2>; + }; + + energy-costs { + + core-cost0 { + busy-cost-data = <0x400 0x400>; + idle-cost-data = <0x80>; + linux,phandle = <0xb>; + phandle = <0xb>; + }; + + core-cost1 { + busy-cost-data = <0x2f0 0x400>; + idle-cost-data = <0x80>; + linux,phandle = <0xe>; + phandle = <0xe>; + }; + }; + + pmc@c360000 { + compatible = "nvidia,tegra186-pmc"; + reg = <0x0 0xc360000 0x0 0x400 0x0 0xc390000 0x0 0x2fff>; + #padcontroller-cells = <0x1>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xf>; + nvidia,restrict-voltage-switch; + linux,phandle = <0xb3>; + phandle = <0xb3>; + + sdmmc1_e_33V_enable { + linux,phandle = <0x19>; + phandle = <0x19>; + + sdmmc1 { + pins = "sdmmc1-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + sdmmc1_e_33V_disable { + linux,phandle = <0x1a>; + phandle = <0x1a>; + + sdmmc1 { + pins = "sdmmc1-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + sdmmc2_e_33V_enable { + linux,phandle = <0x17>; + phandle = <0x17>; + + sdmmc2 { + pins = "sdmmc2-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + sdmmc2_e_33V_disable { + linux,phandle = <0x18>; + phandle = <0x18>; + + sdmmc2 { + pins = "sdmmc2-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + sdmmc3_e_33V_enable { + linux,phandle = <0x14>; + phandle = <0x14>; + + sdmmc3 { + pins = "sdmmc3-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + sdmmc3_e_33V_disable { + linux,phandle = <0x15>; + phandle = <0x15>; + + sdmmc3 { + pins = "sdmmc3-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + dpd-enable { + linux,phandle = <0x23>; + phandle = <0x23>; + + ufs { + pins = "ufs"; + low-power-enable; + }; + }; + + dpd-disable { + linux,phandle = <0x24>; + phandle = <0x24>; + + ufs { + pins = "ufs"; + low-power-disable; + }; + }; + + iopad-defaults { + linux,phandle = <0xf>; + phandle = <0xf>; + + sdmmc-io-pads { + pins = "sdmmc1-hv", "sdmmc2-hv", "sdmmc3-hv"; + nvidia,enable-voltage-switching; + }; + }; + + hdmi-dp0-dpd-enable { + linux,phandle = <0x7d>; + phandle = <0x7d>; + + hdmi-dp0-pad-lowpower-enable { + pins = "hdmi-dp0"; + low-power-enable; + }; + }; + + hdmi-dp0-dpd-disable { + linux,phandle = <0x7c>; + phandle = <0x7c>; + + hdmi-dp0-pad-lowpower-disable { + pins = "hdmi-dp0"; + low-power-disable; + }; + }; + + hdmi-dp1-dpd-enable { + linux,phandle = <0x7f>; + phandle = <0x7f>; + + hdmi-dp1-pad-lowpower-enable { + pins = "hdmi-dp1"; + low-power-enable; + }; + }; + + hdmi-dp1-dpd-disable { + linux,phandle = <0x7e>; + phandle = <0x7e>; + + hdmi-dp1-pad-lowpower-disable { + pins = "hdmi-dp1"; + low-power-disable; + }; + }; + + dsi-dpd-enable { + linux,phandle = <0x75>; + phandle = <0x75>; + + dsi-pad-lowpower-enable { + pins = "dsi"; + low-power-enable; + }; + }; + + dsi-dpd-disable { + linux,phandle = <0x74>; + phandle = <0x74>; + + dsi-pad-lowpower-disable { + pins = "dsi"; + low-power-disable; + }; + }; + + dsib-dpd-enable { + linux,phandle = <0x77>; + phandle = <0x77>; + + dsib-pad-lowpower-enable { + pins = "dsib"; + low-power-enable; + }; + }; + + dsib-dpd-disable { + linux,phandle = <0x76>; + phandle = <0x76>; + + dsib-pad-lowpower-disable { + pins = "dsib"; + low-power-disable; + }; + }; + + dsic-dpd-enable { + linux,phandle = <0x79>; + phandle = <0x79>; + + dsic-pad-lowpower-enable { + pins = "dsic"; + low-power-enable; + }; + }; + + dsic-dpd-disable { + linux,phandle = <0x78>; + phandle = <0x78>; + + dsic-pad-lowpower-disable { + pins = "dsic"; + low-power-disable; + }; + }; + + dsid-dpd-enable { + linux,phandle = <0x7b>; + phandle = <0x7b>; + + dsid-pad-lowpower-enable { + pins = "dsid"; + low-power-enable; + }; + }; + + dsid-dpd-disable { + linux,phandle = <0x7a>; + phandle = <0x7a>; + + dsidpad-lowpower-disable { + pins = "dsid"; + low-power-disable; + }; + }; + }; + + aliases { + sdhci0 = "/sdhci@3400000"; + sdhci1 = "/sdhci@3420000"; + sdhci2 = "/sdhci@3440000"; + sdhci3 = "/sdhci@3460000"; + i2c0 = "/i2c@3160000"; + i2c1 = "/i2c@c240000"; + i2c2 = "/i2c@3180000"; + i2c3 = "/i2c@3190000"; + i2c4 = "/bpmp_i2c"; + i2c5 = "/i2c@31b0000"; + i2c6 = "/i2c@31c0000"; + i2c7 = "/i2c@c250000"; + i2c8 = "/i2c@31e0000"; + spi0 = "/spi@3210000"; + spi1 = "/spi@c260000"; + spi2 = "/spi@3230000"; + spi3 = "/spi@3240000"; + spi4 = "/aon_spi@c260000"; + spi6 = "/spi@3270000"; + tegra-camera-rtcpu = "/rtcpu@b000000"; + serial0 = "/serial@3100000"; + serial1 = "/serial@3110000"; + serial2 = "/serial@c280000"; + serial3 = "/serial@3130000"; + serial4 = "/serial@3140000"; + serial5 = "/serial@3150000"; + serial6 = "/serial@c290000"; + rtc1 = "/rtc@c2a0000"; + rtc0 = "/bpmp_i2c/spmic@3c"; + }; + + sdhci@3460000 { + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x3460000 0x0 0x210>; + interrupts = <0x0 0x41 0x4>; + max-clk-limit = <0xbb288cc>; + ddr-clk-limit = <0x2dc6c00>; + nvidia,clk-en-before-freq-update; + tap-delay = <0x9>; + trim-delay = <0x5>; + nvidia,ddr-tap-delay = <0x9>; + ddr-trim-delay = <0x5>; + mmc-ocr-mask = <0x0>; + bus-width = <0x8>; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + cap-mmc-highspeed; + cap-sd-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + only-1-8-v; + compad-vref-3v3 = <0x7>; + compad-vref-1v8 = <0x7>; + nvidia,min-tap-delay = <0x54>; + nvidia,max-tap-delay = <0x88>; + nvidia,is-emmc; + nvidia,set-parent-clk; + calib-3v3-offsets = <0x505>; + calib-1v8-offsets = <0x505>; + nvidia,parent_clk_list = "pll_p", "pll_p", "pll_p", "pll_p", "pll_p", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0"; + pll_source = "pll_p", "pll_c4_out0"; + resets = <0x10 0x24>; + reset-names = "sdhci"; + clocks = <0x10 0x36 0x10 0x10d 0x10 0x114 0x10 0x80>; + clock-names = "sdmmc", "pll_p", "pll_c4_out0", "sdmmc_legacy_tm"; + iommus = <0x11 0x17>; + status = "NILL"; + uhs-mask = <0x0>; + nvidia,enable-strobe-mode; + nvidia,en-periodic-cflush; + nvidia,periodic-cflush-to = <0x64>; + nvidia,enable-hwcq; + mmc-hs400-enhanced-strobe; + vqmmc-supply = <0x12>; + vmmc-supply = <0x13>; + linux,phandle = <0x101>; + phandle = <0x101>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_ds { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x5090000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000505>; + }; + + prod_c_hs400 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x10c 0x3f00 0x3f00 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000505>; + }; + + prod_c_hs533 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x2000 0x1e0 0xf 0x7 0x1e4 0x20000000 0x20000505>; + }; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x10c 0x3f00 0x3f00 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + }; + }; + + sdhci@3440000 { + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x3440000 0x0 0x210>; + interrupts = <0x0 0x40 0x4>; + max-clk-limit = <0xc28cb00>; + ddr-clk-limit = <0x2dc6c00>; + tap-delay = <0xb>; + trim-delay = <0x5>; + nvidia,ddr-tap-delay = <0xb>; + ddr-trim-delay = <0x5>; + bus-width = <0x4>; + ignore-pm-notify; + mmc-ocr-mask = <0x0>; + keep-power-in-suspend; + non-removable; + cap-mmc-highspeed; + cap-sd-highspeed; + pwrdet-support; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + pinctrl-0 = <0x14>; + pinctrl-1 = <0x15>; + compad-vref-3v3 = <0x1>; + compad-vref-1v8 = <0x2>; + nvidia,min-tap-delay = <0x54>; + nvidia,max-tap-delay = <0x88>; + pll_source = "pll_p"; + resets = <0x10 0x23>; + reset-names = "sdhci"; + clocks = <0x10 0x4c 0x10 0x10d 0x10 0x80>; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + nvidia,en-periodic-calib; + force-non-removable-rescan; + status = "okay"; + uhs-mask = <0x8>; + only-1-8-v; + vqmmc-supply = <0x16>; + vmmc-supply = <0x12>; + linux,phandle = <0xf9>; + phandle = <0xf9>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_ds { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr12 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr25 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20006a76>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x50b0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + }; + }; + + sdhci@3420000 { + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x3420000 0x0 0x210>; + interrupts = <0x0 0x3f 0x4>; + max-clk-limit = <0xbebc200>; + ddr-clk-limit = <0x2dc6c00>; + tap-delay = <0xb>; + trim-delay = <0x5>; + nvidia,ddr-tap-delay = <0xb>; + ddr-trim-delay = <0x5>; + mmc-ocr-mask = <0x0>; + bus-width = <0x8>; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + cap-mmc-highspeed; + cap-sd-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + pwrdet-support; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + pinctrl-0 = <0x17>; + pinctrl-1 = <0x18>; + compad-vref-3v3 = <0x1>; + compad-vref-1v8 = <0x2>; + nvidia,is-emmc; + nvidia,min-tap-delay = <0x54>; + nvidia,max-tap-delay = <0x88>; + pll_source = "pll_p"; + resets = <0x10 0x22>; + reset-names = "sdhci"; + clocks = <0x10 0x35 0x10 0x10d 0x10 0x80>; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + iommus = <0x11 0x19>; + status = "disabled"; + vqmmc-supply = <0x12>; + vmmc-supply = <0x13>; + linux,phandle = <0x17a>; + phandle = <0x17a>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_ds { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x5090000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs400 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod { + prod = <0x100 0x1fff002e 0x50b0028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + }; + }; + + sdhci@3400000 { + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x3400000 0x0 0x210>; + interrupts = <0x0 0x3e 0x4>; + max-clk-limit = <0xc28cb00>; + ddr-clk-limit = <0x2dc6c00>; + tap-delay = <0xb>; + trim-delay = <0x5>; + nvidia,ddr-tap-delay = <0xb>; + ddr-trim-delay = <0x5>; + mmc-ocr-mask = <0x3>; + bus-width = <0x4>; + ignore-pm-notify; + keep-power-in-suspend; + cap-mmc-highspeed; + cap-sd-highspeed; + pwrdet-support; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + pinctrl-0 = <0x19>; + pinctrl-1 = <0x1a>; + compad-vref-3v3 = <0x1>; + compad-vref-1v8 = <0x2>; + nvidia,min-tap-delay = <0x54>; + nvidia,max-tap-delay = <0x88>; + pll_source = "pll_p"; + resets = <0x10 0x21>; + reset-names = "sdhci"; + clocks = <0x10 0x34 0x10 0x10d 0x10 0x80>; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + iommus = <0x11 0x1a>; + nvidia,en-periodic-calib; + status = "okay"; + cd-gpios = <0x1b 0x7d 0x0>; + wp-gpios = <0x1b 0x7c 0x0>; + cd-inverted; + wp-inverted; + uhs-mask = <0x8>; + vqmmc-supply = <0x1c>; + vmmc-supply = <0x1d>; + nvidia,cd-wakeup-capable; + linux,phandle = <0x100>; + phandle = <0x100>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_ds { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr12 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr25 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000503>; + }; + + prod_c_ddr52 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + }; + }; + + pinmux@2430000 { + compatible = "nvidia,tegra186-pinmux"; + reg = <0x0 0x2430000 0x0 0x15000 0x0 0xc300000 0x0 0x4000>; + #gpio-range-cells = <0x3>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x1e>; + linux,phandle = <0xb7>; + phandle = <0xb7>; + + devslp_active { + linux,phandle = <0x20>; + phandle = <0x20>; + + sata { + nvidia,pins = "pex_l2_clkreq_n_pa6"; + nvidia,function = "sata"; + nvidia,pull = <0x0>; + nvidia,enable-input = <0x0>; + nvidia,io-high-voltage = <0x1>; + nvidia,lpdr = <0x1>; + }; + }; + + devslp_pullup { + linux,phandle = <0x21>; + phandle = <0x21>; + + sata { + nvidia,pins = "pex_l2_clkreq_n_pa6"; + nvidia,function = "sata"; + nvidia,pull = <0x2>; + }; + }; + + eqos_idle { + linux,phandle = <0x42>; + phandle = <0x42>; + + eqos { + nvidia,pins = "eqos_td3_pe4", "eqos_td2_pe3", "eqos_td1_pe2", "eqos_td0_pe1", "eqos_txc_pe0", "eqos_tx_ctl_pe5"; + nvidia,tristate = <0x1>; + }; + }; + + eqos_default { + linux,phandle = <0x43>; + phandle = <0x43>; + + eqos { + nvidia,pins = "eqos_td3_pe4", "eqos_td2_pe3", "eqos_td1_pe2", "eqos_td0_pe1", "eqos_txc_pe0", "eqos_tx_ctl_pe5"; + nvidia,tristate = <0x0>; + }; + }; + + vbus_en0_oc_tristate { + linux,phandle = <0xa4>; + phandle = <0xa4>; + + usb_vbus_en0_pl4 { + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,function = "usb"; + nvidia,tristate = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,enable-input = <0x1>; + }; + }; + + vbus_en1_oc_tristate { + linux,phandle = <0xa5>; + phandle = <0xa5>; + + usb_vbus_en1_pl5 { + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,function = "usb"; + nvidia,tristate = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,enable-input = <0x1>; + }; + }; + + vbus_en0_oc_passthrough { + linux,phandle = <0xa6>; + phandle = <0xa6>; + + usb_vbus_en0_pl4 { + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,function = "usb"; + nvidia,tristate = <0x0>; + nvidia,io-high-voltage = <0x1>; + nvidia,enable-input = <0x1>; + }; + }; + + vbus_en1_oc_passthrough { + linux,phandle = <0xa7>; + phandle = <0xa7>; + + usb_vbus_en1_pl5 { + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,function = "usb"; + nvidia,tristate = <0x0>; + nvidia,io-high-voltage = <0x1>; + nvidia,enable-input = <0x1>; + }; + }; + + vbus_en0_default { + linux,phandle = <0xa2>; + phandle = <0xa2>; + + usb_vbus_en0_pl4 { + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,function = "rsvd1"; + nvidia,io-high-voltage = <0x1>; + nvidia,enable-input = <0x1>; + }; + }; + + vbus_en1_default { + linux,phandle = <0xa3>; + phandle = <0xa3>; + + usb_vbus_en1_pl5 { + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,function = "rsvd1"; + nvidia,io-high-voltage = <0x1>; + nvidia,enable-input = <0x1>; + }; + }; + + common { + linux,phandle = <0x1e>; + phandle = <0x1e>; + + gpio_edp2_pp5 { + nvidia,pins = "gpio_edp2_pp5"; + nvidia,pull = <0x2>; + nvidia,tristate = <0x1>; + nvidia,enable-input = <0x1>; + status = "okay"; + }; + + gpio_edp3_pp6 { + nvidia,pins = "gpio_edp3_pp6"; + nvidia,pull = <0x0>; + nvidia,tristate = <0x0>; + nvidia,enable-input = <0x0>; + status = "okay"; + }; + }; + }; + + ahci-sata@3507000 { + compatible = "nvidia,tegra186-ahci-sata"; + reg = <0x0 0x3507000 0x0 0x2000 0x0 0x3501000 0x0 0x6000 0x0 0x3500000 0x0 0x1000 0x0 0x3a90000 0x0 0x10000>; + reg-names = "sata-ahci", "sata-config", "sata-ipfs", "sata-aux"; + interrupts = <0x0 0xc5 0x4>; + iommus = <0x11 0x1d>; + iommu_sodev_map; + power-domains = <0x1f 0xa>; + clocks = <0x10 0x63 0x10 0x64 0x10 0x204 0x10 0x10d>; + clock-names = "sata", "sata-oob", "pllp", "pllp-uphy"; + resets = <0x10 0x1f 0x10 0x20>; + reset-names = "sata", "sata-cold"; + pinctrl-names = "devslp_active", "devslp_pullup"; + pinctrl-0 = <0x20>; + pinctrl-1 = <0x21>; + nvidia,disable-features = "devslp", "dipm"; + nvidia,link-flags = "min_power"; + status = "okay"; + gpios = <0x22 0x7 0x0>; + linux,phandle = <0x105>; + phandle = <0x105>; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x52c 0xffffffff 0x31ce0 0x1 0x338 0x10000000 0x10000000>; + }; + }; + }; + + ufshci@2450000 { + compatible = "tegra,ufs_variant"; + reg = <0x0 0x2450000 0x0 0x4000>; + interrupts = <0x0 0x2c 0x4>; + iommus = <0x11 0x15>; + clocks = <0x10 0x94 0x10 0x8e 0x10 0x93 0x10 0x90 0x10 0x8c 0x10 0x8f 0x10 0x8d 0x10 0x91 0x10 0x27a 0x10 0xb2 0x10 0xb3 0x10 0x10d 0x10 0x261>; + clock-names = "mphy_core_pll_fixed", "mphy_l0_tx_symb", "mphy_tx_1mhz_ref", "mphy_l0_rx_ana", "mphy_l0_rx_symb", "mphy_l0_tx_ls_3xbit", "mphy_l0_rx_ls_bit", "mphy_l1_rx_ana", "mphy_force_ls_mode", "ufshc", "ufsdev_ref", "pll_p", "clk_m"; + resets = <0x10 0x56 0x10 0x57 0x10 0x94 0x10 0x95 0x10 0x93 0x10 0x71 0x10 0x72 0x10 0xc0>; + reset-names = "mphy-l0-rx-rst", "mphy-l0-tx-rst", "mphy-l1-rx-rst", "mphy-l1-tx-rst", "mphy-clk-ctl-rst", "ufs-rst", "ufs-axi-m-rst", "ufshc-lp-rst"; + nvidia,enable-x2-config; + nvidia,enable-rx-calib; + nvidia,enable-hs-mode; + nvidia,enable-wlu-scsi-device-add; + nvidia,mask-fast-auto-mode; + nvidia,enable-hibern8-war; + nvidia,max-hs-gear = <0x3>; + nvidia,max-pwm-gear = <0x4>; + vcc-max-microamp = <0x0>; + vccq-max-microamp = <0x0>; + vccq2-max-microamp = <0x0>; + pinctrl-names = "ufs_dpd_enable", "ufs_dpd_disable"; + pinctrl-0 = <0x23>; + pinctrl-1 = <0x24>; + status = "disabled"; + linux,phandle = <0x104>; + phandle = <0x104>; + + ufs_variant { + compatible = "tegra,ufs_variant"; + }; + }; + + i2c@3160000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0x3160000 0x0 0x100>; + interrupts = <0x0 0x19 0x4>; + scl-gpio = <0x1b 0x15 0x0>; + sda-gpio = <0x1b 0x16 0x0>; + status = "okay"; + clock-frequency = <0x61a80>; + clocks = <0x10 0x2f 0x10 0x10d 0x10 0x5c>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x13>; + reset-names = "i2c"; + dmas = <0x25 0x15 0x25 0x15>; + dma-names = "rx", "tx"; + linux,phandle = <0x106>; + phandle = <0x106>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + status = "disabled"; + disable-on-kernel-charging; + compatible = "ti,lp8557"; + reg = <0x2c>; + power-supply = <0x26>; + bl-name = "pwm-backlight"; + init-brt = [ff]; + dev-ctrl = [80]; + pwm-period = <0x9ce1>; + pwm-names = "lp8557"; + pwms = <0x27 0x0 0x9ce1>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + bl-curve = <0x0 0x1 0x1 0x2 0x2 0x3 0x3 0x4 0x4 0x5 0x5 0x6 0x7 0x7 0x8 0x8 0x9 0x9 0xa 0xa 0xb 0xb 0xc 0xc 0xd 0xe 0xe 0xf 0xf 0x10 0x10 0x11 0x11 0x12 0x12 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x18 0x18 0x19 0x19 0x1a 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1e 0x1e 0x1f 0x1f 0x20 0x21 0x21 0x22 0x22 0x23 0x23 0x24 0x24 0x25 0x25 0x26 0x26 0x27 0x28 0x28 0x29 0x29 0x2a 0x2a 0x2b 0x2b 0x2c 0x2c 0x2d 0x2e 0x2e 0x2f 0x2f 0x30 0x30 0x31 0x31 0x32 0x32 0x33 0x34 0x34 0x35 0x35 0x36 0x36 0x37 0x37 0x38 0x38 0x39 0x39 0x3a 0x3b 0x3b 0x3c 0x3c 0x3d 0x3d 0x3e 0x3e 0x3f 0x3f 0x40 0x41 0x41 0x42 0x42 0x43 0x43 0x44 0x44 0x45 0x45 0x46 0x46 0x47 0x48 0x48 0x49 0x49 0x4a 0x4a 0x4b 0x4b 0x4c 0x4c 0x4d 0x4e 0x4e 0x4f 0x4f 0x50 0x50 0x51 0x51 0x52 0x52 0x53 0x53 0x54 0x55 0x55 0x56 0x56 0x57 0x57 0x58 0x58 0x59 0x59 0x5a 0x5c 0x5e 0x60 0x61 0x63 0x65 0x67 0x69 0x6b 0x6d 0x6e 0x70 0x72 0x74 0x76 0x78 0x7a 0x7b 0x7d 0x7f 0x81 0x83 0x85 0x86 0x88 0x8a 0x8c 0x8e 0x90 0x92 0x93 0x95 0x97 0x99 0x9b 0x9d 0x9f 0xa0 0xa2 0xa4 0xa6 0xa8 0xaa 0xac 0xad 0xaf 0xb1 0xb3 0xb5 0xb7 0xb9 0xba 0xbc 0xbe 0xc0 0xc2 0xc4 0xc6 0xc7 0xc9 0xcb 0xcd 0xcf 0xd1 0xd3 0xd4 0xd6 0xd8 0xda 0xdc 0xde 0xdf 0xe1 0xe3 0xe5 0xe7 0xe9 0xeb 0xec 0xee 0xf0 0xf2 0xf4 0xf6 0xf8 0xf9 0xfb 0xfd 0xff>; + linux,phandle = <0xf3>; + phandle = <0xf3>; + + rom_14h { + rom-addr = [14]; + rom-val = [9f]; + }; + + rom_13h { + rom-addr = [13]; + rom-val = [01]; + }; + + rom_11h { + rom-addr = [11]; + rom-val = [05]; + }; + }; + + ina3221x@40 { + compatible = "ti,ina3221x"; + reg = <0x40>; + ti,trigger-config = <0x7003>; + ti,continuous-config = <0x7c07>; + ti,enable-forced-continuous; + #address-cells = <0x1>; + #size-cells = <0x0>; + #io-channel-cells = <0x1>; + linux,phandle = <0xf0>; + phandle = <0xf0>; + + channel@0 { + reg = <0x0>; + ti,rail-name = "VDD_SYS_GPU"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@1 { + reg = <0x1>; + ti,rail-name = "VDD_SYS_SOC"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@2 { + reg = <0x2>; + ti,rail-name = "VDD_4V0_WIFI"; + ti,shunt-resistor-mohm = <0xa>; + }; + }; + + ina3221x@41 { + compatible = "ti,ina3221x"; + reg = <0x41>; + ti,trigger-config = <0x7003>; + ti,continuous-config = <0x7c07>; + ti,enable-forced-continuous; + #address-cells = <0x1>; + #size-cells = <0x0>; + #io-channel-cells = <0x1>; + linux,phandle = <0xf1>; + phandle = <0xf1>; + + channel@0 { + reg = <0x0>; + ti,rail-name = "VDD_IN"; + ti,shunt-resistor-mohm = <0x14>; + }; + + channel@1 { + reg = <0x1>; + ti,rail-name = "VDD_SYS_CPU"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@2 { + reg = <0x2>; + ti,rail-name = "VDD_SYS_DDR"; + ti,shunt-resistor-mohm = <0xa>; + }; + }; + + ina3221x@42 { + compatible = "ti,ina3221x"; + reg = <0x42>; + ti,trigger-config = <0x7003>; + ti,continuous-config = <0x7c07>; + ti,enable-forced-continuous; + #address-cells = <0x1>; + #size-cells = <0x0>; + + channel@0 { + reg = <0x0>; + ti,rail-name = "VDD_MUX"; + ti,shunt-resistor-mohm = <0x14>; + }; + + channel@1 { + reg = <0x1>; + ti,rail-name = "VDD_5V0_IO_SYS"; + ti,shunt-resistor-mohm = <0x5>; + }; + + channel@2 { + reg = <0x2>; + ti,rail-name = "VDD_3V3_SYS"; + ti,shunt-resistor-mohm = <0xa>; + }; + }; + + ina3221x@43 { + compatible = "ti,ina3221x"; + reg = <0x43>; + ti,trigger-config = <0x7003>; + ti,continuous-config = <0x7c07>; + ti,enable-forced-continuous; + #address-cells = <0x1>; + #size-cells = <0x0>; + + channel@0 { + reg = <0x0>; + ti,rail-name = "VDD_3V3_IO_SLP"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@1 { + reg = <0x1>; + ti,rail-name = "VDD_1V8_IO"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@2 { + reg = <0x2>; + ti,rail-name = "VDD_3V3_SYS_M2"; + ti,shunt-resistor-mohm = <0xa>; + }; + }; + + gpio@74 { + compatible = "ti,tca9539"; + reg = <0x74>; + gpio-controller; + #gpio-cells = <0x2>; + vcc-supply = <0x26>; + linux,phandle = <0xe9>; + phandle = <0xe9>; + + touch-rails { + gpio-hog; + gpios = <0x1 0x0 0x2 0x0>; + output-high; + label = "touch-rail-1", "touch-rail-2"; + }; + }; + + gpio@77 { + compatible = "ti,tca9539"; + reg = <0x77>; + gpio-controller; + #gpio-cells = <0x2>; + vcc-supply = <0x26>; + linux,phandle = <0x8d>; + phandle = <0x8d>; + + lcd-bias-rails { + gpio-hog; + gpios = <0x4 0x0>; + output-high; + label = "lcd-bias-en-rail"; + }; + }; + + gpio@21 { + compatible = "ti,tca6408"; + status = "disabled"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <0x2>; + vcc-supply = <0x26>; + linux,phandle = <0x40>; + phandle = <0x40>; + + vpp-vmm-rails { + gpio-hog; + gpios = <0x2 0x0>; + output-high; + label = "vmm-en-rail"; + }; + }; + + tps65132@3e { + reg = <0x3e>; + compatible = "ti,tps65132"; + status = "disabled"; + linux,phandle = <0x11c>; + phandle = <0x11c>; + + outp { + regulator-name = "outp"; + regulator-min-microvolt = <0x3d0900>; + regulator-max-microvolt = <0x5b8d80>; + enable-active-high; + linux,phandle = <0x86>; + phandle = <0x86>; + }; + + outn { + regulator-name = "outn"; + regulator-min-microvolt = <0x3d0900>; + regulator-max-microvolt = <0x5b8d80>; + enable-active-high; + ti,disable-active-discharge; + linux,phandle = <0x87>; + phandle = <0x87>; + }; + }; + }; + + i2c@c240000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0xc240000 0x0 0x100>; + interrupts = <0x0 0x1a 0x4>; + scl-gpio = <0x28 0x30 0x0>; + sda-gpio = <0x28 0x31 0x0>; + status = "okay"; + clock-frequency = <0x61a80>; + clocks = <0x10 0xda 0x10 0x10d 0x10 0xdd>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x14>; + reset-names = "i2c"; + dmas = <0x25 0x16 0x25 0x16>; + dma-names = "rx", "tx"; + linux,phandle = <0x175>; + phandle = <0x175>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + + lp8556-backlight-s-wqxga-10-1@2c { + status = "disabled"; + disable-on-kernel-charging; + compatible = "ti,lp8556"; + reg = <0x2c>; + bl-name = "pwm-backlight"; + init-brt = [ff]; + dev-ctrl = [80]; + pwm-period = <0x9ce1>; + pwm-names = "lp8556"; + pwms = <0x27 0x0 0x9ce1>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + linux,phandle = <0x11d>; + phandle = <0x11d>; + }; + + ov23850_c@36 { + compatible = "nvidia,ov23850"; + reg = <0x36>; + physical_w = "7.3998"; + physical_h = "5.5998"; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "vif"; + vcmvdd-reg = "vvcm"; + devnode = "video1"; + clocks = <0x10 0x5a 0x10 0x10d>; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + reset-gpios = <0x1b 0x89 0x0>; + pwdn-gpios = <0x1b 0x6a 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + vif-supply = <0x2b>; + vvcm-suply = <0x2c>; + status = "disabled"; + linux,phandle = <0x136>; + phandle = <0x136>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "5632"; + active_h = "3168"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "270"; + line_length = "5922"; + inherent_gain = [31 00]; + mclk_multiplier = "25"; + pix_clk_hz = "600000000"; + min_gain_val = "1.0"; + max_gain_val = "15.5"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "3.09135"; + max_framerate = "30"; + min_exp_time = "19.74"; + max_exp_time = "323094"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + bus-width = <0x4>; + remote-endpoint = <0x2d>; + linux,phandle = <0x139>; + phandle = <0x139>; + }; + }; + }; + }; + + bmi160@69 { + compatible = "bmi,bmi160"; + reg = <0x69>; + interrupt-parent = <0x28>; + interrupts = <0x2a 0x1>; + accelerometer_matrix = [01 00 00 00 01 00 00 00 01]; + gyroscope_matrix = [01 00 00 00 01 00 00 00 01]; + accelerometer_delay_us_min = <0x4e2>; + gyroscope_delay_us_min = <0x4e2>; + vdd-supply = <0x13>; + vdd_IO-supply = <0x13>; + status = "disabled"; + }; + + i2cmux@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2e>; + vcc-pullup-supply = <0x26>; + status = "disabled"; + linux,phandle = <0x10f>; + phandle = <0x10f>; + + i2c@0 { + reg = <0x0>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + tas2552.9-0040@40 { + compatible = "ti,tas2552"; + reg = <0x40>; + vbat-supply = <0x26>; + iovdd-supply = <0x2e>; + avdd-supply = <0x2f>; + tas2552,pdm_edge_select = <0x0>; + linux,phandle = <0x117>; + phandle = <0x117>; + }; + + tas2552.9-0041@41 { + compatible = "ti,tas2552"; + reg = <0x41>; + vbat-supply = <0x26>; + iovdd-supply = <0x2e>; + avdd-supply = <0x2f>; + tas2552,pdm_edge_select = <0x1>; + linux,phandle = <0x119>; + phandle = <0x119>; + }; + }; + + i2c@1 { + reg = <0x1>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ina3221x@40 { + compatible = "ti,ina3221x"; + reg = <0x40>; + ti,trigger-config = <0x7003>; + ti,continuous-config = <0x7c07>; + ti,enable-forced-continuous; + #address-cells = <0x1>; + #size-cells = <0x0>; + + channel@0 { + reg = <0x0>; + ti,rail-name = "VDD_5V"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@1 { + reg = <0x1>; + ti,rail-name = "VDD_3V3"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@2 { + reg = <0x2>; + ti,rail-name = "VDD_1V8"; + ti,shunt-resistor-mohm = <0x1>; + }; + }; + + ina3221x@41 { + compatible = "ti,ina3221x"; + reg = <0x41>; + ti,trigger-config = <0x7003>; + ti,continuous-config = <0x7c07>; + ti,enable-forced-continuous; + #address-cells = <0x1>; + #size-cells = <0x0>; + + channel@0 { + reg = <0x0>; + ti,rail-name = "VDD_5V_AUD"; + ti,shunt-resistor-mohm = <0x1>; + }; + + channel@1 { + reg = <0x1>; + ti,rail-name = "VDD_3V3_AUD"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@2 { + reg = <0x2>; + ti,rail-name = "VDD_1V8_AUD"; + ti,shunt-resistor-mohm = <0xa>; + }; + }; + + ina3221x@42 { + compatible = "ti,ina3221x"; + reg = <0x42>; + ti,trigger-config = <0x7003>; + ti,continuous-config = <0x7c07>; + ti,enable-forced-continuous; + #address-cells = <0x1>; + #size-cells = <0x0>; + + channel@0 { + reg = <0x0>; + ti,rail-name = "VDD_3V3_GPS"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@1 { + reg = <0x1>; + ti,rail-name = "VDD_3V3_NFC"; + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@2 { + reg = <0x2>; + ti,rail-name = "VDD_3V3_GYRO"; + ti,shunt-resistor-mohm = <0xa>; + }; + }; + }; + + i2c@2 { + reg = <0x2>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + }; + + i2c@3 { + reg = <0x3>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + rt5659.12-001a@1a { + compatible = "realtek,rt5658"; + reg = <0x1a>; + status = "disabled"; + gpios = <0x1b 0x4d 0x0>; + realtek,jd-src = <0x1>; + realtek,dmic1-data-pin = <0x2>; + linux,phandle = <0x11b>; + phandle = <0x11b>; + }; + }; + }; + + gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <0x2>; + vcc-supply = <0x26>; + status = "disabled"; + linux,phandle = <0xea>; + phandle = <0xea>; + }; + + icm20628@68 { + compatible = "invensense,mpu6xxx"; + reg = <0x68>; + interrupt-parent = <0x28>; + interrupts = <0x2a 0x1>; + accelerometer_matrix = [01 00 00 00 01 00 00 00 01]; + gyroscope_matrix = [01 00 00 00 01 00 00 00 01]; + vdd-supply = <0x13>; + vlogic-supply = <0x13>; + geomagnetic_rotation_vector_disable = <0x1>; + gyroscope_uncalibrated_disable = <0x1>; + quaternion_disable = <0x1>; + status = "disabled"; + linux,phandle = <0x110>; + phandle = <0x110>; + }; + + ak8963@0d { + compatible = "ak,ak89xx"; + reg = <0xd>; + magnetic_field_matrix = [01 00 00 00 01 00 00 00 01]; + status = "disabled"; + linux,phandle = <0x111>; + phandle = <0x111>; + }; + + bmp280@77 { + compatible = "bmp,bmpX80"; + reg = <0x77>; + status = "disabled"; + linux,phandle = <0x112>; + phandle = <0x112>; + }; + + cm32180@48 { + compatible = "capella,cm32180"; + reg = <0x48>; + gpio_irq = <0x1b 0x44 0x1>; + light_uncalibrated_lo = <0x1>; + light_calibrated_lo = <0x96>; + light_uncalibrated_hi = <0x17318>; + light_calibrated_hi = <0x1ab3f0>; + status = "disabled"; + linux,phandle = <0x113>; + phandle = <0x113>; + }; + + iqs263@44 { + status = "disabled"; + linux,phandle = <0x17b>; + phandle = <0x17b>; + }; + + rt5659.1-001a@1a { + compatible = "realtek,rt5658"; + reg = <0x1a>; + status = "disabled"; + gpios = <0x1b 0x4d 0x0>; + realtek,jd-src = <0x1>; + realtek,dmic1-data-pin = <0x2>; + linux,phandle = <0x11a>; + phandle = <0x11a>; + }; + }; + + i2c@3180000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0x3180000 0x0 0x100>; + interrupts = <0x0 0x1b 0x4>; + scl-gpio = <0x1b 0x72 0x0>; + sda-gpio = <0x1b 0x73 0x0>; + status = "okay"; + clock-frequency = <0x61a80>; + clocks = <0x10 0x4b 0x10 0x10d 0x10 0x5c>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x15>; + reset-names = "i2c"; + dmas = <0x25 0x17 0x25 0x17>; + dma-names = "rx", "tx"; + linux,phandle = <0x59>; + phandle = <0x59>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + + ov5693_c@36 { + compatible = "nvidia,ov5693"; + reg = <0x36>; + devnode = "video0"; + physical_w = "3.674"; + physical_h = "2.738"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + vertical-flip = "true"; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + clock-frequency = <0x16e3600>; + reset-gpios = <0x1b 0x8d 0x0>; + pwdn-gpios = <0x1b 0x88 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "okay"; + linux,phandle = <0x132>; + phandle = <0x132>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1944"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1458"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "1752"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "2787078"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + exposure_factor = "1000000"; + min_exp_time = "22"; + max_exp_time = "358733"; + step_exp_time = [31 00]; + default_exp_time = "8334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x30>; + linux,phandle = <0x134>; + phandle = <0x134>; + }; + }; + }; + }; + + ov23850_a@10 { + compatible = "nvidia,ov23850"; + reg = <0x10>; + physical_w = "7.3998"; + physical_h = "5.5998"; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "vif"; + vcmvdd-reg = "vvcm"; + devnode = "video0"; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + reset-gpios = <0x1b 0x8d 0x0>; + pwdn-gpios = <0x1b 0x88 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + vif-supply = <0x2b>; + vvcm-suply = <0x2c>; + status = "disabled"; + linux,phandle = <0x135>; + phandle = <0x135>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "5632"; + active_h = "3168"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "270"; + line_length = "5922"; + inherent_gain = [31 00]; + mclk_multiplier = "25"; + pix_clk_hz = "600000000"; + min_gain_val = "1.0"; + max_gain_val = "15.5"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "3.09135"; + max_framerate = "30"; + min_exp_time = "19.74"; + max_exp_time = "323094"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x30>; + linux,phandle = <0x138>; + phandle = <0x138>; + }; + }; + }; + }; + + tca9546@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2b>; + skip_mux_detect = "yes"; + force_bus_start = <0x1e>; + vcc_lp = "vcc"; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x130>; + phandle = <0x130>; + + i2c@0 { + reg = <0x0>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + imx318_a@10 { + compatible = "nvidia,imx318"; + reg = <0x10>; + physical_w = "6.811"; + physical_h = "5.254"; + sensor_model = "imx318"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + dvdd-reg = "vdig"; + has-eeprom; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + clock-frequency = <0x16e3600>; + reset-gpios = <0x1b 0x8d 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + vdig-supply = <0x2a>; + status = "disabled"; + linux,phandle = <0x172>; + phandle = <0x172>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [33 00]; + phy_mode = "CPHY"; + tegra_sinterface = "serial_a"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = "20"; + active_w = "5488"; + active_h = "4112"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = [30 00]; + line_length = "5488"; + inherent_gain = [31 00]; + mclk_multiplier = "31.25"; + pix_clk_hz = "750000000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "256"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "1500000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + bus-width = <0x3>; + remote-endpoint = <0x30>; + linux,phandle = <0x173>; + phandle = <0x173>; + }; + }; + }; + }; + + imx185_a@1a { + compatible = "nvidia,imx185"; + reg = <0x1a>; + devnode = "video0"; + physical_w = "15.0"; + physical_h = "12.5"; + sensor_model = "imx185"; + post_crop_frame_drop = [30 00]; + use_decibel_gain = "true"; + delayed_gain = "true"; + use_sensor_mode_id = "true"; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + reset-gpios = <0x1b 0x8d 0x0>; + status = "disabled"; + linux,phandle = <0x16b>; + phandle = <0x16b>; + + mode0 { + mclk_khz = "37125"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "12"; + csi_pixel_bit_depth = "12"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "2200"; + inherent_gain = [31 00]; + mclk_multiplier = [32 00]; + pix_clk_hz = "74250000"; + gain_factor = "10"; + min_gain_val = [30 00]; + max_gain_val = "480"; + step_gain_val = [33 00]; + default_gain = [30 00]; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "30"; + max_exp_time = "660000"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [31 00]; + }; + + mode1 { + mclk_khz = "37125"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "2640"; + inherent_gain = [31 00]; + mclk_multiplier = "2.4"; + pix_clk_hz = "89100000"; + gain_factor = "10"; + min_gain_val = [30 00]; + max_gain_val = "480"; + step_gain_val = [33 00]; + default_gain = [30 00]; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "30"; + max_exp_time = "660000"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [31 00]; + }; + + mode2 { + mclk_khz = "37125"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "12"; + csi_pixel_bit_depth = "12"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "2200"; + inherent_gain = [31 00]; + mclk_multiplier = [34 00]; + pix_clk_hz = "148500000"; + gain_factor = "10"; + min_gain_val = [30 00]; + max_gain_val = "480"; + step_gain_val = [33 00]; + default_gain = [30 00]; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "30"; + max_exp_time = "660000"; + step_exp_time = [31 00]; + default_exp_time = "16667"; + embedded_metadata_height = [31 00]; + }; + + mode3 { + mclk_khz = "37125"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "2640"; + inherent_gain = [31 00]; + mclk_multiplier = "4.8"; + pix_clk_hz = "178200000"; + gain_factor = "10"; + min_gain_val = [30 00]; + max_gain_val = "480"; + step_gain_val = [33 00]; + default_gain = [30 00]; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "30"; + max_exp_time = "660000"; + step_exp_time = [31 00]; + default_exp_time = "16667"; + embedded_metadata_height = [31 00]; + }; + + mode4 { + mclk_khz = "37125"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "16"; + csi_pixel_bit_depth = "12"; + mode_type = "bayer_wdr_pwl"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "2200"; + inherent_gain = [31 00]; + mclk_multiplier = [32 00]; + pix_clk_hz = "74250000"; + gain_factor = "10"; + min_gain_val = [30 00]; + max_gain_val = "120"; + step_gain_val = [33 00]; + default_gain = [30 00]; + min_hdr_ratio = "16"; + max_hdr_ratio = "16"; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "2433"; + max_exp_time = "660000"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [31 00]; + num_control_point = [34 00]; + control_point_x_0 = [30 00]; + control_point_x_1 = "2048"; + control_point_x_2 = "16384"; + control_point_x_3 = "65536"; + control_point_y_0 = [30 00]; + control_point_y_1 = "2048"; + control_point_y_2 = "2944"; + control_point_y_3 = "3712"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x30>; + linux,phandle = <0x16c>; + phandle = <0x16c>; + }; + }; + }; + }; + + pca9570_a@24 { + compatible = "nvidia,pca9570"; + reg = <0x24>; + channel = [61 00]; + drive_ic = "DRV8838"; + status = "disabled"; + linux,phandle = <0x16d>; + phandle = <0x16d>; + }; + + imx274_a@1a { + compatible = "nvidia,imx274"; + reg = <0x1a>; + devnode = "video0"; + physical_w = "3.674"; + physical_h = "2.738"; + sensor_model = "imx274"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + delayed_gain = "true"; + has-eeprom; + fuse_id_start_addr = <0x5b>; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + reset-gpios = <0x1b 0x8d 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x16e>; + phandle = <0x16e>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3840"; + active_h = "2160"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "4208"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "44400000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "44"; + max_exp_time = "478696"; + step_exp_time = [31 00]; + default_exp_time = "16667"; + embedded_metadata_height = [31 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "4160"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "177000000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "58"; + max_exp_time = "184611"; + step_exp_time = [31 00]; + default_exp_time = "16667"; + embedded_metadata_height = [31 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer_wdr_dol"; + pixel_phase = "rggb"; + active_w = "3856"; + active_h = "4448"; + readout_orientation = [30 00]; + line_length = "4208"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "30000000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = "32"; + max_hdr_ratio = "32"; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "864"; + max_exp_time = "20480"; + step_exp_time = [31 00]; + default_exp_time = "20480"; + embedded_metadata_height = [31 00]; + num_of_exposure = [32 00]; + num_of_ignored_lines = "14"; + num_of_lines_offset_0 = "50"; + num_of_ignored_pixels = [34 00]; + num_of_left_margin_pixels = "12"; + num_of_right_margin_pixels = [30 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer_wdr_dol"; + pixel_phase = "rggb"; + active_w = "1936"; + active_h = "2264"; + readout_orientation = [30 00]; + line_length = "4160"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "177000000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = "32"; + max_hdr_ratio = "32"; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "859"; + max_exp_time = "15649"; + step_exp_time = [31 00]; + default_exp_time = "15649"; + embedded_metadata_height = [31 00]; + num_of_exposure = [32 00]; + num_of_ignored_lines = "14"; + num_of_lines_offset_0 = "38"; + num_of_ignored_pixels = [34 00]; + num_of_left_margin_pixels = [36 00]; + num_of_right_margin_pixels = [36 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x30>; + linux,phandle = <0x16f>; + phandle = <0x16f>; + }; + }; + }; + }; + + imx390_a@1b { + compatible = "nvidia,imx390"; + reg = <0x1b>; + physical_w = "15.0"; + physical_h = "12.5"; + sensor_model = "imx390"; + post_crop_frame_drop = [30 00]; + use_decibel_gain = "true"; + use_sensor_mode_id = "true"; + def-addr = <0x1a>; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + nvidia,gmsl-ser-device = <0x31>; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + linux,phandle = <0x120>; + phandle = <0x120>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + vc_id = [30 00]; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "12"; + csi_pixel_bit_depth = "12"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "2200"; + inherent_gain = [31 00]; + pix_clk_hz = "74250000"; + serdes_pix_clk_hz = "833333333"; + gain_factor = "10"; + min_gain_val = [30 00]; + max_gain_val = "300"; + step_gain_val = [33 00]; + default_gain = [30 00]; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "30000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "59"; + max_exp_time = "33333"; + step_exp_time = [31 00]; + default_exp_time = "33333"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + vc-id = <0x0>; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x30>; + linux,phandle = <0x61>; + phandle = <0x61>; + }; + }; + }; + + gmsl-link { + src-csi-port = [62 00]; + dst-csi-port = [61 00]; + serdes-csi-link = [61 00]; + csi-mode = "1x4"; + st-vc = <0x0>; + vc-id = <0x0>; + num-lanes = <0x2>; + streams = "ued-u1", "raw12"; + }; + }; + + imx390_b@1c { + compatible = "nvidia,imx390"; + reg = <0x1c>; + physical_w = "15.0"; + physical_h = "12.5"; + sensor_model = "imx390"; + post_crop_frame_drop = [30 00]; + use_decibel_gain = "true"; + use_sensor_mode_id = "true"; + def-addr = <0x1a>; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + nvidia,gmsl-ser-device = <0x33>; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + linux,phandle = <0x123>; + phandle = <0x123>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + vc_id = [31 00]; + discontinuous_clk = "no"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "12"; + csi_pixel_bit_depth = "12"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "4400"; + inherent_gain = [31 00]; + pix_clk_hz = "74250000"; + serdes_pix_clk_hz = "833333333"; + gain_factor = "10"; + min_gain_val = [30 00]; + max_gain_val = "300"; + step_gain_val = [33 00]; + default_gain = [30 00]; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "30000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "59"; + max_exp_time = "33333"; + step_exp_time = [31 00]; + default_exp_time = "33333"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + vc-id = <0x1>; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x2d>; + linux,phandle = <0x63>; + phandle = <0x63>; + }; + }; + }; + + gmsl-link { + src-csi-port = [62 00]; + dst-csi-port = [61 00]; + serdes-csi-link = [62 00]; + csi-mode = "1x4"; + st-vc = <0x0>; + vc-id = <0x1>; + num-lanes = <0x2>; + streams = "ued-u1", "raw12"; + }; + }; + + max9296@48 { + compatible = "nvidia,max9296"; + reg = <0x48>; + csi-mode = "2x4"; + max-src = <0x2>; + reset-gpios = <0x1b 0x8d 0x0>; + vdd_cam_1v2-supply = <0x34>; + status = "disabled"; + linux,phandle = <0x32>; + phandle = <0x32>; + }; + + max9295_prim@62 { + compatible = "nvidia,max9295"; + reg = <0x62>; + is-prim-ser; + status = "disabled"; + linux,phandle = <0x131>; + phandle = <0x131>; + }; + + max9295_a@40 { + compatible = "nvidia,max9295"; + reg = <0x40>; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + linux,phandle = <0x31>; + phandle = <0x31>; + }; + + max9295_b@60 { + compatible = "nvidia,max9295"; + reg = <0x60>; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + linux,phandle = <0x33>; + phandle = <0x33>; + }; + }; + + i2c@1 { + reg = <0x1>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + imx274_c@1a { + compatible = "nvidia,imx274"; + reg = <0x1a>; + devnode = "video1"; + physical_w = "3.674"; + physical_h = "2.738"; + sensor_model = "imx274"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + delayed_gain = "true"; + has-eeprom; + fuse_id_start_addr = <0x63>; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + reset-gpios = <0x1b 0x88 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x170>; + phandle = <0x170>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3840"; + active_h = "2160"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "4208"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "44400000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "44"; + max_exp_time = "478696"; + step_exp_time = [31 00]; + default_exp_time = "16667"; + embedded_metadata_height = [31 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer"; + pixel_phase = "rggb"; + active_w = "1920"; + active_h = "1080"; + readout_orientation = [30 00]; + line_length = "4160"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "177000000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "58"; + max_exp_time = "184611"; + step_exp_time = [31 00]; + default_exp_time = "16667"; + embedded_metadata_height = [31 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer_wdr_dol"; + pixel_phase = "rggb"; + active_w = "3856"; + active_h = "4448"; + readout_orientation = [30 00]; + line_length = "4208"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "30000000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = "32"; + max_hdr_ratio = "32"; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "864"; + max_exp_time = "20480"; + step_exp_time = [31 00]; + default_exp_time = "20480"; + embedded_metadata_height = [31 00]; + num_of_exposure = [32 00]; + num_of_ignored_lines = "14"; + num_of_lines_offset_0 = "50"; + num_of_ignored_pixels = [34 00]; + num_of_left_margin_pixels = "12"; + num_of_right_margin_pixels = [30 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [34 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + dynamic_pixel_bit_depth = "10"; + csi_pixel_bit_depth = "10"; + mode_type = "bayer_wdr_dol"; + pixel_phase = "rggb"; + active_w = "1936"; + active_h = "2264"; + readout_orientation = [30 00]; + line_length = "4160"; + inherent_gain = [31 00]; + mclk_multiplier = "24"; + pix_clk_hz = "576000000"; + gain_factor = "1000000"; + min_gain_val = "1000000"; + max_gain_val = "177000000"; + step_gain_val = [31 00]; + default_gain = "1000000"; + min_hdr_ratio = "32"; + max_hdr_ratio = "32"; + framerate_factor = "1000000"; + min_framerate = "1500000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + exposure_factor = "1000000"; + min_exp_time = "859"; + max_exp_time = "15649"; + step_exp_time = [31 00]; + default_exp_time = "15649"; + embedded_metadata_height = [31 00]; + num_of_exposure = [32 00]; + num_of_ignored_lines = "14"; + num_of_lines_offset_0 = "38"; + num_of_ignored_pixels = [34 00]; + num_of_left_margin_pixels = [36 00]; + num_of_right_margin_pixels = [36 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + bus-width = <0x4>; + remote-endpoint = <0x2d>; + linux,phandle = <0x171>; + phandle = <0x171>; + }; + }; + }; + }; + }; + }; + + tca9548@77 { + compatible = "nxp,pca9548"; + reg = <0x77>; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2b>; + skip_mux_detect; + force_bus_start = <0x1e>; + status = "disabled"; + linux,phandle = <0x13b>; + phandle = <0x13b>; + + i2c@0 { + reg = <0x0>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ov5693_a@36 { + compatible = "nvidia,ov5693"; + reg = <0x36>; + devnode = "video0"; + physical_w = "3.674"; + physical_h = "2.738"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + clock-frequency = <0x16e3600>; + reset-gpios = <0x1b 0x8d 0x0>; + pwdn-gpios = <0x1b 0x88 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x13c>; + phandle = <0x13c>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1944"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1458"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "1752"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "2787078"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + exposure_factor = "1000000"; + min_exp_time = "22"; + max_exp_time = "358733"; + step_exp_time = [31 00]; + default_exp_time = "8334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x30>; + linux,phandle = <0x13d>; + phandle = <0x13d>; + }; + }; + }; + }; + + imx219_a@10 { + devnode = "video0"; + compatible = "nvidia,imx219"; + reg = <0x10>; + physical_w = "5.095"; + physical_h = "4.930"; + sensor_model = "imx219"; + dovdd-supply = <0x2b>; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "dovdd"; + clocks = <0x10 0x59>; + clock-names = "extperiph1"; + mclk = "extperiph1"; + reset-gpios = <0x35 0x0 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + status = "disabled"; + linux,phandle = <0x163>; + phandle = <0x163>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "2464"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "18.67"; + pix_clk_hz = "224000000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "256"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "1462526"; + max_framerate = "21000000"; + step_framerate = [31 00]; + default_framerate = "21000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "1848"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "28000000"; + step_framerate = [31 00]; + default_framerate = "28000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1920"; + active_h = "1080"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode4 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_a"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "169600000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x30>; + linux,phandle = <0x164>; + phandle = <0x164>; + }; + }; + }; + }; + }; + + i2c@1 { + reg = <0x1>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ov5693_b@36 { + compatible = "nvidia,ov5693"; + reg = <0x36>; + devnode = "video1"; + physical_w = "3.674"; + physical_h = "2.738"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + clock-frequency = <0x16e3600>; + reset-gpios = <0x1b 0x89 0x0>; + pwdn-gpios = <0x1b 0x6a 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x13a>; + phandle = <0x13a>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1944"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1458"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "1752"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "2787078"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + exposure_factor = "1000000"; + min_exp_time = "22"; + max_exp_time = "358733"; + step_exp_time = [31 00]; + default_exp_time = "8334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x1>; + bus-width = <0x2>; + remote-endpoint = <0x2d>; + linux,phandle = <0x13e>; + phandle = <0x13e>; + }; + }; + }; + }; + + imx219_b@10 { + devnode = "video1"; + compatible = "nvidia,imx219"; + reg = <0x10>; + physical_w = "5.095"; + physical_h = "4.930"; + sensor_model = "imx219"; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "dovdd"; + clocks = <0x10 0x59>; + clock-names = "extperiph1"; + mclk = "extperiph1"; + reset-gpios = <0x35 0x1 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + dovdd-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x165>; + phandle = <0x165>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "2464"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "18.67"; + pix_clk_hz = "224000000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "256"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "1462526"; + max_framerate = "21000000"; + step_framerate = [31 00]; + default_framerate = "21000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "1848"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "28000000"; + step_framerate = [31 00]; + default_framerate = "28000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1920"; + active_h = "1080"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode4 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_b"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "169600000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x1>; + bus-width = <0x2>; + remote-endpoint = <0x2d>; + linux,phandle = <0x166>; + phandle = <0x166>; + }; + }; + }; + }; + }; + + i2c@2 { + reg = <0x2>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ov5693_c@36 { + compatible = "nvidia,ov5693"; + reg = <0x36>; + devnode = "video2"; + physical_w = "3.674"; + physical_h = "2.738"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + clocks = <0x10 0x59 0x10 0x10d>; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + clock-frequency = <0x16e3600>; + pwdn-gpios = <0x35 0x0 0x0>; + reset-gpios = <0x35 0x1 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x13f>; + phandle = <0x13f>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1944"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1458"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "1752"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "2787078"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + exposure_factor = "1000000"; + min_exp_time = "22"; + max_exp_time = "358733"; + step_exp_time = [31 00]; + default_exp_time = "8334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x36>; + linux,phandle = <0x146>; + phandle = <0x146>; + }; + }; + }; + }; + + imx219_c@10 { + devnode = "video2"; + compatible = "nvidia,imx219"; + reg = <0x10>; + physical_w = "5.095"; + physical_h = "4.930"; + sensor_model = "imx219"; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "dovdd"; + clocks = <0x10 0x59>; + clock-names = "extperiph1"; + mclk = "extperiph1"; + reset-gpios = <0x35 0x2 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + dovdd-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x167>; + phandle = <0x167>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "2464"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "18.67"; + pix_clk_hz = "224000000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "256"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "1462526"; + max_framerate = "21000000"; + step_framerate = [31 00]; + default_framerate = "21000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "1848"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "28000000"; + step_framerate = [31 00]; + default_framerate = "28000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1920"; + active_h = "1080"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode4 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_c"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "169600000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x36>; + linux,phandle = <0x65>; + phandle = <0x65>; + }; + }; + }; + }; + }; + + i2c@3 { + reg = <0x3>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ov5693_d@36 { + compatible = "nvidia,ov5693"; + reg = <0x36>; + devnode = "video3"; + physical_w = "3.674"; + physical_h = "2.738"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + clocks = <0x10 0x5a 0x10 0x10d>; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + clock-frequency = <0x16e3600>; + pwdn-gpios = <0x35 0x2 0x0>; + reset-gpios = <0x35 0x3 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x148>; + phandle = <0x148>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1944"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1458"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "1752"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "2787078"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + exposure_factor = "1000000"; + min_exp_time = "22"; + max_exp_time = "358733"; + step_exp_time = [31 00]; + default_exp_time = "8334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x37>; + linux,phandle = <0x14f>; + phandle = <0x14f>; + }; + }; + }; + }; + + imx219_d@10 { + devnode = "video3"; + compatible = "nvidia,imx219"; + reg = <0x10>; + physical_w = "5.095"; + physical_h = "4.930"; + sensor_model = "imx219"; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "dovdd"; + clocks = <0x10 0x5a>; + clock-names = "extperiph2"; + mclk = "extperiph2"; + reset-gpios = <0x35 0x3 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + dovdd-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x168>; + phandle = <0x168>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "2464"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "18.67"; + pix_clk_hz = "224000000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "256"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "1462526"; + max_framerate = "21000000"; + step_framerate = [31 00]; + default_framerate = "21000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "1848"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "28000000"; + step_framerate = [31 00]; + default_framerate = "28000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1920"; + active_h = "1080"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode4 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_d"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "169600000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x37>; + linux,phandle = <0x67>; + phandle = <0x67>; + }; + }; + }; + }; + }; + + i2c@4 { + reg = <0x4>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ov5693_e@36 { + compatible = "nvidia,ov5693"; + reg = <0x36>; + devnode = "video4"; + physical_w = "3.674"; + physical_h = "2.738"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + clocks = <0x10 0x5a 0x10 0x10d>; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + clock-frequency = <0x16e3600>; + pwdn-gpios = <0x35 0x4 0x0>; + reset-gpios = <0x35 0x5 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x151>; + phandle = <0x151>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1944"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1458"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "1752"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "2787078"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + exposure_factor = "1000000"; + min_exp_time = "22"; + max_exp_time = "358733"; + step_exp_time = [31 00]; + default_exp_time = "8334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x38>; + linux,phandle = <0x158>; + phandle = <0x158>; + }; + }; + }; + }; + + imx219_e@10 { + devnode = "video4"; + compatible = "nvidia,imx219"; + reg = <0x10>; + physical_w = "5.095"; + physical_h = "4.930"; + sensor_model = "imx219"; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "dovdd"; + clocks = <0x10 0x5a>; + clock-names = "extperiph2"; + mclk = "extperiph2"; + reset-gpios = <0x35 0x4 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + dovdd-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x169>; + phandle = <0x169>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "2464"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "18.67"; + pix_clk_hz = "224000000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "256"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "1462526"; + max_framerate = "21000000"; + step_framerate = [31 00]; + default_framerate = "21000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "1848"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "28000000"; + step_framerate = [31 00]; + default_framerate = "28000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1920"; + active_h = "1080"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode4 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_e"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "169600000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x38>; + linux,phandle = <0x69>; + phandle = <0x69>; + }; + }; + }; + }; + }; + + i2c@5 { + reg = <0x5>; + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ov5693_f@36 { + compatible = "nvidia,ov5693"; + reg = <0x36>; + devnode = "video5"; + physical_w = "3.674"; + physical_h = "2.738"; + avdd-reg = "vana"; + iovdd-reg = "vif"; + clocks = <0x10 0x5a 0x10 0x10d>; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + clock-frequency = <0x16e3600>; + pwdn-gpios = <0x35 0x6 0x0>; + reset-gpios = <0x35 0x7 0x0>; + vana-supply = <0x29>; + vif-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x15a>; + phandle = <0x15a>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1944"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "2592"; + active_h = "1458"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "2688"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "1816577"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + exposure_factor = "1000000"; + min_exp_time = "34"; + max_exp_time = "550385"; + step_exp_time = [31 00]; + default_exp_time = "33334"; + embedded_metadata_height = [30 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "bggr"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "1752"; + inherent_gain = [31 00]; + mclk_multiplier = "6.67"; + pix_clk_hz = "160000000"; + gain_factor = "10"; + min_gain_val = "10"; + max_gain_val = "160"; + step_gain_val = [31 00]; + default_gain = "10"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + framerate_factor = "1000000"; + min_framerate = "2787078"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + exposure_factor = "1000000"; + min_exp_time = "22"; + max_exp_time = "358733"; + step_exp_time = [31 00]; + default_exp_time = "8334"; + embedded_metadata_height = [30 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x39>; + linux,phandle = <0x161>; + phandle = <0x161>; + }; + }; + }; + }; + + imx219_f@10 { + devnode = "video5"; + compatible = "nvidia,imx219"; + reg = <0x10>; + physical_w = "5.095"; + physical_h = "4.930"; + sensor_model = "imx219"; + avdd-reg = "vana"; + dvdd-reg = "vdig"; + iovdd-reg = "dovdd"; + clocks = <0x10 0x5a>; + clock-names = "extperiph2"; + mclk = "extperiph2"; + reset-gpios = <0x35 0x5 0x0>; + vana-supply = <0x29>; + vdig-supply = <0x2a>; + dovdd-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x16a>; + phandle = <0x16a>; + + mode0 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "2464"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "18.67"; + pix_clk_hz = "224000000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "256"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "1462526"; + max_framerate = "21000000"; + step_framerate = [31 00]; + default_framerate = "21000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode1 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "3264"; + active_h = "1848"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "28000000"; + step_framerate = [31 00]; + default_framerate = "28000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode2 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1920"; + active_h = "1080"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "30000000"; + step_framerate = [31 00]; + default_framerate = "30000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode3 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "182400000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "60000000"; + step_framerate = [31 00]; + default_framerate = "60000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + mode4 { + mclk_khz = "24000"; + num_lanes = [32 00]; + tegra_sinterface = "serial_f"; + phy_mode = "DPHY"; + discontinuous_clk = "yes"; + dpcm_enable = "false"; + cil_settletime = [30 00]; + active_w = "1280"; + active_h = "720"; + mode_type = "bayer"; + pixel_phase = "rggb"; + csi_pixel_bit_depth = "10"; + readout_orientation = "90"; + line_length = "3448"; + inherent_gain = [31 00]; + mclk_multiplier = "9.33"; + pix_clk_hz = "169600000"; + gain_factor = "16"; + framerate_factor = "1000000"; + exposure_factor = "1000000"; + min_gain_val = "16"; + max_gain_val = "170"; + step_gain_val = [31 00]; + default_gain = "16"; + min_hdr_ratio = [31 00]; + max_hdr_ratio = [31 00]; + min_framerate = "2000000"; + max_framerate = "120000000"; + step_framerate = [31 00]; + default_framerate = "120000000"; + min_exp_time = "13"; + max_exp_time = "683709"; + step_exp_time = [31 00]; + default_exp_time = "2495"; + embedded_metadata_height = [32 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x39>; + linux,phandle = <0x6b>; + phandle = <0x6b>; + }; + }; + }; + }; + }; + }; + + tca6408@21 { + compatible = "ti,tca6408"; + gpio-controller; + #gpio-cells = <0x2>; + reg = <0x21>; + vcc-supply = <0x2b>; + status = "disabled"; + linux,phandle = <0x35>; + phandle = <0x35>; + + tca6408_21_outlow { + gpio-hog; + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0>; + output-low; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + + tca6408_21_input { + status = "disabled"; + gpio-hog; + input; + gpios = <0x6 0x0 0x7 0x0>; + label = "tca6408_21_input_6", "tca6408_21_input_7"; + }; + }; + }; + + i2c@3190000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0x3190000 0x0 0x100>; + interrupts = <0x0 0x1c 0x4>; + status = "okay"; + clock-frequency = <0x186a0>; + clocks = <0x10 0x56 0x10 0x10d 0x10 0xdd>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x16>; + reset-names = "i2c"; + dmas = <0x25 0x1a 0x25 0x1a>; + dma-names = "rx", "tx"; + linux,phandle = <0x92>; + phandle = <0x92>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + }; + + bpmp_i2c { + #address-cells = <0x1>; + #size-cells = <0x0>; + compatible = "nvidia,tegra186-bpmp-i2c"; + status = "okay"; + adapter = <0x5>; + linux,phandle = <0x17c>; + phandle = <0x17c>; + + spmic@3c { + compatible = "maxim,max77620"; + reg = <0x3c>; + interrupt-parent = <0x3a>; + interrupts = <0x0 0xd1 0x0>; + #interrupt-cells = <0x2>; + interrupt-controller; + gpio-controller; + #gpio-cells = <0x2>; + maxim,enable-clock32k-out; + maxim,system-pmic-power-off; + maxim,avoid-power-off-commands; + maxim,hot-die-threshold-temp = <0x1adb0>; + #thermal-sensor-cells = <0x0>; + pinctrl-names = "default"; + pinctrl-0 = <0x3b>; + linux,phandle = <0x22>; + phandle = <0x22>; + + pinmux@0 { + linux,phandle = <0x3b>; + phandle = <0x3b>; + + pin_gpio0 { + pins = "gpio0"; + function = "gpio"; + }; + + pin_gpio1 { + pins = "gpio1"; + function = "fps-out"; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x1>; + maxim,active-fps-power-down-slot = <0x3>; + }; + + pin_gpio2 { + pins = "gpio2"; + function = "fps-out"; + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x7>; + maxim,active-fps-power-down-slot = <0x1>; + status = "disabled"; + }; + + pin_gpio3 { + pins = "gpio3"; + function = "fps-out"; + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x1>; + maxim,active-fps-power-down-slot = <0x7>; + status = "disabled"; + }; + + pin_gpio4 { + pins = "gpio4"; + function = "32k-out1"; + drive-push-pull = <0x1>; + }; + + pin_gpio5 { + pins = "gpio5"; + function = "gpio"; + drive-push-pull = <0x0>; + }; + + pin_gpio6 { + pins = "gpio6"; + function = "gpio"; + drive-push-pull = <0x1>; + }; + + pin_gpio7 { + pins = "gpio7"; + function = "gpio"; + drive-push-pull = <0x1>; + }; + }; + + spmic_gpio_input { + gpio-hog; + gpios = <0x5 0x0 0x6 0x0>; + input; + label = "spmic_gpio_input_5", "spmic_gpio_input_6"; + }; + + watchdog { + maxim,wdt-timeout = <0x10>; + maxim,wdt-clear-time = <0xd>; + status = "disabled"; + linux,phandle = <0xfe>; + phandle = <0xfe>; + }; + + fps { + + fps0 { + shutdown-fps-time-period-us = <0x280>; + maxim,fps-event-source = <0x0>; + }; + + fps1 { + shutdown-fps-time-period-us = <0x280>; + maxim,fps-event-source = <0x1>; + device-state-on-disabled-event = <0x0>; + }; + + fps2 { + maxim,shutdonw-fps-time-period-us = <0x280>; + maxim,fps-event-source = <0x0>; + }; + }; + + backup-battery { + backup-battery-charging-current = <0x64>; + backup-battery-charging-voltage = <0x2dc6c0>; + backup-battery-output-resister = <0x64>; + status = "disabled"; + }; + + regulators { + in-ldo4-supply = <0x12>; + in-ldo6-supply = <0x12>; + in-ldo7-8-supply = <0x3c>; + + sd0 { + regulator-name = "vddio-ddr"; + regulator-boot-on; + regulator-always-on; + regulator-init-mode = <0x2>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x5>; + maxim,active-fps-power-down-slot = <0x2>; + regulator-enable-ramp-delay = <0x116>; + regulator-disable-ramp-delay = <0x255a8>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-ramp-delay = <0xf5a>; + linux,phandle = <0xb4>; + phandle = <0xb4>; + }; + + sd1 { + regulator-name = "avdd_dsi_csi"; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x124f80>; + regulator-always-on; + regulator-boot-on; + regulator-init-mode = <0x2>; + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x3>; + maxim,active-fps-power-down-slot = <0x1>; + regulator-enable-ramp-delay = <0xd3>; + regulator-disable-ramp-delay = <0x9c40>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-ramp-delay = <0x157c>; + linux,phandle = <0x3c>; + phandle = <0x3c>; + }; + + sd2 { + regulator-name = "vdd-1v8"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-boot-on; + regulator-init-mode = <0x2>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x0>; + maxim,active-fps-power-down-slot = <0x7>; + regulator-enable-ramp-delay = <0xfa0>; + regulator-disable-ramp-delay = <0x5208>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-ramp-delay = <0x1c2>; + linux,phandle = <0x12>; + phandle = <0x12>; + }; + + sd3 { + regulator-name = "vdd-3v3-sys"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-boot-on; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x6>; + maxim,active-fps-power-down-slot = <0x1>; + regulator-enable-ramp-delay = <0x23e>; + regulator-disable-ramp-delay = <0x9c40>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-ramp-delay = <0x157c>; + linux,phandle = <0x13>; + phandle = <0x13>; + }; + + ldo0 { + regulator-name = "spmic-ldo0"; + maxim,active-fps-source = <0x3>; + regulator-enable-ramp-delay = <0x3e8>; + maxim,active-fps-power-up-slot = <0x3>; + maxim,active-fps-power-down-slot = <0x3>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-ramp-delay = <0x186a0>; + linux,phandle = <0x10e>; + phandle = <0x10e>; + }; + + ldo1 { + regulator-name = "spmic-ldo1"; + maxim,active-fps-source = <0x4>; + regulator-enable-ramp-delay = <0x3e8>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-ramp-delay = <0x186a0>; + linux,phandle = <0x17d>; + phandle = <0x17d>; + }; + + ldo2 { + regulator-name = "vddio-3v3"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-boot-on; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x6>; + maxim,active-fps-power-down-slot = <0x1>; + regulator-enable-ramp-delay = <0x98>; + regulator-disable-ramp-delay = <0x36b0>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-ramp-delay = <0x4e20>; + linux,phandle = <0xb5>; + phandle = <0xb5>; + }; + + ldo3 { + regulator-name = "vddio-sdmmc1"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + maxim,active-fps-source = <0x3>; + maxim,active-fps-power-up-slot = <0x0>; + maxim,active-fps-power-down-slot = <0x7>; + regulator-enable-ramp-delay = <0xa0>; + regulator-disable-ramp-delay = <0x3e80>; + maxim,ramp-rate-setting = <0x1388>; + regulator-ramp-delay = <0x3e8>; + linux,phandle = <0x1c>; + phandle = <0x1c>; + }; + + ldo4 { + regulator-name = "vdd-rtc"; + regulator-always-on; + regulator-boot-on; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x1>; + maxim,active-fps-power-down-slot = <0x7>; + regulator-enable-ramp-delay = <0x1a>; + regulator-disable-ramp-delay = <0x672>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-ramp-delay = <0x80e8>; + linux,phandle = <0x17e>; + phandle = <0x17e>; + }; + + ldo5 { + regulator-name = "avdd-ts-hv"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + maxim,active-fps-source = <0x4>; + maxim,active-fps-power-up-slot = <0x0>; + maxim,active-fps-power-down-slot = <0x7>; + regulator-enable-ramp-delay = <0x135>; + regulator-disable-ramp-delay = <0x3e80>; + maxim,ramp-rate-setting = <0x1388>; + regulator-ramp-delay = <0x20e>; + linux,phandle = <0x16>; + phandle = <0x16>; + }; + + ldo6 { + regulator-name = "spmic-ldo6"; + maxim,active-fps-source = <0x3>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-ramp-delay = <0x186a0>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <0x10c>; + phandle = <0x10c>; + }; + + ldo7 { + regulator-name = "vdd-pex-1v00"; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + maxim,active-fps-source = <0x1>; + regulator-always-on; + regulator-boot-on; + maxim,active-fps-power-up-slot = <0x4>; + maxim,active-fps-power-down-slot = <0x1>; + regulator-enable-ramp-delay = <0x5f>; + regulator-disable-ramp-delay = <0x3a98>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-ramp-delay = <0x2710>; + linux,phandle = <0x89>; + phandle = <0x89>; + }; + + ldo8 { + regulator-name = "dvdd-pex"; + maxim,active-fps-source = <0x4>; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + linux,phandle = <0x10d>; + phandle = <0x10d>; + }; + }; + }; + }; + + i2c@31b0000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0x31b0000 0x0 0x100>; + interrupts = <0x0 0x1e 0x4>; + status = "okay"; + clock-frequency = <0x186a0>; + clocks = <0x10 0x7d 0x10 0x10d 0x10 0x5c>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x18>; + reset-names = "i2c"; + dmas = <0x25 0x1e 0x25 0x1e>; + dma-names = "rx", "tx"; + linux,phandle = <0x8f>; + phandle = <0x8f>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + }; + + i2c@31c0000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0x31c0000 0x0 0x100>; + interrupts = <0x0 0x1f 0x4>; + scl-gpio = <0x1b 0x58 0x0>; + sda-gpio = <0x1b 0x59 0x0>; + status = "okay"; + clock-frequency = <0x61a80>; + clocks = <0x10 0xb6 0x10 0x10d 0x10 0x5c>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x51>; + reset-names = "i2c"; + dmas = <0x25 0x1b 0x25 0x1b>; + dma-names = "rx", "tx"; + linux,phandle = <0x17f>; + phandle = <0x17f>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + }; + + i2c@c250000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0xc250000 0x0 0x100>; + interrupts = <0x0 0x20 0x4>; + scl-gpio = <0x28 0x18 0x0>; + sda-gpio = <0x28 0x19 0x0>; + status = "okay"; + clock-frequency = <0x61a80>; + clocks = <0x10 0xdb 0x10 0x10d 0x10 0xdd>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x52>; + reset-names = "i2c"; + dmas = <0x25 0x0 0x25 0x0>; + dma-names = "rx", "tx"; + linux,phandle = <0x174>; + phandle = <0x174>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + + temp-sensor@4c { + status = "okay"; + #thermal-sensor-cells = <0x1>; + compatible = "ti,tmp451"; + reg = <0x4c>; + sensor-name = "tmp451-ext"; + supported-hwrev = <0x1>; + offset = <0xffffffd4>; + conv-rate = <0x6>; + extended-rage = <0x1>; + interrupt-parent = <0x28>; + interrupts = <0x10 0x8>; + temp-alert-gpio = <0x28 0x10 0x0>; + vdd-supply = <0x3d>; + linux,phandle = <0x53>; + phandle = <0x53>; + + loc { + shutdown-limit = <0x6b>; + }; + + ext { + shutdown-limit = <0x6b>; + }; + }; + }; + + i2c@31e0000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + compatible = "nvidia,tegra186-i2c"; + reg = <0x0 0x31e0000 0x0 0x100>; + interrupts = <0x0 0x21 0x4>; + scl-gpio = <0x1b 0x5a 0x0>; + sda-gpio = <0x1b 0x5b 0x0>; + status = "okay"; + clock-frequency = <0x61a80>; + clocks = <0x10 0xb7 0x10 0x10d 0x10 0x5c>; + clock-names = "div-clk", "parent", "slow-clk"; + resets = <0x10 0x53>; + reset-names = "i2c"; + dmas = <0x25 0x1f 0x25 0x1f>; + dma-names = "rx", "tx"; + linux,phandle = <0x180>; + phandle = <0x180>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + }; + + spdif_dit { + compatible = "simple-bus"; + device_type = "spdif-dit"; + #address-cells = <0x1>; + #size-cells = <0x0>; + status = "okay"; + + spdif-dit.0@0 { + compatible = "linux,spdif-dit"; + reg = <0x0>; + status = "okay"; + linux,phandle = <0xba>; + phandle = <0xba>; + }; + + spdif-dit.1@1 { + compatible = "linux,spdif-dit"; + reg = <0x1>; + status = "okay"; + linux,phandle = <0xbc>; + phandle = <0xbc>; + }; + + spdif-dit.2@2 { + compatible = "linux,spdif-dit"; + reg = <0x2>; + status = "okay"; + linux,phandle = <0xbe>; + phandle = <0xbe>; + }; + + spdif-dit.3@3 { + compatible = "linux,spdif-dit"; + reg = <0x3>; + status = "okay"; + linux,phandle = <0xc0>; + phandle = <0xc0>; + }; + + spdif-dit.4@4 { + compatible = "linux,spdif-dit"; + reg = <0x4>; + status = "okay"; + linux,phandle = <0xc2>; + phandle = <0xc2>; + }; + + spdif-dit.5@5 { + compatible = "linux,spdif-dit"; + reg = <0x5>; + status = "okay"; + linux,phandle = <0x181>; + phandle = <0x181>; + }; + + spdif-dit.6@6 { + compatible = "linux,spdif-dit"; + reg = <0x6>; + status = "okay"; + linux,phandle = <0xc4>; + phandle = <0xc4>; + }; + + spdif-dit.7@7 { + compatible = "linux,spdif-dit"; + reg = <0x7>; + status = "okay"; + linux,phandle = <0xc6>; + phandle = <0xc6>; + }; + + spdif-dit.8@8 { + compatible = "linux,spdif-dit"; + reg = <0x8>; + status = "okay"; + linux,phandle = <0xc8>; + phandle = <0xc8>; + }; + + spdif-dit.9@9 { + compatible = "linux,spdif-dit"; + reg = <0x9>; + status = "okay"; + linux,phandle = <0xca>; + phandle = <0xca>; + }; + + spdif-dit.10@a { + compatible = "linux,spdif-dit"; + reg = <0xa>; + status = "okay"; + linux,phandle = <0xcc>; + phandle = <0xcc>; + }; + + spdif-dit.11@b { + compatible = "linux,spdif-dit"; + reg = <0xb>; + status = "okay"; + linux,phandle = <0xd0>; + phandle = <0xd0>; + }; + + spdif-dit.12@c { + compatible = "linux,spdif-dit"; + reg = <0xc>; + status = "okay"; + linux,phandle = <0xd1>; + phandle = <0xd1>; + }; + + spdif-dit.13@d { + compatible = "linux,spdif-dit"; + reg = <0xd>; + status = "okay"; + linux,phandle = <0xce>; + phandle = <0xce>; + }; + }; + + spi@3210000 { + compatible = "nvidia,tegra186-spi"; + reg = <0x0 0x3210000 0x0 0x10000>; + interrupts = <0x0 0x24 0x4>; + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + dmas = <0x25 0xf 0x25 0xf>; + dma-names = "rx", "tx"; + nvidia,clk-parents = "pll_p", "clk_m"; + clocks = <0x10 0x31 0x10 0x10d 0x10 0x261>; + clock-names = "spi", "pll_p", "clk_m"; + resets = <0x10 0x28>; + reset-names = "spi"; + status = "okay"; + linux,phandle = <0x182>; + phandle = <0x182>; + }; + + spi@c260000 { + compatible = "nvidia,tegra186-spi"; + reg = <0x0 0xc260000 0x0 0x10000>; + interrupts = <0x0 0x25 0x4>; + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + dmas = <0x25 0x10 0x25 0x10>; + dma-names = "rx", "tx"; + nvidia,clk-parents = "pll_p", "osc"; + spi-max-frequency = <0xb71b00>; + clocks = <0x10 0xde 0x10 0x10d 0x10 0x264>; + clock-names = "spi", "pll_p", "osc"; + resets = <0x10 0x29>; + reset-names = "spi"; + status = "okay"; + linux,phandle = <0x183>; + phandle = <0x183>; + + spi-touch-sharp19x12@0 { + avdd-supply = <0x3e>; + dvdd-supply = <0x3f>; + status = "okay"; + compatible = "sharp,lr388k7_ts"; + reg = <0x0>; + spi-max-frequency = <0xb71b00>; + irq-gpio = <0x28 0x2f 0x1>; + interrupt-parent = <0x28>; + interrupts = <0x2f 0x1>; + reset-gpio = <0x28 0x3 0x0>; + clock-sel-gpio = <0x40 0x1 0x0>; + x-max = <0x2580>; + y-max = <0x3c00>; + z-max = <0xffff>; + flip-x = <0x1>; + flip-y = <0x1>; + touch-num-max = <0xa>; + platform-id = <0x1>; + }; + + prod-settings { + + prod_c_cs0 { + prod = <0x4 0xfc0 0x400>; + }; + }; + }; + + spi@3230000 { + compatible = "nvidia,tegra186-spi"; + reg = <0x0 0x3230000 0x0 0x10000>; + interrupts = <0x0 0x26 0x4>; + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + dmas = <0x25 0x11 0x25 0x11>; + dma-names = "rx", "tx"; + nvidia,clk-parents = "pll_p", "clk_m"; + clocks = <0x10 0x2e 0x10 0x10d 0x10 0x261>; + clock-names = "spi", "pll_p", "clk_m"; + resets = <0x10 0x2a>; + reset-names = "spi"; + status = "disabled"; + linux,phandle = <0x184>; + phandle = <0x184>; + }; + + spi@3240000 { + compatible = "nvidia,tegra186-spi"; + reg = <0x0 0x3240000 0x0 0x10000>; + interrupts = <0x0 0x27 0x4>; + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + dmas = <0x25 0x12 0x25 0x12>; + dma-names = "rx", "tx"; + nvidia,clk-parents = "pll_p", "clk_m"; + clocks = <0x10 0x4a 0x10 0x10d 0x10 0x261>; + clock-names = "spi", "pll_p", "clk_m"; + resets = <0x10 0x2b>; + reset-names = "spi"; + status = "okay"; + linux,phandle = <0x185>; + phandle = <0x185>; + + spi@0 { + compatible = "spidev"; + reg = <0x0>; + spi-max-frequency = <0x1f78a40>; + + controller-data { + nvidia,enable-hw-based-cs; + nvidia,rx-clk-tap-delay = <0x8>; + nvidia,tx-clk-tap-delay = <0x16>; + }; + }; + + spi@1 { + compatible = "spidev"; + reg = <0x1>; + spi-max-frequency = <0x1f78a40>; + + controller-data { + nvidia,enable-hw-based-cs; + nvidia,rx-clk-tap-delay = <0x8>; + nvidia,tx-clk-tap-delay = <0x16>; + }; + }; + }; + + spi@3270000 { + compatible = "nvidia,tegra186-qspi"; + reg = <0x0 0x3270000 0x0 0x10000>; + interrupts = <0x0 0x23 0x4>; + #address-cells = <0x1>; + #size-cells = <0x0>; + iommus = <0x11 0x20>; + dmas = <0x25 0x5 0x25 0x5>; + dma-names = "rx", "tx"; + nvidia,clk-parents = "pll_p"; + clocks = <0x10 0x84 0x10 0x135 0x10 0x10d 0x10 0x261>; + clock-names = "qspi", "qspi_out", "pll_p", "clk_m"; + resets = <0x10 0x81>; + reset-names = "qspi"; + status = "disabled"; + linux,phandle = <0x186>; + phandle = <0x186>; + + prod-settings { + + prod { + prod = <0x4 0x7cff 0x0>; + }; + }; + }; + + aon_spi@c260000 { + status = "disabled"; + compatible = "nvidia,tegra186-aon-spi"; + bus-number = <0x1>; + #address-cells = <0x1>; + #size-cells = <0x0>; + spi-max-frequency = <0xb71b00>; + mboxes = <0x41 0x2>; + linux,phandle = <0x187>; + phandle = <0x187>; + }; + + pwm@3280000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0x3280000 0x0 0x10000>; + clocks = <0x10 0xbb 0x10 0x10d 0x10 0x261>; + clock-names = "pwm", "parent", "slow-parent"; + #pwm-cells = <0x2>; + resets = <0x10 0x63>; + reset-names = "pwm"; + status = "okay"; + linux,phandle = <0x27>; + phandle = <0x27>; + }; + + pwm@3290000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0x3290000 0x0 0x10000>; + clocks = <0x10 0xbc 0x10 0x10d 0x10 0x261>; + clock-names = "pwm", "parent", "slow-parent"; + #pwm-cells = <0x2>; + resets = <0x10 0x64>; + reset-names = "pwm"; + status = "okay"; + linux,phandle = <0x188>; + phandle = <0x188>; + }; + + pwm@32a0000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0x32a0000 0x0 0x10000>; + clocks = <0x10 0xbd 0x10 0x10d 0x10 0x261>; + clock-names = "pwm", "parent", "slow-parent"; + #pwm-cells = <0x2>; + resets = <0x10 0x65>; + reset-names = "pwm"; + status = "okay"; + linux,phandle = <0xeb>; + phandle = <0xeb>; + }; + + pwm@c340000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0xc340000 0x0 0x10000>; + clocks = <0x10 0xe1>; + clock-names = "pwm"; + #pwm-cells = <0x2>; + resets = <0x10 0x66>; + reset-names = "pwm"; + status = "okay"; + linux,phandle = <0xec>; + phandle = <0xec>; + }; + + pwm@32c0000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0x32c0000 0x0 0x10000>; + clocks = <0x10 0xbe 0x10 0x10d 0x10 0x261>; + clock-names = "pwm", "parent", "slow-parent"; + #pwm-cells = <0x2>; + resets = <0x10 0x67>; + reset-names = "pwm"; + status = "disabled"; + linux,phandle = <0x189>; + phandle = <0x189>; + }; + + pwm@32d0000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0x32d0000 0x0 0x10000>; + clocks = <0x10 0xbf 0x10 0x10d 0x10 0x261>; + clock-names = "pwm", "parent", "slow-parent"; + #pwm-cells = <0x2>; + resets = <0x10 0x68>; + reset-names = "pwm"; + status = "disabled"; + linux,phandle = <0x18a>; + phandle = <0x18a>; + }; + + pwm@32e0000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0x32e0000 0x0 0x10000>; + clocks = <0x10 0xc0 0x10 0x10d 0x10 0x261>; + clock-names = "pwm", "parent", "slow-parent"; + #pwm-cells = <0x2>; + resets = <0x10 0x69>; + reset-names = "pwm"; + status = "disabled"; + linux,phandle = <0x18b>; + phandle = <0x18b>; + }; + + pwm@32f0000 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0x32f0000 0x0 0x10000>; + clocks = <0x10 0xc1 0x10 0x10d 0x10 0x261>; + clock-names = "pwm", "parent", "slow-parent"; + #pwm-cells = <0x2>; + resets = <0x10 0x6a>; + reset-names = "pwm"; + status = "disabled"; + linux,phandle = <0x18c>; + phandle = <0x18c>; + }; + + serial@3100000 { + compatible = "nvidia,tegra20-uart", "nvidia,tegra186-hsuart"; + iommus = <0x11 0x20>; + reg = <0x0 0x3100000 0x0 0x40>; + reg-shift = <0x2>; + interrupts = <0x0 0x70 0x4>; + nvidia,memory-clients = <0xe>; + dmas = <0x25 0x8 0x25 0x8>; + dma-names = "rx", "tx"; + clocks = <0x10 0x37 0x10 0x10d>; + clock-names = "serial", "parent"; + status = "okay"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + console-port; + sqa-automation-port; + linux,phandle = <0x103>; + phandle = <0x103>; + }; + + serial@3110000 { + compatible = "nvidia,tegra186-hsuart"; + iommus = <0x11 0x20>; + reg = <0x0 0x3110000 0x0 0x40>; + reg-shift = <0x2>; + interrupts = <0x0 0x71 0x4>; + nvidia,memory-clients = <0xe>; + dmas = <0x25 0x9 0x25 0x9>; + dma-names = "rx", "tx"; + clocks = <0x10 0x38 0x10 0x10d>; + clock-names = "serial", "parent"; + resets = <0x10 0x30>; + reset-names = "serial"; + status = "NILL"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + linux,phandle = <0x18d>; + phandle = <0x18d>; + }; + + serial@c280000 { + compatible = "nvidia,tegra186-hsuart"; + iommus = <0x11 0x20>; + reg = <0x0 0xc280000 0x0 0x40>; + reg-shift = <0x2>; + interrupts = <0x0 0x72 0x4>; + nvidia,memory-clients = <0xe>; + dmas = <0x25 0x3 0x25 0x3>; + dma-names = "rx", "tx"; + clocks = <0x10 0xd7 0x10 0x10d>; + clock-names = "serial", "parent"; + resets = <0x10 0x31>; + reset-names = "serial"; + status = "NILL"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + linux,phandle = <0x18e>; + phandle = <0x18e>; + }; + + serial@3130000 { + compatible = "nvidia,tegra186-hsuart"; + iommus = <0x11 0x20>; + reg = <0x0 0x3130000 0x0 0x40>; + reg-shift = <0x2>; + interrupts = <0x0 0x73 0x4>; + nvidia,memory-clients = <0xe>; + dmas = <0x25 0x13 0x25 0x13>; + dma-names = "tx"; + clocks = <0x10 0x4d 0x10 0x10d>; + clock-names = "serial", "parent"; + resets = <0x10 0x32>; + reset-names = "serial"; + status = "NILL"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + linux,phandle = <0x18f>; + phandle = <0x18f>; + }; + + serial@3140000 { + compatible = "nvidia,tegra186-hsuart"; + iommus = <0x11 0x20>; + reg = <0x0 0x3140000 0x0 0x40>; + reg-shift = <0x2>; + interrupts = <0x0 0x74 0x4>; + nvidia,memory-clients = <0xe>; + dmas = <0x25 0x14 0x25 0x14>; + dma-names = "rx", "tx"; + clocks = <0x10 0xc2 0x10 0x10d>; + clock-names = "serial", "parent"; + resets = <0x10 0x84>; + reset-names = "serial"; + status = "disabled"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + linux,phandle = <0x190>; + phandle = <0x190>; + }; + + serial@3150000 { + compatible = "nvidia,tegra186-hsuart"; + iommus = <0x11 0x20>; + reg = <0x0 0x3150000 0x0 0x40>; + reg-shift = <0x2>; + interrupts = <0x0 0x75 0x4>; + nvidia,memory-clients = <0xe>; + dmas = <0x25 0xc 0x25 0xc>; + dma-names = "rx", "tx"; + clocks = <0x10 0xc3 0x10 0x10d>; + clock-names = "serial", "parent"; + resets = <0x10 0x6f>; + reset-names = "serial"; + status = "disabled"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + linux,phandle = <0x191>; + phandle = <0x191>; + }; + + serial@c290000 { + compatible = "nvidia,tegra186-hsuart"; + iommus = <0x11 0x20>; + reg = <0x0 0xc290000 0x0 0x40>; + reg-shift = <0x2>; + interrupts = <0x0 0x76 0x4>; + nvidia,memory-clients = <0xe>; + dmas = <0x25 0x2 0x25 0x2>; + dma-names = "rx", "tx"; + clocks = <0x10 0xd8 0x10 0x10d>; + clock-names = "serial", "parent"; + resets = <0x10 0x70>; + reset-names = "serial"; + status = "disabled"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + linux,phandle = <0x192>; + phandle = <0x192>; + }; + + combined-uart { + compatible = "nvidia,tegra186-combined-uart"; + reg = <0x0 0x3c10000 0x0 0x4 0x0 0xc168000 0x0 0x4 0x0 0x3c00000 0x0 0x1000>; + interrupts = <0x0 0x78 0x4>; + status = "NILL"; + }; + + ether_qos@2490000 { + compatible = "nvidia,eqos"; + reg = <0x0 0x2490000 0x0 0x10000>; + reg-names = "eqos_base"; + interrupts = <0x0 0xc2 0x4 0x0 0xc3 0x4 0x0 0xbe 0x4 0x0 0xba 0x4 0x0 0xbf 0x4 0x0 0xbb 0x4 0x0 0xc0 0x4 0x0 0xbc 0x4 0x0 0xc1 0x4 0x0 0xbd 0x4>; + nvidia,csr_clock_speed = <0x19>; + nvidia,iso_bw = <0x14000>; + nvidia,rx_riwt = <0x7c>; + nvidia,local-mac-address = <0x0 0x0 0x0 0x0 0x0 0x0>; + clocks = <0x10 0xa7 0x10 0xa8 0x10 0xef 0x10 0xf0 0x10 0x95>; + clock-names = "eqos_axi", "eqos_rx", "eqos_ptp_ref", "eqos_tx", "axi_cbb"; + resets = <0x10 0x45>; + reset-names = "eqos_rst"; + iommus = <0x11 0x14>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommu_sodev_map; + phy-mode = "rgmii"; + status = "okay"; + pinctrl-names = "idle", "default"; + pinctrl-0 = <0x42>; + pinctrl-1 = <0x43>; + nvidia,ptp_ref_clock_speed = <0x7d>; + nvidia,rxq_enable_ctrl = <0x2 0x2 0x2 0x2>; + nvidia,queue_prio = <0x0 0x1 0x2 0x3>; + nvidia,use_tagged_ptp; + nvidia,ptp_dma_ch = <0x3>; + nvidia,chan_napi_quota = <0x40 0x40 0x40 0x40>; + nvidia,pause_frames = <0x0>; + nvidia,phy-reset-gpio = <0x1b 0x64 0x0>; + nvidia,phy-max-frame-size = <0xa>; + nvidia,eth_iso_enable = <0x1>; + nvidia,brcm_phy_apd_mode; + phy-handle = <0x44>; + vddio_sys_enet_bias-supply = <0x12>; + vddio_enet-supply = <0x13>; + phy_vdd_1v8-supply = <0x12>; + phy_ovdd_rgmii-supply = <0x13>; + phy_pllvdd-supply = <0x3c>; + + eqos-cool-dev { + cooling-min-state = <0x0>; + cooling-max-state = <0x5>; + #cooling-cells = <0x2>; + linux,phandle = <0x4c>; + phandle = <0x4c>; + }; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x0 0x8800 0xdff7ffff 0x8000007>; + }; + }; + + mdio { + compatible = "nvidia,eqos-mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ethernet-phy@0 { + interrupt-parent = <0x1b>; + interrupts = <0x65 0x8>; + reg = <0x0>; + linux,phandle = <0x44>; + phandle = <0x44>; + }; + }; + }; + + ether_qos_virt_test@2490000 { + compatible = "synopsys,dwc_eqos_virt_test"; + reg = <0x0 0x2490000 0x0 0x10000 0x0 0x24a0000 0x0 0x10000>; + status = "disabled"; + }; + + power-domain { + compatible = "tegra-power-domains"; + + ape-pd { + compatible = "nvidia,tegra186-ape-pd"; + is_off; + #power-domain-cells = <0x0>; + partition-id = <0x0>; + clocks = <0x10 0x69 0x10 0x68 0x10 0x8a 0x10 0x111>; + clock-names = "ape", "apb2ape", "adsp", "aclk"; + linux,phandle = <0x45>; + phandle = <0x45>; + }; + + adsp-pd { + compatible = "nvidia,tegra186-adsp-pd"; + is_off; + #power-domain-cells = <0x0>; + power-domains = <0x45>; + linux,phandle = <0x193>; + phandle = <0x193>; + }; + + pcie-pd { + compatible = "nvidia,tegra186-pcie-pd"; + is_off; + #power-domain-cells = <0x0>; + partition-id = <0x9>; + linux,phandle = <0x194>; + phandle = <0x194>; + }; + + sata-pd { + compatible = "nvidia,tegra186-sata-pd"; + #power-domain-cells = <0x0>; + partition-id = <0xa>; + linux,phandle = <0x195>; + phandle = <0x195>; + }; + + disa-pd { + compatible = "nvidia,tegra186-disa-pd"; + #power-domain-cells = <0x0>; + partition-id = <0x2>; + linux,phandle = <0x94>; + phandle = <0x94>; + }; + + disb-pd { + compatible = "nvidia,tegra186-disb-pd"; + #power-domain-cells = <0x0>; + partition-id = <0x3>; + linux,phandle = <0x196>; + phandle = <0x196>; + }; + + disc-pd { + compatible = "nvidia,tegra186-disc-pd"; + #power-domain-cells = <0x0>; + partition-id = <0x4>; + linux,phandle = <0x197>; + phandle = <0x197>; + }; + + xusba-pd { + compatible = "nvidia,tegra186-xusba-pd"; + #power-domain-cells = <0x0>; + partition-id = <0xd>; + linux,phandle = <0x198>; + phandle = <0x198>; + }; + + xusbb-pd { + compatible = "nvidia,tegra186-xusbb-pd"; + #power-domain-cells = <0x0>; + partition-id = <0xe>; + linux,phandle = <0x199>; + phandle = <0x199>; + }; + + xusbc-pd { + compatible = "nvidia,tegra186-xusbc-pd"; + #power-domain-cells = <0x0>; + partition-id = <0xf>; + linux,phandle = <0x19a>; + phandle = <0x19a>; + }; + }; + + trusty { + compatible = "android,trusty-smc-v1"; + ranges; + #address-cells = <0x2>; + #size-cells = <0x2>; + status = "NILL"; + + irq { + compatible = "android,trusty-irq-v1"; + interrupt-templates = <0x46 0x0 0x1 0x1 0x1 0x0 0x1 0x1 0x0 0x0>; + interrupt-ranges = <0x0 0xf 0x0 0x10 0x1f 0x1 0x20 0x1ae 0x2>; + }; + + fiq { + compatible = "android,trusty-fiq-v1"; + }; + + virtio { + compatible = "android,trusty-virtio-v1"; + }; + + log { + compatible = "android,trusty-log-v1"; + }; + + ote { + compatible = "android,trusty-ote-v1"; + }; + }; + + interrupt-controller { + compatible = "android,CustomIPI"; + #interrupt-cells = <0x1>; + interrupt-controller; + linux,phandle = <0x46>; + phandle = <0x46>; + }; + + thermal-zones { + status = "okay"; + + BCPU-therm { + polling-delay = <0x0>; + polling-delay-passive = <0x1f4>; + thermal-sensors = <0x47 0x2>; + status = "okay"; + + thermal-zone-params { + governor-name = "step_wise"; + }; + + trips { + + trip_critical { + temperature = <0x18894>; + type = "critical"; + hysteresis = <0x0>; + writable; + }; + + trip_bthrot { + temperature = <0x1750c>; + type = "passive"; + hysteresis = <0x0>; + writable; + linux,phandle = <0x48>; + phandle = <0x48>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x48>; + cdev-type = "cpu-balanced"; + cooling-device = <0x49 0xffffffff 0xffffffff>; + }; + }; + }; + + MCPU-therm { + polling-delay = <0x0>; + polling-delay-passive = <0x1f4>; + thermal-sensors = <0x47 0x4>; + status = "okay"; + + thermal-zone-params { + governor-name = "step_wise"; + }; + + trips { + + trip_critical { + temperature = <0x18894>; + type = "critical"; + hysteresis = <0x0>; + writable; + }; + + trip_bthrot { + temperature = <0x1750c>; + type = "passive"; + hysteresis = <0x0>; + writable; + linux,phandle = <0x4a>; + phandle = <0x4a>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x4a>; + cdev-type = "cpu-balanced"; + cooling-device = <0x49 0xffffffff 0xffffffff>; + }; + }; + }; + + GPU-therm { + polling-delay = <0x0>; + polling-delay-passive = <0xfa>; + thermal-sensors = <0x47 0x6>; + status = "okay"; + + trips { + + eqos-m40@-40000 { + temperature = <0xffff63c0>; + hysteresis = <0x1388>; + type = "active"; + linux,phandle = <0x4b>; + phandle = <0x4b>; + }; + + eqos-m5@-5000 { + temperature = <0xffffec78>; + hysteresis = <0x1388>; + type = "active"; + linux,phandle = <0x4d>; + phandle = <0x4d>; + }; + + eqos-p30@30000 { + temperature = <0x7530>; + hysteresis = <0x1388>; + type = "active"; + linux,phandle = <0x4e>; + phandle = <0x4e>; + }; + + eqos-p65@65000 { + temperature = <0xfde8>; + hysteresis = <0x1388>; + type = "active"; + linux,phandle = <0x4f>; + phandle = <0x4f>; + }; + + eqos-p100@100000 { + temperature = <0x186a0>; + hysteresis = <0x1388>; + type = "active"; + linux,phandle = <0x50>; + phandle = <0x50>; + }; + + trip_critical { + temperature = <0x18894>; + type = "critical"; + hysteresis = <0x0>; + writable; + }; + + trip_bthrot { + temperature = <0x1750c>; + type = "passive"; + hysteresis = <0x0>; + writable; + linux,phandle = <0x51>; + phandle = <0x51>; + }; + }; + + cooling-maps { + + map_eqos_m40 { + trip = <0x4b>; + cooling-device = <0x4c 0x1 0x1>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_m5 { + trip = <0x4d>; + cooling-device = <0x4c 0x2 0x2>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_p30 { + trip = <0x4e>; + cooling-device = <0x4c 0x3 0x3>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_p65 { + trip = <0x4f>; + cooling-device = <0x4c 0x4 0x4>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_p100 { + trip = <0x50>; + cooling-device = <0x4c 0x5 0x5>; + cdev-type = "tegra-eqos"; + }; + + map0 { + trip = <0x51>; + cdev-type = "gpu-balanced"; + cooling-device = <0x52 0xffffffff 0xffffffff>; + }; + }; + + thermal-zone-params { + governor-name = "step_wise"; + }; + }; + + PLL-therm { + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + thermal-sensors = <0x47 0x5>; + status = "okay"; + }; + + AO-therm { + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + thermal-sensors = <0x47 0x6>; + status = "disabled"; + linux,phandle = <0xe7>; + phandle = <0xe7>; + }; + + Tboard_tegra { + status = "okay"; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + thermal-sensors = <0x53 0x0>; + linux,phandle = <0xf5>; + phandle = <0xf5>; + + thermal-zone-params { + governor-name = "pid_thermal_gov"; + }; + + trips { + + trip_critical { + type = "critical"; + temperature = <0x1a1f8>; + hysteresis = <0x1>; + }; + }; + }; + + Tdiode_tegra { + status = "okay"; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + thermal-sensors = <0x53 0x1>; + linux,phandle = <0x19b>; + phandle = <0x19b>; + + thermal-zone-params { + governor-name = "pid_thermal_gov"; + }; + + trips { + + trip_critical { + temperature = <0x1a1f8>; + type = "critical"; + hysteresis = <0x0>; + writable; + }; + }; + }; + + PMIC-Die { + polling-delay = <0x0>; + polling-delay-passive = <0x0>; + thermal-sensors = <0x22>; + + trips { + + hot-die { + temperature = <0x1d4c0>; + type = "active"; + hysteresis = <0x0>; + linux,phandle = <0x54>; + phandle = <0x54>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x54>; + cooling-device = <0x55 0xffffffff 0xffffffff>; + contribution = <0x64>; + cdev-type = "emergency-balanced"; + }; + }; + }; + }; + + rtcpu@b000000 { + compatible = "nvidia,tegra186-sce-ivc"; + status = "okay"; + reg = <0x0 0xb000000 0x0 0x1000 0x0 0xb1f0000 0x0 0x40000 0x0 0xb230000 0x0 0x10000 0x0 0xb040000 0x0 0x10000 0x0 0xb050000 0x0 0x10000>; + reg-names = "sce-evp", "sce-pm", "sce-cfg", "ast-cpu", "ast-dma"; + iommus = <0x11 0x2a>; + iommu-resv-regions = <0x0 0x0 0x0 0xa0000000 0x0 0xc0000000 0xffffffff 0xffffffff>; + clocks = <0x10 0xe6 0x10 0xe4>; + clock-names = "sce-apb", "sce-cpu-nic"; + nvidia,clock-rates = <0x6146580 0x6146580 0x6ddd000 0x1c3a9000>; + resets = <0x10 0xbb 0x10 0xb8 0x10 0xb5 0x10 0xb6 0x10 0xb7 0x10 0xb9 0x10 0xbc 0x10 0xbd 0x10 0xbe 0x10 0xb4 0x10 0xb3>; + reset-names = "tsctnsce", "sce-pm", "sce-dbgresetn", "sce-presetdbgn", "sce-actmon", "sce-dma", "sce-tke", "sce-gte", "sce-cfg", "sce-nreset", "sce-nsysporeset"; + nvidia,reset-group-1 = "tsctnsce", "sce-pm", "sce-dbgresetn", "sce-presetdbgn", "sce-actmon", "sce-dma", "sce-tke", "sce-gte", "sce-cfg"; + nvidia,reset-group-2 = "sce-nreset", "sce-nsysporeset"; + nvidia,memory-bw = <0xffffffff>; + interrupts = <0x0 0x10 0x4>; + interrupt-names = "wdt-remote"; + nvidia,trace = <0x56 0x4 0x70100000 0x100000>; + nvidia,ivc-channels = <0x57 0x2 0x90000000 0x10000>; + nvidia,autosuspend-delay-ms = <0x1388>; + nvidia,ch-base = <0x3c>; + nvidia,nb-channels = <0x2>; + nvidia,pts-base = <0x23c>; + nvidia,nb-pts = <0x4>; + linux,phandle = <0x19c>; + phandle = <0x19c>; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + nvidia,hsp-shared-mailbox = <0x58 0x1 0x58 0x6>; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + }; + }; + + tegra-rtcpu-sce-trace { + nvidia,enable-printk; + nvidia,interval-ms = <0x32>; + nvidia,log-prefix = "[SCE]"; + linux,phandle = <0x56>; + phandle = <0x56>; + }; + + sce-ivc-channels { + linux,phandle = <0x57>; + phandle = <0x57>; + + echo@0 { + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,devname = "camchar-echo"; + nvidia,service = "echo"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x40>; + }; + + i2c@480 { + compatible = "nvidia,tegra186-camera-ivc-rpc-i2c-single"; + nvidia,service = "i2c-single"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x8>; + nvidia,frame-size = <0x80>; + device = <0x59>; + status = "okay"; + }; + + vinotify@12c0 { + compatible = "nvidia,tegra186-camera-ivc-protocol-vinotify"; + nvidia,service = "vinotify"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x40>; + nvidia,frame-size = <0x80>; + device = <0x5a>; + }; + + mods@32c0 { + compatible = "nvidia,tegra186-camera-ivc-protocol-mods"; + nvidia,service = "mods"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,frame-size = <0x40>; + }; + + ivccontrol@52c0 { + compatible = "nvidia,tegra186-camera-ivc-protocol-capture-control"; + nvidia,service = "capture-control"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x140>; + }; + + ivccapture@72c0 { + compatible = "nvidia,tegra186-camera-ivc-protocol-capture"; + nvidia,service = "capture"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x40>; + }; + + dbg@7c00 { + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,devname = "camchar-dbg"; + nvidia,service = "debug"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,frame-size = <0x180>; + }; + + dbg@7e00 { + compatible = "nvidia,tegra186-camera-ivc-protocol-debug"; + nvidia,service = "debug"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,frame-size = <0x2000>; + nvidia,ivc-timeout = <0x32>; + nvidia,test-timeout = <0x1388>; + }; + }; + + aconnect@2a41000 { + compatible = "nvidia,tegra210-aconnect"; + clocks = <0x10 0x69 0x10 0x68>; + power-domains = <0x1f 0x0>; + clock-names = "ape", "apb2ape"; + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + status = "okay"; + + rtcpu@2993000 { + compatible = "nvidia,tegra186-ape-ivc"; + status = "disabled"; + reg = <0x0 0x2993000 0x0 0x1000 0x0 0x2990000 0x0 0x800 0x0 0x2994000 0x0 0x2000>; + reg-names = "ape-evp", "ape-amisc", "ast-cpu"; + iommus = <0x11 0x2d>; + iommu-group-id = <0x3>; + clocks = <0x10 0x69 0x10 0x68 0x10 0x8b 0x10 0x8a>; + clock-names = "ape", "apb2ape", "adspneon", "adsp"; + resets = <0x10 0xbf>; + reset-names = "adsp-all"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x3e 0x4 0x0 0x0 0x3f 0x4 0x0 0x0 0x54 0x4 0x0 0x0 0x1f 0x4 0x4 0x0 0x30 0x4 0x4 0x0 0x44 0x4 0x4 0x0 0x45 0x4 0x4 0x0 0x47 0x4 0x4 0x0 0x46 0x4 0x4 0x0 0x48 0x4 0x4 0x0 0x49 0x4 0x4 0x0 0x4a 0x4 0x4 0x0 0x4b 0x4 0x4 0x0 0x4e 0x4 0x4 0x0 0x4f 0x4 0x4 0x0 0x50 0x4 0x4 0x0 0x53 0x4 0x4 0x0 0x52 0x4 0x4>; + interrupt-names = "adsp-wfi", "adsp-wfe", "wdt-remote"; + nvidia,trace = <0x5c 0x4 0x40200000 0x80000>; + nvidia,ivc-channels = <0x5d 0x2 0x40000000 0x10000>; + nvidia,autosuspend-delay-ms = <0x1388>; + linux,phandle = <0x19d>; + phandle = <0x19d>; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + device = <0x5e>; + nvidia,hsp-shared-mailbox = <0x5e 0x1 0x5e 0x6>; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + }; + }; + + agic-controller@2a41000 { + compatible = "nvidia,tegra186-agic"; + #interrupt-cells = <0x4>; + interrupt-controller; + reg = <0x0 0x2a41000 0x0 0x1000 0x0 0x2a42000 0x0 0x2000>; + interrupts = <0x0 0x91 0xf04>; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "okay"; + linux,phandle = <0x5b>; + phandle = <0x5b>; + }; + + agic-controller@2a51000 { + compatible = "nvidia,tegra186-agic"; + interrupt-controller; + #interrupt-cells = <0x4>; + reg = <0x0 0x2a51000 0x0 0x1000 0x0 0x2a52000 0x0 0x2000>; + interrupts = <0x0 0x92 0xf04>; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "disabled"; + linux,phandle = <0x19e>; + phandle = <0x19e>; + }; + + agic-controller@2a61000 { + compatible = "nvidia,tegra186-agic"; + interrupt-controller; + #interrupt-cells = <0x4>; + reg = <0x0 0x2a61000 0x0 0x1000 0x0 0x2a62000 0x0 0x2000>; + interrupts = <0x0 0x93 0xf04>; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "disabled"; + linux,phandle = <0x19f>; + phandle = <0x19f>; + }; + + tegra-hsp@29a0000 { + compatible = "nvidia,tegra186-hsp"; + reg = <0x0 0x29a0000 0x0 0x90000>; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x20 0x4 0x0 0x0 0x21 0x4 0x0 0x0 0x22 0x4 0x0 0x0 0x23 0x4 0x0 0x0 0x24 0x4 0x0 0x0 0x25 0x4 0x0 0x0 0x26 0x4 0x0 0x0 0x27 0x4 0x0 0x0 0x28 0x4 0x0 0x0 0x29 0x4 0x0 0x0 0x2a 0x4 0x0 0x0 0x2b 0x4 0x0 0x0 0x2c 0x4 0x0 0x0 0x2d 0x4 0x0 0x0 0x2e 0x4 0x0 0x0 0x2f 0x4 0x0 0x0 0x30 0x4 0x4 0x0 0x31 0x4 0x0 0x0 0x32 0x4 0x0 0x0 0x33 0x4 0x0 0x0 0x34 0x4 0x0>; + interrupt-names = "full0", "full1", "full2", "full3", "full4", "full5", "full6", "full7", "empty0", "empty1", "empty2", "empty3", "empty4", "empty5", "empty6", "empty7", "adsp-shared0", "shared1", "shared2", "shared3", "shared4"; + status = "disabled"; + linux,phandle = <0x5e>; + phandle = <0x5e>; + }; + + adma@2930000 { + compatible = "nvidia,tegra186-adma"; + interrupt-parent = <0x5b>; + reg = <0x0 0x2930000 0x0 0x50000 0x0 0x29f0000 0x0 0x10>; + clocks = <0x10 0x57>; + clock-names = "d_audio"; + interrupts = <0x0 0x0 0x4 0x0 0x0 0x1 0x4 0x0 0x0 0x2 0x4 0x0 0x0 0x3 0x4 0x0 0x0 0x4 0x4 0x0 0x0 0x5 0x4 0x0 0x0 0x6 0x4 0x0 0x0 0x7 0x4 0x0 0x0 0x8 0x4 0x0 0x0 0x9 0x4 0x0 0x0 0xa 0x4 0x0 0x0 0xb 0x4 0x0 0x0 0xc 0x4 0x0 0x0 0xd 0x4 0x0 0x0 0xe 0x4 0x0 0x0 0xf 0x4 0x0 0x0 0x10 0x4 0x0 0x0 0x11 0x4 0x0 0x0 0x12 0x4 0x0 0x0 0x13 0x4 0x0 0x0 0x14 0x4 0x0 0x0 0x15 0x4 0x0 0x0 0x16 0x4 0x0 0x0 0x17 0x4 0x0 0x0 0x18 0x4 0x0 0x0 0x19 0x4 0x0 0x0 0x1a 0x4 0x0 0x0 0x1b 0x4 0x0 0x0 0x1c 0x4 0x0 0x0 0x1d 0x4 0x0 0x0 0x1e 0x4 0x0 0x0 0x1f 0x4 0x0>; + #dma-cells = <0x1>; + status = "okay"; + linux,phandle = <0x5f>; + phandle = <0x5f>; + }; + + ahub { + compatible = "nvidia,tegra186-axbar"; + wakeup-disable; + reg = <0x0 0x2900800 0x0 0x800>; + clocks = <0x10 0x57 0x10 0xf6 0x10 0x68 0x10 0x69>; + clock-names = "ahub", "parent", "apb2ape", "xbar.ape"; + assigned-clocks = <0x10 0x57>; + assigned-clock-parents = <0x10 0x10d>; + status = "okay"; + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + assigned-clock-rates = <0x2b3bb55>; + linux,phandle = <0xb8>; + phandle = <0xb8>; + + admaif@290f000 { + compatible = "nvidia,tegra186-admaif"; + reg = <0x0 0x290f000 0x0 0x1000>; + clocks = <0x10 0x57>; + clock-names = "ahub"; + dmas = <0x5f 0x1 0x5f 0x1 0x5f 0x2 0x5f 0x2 0x5f 0x3 0x5f 0x3 0x5f 0x4 0x5f 0x4 0x5f 0x5 0x5f 0x5 0x5f 0x6 0x5f 0x6 0x5f 0x7 0x5f 0x7 0x5f 0x8 0x5f 0x8 0x5f 0x9 0x5f 0x9 0x5f 0xa 0x5f 0xa 0x5f 0xb 0x5f 0xb 0x5f 0xc 0x5f 0xc 0x5f 0xd 0x5f 0xd 0x5f 0xe 0x5f 0xe 0x5f 0xf 0x5f 0xf 0x5f 0x10 0x5f 0x10 0x5f 0x11 0x5f 0x11 0x5f 0x12 0x5f 0x12 0x5f 0x13 0x5f 0x13 0x5f 0x14 0x5f 0x14>; + dma-names = "rx1", "tx1", "rx2", "tx2", "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", "rx9", "tx9", "rx10", "tx10", "rx11", "tx11", "rx12", "tx12", "rx13", "tx13", "rx14", "tx14", "rx15", "tx15", "rx16", "tx16", "rx17", "tx17", "rx18", "tx18", "rx19", "tx19", "rx20", "tx20"; + status = "okay"; + dma-buffer-size = <0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000>; + linux,phandle = <0x1a0>; + phandle = <0x1a0>; + }; + + sfc@2902000 { + compatible = "nvidia,tegra210-sfc"; + reg = <0x0 0x2902000 0x0 0x200>; + nvidia,ahub-sfc-id = <0x0>; + status = "okay"; + linux,phandle = <0x1a1>; + phandle = <0x1a1>; + }; + + sfc@2902200 { + compatible = "nvidia,tegra210-sfc"; + reg = <0x0 0x2902200 0x0 0x200>; + nvidia,ahub-sfc-id = <0x1>; + status = "okay"; + linux,phandle = <0x1a2>; + phandle = <0x1a2>; + }; + + sfc@2902400 { + compatible = "nvidia,tegra210-sfc"; + reg = <0x0 0x2902400 0x0 0x200>; + nvidia,ahub-sfc-id = <0x2>; + status = "okay"; + linux,phandle = <0x1a3>; + phandle = <0x1a3>; + }; + + sfc@2902600 { + compatible = "nvidia,tegra210-sfc"; + reg = <0x0 0x2902600 0x0 0x200>; + nvidia,ahub-sfc-id = <0x3>; + status = "okay"; + linux,phandle = <0x1a4>; + phandle = <0x1a4>; + }; + + spkprot@2908c00 { + compatible = "nvidia,tegra210-spkprot"; + reg = <0x0 0x2908c00 0x0 0x400>; + nvidia,ahub-spkprot-id = <0x0>; + status = "okay"; + linux,phandle = <0x1a5>; + phandle = <0x1a5>; + }; + + amixer@290bb00 { + compatible = "nvidia,tegra210-amixer"; + reg = <0x0 0x290bb00 0x0 0x800>; + nvidia,ahub-amixer-id = <0x0>; + status = "okay"; + linux,phandle = <0x1a6>; + phandle = <0x1a6>; + }; + + i2s@2901000 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x0 0x2901000 0x0 0x100>; + nvidia,ahub-i2s-id = <0x0>; + clocks = <0x10 0x4f 0x10 0xf6 0x10 0x269 0x10 0xf7 0x10 0x269>; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + assigned-clocks = <0x10 0x4f>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x177000>; + pinctrl-names = "dap_active", "dap_inactive"; + pinctrl-0; + pinctrl-1; + fsync-width = <0x1f>; + status = "okay"; + linux,phandle = <0xb9>; + phandle = <0xb9>; + }; + + i2s@2901100 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x0 0x2901100 0x0 0x100>; + nvidia,ahub-i2s-id = <0x1>; + clocks = <0x10 0x2a 0x10 0xf6 0x10 0x26a 0x10 0xf8 0x10 0x26a>; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + assigned-clocks = <0x10 0x2a>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x177000>; + pinctrl-names = "dap_active", "dap_inactive"; + pinctrl-0; + pinctrl-1; + fsync-width = <0x0>; + status = "okay"; + linux,phandle = <0xbb>; + phandle = <0xbb>; + }; + + i2s@2901200 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x0 0x2901200 0x0 0x100>; + nvidia,ahub-i2s-id = <0x2>; + clocks = <0x10 0x2b 0x10 0xf6 0x10 0x26b 0x10 0xf9 0x10 0x26b>; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + assigned-clocks = <0x10 0x2b>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x177000>; + pinctrl-names = "dap_active", "dap_inactive"; + pinctrl-0; + pinctrl-1; + fsync-width = <0x1f>; + status = "okay"; + linux,phandle = <0xbd>; + phandle = <0xbd>; + }; + + i2s@2901300 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x0 0x2901300 0x0 0x100>; + nvidia,ahub-i2s-id = <0x3>; + clocks = <0x10 0x54 0x10 0xf6 0x10 0x26c 0x10 0xfa 0x10 0x26c>; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + assigned-clocks = <0x10 0x54>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x177000>; + pinctrl-names = "dap_active", "dap_inactive"; + pinctrl-0; + pinctrl-1; + fsync-width = <0x1f>; + status = "okay"; + linux,phandle = <0xbf>; + phandle = <0xbf>; + }; + + i2s@2901400 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x0 0x2901400 0x0 0x100>; + nvidia,ahub-i2s-id = <0x4>; + clocks = <0x10 0x55 0x10 0xf6 0x10 0x26d 0x10 0xfb 0x10 0x26d>; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + assigned-clocks = <0x10 0x55>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x177000>; + pinctrl-names = "dap_active", "dap_inactive"; + pinctrl-0; + pinctrl-1; + fsync-width = <0x1f>; + status = "okay"; + linux,phandle = <0xc1>; + phandle = <0xc1>; + }; + + i2s@2901500 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x0 0x2901500 0x0 0x100>; + nvidia,ahub-i2s-id = <0x5>; + clocks = <0x10 0x9a 0x10 0xf6 0x10 0x26e 0x10 0xfc 0x10 0x26e>; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + assigned-clocks = <0x10 0x9a>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x177000>; + pinctrl-names = "dap_active", "dap_inactive"; + pinctrl-0; + pinctrl-1; + fsync-width = <0x0>; + status = "okay"; + bclk-ratio = <0x4>; + linux,phandle = <0xc3>; + phandle = <0xc3>; + }; + + amx@2903000 { + compatible = "nvidia,tegra210-amx"; + reg = <0x0 0x2903000 0x0 0x100>; + nvidia,ahub-amx-id = <0x0>; + status = "okay"; + linux,phandle = <0x1a7>; + phandle = <0x1a7>; + }; + + amx@2903100 { + compatible = "nvidia,tegra210-amx"; + reg = <0x0 0x2903100 0x0 0x100>; + nvidia,ahub-amx-id = <0x1>; + status = "okay"; + linux,phandle = <0x1a8>; + phandle = <0x1a8>; + }; + + amx@2903200 { + compatible = "nvidia,tegra210-amx"; + reg = <0x0 0x2903200 0x0 0x100>; + nvidia,ahub-amx-id = <0x2>; + status = "okay"; + linux,phandle = <0x1a9>; + phandle = <0x1a9>; + }; + + amx@2903300 { + compatible = "nvidia,tegra210-amx"; + reg = <0x0 0x2903300 0x0 0x100>; + nvidia,ahub-amx-id = <0x3>; + status = "okay"; + linux,phandle = <0x1aa>; + phandle = <0x1aa>; + }; + + adx@2903800 { + compatible = "nvidia,tegra210-adx"; + reg = <0x0 0x2903800 0x0 0x100>; + nvidia,ahub-adx-id = <0x0>; + status = "okay"; + linux,phandle = <0x1ab>; + phandle = <0x1ab>; + }; + + adx@2903900 { + compatible = "nvidia,tegra210-adx"; + reg = <0x0 0x2903900 0x0 0x100>; + nvidia,ahub-adx-id = <0x1>; + status = "okay"; + linux,phandle = <0x1ac>; + phandle = <0x1ac>; + }; + + adx@2903a00 { + compatible = "nvidia,tegra210-adx"; + reg = <0x0 0x2903a00 0x0 0x100>; + nvidia,ahub-adx-id = <0x2>; + status = "okay"; + linux,phandle = <0x1ad>; + phandle = <0x1ad>; + }; + + adx@2903b00 { + compatible = "nvidia,tegra210-adx"; + reg = <0x0 0x2903b00 0x0 0x100>; + nvidia,ahub-adx-id = <0x3>; + status = "okay"; + linux,phandle = <0x1ae>; + phandle = <0x1ae>; + }; + + dmic@2904000 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x0 0x2904000 0x0 0x100>; + nvidia,ahub-dmic-id = <0x0>; + clocks = <0x10 0x7a 0x10 0xf6>; + clock-names = "dmic", "parent"; + assigned-clocks = <0x10 0x7a>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x2ee000>; + status = "okay"; + linux,phandle = <0xc5>; + phandle = <0xc5>; + }; + + dmic@2904100 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x0 0x2904100 0x0 0x100>; + nvidia,ahub-dmic-id = <0x1>; + clocks = <0x10 0x7b 0x10 0xf6>; + clock-names = "dmic", "parent"; + assigned-clocks = <0x10 0x7b>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x2ee000>; + status = "okay"; + linux,phandle = <0xc7>; + phandle = <0xc7>; + }; + + dmic@2904200 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x0 0x2904200 0x0 0x100 0x0 0xc303000 0x0 0x1f0>; + nvidia,ahub-dmic-id = <0x2>; + clocks = <0x10 0x96 0x10 0xf6>; + clock-names = "dmic", "parent"; + assigned-clocks = <0x10 0x96>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x2ee000>; + status = "okay"; + linux,phandle = <0xc9>; + phandle = <0xc9>; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x28 0xffff 0x6441 0x1 0x30 0xffff 0x6441>; + }; + }; + }; + + dmic@2904300 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x0 0x2904300 0x0 0x100>; + nvidia,ahub-dmic-id = <0x3>; + clocks = <0x10 0x97 0x10 0xf6>; + clock-names = "dmic", "parent"; + assigned-clocks = <0x10 0x97>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0x2ee000>; + status = "okay"; + linux,phandle = <0xcb>; + phandle = <0xcb>; + }; + + afc@2907000 { + compatible = "nvidia,tegra186-afc"; + reg = <0x0 0x2907000 0x0 0x100>; + nvidia,ahub-afc-id = <0x0>; + status = "okay"; + linux,phandle = <0x1af>; + phandle = <0x1af>; + }; + + afc@2907100 { + compatible = "nvidia,tegra186-afc"; + reg = <0x0 0x2907100 0x0 0x100>; + nvidia,ahub-afc-id = <0x1>; + status = "okay"; + linux,phandle = <0x1b0>; + phandle = <0x1b0>; + }; + + afc@2907200 { + compatible = "nvidia,tegra186-afc"; + reg = <0x0 0x2907200 0x0 0x100>; + nvidia,ahub-afc-id = <0x2>; + status = "okay"; + linux,phandle = <0x1b1>; + phandle = <0x1b1>; + }; + + afc@2907300 { + compatible = "nvidia,tegra186-afc"; + reg = <0x0 0x2907300 0x0 0x100>; + nvidia,ahub-afc-id = <0x3>; + status = "okay"; + linux,phandle = <0x1b2>; + phandle = <0x1b2>; + }; + + afc@2907400 { + compatible = "nvidia,tegra186-afc"; + reg = <0x0 0x2907400 0x0 0x100>; + nvidia,ahub-afc-id = <0x4>; + status = "okay"; + linux,phandle = <0x1b3>; + phandle = <0x1b3>; + }; + + afc@2907500 { + compatible = "nvidia,tegra186-afc"; + reg = <0x0 0x2907500 0x0 0x100>; + nvidia,ahub-afc-id = <0x5>; + status = "okay"; + linux,phandle = <0x1b4>; + phandle = <0x1b4>; + }; + + mvc@290a000 { + compatible = "nvidia,tegra210-mvc"; + reg = <0x0 0x290a000 0x0 0x200>; + nvidia,ahub-mvc-id = <0x0>; + status = "okay"; + linux,phandle = <0x1b5>; + phandle = <0x1b5>; + }; + + mvc@290a200 { + compatible = "nvidia,tegra210-mvc"; + reg = <0x0 0x290a200 0x0 0x200>; + nvidia,ahub-mvc-id = <0x1>; + status = "okay"; + linux,phandle = <0x1b6>; + phandle = <0x1b6>; + }; + + iqc@290e000 { + compatible = "nvidia,tegra210-iqc"; + reg = <0x0 0x290e000 0x0 0x200>; + nvidia,ahub-iqc-id = <0x0>; + clocks = <0x10 0x6a>; + clock-names = "iqc"; + status = "okay"; + linux,phandle = <0x1b7>; + phandle = <0x1b7>; + }; + + asrc@2910000 { + compatible = "nvidia,tegra186-asrc"; + reg = <0x0 0x2910000 0x0 0x2000>; + nvidia,ahub-asrc-id = <0x0>; + status = "okay"; + linux,phandle = <0x1b8>; + phandle = <0x1b8>; + }; + + arad@290e400 { + compatible = "nvidia,tegra186-arad"; + reg = <0x0 0x290e400 0x0 0x400>; + nvidia,ahub-arad-id = <0x0>; + status = "okay"; + linux,phandle = <0x1b9>; + phandle = <0x1b9>; + }; + + ahc@290b900 { + compatible = "nvidia,tegra186-ahc"; + interrupt-parent = <0x5b>; + reg = <0x0 0x290b900 0x0 0x200>; + interrupts = <0x0 0x38 0x4 0x0>; + status = "okay"; + linux,phandle = <0x1ba>; + phandle = <0x1ba>; + }; + + ope@2908000 { + compatible = "nvidia,tegra210-ope"; + reg = <0x0 0x2908000 0x0 0x100 0x0 0x2908100 0x0 0x100 0x0 0x2908200 0x0 0x200>; + nvidia,ahub-ope-id = <0x0>; + status = "okay"; + linux,phandle = <0x1bb>; + phandle = <0x1bb>; + + peq@2908100 { + status = "okay"; + }; + + mbdrc@2908200 { + status = "okay"; + }; + }; + + dspk@2905000 { + compatible = "nvidia,tegra186-dspk"; + reg = <0x0 0x2905000 0x0 0x100>; + nvidia,ahub-dspk-id = <0x0>; + clocks = <0x10 0x98 0x10 0xf6 0x10 0xfd>; + clock-names = "dspk", "pll_a_out0", "sync_dspk"; + assigned-clocks = <0x10 0x98>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0xbb8000>; + status = "okay"; + linux,phandle = <0xcd>; + phandle = <0xcd>; + }; + + dspk@2905100 { + compatible = "nvidia,tegra186-dspk"; + reg = <0x0 0x2905100 0x0 0x100 0x0 0x2431000 0x0 0x1f0>; + nvidia,ahub-dspk-id = <0x1>; + clocks = <0x10 0x99 0x10 0xf6 0x10 0xfe>; + clock-names = "dspk", "pll_a_out0", "sync_dspk"; + assigned-clocks = <0x10 0x99>; + assigned-clock-parents = <0x10 0xf6>; + assigned-clock-rates = <0xbb8000>; + status = "okay"; + linux,phandle = <0xcf>; + phandle = <0xcf>; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x8 0xfff 0x441 0x1 0x0 0xfff 0x441>; + }; + }; + }; + }; + + adsp_audio { + compatible = "nvidia,tegra186-adsp-audio"; + wakeup-disable; + iommus = <0x11 0x1e>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommu-group-id = <0x2>; + nvidia,adma_ch_start = <0x10>; + nvidia,adma_ch_cnt = <0x10>; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x10 0x4 0x4 0x0 0x11 0x4 0x4 0x0 0x12 0x4 0x4 0x0 0x13 0x4 0x4 0x0 0x14 0x4 0x4 0x0 0x15 0x4 0x4 0x0 0x16 0x4 0x4 0x0 0x17 0x4 0x4 0x0 0x18 0x4 0x4 0x0 0x19 0x4 0x4 0x0 0x1a 0x4 0x4 0x0 0x1b 0x4 0x4 0x0 0x1c 0x4 0x4 0x0 0x1d 0x4 0x4 0x0 0x1e 0x4 0x4 0x0 0x1f 0x4 0x4>; + clocks = <0x10 0x57 0x10 0x69 0x10 0x68>; + clock-names = "ahub", "ape", "apb2ape"; + status = "okay"; + compr-ops = <0x1>; + num-plugin = <0x5>; + linux,phandle = <0x1bc>; + phandle = <0x1bc>; + + plugin-info-1 { + plugin-name = "mp3-dec1"; + firmware-name = "nvmp3dec.elf"; + widget-name = "MP3-DEC1"; + }; + + plugin-info-2 { + plugin-name = "spkprot"; + firmware-name = "nvspkprot.elf"; + widget-name = "SPKPROT-SW"; + }; + + plugin-info-3 { + plugin-name = "src"; + firmware-name = "nvsrc.elf"; + widget-name = "SRC"; + }; + + plugin-info-4 { + plugin-name = "aac-dec1"; + firmware-name = "nvaacdec.elf"; + widget-name = "AAC-DEC1"; + }; + + plugin-info-5 { + plugin-name = "aec"; + firmware-name = "nvoice.elf"; + widget-name = "AEC"; + }; + }; + + adsp@2993000 { + status = "okay"; + compatible = "nvidia,tegra18x-adsp"; + nvidia,adsp_os_secload; + interrupt-parent = <0x5b>; + reg = <0x0 0x2993000 0x0 0x1000 0x0 0x2990000 0x0 0x2000 0x0 0x0 0x0 0x1 0x0 0x290c800 0x0 0x1 0x0 0x29b0000 0x0 0x90000 0x0 0x40000000 0x0 0xc0000000 0x0 0x0 0x0 0x1>; + nvidia,adsp_mem = <0x5ef00000 0x1000000 0x5f700000 0x800000 0x3f813000 0x5000 0x5fd00000 0x200000>; + nvidia,adsp_unit_fpga_reset = <0x7f00040 0x40>; + nvidia,adsp-evp-base = <0x2993700 0x40>; + interrupts = <0x0 0x29 0x4 0x0 0x0 0x20 0x4 0x0 0x0 0x53 0x4 0x0 0x0 0x3e 0x4 0x0 0x0 0x39 0x4 0x0 0x0 0x41 0x4 0x0 0x0 0x28 0x4 0x4 0x0 0x21 0x4 0x4 0x0 0x22 0x4 0x4 0x0 0x4e 0x4 0x4 0x0 0x4f 0x4 0x4 0x0 0x50 0x4 0x4 0x0 0x4b 0x4 0x4>; + clocks = <0x10 0x8b 0x10 0x8a 0x10 0x111>; + clock-names = "adspneon", "adsp", "aclk"; + resets = <0x10 0xbf>; + reset-names = "adspall"; + iommus = <0x11 0x1e>; + dma-mask = <0x0 0x5e000000>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommu-group-id = <0x2>; + }; + }; + + tegra-rtcpu-ape-trace { + nvidia,enable-printk; + nvidia,interval-ms = <0x32>; + nvidia,log-prefix = "[APE]"; + linux,phandle = <0x5c>; + phandle = <0x5c>; + }; + + ape-ivc-channels { + linux,phandle = <0x5d>; + phandle = <0x5d>; + + echo@0 { + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,devname = "camchar-echo"; + nvidia,service = "echo"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x40>; + }; + + vinotify@12c0 { + compatible = "nvidia,tegra186-camera-ivc-protocol-vinotify"; + nvidia,service = "vinotify"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x40>; + nvidia,frame-size = <0x80>; + device = <0x5a>; + }; + + ivccontrol@52c0 { + compatible = "nvidia,tegra186-camera-ivc-protocol-capture-control"; + nvidia,service = "capture-control"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x140>; + }; + + ivccapture@72c0 { + compatible = "nvidia,tegra186-camera-ivc-protocol-capture"; + nvidia,service = "capture"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x40>; + }; + + dbg@7c00 { + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,devname = "camchar-dbg"; + nvidia,service = "debug"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,frame-size = <0x180>; + }; + + dbg@7e00 { + compatible = "nvidia,tegra186-camera-ivc-protocol-debug"; + nvidia,service = "debug"; + nvidia,version = <0x0>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,frame-size = <0x2000>; + nvidia,ivc-timeout = <0x32>; + nvidia,test-timeout = <0x1388>; + }; + }; + + tegra_safety_ivc { + #address-cells = <0x1>; + #size-cells = <0x0>; + linux,phandle = <0x60>; + phandle = <0x60>; + + cmdresp@0 { + compatible = "nvidia,tegra186-safety-cmd-resp"; + reg = <0x0 0x8000>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x40>; + }; + + hb@0 { + compatible = "nvidia,tegra186-safety-hb"; + reg = <0x500 0x8500>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x1>; + nvidia,frame-size = <0x40>; + }; + }; + + sce@b000000 { + compatible = "nvidia,tegra186-safety-ivc"; + status = "disabled"; + reg = <0x0 0xb040000 0x0 0x10000 0x0 0xb050000 0x0 0x10000>; + reg-names = "ast-cpu", "ast-dma"; + iommus = <0x11 0x1f>; + nvidia,ivc-channels = <0x60 0x2 0x90000000 0x10000>; + linux,phandle = <0x1bd>; + phandle = <0x1bd>; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + nvidia,hsp-shared-mailbox = <0x58 0x1 0x58 0x6>; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + }; + }; + + actmon@d230000 { + status = "okay"; + #address-cells = <0x2>; + #size-cells = <0x2>; + compatible = "nvidia,tegra186-cactmon"; + reg = <0x0 0xd230000 0x0 0x1000>; + interrupts = <0x0 0xd2 0x4>; + clocks = <0x10 0xc9>; + clock-names = "actmon"; + resets = <0x10 0x0>; + reset-names = "actmon_rst"; + nvidia,sample_period = [14]; + + mc_all { + #address-cells = <0x1>; + #size-cells = <0x0>; + nvidia,reg_offs = <0x100>; + nvidia,irq_mask = <0x2>; + nvidia,suspend_freq = <0x31ce0>; + nvidia,boost_freq_step = <0x31ce0>; + nvidia,boost_up_coef = <0xc8>; + nvidia,boost_down_coef = <0x32>; + nvidia,boost_up_threshold = <0x1e>; + nvidia,boost_down_threshold = <0x14>; + nvidia,up_wmark_window = [03]; + nvidia,down_wmark_window = [02]; + nvidia,avg_window_log2 = [06]; + nvidia,count_weight = <0x200>; + nvidia,max_dram_channels = [04]; + nvidia,type = <0x1>; + status = "okay"; + }; + }; + + host1x { + compatible = "nvidia,tegra186-host1x", "simple-bus"; + reg = <0x0 0x13e10000 0x0 0x10000 0x0 0x13e00000 0x0 0x10000 0x0 0x13ec0000 0x0 0x40000>; + interrupts = <0x0 0x109 0x4 0x0 0x107 0x4>; + wakeup_capable; + resets = <0x10 0x12>; + clocks = <0x10 0x39 0x10 0xc9>; + clock-names = "host1x", "actmon"; + nvidia,vmid = <0x1>; + iommus = <0x11 0x1 0x11 0x40 0x11 0x41 0x11 0x42 0x11 0x43 0x11 0x44 0x11 0x45 0x11 0x46 0x11 0x47>; + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + status = "okay"; + nvidia,ch-base = <0x0>; + nvidia,nb-channels = <0x3c>; + nvidia,nb-hw-pts = <0x240>; + nvidia,pts-base = <0x0>; + nvidia,nb-pts = <0x23c>; + linux,phandle = <0xb6>; + phandle = <0xb6>; + + disp_imp_table { + status = "okay"; + num_settings = <0x6>; + linux,phandle = <0x73>; + phandle = <0x73>; + + disp_imp_settings_0 { + nvidia,total_disp_bw_with_catchup = <0x0 0xff3bd8>; + nvidia,total_disp_bw_without_catchup = <0x0 0xe80800>; + nvidia,disp_emc_floor = <0x0 0x27ac4000>; + nvidia,disp_min_hubclk = <0x0 0x1550d920>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + }; + + disp_imp_settings_1 { + nvidia,total_disp_bw_with_catchup = <0x0 0xd4b200>; + nvidia,total_disp_bw_without_catchup = <0x0 0xc15c00>; + nvidia,disp_emc_floor = <0x0 0x1fa97800>; + nvidia,disp_min_hubclk = <0x0 0x1313ba60>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + }; + + disp_imp_settings_2 { + nvidia,total_disp_bw_with_catchup = <0x0 0xaa2828>; + nvidia,total_disp_bw_without_catchup = <0x0 0x9ab000>; + nvidia,disp_emc_floor = <0x0 0x13d62000>; + nvidia,disp_min_hubclk = <0x0 0x10d69ba0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + }; + + disp_imp_settings_3 { + nvidia,total_disp_bw_with_catchup = <0x0 0x7f9dec>; + nvidia,total_disp_bw_without_catchup = <0x0 0x740400>; + nvidia,disp_emc_floor = <0x0 0x13d62000>; + nvidia,disp_min_hubclk = <0x0 0xe997ce0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + }; + + disp_imp_settings_4 { + nvidia,total_disp_bw_with_catchup = <0x0 0x5a6568>; + nvidia,total_disp_bw_without_catchup = <0x0 0x522d80>; + nvidia,disp_emc_floor = <0x0 0xc28cb00>; + nvidia,disp_min_hubclk = <0x0 0xc5c5e20>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + }; + + disp_imp_settings_5 { + nvidia,total_disp_bw_with_catchup = <0x0 0x2fdb2c>; + nvidia,total_disp_bw_without_catchup = <0x0 0x2b8180>; + nvidia,disp_emc_floor = <0x0 0x6146580>; + nvidia,disp_min_hubclk = <0x0 0xa1f3f60>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + }; + }; + + ctx0 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x38>; + status = "okay"; + linux,phandle = <0x1be>; + phandle = <0x1be>; + }; + + ctx1 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x39>; + status = "okay"; + linux,phandle = <0x1bf>; + phandle = <0x1bf>; + }; + + ctx2 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x3a>; + status = "okay"; + linux,phandle = <0x1c0>; + phandle = <0x1c0>; + }; + + ctx3 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x3b>; + status = "okay"; + linux,phandle = <0x1c1>; + phandle = <0x1c1>; + }; + + ctx4 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x3c>; + status = "okay"; + linux,phandle = <0x1c2>; + phandle = <0x1c2>; + }; + + ctx5 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x3d>; + status = "okay"; + linux,phandle = <0x1c3>; + phandle = <0x1c3>; + }; + + ctx6 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x3e>; + status = "okay"; + linux,phandle = <0x1c4>; + phandle = <0x1c4>; + }; + + ctx7 { + compatible = "nvidia,tegra186-iommu-context"; + iommus = <0x11 0x3f>; + status = "okay"; + linux,phandle = <0x1c5>; + phandle = <0x1c5>; + }; + + nvcsi@150c0000 { + compatible = "nvidia,tegra186-nvcsi"; + power-domains = <0x1f 0xb>; + reg = <0x0 0x150c0000 0x0 0x40000>; + resets = <0x10 0x58>; + clocks = <0x10 0xb4 0x10 0xb5 0x10 0x20e 0x10 0x10d>; + clock-names = "nvcsi", "nvcsilp", "nvcsi_parent", "nvcsilp_parent"; + interrupts = <0x0 0x77 0x4>; + iommus = <0x11 0x2>; + iommu-group-id = <0x1>; + status = "okay"; + num-ports = <0x6>; + nvidia,csi_regulator = "avdd_dsi_csi"; + num-channels = <0x1>; + #address-cells = <0x1>; + #size-cells = <0x0>; + linux,phandle = <0x128>; + phandle = <0x128>; + + channel@0 { + reg = <0x0>; + status = "okay"; + linux,phandle = <0x129>; + phandle = <0x129>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + status = "okay"; + linux,phandle = <0x12a>; + phandle = <0x12a>; + + endpoint@0 { + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x134>; + status = "okay"; + linux,phandle = <0x30>; + phandle = <0x30>; + }; + }; + + port@1 { + reg = <0x1>; + status = "okay"; + linux,phandle = <0x12b>; + phandle = <0x12b>; + + endpoint@1 { + remote-endpoint = <0x62>; + status = "okay"; + linux,phandle = <0x6d>; + phandle = <0x6d>; + }; + }; + }; + }; + + channel@1 { + reg = <0x1>; + status = "disabled"; + linux,phandle = <0x12c>; + phandle = <0x12c>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + status = "disabled"; + linux,phandle = <0x12d>; + phandle = <0x12d>; + + endpoint@2 { + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x63>; + status = "disabled"; + linux,phandle = <0x2d>; + phandle = <0x2d>; + }; + }; + + port@1 { + reg = <0x1>; + status = "disabled"; + linux,phandle = <0x12e>; + phandle = <0x12e>; + + endpoint@3 { + remote-endpoint = <0x64>; + status = "disabled"; + linux,phandle = <0x6e>; + phandle = <0x6e>; + }; + }; + }; + }; + + channel@2 { + reg = <0x2>; + status = "disabled"; + linux,phandle = <0x144>; + phandle = <0x144>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + status = "disabled"; + linux,phandle = <0x145>; + phandle = <0x145>; + + endpoint@4 { + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x65>; + status = "disabled"; + linux,phandle = <0x36>; + phandle = <0x36>; + }; + }; + + port@1 { + reg = <0x1>; + status = "disabled"; + linux,phandle = <0x147>; + phandle = <0x147>; + + endpoint@5 { + remote-endpoint = <0x66>; + status = "disabled"; + linux,phandle = <0x6f>; + phandle = <0x6f>; + }; + }; + }; + }; + + channel@3 { + reg = <0x3>; + status = "disabled"; + linux,phandle = <0x14d>; + phandle = <0x14d>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + status = "disabled"; + linux,phandle = <0x14e>; + phandle = <0x14e>; + + endpoint@6 { + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x67>; + status = "disabled"; + linux,phandle = <0x37>; + phandle = <0x37>; + }; + }; + + port@1 { + reg = <0x1>; + status = "disabled"; + linux,phandle = <0x150>; + phandle = <0x150>; + + endpoint@7 { + remote-endpoint = <0x68>; + status = "disabled"; + linux,phandle = <0x70>; + phandle = <0x70>; + }; + }; + }; + }; + + channel@4 { + reg = <0x4>; + status = "disabled"; + linux,phandle = <0x156>; + phandle = <0x156>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + status = "disabled"; + linux,phandle = <0x157>; + phandle = <0x157>; + + endpoint@8 { + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x69>; + status = "disabled"; + linux,phandle = <0x38>; + phandle = <0x38>; + }; + }; + + port@1 { + reg = <0x1>; + status = "disabled"; + linux,phandle = <0x159>; + phandle = <0x159>; + + endpoint@9 { + remote-endpoint = <0x6a>; + status = "disabled"; + linux,phandle = <0x71>; + phandle = <0x71>; + }; + }; + }; + }; + + channel@5 { + reg = <0x5>; + status = "disabled"; + linux,phandle = <0x15f>; + phandle = <0x15f>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + status = "disabled"; + linux,phandle = <0x160>; + phandle = <0x160>; + + endpoint@10 { + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x6b>; + status = "disabled"; + linux,phandle = <0x39>; + phandle = <0x39>; + }; + }; + + port@1 { + reg = <0x1>; + status = "disabled"; + linux,phandle = <0x162>; + phandle = <0x162>; + + endpoint@11 { + remote-endpoint = <0x6c>; + status = "disabled"; + linux,phandle = <0x72>; + phandle = <0x72>; + }; + }; + }; + }; + }; + + vi@15700000 { + compatible = "nvidia,tegra186-vi"; + power-domains = <0x1f 0xb>; + reg = <0x0 0x15700000 0x0 0x100000>; + interrupts = <0x0 0xc9 0x4 0x0 0xca 0x4 0x0 0xcb 0x4>; + resets = <0x10 0x33 0x10 0x8f>; + reset-names = "vi", "tsctnvi"; + clocks = <0x10 0x33 0x10 0xb4 0x10 0xb5>; + clock-names = "vi", "nvcsi", "nvcsilp"; + iommus = <0x11 0x4>; + iommu-group-id = <0x1>; + status = "okay"; + avdd_dsi_csi-supply = <0x3c>; + num-channels = <0x1>; + linux,phandle = <0x5a>; + phandle = <0x5a>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + status = "okay"; + linux,phandle = <0x126>; + phandle = <0x126>; + + endpoint { + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x6d>; + vc-id = <0x0>; + status = "okay"; + linux,phandle = <0x62>; + phandle = <0x62>; + }; + }; + + port@1 { + reg = <0x1>; + status = "disabled"; + linux,phandle = <0x127>; + phandle = <0x127>; + + endpoint { + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x6e>; + vc-id = <0x0>; + status = "disabled"; + linux,phandle = <0x64>; + phandle = <0x64>; + }; + }; + + port@2 { + reg = <0x2>; + status = "disabled"; + linux,phandle = <0x143>; + phandle = <0x143>; + + endpoint { + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x6f>; + vc-id = <0x0>; + status = "disabled"; + linux,phandle = <0x66>; + phandle = <0x66>; + }; + }; + + port@3 { + reg = <0x3>; + status = "disabled"; + linux,phandle = <0x14c>; + phandle = <0x14c>; + + endpoint { + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x70>; + vc-id = <0x0>; + status = "disabled"; + linux,phandle = <0x68>; + phandle = <0x68>; + }; + }; + + port@4 { + reg = <0x4>; + status = "disabled"; + linux,phandle = <0x155>; + phandle = <0x155>; + + endpoint { + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x71>; + vc-id = <0x0>; + status = "disabled"; + linux,phandle = <0x6a>; + phandle = <0x6a>; + }; + }; + + port@5 { + reg = <0x5>; + status = "disabled"; + linux,phandle = <0x15e>; + phandle = <0x15e>; + + endpoint { + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x72>; + vc-id = <0x0>; + status = "disabled"; + linux,phandle = <0x6c>; + phandle = <0x6c>; + }; + }; + }; + }; + + isp@15600000 { + compatible = "nvidia,tegra186-isp"; + power-domains = <0x1f 0x5>; + reg = <0x0 0x15600000 0x0 0x40000>; + interrupts = <0x0 0xcd 0x4>; + resets = <0x10 0x19>; + clocks = <0x10 0x32>; + clock-names = "isp"; + iommus = <0x11 0x5>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + dc_common { + compatible = "nvidia,tegra_dc_common"; + reg = <0x0 0x15200000 0x0 0x30000>; + nvidia,valid_heads = <0x3>; + nvidia,disp_imp_table = <0x73>; + }; + + nvdisplay@15200000 { + compatible = "nvidia,tegra186-dc"; + reg = <0x0 0x15200000 0x0 0x10000>; + interrupts = <0x0 0x99 0x4>; + win-mask = <0x7>; + iommus = <0x11 0x9>; + iommu-group-id = <0x1>; + nvidia,dc-ctrlnum = <0x0>; + nvidia,cmu-enable = <0x1>; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x206 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x10b 0x10 0x3a>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "pll_d", "plld2", "plld3", "pllp_display", "pll_d_out1", "disp1_emc"; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x59>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head0"; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + pinctrl-0 = <0x74>; + pinctrl-1 = <0x75>; + pinctrl-2 = <0x76>; + pinctrl-3 = <0x77>; + pinctrl-4 = <0x78>; + pinctrl-5 = <0x79>; + pinctrl-6 = <0x7a>; + pinctrl-7 = <0x7b>; + pinctrl-8 = <0x7c>; + pinctrl-9 = <0x7d>; + pinctrl-10 = <0x7e>; + pinctrl-11 = <0x7f>; + status = "disabled"; + fb_reserved = <0x80>; + iommu-direct-regions = <0x80 0x81 0x82>; + nvidia,dc-flags = <0x1>; + nvidia,emc-rate = <0x11e1a300>; + nvidia,fb-bpp = <0x20>; + nvidia,fb-flags = <0x1>; + nvidia,fb-win = <0x0>; + nvidia,dc-or-node = "/host1x/dsi"; + nvidia,dc-connector = <0x83>; + avdd_lcd-supply = <0x84>; + dvdd_lcd-supply = <0x85>; + avdd_dsi_csi-supply = <0x3c>; + outp-supply = <0x86>; + outn-supply = <0x87>; + vdd_lcd_bl-supply = <0x26>; + vdd_lcd_bl_en-supply = <0x88>; + avdd_hdmi-supply = <0x89>; + avdd_hdmi_pll-supply = <0x12>; + vdd_hdmi_5v0-supply = <0x8a>; + linux,phandle = <0x1c6>; + phandle = <0x1c6>; + }; + + nvdisplay@15210000 { + compatible = "nvidia,tegra186-dc"; + reg = <0x0 0x15210000 0x0 0x10000>; + interrupts = <0x0 0x9a 0x4>; + win-mask = <0x38>; + iommus = <0x11 0x9>; + iommu-group-id = <0x1>; + nvidia,dc-ctrlnum = <0x1>; + nvidia,cmu-enable = <0x1>; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x206 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x10b 0x10 0x3a>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "pll_d", "plld2", "plld3", "pllp_display", "pll_d_out1", "disp2_emc"; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x5a>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head1"; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + pinctrl-0 = <0x74>; + pinctrl-1 = <0x75>; + pinctrl-2 = <0x76>; + pinctrl-3 = <0x77>; + pinctrl-4 = <0x78>; + pinctrl-5 = <0x79>; + pinctrl-6 = <0x7a>; + pinctrl-7 = <0x7b>; + pinctrl-8 = <0x7c>; + pinctrl-9 = <0x7d>; + pinctrl-10 = <0x7e>; + pinctrl-11 = <0x7f>; + status = "okay"; + fb_reserved = <0x81>; + iommu-direct-regions = <0x80 0x81 0x82>; + nvidia,dc-flags = <0x1>; + nvidia,emc-clk-rate = <0x11e1a300>; + nvidia,fb-bpp = <0x20>; + nvidia,fb-flags = <0x1>; + nvidia,fb-win = <0x3>; + nvidia,dc-or-node = "/host1x/sor1"; + nvidia,dc-connector = <0x8b>; + avdd_hdmi-supply = <0x89>; + avdd_hdmi_pll-supply = <0x12>; + vdd_hdmi_5v0-supply = <0x8a>; + linux,phandle = <0x1c7>; + phandle = <0x1c7>; + }; + + nvdisplay@15220000 { + compatible = "nvidia,tegra186-dc"; + reg = <0x0 0x15220000 0x0 0x10000>; + interrupts = <0x0 0x9b 0x4>; + win-mask = <0x0>; + iommus = <0x11 0x9>; + iommu-group-id = <0x1>; + nvidia,dc-ctrlnum = <0x2>; + nvidia,cmu-enable = <0x1>; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x3a>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "plld2", "plld3", "pllp_display", "disp3_emc"; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x5b>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head2"; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + pinctrl-0 = <0x74>; + pinctrl-1 = <0x75>; + pinctrl-2 = <0x76>; + pinctrl-3 = <0x77>; + pinctrl-4 = <0x78>; + pinctrl-5 = <0x79>; + pinctrl-6 = <0x7a>; + pinctrl-7 = <0x7b>; + pinctrl-8 = <0x7c>; + pinctrl-9 = <0x7d>; + pinctrl-10 = <0x7e>; + pinctrl-11 = <0x7f>; + status = "disabled"; + fb_reserved = <0x82>; + iommu-direct-regions = <0x80 0x81 0x82>; + nvidia,dc-flags = <0x1>; + nvidia,emc-clk-rate = <0x11e1a300>; + nvidia,fb-bpp = <0x20>; + nvidia,fb-flags = <0x1>; + nvidia,dc-or-node = "/host1x/sor"; + nvidia,dc-connector = <0x8c>; + vdd-dp-pwr-supply = <0x26>; + avdd-dp-pll-supply = <0x26>; + vdd-edp-sec-mode-supply = <0x26>; + vdd-dp-pad-supply = <0x26>; + vdd_hdmi_5v0-supply = <0x26>; + linux,phandle = <0x1c8>; + phandle = <0x1c8>; + }; + + dsi { + compatible = "nvidia,tegra186-dsi"; + reg = <0x0 0x15300000 0x0 0x40000 0x0 0x15400000 0x0 0x40000 0x0 0x15900000 0x0 0x40000 0x0 0x15940000 0x0 0x40000 0x0 0x15880000 0x0 0x10000>; + clocks = <0x10 0x73 0x10 0x75 0x10 0x76 0x10 0x77 0x10 0xe7 0x10 0xe8 0x10 0xe9 0x10 0xea>; + clock-names = "dsi", "dsia_lp", "dsib", "dsib_lp", "dsic", "dsic_lp", "dsid", "dsid_lp"; + resets = <0x10 0x6 0x10 0x7 0x10 0x3f 0x10 0x40 0x10 0x91>; + reset-names = "dsia", "dsib", "dsic", "dsid", "dsi_padctrl"; + nvidia,enable-hs-clk-in-lp-mode = <0x1>; + status = "disabled"; + nvidia,dsi-controller-vs = <0x1>; + linux,phandle = <0x83>; + phandle = <0x83>; + + prod-settings { + #prod-cells = <0x3>; + + dsi-padctrl-prod { + prod = <0x1c 0x7 0x0 0x20 0x1 0x0 0x24 0x3f0fc3f 0x0 0x28 0x333333 0x0 0x30 0xffffff 0x0 0x34 0xffffff 0x777777 0x4c 0x7 0x0 0x50 0x1 0x0 0x54 0x3f0fc3f 0x0 0x58 0x333333 0x0 0x60 0xffffff 0x0 0x64 0xffffff 0x777777 0x7c 0x7 0x0 0x80 0x1 0x0 0x84 0x3f0fc3f 0x0 0x88 0x333333 0x0 0x90 0xffffff 0x0 0x94 0xffffff 0x777777 0xac 0x7 0x0 0xb0 0x1 0x0 0xb4 0x3f0fc3f 0x0 0xb8 0x333333 0x0 0xc0 0xffffff 0x0 0xc4 0xffffff 0x777777>; + }; + }; + + panel-s-wuxga-8-0 { + status = "disabled"; + compatible = "s,wuxga-8-0"; + nvidia,dsi-instance = <0x0>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-refresh-rate = <0x3c>; + nvidia,dsi-video-data-type = <0x0>; + nvidia,dsi-video-clock-mode = <0x0>; + nvidia,dsi-video-burst-mode = <0x0>; + nvidia,dsi-ganged-type = <0x1>; + nvidia,dsi-ganged-swap-links = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-controller-vs = <0x1>; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-panel-reset = <0x1>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-suspend-stop-stream-late = <0x1>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,default_color_space = <0x0>; + nvidia,dsi-init-cmd = <0x0 0x5 0x11 0x0 0x0 0x3 0xa 0x0 0x5 0x29 0x0 0x0>; + nvidia,dsi-n-init-cmd = <0x3>; + nvidia,dsi-suspend-cmd = <0x0 0x5 0x28 0x0 0x0 0x3 0x3 0x0 0x5 0x10 0x0 0x0 0x3 0xa>; + nvidia,dsi-n-suspend-cmd = <0x4>; + nvidia,dsi-pkt-seq = <0x1 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + nvidia,panel-bl-pwm-gpio = <0x28 0x8 0x1>; + nvidia,panel-bl-en-gpio = <0x28 0xb 0x1>; + nvidia,panel-en-gpio = <0x8d 0x4 0x1>; + nvidia,en-vmm-vpp-with-i2c-config; + linux,phandle = <0x102>; + phandle = <0x102>; + + disp-default-out { + nvidia,out-type = <0x2>; + nvidia,out-width = <0x6b>; + nvidia,out-height = <0xac>; + nvidia,out-flags = <0x0>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-xres = <0x1000>; + nvidia,out-yres = <0x870>; + }; + + display-timings { + + 1200x1920-32-60Hz { + clock-frequency = <0xb845d40>; + hactive = <0x4b0>; + vactive = <0x780>; + hfront-porch = <0x6b>; + hback-porch = <0x14>; + hsync-len = <0x1>; + vfront-porch = <0x1f1>; + vback-porch = <0x7>; + vsync-len = <0x1>; + nvidia,h-ref-to-sync = <0x1>; + nvidia,v-ref-to-sync = <0xb>; + }; + }; + + smartdimmer { + status = "disabled"; + nvidia,turn-off-brightness = <0x0>; + nvidia,turn-on-brightness = <0xff>; + nvidia,use-auto-pwm = <0x0>; + nvidia,hw-update-delay = <0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,k-limit-enable = <0x1>; + nvidia,k-limit = <0xc8>; + nvidia,sd-window-enable = <0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,smooth-k-enable = <0x1>; + nvidia,smooth-k-incr = <0x4>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,fc = <0x0 0x0>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,sw-update-delay = <0x0>; + nvidia,gain_table = <0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x4250 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x42b4 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x44e0 0x4304 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4660 0x4570 0x4318 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x4768 0x45e8 0x433c 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f0 0x482c 0x4644 0x4354 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a00 0x48c4 0x4688 0x4368 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4af4 0x4960 0x46e0 0x4388 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ca8 0x4ba8 0x49c0 0x4708 0x4390 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4db0 0x4c60 0x4a34 0x4748 0x43ac 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f48 0x4e78 0x4cd4 0x4a6c 0x475c 0x43ac 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x5060 0x4f44 0x4d60 0x4ac4 0x478c 0x43c0 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x5158 0x4ff8 0x4dd8 0x4b14 0x47b4 0x43d0 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5314 0x5238 0x5098 0x4e44 0x4b54 0x47d8 0x43dc 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5424 0x5300 0x5124 0x4ea4 0x4b90 0x47f8 0x43e8 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55b8 0x5518 0x53b4 0x51a4 0x4ef8 0x4bc4 0x4814 0x43f0 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x56dc 0x55f4 0x5458 0x5214 0x4f44 0x4bf0 0x4828 0x43f8 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x57e8 0x56bc 0x54e8 0x527c 0x4f88 0x4c18 0x483c 0x4400 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5990 0x58f4 0x579c 0x559c 0x5308 0x4ff4 0x4c64 0x486c 0x4414 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ab8 0x59d4 0x5840 0x5614 0x5358 0x5024 0x4c80 0x4878 0x4418 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5bd8 0x5ac4 0x5908 0x56b4 0x53d8 0x5084 0x4cc4 0x48a4 0x4428 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d68 0x5cd0 0x5b80 0x5990 0x5714 0x5418 0x50a8 0x4cd8 0x48ac 0x442c 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5e9c 0x5dd4 0x5c58 0x5a40 0x57a0 0x5484 0x50fc 0x4d10 0x48cc 0x443c 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x5fc4 0x5ecc 0x5d24 0x5ae8 0x5828 0x54ec 0x514c 0x4d48 0x48f0 0x4448 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x60c4 0x5f8c 0x5db4 0x5b50 0x586c 0x5518 0x5160 0x4d50 0x48f0 0x4448 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x6280 0x61cc 0x606c 0x5e6c 0x5be4 0x58e0 0x5574 0x51a4 0x4d80 0x490c 0x4454 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63ac 0x62cc 0x6140 0x5f1c 0x5c70 0x5950 0x55cc 0x51e4 0x4dac 0x4928 0x4460 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x64cc 0x63c0 0x6208 0x5fc0 0x5cf8 0x59bc 0x561c 0x5220 0x4dd4 0x4940 0x446c 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x65e0 0x64a4 0x62c8 0x605c 0x5d78 0x5a20 0x5668 0x525c 0x4dfc 0x4958 0x4474 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x679c 0x66e8 0x6584 0x6380 0x60f4 0x5df0 0x5a80 0x56b0 0x5290 0x4e20 0x4970 0x4480 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68c8 0x67e8 0x6654 0x642c 0x6180 0x5e60 0x5ad8 0x56f4 0x52c0 0x4e44 0x4984 0x4488 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x69ec 0x68d8 0x6720 0x64d4 0x6208 0x5ecc 0x5b2c 0x5734 0x52f0 0x4e60 0x4994 0x4490 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b80 0x6b00 0x69c0 0x67e0 0x6570 0x6288 0x5f30 0x5b7c 0x5770 0x531c 0x4e80 0x49a8 0x4494 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6cc4 0x6c24 0x6acc 0x68d0 0x6648 0x6344 0x5fd8 0x5c08 0x57e4 0x5378 0x4ec4 0x49d4 0x44ac 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6df8 0x6d28 0x6ba0 0x6980 0x66d8 0x63b8 0x6034 0x5c50 0x5818 0x539c 0x4edc 0x49e0 0x44b0 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f1c 0x6e1c 0x6c6c 0x6a28 0x6760 0x6428 0x6088 0x5c90 0x584c 0x53c0 0x4ef4 0x49ec 0x44b4 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x7034 0x6f04 0x6d30 0x6ac8 0x67e0 0x648c 0x60d8 0x5cd0 0x5878 0x53e0 0x4f08 0x49f8 0x44bc 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x7160 0x7014 0x6e24 0x6ba4 0x68a4 0x6538 0x616c 0x5d4c 0x58e0 0x5430 0x4f44 0x4a20 0x44cc 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7320 0x7264 0x70ec 0x6ed4 0x6c34 0x6918 0x6594 0x61b4 0x5d84 0x5908 0x544c 0x4f54 0x4a2c 0x44d0 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x745c 0x7384 0x71f0 0x6fc0 0x6d04 0x69d4 0x6638 0x6244 0x5dfc 0x5968 0x5498 0x4f90 0x4a50 0x44e0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x7580 0x7474 0x72b8 0x7064 0x6d88 0x6a3c 0x668c 0x6280 0x5e28 0x598c 0x54b0 0x4f9c 0x4a58 0x44e4 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x76b0 0x758c 0x73b4 0x7144 0x6e54 0x6af0 0x6728 0x6308 0x5e9c 0x59e8 0x54f8 0x4fd4 0x4a78 0x44f4 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x77c0 0x766c 0x746c 0x71d8 0x6ec8 0x6b4c 0x6770 0x6340 0x5ec4 0x5a04 0x550c 0x4fdc 0x4a80 0x44f8 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7990 0x78e4 0x7774 0x755c 0x72b0 0x6f88 0x6bf8 0x6804 0x63c0 0x5f30 0x5a5c 0x5550 0x5010 0x4aa0 0x4504 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ac0 0x79e0 0x7844 0x7604 0x7338 0x6ff4 0x6c48 0x6844 0x63ec 0x5f50 0x5a74 0x5560 0x5018 0x4aa4 0x4508 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7bf8 0x7afc 0x7940 0x76e8 0x7404 0x70ac 0x6cec 0x68d0 0x6468 0x5fb8 0x5ac8 0x55a0 0x5048 0x4ac4 0x4514 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d2c 0x7c10 0x7a3c 0x77cc 0x74d0 0x7160 0x6d8c 0x695c 0x64dc 0x601c 0x5b18 0x55e0 0x5078 0x4ae0 0x4524 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7e40 0x7cf4 0x7af4 0x785c 0x7544 0x71bc 0x6dd0 0x6990 0x6504 0x6034 0x5b28 0x55ec 0x507c 0x4ae4 0x4524 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x7ffc 0x7f68 0x7e00 0x7be4 0x7938 0x7608 0x7268 0x6e68 0x6a14 0x6574 0x6094 0x5b78 0x5628 0x50a8 0x4b00 0x4530>; + nvidia,backlight_table = <0xff 0xf3 0xe8 0xde 0xd4 0xcb 0xc2 0xba 0xb3 0xab 0xa5 0x9e 0x98 0x92 0x8d 0x88 0x83 0x7e 0x7a 0x76 0x72 0x6e 0x6a 0x67 0x64 0x60 0x5d 0x5a 0x58 0x55 0x53 0x50 0x4e 0x4c 0x49 0x47 0x45 0x43 0x42 0x40 0x3e 0x3d 0x3b 0x3a 0x38 0x37 0x35 0x34 0x33 0x31 0x30>; + }; + + cmu { + nvidia,cmu-csc = <0x100 0x0 0x0 0x0 0x100 0x0 0x0 0x0 0x100>; + nvidia,cmu-lut2 = <0x0 0x1 0x2 0x2 0x3 0x4 0x5 0x6 0x6 0x7 0x8 0x9 0xa 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0xf 0x10 0x10 0x11 0x12 0x12 0x13 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x17 0x18 0x18 0x19 0x19 0x19 0x1a 0x1a 0x1b 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1d 0x1e 0x1e 0x1e 0x1f 0x1f 0x1f 0x20 0x20 0x20 0x21 0x21 0x21 0x22 0x22 0x22 0x22 0x23 0x23 0x23 0x24 0x24 0x24 0x25 0x25 0x25 0x25 0x26 0x26 0x26 0x26 0x27 0x27 0x27 0x28 0x28 0x28 0x28 0x29 0x29 0x29 0x29 0x2a 0x2a 0x2a 0x2a 0x2b 0x2b 0x2b 0x2b 0x2b 0x2c 0x2c 0x2c 0x2c 0x2d 0x2d 0x2d 0x2d 0x2e 0x2e 0x2e 0x2e 0x2e 0x2f 0x2f 0x2f 0x2f 0x30 0x30 0x30 0x30 0x30 0x31 0x31 0x31 0x31 0x31 0x32 0x32 0x32 0x32 0x32 0x33 0x33 0x33 0x33 0x33 0x34 0x34 0x34 0x34 0x34 0x35 0x35 0x35 0x35 0x35 0x36 0x36 0x36 0x36 0x36 0x37 0x37 0x37 0x37 0x37 0x37 0x38 0x38 0x38 0x38 0x38 0x39 0x39 0x39 0x39 0x39 0x39 0x3a 0x3a 0x3a 0x3a 0x3a 0x3a 0x3b 0x3b 0x3b 0x3b 0x3b 0x3b 0x3c 0x3c 0x3c 0x3c 0x3c 0x3c 0x3d 0x3d 0x3d 0x3d 0x3d 0x3d 0x3e 0x3e 0x3e 0x3e 0x3e 0x3e 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x40 0x40 0x40 0x40 0x40 0x40 0x40 0x41 0x41 0x41 0x41 0x41 0x41 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x44 0x44 0x44 0x44 0x44 0x44 0x44 0x45 0x45 0x45 0x45 0x45 0x45 0x45 0x46 0x46 0x46 0x46 0x46 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x49 0x49 0x49 0x49 0x49 0x49 0x49 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x63 0x63 0x63 0x63 0x63 0x63 0x63 0x64 0x65 0x65 0x66 0x67 0x67 0x68 0x69 0x69 0x6a 0x6b 0x6b 0x6c 0x6d 0x6d 0x6e 0x6f 0x6f 0x70 0x71 0x71 0x72 0x73 0x73 0x74 0x74 0x75 0x76 0x76 0x77 0x77 0x78 0x78 0x79 0x7a 0x7a 0x7b 0x7b 0x7c 0x7c 0x7d 0x7e 0x7e 0x7f 0x7f 0x80 0x80 0x81 0x81 0x82 0x82 0x83 0x83 0x84 0x84 0x85 0x85 0x86 0x86 0x87 0x87 0x88 0x88 0x89 0x89 0x8a 0x8a 0x8b 0x8b 0x8c 0x8c 0x8d 0x8d 0x8e 0x8e 0x8f 0x8f 0x90 0x90 0x91 0x91 0x91 0x92 0x92 0x93 0x93 0x94 0x94 0x95 0x95 0x96 0x96 0x96 0x97 0x97 0x98 0x98 0x99 0x99 0x99 0x9a 0x9a 0x9b 0x9b 0x9c 0x9c 0x9c 0x9d 0x9d 0x9e 0x9e 0x9e 0x9f 0x9f 0xa0 0xa0 0xa0 0xa1 0xa1 0xa2 0xa2 0xa2 0xa3 0xa3 0xa4 0xa4 0xa4 0xa5 0xa5 0xa6 0xa6 0xa6 0xa7 0xa7 0xa7 0xa8 0xa8 0xa9 0xa9 0xa9 0xaa 0xaa 0xaa 0xab 0xab 0xac 0xac 0xac 0xad 0xad 0xad 0xae 0xae 0xae 0xaf 0xaf 0xb0 0xb0 0xb0 0xb1 0xb1 0xb1 0xb2 0xb2 0xb2 0xb3 0xb3 0xb3 0xb4 0xb4 0xb4 0xb5 0xb5 0xb6 0xb6 0xb6 0xb7 0xb7 0xb7 0xb8 0xb8 0xb8 0xb9 0xb9 0xb9 0xba 0xba 0xba 0xbb 0xbb 0xbb 0xbc 0xbc 0xbc 0xbd 0xbd 0xbd 0xbd 0xbe 0xbe 0xbe 0xbf 0xbf 0xbf 0xc0 0xc0 0xc0 0xc1 0xc1 0xc1 0xc2 0xc2 0xc2 0xc3 0xc3 0xc3 0xc4 0xc4 0xc4 0xc4 0xc5 0xc5 0xc5 0xc6 0xc6 0xc6 0xc7 0xc7 0xc7 0xc8 0xc8 0xc8 0xc8 0xc9 0xc9 0xc9 0xca 0xca 0xca 0xca 0xcb 0xcb 0xcb 0xcc 0xcc 0xcc 0xcd 0xcd 0xcd 0xcd 0xce 0xce 0xce 0xcf 0xcf 0xcf 0xcf 0xd0 0xd0 0xd0 0xd1 0xd1 0xd1 0xd1 0xd2 0xd2 0xd2 0xd3 0xd3 0xd3 0xd3 0xd4 0xd4 0xd4 0xd5 0xd5 0xd5 0xd5 0xd6 0xd6 0xd6 0xd6 0xd7 0xd7 0xd7 0xd8 0xd8 0xd8 0xd8 0xd9 0xd9 0xd9 0xd9 0xda 0xda 0xda 0xdb 0xdb 0xdb 0xdb 0xdc 0xdc 0xdc 0xdc 0xdd 0xdd 0xdd 0xdd 0xde 0xde 0xde 0xdf 0xdf 0xdf 0xdf 0xe0 0xe0 0xe0 0xe0 0xe1 0xe1 0xe1 0xe1 0xe2 0xe2 0xe2 0xe2 0xe3 0xe3 0xe3 0xe3 0xe4 0xe4 0xe4 0xe4 0xe5 0xe5 0xe5 0xe5 0xe6 0xe6 0xe6 0xe6 0xe7 0xe7 0xe7 0xe7 0xe8 0xe8 0xe8 0xe8 0xe9 0xe9 0xe9 0xe9 0xea 0xea 0xea 0xea 0xeb 0xeb 0xeb 0xeb 0xec 0xec 0xec 0xec 0xed 0xed 0xed 0xed 0xee 0xee 0xee 0xee 0xef 0xef 0xef 0xef 0xf0 0xf0 0xf0 0xf0 0xf0 0xf1 0xf1 0xf1 0xf1 0xf2 0xf2 0xf2 0xf2 0xf3 0xf3 0xf3 0xf3 0xf4 0xf4 0xf4 0xf4 0xf4 0xf5 0xf5 0xf5 0xf5 0xf6 0xf6 0xf6 0xf6 0xf7 0xf7 0xf7 0xf7 0xf7 0xf8 0xf8 0xf8 0xf8 0xf9 0xf9 0xf9 0xf9 0xf9 0xfa 0xfa 0xfa 0xfa 0xfb 0xfb 0xfb 0xfb 0xfb 0xfc 0xfc 0xfc 0xfc 0xfd 0xfd 0xfd 0xfd 0xfd 0xfe 0xfe 0xfe 0xfe 0xff 0xff>; + }; + + nvdisp-cmu { + nvidia,panel-csc = <0xd581 0x2979 0xc5 0x0 0x831 0xcac1 0x20c 0x0 0x189 0x625 0xcc4a 0x0>; + nvidia,cmu-lut = <0x6000 0x6000 0x6000 0x6191 0x6191 0x6191 0x6322 0x6322 0x6322 0x643b 0x643b 0x643b 0x64ba 0x64ba 0x64ba 0x6539 0x6539 0x6539 0x65b8 0x65b8 0x65b8 0x6637 0x6637 0x6637 0x66b6 0x66b6 0x66b6 0x6735 0x6735 0x6735 0x67b4 0x67b4 0x67b4 0x6826 0x6826 0x6826 0x687d 0x687d 0x687d 0x68d4 0x68d4 0x68d4 0x692b 0x692b 0x692b 0x6983 0x6983 0x6983 0x69da 0x69da 0x69da 0x6a31 0x6a31 0x6a31 0x6a88 0x6a88 0x6a88 0x6ae0 0x6ae0 0x6ae0 0x6b37 0x6b37 0x6b37 0x6b8e 0x6b8e 0x6b8e 0x6be5 0x6be5 0x6be5 0x6c28 0x6c28 0x6c28 0x6c5b 0x6c5b 0x6c5b 0x6c8e 0x6c8e 0x6c8e 0x6cc1 0x6cc1 0x6cc1 0x6cf4 0x6cf4 0x6cf4 0x6d27 0x6d27 0x6d27 0x6d5a 0x6d5a 0x6d5a 0x6d8d 0x6d8d 0x6d8d 0x6dbf 0x6dbf 0x6dbf 0x6df2 0x6df2 0x6df2 0x6e25 0x6e25 0x6e25 0x6e58 0x6e58 0x6e58 0x6e8b 0x6e8b 0x6e8b 0x6ebe 0x6ebe 0x6ebe 0x6ef1 0x6ef1 0x6ef1 0x6f24 0x6f24 0x6f24 0x6f57 0x6f57 0x6f57 0x6f8a 0x6f8a 0x6f8a 0x6fbd 0x6fbd 0x6fbd 0x6ff0 0x6ff0 0x6ff0 0x701a 0x701a 0x701a 0x7037 0x7037 0x7037 0x7053 0x7053 0x7053 0x706f 0x706f 0x706f 0x708c 0x708c 0x708c 0x70a8 0x70a8 0x70a8 0x70c5 0x70c5 0x70c5 0x70e1 0x70e1 0x70e1 0x70fe 0x70fe 0x70fe 0x711a 0x711a 0x711a 0x7136 0x7136 0x7136 0x7153 0x7153 0x7153 0x716f 0x716f 0x716f 0x718c 0x718c 0x718c 0x71a8 0x71a8 0x71a8 0x71c4 0x71c4 0x71c4 0x71e1 0x71e1 0x71e1 0x71fd 0x71fd 0x71fd 0x721a 0x721a 0x721a 0x7236 0x7236 0x7236 0x7253 0x7253 0x7253 0x726f 0x726f 0x726f 0x728b 0x728b 0x728b 0x72a8 0x72a8 0x72a8 0x72c4 0x72c4 0x72c4 0x72e1 0x72e1 0x72e1 0x72fd 0x72fd 0x72fd 0x731a 0x731a 0x731a 0x7336 0x7336 0x7336 0x7352 0x7352 0x7352 0x736f 0x736f 0x736f 0x738b 0x738b 0x738b 0x73a8 0x73a8 0x73a8 0x73c4 0x73c4 0x73c4 0x73e1 0x73e1 0x73e1 0x73fd 0x73fd 0x73fd 0x741b 0x741b 0x741b 0x743f 0x743f 0x743f 0x7463 0x7463 0x7463 0x7486 0x7486 0x7486 0x74aa 0x74aa 0x74aa 0x74ce 0x74ce 0x74ce 0x74f2 0x74f2 0x74f2 0x7516 0x7516 0x7516 0x753a 0x753a 0x753a 0x755d 0x755d 0x755d 0x7581 0x7581 0x7581 0x75a5 0x75a5 0x75a5 0x75c9 0x75c9 0x75c9 0x75ed 0x75ed 0x75ed 0x7611 0x7611 0x7611 0x7634 0x7634 0x7634 0x7658 0x7658 0x7658 0x767c 0x767c 0x767c 0x76a0 0x76a0 0x76a0 0x76c4 0x76c4 0x76c4 0x76e8 0x76e8 0x76e8 0x770b 0x770b 0x770b 0x772f 0x772f 0x772f 0x7753 0x7753 0x7753 0x7777 0x7777 0x7777 0x779b 0x779b 0x779b 0x77bf 0x77bf 0x77bf 0x77e2 0x77e2 0x77e2 0x7806 0x7806 0x7806 0x7825 0x7825 0x7825 0x7840 0x7840 0x7840 0x785b 0x785b 0x785b 0x7876 0x7876 0x7876 0x7891 0x7891 0x7891 0x78ac 0x78ac 0x78ac 0x78c7 0x78c7 0x78c7 0x78e2 0x78e2 0x78e2 0x78fd 0x78fd 0x78fd 0x7918 0x7918 0x7918 0x7933 0x7933 0x7933 0x794e 0x794e 0x794e 0x7969 0x7969 0x7969 0x7984 0x7984 0x7984 0x799f 0x799f 0x799f 0x79ba 0x79ba 0x79ba 0x79d5 0x79d5 0x79d5 0x79f0 0x79f0 0x79f0 0x7a0b 0x7a0b 0x7a0b 0x7a26 0x7a26 0x7a26 0x7a41 0x7a41 0x7a41 0x7a5c 0x7a5c 0x7a5c 0x7a77 0x7a77 0x7a77 0x7a92 0x7a92 0x7a92 0x7aad 0x7aad 0x7aad 0x7ac8 0x7ac8 0x7ac8 0x7ae3 0x7ae3 0x7ae3 0x7afe 0x7afe 0x7afe 0x7b19 0x7b19 0x7b19 0x7b34 0x7b34 0x7b34 0x7b4f 0x7b4f 0x7b4f 0x7b6a 0x7b6a 0x7b6a 0x7b85 0x7b85 0x7b85 0x7ba0 0x7ba0 0x7ba0 0x7bbb 0x7bbb 0x7bbb 0x7bd5 0x7bd5 0x7bd5 0x7bf0 0x7bf0 0x7bf0 0x7c0b 0x7c0b 0x7c0b 0x7c23 0x7c23 0x7c23 0x7c35 0x7c35 0x7c35 0x7c47 0x7c47 0x7c47 0x7c59 0x7c59 0x7c59 0x7c6b 0x7c6b 0x7c6b 0x7c7d 0x7c7d 0x7c7d 0x7c90 0x7c90 0x7c90 0x7ca2 0x7ca2 0x7ca2 0x7cb4 0x7cb4 0x7cb4 0x7cc6 0x7cc6 0x7cc6 0x7cd8 0x7cd8 0x7cd8 0x7cea 0x7cea 0x7cea 0x7cfc 0x7cfc 0x7cfc 0x7d0f 0x7d0f 0x7d0f 0x7d21 0x7d21 0x7d21 0x7d33 0x7d33 0x7d33 0x7d45 0x7d45 0x7d45 0x7d57 0x7d57 0x7d57 0x7d69 0x7d69 0x7d69 0x7d7b 0x7d7b 0x7d7b 0x7d8e 0x7d8e 0x7d8e 0x7da0 0x7da0 0x7da0 0x7db2 0x7db2 0x7db2 0x7dc4 0x7dc4 0x7dc4 0x7dd6 0x7dd6 0x7dd6 0x7de8 0x7de8 0x7de8 0x7dfa 0x7dfa 0x7dfa 0x7e0d 0x7e0d 0x7e0d 0x7e1f 0x7e1f 0x7e1f 0x7e31 0x7e31 0x7e31 0x7e43 0x7e43 0x7e43 0x7e55 0x7e55 0x7e55 0x7e67 0x7e67 0x7e67 0x7e79 0x7e79 0x7e79 0x7e8c 0x7e8c 0x7e8c 0x7e9e 0x7e9e 0x7e9e 0x7eb0 0x7eb0 0x7eb0 0x7ec2 0x7ec2 0x7ec2 0x7ed4 0x7ed4 0x7ed4 0x7ee6 0x7ee6 0x7ee6 0x7ef8 0x7ef8 0x7ef8 0x7f0b 0x7f0b 0x7f0b 0x7f1d 0x7f1d 0x7f1d 0x7f2f 0x7f2f 0x7f2f 0x7f41 0x7f41 0x7f41 0x7f53 0x7f53 0x7f53 0x7f65 0x7f65 0x7f65 0x7f77 0x7f77 0x7f77 0x7f8a 0x7f8a 0x7f8a 0x7f9c 0x7f9c 0x7f9c 0x7fae 0x7fae 0x7fae 0x7fc0 0x7fc0 0x7fc0 0x7fd2 0x7fd2 0x7fd2 0x7fe4 0x7fe4 0x7fe4 0x7ff7 0x7ff7 0x7ff7 0x8009 0x8009 0x8009 0x801b 0x801b 0x801b 0x802b 0x802b 0x802b 0x803a 0x803a 0x803a 0x804a 0x804a 0x804a 0x8059 0x8059 0x8059 0x8069 0x8069 0x8069 0x8078 0x8078 0x8078 0x8087 0x8087 0x8087 0x8097 0x8097 0x8097 0x80a6 0x80a6 0x80a6 0x80b6 0x80b6 0x80b6 0x80c5 0x80c5 0x80c5 0x80d5 0x80d5 0x80d5 0x80e4 0x80e4 0x80e4 0x80f4 0x80f4 0x80f4 0x8103 0x8103 0x8103 0x8112 0x8112 0x8112 0x8122 0x8122 0x8122 0x8131 0x8131 0x8131 0x8141 0x8141 0x8141 0x8150 0x8150 0x8150 0x8160 0x8160 0x8160 0x816f 0x816f 0x816f 0x817e 0x817e 0x817e 0x818e 0x818e 0x818e 0x819d 0x819d 0x819d 0x81ad 0x81ad 0x81ad 0x81bc 0x81bc 0x81bc 0x81cc 0x81cc 0x81cc 0x81db 0x81db 0x81db 0x81eb 0x81eb 0x81eb 0x81fa 0x81fa 0x81fa 0x8209 0x8209 0x8209 0x8219 0x8219 0x8219 0x8228 0x8228 0x8228 0x8238 0x8238 0x8238 0x8247 0x8247 0x8247 0x8257 0x8257 0x8257 0x8266 0x8266 0x8266 0x8275 0x8275 0x8275 0x8285 0x8285 0x8285 0x8294 0x8294 0x8294 0x82a4 0x82a4 0x82a4 0x82b3 0x82b3 0x82b3 0x82c3 0x82c3 0x82c3 0x82d2 0x82d2 0x82d2 0x82e2 0x82e2 0x82e2 0x82f1 0x82f1 0x82f1 0x8300 0x8300 0x8300 0x8310 0x8310 0x8310 0x831f 0x831f 0x831f 0x832f 0x832f 0x832f 0x833e 0x833e 0x833e 0x834e 0x834e 0x834e 0x835d 0x835d 0x835d 0x836c 0x836c 0x836c 0x837c 0x837c 0x837c 0x838b 0x838b 0x838b 0x839b 0x839b 0x839b 0x83aa 0x83aa 0x83aa 0x83ba 0x83ba 0x83ba 0x83c9 0x83c9 0x83c9 0x83d8 0x83d8 0x83d8 0x83e8 0x83e8 0x83e8 0x83f7 0x83f7 0x83f7 0x8407 0x8407 0x8407 0x8416 0x8416 0x8416 0x8425 0x8425 0x8425 0x8431 0x8431 0x8431 0x843d 0x843d 0x843d 0x8449 0x8449 0x8449 0x8455 0x8455 0x8455 0x8462 0x8462 0x8462 0x846e 0x846e 0x846e 0x847a 0x847a 0x847a 0x8486 0x8486 0x8486 0x8492 0x8492 0x8492 0x849e 0x849e 0x849e 0x84aa 0x84aa 0x84aa 0x84b6 0x84b6 0x84b6 0x84c2 0x84c2 0x84c2 0x84ce 0x84ce 0x84ce 0x84da 0x84da 0x84da 0x84e7 0x84e7 0x84e7 0x84f3 0x84f3 0x84f3 0x84ff 0x84ff 0x84ff 0x850b 0x850b 0x850b 0x8517 0x8517 0x8517 0x8523 0x8523 0x8523 0x852f 0x852f 0x852f 0x853b 0x853b 0x853b 0x8547 0x8547 0x8547 0x8553 0x8553 0x8553 0x855f 0x855f 0x855f 0x856c 0x856c 0x856c 0x8578 0x8578 0x8578 0x8584 0x8584 0x8584 0x8590 0x8590 0x8590 0x859c 0x859c 0x859c 0x85a8 0x85a8 0x85a8 0x85b4 0x85b4 0x85b4 0x85c0 0x85c0 0x85c0 0x85cc 0x85cc 0x85cc 0x85d8 0x85d8 0x85d8 0x85e4 0x85e4 0x85e4 0x85f0 0x85f0 0x85f0 0x85fd 0x85fd 0x85fd 0x8609 0x8609 0x8609 0x8615 0x8615 0x8615 0x8621 0x8621 0x8621 0x862d 0x862d 0x862d 0x8639 0x8639 0x8639 0x8645 0x8645 0x8645 0x8651 0x8651 0x8651 0x865d 0x865d 0x865d 0x8669 0x8669 0x8669 0x8675 0x8675 0x8675 0x8682 0x8682 0x8682 0x868e 0x868e 0x868e 0x869a 0x869a 0x869a 0x86a6 0x86a6 0x86a6 0x86b2 0x86b2 0x86b2 0x86be 0x86be 0x86be 0x86ca 0x86ca 0x86ca 0x86d6 0x86d6 0x86d6 0x86e2 0x86e2 0x86e2 0x86ee 0x86ee 0x86ee 0x86fa 0x86fa 0x86fa 0x8707 0x8707 0x8707 0x8713 0x8713 0x8713 0x871f 0x871f 0x871f 0x872b 0x872b 0x872b 0x8737 0x8737 0x8737 0x8743 0x8743 0x8743 0x874f 0x874f 0x874f 0x875b 0x875b 0x875b 0x8767 0x8767 0x8767 0x8773 0x8773 0x8773 0x877f 0x877f 0x877f 0x878b 0x878b 0x878b 0x8798 0x8798 0x8798 0x87a4 0x87a4 0x87a4 0x87b0 0x87b0 0x87b0 0x87bc 0x87bc 0x87bc 0x87c8 0x87c8 0x87c8 0x87d4 0x87d4 0x87d4 0x87e0 0x87e0 0x87e0 0x87ec 0x87ec 0x87ec 0x87f8 0x87f8 0x87f8 0x8804 0x8804 0x8804 0x8810 0x8810 0x8810 0x881d 0x881d 0x881d 0x8829 0x8829 0x8829 0x8834 0x8834 0x8834 0x883f 0x883f 0x883f 0x884b 0x884b 0x884b 0x8856 0x8856 0x8856 0x8862 0x8862 0x8862 0x886d 0x886d 0x886d 0x8879 0x8879 0x8879 0x8884 0x8884 0x8884 0x8890 0x8890 0x8890 0x889b 0x889b 0x889b 0x88a6 0x88a6 0x88a6 0x88b2 0x88b2 0x88b2 0x88bd 0x88bd 0x88bd 0x88c9 0x88c9 0x88c9 0x88d4 0x88d4 0x88d4 0x88e0 0x88e0 0x88e0 0x88eb 0x88eb 0x88eb 0x88f6 0x88f6 0x88f6 0x8902 0x8902 0x8902 0x890d 0x890d 0x890d 0x8919 0x8919 0x8919 0x8924 0x8924 0x8924 0x8930 0x8930 0x8930 0x893b 0x893b 0x893b 0x8947 0x8947 0x8947 0x8952 0x8952 0x8952 0x895d 0x895d 0x895d 0x8969 0x8969 0x8969 0x8974 0x8974 0x8974 0x8980 0x8980 0x8980 0x898b 0x898b 0x898b 0x8997 0x8997 0x8997 0x89a2 0x89a2 0x89a2 0x89ae 0x89ae 0x89ae 0x89b9 0x89b9 0x89b9 0x89c4 0x89c4 0x89c4 0x89d0 0x89d0 0x89d0 0x89db 0x89db 0x89db 0x89e7 0x89e7 0x89e7 0x89f2 0x89f2 0x89f2 0x89fe 0x89fe 0x89fe 0x8a09 0x8a09 0x8a09 0x8a15 0x8a15 0x8a15 0x8a20 0x8a20 0x8a20 0x8a2b 0x8a2b 0x8a2b 0x8a37 0x8a37 0x8a37 0x8a42 0x8a42 0x8a42 0x8a4e 0x8a4e 0x8a4e 0x8a59 0x8a59 0x8a59 0x8a65 0x8a65 0x8a65 0x8a70 0x8a70 0x8a70 0x8a7b 0x8a7b 0x8a7b 0x8a87 0x8a87 0x8a87 0x8a92 0x8a92 0x8a92 0x8a9e 0x8a9e 0x8a9e 0x8aa9 0x8aa9 0x8aa9 0x8ab5 0x8ab5 0x8ab5 0x8ac0 0x8ac0 0x8ac0 0x8acc 0x8acc 0x8acc 0x8ad7 0x8ad7 0x8ad7 0x8ae2 0x8ae2 0x8ae2 0x8aee 0x8aee 0x8aee 0x8af9 0x8af9 0x8af9 0x8b05 0x8b05 0x8b05 0x8b10 0x8b10 0x8b10 0x8b1c 0x8b1c 0x8b1c 0x8b27 0x8b27 0x8b27 0x8b33 0x8b33 0x8b33 0x8b3e 0x8b3e 0x8b3e 0x8b49 0x8b49 0x8b49 0x8b55 0x8b55 0x8b55 0x8b60 0x8b60 0x8b60 0x8b6c 0x8b6c 0x8b6c 0x8b77 0x8b77 0x8b77 0x8b83 0x8b83 0x8b83 0x8b8e 0x8b8e 0x8b8e 0x8b99 0x8b99 0x8b99 0x8ba5 0x8ba5 0x8ba5 0x8bb0 0x8bb0 0x8bb0 0x8bbc 0x8bbc 0x8bbc 0x8bc7 0x8bc7 0x8bc7 0x8bd3 0x8bd3 0x8bd3 0x8bde 0x8bde 0x8bde 0x8bea 0x8bea 0x8bea 0x8bf5 0x8bf5 0x8bf5 0x8c00 0x8c00 0x8c00 0x8c0c 0x8c0c 0x8c0c 0x8c17 0x8c17 0x8c17 0x8c23 0x8c23 0x8c23 0x8c2e 0x8c2e 0x8c2e 0x8c38 0x8c38 0x8c38 0x8c43 0x8c43 0x8c43 0x8c4d 0x8c4d 0x8c4d 0x8c58 0x8c58 0x8c58 0x8c62 0x8c62 0x8c62 0x8c6c 0x8c6c 0x8c6c 0x8c77 0x8c77 0x8c77 0x8c81 0x8c81 0x8c81 0x8c8c 0x8c8c 0x8c8c 0x8c96 0x8c96 0x8c96 0x8ca0 0x8ca0 0x8ca0 0x8cab 0x8cab 0x8cab 0x8cb5 0x8cb5 0x8cb5 0x8cc0 0x8cc0 0x8cc0 0x8cca 0x8cca 0x8cca 0x8cd4 0x8cd4 0x8cd4 0x8cdf 0x8cdf 0x8cdf 0x8ce9 0x8ce9 0x8ce9 0x8cf4 0x8cf4 0x8cf4 0x8cfe 0x8cfe 0x8cfe 0x8d09 0x8d09 0x8d09 0x8d13 0x8d13 0x8d13 0x8d1d 0x8d1d 0x8d1d 0x8d28 0x8d28 0x8d28 0x8d32 0x8d32 0x8d32 0x8d3d 0x8d3d 0x8d3d 0x8d47 0x8d47 0x8d47 0x8d51 0x8d51 0x8d51 0x8d5c 0x8d5c 0x8d5c 0x8d66 0x8d66 0x8d66 0x8d71 0x8d71 0x8d71 0x8d7b 0x8d7b 0x8d7b 0x8d85 0x8d85 0x8d85 0x8d90 0x8d90 0x8d90 0x8d9a 0x8d9a 0x8d9a 0x8da5 0x8da5 0x8da5 0x8daf 0x8daf 0x8daf 0x8db9 0x8db9 0x8db9 0x8dc4 0x8dc4 0x8dc4 0x8dce 0x8dce 0x8dce 0x8dd9 0x8dd9 0x8dd9 0x8de3 0x8de3 0x8de3 0x8ded 0x8ded 0x8ded 0x8df8 0x8df8 0x8df8 0x8e02 0x8e02 0x8e02 0x8e0d 0x8e0d 0x8e0d 0x8e17 0x8e17 0x8e17 0x8e22 0x8e22 0x8e22 0x8e2c 0x8e2c 0x8e2c 0x8e36 0x8e36 0x8e36 0x8e41 0x8e41 0x8e41 0x8e4b 0x8e4b 0x8e4b 0x8e56 0x8e56 0x8e56 0x8e60 0x8e60 0x8e60 0x8e6a 0x8e6a 0x8e6a 0x8e75 0x8e75 0x8e75 0x8e7f 0x8e7f 0x8e7f 0x8e8a 0x8e8a 0x8e8a 0x8e94 0x8e94 0x8e94 0x8e9e 0x8e9e 0x8e9e 0x8ea9 0x8ea9 0x8ea9 0x8eb3 0x8eb3 0x8eb3 0x8ebe 0x8ebe 0x8ebe 0x8ec8 0x8ec8 0x8ec8 0x8ed2 0x8ed2 0x8ed2 0x8edd 0x8edd 0x8edd 0x8ee7 0x8ee7 0x8ee7 0x8ef2 0x8ef2 0x8ef2 0x8efc 0x8efc 0x8efc 0x8f07 0x8f07 0x8f07 0x8f11 0x8f11 0x8f11 0x8f1b 0x8f1b 0x8f1b 0x8f26 0x8f26 0x8f26 0x8f30 0x8f30 0x8f30 0x8f3b 0x8f3b 0x8f3b 0x8f45 0x8f45 0x8f45 0x8f4f 0x8f4f 0x8f4f 0x8f5a 0x8f5a 0x8f5a 0x8f64 0x8f64 0x8f64 0x8f6f 0x8f6f 0x8f6f 0x8f79 0x8f79 0x8f79 0x8f83 0x8f83 0x8f83 0x8f8e 0x8f8e 0x8f8e 0x8f98 0x8f98 0x8f98 0x8fa3 0x8fa3 0x8fa3 0x8fad 0x8fad 0x8fad 0x8fb7 0x8fb7 0x8fb7 0x8fc2 0x8fc2 0x8fc2 0x8fcc 0x8fcc 0x8fcc 0x8fd7 0x8fd7 0x8fd7 0x8fe1 0x8fe1 0x8fe1 0x8feb 0x8feb 0x8feb 0x8ff6 0x8ff6 0x8ff6 0x9000 0x9000 0x9000 0x900b 0x900b 0x900b 0x9015 0x9015 0x9015 0x9020 0x9020 0x9020 0x902a 0x902a 0x902a 0x9034 0x9034 0x9034 0x903e 0x903e 0x903e 0x9048 0x9048 0x9048 0x9052 0x9052 0x9052 0x905c 0x905c 0x905c 0x9066 0x9066 0x9066 0x9070 0x9070 0x9070 0x907a 0x907a 0x907a 0x9084 0x9084 0x9084 0x908e 0x908e 0x908e 0x9098 0x9098 0x9098 0x90a2 0x90a2 0x90a2 0x90ac 0x90ac 0x90ac 0x90b6 0x90b6 0x90b6 0x90c0 0x90c0 0x90c0 0x90ca 0x90ca 0x90ca 0x90d4 0x90d4 0x90d4 0x90de 0x90de 0x90de 0x90e8 0x90e8 0x90e8 0x90f2 0x90f2 0x90f2 0x90fc 0x90fc 0x90fc 0x9106 0x9106 0x9106 0x9110 0x9110 0x9110 0x911a 0x911a 0x911a 0x9123 0x9123 0x9123 0x912d 0x912d 0x912d 0x9137 0x9137 0x9137 0x9141 0x9141 0x9141 0x914b 0x914b 0x914b 0x9155 0x9155 0x9155 0x915f 0x915f 0x915f 0x9169 0x9169 0x9169 0x9173 0x9173 0x9173 0x917d 0x917d 0x917d 0x9187 0x9187 0x9187 0x9191 0x9191 0x9191 0x919b 0x919b 0x919b 0x91a5 0x91a5 0x91a5 0x91af 0x91af 0x91af 0x91b9 0x91b9 0x91b9 0x91c3 0x91c3 0x91c3 0x91cd 0x91cd 0x91cd 0x91d7 0x91d7 0x91d7 0x91e1 0x91e1 0x91e1 0x91eb 0x91eb 0x91eb 0x91f5 0x91f5 0x91f5 0x91ff 0x91ff 0x91ff 0x9209 0x9209 0x9209 0x9213 0x9213 0x9213 0x921d 0x921d 0x921d 0x9227 0x9227 0x9227 0x9231 0x9231 0x9231 0x923b 0x923b 0x923b 0x9245 0x9245 0x9245 0x924f 0x924f 0x924f 0x9259 0x9259 0x9259 0x9263 0x9263 0x9263 0x926d 0x926d 0x926d 0x9277 0x9277 0x9277 0x9281 0x9281 0x9281 0x928b 0x928b 0x928b 0x9295 0x9295 0x9295 0x929f 0x929f 0x929f 0x92a8 0x92a8 0x92a8 0x92b2 0x92b2 0x92b2 0x92bc 0x92bc 0x92bc 0x92c6 0x92c6 0x92c6 0x92d0 0x92d0 0x92d0 0x92da 0x92da 0x92da 0x92e4 0x92e4 0x92e4 0x92ee 0x92ee 0x92ee 0x92f8 0x92f8 0x92f8 0x9302 0x9302 0x9302 0x930c 0x930c 0x930c 0x9316 0x9316 0x9316 0x9320 0x9320 0x9320 0x932a 0x932a 0x932a 0x9334 0x9334 0x9334 0x933e 0x933e 0x933e 0x9348 0x9348 0x9348 0x9352 0x9352 0x9352 0x935c 0x935c 0x935c 0x9366 0x9366 0x9366 0x9370 0x9370 0x9370 0x937a 0x937a 0x937a 0x9384 0x9384 0x9384 0x938e 0x938e 0x938e 0x9398 0x9398 0x9398 0x93a2 0x93a2 0x93a2 0x93ac 0x93ac 0x93ac 0x93b6 0x93b6 0x93b6 0x93c0 0x93c0 0x93c0 0x93ca 0x93ca 0x93ca 0x93d4 0x93d4 0x93d4 0x93de 0x93de 0x93de 0x93e8 0x93e8 0x93e8 0x93f2 0x93f2 0x93f2 0x93fc 0x93fc 0x93fc 0x9406 0x9406 0x9406 0x9410 0x9410 0x9410 0x941a 0x941a 0x941a 0x9423 0x9423 0x9423 0x942d 0x942d 0x942d 0x9437 0x9437 0x9437 0x9440 0x9440 0x9440 0x9449 0x9449 0x9449 0x9451 0x9451 0x9451 0x945a 0x945a 0x945a 0x9463 0x9463 0x9463 0x946c 0x946c 0x946c 0x9475 0x9475 0x9475 0x947e 0x947e 0x947e 0x9486 0x9486 0x9486 0x948f 0x948f 0x948f 0x9498 0x9498 0x9498 0x94a1 0x94a1 0x94a1 0x94aa 0x94aa 0x94aa 0x94b3 0x94b3 0x94b3 0x94bb 0x94bb 0x94bb 0x94c4 0x94c4 0x94c4 0x94cd 0x94cd 0x94cd 0x94d6 0x94d6 0x94d6 0x94df 0x94df 0x94df 0x94e8 0x94e8 0x94e8 0x94f0 0x94f0 0x94f0 0x94f9 0x94f9 0x94f9 0x9502 0x9502 0x9502 0x950b 0x950b 0x950b 0x9514 0x9514 0x9514 0x951d 0x951d 0x951d 0x9525 0x9525 0x9525 0x952e 0x952e 0x952e 0x9537 0x9537 0x9537 0x9540 0x9540 0x9540 0x9549 0x9549 0x9549 0x9552 0x9552 0x9552 0x955a 0x955a 0x955a 0x9563 0x9563 0x9563 0x956c 0x956c 0x956c 0x9575 0x9575 0x9575 0x957e 0x957e 0x957e 0x9587 0x9587 0x9587 0x958f 0x958f 0x958f 0x9598 0x9598 0x9598 0x95a1 0x95a1 0x95a1 0x95aa 0x95aa 0x95aa 0x95b3 0x95b3 0x95b3 0x95bc 0x95bc 0x95bc 0x95c4 0x95c4 0x95c4 0x95cd 0x95cd 0x95cd 0x95d6 0x95d6 0x95d6 0x95df 0x95df 0x95df 0x95e8 0x95e8 0x95e8 0x95f1 0x95f1 0x95f1 0x95f9 0x95f9 0x95f9 0x9602 0x9602 0x9602 0x960b 0x960b 0x960b 0x9614 0x9614 0x9614 0x961d 0x961d 0x961d 0x9626 0x9626 0x9626 0x962e 0x962e 0x962e 0x9637 0x9637 0x9637 0x9640 0x9640 0x9640 0x9649 0x9649 0x9649 0x9652 0x9652 0x9652 0x965b 0x965b 0x965b 0x9663 0x9663 0x9663 0x966c 0x966c 0x966c 0x9675 0x9675 0x9675 0x967e 0x967e 0x967e 0x9687 0x9687 0x9687 0x9690 0x9690 0x9690 0x9698 0x9698 0x9698 0x96a1 0x96a1 0x96a1 0x96aa 0x96aa 0x96aa 0x96b3 0x96b3 0x96b3 0x96bc 0x96bc 0x96bc 0x96c5 0x96c5 0x96c5 0x96cd 0x96cd 0x96cd 0x96d6 0x96d6 0x96d6 0x96df 0x96df 0x96df 0x96e8 0x96e8 0x96e8 0x96f1 0x96f1 0x96f1 0x96f9 0x96f9 0x96f9 0x9702 0x9702 0x9702 0x970b 0x970b 0x970b 0x9714 0x9714 0x9714 0x971d 0x971d 0x971d 0x9726 0x9726 0x9726 0x972e 0x972e 0x972e 0x9737 0x9737 0x9737 0x9740 0x9740 0x9740 0x9749 0x9749 0x9749 0x9752 0x9752 0x9752 0x975b 0x975b 0x975b 0x9763 0x9763 0x9763 0x976c 0x976c 0x976c 0x9775 0x9775 0x9775 0x977e 0x977e 0x977e 0x9787 0x9787 0x9787 0x9790 0x9790 0x9790 0x9798 0x9798 0x9798 0x97a1 0x97a1 0x97a1 0x97aa 0x97aa 0x97aa 0x97b3 0x97b3 0x97b3 0x97bc 0x97bc 0x97bc 0x97c5 0x97c5 0x97c5 0x97cd 0x97cd 0x97cd 0x97d6 0x97d6 0x97d6 0x97df 0x97df 0x97df 0x97e8 0x97e8 0x97e8 0x97f1 0x97f1 0x97f1 0x97fa 0x97fa 0x97fa 0x9802 0x9802 0x9802 0x980b 0x980b 0x980b 0x9814 0x9814 0x9814 0x981d 0x981d 0x981d 0x9826 0x9826 0x9826 0x982f 0x982f 0x982f 0x9837 0x9837 0x9837 0x983f 0x983f 0x983f 0x9847 0x9847 0x9847 0x984f 0x984f 0x984f 0x9857 0x9857 0x9857 0x985f 0x985f 0x985f 0x9867 0x9867 0x9867 0x986e 0x986e 0x986e 0x9876 0x9876 0x9876 0x987e 0x987e 0x987e 0x9886 0x9886 0x9886 0x988e 0x988e 0x988e 0x9896 0x9896 0x9896 0x989e 0x989e 0x989e 0x98a5 0x98a5 0x98a5 0x98ad 0x98ad 0x98ad 0x98b5 0x98b5 0x98b5 0x98bd 0x98bd 0x98bd 0x98c5 0x98c5 0x98c5 0x98cd 0x98cd 0x98cd 0x98d5 0x98d5 0x98d5 0x98dc 0x98dc 0x98dc 0x98e4 0x98e4 0x98e4 0x98ec 0x98ec 0x98ec 0x98f4 0x98f4 0x98f4 0x98fc 0x98fc 0x98fc 0x9904 0x9904 0x9904 0x990c 0x990c 0x990c 0x9913 0x9913 0x9913 0x991b 0x991b 0x991b 0x9923 0x9923 0x9923 0x992b 0x992b 0x992b 0x9933 0x9933 0x9933 0x993b 0x993b 0x993b 0x9943 0x9943 0x9943 0x994a 0x994a 0x994a 0x9952 0x9952 0x9952 0x995a 0x995a 0x995a 0x9962 0x9962 0x9962 0x996a 0x996a 0x996a 0x9972 0x9972 0x9972 0x997a 0x997a 0x997a 0x9981 0x9981 0x9981 0x9989 0x9989 0x9989 0x9991 0x9991 0x9991 0x9999 0x9999 0x9999 0x99a1 0x99a1 0x99a1 0x99a9 0x99a9 0x99a9 0x99b1 0x99b1 0x99b1 0x99b8 0x99b8 0x99b8 0x99c0 0x99c0 0x99c0 0x99c8 0x99c8 0x99c8 0x99d0 0x99d0 0x99d0 0x99d8 0x99d8 0x99d8 0x99e0 0x99e0 0x99e0 0x99e8 0x99e8 0x99e8 0x99ef 0x99ef 0x99ef 0x99f7 0x99f7 0x99f7 0x99ff 0x99ff 0x99ff 0x9a07 0x9a07 0x9a07 0x9a0f 0x9a0f 0x9a0f 0x9a17 0x9a17 0x9a17 0x9a1f 0x9a1f 0x9a1f 0x9a26 0x9a26 0x9a26 0x9a2e 0x9a2e 0x9a2e 0x9a36 0x9a36 0x9a36 0x9a3e 0x9a3e 0x9a3e 0x9a46 0x9a46 0x9a46 0x9a4e 0x9a4e 0x9a4e 0x9a56 0x9a56 0x9a56 0x9a5d 0x9a5d 0x9a5d 0x9a65 0x9a65 0x9a65 0x9a6d 0x9a6d 0x9a6d 0x9a75 0x9a75 0x9a75 0x9a7d 0x9a7d 0x9a7d 0x9a85 0x9a85 0x9a85 0x9a8d 0x9a8d 0x9a8d 0x9a94 0x9a94 0x9a94 0x9a9c 0x9a9c 0x9a9c 0x9aa4 0x9aa4 0x9aa4 0x9aac 0x9aac 0x9aac 0x9ab4 0x9ab4 0x9ab4 0x9abc 0x9abc 0x9abc 0x9ac4 0x9ac4 0x9ac4 0x9acb 0x9acb 0x9acb 0x9ad3 0x9ad3 0x9ad3 0x9adb 0x9adb 0x9adb 0x9ae3 0x9ae3 0x9ae3 0x9aeb 0x9aeb 0x9aeb 0x9af3 0x9af3 0x9af3 0x9afb 0x9afb 0x9afb 0x9b02 0x9b02 0x9b02 0x9b0a 0x9b0a 0x9b0a 0x9b12 0x9b12 0x9b12 0x9b1a 0x9b1a 0x9b1a 0x9b22 0x9b22 0x9b22 0x9b2a 0x9b2a 0x9b2a 0x9b32 0x9b32 0x9b32 0x9b39 0x9b39 0x9b39 0x9b41 0x9b41 0x9b41 0x9b49 0x9b49 0x9b49 0x9b51 0x9b51 0x9b51 0x9b59 0x9b59 0x9b59 0x9b61 0x9b61 0x9b61 0x9b69 0x9b69 0x9b69 0x9b70 0x9b70 0x9b70 0x9b78 0x9b78 0x9b78 0x9b80 0x9b80 0x9b80 0x9b88 0x9b88 0x9b88 0x9b90 0x9b90 0x9b90 0x9b98 0x9b98 0x9b98 0x9ba0 0x9ba0 0x9ba0 0x9ba7 0x9ba7 0x9ba7 0x9baf 0x9baf 0x9baf 0x9bb7 0x9bb7 0x9bb7 0x9bbf 0x9bbf 0x9bbf 0x9bc7 0x9bc7 0x9bc7 0x9bcf 0x9bcf 0x9bcf 0x9bd7 0x9bd7 0x9bd7 0x9bde 0x9bde 0x9bde 0x9be6 0x9be6 0x9be6 0x9bee 0x9bee 0x9bee 0x9bf6 0x9bf6 0x9bf6 0x9bfe 0x9bfe 0x9bfe 0x9c06 0x9c06 0x9c06 0x9c0e 0x9c0e 0x9c0e 0x9c15 0x9c15 0x9c15 0x9c1d 0x9c1d 0x9c1d 0x9c25 0x9c25 0x9c25 0x9c2d 0x9c2d 0x9c2d 0x9c35 0x9c35 0x9c35 0x9c3d 0x9c3d 0x9c3d 0x9c44 0x9c44 0x9c44 0x9c4b 0x9c4b 0x9c4b 0x9c53 0x9c53 0x9c53 0x9c5a 0x9c5a 0x9c5a 0x9c61 0x9c61 0x9c61 0x9c69 0x9c69 0x9c69 0x9c70 0x9c70 0x9c70 0x9c77 0x9c77 0x9c77 0x9c7f 0x9c7f 0x9c7f 0x9c86 0x9c86 0x9c86 0x9c8d 0x9c8d 0x9c8d 0x9c95 0x9c95 0x9c95 0x9c9c 0x9c9c 0x9c9c 0x9ca3 0x9ca3 0x9ca3 0x9cab 0x9cab 0x9cab 0x9cb2 0x9cb2 0x9cb2 0x9cb9 0x9cb9 0x9cb9 0x9cc1 0x9cc1 0x9cc1 0x9cc8 0x9cc8 0x9cc8 0x9ccf 0x9ccf 0x9ccf 0x9cd7 0x9cd7 0x9cd7 0x9cde 0x9cde 0x9cde 0x9ce5 0x9ce5 0x9ce5 0x9ced 0x9ced 0x9ced 0x9cf4 0x9cf4 0x9cf4 0x9cfb 0x9cfb 0x9cfb 0x9d03 0x9d03 0x9d03 0x9d0a 0x9d0a 0x9d0a 0x9d12 0x9d12 0x9d12 0x9d19 0x9d19 0x9d19 0x9d20 0x9d20 0x9d20 0x9d28 0x9d28 0x9d28 0x9d2f 0x9d2f 0x9d2f 0x9d36 0x9d36 0x9d36 0x9d3e 0x9d3e 0x9d3e 0x9d45 0x9d45 0x9d45 0x9d4c 0x9d4c 0x9d4c 0x9d54 0x9d54 0x9d54 0x9d5b 0x9d5b 0x9d5b 0x9d62 0x9d62 0x9d62 0x9d6a 0x9d6a 0x9d6a 0x9d71 0x9d71 0x9d71 0x9d78 0x9d78 0x9d78 0x9d80 0x9d80 0x9d80 0x9d87 0x9d87 0x9d87 0x9d8e 0x9d8e 0x9d8e 0x9d96 0x9d96 0x9d96 0x9d9d 0x9d9d 0x9d9d 0x9da4 0x9da4 0x9da4 0x9dac 0x9dac 0x9dac 0x9db3 0x9db3 0x9db3 0x9dba 0x9dba 0x9dba 0x9dc2 0x9dc2 0x9dc2 0x9dc9 0x9dc9 0x9dc9 0x9dd0 0x9dd0 0x9dd0 0x9dd8 0x9dd8 0x9dd8 0x9ddf 0x9ddf 0x9ddf 0x9de6 0x9de6 0x9de6 0x9dee 0x9dee 0x9dee 0x9df5 0x9df5 0x9df5 0x9dfc 0x9dfc 0x9dfc 0x9e04 0x9e04 0x9e04 0x9e0b 0x9e0b 0x9e0b 0x9e13 0x9e13 0x9e13 0x9e1a 0x9e1a 0x9e1a 0x9e21 0x9e21 0x9e21 0x9e29 0x9e29 0x9e29 0x9e30 0x9e30 0x9e30 0x9e37 0x9e37 0x9e37 0x9e3f 0x9e3f 0x9e3f 0x9e46 0x9e46 0x9e46 0x9e4d 0x9e4d 0x9e4d 0x9e55 0x9e55 0x9e55 0x9e5c 0x9e5c 0x9e5c 0x9e63 0x9e63 0x9e63 0x9e6b 0x9e6b 0x9e6b 0x9e72 0x9e72 0x9e72 0x9e79 0x9e79 0x9e79 0x9e81 0x9e81 0x9e81 0x9e88 0x9e88 0x9e88 0x9e8f 0x9e8f 0x9e8f 0x9e97 0x9e97 0x9e97 0x9e9e 0x9e9e 0x9e9e 0x9ea5 0x9ea5 0x9ea5 0x9ead 0x9ead 0x9ead 0x9eb4 0x9eb4 0x9eb4 0x9ebb 0x9ebb 0x9ebb 0x9ec3 0x9ec3 0x9ec3 0x9eca 0x9eca 0x9eca 0x9ed1 0x9ed1 0x9ed1 0x9ed9 0x9ed9 0x9ed9 0x9ee0 0x9ee0 0x9ee0 0x9ee7 0x9ee7 0x9ee7 0x9eef 0x9eef 0x9eef 0x9ef6 0x9ef6 0x9ef6 0x9efd 0x9efd 0x9efd 0x9f05 0x9f05 0x9f05 0x9f0c 0x9f0c 0x9f0c 0x9f14 0x9f14 0x9f14 0x9f1b 0x9f1b 0x9f1b 0x9f22 0x9f22 0x9f22 0x9f2a 0x9f2a 0x9f2a 0x9f31 0x9f31 0x9f31 0x9f38 0x9f38 0x9f38 0x9f40 0x9f40 0x9f40 0x9f47 0x9f47 0x9f47 0x9f4e 0x9f4e 0x9f4e 0x9f56 0x9f56 0x9f56 0x9f5d 0x9f5d 0x9f5d 0x9f64 0x9f64 0x9f64 0x9f6c 0x9f6c 0x9f6c 0x9f73 0x9f73 0x9f73 0x9f7a 0x9f7a 0x9f7a 0x9f82 0x9f82 0x9f82 0x9f89 0x9f89 0x9f89 0x9f90 0x9f90 0x9f90 0x9f98 0x9f98 0x9f98 0x9f9f 0x9f9f 0x9f9f 0x9fa6 0x9fa6 0x9fa6 0x9fae 0x9fae 0x9fae 0x9fb5 0x9fb5 0x9fb5 0x9fbc 0x9fbc 0x9fbc 0x9fc4 0x9fc4 0x9fc4 0x9fcb 0x9fcb 0x9fcb 0x9fd2 0x9fd2 0x9fd2 0x9fda 0x9fda 0x9fda 0x9fe1 0x9fe1 0x9fe1 0x9fe8 0x9fe8 0x9fe8 0x9ff0 0x9ff0 0x9ff0 0x9ff7 0x9ff7 0x9ff7 0x9fff 0x9fff 0x9fff>; + }; + }; + + panel-null-dsi-hotplug { + status = "disabled"; + compatible = "null,dsi-hotplug"; + nvidia,dsi-instance = <0x0>; + nvidia,dsi-hdmi-bridge = <0x1>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-video-data-type = <0x0>; + nvidia,dsi-video-clock-mode = <0x0>; + nvidia,dsi-video-burst-mode = <0x0>; + nvidia,dsi-ganged-type = <0x1>; + nvidia,dsi-ganged-swap-links = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-controller-vs = <0x1>; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-suspend-stop-stream-late = <0x1>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,default_color_space = <0x0>; + nvidia,dsi-pkt-seq = <0x1 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff>; + nvidia,edid = <0xffffff 0xffffff00 0x10ac68a0 0x55344b31 0x1c160103 0x80351e78 0xea9265a6 0x55559f28 0xd5054a5 0x4b00714f 0x8180d1c0 0x1010101 0x1010101 0x101023a 0x80187138 0x2d40582c 0x4500132b 0x2100001e 0xff 0x573856 0x59393237 0x41314b34 0x550a0000 0xfc0044 0x454c4c20 0x53543234 0x32304c0a 0xfd 0x384c1e 0x5311000a 0x20202020 0x20200198>; + + disp-default-out { + nvidia,out-type = <0x2>; + nvidia,out-flags = <0x0>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-xres = <0x1000>; + nvidia,out-yres = <0x870>; + }; + + smartdimmer { + status = "disabled"; + }; + + nvdisp-cmu { + nvidia,panel-csc = <0xd581 0x2979 0xc5 0x0 0x831 0xcac1 0x20c 0x0 0x189 0x625 0xcc4a 0x0>; + nvidia,cmu-lut = <0x6000 0x6000 0x6000 0x6191 0x6191 0x6191 0x6322 0x6322 0x6322 0x643b 0x643b 0x643b 0x64ba 0x64ba 0x64ba 0x6539 0x6539 0x6539 0x65b8 0x65b8 0x65b8 0x6637 0x6637 0x6637 0x66b6 0x66b6 0x66b6 0x6735 0x6735 0x6735 0x67b4 0x67b4 0x67b4 0x6826 0x6826 0x6826 0x687d 0x687d 0x687d 0x68d4 0x68d4 0x68d4 0x692b 0x692b 0x692b 0x6983 0x6983 0x6983 0x69da 0x69da 0x69da 0x6a31 0x6a31 0x6a31 0x6a88 0x6a88 0x6a88 0x6ae0 0x6ae0 0x6ae0 0x6b37 0x6b37 0x6b37 0x6b8e 0x6b8e 0x6b8e 0x6be5 0x6be5 0x6be5 0x6c28 0x6c28 0x6c28 0x6c5b 0x6c5b 0x6c5b 0x6c8e 0x6c8e 0x6c8e 0x6cc1 0x6cc1 0x6cc1 0x6cf4 0x6cf4 0x6cf4 0x6d27 0x6d27 0x6d27 0x6d5a 0x6d5a 0x6d5a 0x6d8d 0x6d8d 0x6d8d 0x6dbf 0x6dbf 0x6dbf 0x6df2 0x6df2 0x6df2 0x6e25 0x6e25 0x6e25 0x6e58 0x6e58 0x6e58 0x6e8b 0x6e8b 0x6e8b 0x6ebe 0x6ebe 0x6ebe 0x6ef1 0x6ef1 0x6ef1 0x6f24 0x6f24 0x6f24 0x6f57 0x6f57 0x6f57 0x6f8a 0x6f8a 0x6f8a 0x6fbd 0x6fbd 0x6fbd 0x6ff0 0x6ff0 0x6ff0 0x701a 0x701a 0x701a 0x7037 0x7037 0x7037 0x7053 0x7053 0x7053 0x706f 0x706f 0x706f 0x708c 0x708c 0x708c 0x70a8 0x70a8 0x70a8 0x70c5 0x70c5 0x70c5 0x70e1 0x70e1 0x70e1 0x70fe 0x70fe 0x70fe 0x711a 0x711a 0x711a 0x7136 0x7136 0x7136 0x7153 0x7153 0x7153 0x716f 0x716f 0x716f 0x718c 0x718c 0x718c 0x71a8 0x71a8 0x71a8 0x71c4 0x71c4 0x71c4 0x71e1 0x71e1 0x71e1 0x71fd 0x71fd 0x71fd 0x721a 0x721a 0x721a 0x7236 0x7236 0x7236 0x7253 0x7253 0x7253 0x726f 0x726f 0x726f 0x728b 0x728b 0x728b 0x72a8 0x72a8 0x72a8 0x72c4 0x72c4 0x72c4 0x72e1 0x72e1 0x72e1 0x72fd 0x72fd 0x72fd 0x731a 0x731a 0x731a 0x7336 0x7336 0x7336 0x7352 0x7352 0x7352 0x736f 0x736f 0x736f 0x738b 0x738b 0x738b 0x73a8 0x73a8 0x73a8 0x73c4 0x73c4 0x73c4 0x73e1 0x73e1 0x73e1 0x73fd 0x73fd 0x73fd 0x741b 0x741b 0x741b 0x743f 0x743f 0x743f 0x7463 0x7463 0x7463 0x7486 0x7486 0x7486 0x74aa 0x74aa 0x74aa 0x74ce 0x74ce 0x74ce 0x74f2 0x74f2 0x74f2 0x7516 0x7516 0x7516 0x753a 0x753a 0x753a 0x755d 0x755d 0x755d 0x7581 0x7581 0x7581 0x75a5 0x75a5 0x75a5 0x75c9 0x75c9 0x75c9 0x75ed 0x75ed 0x75ed 0x7611 0x7611 0x7611 0x7634 0x7634 0x7634 0x7658 0x7658 0x7658 0x767c 0x767c 0x767c 0x76a0 0x76a0 0x76a0 0x76c4 0x76c4 0x76c4 0x76e8 0x76e8 0x76e8 0x770b 0x770b 0x770b 0x772f 0x772f 0x772f 0x7753 0x7753 0x7753 0x7777 0x7777 0x7777 0x779b 0x779b 0x779b 0x77bf 0x77bf 0x77bf 0x77e2 0x77e2 0x77e2 0x7806 0x7806 0x7806 0x7825 0x7825 0x7825 0x7840 0x7840 0x7840 0x785b 0x785b 0x785b 0x7876 0x7876 0x7876 0x7891 0x7891 0x7891 0x78ac 0x78ac 0x78ac 0x78c7 0x78c7 0x78c7 0x78e2 0x78e2 0x78e2 0x78fd 0x78fd 0x78fd 0x7918 0x7918 0x7918 0x7933 0x7933 0x7933 0x794e 0x794e 0x794e 0x7969 0x7969 0x7969 0x7984 0x7984 0x7984 0x799f 0x799f 0x799f 0x79ba 0x79ba 0x79ba 0x79d5 0x79d5 0x79d5 0x79f0 0x79f0 0x79f0 0x7a0b 0x7a0b 0x7a0b 0x7a26 0x7a26 0x7a26 0x7a41 0x7a41 0x7a41 0x7a5c 0x7a5c 0x7a5c 0x7a77 0x7a77 0x7a77 0x7a92 0x7a92 0x7a92 0x7aad 0x7aad 0x7aad 0x7ac8 0x7ac8 0x7ac8 0x7ae3 0x7ae3 0x7ae3 0x7afe 0x7afe 0x7afe 0x7b19 0x7b19 0x7b19 0x7b34 0x7b34 0x7b34 0x7b4f 0x7b4f 0x7b4f 0x7b6a 0x7b6a 0x7b6a 0x7b85 0x7b85 0x7b85 0x7ba0 0x7ba0 0x7ba0 0x7bbb 0x7bbb 0x7bbb 0x7bd5 0x7bd5 0x7bd5 0x7bf0 0x7bf0 0x7bf0 0x7c0b 0x7c0b 0x7c0b 0x7c23 0x7c23 0x7c23 0x7c35 0x7c35 0x7c35 0x7c47 0x7c47 0x7c47 0x7c59 0x7c59 0x7c59 0x7c6b 0x7c6b 0x7c6b 0x7c7d 0x7c7d 0x7c7d 0x7c90 0x7c90 0x7c90 0x7ca2 0x7ca2 0x7ca2 0x7cb4 0x7cb4 0x7cb4 0x7cc6 0x7cc6 0x7cc6 0x7cd8 0x7cd8 0x7cd8 0x7cea 0x7cea 0x7cea 0x7cfc 0x7cfc 0x7cfc 0x7d0f 0x7d0f 0x7d0f 0x7d21 0x7d21 0x7d21 0x7d33 0x7d33 0x7d33 0x7d45 0x7d45 0x7d45 0x7d57 0x7d57 0x7d57 0x7d69 0x7d69 0x7d69 0x7d7b 0x7d7b 0x7d7b 0x7d8e 0x7d8e 0x7d8e 0x7da0 0x7da0 0x7da0 0x7db2 0x7db2 0x7db2 0x7dc4 0x7dc4 0x7dc4 0x7dd6 0x7dd6 0x7dd6 0x7de8 0x7de8 0x7de8 0x7dfa 0x7dfa 0x7dfa 0x7e0d 0x7e0d 0x7e0d 0x7e1f 0x7e1f 0x7e1f 0x7e31 0x7e31 0x7e31 0x7e43 0x7e43 0x7e43 0x7e55 0x7e55 0x7e55 0x7e67 0x7e67 0x7e67 0x7e79 0x7e79 0x7e79 0x7e8c 0x7e8c 0x7e8c 0x7e9e 0x7e9e 0x7e9e 0x7eb0 0x7eb0 0x7eb0 0x7ec2 0x7ec2 0x7ec2 0x7ed4 0x7ed4 0x7ed4 0x7ee6 0x7ee6 0x7ee6 0x7ef8 0x7ef8 0x7ef8 0x7f0b 0x7f0b 0x7f0b 0x7f1d 0x7f1d 0x7f1d 0x7f2f 0x7f2f 0x7f2f 0x7f41 0x7f41 0x7f41 0x7f53 0x7f53 0x7f53 0x7f65 0x7f65 0x7f65 0x7f77 0x7f77 0x7f77 0x7f8a 0x7f8a 0x7f8a 0x7f9c 0x7f9c 0x7f9c 0x7fae 0x7fae 0x7fae 0x7fc0 0x7fc0 0x7fc0 0x7fd2 0x7fd2 0x7fd2 0x7fe4 0x7fe4 0x7fe4 0x7ff7 0x7ff7 0x7ff7 0x8009 0x8009 0x8009 0x801b 0x801b 0x801b 0x802b 0x802b 0x802b 0x803a 0x803a 0x803a 0x804a 0x804a 0x804a 0x8059 0x8059 0x8059 0x8069 0x8069 0x8069 0x8078 0x8078 0x8078 0x8087 0x8087 0x8087 0x8097 0x8097 0x8097 0x80a6 0x80a6 0x80a6 0x80b6 0x80b6 0x80b6 0x80c5 0x80c5 0x80c5 0x80d5 0x80d5 0x80d5 0x80e4 0x80e4 0x80e4 0x80f4 0x80f4 0x80f4 0x8103 0x8103 0x8103 0x8112 0x8112 0x8112 0x8122 0x8122 0x8122 0x8131 0x8131 0x8131 0x8141 0x8141 0x8141 0x8150 0x8150 0x8150 0x8160 0x8160 0x8160 0x816f 0x816f 0x816f 0x817e 0x817e 0x817e 0x818e 0x818e 0x818e 0x819d 0x819d 0x819d 0x81ad 0x81ad 0x81ad 0x81bc 0x81bc 0x81bc 0x81cc 0x81cc 0x81cc 0x81db 0x81db 0x81db 0x81eb 0x81eb 0x81eb 0x81fa 0x81fa 0x81fa 0x8209 0x8209 0x8209 0x8219 0x8219 0x8219 0x8228 0x8228 0x8228 0x8238 0x8238 0x8238 0x8247 0x8247 0x8247 0x8257 0x8257 0x8257 0x8266 0x8266 0x8266 0x8275 0x8275 0x8275 0x8285 0x8285 0x8285 0x8294 0x8294 0x8294 0x82a4 0x82a4 0x82a4 0x82b3 0x82b3 0x82b3 0x82c3 0x82c3 0x82c3 0x82d2 0x82d2 0x82d2 0x82e2 0x82e2 0x82e2 0x82f1 0x82f1 0x82f1 0x8300 0x8300 0x8300 0x8310 0x8310 0x8310 0x831f 0x831f 0x831f 0x832f 0x832f 0x832f 0x833e 0x833e 0x833e 0x834e 0x834e 0x834e 0x835d 0x835d 0x835d 0x836c 0x836c 0x836c 0x837c 0x837c 0x837c 0x838b 0x838b 0x838b 0x839b 0x839b 0x839b 0x83aa 0x83aa 0x83aa 0x83ba 0x83ba 0x83ba 0x83c9 0x83c9 0x83c9 0x83d8 0x83d8 0x83d8 0x83e8 0x83e8 0x83e8 0x83f7 0x83f7 0x83f7 0x8407 0x8407 0x8407 0x8416 0x8416 0x8416 0x8425 0x8425 0x8425 0x8431 0x8431 0x8431 0x843d 0x843d 0x843d 0x8449 0x8449 0x8449 0x8455 0x8455 0x8455 0x8462 0x8462 0x8462 0x846e 0x846e 0x846e 0x847a 0x847a 0x847a 0x8486 0x8486 0x8486 0x8492 0x8492 0x8492 0x849e 0x849e 0x849e 0x84aa 0x84aa 0x84aa 0x84b6 0x84b6 0x84b6 0x84c2 0x84c2 0x84c2 0x84ce 0x84ce 0x84ce 0x84da 0x84da 0x84da 0x84e7 0x84e7 0x84e7 0x84f3 0x84f3 0x84f3 0x84ff 0x84ff 0x84ff 0x850b 0x850b 0x850b 0x8517 0x8517 0x8517 0x8523 0x8523 0x8523 0x852f 0x852f 0x852f 0x853b 0x853b 0x853b 0x8547 0x8547 0x8547 0x8553 0x8553 0x8553 0x855f 0x855f 0x855f 0x856c 0x856c 0x856c 0x8578 0x8578 0x8578 0x8584 0x8584 0x8584 0x8590 0x8590 0x8590 0x859c 0x859c 0x859c 0x85a8 0x85a8 0x85a8 0x85b4 0x85b4 0x85b4 0x85c0 0x85c0 0x85c0 0x85cc 0x85cc 0x85cc 0x85d8 0x85d8 0x85d8 0x85e4 0x85e4 0x85e4 0x85f0 0x85f0 0x85f0 0x85fd 0x85fd 0x85fd 0x8609 0x8609 0x8609 0x8615 0x8615 0x8615 0x8621 0x8621 0x8621 0x862d 0x862d 0x862d 0x8639 0x8639 0x8639 0x8645 0x8645 0x8645 0x8651 0x8651 0x8651 0x865d 0x865d 0x865d 0x8669 0x8669 0x8669 0x8675 0x8675 0x8675 0x8682 0x8682 0x8682 0x868e 0x868e 0x868e 0x869a 0x869a 0x869a 0x86a6 0x86a6 0x86a6 0x86b2 0x86b2 0x86b2 0x86be 0x86be 0x86be 0x86ca 0x86ca 0x86ca 0x86d6 0x86d6 0x86d6 0x86e2 0x86e2 0x86e2 0x86ee 0x86ee 0x86ee 0x86fa 0x86fa 0x86fa 0x8707 0x8707 0x8707 0x8713 0x8713 0x8713 0x871f 0x871f 0x871f 0x872b 0x872b 0x872b 0x8737 0x8737 0x8737 0x8743 0x8743 0x8743 0x874f 0x874f 0x874f 0x875b 0x875b 0x875b 0x8767 0x8767 0x8767 0x8773 0x8773 0x8773 0x877f 0x877f 0x877f 0x878b 0x878b 0x878b 0x8798 0x8798 0x8798 0x87a4 0x87a4 0x87a4 0x87b0 0x87b0 0x87b0 0x87bc 0x87bc 0x87bc 0x87c8 0x87c8 0x87c8 0x87d4 0x87d4 0x87d4 0x87e0 0x87e0 0x87e0 0x87ec 0x87ec 0x87ec 0x87f8 0x87f8 0x87f8 0x8804 0x8804 0x8804 0x8810 0x8810 0x8810 0x881d 0x881d 0x881d 0x8829 0x8829 0x8829 0x8834 0x8834 0x8834 0x883f 0x883f 0x883f 0x884b 0x884b 0x884b 0x8856 0x8856 0x8856 0x8862 0x8862 0x8862 0x886d 0x886d 0x886d 0x8879 0x8879 0x8879 0x8884 0x8884 0x8884 0x8890 0x8890 0x8890 0x889b 0x889b 0x889b 0x88a6 0x88a6 0x88a6 0x88b2 0x88b2 0x88b2 0x88bd 0x88bd 0x88bd 0x88c9 0x88c9 0x88c9 0x88d4 0x88d4 0x88d4 0x88e0 0x88e0 0x88e0 0x88eb 0x88eb 0x88eb 0x88f6 0x88f6 0x88f6 0x8902 0x8902 0x8902 0x890d 0x890d 0x890d 0x8919 0x8919 0x8919 0x8924 0x8924 0x8924 0x8930 0x8930 0x8930 0x893b 0x893b 0x893b 0x8947 0x8947 0x8947 0x8952 0x8952 0x8952 0x895d 0x895d 0x895d 0x8969 0x8969 0x8969 0x8974 0x8974 0x8974 0x8980 0x8980 0x8980 0x898b 0x898b 0x898b 0x8997 0x8997 0x8997 0x89a2 0x89a2 0x89a2 0x89ae 0x89ae 0x89ae 0x89b9 0x89b9 0x89b9 0x89c4 0x89c4 0x89c4 0x89d0 0x89d0 0x89d0 0x89db 0x89db 0x89db 0x89e7 0x89e7 0x89e7 0x89f2 0x89f2 0x89f2 0x89fe 0x89fe 0x89fe 0x8a09 0x8a09 0x8a09 0x8a15 0x8a15 0x8a15 0x8a20 0x8a20 0x8a20 0x8a2b 0x8a2b 0x8a2b 0x8a37 0x8a37 0x8a37 0x8a42 0x8a42 0x8a42 0x8a4e 0x8a4e 0x8a4e 0x8a59 0x8a59 0x8a59 0x8a65 0x8a65 0x8a65 0x8a70 0x8a70 0x8a70 0x8a7b 0x8a7b 0x8a7b 0x8a87 0x8a87 0x8a87 0x8a92 0x8a92 0x8a92 0x8a9e 0x8a9e 0x8a9e 0x8aa9 0x8aa9 0x8aa9 0x8ab5 0x8ab5 0x8ab5 0x8ac0 0x8ac0 0x8ac0 0x8acc 0x8acc 0x8acc 0x8ad7 0x8ad7 0x8ad7 0x8ae2 0x8ae2 0x8ae2 0x8aee 0x8aee 0x8aee 0x8af9 0x8af9 0x8af9 0x8b05 0x8b05 0x8b05 0x8b10 0x8b10 0x8b10 0x8b1c 0x8b1c 0x8b1c 0x8b27 0x8b27 0x8b27 0x8b33 0x8b33 0x8b33 0x8b3e 0x8b3e 0x8b3e 0x8b49 0x8b49 0x8b49 0x8b55 0x8b55 0x8b55 0x8b60 0x8b60 0x8b60 0x8b6c 0x8b6c 0x8b6c 0x8b77 0x8b77 0x8b77 0x8b83 0x8b83 0x8b83 0x8b8e 0x8b8e 0x8b8e 0x8b99 0x8b99 0x8b99 0x8ba5 0x8ba5 0x8ba5 0x8bb0 0x8bb0 0x8bb0 0x8bbc 0x8bbc 0x8bbc 0x8bc7 0x8bc7 0x8bc7 0x8bd3 0x8bd3 0x8bd3 0x8bde 0x8bde 0x8bde 0x8bea 0x8bea 0x8bea 0x8bf5 0x8bf5 0x8bf5 0x8c00 0x8c00 0x8c00 0x8c0c 0x8c0c 0x8c0c 0x8c17 0x8c17 0x8c17 0x8c23 0x8c23 0x8c23 0x8c2e 0x8c2e 0x8c2e 0x8c38 0x8c38 0x8c38 0x8c43 0x8c43 0x8c43 0x8c4d 0x8c4d 0x8c4d 0x8c58 0x8c58 0x8c58 0x8c62 0x8c62 0x8c62 0x8c6c 0x8c6c 0x8c6c 0x8c77 0x8c77 0x8c77 0x8c81 0x8c81 0x8c81 0x8c8c 0x8c8c 0x8c8c 0x8c96 0x8c96 0x8c96 0x8ca0 0x8ca0 0x8ca0 0x8cab 0x8cab 0x8cab 0x8cb5 0x8cb5 0x8cb5 0x8cc0 0x8cc0 0x8cc0 0x8cca 0x8cca 0x8cca 0x8cd4 0x8cd4 0x8cd4 0x8cdf 0x8cdf 0x8cdf 0x8ce9 0x8ce9 0x8ce9 0x8cf4 0x8cf4 0x8cf4 0x8cfe 0x8cfe 0x8cfe 0x8d09 0x8d09 0x8d09 0x8d13 0x8d13 0x8d13 0x8d1d 0x8d1d 0x8d1d 0x8d28 0x8d28 0x8d28 0x8d32 0x8d32 0x8d32 0x8d3d 0x8d3d 0x8d3d 0x8d47 0x8d47 0x8d47 0x8d51 0x8d51 0x8d51 0x8d5c 0x8d5c 0x8d5c 0x8d66 0x8d66 0x8d66 0x8d71 0x8d71 0x8d71 0x8d7b 0x8d7b 0x8d7b 0x8d85 0x8d85 0x8d85 0x8d90 0x8d90 0x8d90 0x8d9a 0x8d9a 0x8d9a 0x8da5 0x8da5 0x8da5 0x8daf 0x8daf 0x8daf 0x8db9 0x8db9 0x8db9 0x8dc4 0x8dc4 0x8dc4 0x8dce 0x8dce 0x8dce 0x8dd9 0x8dd9 0x8dd9 0x8de3 0x8de3 0x8de3 0x8ded 0x8ded 0x8ded 0x8df8 0x8df8 0x8df8 0x8e02 0x8e02 0x8e02 0x8e0d 0x8e0d 0x8e0d 0x8e17 0x8e17 0x8e17 0x8e22 0x8e22 0x8e22 0x8e2c 0x8e2c 0x8e2c 0x8e36 0x8e36 0x8e36 0x8e41 0x8e41 0x8e41 0x8e4b 0x8e4b 0x8e4b 0x8e56 0x8e56 0x8e56 0x8e60 0x8e60 0x8e60 0x8e6a 0x8e6a 0x8e6a 0x8e75 0x8e75 0x8e75 0x8e7f 0x8e7f 0x8e7f 0x8e8a 0x8e8a 0x8e8a 0x8e94 0x8e94 0x8e94 0x8e9e 0x8e9e 0x8e9e 0x8ea9 0x8ea9 0x8ea9 0x8eb3 0x8eb3 0x8eb3 0x8ebe 0x8ebe 0x8ebe 0x8ec8 0x8ec8 0x8ec8 0x8ed2 0x8ed2 0x8ed2 0x8edd 0x8edd 0x8edd 0x8ee7 0x8ee7 0x8ee7 0x8ef2 0x8ef2 0x8ef2 0x8efc 0x8efc 0x8efc 0x8f07 0x8f07 0x8f07 0x8f11 0x8f11 0x8f11 0x8f1b 0x8f1b 0x8f1b 0x8f26 0x8f26 0x8f26 0x8f30 0x8f30 0x8f30 0x8f3b 0x8f3b 0x8f3b 0x8f45 0x8f45 0x8f45 0x8f4f 0x8f4f 0x8f4f 0x8f5a 0x8f5a 0x8f5a 0x8f64 0x8f64 0x8f64 0x8f6f 0x8f6f 0x8f6f 0x8f79 0x8f79 0x8f79 0x8f83 0x8f83 0x8f83 0x8f8e 0x8f8e 0x8f8e 0x8f98 0x8f98 0x8f98 0x8fa3 0x8fa3 0x8fa3 0x8fad 0x8fad 0x8fad 0x8fb7 0x8fb7 0x8fb7 0x8fc2 0x8fc2 0x8fc2 0x8fcc 0x8fcc 0x8fcc 0x8fd7 0x8fd7 0x8fd7 0x8fe1 0x8fe1 0x8fe1 0x8feb 0x8feb 0x8feb 0x8ff6 0x8ff6 0x8ff6 0x9000 0x9000 0x9000 0x900b 0x900b 0x900b 0x9015 0x9015 0x9015 0x9020 0x9020 0x9020 0x902a 0x902a 0x902a 0x9034 0x9034 0x9034 0x903e 0x903e 0x903e 0x9048 0x9048 0x9048 0x9052 0x9052 0x9052 0x905c 0x905c 0x905c 0x9066 0x9066 0x9066 0x9070 0x9070 0x9070 0x907a 0x907a 0x907a 0x9084 0x9084 0x9084 0x908e 0x908e 0x908e 0x9098 0x9098 0x9098 0x90a2 0x90a2 0x90a2 0x90ac 0x90ac 0x90ac 0x90b6 0x90b6 0x90b6 0x90c0 0x90c0 0x90c0 0x90ca 0x90ca 0x90ca 0x90d4 0x90d4 0x90d4 0x90de 0x90de 0x90de 0x90e8 0x90e8 0x90e8 0x90f2 0x90f2 0x90f2 0x90fc 0x90fc 0x90fc 0x9106 0x9106 0x9106 0x9110 0x9110 0x9110 0x911a 0x911a 0x911a 0x9123 0x9123 0x9123 0x912d 0x912d 0x912d 0x9137 0x9137 0x9137 0x9141 0x9141 0x9141 0x914b 0x914b 0x914b 0x9155 0x9155 0x9155 0x915f 0x915f 0x915f 0x9169 0x9169 0x9169 0x9173 0x9173 0x9173 0x917d 0x917d 0x917d 0x9187 0x9187 0x9187 0x9191 0x9191 0x9191 0x919b 0x919b 0x919b 0x91a5 0x91a5 0x91a5 0x91af 0x91af 0x91af 0x91b9 0x91b9 0x91b9 0x91c3 0x91c3 0x91c3 0x91cd 0x91cd 0x91cd 0x91d7 0x91d7 0x91d7 0x91e1 0x91e1 0x91e1 0x91eb 0x91eb 0x91eb 0x91f5 0x91f5 0x91f5 0x91ff 0x91ff 0x91ff 0x9209 0x9209 0x9209 0x9213 0x9213 0x9213 0x921d 0x921d 0x921d 0x9227 0x9227 0x9227 0x9231 0x9231 0x9231 0x923b 0x923b 0x923b 0x9245 0x9245 0x9245 0x924f 0x924f 0x924f 0x9259 0x9259 0x9259 0x9263 0x9263 0x9263 0x926d 0x926d 0x926d 0x9277 0x9277 0x9277 0x9281 0x9281 0x9281 0x928b 0x928b 0x928b 0x9295 0x9295 0x9295 0x929f 0x929f 0x929f 0x92a8 0x92a8 0x92a8 0x92b2 0x92b2 0x92b2 0x92bc 0x92bc 0x92bc 0x92c6 0x92c6 0x92c6 0x92d0 0x92d0 0x92d0 0x92da 0x92da 0x92da 0x92e4 0x92e4 0x92e4 0x92ee 0x92ee 0x92ee 0x92f8 0x92f8 0x92f8 0x9302 0x9302 0x9302 0x930c 0x930c 0x930c 0x9316 0x9316 0x9316 0x9320 0x9320 0x9320 0x932a 0x932a 0x932a 0x9334 0x9334 0x9334 0x933e 0x933e 0x933e 0x9348 0x9348 0x9348 0x9352 0x9352 0x9352 0x935c 0x935c 0x935c 0x9366 0x9366 0x9366 0x9370 0x9370 0x9370 0x937a 0x937a 0x937a 0x9384 0x9384 0x9384 0x938e 0x938e 0x938e 0x9398 0x9398 0x9398 0x93a2 0x93a2 0x93a2 0x93ac 0x93ac 0x93ac 0x93b6 0x93b6 0x93b6 0x93c0 0x93c0 0x93c0 0x93ca 0x93ca 0x93ca 0x93d4 0x93d4 0x93d4 0x93de 0x93de 0x93de 0x93e8 0x93e8 0x93e8 0x93f2 0x93f2 0x93f2 0x93fc 0x93fc 0x93fc 0x9406 0x9406 0x9406 0x9410 0x9410 0x9410 0x941a 0x941a 0x941a 0x9423 0x9423 0x9423 0x942d 0x942d 0x942d 0x9437 0x9437 0x9437 0x9440 0x9440 0x9440 0x9449 0x9449 0x9449 0x9451 0x9451 0x9451 0x945a 0x945a 0x945a 0x9463 0x9463 0x9463 0x946c 0x946c 0x946c 0x9475 0x9475 0x9475 0x947e 0x947e 0x947e 0x9486 0x9486 0x9486 0x948f 0x948f 0x948f 0x9498 0x9498 0x9498 0x94a1 0x94a1 0x94a1 0x94aa 0x94aa 0x94aa 0x94b3 0x94b3 0x94b3 0x94bb 0x94bb 0x94bb 0x94c4 0x94c4 0x94c4 0x94cd 0x94cd 0x94cd 0x94d6 0x94d6 0x94d6 0x94df 0x94df 0x94df 0x94e8 0x94e8 0x94e8 0x94f0 0x94f0 0x94f0 0x94f9 0x94f9 0x94f9 0x9502 0x9502 0x9502 0x950b 0x950b 0x950b 0x9514 0x9514 0x9514 0x951d 0x951d 0x951d 0x9525 0x9525 0x9525 0x952e 0x952e 0x952e 0x9537 0x9537 0x9537 0x9540 0x9540 0x9540 0x9549 0x9549 0x9549 0x9552 0x9552 0x9552 0x955a 0x955a 0x955a 0x9563 0x9563 0x9563 0x956c 0x956c 0x956c 0x9575 0x9575 0x9575 0x957e 0x957e 0x957e 0x9587 0x9587 0x9587 0x958f 0x958f 0x958f 0x9598 0x9598 0x9598 0x95a1 0x95a1 0x95a1 0x95aa 0x95aa 0x95aa 0x95b3 0x95b3 0x95b3 0x95bc 0x95bc 0x95bc 0x95c4 0x95c4 0x95c4 0x95cd 0x95cd 0x95cd 0x95d6 0x95d6 0x95d6 0x95df 0x95df 0x95df 0x95e8 0x95e8 0x95e8 0x95f1 0x95f1 0x95f1 0x95f9 0x95f9 0x95f9 0x9602 0x9602 0x9602 0x960b 0x960b 0x960b 0x9614 0x9614 0x9614 0x961d 0x961d 0x961d 0x9626 0x9626 0x9626 0x962e 0x962e 0x962e 0x9637 0x9637 0x9637 0x9640 0x9640 0x9640 0x9649 0x9649 0x9649 0x9652 0x9652 0x9652 0x965b 0x965b 0x965b 0x9663 0x9663 0x9663 0x966c 0x966c 0x966c 0x9675 0x9675 0x9675 0x967e 0x967e 0x967e 0x9687 0x9687 0x9687 0x9690 0x9690 0x9690 0x9698 0x9698 0x9698 0x96a1 0x96a1 0x96a1 0x96aa 0x96aa 0x96aa 0x96b3 0x96b3 0x96b3 0x96bc 0x96bc 0x96bc 0x96c5 0x96c5 0x96c5 0x96cd 0x96cd 0x96cd 0x96d6 0x96d6 0x96d6 0x96df 0x96df 0x96df 0x96e8 0x96e8 0x96e8 0x96f1 0x96f1 0x96f1 0x96f9 0x96f9 0x96f9 0x9702 0x9702 0x9702 0x970b 0x970b 0x970b 0x9714 0x9714 0x9714 0x971d 0x971d 0x971d 0x9726 0x9726 0x9726 0x972e 0x972e 0x972e 0x9737 0x9737 0x9737 0x9740 0x9740 0x9740 0x9749 0x9749 0x9749 0x9752 0x9752 0x9752 0x975b 0x975b 0x975b 0x9763 0x9763 0x9763 0x976c 0x976c 0x976c 0x9775 0x9775 0x9775 0x977e 0x977e 0x977e 0x9787 0x9787 0x9787 0x9790 0x9790 0x9790 0x9798 0x9798 0x9798 0x97a1 0x97a1 0x97a1 0x97aa 0x97aa 0x97aa 0x97b3 0x97b3 0x97b3 0x97bc 0x97bc 0x97bc 0x97c5 0x97c5 0x97c5 0x97cd 0x97cd 0x97cd 0x97d6 0x97d6 0x97d6 0x97df 0x97df 0x97df 0x97e8 0x97e8 0x97e8 0x97f1 0x97f1 0x97f1 0x97fa 0x97fa 0x97fa 0x9802 0x9802 0x9802 0x980b 0x980b 0x980b 0x9814 0x9814 0x9814 0x981d 0x981d 0x981d 0x9826 0x9826 0x9826 0x982f 0x982f 0x982f 0x9837 0x9837 0x9837 0x983f 0x983f 0x983f 0x9847 0x9847 0x9847 0x984f 0x984f 0x984f 0x9857 0x9857 0x9857 0x985f 0x985f 0x985f 0x9867 0x9867 0x9867 0x986e 0x986e 0x986e 0x9876 0x9876 0x9876 0x987e 0x987e 0x987e 0x9886 0x9886 0x9886 0x988e 0x988e 0x988e 0x9896 0x9896 0x9896 0x989e 0x989e 0x989e 0x98a5 0x98a5 0x98a5 0x98ad 0x98ad 0x98ad 0x98b5 0x98b5 0x98b5 0x98bd 0x98bd 0x98bd 0x98c5 0x98c5 0x98c5 0x98cd 0x98cd 0x98cd 0x98d5 0x98d5 0x98d5 0x98dc 0x98dc 0x98dc 0x98e4 0x98e4 0x98e4 0x98ec 0x98ec 0x98ec 0x98f4 0x98f4 0x98f4 0x98fc 0x98fc 0x98fc 0x9904 0x9904 0x9904 0x990c 0x990c 0x990c 0x9913 0x9913 0x9913 0x991b 0x991b 0x991b 0x9923 0x9923 0x9923 0x992b 0x992b 0x992b 0x9933 0x9933 0x9933 0x993b 0x993b 0x993b 0x9943 0x9943 0x9943 0x994a 0x994a 0x994a 0x9952 0x9952 0x9952 0x995a 0x995a 0x995a 0x9962 0x9962 0x9962 0x996a 0x996a 0x996a 0x9972 0x9972 0x9972 0x997a 0x997a 0x997a 0x9981 0x9981 0x9981 0x9989 0x9989 0x9989 0x9991 0x9991 0x9991 0x9999 0x9999 0x9999 0x99a1 0x99a1 0x99a1 0x99a9 0x99a9 0x99a9 0x99b1 0x99b1 0x99b1 0x99b8 0x99b8 0x99b8 0x99c0 0x99c0 0x99c0 0x99c8 0x99c8 0x99c8 0x99d0 0x99d0 0x99d0 0x99d8 0x99d8 0x99d8 0x99e0 0x99e0 0x99e0 0x99e8 0x99e8 0x99e8 0x99ef 0x99ef 0x99ef 0x99f7 0x99f7 0x99f7 0x99ff 0x99ff 0x99ff 0x9a07 0x9a07 0x9a07 0x9a0f 0x9a0f 0x9a0f 0x9a17 0x9a17 0x9a17 0x9a1f 0x9a1f 0x9a1f 0x9a26 0x9a26 0x9a26 0x9a2e 0x9a2e 0x9a2e 0x9a36 0x9a36 0x9a36 0x9a3e 0x9a3e 0x9a3e 0x9a46 0x9a46 0x9a46 0x9a4e 0x9a4e 0x9a4e 0x9a56 0x9a56 0x9a56 0x9a5d 0x9a5d 0x9a5d 0x9a65 0x9a65 0x9a65 0x9a6d 0x9a6d 0x9a6d 0x9a75 0x9a75 0x9a75 0x9a7d 0x9a7d 0x9a7d 0x9a85 0x9a85 0x9a85 0x9a8d 0x9a8d 0x9a8d 0x9a94 0x9a94 0x9a94 0x9a9c 0x9a9c 0x9a9c 0x9aa4 0x9aa4 0x9aa4 0x9aac 0x9aac 0x9aac 0x9ab4 0x9ab4 0x9ab4 0x9abc 0x9abc 0x9abc 0x9ac4 0x9ac4 0x9ac4 0x9acb 0x9acb 0x9acb 0x9ad3 0x9ad3 0x9ad3 0x9adb 0x9adb 0x9adb 0x9ae3 0x9ae3 0x9ae3 0x9aeb 0x9aeb 0x9aeb 0x9af3 0x9af3 0x9af3 0x9afb 0x9afb 0x9afb 0x9b02 0x9b02 0x9b02 0x9b0a 0x9b0a 0x9b0a 0x9b12 0x9b12 0x9b12 0x9b1a 0x9b1a 0x9b1a 0x9b22 0x9b22 0x9b22 0x9b2a 0x9b2a 0x9b2a 0x9b32 0x9b32 0x9b32 0x9b39 0x9b39 0x9b39 0x9b41 0x9b41 0x9b41 0x9b49 0x9b49 0x9b49 0x9b51 0x9b51 0x9b51 0x9b59 0x9b59 0x9b59 0x9b61 0x9b61 0x9b61 0x9b69 0x9b69 0x9b69 0x9b70 0x9b70 0x9b70 0x9b78 0x9b78 0x9b78 0x9b80 0x9b80 0x9b80 0x9b88 0x9b88 0x9b88 0x9b90 0x9b90 0x9b90 0x9b98 0x9b98 0x9b98 0x9ba0 0x9ba0 0x9ba0 0x9ba7 0x9ba7 0x9ba7 0x9baf 0x9baf 0x9baf 0x9bb7 0x9bb7 0x9bb7 0x9bbf 0x9bbf 0x9bbf 0x9bc7 0x9bc7 0x9bc7 0x9bcf 0x9bcf 0x9bcf 0x9bd7 0x9bd7 0x9bd7 0x9bde 0x9bde 0x9bde 0x9be6 0x9be6 0x9be6 0x9bee 0x9bee 0x9bee 0x9bf6 0x9bf6 0x9bf6 0x9bfe 0x9bfe 0x9bfe 0x9c06 0x9c06 0x9c06 0x9c0e 0x9c0e 0x9c0e 0x9c15 0x9c15 0x9c15 0x9c1d 0x9c1d 0x9c1d 0x9c25 0x9c25 0x9c25 0x9c2d 0x9c2d 0x9c2d 0x9c35 0x9c35 0x9c35 0x9c3d 0x9c3d 0x9c3d 0x9c44 0x9c44 0x9c44 0x9c4b 0x9c4b 0x9c4b 0x9c53 0x9c53 0x9c53 0x9c5a 0x9c5a 0x9c5a 0x9c61 0x9c61 0x9c61 0x9c69 0x9c69 0x9c69 0x9c70 0x9c70 0x9c70 0x9c77 0x9c77 0x9c77 0x9c7f 0x9c7f 0x9c7f 0x9c86 0x9c86 0x9c86 0x9c8d 0x9c8d 0x9c8d 0x9c95 0x9c95 0x9c95 0x9c9c 0x9c9c 0x9c9c 0x9ca3 0x9ca3 0x9ca3 0x9cab 0x9cab 0x9cab 0x9cb2 0x9cb2 0x9cb2 0x9cb9 0x9cb9 0x9cb9 0x9cc1 0x9cc1 0x9cc1 0x9cc8 0x9cc8 0x9cc8 0x9ccf 0x9ccf 0x9ccf 0x9cd7 0x9cd7 0x9cd7 0x9cde 0x9cde 0x9cde 0x9ce5 0x9ce5 0x9ce5 0x9ced 0x9ced 0x9ced 0x9cf4 0x9cf4 0x9cf4 0x9cfb 0x9cfb 0x9cfb 0x9d03 0x9d03 0x9d03 0x9d0a 0x9d0a 0x9d0a 0x9d12 0x9d12 0x9d12 0x9d19 0x9d19 0x9d19 0x9d20 0x9d20 0x9d20 0x9d28 0x9d28 0x9d28 0x9d2f 0x9d2f 0x9d2f 0x9d36 0x9d36 0x9d36 0x9d3e 0x9d3e 0x9d3e 0x9d45 0x9d45 0x9d45 0x9d4c 0x9d4c 0x9d4c 0x9d54 0x9d54 0x9d54 0x9d5b 0x9d5b 0x9d5b 0x9d62 0x9d62 0x9d62 0x9d6a 0x9d6a 0x9d6a 0x9d71 0x9d71 0x9d71 0x9d78 0x9d78 0x9d78 0x9d80 0x9d80 0x9d80 0x9d87 0x9d87 0x9d87 0x9d8e 0x9d8e 0x9d8e 0x9d96 0x9d96 0x9d96 0x9d9d 0x9d9d 0x9d9d 0x9da4 0x9da4 0x9da4 0x9dac 0x9dac 0x9dac 0x9db3 0x9db3 0x9db3 0x9dba 0x9dba 0x9dba 0x9dc2 0x9dc2 0x9dc2 0x9dc9 0x9dc9 0x9dc9 0x9dd0 0x9dd0 0x9dd0 0x9dd8 0x9dd8 0x9dd8 0x9ddf 0x9ddf 0x9ddf 0x9de6 0x9de6 0x9de6 0x9dee 0x9dee 0x9dee 0x9df5 0x9df5 0x9df5 0x9dfc 0x9dfc 0x9dfc 0x9e04 0x9e04 0x9e04 0x9e0b 0x9e0b 0x9e0b 0x9e13 0x9e13 0x9e13 0x9e1a 0x9e1a 0x9e1a 0x9e21 0x9e21 0x9e21 0x9e29 0x9e29 0x9e29 0x9e30 0x9e30 0x9e30 0x9e37 0x9e37 0x9e37 0x9e3f 0x9e3f 0x9e3f 0x9e46 0x9e46 0x9e46 0x9e4d 0x9e4d 0x9e4d 0x9e55 0x9e55 0x9e55 0x9e5c 0x9e5c 0x9e5c 0x9e63 0x9e63 0x9e63 0x9e6b 0x9e6b 0x9e6b 0x9e72 0x9e72 0x9e72 0x9e79 0x9e79 0x9e79 0x9e81 0x9e81 0x9e81 0x9e88 0x9e88 0x9e88 0x9e8f 0x9e8f 0x9e8f 0x9e97 0x9e97 0x9e97 0x9e9e 0x9e9e 0x9e9e 0x9ea5 0x9ea5 0x9ea5 0x9ead 0x9ead 0x9ead 0x9eb4 0x9eb4 0x9eb4 0x9ebb 0x9ebb 0x9ebb 0x9ec3 0x9ec3 0x9ec3 0x9eca 0x9eca 0x9eca 0x9ed1 0x9ed1 0x9ed1 0x9ed9 0x9ed9 0x9ed9 0x9ee0 0x9ee0 0x9ee0 0x9ee7 0x9ee7 0x9ee7 0x9eef 0x9eef 0x9eef 0x9ef6 0x9ef6 0x9ef6 0x9efd 0x9efd 0x9efd 0x9f05 0x9f05 0x9f05 0x9f0c 0x9f0c 0x9f0c 0x9f14 0x9f14 0x9f14 0x9f1b 0x9f1b 0x9f1b 0x9f22 0x9f22 0x9f22 0x9f2a 0x9f2a 0x9f2a 0x9f31 0x9f31 0x9f31 0x9f38 0x9f38 0x9f38 0x9f40 0x9f40 0x9f40 0x9f47 0x9f47 0x9f47 0x9f4e 0x9f4e 0x9f4e 0x9f56 0x9f56 0x9f56 0x9f5d 0x9f5d 0x9f5d 0x9f64 0x9f64 0x9f64 0x9f6c 0x9f6c 0x9f6c 0x9f73 0x9f73 0x9f73 0x9f7a 0x9f7a 0x9f7a 0x9f82 0x9f82 0x9f82 0x9f89 0x9f89 0x9f89 0x9f90 0x9f90 0x9f90 0x9f98 0x9f98 0x9f98 0x9f9f 0x9f9f 0x9f9f 0x9fa6 0x9fa6 0x9fa6 0x9fae 0x9fae 0x9fae 0x9fb5 0x9fb5 0x9fb5 0x9fbc 0x9fbc 0x9fbc 0x9fc4 0x9fc4 0x9fc4 0x9fcb 0x9fcb 0x9fcb 0x9fd2 0x9fd2 0x9fd2 0x9fda 0x9fda 0x9fda 0x9fe1 0x9fe1 0x9fe1 0x9fe8 0x9fe8 0x9fe8 0x9ff0 0x9ff0 0x9ff0 0x9ff7 0x9ff7 0x9ff7 0x9fff 0x9fff 0x9fff>; + }; + }; + + panel-s-wqxga-10-1 { + status = "disabled"; + compatible = "s,wqxga-10-1"; + nvidia,dsi-instance = <0x0>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-refresh-rate = <0x3d>; + nvidia,dsi-rated-refresh-rate = <0x3c>; + nvidia,dsi-te-polarity-low = <0x1>; + nvidia,dsi-video-data-type = <0x1>; + nvidia,dsi-video-clock-mode = <0x1>; + nvidia,dsi-ganged-type = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-controller-vs = <0x1>; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-panel-reset = <0x1>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,dsi-lp00-pre-panel-wakeup = <0x1>; + nvidia,dsi-suspend-aggr = <0x3>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-init-cmd = <0x0 0x29 0x3 0x0 0x0 0x10 0x0 0x2a 0x0 0x0 0x1 0x14 0x0 0x5 0x0 0x0 0x0 0x1 0x14 0x0 0x29 0x3 0x0 0x0 0x10 0x1 0x1 0x0 0x0 0x1 0x14 0x0 0x5 0x0 0x0 0x0 0x1 0x14 0x0 0x5 0x35 0x0 0x0 0x1 0x14 0x0 0x5 0x11 0x0 0x0 0x1 0x78 0x0 0x5 0x29 0x0 0x0 0x1 0x14 0x3 0x1 0x1 0x78>; + nvidia,dsi-n-init-cmd = <0x10>; + nvidia,dsi-suspend-cmd = <0x0 0x5 0x28 0x0 0x0 0x1 0x32 0x0 0x5 0x10 0x0 0x0 0x1 0xc8 0x0 0x5 0x34 0x0 0x0 0x1 0x14>; + nvidia,dsi-n-suspend-cmd = <0x6>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + nvidia,panel-bl-pwm-gpio = <0x28 0x8 0x1>; + linux,phandle = <0x11e>; + phandle = <0x11e>; + + disp-default-out { + nvidia,out-type = <0x2>; + nvidia,out-width = <0xd8>; + nvidia,out-height = <0x87>; + nvidia,out-flags = <0x20>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-xres = <0xa00>; + nvidia,out-yres = <0x640>; + nvidia,out-rotation = <0xb4>; + }; + + display-timings { + + 2560x1600-32 { + clock-frequency = <0x118a1cc0>; + hactive = <0xa00>; + vactive = <0x640>; + hfront-porch = <0x148>; + hback-porch = <0x50>; + hsync-len = <0x20>; + vfront-porch = <0x2>; + vback-porch = <0x5>; + vsync-len = <0x1>; + nvidia,h-ref-to-sync = <0x0>; + nvidia,v-ref-to-sync = <0x1>; + }; + }; + + smartdimmer { + status = "disabled"; + nvidia,use-auto-pwm = <0x0>; + nvidia,hw-update-delay = <0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,k-limit-enable = <0x1>; + nvidia,k-limit = <0xc8>; + nvidia,sd-window-enable = <0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,smooth-k-enable = <0x1>; + nvidia,smooth-k-incr = <0x4>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,fc = <0x0 0x0>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,turn-off-brightness = <0x0>; + nvidia,turn-on-brightness = <0xff>; + nvidia,sw-update-delay = <0x0>; + }; + + cmu { + nvidia,cmu-csc = <0x105 0x3d5 0x24 0x3ea 0x121 0x3c1 0x2 0xa 0xf4>; + nvidia,cmu-lut2 = <0x0 0x1 0x2 0x2 0x3 0x4 0x5 0x6 0x6 0x7 0x8 0x9 0xa 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0xf 0x10 0x10 0x11 0x12 0x12 0x13 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x17 0x18 0x18 0x19 0x19 0x19 0x1a 0x1a 0x1b 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1d 0x1e 0x1e 0x1e 0x1f 0x1f 0x1f 0x20 0x20 0x20 0x21 0x21 0x21 0x22 0x22 0x22 0x22 0x23 0x23 0x23 0x24 0x24 0x24 0x25 0x25 0x25 0x25 0x26 0x26 0x26 0x26 0x27 0x27 0x27 0x28 0x28 0x28 0x28 0x29 0x29 0x29 0x29 0x2a 0x2a 0x2a 0x2a 0x2b 0x2b 0x2b 0x2b 0x2b 0x2c 0x2c 0x2c 0x2c 0x2d 0x2d 0x2d 0x2d 0x2e 0x2e 0x2e 0x2e 0x2e 0x2f 0x2f 0x2f 0x2f 0x30 0x30 0x30 0x30 0x30 0x31 0x31 0x31 0x31 0x31 0x32 0x32 0x32 0x32 0x32 0x33 0x33 0x33 0x33 0x33 0x34 0x34 0x34 0x34 0x34 0x35 0x35 0x35 0x35 0x35 0x36 0x36 0x36 0x36 0x36 0x37 0x37 0x37 0x37 0x37 0x37 0x38 0x38 0x38 0x38 0x38 0x39 0x39 0x39 0x39 0x39 0x39 0x3a 0x3a 0x3a 0x3a 0x3a 0x3a 0x3b 0x3b 0x3b 0x3b 0x3b 0x3b 0x3c 0x3c 0x3c 0x3c 0x3c 0x3c 0x3d 0x3d 0x3d 0x3d 0x3d 0x3d 0x3e 0x3e 0x3e 0x3e 0x3e 0x3e 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x40 0x40 0x40 0x40 0x40 0x40 0x40 0x41 0x41 0x41 0x41 0x41 0x41 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x44 0x44 0x44 0x44 0x44 0x44 0x44 0x45 0x45 0x45 0x45 0x45 0x45 0x45 0x46 0x46 0x46 0x46 0x46 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x49 0x49 0x49 0x49 0x49 0x49 0x49 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x63 0x63 0x63 0x63 0x63 0x63 0x63 0x64 0x65 0x65 0x66 0x67 0x67 0x68 0x69 0x69 0x6a 0x6b 0x6b 0x6c 0x6d 0x6d 0x6e 0x6f 0x6f 0x70 0x71 0x71 0x72 0x73 0x73 0x74 0x74 0x75 0x76 0x76 0x77 0x77 0x78 0x78 0x79 0x7a 0x7a 0x7b 0x7b 0x7c 0x7c 0x7d 0x7e 0x7e 0x7f 0x7f 0x80 0x80 0x81 0x81 0x82 0x82 0x83 0x83 0x84 0x84 0x85 0x85 0x86 0x86 0x87 0x87 0x88 0x88 0x89 0x89 0x8a 0x8a 0x8b 0x8b 0x8c 0x8c 0x8d 0x8d 0x8e 0x8e 0x8f 0x8f 0x90 0x90 0x91 0x91 0x91 0x92 0x92 0x93 0x93 0x94 0x94 0x95 0x95 0x96 0x96 0x96 0x97 0x97 0x98 0x98 0x99 0x99 0x99 0x9a 0x9a 0x9b 0x9b 0x9c 0x9c 0x9c 0x9d 0x9d 0x9e 0x9e 0x9e 0x9f 0x9f 0xa0 0xa0 0xa0 0xa1 0xa1 0xa2 0xa2 0xa2 0xa3 0xa3 0xa4 0xa4 0xa4 0xa5 0xa5 0xa6 0xa6 0xa6 0xa7 0xa7 0xa7 0xa8 0xa8 0xa9 0xa9 0xa9 0xaa 0xaa 0xaa 0xab 0xab 0xac 0xac 0xac 0xad 0xad 0xad 0xae 0xae 0xae 0xaf 0xaf 0xb0 0xb0 0xb0 0xb1 0xb1 0xb1 0xb2 0xb2 0xb2 0xb3 0xb3 0xb3 0xb4 0xb4 0xb4 0xb5 0xb5 0xb6 0xb6 0xb6 0xb7 0xb7 0xb7 0xb8 0xb8 0xb8 0xb9 0xb9 0xb9 0xba 0xba 0xba 0xbb 0xbb 0xbb 0xbc 0xbc 0xbc 0xbd 0xbd 0xbd 0xbd 0xbe 0xbe 0xbe 0xbf 0xbf 0xbf 0xc0 0xc0 0xc0 0xc1 0xc1 0xc1 0xc2 0xc2 0xc2 0xc3 0xc3 0xc3 0xc4 0xc4 0xc4 0xc4 0xc5 0xc5 0xc5 0xc6 0xc6 0xc6 0xc7 0xc7 0xc7 0xc8 0xc8 0xc8 0xc8 0xc9 0xc9 0xc9 0xca 0xca 0xca 0xca 0xcb 0xcb 0xcb 0xcc 0xcc 0xcc 0xcd 0xcd 0xcd 0xcd 0xce 0xce 0xce 0xcf 0xcf 0xcf 0xcf 0xd0 0xd0 0xd0 0xd1 0xd1 0xd1 0xd1 0xd2 0xd2 0xd2 0xd3 0xd3 0xd3 0xd3 0xd4 0xd4 0xd4 0xd5 0xd5 0xd5 0xd5 0xd6 0xd6 0xd6 0xd6 0xd7 0xd7 0xd7 0xd8 0xd8 0xd8 0xd8 0xd9 0xd9 0xd9 0xd9 0xda 0xda 0xda 0xdb 0xdb 0xdb 0xdb 0xdc 0xdc 0xdc 0xdc 0xdd 0xdd 0xdd 0xdd 0xde 0xde 0xde 0xdf 0xdf 0xdf 0xdf 0xe0 0xe0 0xe0 0xe0 0xe1 0xe1 0xe1 0xe1 0xe2 0xe2 0xe2 0xe2 0xe3 0xe3 0xe3 0xe3 0xe4 0xe4 0xe4 0xe4 0xe5 0xe5 0xe5 0xe5 0xe6 0xe6 0xe6 0xe6 0xe7 0xe7 0xe7 0xe7 0xe8 0xe8 0xe8 0xe8 0xe9 0xe9 0xe9 0xe9 0xea 0xea 0xea 0xea 0xeb 0xeb 0xeb 0xeb 0xec 0xec 0xec 0xec 0xed 0xed 0xed 0xed 0xee 0xee 0xee 0xee 0xef 0xef 0xef 0xef 0xf0 0xf0 0xf0 0xf0 0xf0 0xf1 0xf1 0xf1 0xf1 0xf2 0xf2 0xf2 0xf2 0xf3 0xf3 0xf3 0xf3 0xf4 0xf4 0xf4 0xf4 0xf4 0xf5 0xf5 0xf5 0xf5 0xf6 0xf6 0xf6 0xf6 0xf7 0xf7 0xf7 0xf7 0xf7 0xf8 0xf8 0xf8 0xf8 0xf9 0xf9 0xf9 0xf9 0xf9 0xfa 0xfa 0xfa 0xfa 0xfb 0xfb 0xfb 0xfb 0xfb 0xfc 0xfc 0xfc 0xfc 0xfd 0xfd 0xfd 0xfd 0xfd 0xfe 0xfe 0xfe 0xfe 0xff 0xff>; + }; + }; + }; + + vic@15340000 { + compatible = "nvidia,tegra186-vic"; + power-domains = <0x1f 0xc>; + reg = <0x0 0x15340000 0x0 0x40000>; + resets = <0x10 0x34>; + clocks = <0x10 0x7f>; + clock-names = "vic"; + iommus = <0x11 0x3>; + iommu-group-id = <0x1>; + status = "okay"; + interrupts = <0x0 0xce 0x4>; + }; + + nvenc@154c0000 { + compatible = "nvidia,tegra186-nvenc"; + power-domains = <0x1f 0x8>; + reg = <0x0 0x154c0000 0x0 0x40000>; + resets = <0x10 0x7e>; + clocks = <0x10 0x83>; + clock-names = "nvenc"; + iommus = <0x11 0x7>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + nvdec@15480000 { + compatible = "nvidia,tegra186-nvdec"; + power-domains = <0x1f 0x6>; + reg = <0x0 0x15480000 0x0 0x40000>; + resets = <0x10 0x7d>; + clocks = <0x10 0x81 0x10 0x125>; + clock-names = "nvdec", "kfuse"; + iommus = <0x11 0x6>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + nvjpg@15380000 { + compatible = "nvidia,tegra186-nvjpg"; + power-domains = <0x1f 0x7>; + reg = <0x0 0x15380000 0x0 0x40000>; + resets = <0x10 0x7f>; + clocks = <0x10 0x82>; + clock-names = "nvjpg"; + iommus = <0x11 0x8>; + iommu-group-id = <0x1>; + status = "okay"; + interrupts = <0x0 0xc6 0x4>; + }; + + tsec@15500000 { + compatible = "nvidia,tegra186-tsec"; + reg = <0x0 0x15500000 0x0 0x40000>; + resets = <0x10 0x2e>; + clocks = <0x10 0x51>; + clock-names = "tsec"; + iommus = <0x11 0xa>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + tsecb@15100000 { + compatible = "nvidia,tegra186-tsec"; + reg = <0x0 0x15100000 0x0 0x40000>; + resets = <0x10 0x82>; + clocks = <0x10 0x89>; + clock-names = "tsecb"; + iommus = <0x11 0xb>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + sor { + compatible = "nvidia,tegra186-sor"; + reg = <0x0 0x15540000 0x0 0x40000>; + nvidia,sor-ctrlnum = <0x0>; + nvidia,dpaux = <0x8e>; + nvidia,xbar-ctrl = <0x0 0x1 0x2 0x3 0x4>; + clocks = <0x10 0x61 0x10 0x27 0x10 0x267 0x10 0x128 0x10 0x20b 0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + clock-names = "sor0_ref", "sor_safe", "sor0_pad_clkout", "sor0", "pll_dp", "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + resets = <0x10 0x27 0x10 0xf 0x10 0x10 0x10 0x11>; + reset-names = "sor0", "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + status = "disabled"; + nvidia,ddc-i2c-bus = <0x8f>; + nvidia,active-panel = <0x90>; + nvidia,hpd-gpio = <0x1b 0x78 0x1>; + linux,phandle = <0x8c>; + phandle = <0x8c>; + + hdmi-display { + compatible = "hdmi,display"; + status = "disabled"; + generic-infoframe-type = <0x87>; + linux,phandle = <0x1c9>; + phandle = <0x1c9>; + + disp-default-out { + nvidia,out-type = <0x1>; + nvidia,out-flags = <0x2>; + nvidia,out-parent-clk = "plld3"; + nvidia,out-align = <0x0>; + nvidia,out-order = <0x0>; + nvidia,out-xres = <0x1000>; + nvidia,out-yres = <0x870>; + }; + }; + + dp-display { + compatible = "dp, display"; + status = "disabled"; + nvidia,is_ext_dp_panel = <0x1>; + linux,phandle = <0x90>; + phandle = <0x90>; + + disp-default-out { + nvidia,out-type = <0x3>; + nvidia,out-align = <0x0>; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-parent-clk = "plld3"; + nvidia,out-xres = <0x1000>; + nvidia,out-yres = <0x870>; + }; + + lt-data { + + tegra-dp-vs-regs { + pc2_l0 = <0x13 0x19 0x1e 0x28 0x1e 0x25 0x2d 0x28 0x32 0x39>; + pc2_l1 = <0x12 0x17 0x1b 0x25 0x1c 0x23 0x2a 0x25 0x2f 0x37>; + pc2_l2 = <0x12 0x16 0x1a 0x22 0x1b 0x20 0x27 0x24 0x2d 0x35>; + pc2_l3 = <0x11 0x14 0x17 0x1f 0x19 0x1e 0x24 0x22 0x2a 0x32>; + }; + + tegra-dp-pe-regs { + pc2_l0 = <0x0 0x8 0x12 0x24 0x1 0xe 0x1d 0x1 0x13 0x0>; + pc2_l1 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l2 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l3 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + }; + + tegra-dp-pc-regs { + pc2_l0 = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + pc2_l1 = <0x2 0x2 0x4 0x5 0x2 0x4 0x5 0x4 0x5 0x5>; + pc2_l2 = <0x4 0x5 0x8 0xb 0x5 0x9 0xb 0x8 0xa 0xb>; + pc2_l3 = <0x5 0x9 0xb 0x12 0x9 0xd 0x12 0xb 0xf 0x12>; + }; + + tegra-dp-tx-pu { + pc2_l0 = <0x22 0x33 0x44 0x66 0x33 0x44 0x66 0x44 0x66 0x66>; + pc2_l1 = <0x22 0x22 0x33 0x55 0x33 0x44 0x55 0x44 0x55 0x66>; + pc2_l2 = <0x22 0x22 0x33 0x44 0x33 0x33 0x44 0x44 0x55 0x66>; + pc2_l3 = <0x22 0x22 0x22 0x44 0x33 0x33 0x44 0x44 0x44 0x66>; + }; + }; + + dp-lt-settings { + + lt-setting@0 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x3>; + }; + + lt-setting@1 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x4>; + }; + + lt-setting@2 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x6>; + }; + }; + }; + + prod-settings { + #prod-cells = <0x3>; + prod_list_hdmi_soc = "prod_c_hdmi_0m_54m", "prod_c_hdmi_54m_111m", "prod_c_hdmi_111m_223m", "prod_c_hdmi_223m_300m", "prod_c_hdmi_300m_600m"; + + prod_c_hdmi_0m_54m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hdmi_54m_111m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_hdmi_111m_223m { + prod = <0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_223m_300m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_300m_600m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_54M { + prod = <0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_75M { + prod = <0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_150M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_300M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_600M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_dp { + prod = <0x58c 0xf0f0f10 0x5050310 0x590 0x3000100 0x100 0x594 0xf0000000 0x0 0x598 0x2ff0 0x2440 0x59c 0x401800 0x0 0x5a0 0x400000 0x400000 0x5a8 0xff000000 0x34000000 0x70 0xffffffff 0x0 0x180 0x1 0x1>; + }; + + prod_c_hbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_hbr2 { + prod = <0x590 0xf00000 0x400000>; + }; + + prod_c_rbr { + prod = <0x590 0xf00000 0x300000>; + }; + }; + + panel-s-edp-uhdtv-15-6 { + status = "disabled"; + compatible = "s-edp,uhdtv-15-6"; + nvidia,tx-pu-disable = <0x1>; + nvidia,panel-bl-pwm-gpio = <0x28 0xd 0x0>; + linux,phandle = <0x11f>; + phandle = <0x11f>; + + disp-default-out { + nvidia,out-type = <0x3>; + nvidia,out-align = <0x0>; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-depth = <0x18>; + nvidia,out-parent-clk = "pll_d_out0"; + nvidia,out-width = <0x15a>; + nvidia,out-height = <0xc2>; + nvidia,out-xres = <0xf00>; + nvidia,out-yres = <0x870>; + }; + + display-timings { + + 3840x2160-32 { + clock-frequency = <0x1f1e7610>; + hactive = <0xf00>; + vactive = <0x870>; + hfront-porch = <0x30>; + hback-porch = <0x50>; + hsync-len = <0x20>; + vfront-porch = <0x3>; + vback-porch = <0x36>; + vsync-len = <0x5>; + nvidia,h-ref-to-sync = <0x1>; + nvidia,v-ref-to-sync = <0x1>; + }; + }; + + dp-lt-settings { + + lt-setting@0 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x3>; + }; + + lt-setting@1 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x4>; + }; + + lt-setting@2 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x6>; + }; + }; + + smartdimmer { + status = "disabled"; + nvidia,use-auto-pwm = <0x0>; + nvidia,hw-update-delay = <0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,k-limit-enable = <0x1>; + nvidia,k-limit = <0xc8>; + nvidia,sd-window-enable = <0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,smooth-k-enable = <0x0>; + nvidia,smooth-k-incr = <0x40>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,fc = <0x0 0x0>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,bl-device-name = "pwm-backlight"; + }; + }; + + panel-a-edp-1080p-14-0 { + status = "disabled"; + compatible = "a-edp,1080p-14-0"; + nvidia,tx-pu-disable = <0x1>; + linux,phandle = <0x1ca>; + phandle = <0x1ca>; + + disp-default-out { + nvidia,out-type = <0x3>; + nvidia,out-align = <0x0>; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-depth = <0x12>; + nvidia,out-parent-clk = "pll_d_out0"; + }; + + dp-lt-settings { + + lt-setting@0 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x3>; + }; + + lt-setting@1 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x4>; + }; + + lt-setting@2 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x6>; + }; + }; + + smartdimmer { + status = "okay"; + nvidia,use-auto-pwm = <0x0>; + nvidia,hw-update-delay = <0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,k-limit-enable = <0x1>; + nvidia,k-limit = <0xc8>; + nvidia,sd-window-enable = <0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,smooth-k-enable = <0x0>; + nvidia,smooth-k-incr = <0x40>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,fc = <0x0 0x0>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,bl-device-name = "pwm-backlight"; + }; + }; + }; + + sor1 { + compatible = "nvidia,tegra186-sor1"; + reg = <0x0 0x15580000 0x0 0x40000>; + interrupts = <0x0 0x9e 0x4>; + nvidia,sor-ctrlnum = <0x1>; + nvidia,dpaux = <0x91>; + nvidia,xbar-ctrl = <0x0 0x1 0x2 0x3 0x4>; + clocks = <0x10 0x5d 0x10 0x27 0x10 0x268 0x10 0x129 0x10 0x20b 0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + clock-names = "sor1_ref", "sor_safe", "sor1_pad_clkout", "sor1", "pll_dp", "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + resets = <0x10 0x6c 0x10 0xf 0x10 0x10 0x10 0x11>; + reset-names = "sor1", "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + status = "okay"; + nvidia,ddc-i2c-bus = <0x92>; + nvidia,active-panel = <0x93>; + nvidia,hpd-gpio = <0x1b 0x79 0x1>; + linux,phandle = <0x8b>; + phandle = <0x8b>; + + hdmi-display { + compatible = "hdmi,display"; + status = "okay"; + generic-infoframe-type = <0x87>; + linux,phandle = <0x93>; + phandle = <0x93>; + + disp-default-out { + nvidia,out-type = <0x1>; + nvidia,out-flags = <0x2>; + nvidia,out-parent-clk = "plld2"; + nvidia,out-align = <0x0>; + nvidia,out-order = <0x0>; + nvidia,out-xres = <0x1000>; + nvidia,out-yres = <0x870>; + }; + }; + + dp-display { + compatible = "dp, display"; + status = "disabled"; + nvidia,is_ext_dp_panel = <0x1>; + linux,phandle = <0x1cb>; + phandle = <0x1cb>; + + disp-default-out { + nvidia,out-type = <0x3>; + nvidia,out-align = <0x0>; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-parent-clk = "plld2"; + nvidia,out-xres = <0x1000>; + nvidia,out-yres = <0x870>; + }; + + lt-data { + + tegra-dp-vs-regs { + pc2_l0 = <0x13 0x19 0x1e 0x28 0x1e 0x25 0x2d 0x28 0x32 0x39>; + pc2_l1 = <0x12 0x17 0x1b 0x25 0x1c 0x23 0x2a 0x25 0x2f 0x37>; + pc2_l2 = <0x12 0x16 0x1a 0x22 0x1b 0x20 0x27 0x24 0x2d 0x35>; + pc2_l3 = <0x11 0x14 0x17 0x1f 0x19 0x1e 0x24 0x22 0x2a 0x32>; + }; + + tegra-dp-pe-regs { + pc2_l0 = <0x0 0x8 0x12 0x24 0x1 0xe 0x1d 0x1 0x13 0x0>; + pc2_l1 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l2 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l3 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + }; + + tegra-dp-pc-regs { + pc2_l0 = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + pc2_l1 = <0x2 0x2 0x4 0x5 0x2 0x4 0x5 0x4 0x5 0x5>; + pc2_l2 = <0x4 0x5 0x8 0xb 0x5 0x9 0xb 0x8 0xa 0xb>; + pc2_l3 = <0x5 0x9 0xb 0x12 0x9 0xd 0x12 0xb 0xf 0x12>; + }; + + tegra-dp-tx-pu { + pc2_l0 = <0x22 0x33 0x44 0x66 0x33 0x44 0x66 0x44 0x66 0x66>; + pc2_l1 = <0x22 0x22 0x33 0x55 0x33 0x44 0x55 0x44 0x55 0x66>; + pc2_l2 = <0x22 0x22 0x33 0x44 0x33 0x33 0x44 0x44 0x55 0x66>; + pc2_l3 = <0x22 0x22 0x22 0x44 0x33 0x33 0x44 0x44 0x44 0x66>; + }; + }; + + display-timings { + + 1920x1080-32 { + clock-frequency = <0x8d9ee20>; + hactive = <0x780>; + vactive = <0x438>; + hfront-porch = <0x58>; + hback-porch = <0x94>; + hsync-len = <0x2c>; + vfront-porch = <0x4>; + vback-porch = <0x24>; + vsync-len = <0x5>; + nvidia,h-ref-to-sync = <0x1>; + nvidia,v-ref-to-sync = <0x1>; + }; + + 720x480-32 { + clock-frequency = <0x19bfcc0>; + hactive = <0x2d0>; + vactive = <0x1e0>; + hfront-porch = <0x10>; + hback-porch = <0x3c>; + hsync-len = <0x3e>; + vfront-porch = <0x9>; + vback-porch = <0x1e>; + vsync-len = <0x6>; + nvidia,h-ref-to-sync = <0x1>; + nvidia,v-ref-to-sync = <0x1>; + }; + }; + + dp-lt-settings { + + lt-setting@0 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x3>; + }; + + lt-setting@1 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x4>; + }; + + lt-setting@2 { + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,load-adj = <0x6>; + }; + }; + }; + + prod-settings { + #prod-cells = <0x3>; + prod_list_hdmi_soc = "prod_c_hdmi_0m_54m", "prod_c_hdmi_54m_111m", "prod_c_hdmi_111m_223m", "prod_c_hdmi_223m_300m", "prod_c_hdmi_300m_600m"; + + prod_c_hdmi_0m_54m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hdmi_54m_111m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_hdmi_111m_223m { + prod = <0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_223m_300m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_300m_600m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_54M { + prod = <0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_75M { + prod = <0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_150M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_300M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_600M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_dp { + prod = <0x58c 0xf0f0f10 0x5050310 0x590 0x3000100 0x100 0x594 0xf0000000 0x0 0x598 0x2ff0 0x2440 0x59c 0x401800 0x0 0x5a0 0x400000 0x400000 0x5a8 0xff000000 0x34000000 0x70 0xffffffff 0x0 0x180 0x1 0x1>; + }; + + prod_c_hbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_hbr2 { + prod = <0x590 0xf00000 0x400000>; + }; + + prod_c_rbr { + prod = <0x590 0xf00000 0x300000>; + }; + }; + }; + + dpaux@155c0000 { + compatible = "nvidia,tegra186-dpaux"; + reg = <0x0 0x155c0000 0x0 0x40000>; + interrupts = <0x0 0x9f 0x4>; + nvidia,dpaux-ctrlnum = <0x0>; + clocks = <0x10 0x60>; + clock-names = "dpaux"; + resets = <0x10 0x5>; + reset-names = "dpaux"; + power-domains = <0x94>; + status = "disabled"; + linux,phandle = <0x8e>; + phandle = <0x8e>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_dpaux_dp { + prod = <0x124 0x37fe 0x24c2>; + }; + + prod_c_dpaux_hdmi { + prod = <0x124 0x700 0x400>; + }; + }; + }; + + dpaux@15040000 { + compatible = "nvidia,tegra186-dpaux1"; + reg = <0x0 0x15040000 0x0 0x40000>; + interrupts = <0x0 0xa0 0x4>; + nvidia,dpaux-ctrlnum = <0x1>; + clocks = <0x10 0x5f>; + clock-names = "dpaux1"; + resets = <0x10 0x7c>; + reset-names = "dpaux1"; + power-domains = <0x94>; + status = "okay"; + linux,phandle = <0x91>; + phandle = <0x91>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_dpaux_dp { + prod = <0x124 0x37fe 0x24c2>; + }; + + prod_c_dpaux_hdmi { + prod = <0x124 0x700 0x400>; + }; + }; + }; + + se@15810000 { + compatible = "nvidia,tegra186-se1-nvhost"; + reg = <0x0 0x15810000 0x0 0x10000>; + supported-algos = "drbg"; + opcode_addr = <0x204>; + resets = <0x10 0x25>; + clocks = <0x10 0x67>; + clock-names = "se"; + iommus = <0x11 0xc>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + se@15820000 { + compatible = "nvidia,tegra186-se2-nvhost"; + reg = <0x0 0x15820000 0x0 0x10000>; + supported-algos = "aes", "cmac"; + opcode_addr = <0x404>; + resets = <0x10 0x25>; + clocks = <0x10 0x67>; + clock-names = "se"; + iommus = <0x11 0xd>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + se@15830000 { + compatible = "nvidia,tegra186-se3-nvhost"; + reg = <0x0 0x15830000 0x0 0x10000>; + supported-algos = "rsa"; + opcode_addr = <0x604>; + resets = <0x10 0x25>; + clocks = <0x10 0x67>; + clock-names = "se"; + iommus = <0x11 0xe>; + iommu-group-id = <0x1>; + status = "okay"; + }; + + se@15840000 { + compatible = "nvidia,tegra186-se4-nvhost"; + reg = <0x0 0x15840000 0x0 0x10000>; + supported-algos = "sha"; + opcode_addr = <0x104>; + resets = <0x10 0x25>; + clocks = <0x10 0x67>; + clock-names = "se"; + iommus = <0x11 0xf>; + iommu-group-id = <0x1>; + status = "okay"; + }; + }; + + reserved-memory { + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + + generic_carveout { + compatible = "nvidia,generic_carveout"; + size = <0x0 0x0>; + alignment = <0x0 0x100000>; + alloc-ranges = <0x0 0x0 0x1 0x0>; + no-map; + status = "disabled"; + linux,phandle = <0x95>; + phandle = <0x95>; + }; + + ramoops_carveout { + status = "disabled"; + reg = <0x2 0x75880000 0x0 0x200000>; + compatible = "nvidia,ramoops"; + alignment = <0x0 0x10000>; + no-map; + linux,phandle = <0x1cc>; + phandle = <0x1cc>; + }; + + vpr-carveout { + alignment = <0x0 0x400000>; + alloc-ranges = <0x0 0x80000000 0x0 0x70000000>; + reusable; + linux,phandle = <0x96>; + phandle = <0x96>; + }; + + fb0_carveout { + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + reg-names = "surface", "lut"; + no-map; + linux,phandle = <0x80>; + phandle = <0x80>; + }; + + fb1_carveout { + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + reg-names = "surface", "lut"; + no-map; + linux,phandle = <0x81>; + phandle = <0x81>; + }; + + fb2_carveout { + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + reg-names = "surface", "lut"; + no-map; + linux,phandle = <0x82>; + phandle = <0x82>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x1 0xd 0x3f08 0x1 0xe 0x3f08 0x1 0xb 0x3f08 0x1 0xa 0x3f08>; + status = "okay"; + }; + + rtc@c2a0000 { + compatible = "nvidia,tegra18-rtc"; + reg = <0x0 0xc2a0000 0x0 0x100>; + interrupt-parent = <0x3a>; + interrupts = <0x0 0xa 0x4>; + status = "okay"; + }; + + tegra-carveouts { + compatible = "nvidia,carveouts-t18x"; + memory-region = <0x95 0x96>; + }; + + mc_sid@2c00000 { + compatible = "nvidia,tegra186-mc-sid"; + reg = <0x0 0x2c00000 0x0 0x10000 0x0 0x2c10000 0x0 0x10000>; + status = "okay"; + }; + + iommu@12000000 { + compatible = "arm,mmu-500"; + reg = <0x0 0x12000000 0x0 0x1000000>; + #global-interrupts = <0x2>; + interrupts = <0x0 0xaa 0x4 0x0 0xab 0x4>; + #iommu-cells = <0x1>; + suspend-save-reg = <0xc390868>; + status = "okay"; + linux,phandle = <0x11>; + phandle = <0x11>; + + domains { + + gpu_domain { + address-space = <0x97>; + sid-list = <0x10>; + }; + + host1x_domain { + address-space = <0x98>; + sid-list = <0x1>; + }; + + host1x_client_domain { + address-space = <0x99>; + sid-list = <0x3 0x4 0x6 0x7 0x8 0x5 0xa 0xb 0x9 0x2 0x2b 0xc 0xd 0xe 0xf>; + }; + + host1x0_domain { + address-space = <0x99>; + sid-list = <0x38>; + }; + + host1x1_domain { + address-space = <0x99>; + sid-list = <0x39>; + }; + + host1x2_domain { + address-space = <0x99>; + sid-list = <0x3a>; + }; + + host1x3_domain { + address-space = <0x99>; + sid-list = <0x3b>; + }; + + host1x4_domain { + address-space = <0x99>; + sid-list = <0x3c>; + }; + + host1x5_domain { + address-space = <0x99>; + sid-list = <0x3d>; + }; + + host1x6_domain { + address-space = <0x99>; + sid-list = <0x3e>; + }; + + host1x7_domain { + address-space = <0x99>; + sid-list = <0x3f>; + }; + + hda_domain { + address-space = <0x9a>; + sid-list = <0x12>; + }; + + sdmmc1a_domain { + address-space = <0x9a>; + sid-list = <0x1a>; + }; + + sdmmc2a_domain { + address-space = <0x9a>; + sid-list = <0x19>; + }; + + sdmmc3a_domain { + address-space = <0x9a>; + sid-list = <0x18>; + }; + + sdmmc4a_domain { + address-space = <0x9a>; + sid-list = <0x17>; + }; + + ape_domain { + address-space = <0x9b>; + sid-list = <0x1e 0x14>; + }; + + xusb_host_domain { + address-space = <0x9a>; + sid-list = <0x1b>; + }; + + xusb_dev_domain { + address-space = <0x9a>; + sid-list = <0x1c>; + }; + + gpcdma_domain { + address-space = <0x9a>; + sid-list = <0x20>; + }; + + bpmp_domain { + address-space = <0x9a>; + sid-list = <0x32>; + }; + + sce_domain { + address-space = <0x9a>; + sid-list = <0x1f>; + }; + + aon_domain { + address-space = <0x9a>; + sid-list = <0x16>; + }; + + afi_domain { + address-space = <0x9c>; + sid-list = <0x11>; + }; + + sata2_domain { + address-space = <0x9a>; + sid-list = <0x1d>; + }; + + smmu_test_domain { + address-space = <0x9a>; + sid-list = <0x33>; + }; + + ufshci_domain { + address-space = <0x9a>; + sid-list = <0x15>; + }; + + rtcpu_domain { + address-space = <0x9d>; + sid-list = <0x2a 0x2d>; + }; + }; + + address-space-prop { + + host1x { + iova-start = <0x0 0x1000>; + iova-size = <0x0 0xfffff000>; + alignment = <0xfffff>; + num-pf-page = <0x0>; + gap-page = <0x1>; + linux,phandle = <0x98>; + phandle = <0x98>; + }; + + host1x_client { + iova-start = <0x0 0x1000>; + iova-size = <0x1f 0xfffff000>; + alignment = <0xfffff>; + num-pf-page = <0x0>; + gap-page = <0x1>; + linux,phandle = <0x99>; + phandle = <0x99>; + }; + + common { + iova-start = <0x0 0x80000000>; + iova-size = <0x0 0x7ff00000>; + alignment = <0xfffff>; + num-pf-page = <0x0>; + gap-page = <0x1>; + linux,phandle = <0x9a>; + phandle = <0x9a>; + }; + + pcie_as { + iova-start = <0x0 0x80000000>; + iova-size = <0x0 0xffffffff>; + alignment = <0xfffff>; + num-pf-page = <0x0>; + gap-page = <0x1>; + linux,phandle = <0x9c>; + phandle = <0x9c>; + }; + + gpu { + iova-start = <0x0 0x100000>; + iova-size = <0x3ff 0xffefffff>; + alignment = <0xfffff>; + num-pf-page = <0x0>; + gap-page = <0x0>; + linux,phandle = <0x97>; + phandle = <0x97>; + }; + + ape { + iova-start = <0x0 0x40000000>; + iova-size = <0x0 0x20000000>; + alignment = <0xfffff>; + num-pf-page = <0x0>; + gap-page = <0x1>; + linux,phandle = <0x9b>; + phandle = <0x9b>; + }; + + camera { + iova-start = <0x0 0xa0000000>; + iova-size = <0x0 0x20000000>; + alignment = <0xfffff>; + num-pf-page = <0x0>; + gap-page = <0x1>; + linux,phandle = <0x9d>; + phandle = <0x9d>; + }; + }; + }; + + smmu_test { + compatible = "nvidia,smmu_test"; + iommus = <0x11 0x33>; + linux,phandle = <0x1cd>; + phandle = <0x1cd>; + }; + + dma_test { + compatible = "nvidia,dma_test"; + linux,phandle = <0x1ce>; + phandle = <0x1ce>; + }; + + mc { + compatible = "nvidia,tegra-t18x-mc"; + reg-ranges = <0x1>; + reg = <0x0 0x2c10000 0x0 0x10000 0x0 0x2c20000 0x0 0x10000 0x0 0x2c30000 0x0 0x10000 0x0 0x2c40000 0x0 0x10000 0x0 0x2c50000 0x0 0x10000 0x0 0x2c60000 0x0 0x10000 0x0 0x2c70000 0x0 0x10000 0x0 0x2c80000 0x0 0x10000 0x0 0x2c90000 0x0 0x10000 0x0 0x2ca0000 0x0 0x10000>; + interrupts = <0x0 0xdf 0x4 0x0 0xe0 0x4>; + int_mask = <0xf3140>; + ecc_int_mask = <0x1c00>; + channels = <0x4>; + status = "okay"; + }; + + usb_cd { + compatible = "nvidia,tegra186-usb-cd"; + status = "okay"; + phys = <0x9e>; + phy-names = "otg-phy"; + nvidia,xusb-padctl = <0x9f>; + linux,phandle = <0xaf>; + phandle = <0xaf>; + }; + + mailbox@3538000 { + compatible = "nvidia,tegra186-xusb-mbox"; + reg = <0x0 0x3538000 0x0 0x1000>; + interrupts = <0x0 0xa4 0x4>; + #mbox-cells = <0x0>; + status = "okay"; + linux,phandle = <0xb0>; + phandle = <0xb0>; + }; + + xotg { + compatible = "nvidia,tegra186-xotg"; + interrupts = <0x0 0xa7 0x4>; + otg-rev = <0x300>; + adp-disable; + status = "okay"; + extcon-cables = <0xa0 0x1 0xa0 0x0>; + extcon-cable-names = "id", "vbus"; + #extcon-cells = <0x1>; + phys = <0xa1 0x10>; + phy-names = "otg-usb2"; + linux,phandle = <0xab>; + phandle = <0xab>; + }; + + xusb_padctl@3520000 { + compatible = "nvidia,tegra18x-xusb-padctl"; + reg = <0x0 0x3520000 0x0 0x1000 0x0 0x3540000 0x0 0x1000>; + reg-names = "padctl", "ao"; + resets = <0x10 0x37>; + reset-names = "padctl"; + status = "okay"; + avdd_usb-supply = <0x13>; + vclamp_usb-supply = <0x12>; + avdd_pll_erefeut-supply = <0x12>; + pinctrl-0 = <0xa2>; + pinctrl-1 = <0xa3>; + pinctrl-2 = <0xa4>; + pinctrl-3 = <0xa5>; + pinctrl-4 = <0xa6>; + pinctrl-5 = <0xa7>; + pinctrl-names = "vbus_en0_default", "vbus_en1_default", "vbus_en0_sfio_tristate", "vbus_en1_sfio_tristate", "vbus_en0_sfio_passthrough", "vbus_en1_sfio_passthrough"; + linux,phandle = <0x9f>; + phandle = <0x9f>; + + pads { + + usb2 { + clocks = <0x10 0x87>; + clock-names = "trk"; + + lanes { + + usb2-0 { + status = "okay"; + #phy-cells = <0x0>; + nvidia,function = "xusb"; + linux,phandle = <0x9e>; + phandle = <0x9e>; + }; + + usb2-1 { + status = "okay"; + #phy-cells = <0x0>; + nvidia,function = "xusb"; + linux,phandle = <0xac>; + phandle = <0xac>; + }; + + usb2-2 { + status = "okay"; + #phy-cells = <0x0>; + nvidia,function = "xusb"; + linux,phandle = <0xad>; + phandle = <0xad>; + }; + }; + }; + + usb3 { + + lanes { + + usb3-0 { + status = "okay"; + #phy-cells = <0x0>; + nvidia,function = "xusb"; + linux,phandle = <0xae>; + phandle = <0xae>; + }; + + usb3-1 { + status = "okay"; + #phy-cells = <0x0>; + nvidia,function = "xusb"; + linux,phandle = <0x108>; + phandle = <0x108>; + }; + + usb3-2 { + status = "okay"; + #phy-cells = <0x0>; + nvidia,function = "xusb"; + }; + }; + }; + + hsic { + status = "disabled"; + clocks = <0x10 0x86>; + clock-names = "trk"; + + lanes { + + hsic-0 { + status = "disabled"; + #phy-cells = <0x0>; + }; + }; + }; + }; + + ports { + + usb2-0 { + status = "okay"; + mode = "otg"; + vbus-supply = <0xa8>; + nvidia,oc-pin = <0x0>; + }; + + usb2-1 { + status = "okay"; + mode = "host"; + vbus-supply = <0xa9>; + nvidia,oc-pin = <0x1>; + }; + + usb2-2 { + status = "okay"; + mode = "host"; + vbus-supply = <0xaa>; + }; + + usb3-0 { + status = "okay"; + nvidia,usb2-companion = <0x1>; + }; + + usb3-1 { + status = "disabled"; + nvidia,usb2-companion = <0x1>; + }; + + usb3-2 { + status = "disabled"; + }; + + hsic-0 { + status = "disabled"; + }; + }; + + prod-settings { + #prod-cells = <0x4>; + + prod_c_bias { + prod = <0x0 0x284 0x38 0x38>; + }; + + prod_c_hsic0 { + prod = <0x0 0x344 0x7f 0x2d>; + }; + + prod_c_utmi0 { + prod = <0x0 0x88 0x1fe0000 0xcc0000>; + }; + + prod_c_utmi1 { + prod = <0x0 0xc8 0x1fe0000 0xcc0000>; + }; + + prod_c_utmi2 { + prod = <0x0 0x108 0x1fe0000 0xcc0000>; + }; + }; + }; + + xhci@3530000 { + compatible = "nvidia,tegra186-xhci"; + reg = <0x0 0x3530000 0x0 0x8000 0x0 0x3538000 0x0 0x1000>; + interrupt-parent = <0x3a>; + iommus = <0x11 0x1b>; + iommu_sodev_map; + status = "okay"; + otg-controller = <0xab>; + interrupts = <0x0 0xa3 0x4 0x0 0xa4 0x4 0x0 0xa7 0x4>; + clocks = <0x10 0x71 0x10 0xf4 0x10 0x72 0x10 0xf2 0x10 0x261 0x10 0xf5 0x10 0x215 0x10 0x261 0x10 0x200>; + clock-names = "xusb_host", "xusb_falcon_src", "xusb_ss", "xusb_ss_src", "xusb_hs_src", "xusb_fs_src", "pll_u_480m", "clk_m", "pll_e"; + nvidia,xusb-padctl = <0x9f>; + extcon-cables = <0xa0 0x1>; + extcon-cable-names = "id"; + #extcon-cells = <0x1>; + avddio_usb-supply = <0x13>; + avdd_pll_utmip-supply = <0x12>; + hvdd_usb-supply = <0x12>; + phys = <0x9e 0xac 0xad 0xae>; + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0"; + nvidia,boost_cpu_freq = <0x4b0>; + linux,phandle = <0x107>; + phandle = <0x107>; + }; + + xudc@3550000 { + compatible = "nvidia,tegra186-xudc"; + reg = <0x0 0x3550000 0x0 0x8000 0x0 0x3558000 0x0 0x1000>; + interrupts = <0x0 0xa6 0x4>; + iommus = <0x11 0x1c>; + iommu_sodev_map; + status = "okay"; + charger-detector = <0xaf>; + otg-controller = <0xab>; + clocks = <0x10 0xf3 0x10 0x72 0x10 0xf2 0x10 0xf5>; + nvidia,xusb-padctl = <0x9f>; + extcon-cables = <0xa0 0x0>; + extcon-cable-names = "vbus"; + #extcon-cells = <0x1>; + avdd-usb-supply = <0x13>; + phys = <0x9e>; + phy-names = "usb2"; + nvidia,boost-cpu-freq = <0x4b0>; + linux,phandle = <0x1cf>; + phandle = <0x1cf>; + }; + + pinctrl@3520000 { + compatible = "nvidia,tegra186-xusb-padctl"; + reg = <0x0 0x3520000 0x0 0x1000 0x0 0x3540000 0x0 0x1000>; + reg-names = "padctl", "ao"; + resets = <0x10 0x37>; + reset-names = "padctl_rst"; + clocks = <0x10 0x6f 0x10 0x215 0x10 0x87 0x10 0x86>; + clock-names = "xusb_clk", "utmipll", "usb2_trk", "hsic_trk"; + interrupts = <0x0 0xa7 0x4>; + mboxes = <0xb0>; + mbox-names = "xusb"; + #phy-cells = <0x1>; + status = "okay"; + vbus-0-supply = <0xa8>; + vbus-1-supply = <0xa9>; + vbus-2-supply = <0xaa>; + vbus-3-supply = <0x26>; + vddio-hsic-supply = <0x26>; + avdd_usb-supply = <0x13>; + vclamp_usb-supply = <0x12>; + avdd_pll_erefeut-supply = <0x12>; + pinctrl-0 = <0xb1>; + pinctrl-1 = <0xa4>; + pinctrl-2 = <0xa5>; + pinctrl-3 = <0xa6>; + pinctrl-4 = <0xa7>; + pinctrl-5 = <0xa2>; + pinctrl-6 = <0xa3>; + pinctrl-names = "default", "vbus_en0_sfio_tristate", "vbus_en1_sfio_tristate", "vbus_en0_sfio_passthrough", "vbus_en1_sfio_passthrough", "vbus_en0_default", "vbus_en1_default"; + linux,phandle = <0xa1>; + phandle = <0xa1>; + + pinmux { + linux,phandle = <0xb1>; + phandle = <0xb1>; + + usb2-micro-AB { + nvidia,lanes = "otg-0"; + nvidia,function = "xusb"; + nvidia,port-cap = <0x3>; + nvidia,oc-pin = <0x0>; + }; + + usb2-std-A-port2 { + nvidia,lanes = "otg-1"; + nvidia,function = "xusb"; + nvidia,port-cap = <0x1>; + nvidia,oc-pin = <0x1>; + }; + + usb3-std-A-port2 { + nvidia,lanes = "usb3-1"; + nvidia,port-cap = <0x1>; + nvidia,oc-pin = <0x1>; + }; + + e3325-usb3-std-A-HS { + nvidia,lanes = "otg-2"; + nvidia,function = "xusb"; + nvidia,port-cap = <0x1>; + status = "disabled"; + }; + + e3325-usb3-std-A-SS { + nvidia,lanes = "usb3-0"; + nvidia,port-cap = <0x1>; + status = "disabled"; + }; + }; + }; + + max16984-cdp { + compatible = "maxim,max16984-tegra186-cdp-phy"; + #phy-cells = <0x1>; + status = "disabled"; + linux,phandle = <0x1d0>; + phandle = <0x1d0>; + }; + + kfuse@0x3830000 { + compatible = "nvidia,tegra186-kfuse"; + reg = <0x0 0x3830000 0x0 0x10000>; + clocks = <0x10 0x125>; + clock-names = "kfuse"; + status = "okay"; + }; + + tachometer@39c0000 { + compatible = "nvidia,pwm-tegra186-tachometer"; + reg = <0x0 0x39c0000 0x0 0x10>; + #pwm-cells = <0x2>; + clocks = <0x10 0xa6>; + clock-names = "tach"; + resets = <0x10 0x6d>; + reset-names = "tach"; + pulse-per-rev = <0x2>; + capture-window-length = <0x8>; + status = "okay"; + linux,phandle = <0xb2>; + phandle = <0xb2>; + }; + + generic_pwm_tachometer { + compatible = "generic-pwm-tachometer"; + status = "okay"; + pwms = <0xb2 0x0 0xf4240>; + }; + + pmc@c370000 { + compatible = "nvidia,tegra186-aowake"; + reg = <0x0 0xc370000 0x0 0x600>; + status = "okay"; + nvidia,invert-interrupt; + linux,phandle = <0x1d1>; + phandle = <0x1d1>; + }; + + pmc-iopower { + compatible = "nvidia,tegra186-pmc-iopower"; + pad-controllers = <0xb3 0x34 0xa 0x29 0x1 0x35 0xd 0x24 0x25 0x27 0xf 0x10 0x11 0x12 0x18 0x19>; + pad-names = "ufs", "dbg", "spi", "audio-hv", "ao-hv", "dmic-hv", "sdmmc1-hv", "sdmmc2-hv", "sdmmc3-hv", "dsia", "dsib", "dsic", "dsid", "hdmi-dp0", "hdmi-dp1"; + status = "okay"; + vddio-sys-supply = <0x3d>; + vddio-uart-supply = <0x3d>; + vddio-conn-supply = <0x3d>; + vddio-edp-supply = <0x3d>; + vddio-pex-ctrl-supply = <0x3d>; + vddio-audio-supply = <0x3d>; + vddio-ufs-supply = <0x3d>; + vddio-ddr0-supply = <0xb4>; + vddio-ddr1-supply = <0xb4>; + vddio-mipi-bias-supply = <0x3c>; + vddio-cam-supply = <0x3d>; + vddio-sdmmc4-supply = <0x3d>; + vddio-sdmmc1-hv-supply = <0x1c>; + vddio-audio-hv-supply = <0x3d>; + vddio-dbg-supply = <0x3d>; + vddio-spi-supply = <0x3d>; + vddio-ao-supply = <0x3d>; + vddio-ao-hv-supply = <0xb5>; + vddio-dmic-hv-supply = <0x3d>; + vddio-sdmmc2-hv-supply = <0x13>; + vddio-sdmmc3-hv-supply = <0x16>; + linux,phandle = <0x1d2>; + phandle = <0x1d2>; + }; + + mipical { + compatible = "nvidia, tegra186-mipical"; + reg = <0x0 0x3990000 0x0 0x10000>; + clocks = <0x10 0x74 0x10 0x7e>; + clock-names = "mipi_cal", "uart_fs_mipi_cal"; + resets = <0x10 0x1c>; + reset-names = "mipi_cal"; + status = "okay"; + + prod-settings { + #prod-cells = <0x3>; + + prod { + prod = <0x4 0x3f000012 0x2a000010 0x18 0x40000000 0x0 0x1c 0x40000000 0x0 0x20 0x40000000 0x0 0x24 0x40000000 0x0 0x28 0x40000000 0x0 0x2c 0x40000000 0x0 0x3c 0x1f00 0x200 0x40 0x1f00 0x200 0x44 0x1f00 0x200 0x48 0x1f00 0x200 0x5c 0x1 0x0 0x60 0xf0f0f 0x0 0x64 0xf0ffff5 0x10010 0x68 0x4000001f 0x0 0x6c 0x4000001f 0x0 0x74 0x4000001f 0x0 0x78 0x4000001f 0x0>; + }; + + prod_c_cphy_csi { + prod = <0x18 0xf81f 0x0 0x1c 0xf81f 0x0 0x20 0xf81f 0x0 0x24 0xf81f 0x0 0x28 0xf81f 0x0 0x2c 0xf81f 0x0>; + + soc_a01 { + status = "disabled"; + prod = <0x18 0xf81f 0x8010 0x1c 0xf81f 0x8010 0x20 0xf81f 0x8010 0x24 0xf81f 0x8010 0x28 0xf81f 0x8010 0x2c 0xf81f 0x8010>; + linux,phandle = <0xfa>; + phandle = <0xfa>; + }; + }; + + prod_c_dphy_csi { + prod = <0x18 0xf81f 0x0 0x1c 0xf81f 0x0 0x20 0xf81f 0x0 0x24 0xf81f 0x0 0x28 0xf81f 0x0 0x2c 0xf81f 0x0>; + + soc_a01 { + status = "disabled"; + prod = <0x18 0xf81f 0x8010 0x1c 0xf81f 0x8010 0x20 0xf81f 0x8010 0x24 0xf81f 0x8010 0x28 0xf81f 0x8010 0x2c 0xf81f 0x8010>; + linux,phandle = <0xfb>; + phandle = <0xfb>; + }; + }; + + prod_c_dphy_dsi { + prod = <0x3c 0x1f1f1f 0x0 0x40 0x1f1f1f 0x0 0x44 0x1f1f1f 0x0 0x48 0x1f1f1f 0x0 0x68 0x1f0000 0x70000 0x6c 0x1f0000 0x70000 0x74 0x1f0000 0x70000 0x78 0x1f0000 0x70000>; + + soc_a01 { + status = "disabled"; + prod = <0x3c 0x1f1f1f 0x101010 0x40 0x1f1f1f 0x101010 0x44 0x1f1f1f 0x101010 0x48 0x1f1f1f 0x101010 0x68 0x1f0000 0x100000 0x6c 0x1f0000 0x100000 0x74 0x1f0000 0x100000 0x78 0x1f0000 0x100000>; + linux,phandle = <0xfc>; + phandle = <0xfc>; + }; + }; + }; + }; + + gp10b { + compatible = "nvidia,tegra186-gp10b", "nvidia,gp10b"; + dma-noncont; + reg = <0x0 0x17000000 0x0 0x1000000 0x0 0x18000000 0x0 0x1000000 0x0 0x3b41000 0x0 0x1000>; + interrupts = <0x0 0x46 0x4 0x0 0x47 0x4>; + interrupt-names = "stall", "nonstall"; + nvidia,host1x = <0xb6>; + iommus = <0x11 0x10>; + access-vpr-phys; + resets = <0x10 0xe>; + clocks = <0x10 0x136 0x10 0x1>; + clock-names = "gpu", "gpu_sys"; + fuse-overrides = <0x228 0x9999>; + status = "okay"; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + cpu_suspend = <0xc4000001>; + status = "okay"; + }; + + interrupt-controller@3881000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <0x3>; + interrupt-controller; + reg = <0x0 0x3881000 0x0 0x1000 0x0 0x3882000 0x0 0x2000>; + status = "okay"; + linux,phandle = <0x1>; + phandle = <0x1>; + }; + + interrupt-controller@3000000 { + compatible = "nvidia,tegra-gic"; + interrupt-controller; + reg = <0x0 0x3000000 0x0 0x800 0x0 0x3000800 0x0 0x800 0x0 0x3001000 0x0 0x800 0x0 0x3001800 0x0 0x800 0x0 0x3002000 0x0 0x800 0x0 0x3002800 0x0 0x800 0x0 0x3003000 0x0 0x800 0x0 0x3003800 0x0 0x800 0x0 0x300f800 0x0 0x800>; + status = "disabled"; + linux,phandle = <0x1d3>; + phandle = <0x1d3>; + }; + + tegra186-pm-irq { + compatible = "nvidia,tegra186-pm-irq"; + interrupt-controller; + #interrupt-cells = <0x3>; + interrupt-parent = <0x1>; + linux,phandle = <0x3a>; + phandle = <0x3a>; + }; + + timer@3020000 { + compatible = "nvidia,tegra186-timer"; + interrupts = <0x0 0x0 0x4 0x0 0x1 0x4 0x0 0x2 0x4 0x0 0x3 0x4 0x0 0x4 0x4 0x0 0x5 0x4 0x0 0x6 0x4>; + clock-frequency = <0x124f800>; + reg = <0x0 0x3010000 0x0 0xe0000>; + tmr-count = <0xa>; + wdt-count = <0x3>; + status = "okay"; + }; + + clock@5000000 { + compatible = "nvidia,tegra18x-car"; + reg = <0x0 0x5000000 0x0 0x1000000>; + #clock-cells = <0x1>; + #reset-cells = <0x1>; + status = "okay"; + linux,phandle = <0x10>; + phandle = <0x10>; + }; + + se_elp@3ad0000 { + compatible = "nvidia,tegra186-se-elp"; + reg = <0x0 0x3ad0000 0x0 0x10000 0x0 0x3ae0000 0x0 0x10000>; + interrupts = <0x0 0x11b 0x4>; + clocks = <0x10 0x67>; + clock-names = "se"; + pka1-rsa-priority = <0x12c>; + status = "okay"; + linux,phandle = <0x1d4>; + phandle = <0x1d4>; + }; + + tegra-hsp@b150000 { + compatible = "nvidia,tegra186-hsp"; + reg = <0x0 0xb150000 0x0 0x90000>; + interrupts = <0x0 0x8d 0x4 0x0 0x8e 0x4 0x0 0x8f 0x4 0x0 0x90 0x4>; + interrupt-names = "shared1", "shared2", "shared3", "shared4"; + resets = <0x10 0xba>; + reset-names = "hsp"; + status = "okay"; + linux,phandle = <0x58>; + phandle = <0x58>; + }; + + tegra-hsp@c150000 { + compatible = "nvidia,tegra186-hsp"; + reg = <0x0 0xc150000 0x0 0x90000>; + interrupts = <0x0 0x85 0x4 0x0 0x86 0x4 0x0 0x87 0x4 0x0 0x88 0x4>; + interrupt-names = "shared1", "shared2", "shared3", "shared4"; + status = "okay"; + linux,phandle = <0xe8>; + phandle = <0xe8>; + }; + + tegra-hsp@3c00000 { + compatible = "nvidia,tegra186-hsp"; + reg = <0x0 0x3c00000 0x0 0xa0000>; + interrupts = <0x0 0xb0 0x4 0x0 0x78 0x4 0x0 0x79 0x4 0x0 0x7a 0x4 0x0 0x7b 0x4 0x0 0x7c 0x4 0x0 0x7d 0x4 0x0 0x7e 0x4 0x0 0x7f 0x4>; + interrupt-names = "doorbell", "shared0", "shared1", "shared2", "shared3", "shared4", "shared5", "shared6", "shared7"; + status = "okay"; + linux,phandle = <0x1d5>; + phandle = <0x1d5>; + }; + + chipid@100000 { + compatible = "nvidia,tegra186-chipid"; + reg = <0x0 0x100000 0x0 0x10000>; + status = "disabled"; + }; + + miscreg@00100000 { + compatible = "nvidia,tegra186-miscreg"; + reg = <0x0 0x100000 0x0 0xf000 0x0 0x10f000 0x0 0x1000>; + status = "disabled"; + }; + + bpmp { + carveout-size = <0x200000>; + carveout-start = <0x77800000>; + compatible = "nvidia,tegra186-bpmp"; + iommus = <0x11 0x32>; + reg = <0x0 0xd000000 0x0 0x800000 0x0 0x3004e000 0x0 0x1000 0x0 0x3004f000 0x0 0x1000>; + status = "okay"; + #power-domain-cells = <0x1>; + linux,phandle = <0x1f>; + phandle = <0x1f>; + + bpmpthermal { + compatible = "nvidia,tegra186-bpmp-thermal"; + #thermal-sensor-cells = <0x1>; + status = "okay"; + linux,phandle = <0x47>; + phandle = <0x47>; + }; + }; + + dma@2600000 { + compatible = "nvidia,tegra186-gpcdma"; + reg = <0x0 0x2600000 0x0 0x210000>; + resets = <0x10 0x46>; + reset-names = "gpcdma"; + interrupts = <0x0 0x4b 0x4 0x0 0x4c 0x4 0x0 0x4d 0x4 0x0 0x4e 0x4 0x0 0x4f 0x4 0x0 0x50 0x4 0x0 0x51 0x4 0x0 0x52 0x4 0x0 0x53 0x4 0x0 0x54 0x4 0x0 0x55 0x4 0x0 0x56 0x4 0x0 0x57 0x4 0x0 0x58 0x4 0x0 0x59 0x4 0x0 0x5a 0x4 0x0 0x5b 0x4 0x0 0x5c 0x4 0x0 0x5d 0x4 0x0 0x5e 0x4 0x0 0x5f 0x4 0x0 0x60 0x4 0x0 0x61 0x4 0x0 0x62 0x4 0x0 0x63 0x4 0x0 0x64 0x4 0x0 0x65 0x4 0x0 0x66 0x4 0x0 0x67 0x4 0x0 0x68 0x4 0x0 0x69 0x4 0x0 0x6a 0x4 0x0 0x6b 0x4>; + #dma-cells = <0x1>; + iommus = <0x11 0x20>; + nvidia,preallocated-descs = <0x20>; + nvidia,preallocate-sg = <0x20>; + status = "okay"; + linux,phandle = <0x25>; + phandle = <0x25>; + }; + + gpio@2200000 { + compatible = "nvidia,tegra186-gpio"; + reg-names = "security", "gpio"; + reg = <0x0 0x2200000 0x0 0x10000 0x0 0x2210000 0x0 0x10000>; + interrupts = <0x0 0x2f 0x4 0x0 0x32 0x4 0x0 0x35 0x4 0x0 0x38 0x4 0x0 0x3b 0x4 0x0 0xb4 0x4>; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x2>; + gpio-ranges = <0xb7 0x0 0x0 0x90 0xb7 0x90 0x98 0x8 0xb7 0x98 0xb8 0x10 0xb7 0xa8 0xd8 0x18>; + status = "okay"; + linux,phandle = <0x1b>; + phandle = <0x1b>; + + wifi_over_pcie { + gpio-hog; + gpios = <0x8c 0x0>; + output-low; + label = "wifi-over-pcie"; + status = "disabled"; + }; + + pcie0_lane2_mux { + gpio-hog; + gpios = <0x8b 0x0>; + output-low; + label = "pcie-lane2-mux"; + status = "disabled"; + }; + + e3325_sdio_rst { + gpio-hog; + gpios = <0xe 0x0>; + output-high; + label = "e3325-sdio-rst"; + status = "disabled"; + }; + + e3325_lane0_mux { + gpio-hog; + gpios = <0xc 0x0>; + output-low; + label = "e3325-lane0-mux"; + status = "disabled"; + }; + + camera-control-output-low { + gpio-hog; + output-low; + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x6a 0x0>; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + status = "okay"; + }; + + camera-control-output-high { + gpio-hog; + output-high; + gpios = <0x8d 0x0>; + label = "cam0-rst"; + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + + wifi-enable { + gpio-hog; + gpios = <0x68 0x0>; + output-high; + line-name = "wifi-enable"; + }; + + wifi-wake-ap { + gpio-hog; + input; + label = "wifi-wake-ap"; + status = "disabled"; + }; + + sdmmc-wake-support-input { + gpio-hog; + gpios = <0x7d 0x0>; + input; + label = "sdmmc-wake-input"; + status = "okay"; + }; + + sdmmc-wake-support-output { + gpio-hog; + gpios = <0x7e 0x0>; + output-low; + label = "sdmmc-wake-output"; + status = "okay"; + }; + }; + + gpio@c2f0000 { + compatible = "nvidia,tegra186-gpio-aon"; + reg-names = "security", "gpio"; + reg = <0x0 0xc2f0000 0x0 0x1000 0x0 0xc2f1000 0x0 0x1000>; + interrupts = <0x0 0x3c 0x4>; + status = "okay"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x2>; + gpio-ranges = <0xb7 0x0 0x90 0x8 0xb7 0x8 0xa0 0x18 0xb7 0x20 0xc8 0x10 0xb7 0x30 0xf0 0x10>; + linux,phandle = <0x28>; + phandle = <0x28>; + + wifi-wake-ap { + gpio-hog; + gpios = <0x3b 0x0>; + input; + label = "wifi-wake-ap"; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + + pcie-controller@10003000 { + compatible = "nvidia,tegra186-pcie"; + power-domains = <0x1f 0x9>; + device_type = "pci"; + reg = <0x0 0x10003000 0x0 0x800 0x0 0x10003800 0x0 0x800 0x0 0x40000000 0x0 0x1000>; + reg-names = "pads", "afi", "cs"; + clocks = <0x10 0x4 0x10 0x3 0x10 0x261 0x10 0x200>; + clock-names = "afi", "pex", "clk_m", "pll_e"; + resets = <0x10 0x1 0x10 0x1d 0x10 0x1e>; + reset-names = "afi", "pex", "pcie_x"; + interrupts = <0x0 0x48 0x4 0x0 0x49 0x4>; + interrupt-names = "intr", "msi"; + #interrupt-cells = <0x1>; + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = <0x0 0x0 0x0 0x0 0x1 0x0 0x48 0x4>; + iommus = <0x11 0x11>; + iommu_sodev_map; + bus-range = <0x0 0xff>; + #address-cells = <0x3>; + #size-cells = <0x2>; + ranges = <0x82000000 0x0 0x10000000 0x0 0x10000000 0x0 0x1000 0x82000000 0x0 0x10001000 0x0 0x10001000 0x0 0x1000 0x82000000 0x0 0x10004000 0x0 0x10004000 0x0 0x1000 0x81000000 0x0 0x0 0x0 0x40001000 0x0 0x10000 0x82000000 0x0 0x40100000 0x0 0x40100000 0x0 0x7f00000 0xc2000000 0x0 0x48000000 0x0 0x48000000 0x0 0x38000000>; + status = "okay"; + dvdd-pex-supply = <0x89>; + hvdd-pex-pll-supply = <0x12>; + hvdd-pex-supply = <0x12>; + vddio-pexctl-aud-supply = <0x12>; + linux,phandle = <0x109>; + phandle = <0x109>; + + pci@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0x0 0x10000000 0x0 0x1000>; + reg = <0x800 0x0 0x0 0x0 0x0>; + status = "okay"; + #address-cells = <0x3>; + #size-cells = <0x2>; + ranges; + nvidia,num-lanes = <0x4>; + nvidia,afi-ctl-offset = <0x110>; + nvidia,disable-aspm-states = <0xf>; + nvidia,disable-clock-request; + }; + + pci@2,0 { + device_type = "pci"; + assigned-addresses = <0x82001000 0x0 0x10001000 0x0 0x1000>; + reg = <0x1000 0x0 0x0 0x0 0x0>; + status = "disabled"; + #address-cells = <0x3>; + #size-cells = <0x2>; + ranges; + nvidia,num-lanes = <0x0>; + nvidia,afi-ctl-offset = <0x118>; + nvidia,disable-aspm-states = <0xf>; + }; + + pci@3,0 { + device_type = "pci"; + assigned-addresses = <0x82001800 0x0 0x10004000 0x0 0x1000>; + reg = <0x1800 0x0 0x0 0x0 0x0>; + status = "okay"; + #address-cells = <0x3>; + #size-cells = <0x2>; + ranges; + nvidia,num-lanes = <0x1>; + nvidia,afi-ctl-offset = <0x19c>; + nvidia,disable-aspm-states = <0xf>; + }; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_pad { + prod = <0xc8 0xffffffff 0x80b880b8 0xcc 0xffffffff 0x480b8>; + }; + }; + }; + + sound { + iommus = <0x11 0x1e>; + dma-mask = <0x0 0x5e000000>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommu-group-id = <0x2>; + status = "okay"; + compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x"; + nvidia,model = "tegra-snd-t186ref-mobile-rt565x"; + nvidia,num-codec-link = <0xc>; + clocks = <0x10 0x10f 0x10 0xf6 0x10 0x7c>; + clock-names = "pll_a", "pll_a_out0", "extern1"; + assigned-clocks = <0x10 0xf6 0x10 0x7c>; + assigned-clock-parents = <0x10 0x10f 0x10 0xf6>; + resets = <0x10 0x92>; + reset-names = "extern1_rst"; + nvidia,audio-routing = "x Headphone", "x OUT", "x IN", "x Mic", "y Headphone", "y OUT", "y IN", "y Mic", "z Headphone", "z OUT", "z IN", "z Mic", "m Headphone", "m OUT", "m IN", "m Mic", "n Headphone", "n OUT", "n IN", "n Mic", "o Headphone", "o OUT", "o IN", "o Mic", "a IN", "a Mic", "b IN", "b Mic", "c IN", "c Mic", "d IN", "d Mic", "d1 Headphone", "d1 OUT", "d3 Headphone", "d3 OUT"; + nvidia,xbar = <0xb8>; + mclk-fs = <0x100>; + linux,phandle = <0x114>; + phandle = <0x114>; + + nvidia,dai-link-1 { + link-name = "spdif-dit-0"; + cpu-dai = <0xb9>; + codec-dai = <0xba>; + cpu-dai-name = "I2S1"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = [78 00]; + status = "okay"; + linux,phandle = <0x115>; + phandle = <0x115>; + }; + + nvidia,dai-link-2 { + link-name = "spdif-dit-1"; + cpu-dai = <0xbb>; + codec-dai = <0xbc>; + cpu-dai-name = "I2S2"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = [79 00]; + status = "okay"; + }; + + nvidia,dai-link-3 { + link-name = "spdif-dit-2"; + cpu-dai = <0xbd>; + codec-dai = <0xbe>; + cpu-dai-name = "I2S3"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = [7a 00]; + status = "okay"; + }; + + nvidia,dai-link-4 { + link-name = "spdif-dit-3"; + cpu-dai = <0xbf>; + codec-dai = <0xc0>; + cpu-dai-name = "I2S4"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = [6d 00]; + status = "okay"; + }; + + nvidia,dai-link-5 { + link-name = "spdif-dit-4"; + cpu-dai = <0xc1>; + codec-dai = <0xc2>; + cpu-dai-name = "I2S5"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = [6e 00]; + status = "okay"; + }; + + nvidia,dai-link-6 { + link-name = "spdif-dit-6"; + cpu-dai = <0xc3>; + codec-dai = <0xc4>; + cpu-dai-name = "I2S6"; + codec-dai-name = "dit-hifi"; + tx-mask = <0xff>; + rx-mask = <0xff>; + format = "dsp_a"; + bitclock-inversion; + bit-format = "s16_le"; + srate = <0x1f40>; + num-channel = <0x1>; + ignore_suspend; + name-prefix = [6f 00]; + status = "okay"; + }; + + nvidia,dai-link-7 { + link-name = "spdif-dit-7"; + cpu-dai = <0xc5>; + codec-dai = <0xc6>; + cpu-dai-name = "DMIC1"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + ignore_suspend; + num-channel = <0x2>; + name-prefix = [61 00]; + status = "okay"; + }; + + nvidia,dai-link-8 { + link-name = "spdif-dit-8"; + cpu-dai = <0xc7>; + codec-dai = <0xc8>; + cpu-dai-name = "DMIC2"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + ignore_suspend; + num-channel = <0x2>; + name-prefix = [62 00]; + status = "okay"; + }; + + nvidia,dai-link-9 { + link-name = "spdif-dit-9"; + cpu-dai = <0xc9>; + codec-dai = <0xca>; + cpu-dai-name = "DMIC3"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + ignore_suspend; + num-channel = <0x2>; + name-prefix = [63 00]; + status = "okay"; + }; + + nvidia,dai-link-10 { + link-name = "spdif-dit-10"; + cpu-dai = <0xcb>; + codec-dai = <0xcc>; + cpu-dai-name = "DMIC4"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + ignore_suspend; + num-channel = <0x2>; + name-prefix = [64 00]; + status = "okay"; + }; + + nvidia,dai-link-11 { + link-name = "dspk1-playback"; + cpu-dai = <0xcd>; + codec-dai = <0xce>; + cpu-dai-name = "DSPK1"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = "d3"; + status = "okay"; + }; + + nvidia,dai-link-12 { + link-name = "dspk-playback-l"; + cpu-dai = <0xcf>; + codec-dai = <0xd0>; + cpu-dai-name = "DSPK2"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = "d1"; + status = "okay"; + linux,phandle = <0x116>; + phandle = <0x116>; + }; + + nvidia,dai-link-13 { + link-name = "dspk-playback-r"; + cpu-dai = <0xcf>; + codec-dai = <0xd1>; + cpu-dai-name = "DSPK2"; + codec-dai-name = "dit-hifi"; + format = "i2s"; + bit-format = "s16_le"; + srate = <0xbb80>; + num-channel = <0x2>; + ignore_suspend; + name-prefix = "d2"; + status = "okay"; + linux,phandle = <0x118>; + phandle = <0x118>; + }; + }; + + sound_ref { + iommus = <0x11 0x1e>; + dma-mask = <0x0 0x5e000000>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommu-group-id = <0x2>; + status = "disabled"; + }; + + hda@3510000 { + compatible = "nvidia,tegra30-hda"; + iommus = <0x11 0x12>; + reg = <0x0 0x3510000 0x0 0x10000>; + clocks = <0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + clock-names = "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + resets = <0x10 0xf 0x10 0x10 0x10 0x11>; + reset-names = "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + interrupts = <0x0 0xa1 0x4>; + status = "okay"; + }; + + eqos_ape@2990000 { + status = "disabled"; + compatible = "nvidia,tegra18x-eqos-ape"; + wakeup-disable; + reg = <0x0 0x2990054 0x0 0x4 0x0 0x29900c0 0x0 0x28>; + clocks = <0x10 0x69 0x10 0xf6 0x10 0x10f>; + clock-names = "eqos_ape.ape", "pll_a_out0", "pll_a"; + }; + + watchdog@30c0000 { + compatible = "nvidia,tegra-wdt-t18x"; + reg = <0x0 0x30c0000 0x0 0x10000 0x0 0x3020000 0x0 0x10000 0x0 0x3010000 0x0 0x10000>; + interrupts = <0x0 0x7 0x4 0x0 0x8 0x4>; + nvidia,watchdog-index = <0x0>; + nvidia,timer-index = <0x7>; + nvidia,expiry-count = <0x5>; + nvidia,enable-on-init; + nvidia,extend-watchdog-suspend; + timeout-sec = <0x78>; + nvidia,disable-debug-reset; + status = "NILL"; + nvidia,shutdown-timeout = <0x96>; + linux,phandle = <0xfd>; + phandle = <0xfd>; + }; + + tegra_fiq_debugger { + compatible = "nvidia,fiq-debugger"; + use-console-port; + interrupts = <0x0 0x11 0x4>; + }; + + roc-flush@e080000 { + compatible = "nvidia,tegra186-roc-flush"; + reg = <0x0 0xe080000 0x0 0x10000>; + status = "disabled"; + }; + + mttcan@c310000 { + compatible = "nvidia,tegra186-mttcan"; + reg = <0x0 0xc310000 0x0 0x400 0x0 0xc311000 0x0 0x32 0x0 0xc312000 0x0 0x1000>; + reg-names = "can-regs", "glue-regs", "msg-ram"; + interrupts = <0x0 0x28 0x4>; + pll_source = "pllaon"; + clocks = <0x10 0xd2 0x10 0xd3 0x10 0x214>; + clock-names = "can", "can_host", "pllaon"; + resets = <0x10 0x3c>; + reset-names = "can"; + mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>; + tx-config = <0x0 0x10 0x0 0x40>; + rx-config = <0x40 0x40 0x40>; + status = "okay"; + gpio_can_stb = <0x28 0x28 0x0>; + gpio_can_en = <0x28 0x29 0x0>; + linux,phandle = <0x1d6>; + phandle = <0x1d6>; + }; + + mttcan@c320000 { + compatible = "nvidia,tegra186-mttcan"; + reg = <0x0 0xc320000 0x0 0x400 0x0 0xc321000 0x0 0x32 0x0 0xc322000 0x0 0x1000>; + reg-names = "can-regs", "glue-regs", "msg-ram"; + interrupts = <0x0 0x2a 0x4>; + pll_source = "pllaon"; + clocks = <0x10 0xd4 0x10 0xd5 0x10 0x214>; + clock-names = "can", "can_host", "pllaon"; + resets = <0x10 0x3d>; + reset-names = "can"; + mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>; + tx-config = <0x0 0x10 0x0 0x40>; + rx-config = <0x40 0x40 0x40>; + status = "okay"; + gpio_can_stb = <0x28 0x2e 0x0>; + gpio_can_en = <0x28 0x2f 0x0>; + linux,phandle = <0x1d7>; + phandle = <0x1d7>; + }; + + stm@8070000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0x0 0x8070000 0x0 0x1000 0x0 0xa000000 0x0 0x180000>; + reg-names = "stm-base", "stm-stimulus-base"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + port { + + endpoint { + remote-endpoint = <0xd2>; + linux,phandle = <0xdd>; + phandle = <0xdd>; + }; + }; + }; + + ptm@9840000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0x0 0x9840000 0x0 0x1000>; + cpu = <0x4>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + linux,phandle = <0x1d8>; + phandle = <0x1d8>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + linux,phandle = <0xd6>; + phandle = <0xd6>; + }; + }; + }; + + ptm@9940000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0x0 0x9940000 0x0 0x1000>; + cpu = <0x5>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + linux,phandle = <0x1d9>; + phandle = <0x1d9>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + linux,phandle = <0xd7>; + phandle = <0xd7>; + }; + }; + }; + + ptm@9a40000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0x0 0x9a40000 0x0 0x1000>; + cpu = <0x6>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + linux,phandle = <0x1da>; + phandle = <0x1da>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + linux,phandle = <0xd8>; + phandle = <0xd8>; + }; + }; + }; + + ptm@9b40000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0x0 0x9b40000 0x0 0x1000>; + cpu = <0x7>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + linux,phandle = <0x1db>; + phandle = <0x1db>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + linux,phandle = <0xd9>; + phandle = <0xd9>; + }; + }; + }; + + ptm_bpmp@8a1c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0x0 0x8a1c000 0x0 0x1000>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + port { + + endpoint { + remote-endpoint = <0xd4>; + linux,phandle = <0xe6>; + phandle = <0xe6>; + }; + }; + }; + + funnel_bccplex@9010000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0x0 0x9010000 0x0 0x1000>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xd5>; + linux,phandle = <0xdb>; + phandle = <0xdb>; + }; + }; + + port@1 { + reg = <0x0>; + + endpoint { + slave-mode; + linux,phandle = <0x1dc>; + phandle = <0x1dc>; + }; + }; + + port@2 { + reg = <0x1>; + + endpoint { + slave-mode; + remote-endpoint0 = <0xd6>; + remote-endpoint1 = <0xd7>; + remote-endpoint2 = <0xd8>; + remote-endpoint3 = <0xd9>; + linux,phandle = <0xd3>; + phandle = <0xd3>; + }; + }; + }; + }; + + funnel_major@8010000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0x0 0x8010000 0x0 0x1000>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xda>; + linux,phandle = <0xe1>; + phandle = <0xe1>; + }; + }; + + port@1 { + reg = <0x0>; + + endpoint { + slave-mode; + remote-endpoint = <0xdb>; + linux,phandle = <0xd5>; + phandle = <0xd5>; + }; + }; + + port@2 { + reg = <0x1>; + + endpoint { + slave-mode; + linux,phandle = <0x1dd>; + phandle = <0x1dd>; + }; + }; + + port@3 { + reg = <0x2>; + + endpoint { + slave-mode; + remote-endpoint = <0xdc>; + linux,phandle = <0xe5>; + phandle = <0xe5>; + }; + }; + + port@4 { + reg = <0x3>; + + endpoint { + slave-mode; + remote-endpoint = <0xdd>; + linux,phandle = <0xd2>; + phandle = <0xd2>; + }; + }; + }; + }; + + replicator@0x8040000 { + compatible = "arm,coresight-replicator"; + reg = <0x0 0x8040000 0x0 0x1000>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xde>; + linux,phandle = <0xe4>; + phandle = <0xe4>; + }; + }; + + port@1 { + reg = <0x1>; + + endpoint { + remote-endpoint = <0xdf>; + linux,phandle = <0xe3>; + phandle = <0xe3>; + }; + }; + + port@2 { + reg = <0x0>; + + endpoint { + slave-mode; + remote-endpoint = <0xe0>; + linux,phandle = <0xe2>; + phandle = <0xe2>; + }; + }; + }; + }; + + etf@8030000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x8030000 0x0 0x1000>; + coresight-default-sink; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + slave-mode; + remote-endpoint = <0xe1>; + linux,phandle = <0xda>; + phandle = <0xda>; + }; + }; + + port@1 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe2>; + linux,phandle = <0xe0>; + phandle = <0xe0>; + }; + }; + }; + }; + + tpiu@8060000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + reg = <0x0 0x8060000 0x0 0x1000>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + port { + + enpoint@0 { + slave-mode; + remote-endpoint = <0xe3>; + linux,phandle = <0xdf>; + phandle = <0xdf>; + }; + }; + }; + + etr@8050000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x8050000 0x0 0x1000>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + port { + + endpoint@0 { + slave-mode; + remote-endpoint = <0xe4>; + linux,phandle = <0xde>; + phandle = <0xde>; + }; + }; + }; + + funnel_minor@8820000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0x0 0x8820000 0x0 0x1000>; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe5>; + linux,phandle = <0xdc>; + phandle = <0xdc>; + }; + }; + + port@2 { + reg = <0x2>; + + endpoint { + slave-mode; + remote-endpoint = <0xe6>; + linux,phandle = <0xd4>; + phandle = <0xd4>; + }; + }; + }; + }; + + cpuidle { + compatible = "nvidia,tegra18x-cpuidle"; + status = "okay"; + }; + + cpufreq@e070000 { + compatible = "nvidia,tegra18x-cpufreq"; + reg = <0x0 0xe000000 0x0 0x80000>; + status = "okay"; + nvidia,enable-autocc3 = <0x0 0x1 0x1 0x1>; + nvidia,autocc3-freq = <0x0 0x0 0x1 0x0>; + cpu_emc_map = <0x79e00 0x31ce0 0x9f600 0x639c0 0x15ae00 0xa2800 0x1d4c00 0x1c7910>; + }; + + bwmgr { + compatible = "nvidia,bwmgr"; + clocks = <0x10 0x3a>; + clock-names = "emc"; + status = "okay"; + }; + + efuse@3820000 { + compatible = "nvidia,tegra186-efuse", "nvidia,tegra210-efuse"; + reg = <0x0 0x3820000 0x0 0x600>; + clocks = <0x10 0x0>; + clock-names = "fuse"; + nvidia,clock-always-on; + status = "okay"; + + efuse-burn { + compatible = "nvidia,tegra186-efuse-burn"; + clocks = <0x10 0x261>; + clock-names = "clk_m"; + nvidia,tz = <0xe7>; + nvidia,temp-range = <0xfa0 0x18a88>; + status = "okay"; + }; + }; + + hardwood { + compatible = "nvidia,denver-hardwood"; + interrupts = <0x0 0x18 0x4>; + }; + + cluster_clk_priv@e090000 { + compatible = "nvidia,t18x-cluster-clk-priv"; + #address-cells = <0x2>; + #size-cells = <0x2>; + reg = <0x0 0xe090000 0x0 0xfff0 0x0 0xe0a0000 0x0 0xfff0 0x0 0xe0b0000 0x0 0xfff0 0x0 0xe0c0000 0x0 0xfff0 0x0 0xe0d0000 0x0 0xfff0>; + status = "okay"; + }; + + generic-system-config { + compatible = "nvidia,tegra186-system-config"; + status = "disabled"; + }; + + axi2apb@2390000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + reg = <0x0 0x2390000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axi2apb@23a0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + reg = <0x0 0x23a0000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axi2apb@23b0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + reg = <0x0 0x23b0000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axi2apb@23c0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + reg = <0x0 0x23c0000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axi2apb@23d0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + reg = <0x0 0x23d0000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2100000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2100000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2110000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2110000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2120000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2120000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2130000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2130000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2140000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2140000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2150000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2150000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2160000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2160000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2170000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2170000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2180000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2180000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + axip2p@2190000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + reg = <0x0 0x2190000 0x0 0x1000>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + timeout = <0x17ae8>; + status = "okay"; + }; + + tegra-serr { + compatible = "nvidia,tegra186"; + }; + + tegra-firmwares { + status = "okay"; + mb1 = "unavailable"; + mb2 = "unavailable"; + mb1-bct = "unavailable"; + qb = "unavailable"; + osl = "unavailable"; + }; + + nvdumper { + compatible = "nvidia,tegra186-nvdumper"; + status = "disabled"; + }; + + tegra-pmc-blink-pwm { + compatible = "nvidia,tegra210-pmc-blink-pwm"; + status = "disabled"; + }; + + nvpmodel { + compatible = "nvidia,nvpmodel"; + status = "okay"; + }; + + external-connection { + compatible = "simple-bus"; + device_type = "external-connection"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + disp-state { + compatible = "extcon-disp-state"; + #extcon-cells = <0x1>; + }; + + extcon@1 { + compatible = "extcon-gpio-states"; + reg = <0x1>; + extcon-gpio,name = "VBUS"; + extcon-gpio,wait-for-gpio-scan = <0x0>; + extcon-gpio,cable-states = <0x3 0x0 0x0 0x2 0x1 0x2 0x2 0x1>; + gpios = <0x1b 0x9f 0x0 0x22 0x0 0x0>; + extcon-gpio,out-cable-names = <0x1 0x2 0x0>; + wakeup-source; + #extcon-cells = <0x1>; + linux,phandle = <0xa0>; + phandle = <0xa0>; + }; + }; + + aon@c160000 { + compatible = "nvidia,tegra186-aon"; + status = "okay"; + reg = <0x0 0xc1a0000 0x0 0x40000>; + #mbox-cells = <0x1>; + iommus = <0x11 0x16>; + nvidia,hsp-shared-mailbox = <0xe8 0x2>; + nvidia,hsp-shared-mailbox-names = "ivc-pair"; + nvidia,ivc-carveout-base-ss = <0x0>; + nvidia,ivc-carveout-size-ss = <0x1>; + nvidia,ivc-rx-ss = <0x2>; + nvidia,ivc-tx-ss = <0x3>; + nvidia,ivc-dbg-enable-ss = <0x0>; + linux,phandle = <0x41>; + phandle = <0x41>; + + ivc-channels@80000000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + + ivc_aon_echo@0 { + reg = <0x0 0x10000>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x40>; + }; + + ivc_aon_aondbg@480 { + reg = <0x480 0x10480>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x2>; + nvidia,frame-size = <0x80>; + }; + + ivc_aon_spi@600 { + reg = <0x600 0x10600>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x2>; + nvidia,frame-size = <0x6080>; + }; + + ivc_can0@c780 { + reg = <0xc780 0x1c780>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x80>; + }; + + ivc_can1@d000 { + reg = <0xd000 0x1d000>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + nvidia,frame-size = <0x80>; + }; + + ivc_aon_shub@d880 { + reg = <0xd880 0x1d880>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x4>; + nvidia,frame-size = <0x100>; + }; + }; + }; + + aondbg { + compatible = "nvidia,tegra186-aondbg"; + mboxes = <0x41 0x1>; + }; + + mttcan0-ivc { + compatible = "bosch,mttcan-ivc"; + mboxes = <0x41 0x3>; + status = "disabled"; + }; + + mttcan1-ivc { + compatible = "bosch,mttcan-ivc"; + mboxes = <0x41 0x4>; + status = "disabled"; + }; + + aon_shub { + status = "disabled"; + compatible = "nvidia,tegra186_aon_shub"; + mboxes = <0x41 0x5>; + }; + + i2c@31a0000 { + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + }; + }; + + hsp_top { + status = "okay"; + }; + + fixed-regulators { + compatible = "simple-bus"; + device_type = "fixed-regulators"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + regulator@0 { + compatible = "regulator-fixed"; + reg = <0x0>; + regulator-name = "vdd-ac-bat"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + regulator-always-on; + linux,phandle = <0x26>; + phandle = <0x26>; + }; + + regulator@1 { + compatible = "regulator-fixed-sync"; + reg = <0x1>; + regulator-name = "en-vdd-sd"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + gpio = <0x1b 0x7e 0x0>; + enable-active-high; + regulator-enable-ramp-delay = <0x460>; + regulator-disable-ramp-delay = <0x4074>; + linux,phandle = <0x1d>; + phandle = <0x1d>; + }; + + regulator@2 { + compatible = "regulator-fixed-sync"; + reg = <0x2>; + regulator-name = "en-vdd-cam"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + gpio = <0x8d 0x9 0x1>; + enable-active-high; + regulator-enable-ramp-delay = <0x6c>; + regulator-disable-ramp-delay = <0x4b0>; + linux,phandle = <0x2b>; + phandle = <0x2b>; + }; + + regulator@3 { + compatible = "regulator-fixed-sync"; + reg = <0x3>; + regulator-name = "vdd-hdmi"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + gpio = <0xe9 0xc 0x1>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + regulator-enable-ramp-delay = <0x2e9>; + regulator-disable-ramp-delay = <0x12110>; + linux,phandle = <0x8a>; + phandle = <0x8a>; + }; + + regulator@4 { + compatible = "regulator-fixed-sync"; + reg = <0x4>; + regulator-name = "vdd-usb0-5v"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + gpio = <0x1b 0x5c 0x0>; + gpio-open-drain; + enable-active-high; + regulator-enable-ramp-delay = <0x3b1>; + regulator-disable-ramp-delay = <0xa5a>; + linux,phandle = <0xa8>; + phandle = <0xa8>; + }; + + regulator@5 { + compatible = "regulator-fixed-sync"; + reg = <0x5>; + regulator-name = "vdd-usb1-5v"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + gpio = <0x1b 0x5d 0x0>; + gpio-open-drain; + enable-active-high; + regulator-enable-ramp-delay = <0x320>; + regulator-disable-ramp-delay = <0x32c8>; + linux,phandle = <0xa9>; + phandle = <0xa9>; + }; + + regulator@6 { + compatible = "regulator-fixed-sync"; + reg = <0x6>; + regulator-name = "en-vdd-ts-1v8"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + gpio = <0xe9 0x1 0x1>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + regulator-enable-ramp-delay = <0xad>; + regulator-disable-ramp-delay = <0x32c8>; + linux,phandle = <0x3f>; + phandle = <0x3f>; + }; + + regulator@7 { + compatible = "regulator-fixed-sync"; + reg = <0x7>; + regulator-name = "en-vdd-ts-hv-3v3"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + gpio = <0xe9 0x2 0x1>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + regulator-enable-ramp-delay = <0xf5>; + regulator-disable-ramp-delay = <0xa7f8>; + linux,phandle = <0x3e>; + phandle = <0x3e>; + }; + + regulator@8 { + compatible = "regulator-fixed-sync"; + reg = <0x8>; + regulator-name = "en-vdd-disp-3v3"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + gpio = <0xe9 0x3 0x0>; + enable-active-high; + regulator-enable-ramp-delay = <0xd8>; + regulator-disable-ramp-delay = <0xa7f8>; + linux,phandle = <0x84>; + phandle = <0x84>; + }; + + regulator@9 { + compatible = "regulator-fixed-sync"; + reg = <0x9>; + regulator-name = "en-mdm-pwr-3v7"; + regulator-min-microvolt = <0x387520>; + regulator-max-microvolt = <0x387520>; + gpio = <0xe9 0x7 0x1>; + enable-active-high; + linux,phandle = <0x1de>; + phandle = <0x1de>; + }; + + regulator@10 { + compatible = "regulator-fixed-sync"; + reg = <0xa>; + regulator-name = "en-vdd-disp-1v8"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + gpio = <0xe9 0x9 0x1>; + enable-active-high; + regulator-enable-ramp-delay = <0xb2>; + regulator-disable-ramp-delay = <0x2710>; + linux,phandle = <0x85>; + phandle = <0x85>; + }; + + regulator@11 { + compatible = "regulator-fixed-sync"; + reg = <0xb>; + regulator-name = "en-vdd-cam-hv-2v8"; + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + gpio = <0xe9 0xd 0x1>; + enable-active-high; + regulator-enable-ramp-delay = <0x1388>; + regulator-disable-ramp-delay = <0x153d8>; + linux,phandle = <0x29>; + phandle = <0x29>; + }; + + regulator@12 { + compatible = "regulator-fixed-sync"; + reg = <0xc>; + regulator-name = "en-vdd-cam-1v2"; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x124f80>; + gpio = <0x8d 0xa 0x0>; + enable-active-high; + linux,phandle = <0x34>; + phandle = <0x34>; + }; + + regulator@13 { + compatible = "regulator-fixed-sync"; + reg = <0xd>; + regulator-name = "vdd-fan"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + gpio = <0xe9 0x4 0x0>; + linux,phandle = <0xee>; + phandle = <0xee>; + }; + + regulator@14 { + compatible = "regulator-fixed-sync"; + reg = <0xe>; + regulator-name = "vdd-3v3"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + linux,phandle = <0x2e>; + phandle = <0x2e>; + }; + + regulator@15 { + compatible = "regulator-fixed-sync"; + reg = <0xf>; + regulator-name = "dis-vdd-1v2"; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x124f80>; + gpio = <0xe9 0xa 0x1>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + linux,phandle = <0x1df>; + phandle = <0x1df>; + }; + + regulator@16 { + compatible = "regulator-fixed-sync"; + reg = <0x10>; + regulator-name = "en-vdd-vcm-2v8"; + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + enable-active-high; + linux,phandle = <0x2c>; + phandle = <0x2c>; + }; + + regulator@17 { + compatible = "regulator-fixed-sync"; + reg = <0x11>; + regulator-name = "vdd-usb2-5v"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + gpio = <0xe9 0x0 0x0>; + linux,phandle = <0xaa>; + phandle = <0xaa>; + }; + + regulator@18 { + compatible = "regulator-fixed-sync"; + reg = <0x12>; + regulator-name = "vdd-sys-bl"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + linux,phandle = <0x88>; + phandle = <0x88>; + }; + + regulator@118 { + compatible = "regulator-fixed-sync"; + reg = <0x76>; + regulator-name = "en-vdd-sys"; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x124f80>; + gpio = <0x8d 0x3 0x1>; + enable-active-high; + linux,phandle = <0x2a>; + phandle = <0x2a>; + }; + + regulator@101 { + compatible = "regulator-fixed"; + reg = <0x65>; + regulator-name = "vdd-1v8-ap"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-boot-on; + linux,phandle = <0x3d>; + phandle = <0x3d>; + }; + + regulator@200 { + compatible = "regulator-fixed-sync"; + reg = <0xc8>; + regulator-name = "vdd-1v8-aud2"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + gpio = <0xea 0xb 0x1>; + enable-active-high; + status = "disabled"; + linux,phandle = <0x2f>; + phandle = <0x2f>; + }; + }; + + backlight { + status = "okay"; + + panel-s-wuxga-8-0-bl { + status = "disabled"; + compatible = "s,wuxga-8-0-bl"; + pwms = <0x27 0x0 0x9ce1>; + max-brightness = <0xff>; + default-brightness = <0xbf>; + default-charge-brightness = <0x70>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + linux,phandle = <0x1e0>; + phandle = <0x1e0>; + }; + + panel-s-wqxga-10-1-bl { + status = "disabled"; + compatible = "s,wqxga-10-1-bl"; + pwms = <0x27 0x0 0xf4240>; + max-brightness = <0xff>; + default-brightness = <0xe0>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc6 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe8 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff>; + linux,phandle = <0x1e1>; + phandle = <0x1e1>; + }; + + panel-s-edp-uhdtv-15-6-bl { + status = "disabled"; + compatible = "s-edp,uhdtv-15-6-bl"; + pwms = <0xeb 0x0 0x4c4b40>; + max-brightness = <0xff>; + default-brightness = <0xe0>; + linux,phandle = <0x1e2>; + phandle = <0x1e2>; + }; + + panel-a-edp-1080p-14-0-bl { + status = "disabled"; + compatible = "a-edp,1080p-14-0-bl"; + pwms = <0x27 0x0 0xf4240>; + max-brightness = <0xff>; + default-brightness = <0xe0>; + bl-measured = <0x0 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0x9 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0x10 0x11 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x2a 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xb0 0xb1 0xb2 0xb3 0xb4 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc2 0xc3 0xc4 0xc5 0xc6 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xe0 0xe1 0xe2 0xe3 0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xee 0xef 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xff>; + linux,phandle = <0x1e3>; + phandle = <0x1e3>; + }; + }; + + mods-simple-bus { + compatible = "simple-bus"; + device_type = "mods-simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + mods-clocks { + compatible = "nvidia,mods-clocks"; + status = "disabled"; + clocks = <0x10 0x264 0x10 0x261 0x10 0x260 0x10 0x262 0x10 0x37 0x10 0x38 0x10 0xd7 0x10 0x4d 0x10 0xc2 0x10 0xc3 0x10 0xd8 0x10 0x57 0x10 0x68 0x10 0x69 0x10 0x4f 0x10 0x2a 0x10 0x2b 0x10 0x54 0x10 0x55 0x10 0x9a 0x10 0x7a 0x10 0x7b 0x10 0x96 0x10 0x97 0x10 0xdf 0x10 0x2c 0x10 0xee 0x10 0x98 0x10 0x99 0x10 0x6a 0x10 0x6b 0x10 0x7c 0x10 0xb4 0x10 0x33 0x10 0x32 0x10 0x59 0x10 0x5a 0x10 0x5b 0x10 0x49 0x10 0x63 0x10 0x64 0x10 0x65 0x10 0x84 0x10 0x31 0x10 0xde 0x10 0x2e 0x10 0x4a 0x10 0x2f 0x10 0xda 0x10 0x4b 0x10 0x56 0x10 0x30 0x10 0x7d 0x10 0xb6 0x10 0xdb 0x10 0xb7 0x10 0xdc 0x10 0xb8 0x10 0xb9 0x10 0xba 0x10 0x34 0x10 0x35 0x10 0x4c 0x10 0x36 0x10 0x80 0x10 0x6f 0x10 0x70 0x10 0x71 0x10 0x72 0x10 0xf2 0x10 0xf3 0x10 0xf4 0x10 0xf5 0x10 0x95 0x10 0xbb 0x10 0xbc 0x10 0xbd 0x10 0xe1 0x10 0xbe 0x10 0xbf 0x10 0xc0 0x10 0xc1 0x10 0x3a 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0xb2 0x10 0xb3 0x10 0x8c 0x10 0x8d 0x10 0x8e 0x10 0x8f 0x10 0x90 0x10 0x91 0x10 0x92 0x10 0x93 0x10 0x94 0x10 0x130 0x10 0x131 0x10 0xec 0x10 0x12e 0x10 0x12f 0x10 0xa6 0x10 0x10d 0x10 0x10e 0x10 0x204 0x10 0x11e 0x10 0x10f 0x10 0x20d 0x10 0xf6 0x10 0x120 0x10 0x201 0x10 0xb 0x10 0xc 0x10 0xd 0x10 0x209 0x10 0x20a 0x10 0x20c 0x10 0x6e 0x10 0x114 0x10 0x115 0x10 0x116 0x10 0x117 0x10 0x206 0x10 0x10b 0x10 0x207 0x10 0x210 0x10 0x20b 0x10 0x200 0x10 0x6c 0x10 0x6d 0x10 0x105 0x10 0x106 0x10 0x208 0x10 0x215 0x10 0x112 0x10 0x113>; + clock-names = "osc", "clk_m", "clk_32k", "pll_ref", "uarta", "uartb", "uartc", "uartd", "uarte", "uartf", "uartg", "ahub", "apb2ape", "ape", "i2s1", "i2s2", "i2s3", "i2s4", "i2s5", "i2s6", "dmic1", "dmic2", "dmic3", "dmic4", "dmic5", "spdif_in", "spdif_out", "dspk1", "dspk2", "iqc1", "iqc2", "aud_mclk", "nvcsi", "vi", "isp", "extperiph1", "extperiph2", "extperiph3", "extperiph4", "sata", "sata_oob", "sata_iobist", "qspi", "spi1", "spi2", "spi3", "spi4", "i2c1", "i2c2", "i2c3", "i2c4", "i2c5", "i2c6", "i2c7", "i2c8", "i2c9", "i2c10", "i2c12", "i2c13", "i2c14", "sdmmc1", "sdmmc2", "sdmmc3", "sdmmc4", "sdmmc_legacy_tm", "xusb", "xusb_dev", "xusb_host", "xusb_ss", "xusb_core_ss", "xusb_core_dev", "xusb_falcon", "xusb_fs", "axi_cbb", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7", "pwm8", "emc", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "ufshc", "ufsdev_ref", "mphy_l0_rx_symb", "mphy_l0_rx_ls_bit", "mphy_l0_tx_symb", "mphy_l0_tx_ls_3xbit", "mphy_l0_rx_ana", "mphy_l1_rx_ana", "mphy_iobist", "mphy_tx_1mhz_ref", "mphy_core_pll_fixed", "uphy_pll0_pwrseq", "uphy_pll1_pwrseq", "pex_sata_usb_rx_byp", "pex_usb_pad0_mgmt", "pex_usb_pad1_mgmt", "tach", "pllp_out0", "pllp_out5", "pllp", "pllp_div8", "plla", "plla1", "pll_a_out0", "pll_a_out1", "pllc", "pllc_out_isp", "pllc_out_ve", "pllc_out_aon", "pllc2", "pllc3", "pllc4_vco", "pllc4_out", "pllc4_out0", "pllc4_out1", "pllc4_out2", "pllc4_out_mux", "pll_d", "pll_d_out1", "pll_d2", "pll_d3", "pll_dp", "plle", "pllrefe_out", "pllrefe_pll_ref", "pllrefe_out_gated", "pllrefe_out1", "pllrefe_vco", "pllu", "pllu_48M", "pllu_480M"; + resets = <0x10 0x2f 0x10 0x30 0x10 0x31 0x10 0x32 0x10 0x84 0x10 0x6f 0x10 0x70 0x10 0x7b 0x10 0x3e 0x10 0x92 0x10 0x58 0x10 0x33 0x10 0x19 0x10 0xb 0x10 0xc 0x10 0xd 0x10 0x90 0x10 0x1f 0x10 0x81 0x10 0x28 0x10 0x29 0x10 0x2a 0x10 0x2b 0x10 0x13 0x10 0x14 0x10 0x15 0x10 0x16 0x10 0x17 0x10 0x18 0x10 0x51 0x10 0x52 0x10 0x53 0x10 0x4d 0x10 0x4e 0x10 0x4f 0x10 0x50 0x10 0x21 0x10 0x22 0x10 0x23 0x10 0x24 0x10 0x35 0x10 0x36 0x10 0x38 0x10 0x3a 0x10 0x63 0x10 0x64 0x10 0x65 0x10 0x66 0x10 0x67 0x10 0x68 0x10 0x69 0x10 0x6a 0x10 0x71 0x10 0x55 0x10 0x6d>; + reset-names = "uarta", "uartb", "uartc", "uartd", "uarte", "uartf", "uartg", "ape", "dmic5", "aud_mclk", "nvcsi", "vi", "isp", "extperiph1", "extperiph2", "extperiph3", "extperiph4", "sata", "qspi", "spi1", "spi2", "spi3", "spi4", "i2c1", "i2c2", "i2c3", "i2c4", "i2c5", "i2c6", "i2c7", "i2c8", "i2c9", "i2c10", "i2c12", "i2c13", "i2c14", "sdmmc1", "sdmmc2", "sdmmc3", "sdmmc4", "xusb_dev", "xusb_host", "xusb_ss", "axi_cbb", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7", "pwm8", "ufshc", "mphy_iobist", "tach"; + }; + }; + + pfsd { + status = "okay"; + num_resources = <0x0>; + secret = <0x2f>; + active_steps = <0xa>; + active_rpm = <0x0 0x3e8 0x7d0 0xbb8 0xfa0 0x1388 0x1770 0x1b58 0x2710 0x2af8>; + rpm_diff_tolerance = <0x2>; + active_rru = <0x28 0x2 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1>; + active_rrd = <0x28 0x2 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1>; + state_cap_lookup = <0x2 0x2 0x2 0x2 0x3 0x3 0x3 0x4 0x4 0x4>; + pwm_period = <0xb116>; + pwm_id = <0x3>; + step_time = <0x64>; + state_cap = <0x7>; + active_pwm_max = <0x100>; + tach_period = <0x3e8>; + pwm_gpio = <0x28 0x16 0x1>; + linux,phandle = <0xed>; + phandle = <0xed>; + }; + + pwm-fan { + status = "okay"; + compatible = "pwm-fan"; + #pwm-cells = <0x1>; + pwms = <0xec 0x0 0xb116>; + shared_data = <0xed>; + active_pwm = <0x0 0x50 0x78 0xa0 0xff 0xff 0xff 0xff 0xff 0xff>; + vdd-fan-supply = <0xee>; + }; + + tfesd { + secret = <0x25>; + toffset = <0x0>; + polling_period = <0x44c>; + ndevs = <0x3>; + cdev_type = "pwm-fan"; + tzp_governor_name = "pid_thermal_gov"; + linux,phandle = <0xef>; + phandle = <0xef>; + + dev1 { + dev_data = "BCPU-therm"; + coeffs = <0x1e 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + dev2 { + dev_data = "MCPU-therm"; + coeffs = <0x1e 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + dev3 { + dev_data = "GPU-therm"; + coeffs = <0x28 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + }; + }; + + thermal-fan-est { + compatible = "thermal-fan-est"; + num_resources = <0x0>; + shared_data = <0xef>; + trip_length = <0xa>; + active_trip_temps = <0x0 0xc738 0xee48 0x11558 0x14050 0x222e0 0x249f0 0x27100 0x29810 0x2bf20>; + active_hysteresis = <0x0 0x3a98 0x2328 0x2328 0x2710 0x0 0x0 0x0 0x0 0x0>; + }; + + vi-bypass@15700000 { + compatible = "nvidia,tegra186-vi-bypass"; + status = "okay"; + }; + + tegra_cec { + status = "okay"; + compatible = "nvidia,tegra186-cec"; + reg = <0x0 0x3960000 0x0 0x1000>; + interrupts = <0x0 0xa2 0x4>; + clocks = <0x10 0x5e>; + clock-names = "cec"; + }; + + soft_watchdog { + compatible = "softdog-platform"; + status = "disabled"; + linux,phandle = <0xff>; + phandle = <0xff>; + }; + + bthrot_cdev { + compatible = "nvidia,tegra18x-balanced-throttle"; + clocks = <0x10 0x242 0x10 0x243 0x10 0x136 0x10 0x3a>; + clock-names = "mcpu", "bcpu", "gpu", "emc"; + + skin_balanced { + cdev-type = "skin-balanced"; + cooling-min-state = <0x0>; + cooling-max-state = <0x42>; + #cooling-cells = <0x2>; + throttle_table = <0x1d8760 0x1d8760 0x1314c4 0xffffffff 0x1d2658 0x1d2658 0x12cf9c 0xffffffff 0x1cc550 0x1cc550 0x128a74 0xffffffff 0x1c6448 0x1c6448 0x12454c 0xffffffff 0x1c0340 0x1c0340 0x120025 0xffffffff 0x1ba238 0x1ba238 0x11bafd 0xffffffff 0x1b4130 0x1b4130 0x1175d5 0xffffffff 0x1ae028 0x1ae028 0x1130ad 0xffffffff 0x1a7f20 0x1a7f20 0x10eb85 0xffffffff 0x1a1e18 0x1a1e18 0x10a65d 0xffffffff 0x19bd10 0x19bd10 0x106136 0xffffffff 0x195c08 0x195c08 0x101c0e 0xffffffff 0x18fb00 0x18fb00 0xfd6e6 0xffffffff 0x1899f8 0x1899f8 0xf91be 0xffffffff 0x1838f0 0x1838f0 0xf4c96 0xffffffff 0x17d7e8 0x17d7e8 0xf076e 0xffffffff 0x1776e0 0x1776e0 0xec246 0xffffffff 0x1715d8 0x1715d8 0xe7d1f 0xffffffff 0x16b4d0 0x16b4d0 0xe37f7 0xffffffff 0x1653c8 0x1653c8 0xdf2cf 0xffffffff 0x15f2c0 0x15f2c0 0xdada7 0xffffffff 0x1591b8 0x1591b8 0xd687f 0xffffffff 0x1530b0 0x1530b0 0xd2357 0xffffffff 0x14cfa8 0x14cfa8 0xcde30 0xffffffff 0x146ea0 0x146ea0 0xc9908 0xffffffff 0x140d98 0x140d98 0xc53e0 0xffffffff 0x13ac90 0x13ac90 0xc0eb8 0xffffffff 0x134b88 0x134b88 0xbc990 0xffffffff 0x12ea80 0x12ea80 0xb8468 0xffffffff 0x128978 0x128978 0xb3f40 0xffffffff 0x122870 0x122870 0xafa19 0xffffffff 0x11c768 0x11c768 0xab4f1 0xffffffff 0x116660 0x116660 0xa6fc9 0xffffffff 0x110558 0x110558 0xa2aa1 0xffffffff 0x10a450 0x10a450 0x9e579 0xffffffff 0x104348 0x104348 0x9a051 0xffffffff 0xfe240 0xfe240 0x95b2a 0xffffffff 0xf8138 0xf8138 0x91602 0xffffffff 0xf2030 0xf2030 0x8d0da 0xffffffff 0xebf28 0xebf28 0x88bb2 0xffffffff 0xe5e20 0xe5e20 0x8468a 0xffffffff 0xdfd18 0xdfd18 0x80162 0xffffffff 0xd9c10 0xd9c10 0x7bc3a 0xffffffff 0xd3b08 0xd3b08 0x77713 0xffffffff 0xcda00 0xcda00 0x731eb 0xffffffff 0xc78f8 0xc78f8 0x6ecc3 0xffffffff 0xc17f0 0xc17f0 0x6a79b 0xffffffff 0xbb6e8 0xbb6e8 0x66273 0xffffffff 0xb55e0 0xb55e0 0x61d4b 0xffffffff 0xaf4d8 0xaf4d8 0x5d824 0xffffffff 0xa93d0 0xa93d0 0x592fc 0xffffffff 0xa32c8 0xa32c8 0x54dd4 0xffffffff 0x9d1c0 0x9d1c0 0x508ac 0xffffffff 0x970b8 0x970b8 0x4c384 0xffffffff 0x90fb0 0x90fb0 0x47e5c 0xffffffff 0x8aea8 0x8aea8 0x43934 0xffffffff 0x84da0 0x84da0 0x3f40d 0xffffffff 0x7ec98 0x7ec98 0x3aee5 0xffffffff 0x78b90 0x78b90 0x369bd 0xffffffff 0x72a88 0x72a88 0x32495 0xffffffff 0x6c980 0x6c980 0x2df6d 0xffffffff 0x66878 0x66878 0x29a45 0xffffffff 0x60770 0x60770 0x2551e 0xffffffff 0x5a668 0x5a668 0x20ff6 0xffffffff 0x54560 0x54560 0x1cace 0xffffffff 0x4e458 0x4e458 0x185a6 0xffffffff>; + }; + + gpu_balanced { + cdev-type = "gpu-balanced"; + cooling-min-state = <0x0>; + cooling-max-state = <0x34>; + #cooling-cells = <0x2>; + throttle_table = <0x1d8760 0x1d8760 0x12b31c 0xffffffff 0x1d2658 0x1d2658 0x125ce2 0xffffffff 0x1cc550 0x1cc550 0x1206a9 0xffffffff 0x1c6448 0x1c6448 0x11b06f 0xffffffff 0x1c0340 0x1c0340 0x115a36 0xffffffff 0x1ba238 0x1ba238 0x1103fc 0xffffffff 0x1b4130 0x1b4130 0x10adc3 0xffffffff 0x1ae028 0x1ae028 0x105789 0xffffffff 0x1a7f20 0x1a7f20 0x100150 0xffffffff 0x1a1e18 0x1a1e18 0xfab16 0xffffffff 0x19bd10 0x19bd10 0xf54dd 0xffffffff 0x195c08 0x195c08 0xefea3 0xffffffff 0x18fb00 0x18fb00 0xea86a 0xffffffff 0x1899f8 0x1899f8 0xe5230 0xffffffff 0x1838f0 0x1838f0 0xdfbf7 0xffffffff 0x17d7e8 0x17d7e8 0xda5bd 0xffffffff 0x1776e0 0x1776e0 0xd4f84 0xffffffff 0x1715d8 0x1715d8 0xcf94a 0xffffffff 0x16b4d0 0x16b4d0 0xca310 0xffffffff 0x1653c8 0x1653c8 0xc4cd7 0xffffffff 0x15f2c0 0x15f2c0 0xbf69d 0xffffffff 0x1591b8 0x1591b8 0xba064 0xffffffff 0x1530b0 0x1530b0 0xb4a2a 0xffffffff 0x14cfa8 0x14cfa8 0xaf3f1 0xffffffff 0x146ea0 0x146ea0 0xa9db7 0xffffffff 0x140d98 0x140d98 0xa477e 0xffffffff 0x13ac90 0x13ac90 0x9f144 0xffffffff 0x134b88 0x134b88 0x99b0b 0xffffffff 0x12ea80 0x12ea80 0x944d1 0xffffffff 0x128978 0x128978 0x8ee98 0xffffffff 0x122870 0x122870 0x8985e 0xffffffff 0x11c768 0x11c768 0x84225 0xffffffff 0x116660 0x116660 0x7ebeb 0xffffffff 0x110558 0x110558 0x795b2 0xffffffff 0x10a450 0x10a450 0x73f78 0xffffffff 0x104348 0x104348 0x6e93e 0xffffffff 0xfe240 0xfe240 0x69305 0xffffffff 0xf8138 0xf8138 0x63ccb 0xffffffff 0xf2030 0xf2030 0x5e692 0xffffffff 0xebf28 0xebf28 0x59058 0xffffffff 0xe5e20 0xe5e20 0x53a1f 0xffffffff 0xdfd18 0xdfd18 0x4e3e5 0xffffffff 0xd9c10 0xd9c10 0x48dac 0xffffffff 0xd3b08 0xd3b08 0x43772 0xffffffff 0xcda00 0xcda00 0x3e139 0xffffffff 0xc78f8 0xc78f8 0x38aff 0xffffffff 0xc17f0 0xc17f0 0x334c6 0xffffffff 0xbb6e8 0xbb6e8 0x2de8c 0xffffffff 0xb55e0 0xb55e0 0x28853 0xffffffff 0xaf4d8 0xaf4d8 0x23219 0xffffffff 0xa93d0 0xa93d0 0x1dbe0 0xffffffff 0xa32c8 0xa32c8 0x185a6 0xffffffff>; + linux,phandle = <0x52>; + phandle = <0x52>; + }; + + cpu_balanced { + cdev-type = "cpu-balanced"; + cooling-min-state = <0x0>; + cooling-max-state = <0x42>; + #cooling-cells = <0x2>; + throttle_table = <0x1d8760 0x1d8760 0xffffffff 0xffffffff 0x1d2658 0x1d2658 0xffffffff 0xffffffff 0x1cc550 0x1cc550 0xffffffff 0xffffffff 0x1c6448 0x1c6448 0xffffffff 0xffffffff 0x1c0340 0x1c0340 0xffffffff 0xffffffff 0x1ba238 0x1ba238 0xffffffff 0xffffffff 0x1b4130 0x1b4130 0xffffffff 0xffffffff 0x1ae028 0x1ae028 0xffffffff 0xffffffff 0x1a7f20 0x1a7f20 0xffffffff 0xffffffff 0x1a1e18 0x1a1e18 0xffffffff 0xffffffff 0x19bd10 0x19bd10 0x13d814 0xffffffff 0x195c08 0x195c08 0x1382cc 0xffffffff 0x18fb00 0x18fb00 0x132d84 0xffffffff 0x1899f8 0x1899f8 0x12d83d 0xffffffff 0x1838f0 0x1838f0 0x1282f5 0xffffffff 0x17d7e8 0x17d7e8 0x122dad 0xffffffff 0x1776e0 0x1776e0 0x11d865 0xffffffff 0x1715d8 0x1715d8 0x11831d 0xffffffff 0x16b4d0 0x16b4d0 0x112dd5 0xffffffff 0x1653c8 0x1653c8 0x10d88e 0xffffffff 0x15f2c0 0x15f2c0 0x108346 0xffffffff 0x1591b8 0x1591b8 0x102dfe 0xffffffff 0x1530b0 0x1530b0 0xfd8b6 0xffffffff 0x14cfa8 0x14cfa8 0xf836e 0xffffffff 0x146ea0 0x146ea0 0xf2e27 0xffffffff 0x140d98 0x140d98 0xed8df 0xffffffff 0x13ac90 0x13ac90 0xe8397 0xffffffff 0x134b88 0x134b88 0xe2e4f 0xffffffff 0x12ea80 0x12ea80 0xdd907 0xffffffff 0x128978 0x128978 0xd83bf 0xffffffff 0x122870 0x122870 0xd2e78 0xffffffff 0x11c768 0x11c768 0xcd930 0xffffffff 0x116660 0x116660 0xc83e8 0xffffffff 0x110558 0x110558 0xc2ea0 0xffffffff 0x10a450 0x10a450 0xbd958 0xffffffff 0x104348 0x104348 0xb8411 0xffffffff 0xfe240 0xfe240 0xb2ec9 0xffffffff 0xf8138 0xf8138 0xad981 0xffffffff 0xf2030 0xf2030 0xa8439 0xffffffff 0xebf28 0xebf28 0xa2ef1 0xffffffff 0xe5e20 0xe5e20 0x9d9a9 0xffffffff 0xdfd18 0xdfd18 0x98462 0xffffffff 0xd9c10 0xd9c10 0x92f1a 0xffffffff 0xd3b08 0xd3b08 0x8d9d2 0xffffffff 0xcda00 0xcda00 0x8848a 0xffffffff 0xc78f8 0xc78f8 0x82f42 0xffffffff 0xc17f0 0xc17f0 0x7d9fb 0xffffffff 0xbb6e8 0xbb6e8 0x784b3 0xffffffff 0xb55e0 0xb55e0 0x72f6b 0xffffffff 0xaf4d8 0xaf4d8 0x6da23 0xffffffff 0xa93d0 0xa93d0 0x684db 0xffffffff 0xa32c8 0xa32c8 0x62f93 0xffffffff 0x9d1c0 0x9d1c0 0x5da4c 0xffffffff 0x970b8 0x970b8 0x58504 0xffffffff 0x90fb0 0x90fb0 0x52fbc 0xffffffff 0x8aea8 0x8aea8 0x4da74 0xffffffff 0x84da0 0x84da0 0x4852c 0xffffffff 0x7ec98 0x7ec98 0x42fe5 0xffffffff 0x78b90 0x78b90 0x3da9d 0xffffffff 0x72a88 0x72a88 0x38555 0xffffffff 0x6c980 0x6c980 0x3300d 0xffffffff 0x66878 0x66878 0x2dac5 0xffffffff 0x60770 0x60770 0x2857d 0xffffffff 0x5a668 0x5a668 0x23036 0xffffffff 0x54560 0x54560 0x1daee 0xffffffff 0x4e458 0x4e458 0x185a6 0xffffffff>; + linux,phandle = <0x49>; + phandle = <0x49>; + }; + + emergency_balanced { + cdev-type = "emergency-balanced"; + cooling-min-state = <0x0>; + cooling-max-state = <0x1>; + #cooling-cells = <0x2>; + throttle_table = <0x111ed0 0x111ed0 0x5f758 0x60ae0>; + linux,phandle = <0x55>; + phandle = <0x55>; + }; + }; + + tegra_skin_thermal { + compatible = "nvidia,tegra-skin-thermal"; + #thermal-sensor-cells = <0x1>; + io-channels = <0xf0 0x0 0xf0 0x1 0xf1 0x3>; + io-channel-names = "gpu-voltage", "gpu-current", "vddin-power"; + + power_feature@0 { + #power-feature-cells = <0x1>; + type = <0x0>; + rc_k = <0x1>; + resistance = <0x1>; + linux,phandle = <0xf2>; + phandle = <0xf2>; + }; + + power_feature@1 { + #power-feature-cells = <0x1>; + type = <0x1>; + rc_k = <0x1>; + resistance = <0x1>; + linux,phandle = <0xf4>; + phandle = <0xf4>; + }; + + hotspot@0 { + power-features-list = <0xf2 0xf3 0xf4 0x0 0xf4 0x1>; + offset = <0x3>; + rc_k = <0x1>; + reference-sensor = <0xf5>; + linux,phandle = <0xf6>; + phandle = <0xf6>; + }; + + hotspot@1 { + power-features-list = <0xf2 0xf3>; + offset = <0x3>; + rc_k = <0x1>; + reference-sensor = <0xf5>; + linux,phandle = <0xf7>; + phandle = <0xf7>; + }; + + hotspot@2 { + power-features-list = <0xf2 0xf3 0xf4 0x2>; + offset = <0x3>; + rc_k = <0x1>; + reference-sensor = <0xf5>; + linux,phandle = <0xf8>; + phandle = <0xf8>; + }; + + skin-sensor@0 { + thermal-sensor = <0x0>; + hotspot-list = <0xf6 0xf7>; + }; + + skin-sensor@1 { + thermal-sensor = <0x1>; + hotspot-list = <0xf7>; + }; + + skin-sensor@2 { + thermal-sensor = <0x2>; + hotspot-list = <0xf8>; + }; + }; + + dummy-cool-dev { + compatible = "dummy-cooling-dev"; + #cooling-cells = <0x2>; + status = "disabled"; + linux,phandle = <0x1e4>; + phandle = <0x1e4>; + }; + + gpio-keys { + compatible = "gpio-keys"; + gpio-keys,name = "gpio-keys"; + + power { + label = "Power"; + gpios = <0x28 0x38 0x1>; + linux,code = <0x74>; + gpio-key,wakeup; + }; + + volume_up { + label = "Volume Up"; + gpios = <0x28 0x39 0x1>; + linux,code = <0x73>; + }; + + volume_down { + label = "Volume Down"; + gpios = <0x28 0x3a 0x1>; + linux,code = <0x72>; + }; + }; + + bluedroid_pm { + avdd-supply = <0x26>; + dvdd-supply = <0x12>; + compatible = "nvidia,tegra-bluedroid_pm"; + id = <0x0>; + bluedroid_pm,reset-gpio = <0x1b 0x3d 0x0>; + bluedroid_pm,host-wake-gpio = <0x28 0x3c 0x0>; + bluedroid_pm,ext-wake-gpio = <0x1b 0xa4 0x0>; + interrupt-parent = <0x28>; + interrupts = <0x3c 0x1>; + linux,phandle = <0x10b>; + phandle = <0x10b>; + }; + + e3326_lens_ov5693@P5V27C { + min_focus_distance = "0.0"; + hyper_focal = "0.0"; + focal_length = "2.67"; + f_number = "2.0"; + aperture = "2.0"; + }; + + tegra-camera-platform { + compatible = "nvidia, tegra-camera-platform"; + num_csi_lanes = <0x4>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + max_pixel_rate = <0xb71b0>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + tpg_max_iso = <0x3bc400>; + linux,phandle = <0x12f>; + phandle = <0x12f>; + + modules { + + module0 { + badge = "e3326_front_P5V27C"; + position = "rear"; + orientation = [31 00]; + status = "okay"; + linux,phandle = <0x121>; + phandle = <0x121>; + + drivernode0 { + pcl_id = "v4l2_sensor"; + devname = "ov5693 2-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov5693_c@36"; + status = "okay"; + linux,phandle = <0x122>; + phandle = <0x122>; + }; + + drivernode1 { + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3326_lens_ov5693@P5V27C/"; + status = "okay"; + linux,phandle = <0x133>; + phandle = <0x133>; + }; + }; + + module1 { + badge = "imx390_front"; + position = "front"; + orientation = [31 00]; + status = "disabled"; + linux,phandle = <0x124>; + phandle = <0x124>; + + drivernode0 { + pcl_id = "v4l2_sensor"; + devname = "imx390 30-001c"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + status = "disabled"; + linux,phandle = <0x125>; + phandle = <0x125>; + }; + + drivernode1 { + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + status = "disabled"; + linux,phandle = <0x137>; + phandle = <0x137>; + }; + }; + + module2 { + badge = "e3322_centerright_A815P2"; + position = "centerright"; + orientation = [31 00]; + status = "disabled"; + linux,phandle = <0x140>; + phandle = <0x140>; + + drivernode0 { + pcl_id = "v4l2_sensor"; + devname = "imx219 32-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + status = "disabled"; + linux,phandle = <0x141>; + phandle = <0x141>; + }; + + drivernode1 { + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + status = "disabled"; + linux,phandle = <0x142>; + phandle = <0x142>; + }; + }; + + module3 { + badge = "e3322_topleft_A815P2"; + position = "topleft"; + orientation = [31 00]; + status = "disabled"; + linux,phandle = <0x149>; + phandle = <0x149>; + + drivernode0 { + pcl_id = "v4l2_sensor"; + devname = "imx219 33-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + status = "disabled"; + linux,phandle = <0x14a>; + phandle = <0x14a>; + }; + + drivernode1 { + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + status = "disabled"; + linux,phandle = <0x14b>; + phandle = <0x14b>; + }; + }; + + module4 { + badge = "e3322_bottomright_A815P2"; + position = "bottomright"; + orientation = [31 00]; + status = "disabled"; + linux,phandle = <0x152>; + phandle = <0x152>; + + drivernode0 { + pcl_id = "v4l2_sensor"; + devname = "imx219 34-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + status = "disabled"; + linux,phandle = <0x153>; + phandle = <0x153>; + }; + + drivernode1 { + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + status = "disabled"; + linux,phandle = <0x154>; + phandle = <0x154>; + }; + }; + + module5 { + badge = "e3322_topright_A815P2"; + position = "topright"; + orientation = [31 00]; + status = "disabled"; + linux,phandle = <0x15b>; + phandle = <0x15b>; + + drivernode0 { + pcl_id = "v4l2_sensor"; + devname = "imx219 35-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + status = "disabled"; + linux,phandle = <0x15c>; + phandle = <0x15c>; + }; + + drivernode1 { + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + status = "disabled"; + linux,phandle = <0x15d>; + phandle = <0x15d>; + }; + }; + }; + }; + + e3323_lens_ov23850@CH06P1 { + min_focus_distance = "10.0"; + hyper_focal = "0.2"; + focal_length = "4.73"; + f_number = "2.2"; + aperture = "2.2"; + }; + + e3333_lens_ov5693@P5V27C { + min_focus_distance = "0.0"; + hyper_focal = "0.0"; + focal_length = "2.67"; + f_number = "2.0"; + aperture = "2.0"; + }; + + lens_imx274@A6V26 { + min_focus_distance = "0.0"; + hyper_focal = "0.0"; + focal_length = "5.00"; + f_number = "2.0"; + aperture = "2.2"; + }; + + vivid-driver { + + instance0 { + + mode0 { + tegra_sinterface = "host"; + pix_clk_hz = "74250000"; + readout_orientation = "90"; + active_w = "1920"; + active_h = "1080"; + pixel_t = "bayer_bggr10"; + line_length = "2200"; + horz_front_porch = "88"; + horz_sync = "44"; + horz_back_porch = "148"; + vert_front_porch = [34 00]; + vert_sync = [35 00]; + vert_back_porch = "36"; + gain_factor = "16"; + framerate_factor = [31 00]; + min_gain_val = [31 00]; + max_gain_val = "256"; + min_exp_time = "34"; + max_exp_time = "999994"; + min_framerate = [31 00]; + max_framerate = "30"; + embedded_metadata_height = [31 00]; + }; + }; + }; + + tegra-virtual-camera-platform { + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + + modules { + + module0 { + badge = "vivid_front_instance0"; + position = "front"; + orientation = [31 00]; + + drivernode0 { + pcl_id = "v4l2_sensor_virtual"; + devname = "tegra-vivid-000"; + proc-device-tree = "/proc/device-tree/vivid-driver/instances/instance0"; + }; + }; + }; + }; + + bcmdhd_pcie_wlan { + compatible = "android,bcmdhd_pcie_wlan"; + interrupt-parent = <0x28>; + interrupts = <0x3b 0x14>; + wlan-pwr-gpio = <0x1b 0x68 0x0>; + fw_path = "/vendor/firmware/fw_bcmdhd.bin"; + nv_path = "/vendor/firmware/nvram_4359_b1.txt"; + status = "disabled"; + linux,phandle = <0x1e5>; + phandle = <0x1e5>; + }; + + bcmdhd_wlan { + compatible = "android,bcmdhd_wlan"; + interrupt-parent = <0x28>; + interrupts = <0x3b 0x14>; + wlan-pwr-gpio = <0x1b 0x68 0x0>; + fw_path = "/vendor/firmware/fw_bcmdhd_4354.bin"; + nv_path = "/vendor/firmware/nvram_quill_4354.txt"; + sdhci-host = <0xf9>; + pwr-retry-cnt = <0x5>; + status = "okay"; + linux,phandle = <0x10a>; + phandle = <0x10a>; + }; + + plugin-manager { + status = "disabled"; + + soc-prod-a01-fragment { + chip-id = "A01", "A01P"; + + override@0 { + target = <0xfa>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0xfb>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0xfc>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragement@0 { + odm-data = "enable-denver-wdt"; + + override@0 { + target = <0xfd>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragement@1 { + odm-data = "disable-denver-wdt"; + + override@0 { + target = <0xb3>; + + _overlay_ { + nvidia,enable-halt-in-fiq; + }; + }; + }; + + fragement@2 { + odm-data = "enable-pmic-wdt"; + + override@0 { + target = <0xfe>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragement@4 { + odm-data = "enable-pmic-wdt", "enable-denver-wdt"; + + override@0 { + target = <0xff>; + + _overlay_ { + status = "disabled"; + }; + }; + }; + + fragement@6 { + odm-data = "mods-build"; + + override@0 { + target = <0xb0>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@1 { + target = <0xa1>; + + _overlay_ { + delete-target-property = "mboxes"; + }; + }; + + override@2 { + target = <0x25>; + + _overlay_ { + nvidia,bypass-smmu; + }; + }; + + override@3 { + target = <0xf9>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@4 { + target = <0x100>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@5 { + target = <0x101>; + + _overlay_ { + delete-target-property = "nvidia,enable-hwcq"; + }; + }; + + override@7 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15200000 { + win-mask = <0x3>; + status = "okay"; + }; + + nvdisplay@15210000 { + win-mask = <0xc>; + status = "okay"; + }; + + nvdisplay@15220000 { + win-mask = <0x30>; + status = "okay"; + }; + + sor { + status = "okay"; + + dp-display { + status = "okay"; + }; + + hdmi-display { + status = "disabled"; + }; + + panel-s-edp-uhdtv-15-6 { + + smartdimmer { + status = "disabled"; + }; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + + sor1 { + status = "okay"; + + hdmi-display { + status = "okay"; + }; + + dp-display { + status = "disabled"; + }; + }; + + dsi { + status = "okay"; + nvidia,dsi-csi-loopback; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + }; + }; + }; + + fragement@7 { + odm-data = "enable-high-speed-uart"; + + override@0 { + target = <0x103>; + + _overlay_ { + compatible = "nvidia,tegra186-hsuart"; + early-print-console-channel; + resets = <0x10 0x2f>; + reset-names = "serial"; + }; + }; + }; + + fragement@8 { + odm-data = "enable-sdmmc-hwcq"; + + override@0 { + target = <0x101>; + + _overlay_ { + nvidia,enable-hwcq; + }; + }; + }; + + fragement@9 { + odm-data = "enable-ufs-on-uphy-lane5"; + + override@0 { + target = <0x104>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x105>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@3 { + target = <0x106>; + + _overlay_ { + + gpio@76 { + + ufs_lane5_mux { + status = "okay"; + }; + + sata_lane5_mux { + status = "disabled"; + }; + }; + }; + }; + }; + + fragement@10 { + odm-data = "enable-ufs-on-uphy-lane4"; + + override@0 { + target = <0x104>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x105>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@3 { + target = <0x106>; + + _overlay_ { + + gpio@76 { + + pcie0_lane4_mux { + status = "disabled"; + }; + + ufs_lane4_mux { + status = "okay"; + }; + + sata_lane5_mux { + status = "disabled"; + }; + + ufs_lane5_mux { + status = "okay"; + }; + }; + }; + }; + }; + + fragment-sdwake-p3310-1000-300 { + ids = ">=3310-1000-300"; + + override@100 { + target = <0x1e>; + + _overlay_ { + + gpio_edp2_pp5 { + status = "okay"; + }; + + gpio_edp3_pp6 { + status = "okay"; + }; + }; + }; + + override@101 { + target = <0x1b>; + + _overlay_ { + + sdmmc-wake-support-input { + status = "okay"; + }; + + sdmmc-wake-support-output { + status = "okay"; + }; + }; + }; + + override@102 { + target = <0x1d>; + + _overlay_ { + gpio = <0x1b 0x7e 0x0>; + }; + }; + + override@103 { + target = <0x100>; + + _overlay_ { + cd-gpios = <0x1b 0x7d 0x0>; + nvidia,cd-wakeup-capable; + }; + }; + }; + + fragement-pmon-p3310-1000-300 { + ids = ">=3310-1000-300", "3310-1000-200-F"; + + override@0 { + target = <0xf0>; + + _overlay_ { + + channel@0 { + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@1 { + ti,shunt-resistor-mohm = <0xa>; + }; + }; + }; + + override@1 { + target = <0xf1>; + + _overlay_ { + + channel@0 { + ti,shunt-resistor-mohm = <0x5>; + }; + + channel@1 { + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@2 { + ti,shunt-resistor-mohm = <0xa>; + }; + }; + }; + }; + + fragement-pmon-p3310-1000-800 { + ids = ">=3310-1000-800"; + + override@0 { + target = <0xf1>; + + _overlay_ { + + channel@0 { + ti,shunt-resistor-mohm = <0x14>; + }; + + channel@2 { + ti,rail-name = "VDD_SYS_DDR"; + }; + }; + }; + }; + + fragment-devslp@0 { + ids = ">=3310-1000-200"; + + override@0 { + target = <0x105>; + + _overlay_ { + gpios = <0x22 0x7 0x0>; + }; + }; + + override@1 { + target = <0x3b>; + + _overlay_ { + + pin_gpio7 { + drive-push-pull = <0x1>; + }; + }; + }; + }; + + fragment-e3325-xusb { + enable-override-on-all-matches; + ids = "<3310-1000-500"; + odm-data = "enable-xusb-on-uphy-lane0"; + + override@0 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "okay"; + }; + }; + }; + }; + + override@1 { + target = <0x107>; + + _overlay_ { + phys = <0x9e 0xac 0xad 0xae 0x108>; + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0", "usb3-1"; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + e3325_sdio_rst { + status = "okay"; + }; + + e3325_lane0_mux { + status = "okay"; + }; + }; + }; + + override@3 { + target = <0x109>; + + _overlay_ { + + pci@1,0 { + nvidia,num-lanes = <0x2>; + }; + + pci@2,0 { + nvidia,num-lanes = <0x1>; + }; + + pci@3,0 { + nvidia,num-lanes = <0x1>; + }; + }; + }; + }; + + fragment-500-pcie-config { + ids = ">=3310-1000-500"; + + override@0 { + target = <0x109>; + + _overlay_ { + + pci@1,0 { + nvidia,num-lanes = <0x4>; + }; + + pci@2,0 { + nvidia,num-lanes = <0x0>; + }; + + pci@3,0 { + nvidia,num-lanes = <0x1>; + }; + }; + }; + }; + + fragment-comms-a00-chip { + ids = "<3310-1000-500"; + + override@0 { + target = <0x10a>; + + _overlay_ { + sdhci-host = <0xf9>; + pwr-retry-cnt = <0x0>; + interrupt-parent = <0x1b>; + interrupts = <0x10 0x14>; + delete-target-property = "wlan-pwr-gpio"; + }; + }; + + override@1 { + target = <0x1b>; + + _overlay_ { + + wifi-wake-ap { + status = "okay"; + gpios = <0x10 0x0>; + }; + + wifi-enable { + gpios = <0xe 0x0>; + }; + }; + }; + + override@3 { + target = <0x28>; + + _overlay_ { + + wifi-wake-ap { + status = "disabled"; + }; + }; + }; + }; + + fragment-500-xusb-config { + ids = ">=3310-1000-500"; + + override@0 { + target = <0x107>; + + _overlay_ { + phys = <0x9e 0xac 0xad 0xae>; + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0"; + }; + }; + + override@1 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-1 { + status = "disabled"; + }; + + usb3-0 { + nvidia,usb2-companion = <0x1>; + status = "okay"; + }; + }; + }; + }; + }; + + fragment-500-e3325-pcie { + enable-override-on-all-matches; + ids = ">=3310-1000-500"; + odm-data = "enable-pcie-on-uphy-lane0"; + + override@0 { + target = <0x107>; + + _overlay_ { + phys = <0x9e 0xac 0xad>; + phy-names = "usb2-0", "usb2-1", "usb2-2"; + }; + }; + + override@1 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "disabled"; + }; + }; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + pcie0_lane2_mux { + status = "okay"; + }; + }; + }; + }; + + fragment-e3320-dp { + ids = ">=3320-1000-000", ">=3320-1100-000"; + + override@0 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15220000 { + status = "okay"; + }; + + sor { + status = "okay"; + + dp-display { + status = "okay"; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + }; + }; + }; + + fragment-p3310-c00-comm { + ids = ">=3310-1000-800"; + + override@0 { + target = <0x10b>; + + _overlay_ { + bluedroid_pm,reset-gpio = <0x1b 0x3d 0x0>; + }; + }; + }; + + fragment-p3310-c00-pmic { + ids = ">=3310-1000-800"; + + override@0 { + target = <0x10c>; + + _overlay_ { + maxim,active-fps-source = <0x3>; + }; + }; + }; + + fragment-p3310-c01 { + ids = ">=3310-1000-900"; + + override@0 { + target = <0x10c>; + + _overlay_ { + regulator-boot-on; + regulator-always-on; + }; + }; + + override@1 { + target = <0x3b>; + + _overlay_ { + + pin_gpio2 { + status = "disabled"; + }; + + pin_gpio3 { + status = "disabled"; + }; + }; + }; + }; + + fragment-p3310-c03 { + ids = ">=3310-1000-B00"; + + override@1 { + target = <0x10d>; + + _overlay_ { + regulator-name = "dvdd-pex"; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + }; + }; + + override@2 { + target = <0x10e>; + + _overlay_ { + maxim,active-fps-source = <0x3>; + }; + }; + + override@3 { + target = <0x89>; + + _overlay_ { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + }; + }; + }; + + fragment-e2614-common@0 { + ids = "2614-0000-*"; + + overrides@0 { + target = <0x10f>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0xea>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@2 { + target = <0x110>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@3 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@4 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@5 { + target = <0x112>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@6 { + target = <0x113>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@8 { + target = <0x2f>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@10 { + target = <0x114>; + + _overlay_ { + nvidia,num-codec-link = <0xd>; + nvidia,audio-routing = "x Headphone Jack", "x HPO L Playback", "x Headphone Jack", "x HPO R Playback", "x IN1P", "x Mic Jack", "x Int Spk", "x SPO Playback", "x DMIC L1", "x Int Mic", "x DMIC L2", "x Int Mic", "x DMIC R1", "x Int Mic", "x DMIC R2", "x Int Mic", "y Headphone", "y OUT", "y IN", "y Mic", "z Headphone", "z OUT", "z IN", "z Mic", "m Headphone", "m OUT", "m IN", "m Mic", "n Headphone", "n OUT", "n IN", "n Mic", "o Headphone", "o OUT", "o IN", "o Mic", "a IN", "a Mic", "b IN", "b Mic", "c IN", "c Mic", "d IN", "d Mic", "d1 Headphone", "d1 OUT", "d2 Headphone", "d2 OUT", "d3 Headphone", "d3 OUT"; + }; + }; + + overrides@11 { + target = <0x115>; + + _overlay_ { + link-name = "rt565x-playback"; + codec-dai-name = "rt5659-aif1"; + }; + }; + + overrides@12 { + target = <0x116>; + + _overlay_ { + cpu-dai = <0xcf>; + codec-dai = <0x117>; + cpu-dai-name = "DSPK2"; + codec-dai-name = "tas2552-amplifier"; + }; + }; + + overrides@13 { + target = <0x118>; + + _overlay_ { + cpu-dai = <0xcf>; + codec-dai = <0x119>; + cpu-dai-name = "DSPK2"; + codec-dai-name = "tas2552-amplifier"; + }; + }; + + overrides@14 { + target = <0x110>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@15 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@16 { + target = <0x112>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@17 { + target = <0x113>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-e2614-a00@1 { + ids = "2614-0000-000"; + + overrides@0 { + target = <0x11a>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x115>; + + _overlay_ { + codec-dai = <0x11a>; + }; + }; + }; + + fragment-e2614-b00@2 { + ids = "2614-0000-100"; + + overrides@0 { + target = <0x11b>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x115>; + + _overlay_ { + codec-dai = <0x11b>; + }; + }; + }; + + fragment-e3320-a00@1 { + ids = "3320-1000-000", "3320-1100-000"; + + overrides@1 { + target = <0x11c>; + + _overlay_ { + status = "okay"; + + outp { + ti,enable-gpio = <0x40 0x2 0x0>; + }; + + outn { + ti,enable-gpio = <0x40 0x3 0x0>; + }; + }; + }; + + overrides@2 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15200000 { + status = "okay"; + }; + + dsi { + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + }; + }; + + overrides@3 { + target = <0x106>; + + _overlay_ { + + gpio@21 { + status = "okay"; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + status = "okay"; + }; + }; + }; + }; + + fragment-e3320-a01@1 { + ids = "3320-1000-100", "3320-1000-200"; + + overrides@1 { + target = <0x11c>; + + _overlay_ { + status = "okay"; + + outp { + ti,enable-gpio = <0x8d 0x4 0x0>; + }; + + outn { + delete-target-property = "ti,disable-active-discharge"; + ti,enable-gpio = <0x40 0x2 0x0>; + ti,active-discharge-gpio = <0x40 0x3 0x0>; + ti,active-discharge-time = <0x7d0>; + }; + }; + }; + + overrides@2 { + target = <0x85>; + + _overlay_ { + gpio = <0x40 0x0 0x0>; + }; + }; + + overrides@3 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15200000 { + status = "okay"; + }; + + dsi { + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + }; + }; + + overrides@4 { + target = <0x106>; + + _overlay_ { + + gpio@21 { + status = "okay"; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + status = "okay"; + }; + }; + }; + }; + + fragment-e1639-sharp-25x16@2 { + ids = "1639-1000-001"; + + overrides@0 { + target = <0x11d>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x88>; + + _overlay_ { + gpio = <0x28 0xb 0x1>; + enable-active-high; + regulator-boot-on; + regulator-always-on; + }; + }; + + overrides@2 { + target = <0x102>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@3 { + target = <0x11e>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@4 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15200000 { + status = "okay"; + }; + + dsi { + status = "okay"; + }; + }; + }; + }; + + fragment-e1824-a00@3 { + ids = "1824-1100-001"; + + overrides@0 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15200000 { + status = "okay"; + }; + + sor { + status = "okay"; + nvidia,active-panel = <0x11f>; + + panel-s-edp-uhdtv-15-6 { + status = "okay"; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + nvidia,en-vmm-vpp-with-i2c-config; + nvidia,is_ext_dp_panel = <0x0>; + + disp-default-out { + nvidia,out-parent-clk = "plld3"; + }; + + smartdimmer { + status = "okay"; + }; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + }; + }; + }; + + fragment-imx390@0 { + ids = "LPRD-001"; + + override@0 { + target = <0x120>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "imx390_rear"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx390 30-001b"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b"; + }; + }; + + override@3 { + target = <0x123>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x124>; + + _overlay_ { + status = "okay"; + badge = "imx390_front"; + position = "front"; + orientation = [31 00]; + }; + }; + + override@5 { + target = <0x125>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx390 30-001c"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + }; + }; + + override@6 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@7 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@8 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x62>; + + _overlay_ { + status = "okay"; + vc-id = <0x0>; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x6d>; + }; + }; + + override@10 { + target = <0x64>; + + _overlay_ { + status = "okay"; + vc-id = <0x1>; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x6e>; + }; + }; + + override@11 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@12 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@14 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x61>; + }; + }; + + override@15 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@18 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x2d>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x63>; + }; + }; + + override@20 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@22 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0x2>; + max_lane_speed = <0x3d0900>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@23 { + target = <0x130>; + + _overlay_ { + status = "okay"; + vcc-pullup-supply = <0x26>; + }; + }; + + override@24 { + target = <0x32>; + + _overlay_ { + status = "okay"; + }; + }; + + override@25 { + target = <0x131>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x31>; + + _overlay_ { + status = "okay"; + }; + }; + + override@27 { + target = <0x33>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-e3326@0 { + ids = "3326-*"; + + override@0 { + target = <0x132>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "e3326_front_P5V27C"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov5693 2-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov5693_c@36"; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3326_lens_ov5693@P5V27C/"; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x6d>; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x134>; + }; + }; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x62>; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0x4>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@14 { + target = <0x1b>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + gpio-hog; + gpios = <0x8d 0x0 0x88 0x0>; + label = "cam0-rst", "cam0-pwdn"; + output-low; + status = "okay"; + }; + + camera-control-output-high { + status = "disabled"; + }; + }; + }; + + override@15 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + }; + + fragment-e3323@0 { + ids = "3323-1000-*"; + + override@0 { + target = <0x135>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "e3323_bottom_CH06P1"; + position = "bottom"; + orientation = [33 00]; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov23850 2-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov23850_a@10"; + }; + }; + + override@3 { + target = <0x136>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x124>; + + _overlay_ { + status = "okay"; + badge = "e3323_top_CH06P1"; + position = "top"; + orientation = [33 00]; + }; + }; + + override@5 { + target = <0x125>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov23850 1-0036"; + proc-device-tree = "/proc/device-tree/i2c@c240000/ov23850_c@36"; + }; + }; + + override@6 { + target = <0x133>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3323_lens_ov23850@CH06P1/"; + }; + }; + + override@7 { + target = <0x137>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3323_lens_ov23850@CH06P1/"; + }; + }; + + override@8 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x6d>; + }; + }; + + override@11 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x64>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x4>; + remote-endpoint = <0x6e>; + }; + }; + + override@13 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@14 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x138>; + }; + }; + + override@17 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@18 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x62>; + }; + }; + + override@19 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@20 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x2d>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x4>; + remote-endpoint = <0x139>; + }; + }; + + override@22 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@23 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x64>; + }; + }; + + override@24 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0x8>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + max_pixel_rate = <0xb71b0>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@25 { + target = <0x1b>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + gpio-hog; + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x5e 0x0>; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + output-low; + status = "okay"; + }; + + camera-control-output-high { + status = "disabled"; + }; + }; + }; + + override@26 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + }; + + fragment-p3310-c00-camera { + ids = ">=3310-1000-800", ">=3489-0000-200", ">=3489-0888-300"; + + override@1 { + target = <0x136>; + + _overlay_ { + pwdn-gpios = <0x1b 0x6a 0x0>; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-low { + gpio-hog; + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x6a 0x0>; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + output-low; + status = "okay"; + }; + }; + }; + + override@3 { + target = <0x13a>; + + _overlay_ { + pwdn-gpios = <0x1b 0x6a 0x0>; + }; + }; + }; + + fragment-e3333@0 { + ids = "3333-*"; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0xc>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + max_pixel_rate = <0x30d40>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@3 { + target = <0x35>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x13b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x13c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "e3333_bottomleft_P5V27C"; + position = "bottomleft"; + orientation = [31 00]; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov5693 30-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36"; + }; + }; + + override@8 { + target = <0x133>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x6d>; + }; + }; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x13d>; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x62>; + }; + }; + + override@16 { + target = <0x13a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x124>; + + _overlay_ { + status = "okay"; + badge = "e3333_centerleft_P5V27C"; + position = "centerleft"; + orientation = [31 00]; + }; + }; + + override@18 { + target = <0x125>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov5693 31-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36"; + }; + }; + + override@19 { + target = <0x137>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@20 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x64>; + + _overlay_ { + status = "okay"; + port-index = <0x1>; + bus-width = <0x2>; + remote-endpoint = <0x6e>; + }; + }; + + override@22 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@23 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@24 { + target = <0x2d>; + + _overlay_ { + status = "okay"; + port-index = <0x1>; + bus-width = <0x2>; + remote-endpoint = <0x13e>; + }; + }; + + override@25 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x64>; + }; + }; + + override@27 { + target = <0x13f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@28 { + target = <0x140>; + + _overlay_ { + status = "okay"; + badge = "e3333_centerright_P5V27C"; + position = "centerright"; + orientation = [31 00]; + }; + }; + + override@29 { + target = <0x141>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov5693 32-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36"; + }; + }; + + override@30 { + target = <0x142>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@31 { + target = <0x143>; + + _overlay_ { + status = "okay"; + }; + }; + + override@32 { + target = <0x66>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x6f>; + }; + }; + + override@33 { + target = <0x144>; + + _overlay_ { + status = "okay"; + }; + }; + + override@34 { + target = <0x145>; + + _overlay_ { + status = "okay"; + }; + }; + + override@35 { + target = <0x36>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x146>; + }; + }; + + override@36 { + target = <0x147>; + + _overlay_ { + status = "okay"; + }; + }; + + override@37 { + target = <0x6f>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x66>; + }; + }; + + override@38 { + target = <0x148>; + + _overlay_ { + status = "okay"; + }; + }; + + override@39 { + target = <0x149>; + + _overlay_ { + status = "okay"; + badge = "e3333_topleft_P5V27C"; + position = "topleft"; + orientation = [31 00]; + }; + }; + + override@40 { + target = <0x14a>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov5693 33-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36"; + }; + }; + + override@41 { + target = <0x14b>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@42 { + target = <0x14c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@43 { + target = <0x68>; + + _overlay_ { + status = "okay"; + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x70>; + }; + }; + + override@44 { + target = <0x14d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@45 { + target = <0x14e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@46 { + target = <0x37>; + + _overlay_ { + status = "okay"; + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x14f>; + }; + }; + + override@47 { + target = <0x150>; + + _overlay_ { + status = "okay"; + }; + }; + + override@48 { + target = <0x70>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x68>; + }; + }; + + override@49 { + target = <0x151>; + + _overlay_ { + status = "okay"; + }; + }; + + override@50 { + target = <0x152>; + + _overlay_ { + status = "okay"; + badge = "e3333_bottomright_P5V27C"; + position = "bottomright"; + orientation = [31 00]; + }; + }; + + override@51 { + target = <0x153>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov5693 34-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36"; + }; + }; + + override@52 { + target = <0x154>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@53 { + target = <0x155>; + + _overlay_ { + status = "okay"; + }; + }; + + override@54 { + target = <0x6a>; + + _overlay_ { + status = "okay"; + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x71>; + }; + }; + + override@55 { + target = <0x156>; + + _overlay_ { + status = "okay"; + }; + }; + + override@56 { + target = <0x157>; + + _overlay_ { + status = "okay"; + }; + }; + + override@57 { + target = <0x38>; + + _overlay_ { + status = "okay"; + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x158>; + }; + }; + + override@58 { + target = <0x159>; + + _overlay_ { + status = "okay"; + }; + }; + + override@59 { + target = <0x71>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x6a>; + }; + }; + + override@60 { + target = <0x15a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@61 { + target = <0x15b>; + + _overlay_ { + status = "okay"; + badge = "e3333_topright_P5V27C"; + position = "topright"; + orientation = [31 00]; + }; + }; + + override@62 { + target = <0x15c>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "ov5693 35-0036"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36"; + }; + }; + + override@63 { + target = <0x15d>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@64 { + target = <0x15e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@65 { + target = <0x6c>; + + _overlay_ { + status = "okay"; + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x72>; + }; + }; + + override@66 { + target = <0x15f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@67 { + target = <0x160>; + + _overlay_ { + status = "okay"; + }; + }; + + override@68 { + target = <0x39>; + + _overlay_ { + status = "okay"; + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x161>; + }; + }; + + override@69 { + target = <0x162>; + + _overlay_ { + status = "okay"; + }; + }; + + override@70 { + target = <0x72>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x6c>; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + gpio-hog; + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x5e 0x0>; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + output-low; + status = "disabled"; + }; + + camera-control-output-high { + status = "disabled"; + }; + }; + }; + + override@712 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + status = "okay"; + }; + + camera-control-output-high { + status = "okay"; + }; + }; + }; + + override@72 { + target = <0x35>; + + _overlay_ { + + tca6408_21_input { + status = "disabled"; + }; + + tca6408_21_outlow { + gpio-hog; + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0 0x6 0x0 0x7 0x0>; + output-low; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5", "tca6408_21_outlow_6", "tca6408_21_outlow_7"; + status = "okay"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + }; + + override@73 { + target = <0x59>; + + _overlay_ { + compatible = "nvidia,tegra186-i2c"; + }; + }; + }; + + fragment-e3322@0 { + ids = "3322-*"; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0xc>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@3 { + target = <0x35>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x13b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x163>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "e3322_bottomleft_P5V27C"; + position = "bottomleft"; + orientation = [31 00]; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx219 30-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@0/imx219_a@10"; + }; + }; + + override@8 { + target = <0x133>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x6d>; + }; + }; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x2>; + remote-endpoint = <0x164>; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x62>; + }; + }; + + override@16 { + target = <0x165>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x124>; + + _overlay_ { + status = "okay"; + badge = "e3322_centerleft_P5V27C"; + position = "centerleft"; + orientation = [31 00]; + }; + }; + + override@18 { + target = <0x125>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx219 31-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/imx219_b@10"; + }; + }; + + override@19 { + target = <0x137>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + }; + }; + + override@20 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x64>; + + _overlay_ { + status = "okay"; + port-index = <0x1>; + bus-width = <0x2>; + remote-endpoint = <0x6e>; + }; + }; + + override@22 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@23 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@24 { + target = <0x2d>; + + _overlay_ { + status = "okay"; + port-index = <0x1>; + bus-width = <0x2>; + remote-endpoint = <0x166>; + }; + }; + + override@25 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x64>; + }; + }; + + override@27 { + target = <0x167>; + + _overlay_ { + status = "okay"; + }; + }; + + override@28 { + target = <0x140>; + + _overlay_ { + status = "okay"; + badge = "e3322_centerright_P5V27C"; + position = "centerright"; + orientation = [31 00]; + }; + }; + + override@29 { + target = <0x141>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx219 32-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + }; + }; + + override@30 { + target = <0x142>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + }; + }; + + override@31 { + target = <0x143>; + + _overlay_ { + status = "okay"; + }; + }; + + override@32 { + target = <0x66>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x6f>; + }; + }; + + override@33 { + target = <0x144>; + + _overlay_ { + status = "okay"; + }; + }; + + override@34 { + target = <0x145>; + + _overlay_ { + status = "okay"; + }; + }; + + override@35 { + target = <0x36>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x2>; + remote-endpoint = <0x65>; + }; + }; + + override@36 { + target = <0x147>; + + _overlay_ { + status = "okay"; + }; + }; + + override@37 { + target = <0x6f>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x66>; + }; + }; + + override@38 { + target = <0x168>; + + _overlay_ { + status = "okay"; + }; + }; + + override@39 { + target = <0x149>; + + _overlay_ { + status = "okay"; + badge = "e3322_topleft_P5V27C"; + position = "topleft"; + orientation = [31 00]; + }; + }; + + override@40 { + target = <0x14a>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx219 33-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + }; + }; + + override@41 { + target = <0x14b>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + }; + }; + + override@42 { + target = <0x14c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@43 { + target = <0x68>; + + _overlay_ { + status = "okay"; + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x70>; + }; + }; + + override@44 { + target = <0x14d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@45 { + target = <0x14e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@46 { + target = <0x37>; + + _overlay_ { + status = "okay"; + port-index = <0x3>; + bus-width = <0x2>; + remote-endpoint = <0x67>; + }; + }; + + override@47 { + target = <0x150>; + + _overlay_ { + status = "okay"; + }; + }; + + override@48 { + target = <0x70>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x68>; + }; + }; + + override@49 { + target = <0x169>; + + _overlay_ { + status = "okay"; + }; + }; + + override@50 { + target = <0x152>; + + _overlay_ { + status = "okay"; + badge = "e3322_bottomright_P5V27C"; + position = "bottomright"; + orientation = [31 00]; + }; + }; + + override@51 { + target = <0x153>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx219 34-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + }; + }; + + override@52 { + target = <0x154>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + }; + }; + + override@53 { + target = <0x155>; + + _overlay_ { + status = "okay"; + }; + }; + + override@54 { + target = <0x6a>; + + _overlay_ { + status = "okay"; + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x71>; + }; + }; + + override@55 { + target = <0x156>; + + _overlay_ { + status = "okay"; + }; + }; + + override@56 { + target = <0x157>; + + _overlay_ { + status = "okay"; + }; + }; + + override@57 { + target = <0x38>; + + _overlay_ { + status = "okay"; + port-index = <0x4>; + bus-width = <0x2>; + remote-endpoint = <0x69>; + }; + }; + + override@58 { + target = <0x159>; + + _overlay_ { + status = "okay"; + }; + }; + + override@59 { + target = <0x71>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x6a>; + }; + }; + + override@60 { + target = <0x16a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@61 { + target = <0x15b>; + + _overlay_ { + status = "okay"; + badge = "e3322_topright_P5V27C"; + position = "topright"; + orientation = [31 00]; + }; + }; + + override@62 { + target = <0x15c>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx219 35-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + }; + }; + + override@63 { + target = <0x15d>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + }; + }; + + override@64 { + target = <0x15e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@65 { + target = <0x6c>; + + _overlay_ { + status = "okay"; + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x72>; + }; + }; + + override@66 { + target = <0x15f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@67 { + target = <0x160>; + + _overlay_ { + status = "okay"; + }; + }; + + override@68 { + target = <0x39>; + + _overlay_ { + status = "okay"; + port-index = <0x5>; + bus-width = <0x2>; + remote-endpoint = <0x6b>; + }; + }; + + override@69 { + target = <0x162>; + + _overlay_ { + status = "okay"; + }; + }; + + override@70 { + target = <0x72>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x6c>; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + gpio-hog; + gpios = <0x88 0x0>; + label = "cam0-pwdn"; + output-low; + status = "okay"; + }; + + camera-control-output-high { + gpio-hog; + gpios = <0x8d 0x0>; + label = "cam0-rst"; + output-high; + status = "okay"; + }; + }; + }; + + override@712 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@72 { + target = <0x35>; + + _overlay_ { + + tca6408_21_input { + gpio-hog; + gpios = <0x6 0x0 0x7 0x0>; + input; + label = "tca6408_21_input_6", "tca6408_21_input_7"; + status = "okay"; + }; + + tca6408_21_outlow { + gpio-hog; + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0>; + output-low; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5"; + status = "okay"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + }; + }; + + fragment-imx185@0 { + ids = "LPRD-002001"; + + override@0 { + target = <0x16b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "imx185_bottom_liimx185"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx185 30-001a"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a"; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x6d>; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x16c>; + }; + }; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x62>; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0x4>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@14 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x16d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x120>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@17 { + target = <0x123>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@18 { + target = <0x124>; + + _overlay_ { + status = "disabled"; + }; + }; + }; + + fragment-imx274@0 { + ids = "LPRD-002002"; + + override@0 { + target = <0x16e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "imx274_bottom_A6V26"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx274 30-001a"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x6d>; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x16f>; + }; + }; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x62>; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0x4>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@14 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x1b>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-output-high { + gpio-hog; + gpios = <0x8d 0x0>; + label = "cam0-rst"; + output-high; + status = "okay"; + }; + }; + }; + + override@16 { + target = <0x16d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x120>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@18 { + target = <0x123>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@19 { + target = <0x124>; + + _overlay_ { + status = "disabled"; + }; + }; + }; + + fragment-imx274-dual@0 { + ids = "LPRD-dual-imx274-002"; + + override@0 { + target = <0x16e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "imx274_bottom_A6V26"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx274 30-001a"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + + override@4 { + target = <0x170>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x124>; + + _overlay_ { + status = "okay"; + badge = "imx274_top_A6V26"; + position = "top"; + orientation = [30 00]; + }; + }; + + override@6 { + target = <0x125>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx274 31-001a"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a"; + }; + }; + + override@7 { + target = <0x137>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_lens"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + + override@8 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@11 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x6d>; + }; + }; + + override@12 { + target = <0x64>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x4>; + remote-endpoint = <0x6e>; + }; + }; + + override@13 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@14 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x4>; + remote-endpoint = <0x16f>; + }; + }; + + override@17 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@18 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@20 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x2d>; + + _overlay_ { + status = "okay"; + port-index = <0x2>; + bus-width = <0x4>; + remote-endpoint = <0x171>; + }; + }; + + override@22 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@23 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@24 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0x8>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@25 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x1b>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-output-high { + gpio-hog; + gpios = <0x8d 0x0 0x88 0x0>; + label = "cam0-rst", "cam1-rst"; + output-high; + status = "okay"; + }; + }; + }; + }; + + fragment-e3331@0 { + ids = "3331-*"; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + num_csi_lanes = <0x3>; + max_lane_speed = <0x16e360>; + min_bits_per_pixel = <0xa>; + vi_peak_byte_per_pixel = <0x2>; + vi_bw_margin_pct = <0x19>; + max_pixel_rate = <0x27100>; + isp_peak_byte_per_pixel = <0x5>; + isp_bw_margin_pct = <0x19>; + }; + }; + + override@4 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x172>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + status = "okay"; + badge = "e3331_rear_22N02A"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + status = "okay"; + pcl_id = "v4l2_sensor"; + devname = "imx318 30-0010"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx318_a@10"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x3>; + remote-endpoint = <0x6d>; + }; + }; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + status = "okay"; + port-index = <0x0>; + bus-width = <0x3>; + remote-endpoint = <0x173>; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + remote-endpoint = <0x62>; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + + camera-control-output-low { + gpio-hog; + gpios = <0x8d 0x0>; + label = "cam0-rst"; + output-low; + status = "disabled"; + }; + + camera-control-output-high { + status = "disabled"; + }; + }; + }; + }; + }; + + eeprom-manager { + data-size = <0x100>; + boardid-with-revision = <0xcee>; + boardid-with-config = <0xcee>; + + bus@0 { + i2c-bus = <0x174>; + + eeprom@0 { + slave-address = <0x50>; + label = "cvm"; + }; + + eeprom@1 { + slave-address = <0x57>; + label = "cvb"; + }; + }; + + bus@1 { + i2c-bus = <0x175>; + + eeprom@0 { + slave-address = <0x51>; + }; + }; + + bus@2 { + i2c-bus = <0x106>; + + eeprom@0 { + slave-address = <0x50>; + }; + }; + + bus@3 { + i2c-bus = <0x59>; + + eeprom@0 { + slave-address = <0x54>; + label = "cam"; + enable-gpio = <0x2 0x9>; + }; + + eeprom@1 { + slave-address = <0x57>; + label = "cam"; + enable-gpio = <0x2 0x9>; + }; + }; + }; + + gps_wake { + compatible = "gps-wake"; + gps-enable-gpio = <0xea 0x8 0x0>; + gps-wakeup-gpio = <0x1b 0x85 0x0>; + status = "disabled"; + linux,phandle = <0x1e6>; + phandle = <0x1e6>; + }; + + chosen { + ecid = "00000001646db7851000000011000540"; + nvidia,ether-mac = "48:b0:2d:0f:30:57"; + nvidia,bluetooth-mac = "48:b0:2d:0f:30:56"; + nvidia,wifi-mac = "48:b0:2d:0f:30:55"; + board-has-eeprom; + bootargs = "earlycon=uart8250,mmio32,0x3100000 console=ttyS0,115200n8 root=/dev/sda1 rw audit=0 default_hugepagesz=32M hugepagesz=32M hugepages=4"; + stdout-path = "/serial@3100000"; + nvidia,tegra-joint_xpu_rail; + + reset { + + pmic-reset-reason { + reason = "NIL_OR_MORE_THAN_1_BIT"; + register-value = "0x50"; + }; + + pmc-reset-reason { + reset-level = [30 00]; + reset-source = "SYS_RESET_N"; + }; + }; + + plugin-manager { + cvm = "3310-1000-D00"; + + odm-data { + enable-sata-on-uphy-lane5 = <0x1>; + enable-pcie-on-uphy-lane4 = <0x1>; + enable-pcie-on-uphy-lane2 = <0x1>; + enable-pcie-on-uphy-lane1 = <0x1>; + enable-xusb-on-uphy-lane0 = <0x1>; + normal-flashed = <0x1>; + no-battery = <0x1>; + disable-sdmmc-hwcq = <0x1>; + disable-pmic-wdt = <0x1>; + enable-denver-wdt = <0x1>; + android-build = <0x1>; + enable-debug-console = <0x1>; + disable-tegra-wdt = <0x1>; + }; + + chip-id { + A02P = <0x1>; + }; + + configs { + 3310-display-config = <0x0>; + 3310-touch-config = <0x0>; + 3310-modem-config = <0x0>; + 3310-misc-config = <0x0>; + 3310-power-config = <0x0>; + 3310-mem-type = <0x0>; + }; + + ids { + 3310-1000-D00-L = <0x1>; + 3326-1000-000 = "/i2c@3180000:module@0x54"; + 2597-0000-900 = "/i2c@c250000:module@0x57"; + 3310-1000-D00 = "/i2c@c250000:module@0x50"; + + connection { + + i2c@3180000 { + + module@0x54 { + 3326-1000-000 = "/i2c@3180000:module@0x54"; + }; + }; + + i2c@c250000 { + + module@0x57 { + 2597-0000-900 = "/i2c@c250000:module@0x57"; + }; + + module@0x50 { + 3310-1000-D00 = "/i2c@c250000:module@0x50"; + }; + }; + }; + }; + }; + }; + + firmware { + + android { + serialno = "1422420073060"; + compatible = "android,firmware"; + hardware = "quill"; + + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,kernel,kernel-dtb,kernel-dtbo,APP,vendor,SOS"; + }; + + fstab { + compatible = "android,fstab"; + + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/3460000.sdhci/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro"; + fsmgr_flags = "wait,avb"; + }; + + odm { + compatible = "android,odm"; + dev = "/dev/block/platform/3460000.sdhci/by-name/odm"; + type = "ext4"; + mnt_flags = "ro"; + fsmgr_flags = "wait,avb"; + }; + }; + }; + }; + + tegra_udrm { + compatible = "nvidia,tegra-udrm"; + linux,phandle = <0x1e7>; + phandle = <0x1e7>; + }; + + __symbols__ { + A57_CORE_POWER_STATES = "/cpus/a57_core_power_states"; + A57_C1 = "/cpus/a57_core_power_states/c1"; + A57_C7 = "/cpus/a57_core_power_states/c7"; + DENVER_CORE_POWER_STATES = "/cpus/denver_core_power_states"; + DENVER_C1 = "/cpus/denver_core_power_states/c1"; + DENVER_C6 = "/cpus/denver_core_power_states/c6"; + DENVER_C7 = "/cpus/denver_core_power_states/c7"; + denver_0 = "/cpus/cpu@0"; + denver_1 = "/cpus/cpu@1"; + cpu_a57_0 = "/cpus/cpu@2"; + cpu_a57_1 = "/cpus/cpu@3"; + cpu_a57_2 = "/cpus/cpu@4"; + cpu_a57_3 = "/cpus/cpu@5"; + L2_A57 = "/cpus/l2-cache0"; + L2_DENVER = "/cpus/l2-cache1"; + CPU_COST_DENVER = "/energy-costs/core-cost0"; + CPU_COST_A57 = "/energy-costs/core-cost1"; + tegra_pmc = "/pmc@c360000"; + sdmmc1_e_33V_enable = "/pmc@c360000/sdmmc1_e_33V_enable"; + sdmmc1_e_33V_disable = "/pmc@c360000/sdmmc1_e_33V_disable"; + sdmmc2_e_33V_enable = "/pmc@c360000/sdmmc2_e_33V_enable"; + sdmmc2_e_33V_disable = "/pmc@c360000/sdmmc2_e_33V_disable"; + sdmmc3_e_33V_enable = "/pmc@c360000/sdmmc3_e_33V_enable"; + sdmmc3_e_33V_disable = "/pmc@c360000/sdmmc3_e_33V_disable"; + ufs_dpd_enable = "/pmc@c360000/dpd-enable"; + ufs_dpd_disable = "/pmc@c360000/dpd-disable"; + iopad_default = "/pmc@c360000/iopad-defaults"; + hdmi_dp0_dpd_enable = "/pmc@c360000/hdmi-dp0-dpd-enable"; + hdmi_dp0_dpd_disable = "/pmc@c360000/hdmi-dp0-dpd-disable"; + hdmi_dp1_dpd_enable = "/pmc@c360000/hdmi-dp1-dpd-enable"; + hdmi_dp1_dpd_disable = "/pmc@c360000/hdmi-dp1-dpd-disable"; + dsi_dpd_enable = "/pmc@c360000/dsi-dpd-enable"; + dsi_dpd_disable = "/pmc@c360000/dsi-dpd-disable"; + dsib_dpd_enable = "/pmc@c360000/dsib-dpd-enable"; + dsib_dpd_disable = "/pmc@c360000/dsib-dpd-disable"; + dsic_dpd_enable = "/pmc@c360000/dsic-dpd-enable"; + dsic_dpd_disable = "/pmc@c360000/dsic-dpd-disable"; + dsid_dpd_enable = "/pmc@c360000/dsid-dpd-enable"; + dsid_dpd_disable = "/pmc@c360000/dsid-dpd-disable"; + sdmmc4 = "/sdhci@3460000"; + sdmmc3 = "/sdhci@3440000"; + sdmmc2 = "/sdhci@3420000"; + sdmmc1 = "/sdhci@3400000"; + pinmux = "/pinmux@2430000"; + tegra_pinctrl = "/pinmux@2430000"; + devslp_active_state = "/pinmux@2430000/devslp_active"; + devslp_pullup_state = "/pinmux@2430000/devslp_pullup"; + eqos_tx_tri_state_idle = "/pinmux@2430000/eqos_idle"; + eqos_tx_tri_state_default = "/pinmux@2430000/eqos_default"; + vbus_en0_sfio_tristate_state = "/pinmux@2430000/vbus_en0_oc_tristate"; + vbus_en1_sfio_tristate_state = "/pinmux@2430000/vbus_en1_oc_tristate"; + vbus_en0_sfio_passthrough_state = "/pinmux@2430000/vbus_en0_oc_passthrough"; + vbus_en1_sfio_passthrough_state = "/pinmux@2430000/vbus_en1_oc_passthrough"; + vbus_en0_default_state = "/pinmux@2430000/vbus_en0_default"; + vbus_en1_default_state = "/pinmux@2430000/vbus_en1_default"; + pinmux_default = "/pinmux@2430000/common"; + tegra_sata = "/ahci-sata@3507000"; + tegra_ufs = "/ufshci@2450000"; + hdr40_i2c0 = "/i2c@3160000"; + gen1_i2c = "/i2c@3160000"; + lp8557_backlight = "/i2c@3160000/lp8557-backlight-s-wuxga-8-0@2c"; + ina3221x_40 = "/i2c@3160000/ina3221x@40"; + ina3221x_41 = "/i2c@3160000/ina3221x@41"; + gpio_i2c_0_74 = "/i2c@3160000/gpio@74"; + gpio_i2c_0_77 = "/i2c@3160000/gpio@77"; + gpio_i2c_0_21 = "/i2c@3160000/gpio@21"; + vpp_lcd = "/i2c@3160000/tps65132@3e/outp"; + vmm_lcd = "/i2c@3160000/tps65132@3e/outn"; + hdr40_i2c1 = "/i2c@c240000"; + gen2_i2c = "/i2c@c240000"; + lp8556_backlight = "/i2c@c240000/lp8556-backlight-s-wqxga-10-1@2c"; + e3323_cam1 = "/i2c@c240000/ov23850_c@36"; + e3323_ov23850_out1 = "/i2c@c240000/ov23850_c@36/ports/port@0/endpoint"; + e2614_i2c_mux = "/i2c@c240000/i2cmux@70"; + e2614_tas2552_r = "/i2c@c240000/i2cmux@70/i2c@0/tas2552.9-0040@40"; + e2614_tas2552_l = "/i2c@c240000/i2cmux@70/i2c@0/tas2552.9-0041@41"; + e2614_rt5658_i2c3 = "/i2c@c240000/i2cmux@70/i2c@3/rt5659.12-001a@1a"; + e2614_gpio_i2c_1_20 = "/i2c@c240000/gpio@20"; + e2614_icm20628 = "/i2c@c240000/icm20628@68"; + e2614_ak8963 = "/i2c@c240000/ak8963@0d"; + e2614_bmp280 = "/i2c@c240000/bmp280@77"; + e2614_cm32180 = "/i2c@c240000/cm32180@48"; + e2614_iqs263 = "/i2c@c240000/iqs263@44"; + e2614_rt5658 = "/i2c@c240000/rt5659.1-001a@1a"; + cam_i2c = "/i2c@3180000"; + e3326_cam0 = "/i2c@3180000/ov5693_c@36"; + e3326_ov5693_out0 = "/i2c@3180000/ov5693_c@36/ports/port@0/endpoint"; + e3323_cam0 = "/i2c@3180000/ov23850_a@10"; + e3323_ov23850_out0 = "/i2c@3180000/ov23850_a@10/ports/port@0/endpoint"; + tca9546_70 = "/i2c@3180000/tca9546@70"; + e3331_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx318_a@10"; + e3331_imx318_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx318_a@10/ports/port@0/endpoint"; + imx185_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a"; + liimx185_imx185_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a/ports/port@0/endpoint"; + pca9570_a_24 = "/i2c@3180000/tca9546@70/i2c@0/pca9570_a@24"; + imx274_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + liimx274_imx274_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a/ports/port@0/endpoint"; + imx390_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b"; + imx390_imx390_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b/ports/port@0/endpoint"; + imx390_cam1 = "/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + imx390_imx390_out1 = "/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c/ports/port@0/endpoint"; + max9296_dser = "/i2c@3180000/tca9546@70/i2c@0/max9296@48"; + dser = "/i2c@3180000/tca9546@70/i2c@0/max9296@48"; + max9295_prim = "/i2c@3180000/tca9546@70/i2c@0/max9295_prim@62"; + ser_prim = "/i2c@3180000/tca9546@70/i2c@0/max9295_prim@62"; + max9295_ser0 = "/i2c@3180000/tca9546@70/i2c@0/max9295_a@40"; + ser_a = "/i2c@3180000/tca9546@70/i2c@0/max9295_a@40"; + max9295_ser1 = "/i2c@3180000/tca9546@70/i2c@0/max9295_b@60"; + ser_b = "/i2c@3180000/tca9546@70/i2c@0/max9295_b@60"; + imx274_cam1 = "/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a"; + liimx274_imx274_out1 = "/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a/ports/port@0/endpoint"; + tca9548_77 = "/i2c@3180000/tca9548@77"; + e3333_cam0 = "/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36"; + e3333_ov5693_out0 = "/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36/ports/port@0/endpoint"; + e3322_cam0 = "/i2c@3180000/tca9548@77/i2c@0/imx219_a@10"; + e3322_imx219_out0 = "/i2c@3180000/tca9548@77/i2c@0/imx219_a@10/ports/port@0/endpoint"; + e3333_cam1 = "/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36"; + e3333_ov5693_out1 = "/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36/ports/port@0/endpoint"; + e3322_cam1 = "/i2c@3180000/tca9548@77/i2c@1/imx219_b@10"; + e3322_imx219_out1 = "/i2c@3180000/tca9548@77/i2c@1/imx219_b@10/ports/port@0/endpoint"; + e3333_cam2 = "/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36"; + e3333_ov5693_out2 = "/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36/ports/port@0/endpoint"; + e3322_cam2 = "/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + e3322_imx219_out2 = "/i2c@3180000/tca9548@77/i2c@2/imx219_c@10/ports/port@0/endpoint"; + e3333_cam3 = "/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36"; + e3333_ov5693_out3 = "/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36/ports/port@0/endpoint"; + e3322_cam3 = "/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + e3322_imx219_out3 = "/i2c@3180000/tca9548@77/i2c@3/imx219_d@10/ports/port@0/endpoint"; + e3333_cam4 = "/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36"; + e3333_ov5693_out4 = "/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36/ports/port@0/endpoint"; + e3322_cam4 = "/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + e3322_imx219_out4 = "/i2c@3180000/tca9548@77/i2c@4/imx219_e@10/ports/port@0/endpoint"; + e3333_cam5 = "/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36"; + e3333_ov5693_out5 = "/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36/ports/port@0/endpoint"; + e3322_cam5 = "/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + e3322_imx219_out5 = "/i2c@3180000/tca9548@77/i2c@5/imx219_f@10/ports/port@0/endpoint"; + tca6408_21 = "/i2c@3180000/tca6408@21"; + dp_aux_ch1_i2c = "/i2c@3190000"; + pwr_i2c = "/bpmp_i2c"; + spmic = "/bpmp_i2c/spmic@3c"; + spmic_default = "/bpmp_i2c/spmic@3c/pinmux@0"; + spmic_wdt = "/bpmp_i2c/spmic@3c/watchdog"; + spmic_sd0 = "/bpmp_i2c/spmic@3c/regulators/sd0"; + spmic_sd1 = "/bpmp_i2c/spmic@3c/regulators/sd1"; + spmic_sd2 = "/bpmp_i2c/spmic@3c/regulators/sd2"; + spmic_sd3 = "/bpmp_i2c/spmic@3c/regulators/sd3"; + spmic_ldo0 = "/bpmp_i2c/spmic@3c/regulators/ldo0"; + spmic_ldo1 = "/bpmp_i2c/spmic@3c/regulators/ldo1"; + spmic_ldo2 = "/bpmp_i2c/spmic@3c/regulators/ldo2"; + spmic_ldo3 = "/bpmp_i2c/spmic@3c/regulators/ldo3"; + spmic_ldo4 = "/bpmp_i2c/spmic@3c/regulators/ldo4"; + spmic_ldo5 = "/bpmp_i2c/spmic@3c/regulators/ldo5"; + spmic_ldo6 = "/bpmp_i2c/spmic@3c/regulators/ldo6"; + spmic_ldo7 = "/bpmp_i2c/spmic@3c/regulators/ldo7"; + spmic_ldo8 = "/bpmp_i2c/spmic@3c/regulators/ldo8"; + dp_aux_ch0_i2c = "/i2c@31b0000"; + gen7_i2c = "/i2c@31c0000"; + gen8_i2c = "/i2c@c250000"; + tegra_tmp451 = "/i2c@c250000/temp-sensor@4c"; + gen9_i2c = "/i2c@31e0000"; + spdif_dit0 = "/spdif_dit/spdif-dit.0@0"; + spdif_dit1 = "/spdif_dit/spdif-dit.1@1"; + spdif_dit2 = "/spdif_dit/spdif-dit.2@2"; + spdif_dit3 = "/spdif_dit/spdif-dit.3@3"; + spdif_dit4 = "/spdif_dit/spdif-dit.4@4"; + spdif_dit5 = "/spdif_dit/spdif-dit.5@5"; + spdif_dit6 = "/spdif_dit/spdif-dit.6@6"; + spdif_dit7 = "/spdif_dit/spdif-dit.7@7"; + spdif_dit8 = "/spdif_dit/spdif-dit.8@8"; + spdif_dit9 = "/spdif_dit/spdif-dit.9@9"; + spdif_dit10 = "/spdif_dit/spdif-dit.10@a"; + spdif_dit11 = "/spdif_dit/spdif-dit.11@b"; + spdif_dit12 = "/spdif_dit/spdif-dit.12@c"; + spdif_dit13 = "/spdif_dit/spdif-dit.13@d"; + spi0 = "/spi@3210000"; + spi1 = "/spi@c260000"; + spi2 = "/spi@3230000"; + spi3 = "/spi@3240000"; + qspi6 = "/spi@3270000"; + aon_spi = "/aon_spi@c260000"; + tegra_pwm1 = "/pwm@3280000"; + tegra_pwm2 = "/pwm@3290000"; + tegra_pwm3 = "/pwm@32a0000"; + tegra_pwm4 = "/pwm@c340000"; + tegra_pwm5 = "/pwm@32c0000"; + tegra_pwm6 = "/pwm@32d0000"; + tegra_pwm7 = "/pwm@32e0000"; + tegra_pwm8 = "/pwm@32f0000"; + uarta = "/serial@3100000"; + uartb = "/serial@3110000"; + uartc = "/serial@c280000"; + uartd = "/serial@3130000"; + uarte = "/serial@3140000"; + uartf = "/serial@3150000"; + uartg = "/serial@c290000"; + eqos_cool_dev = "/ether_qos@2490000/eqos-cool-dev"; + phy0 = "/ether_qos@2490000/mdio/ethernet-phy@0"; + ape_pd = "/power-domain/ape-pd"; + adsp_pd = "/power-domain/adsp-pd"; + pcie_pd = "/power-domain/pcie-pd"; + sata_pd = "/power-domain/sata-pd"; + disa_pd = "/power-domain/disa-pd"; + disb_pd = "/power-domain/disb-pd"; + disc_pd = "/power-domain/disc-pd"; + xusba_pd = "/power-domain/xusba-pd"; + xusbb_pd = "/power-domain/xusbb-pd"; + xusbc_pd = "/power-domain/xusbc-pd"; + IPI = "/interrupt-controller"; + eqos_m40 = "/thermal-zones/GPU-therm/trips/eqos-m40@-40000"; + eqos_m5 = "/thermal-zones/GPU-therm/trips/eqos-m5@-5000"; + eqos_p30 = "/thermal-zones/GPU-therm/trips/eqos-p30@30000"; + eqos_p65 = "/thermal-zones/GPU-therm/trips/eqos-p65@65000"; + eqos_p100 = "/thermal-zones/GPU-therm/trips/eqos-p100@100000"; + aotag = "/thermal-zones/AO-therm"; + Tboard_tegra = "/thermal-zones/Tboard_tegra"; + Tdiode_tegra = "/thermal-zones/Tdiode_tegra"; + die_temp_thresh = "/thermal-zones/PMIC-Die/trips/hot-die"; + tegra_sce = "/rtcpu@b000000"; + tegra_rtcpu_sce_trace = "/tegra-rtcpu-sce-trace"; + tegra_sce_ivc = "/sce-ivc-channels"; + tegra_ape = "/aconnect@2a41000/rtcpu@2993000"; + tegra_agic = "/aconnect@2a41000/agic-controller@2a41000"; + tegra_agic_1 = "/aconnect@2a41000/agic-controller@2a51000"; + tegra_agic_2 = "/aconnect@2a41000/agic-controller@2a61000"; + ape_hsp = "/aconnect@2a41000/tegra-hsp@29a0000"; + adma = "/aconnect@2a41000/adma@2930000"; + tegra_axbar = "/aconnect@2a41000/ahub"; + tegra_admaif = "/aconnect@2a41000/ahub/admaif@290f000"; + tegra_sfc1 = "/aconnect@2a41000/ahub/sfc@2902000"; + tegra_sfc2 = "/aconnect@2a41000/ahub/sfc@2902200"; + tegra_sfc3 = "/aconnect@2a41000/ahub/sfc@2902400"; + tegra_sfc4 = "/aconnect@2a41000/ahub/sfc@2902600"; + tegra_spkprot = "/aconnect@2a41000/ahub/spkprot@2908c00"; + tegra_amixer = "/aconnect@2a41000/ahub/amixer@290bb00"; + tegra_i2s1 = "/aconnect@2a41000/ahub/i2s@2901000"; + tegra_i2s2 = "/aconnect@2a41000/ahub/i2s@2901100"; + tegra_i2s3 = "/aconnect@2a41000/ahub/i2s@2901200"; + tegra_i2s4 = "/aconnect@2a41000/ahub/i2s@2901300"; + tegra_i2s5 = "/aconnect@2a41000/ahub/i2s@2901400"; + tegra_i2s6 = "/aconnect@2a41000/ahub/i2s@2901500"; + tegra_amx1 = "/aconnect@2a41000/ahub/amx@2903000"; + tegra_amx2 = "/aconnect@2a41000/ahub/amx@2903100"; + tegra_amx3 = "/aconnect@2a41000/ahub/amx@2903200"; + tegra_amx4 = "/aconnect@2a41000/ahub/amx@2903300"; + tegra_adx1 = "/aconnect@2a41000/ahub/adx@2903800"; + tegra_adx2 = "/aconnect@2a41000/ahub/adx@2903900"; + tegra_adx3 = "/aconnect@2a41000/ahub/adx@2903a00"; + tegra_adx4 = "/aconnect@2a41000/ahub/adx@2903b00"; + tegra_dmic1 = "/aconnect@2a41000/ahub/dmic@2904000"; + tegra_dmic2 = "/aconnect@2a41000/ahub/dmic@2904100"; + tegra_dmic3 = "/aconnect@2a41000/ahub/dmic@2904200"; + tegra_dmic4 = "/aconnect@2a41000/ahub/dmic@2904300"; + tegra_afc1 = "/aconnect@2a41000/ahub/afc@2907000"; + tegra_afc2 = "/aconnect@2a41000/ahub/afc@2907100"; + tegra_afc3 = "/aconnect@2a41000/ahub/afc@2907200"; + tegra_afc4 = "/aconnect@2a41000/ahub/afc@2907300"; + tegra_afc5 = "/aconnect@2a41000/ahub/afc@2907400"; + tegra_afc6 = "/aconnect@2a41000/ahub/afc@2907500"; + tegra_mvc1 = "/aconnect@2a41000/ahub/mvc@290a000"; + tegra_mvc2 = "/aconnect@2a41000/ahub/mvc@290a200"; + tegra_iqc1 = "/aconnect@2a41000/ahub/iqc@290e000"; + tegra_asrc = "/aconnect@2a41000/ahub/asrc@2910000"; + tegra_arad = "/aconnect@2a41000/ahub/arad@290e400"; + tegra_ahc = "/aconnect@2a41000/ahub/ahc@290b900"; + tegra_ope1 = "/aconnect@2a41000/ahub/ope@2908000"; + tegra_dspk1 = "/aconnect@2a41000/ahub/dspk@2905000"; + tegra_dspk2 = "/aconnect@2a41000/ahub/dspk@2905100"; + tegra_adsp_audio = "/aconnect@2a41000/adsp_audio"; + tegra_rtcpu_ape_trace = "/tegra-rtcpu-ape-trace"; + tegra_ape_ivc = "/ape-ivc-channels"; + tegra_safety_ivc = "/tegra_safety_ivc"; + tegra_safety = "/sce@b000000"; + host1x = "/host1x"; + disp_imp_table = "/host1x/disp_imp_table"; + host1x_ctx0 = "/host1x/ctx0"; + host1x_ctx1 = "/host1x/ctx1"; + host1x_ctx2 = "/host1x/ctx2"; + host1x_ctx3 = "/host1x/ctx3"; + host1x_ctx4 = "/host1x/ctx4"; + host1x_ctx5 = "/host1x/ctx5"; + host1x_ctx6 = "/host1x/ctx6"; + host1x_ctx7 = "/host1x/ctx7"; + csi_base = "/host1x/nvcsi@150c0000"; + csi_chan0 = "/host1x/nvcsi@150c0000/channel@0"; + csi_chan0_port0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0"; + csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + imx390_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + liimx274_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + liimx185_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3322_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3333_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3331_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3323_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3326_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + csi_chan0_port1 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1"; + csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + imx390_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + liimx274_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + liimx185_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e3322_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e3333_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e3331_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e3323_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e3326_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + csi_chan1 = "/host1x/nvcsi@150c0000/channel@1"; + csi_chan1_port0 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0"; + csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + imx390_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + liimx274_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + e3322_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + e3333_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + e3323_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + csi_chan1_port1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1"; + csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + imx390_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + liimx274_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + e3322_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + e3333_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + e3323_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + csi_chan2 = "/host1x/nvcsi@150c0000/channel@2"; + csi_chan2_port0 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0"; + csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + e3322_csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + e3333_csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + csi_chan2_port1 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1"; + csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + e3322_csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + e3333_csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + csi_chan3 = "/host1x/nvcsi@150c0000/channel@3"; + csi_chan3_port0 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0"; + csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + e3322_csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + e3333_csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + csi_chan3_port1 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1"; + csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + e3322_csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + e3333_csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + csi_chan4 = "/host1x/nvcsi@150c0000/channel@4"; + csi_chan4_port0 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0"; + csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + e3322_csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + e3333_csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + csi_chan4_port1 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1"; + csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + e3322_csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + e3333_csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + csi_chan5 = "/host1x/nvcsi@150c0000/channel@5"; + csi_chan5_port0 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0"; + csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + e3322_csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + e3333_csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + csi_chan5_port1 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1"; + csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + e3322_csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + e3333_csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + vi_base = "/host1x/vi@15700000"; + tegra_vi = "/host1x/vi@15700000"; + vi_port0 = "/host1x/vi@15700000/ports/port@0"; + vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + imx390_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + liimx274_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + liimx185_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + e3322_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + e3333_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + e3331_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + e3323_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + e3326_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + vi_port1 = "/host1x/vi@15700000/ports/port@1"; + vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + imx390_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + liimx274_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + e3322_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + e3333_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + e3323_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + vi_port2 = "/host1x/vi@15700000/ports/port@2"; + vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + e3322_vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + e3333_vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + vi_port3 = "/host1x/vi@15700000/ports/port@3"; + vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + e3322_vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + e3333_vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + vi_port4 = "/host1x/vi@15700000/ports/port@4"; + vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + e3322_vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + e3333_vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + vi_port5 = "/host1x/vi@15700000/ports/port@5"; + vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + e3322_vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + e3333_vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + head0 = "/host1x/nvdisplay@15200000"; + head1 = "/host1x/nvdisplay@15210000"; + head2 = "/host1x/nvdisplay@15220000"; + dsi = "/host1x/dsi"; + panel_s_wuxga_8_0 = "/host1x/dsi/panel-s-wuxga-8-0"; + panel_s_wqxga_10_1 = "/host1x/dsi/panel-s-wqxga-10-1"; + sor0 = "/host1x/sor"; + sor0_hdmi_display = "/host1x/sor/hdmi-display"; + sor0_dp_display = "/host1x/sor/dp-display"; + panel_s_edp_uhdtv_15_6 = "/host1x/sor/panel-s-edp-uhdtv-15-6"; + panel_a_edp_1080p_14_0 = "/host1x/sor/panel-a-edp-1080p-14-0"; + sor1 = "/host1x/sor1"; + sor1_hdmi_display = "/host1x/sor1/hdmi-display"; + sor1_dp_display = "/host1x/sor1/dp-display"; + dpaux0 = "/host1x/dpaux@155c0000"; + dpaux1 = "/host1x/dpaux@15040000"; + generic_reserved = "/reserved-memory/generic_carveout"; + ramoops_reserved = "/reserved-memory/ramoops_carveout"; + vpr = "/reserved-memory/vpr-carveout"; + fb0_reserved = "/reserved-memory/fb0_carveout"; + fb1_reserved = "/reserved-memory/fb1_carveout"; + fb2_reserved = "/reserved-memory/fb2_carveout"; + smmu = "/iommu@12000000"; + host1x_as = "/iommu@12000000/address-space-prop/host1x"; + host1x_client_as = "/iommu@12000000/address-space-prop/host1x_client"; + common_as = "/iommu@12000000/address-space-prop/common"; + pcie_as = "/iommu@12000000/address-space-prop/pcie_as"; + gpu_as = "/iommu@12000000/address-space-prop/gpu"; + ape_as = "/iommu@12000000/address-space-prop/ape"; + camera_as = "/iommu@12000000/address-space-prop/camera"; + smmu_test = "/smmu_test"; + dma_test = "/dma_test"; + tegra_usb_cd = "/usb_cd"; + xusb_mbox = "/mailbox@3538000"; + tegra_xotg = "/xotg"; + xusb_padctl = "/xusb_padctl@3520000"; + tegra_xhci = "/xhci@3530000"; + tegra_xudc = "/xudc@3550000"; + tegra_xusb_padctl = "/pinctrl@3520000"; + tegra_xusb_padctl_pinmux_default = "/pinctrl@3520000/pinmux"; + tegra_ext_cdp = "/max16984-cdp"; + tegra_tachometer = "/tachometer@39c0000"; + tegra_aowake = "/pmc@c370000"; + tegra_pmc_iopower = "/pmc-iopower"; + mipical_prod_c_cphy_csi_soc_a01 = "/mipical/prod-settings/prod_c_cphy_csi/soc_a01"; + mipical_prod_c_dphy_csi_soc_a01 = "/mipical/prod-settings/prod_c_dphy_csi/soc_a01"; + mipical_prod_c_dphy_dsi_soc_a01 = "/mipical/prod-settings/prod_c_dphy_dsi/soc_a01"; + intc = "/interrupt-controller@3881000"; + lic = "/interrupt-controller@3000000"; + pm_irq = "/tegra186-pm-irq"; + tegra_car = "/clock@5000000"; + se = "/se_elp@3ad0000"; + sce_hsp = "/tegra-hsp@b150000"; + aon_hsp = "/tegra-hsp@c150000"; + hsp_top = "/tegra-hsp@3c00000"; + bpmp = "/bpmp"; + bpmpthermal = "/bpmp/bpmpthermal"; + gpcdma = "/dma@2600000"; + tegra_main_gpio = "/gpio@2200000"; + tegra_aon_gpio = "/gpio@c2f0000"; + tegra_pcie = "/pcie-controller@10003000"; + tegra_sound = "/sound"; + hdr40_snd_link_i2s = "/sound/nvidia,dai-link-1"; + rt565x_dai_link = "/sound/nvidia,dai-link-1"; + dspk_1_dai_link = "/sound/nvidia,dai-link-12"; + dspk_2_dai_link = "/sound/nvidia,dai-link-13"; + tegra_wdt = "/watchdog@30c0000"; + mttcan0 = "/mttcan@c310000"; + mttcan1 = "/mttcan@c320000"; + stm_out_port = "/stm@8070000/port/endpoint"; + ptm_a57_0 = "/ptm@9840000"; + ptm_a57_0_out_port = "/ptm@9840000/port/endpoint"; + ptm_a57_1 = "/ptm@9940000"; + ptm_a57_1_out_port = "/ptm@9940000/port/endpoint"; + ptm_a57_2 = "/ptm@9a40000"; + ptm_a57_2_out_port = "/ptm@9a40000/port/endpoint"; + ptm_a57_3 = "/ptm@9b40000"; + ptm_a57_3_out_port = "/ptm@9b40000/port/endpoint"; + ptm_bpmp_out_port = "/ptm_bpmp@8a1c000/port/endpoint"; + funnel_bccplex_out_port0 = "/funnel_bccplex@9010000/ports/port@0/endpoint"; + funnel_bccplex_in_port0 = "/funnel_bccplex@9010000/ports/port@1/endpoint"; + funnel_bccplex_in_port1 = "/funnel_bccplex@9010000/ports/port@2/endpoint"; + funnel_major_out_port0 = "/funnel_major@8010000/ports/port@0/endpoint"; + funnel_major_in_port0 = "/funnel_major@8010000/ports/port@1/endpoint"; + funnel_major_in_port1 = "/funnel_major@8010000/ports/port@2/endpoint"; + funnel_major_in_port2 = "/funnel_major@8010000/ports/port@3/endpoint"; + funnel_major_in_port3 = "/funnel_major@8010000/ports/port@4/endpoint"; + replicator_out_port0 = "/replicator@0x8040000/ports/port@0/endpoint"; + replicator_out_port1 = "/replicator@0x8040000/ports/port@1/endpoint"; + replicator_in_port0 = "/replicator@0x8040000/ports/port@2/endpoint"; + etf_in_port = "/etf@8030000/ports/port@0/endpoint"; + etf_out_port = "/etf@8030000/ports/port@1/endpoint"; + tpiu_in_port = "/tpiu@8060000/port/enpoint@0"; + etr_in_port = "/etr@8050000/port/endpoint@0"; + funnel_minor_out_port0 = "/funnel_minor@8820000/ports/port@0/endpoint"; + funnel_minor_in_port0 = "/funnel_minor@8820000/ports/port@2/endpoint"; + vbus_id_extcon = "/external-connection/extcon@1"; + aon = "/aon@c160000"; + hdr40_vdd_5v0 = "/fixed-regulators/regulator@0"; + battery_reg = "/fixed-regulators/regulator@0"; + en_vdd_sdcard1 = "/fixed-regulators/regulator@1"; + en_vdd_cam = "/fixed-regulators/regulator@2"; + vdd_hdmi = "/fixed-regulators/regulator@3"; + vdd_usb0_5v = "/fixed-regulators/regulator@4"; + vdd_usb1_5v = "/fixed-regulators/regulator@5"; + en_vdd_ts_1v8 = "/fixed-regulators/regulator@6"; + en_vdd_ts_hv_3v3 = "/fixed-regulators/regulator@7"; + en_avdd_disp_3v3 = "/fixed-regulators/regulator@8"; + en_mdm_pwr_3v7 = "/fixed-regulators/regulator@9"; + en_vdd_disp_1v8 = "/fixed-regulators/regulator@10"; + en_vdd_cam_hv_2v8 = "/fixed-regulators/regulator@11"; + en_vdd_cam_1v2 = "/fixed-regulators/regulator@12"; + vdd_fan = "/fixed-regulators/regulator@13"; + hdr40_vdd_3v3 = "/fixed-regulators/regulator@14"; + vdd_3v3 = "/fixed-regulators/regulator@14"; + dis_vdd_1v2 = "/fixed-regulators/regulator@15"; + en_vdd_vcm_2v8 = "/fixed-regulators/regulator@16"; + vdd_usb2_5v = "/fixed-regulators/regulator@17"; + vdd_bl_en = "/fixed-regulators/regulator@18"; + en_vdd_sys = "/fixed-regulators/regulator@118"; + vdd_1v8_ap = "/fixed-regulators/regulator@101"; + vdd_1v8_aud2 = "/fixed-regulators/regulator@200"; + panel_s_wuxga_8_0_bl = "/backlight/panel-s-wuxga-8-0-bl"; + panel_s_wqxga_10_1_bl = "/backlight/panel-s-wqxga-10-1-bl"; + panel_s_edp_uhdtv_15_6_bl = "/backlight/panel-s-edp-uhdtv-15-6-bl"; + panel_a_edp_1080p_14_0_bl = "/backlight/panel-a-edp-1080p-14-0-bl"; + pwm_fan_shared_data = "/pfsd"; + thermal_fan_est_shared_data = "/tfesd"; + soft_wdt = "/soft_watchdog"; + pf_backlight = "/tegra_skin_thermal/power_feature@0"; + pf_iio_ina3221 = "/tegra_skin_thermal/power_feature@1"; + hs0 = "/tegra_skin_thermal/hotspot@0"; + hs1 = "/tegra_skin_thermal/hotspot@1"; + hs2 = "/tegra_skin_thermal/hotspot@2"; + dummy_cool_dev = "/dummy-cool-dev"; + tcp = "/tegra-camera-platform"; + cam_module0 = "/tegra-camera-platform/modules/module0"; + cam_module0_drivernode0 = "/tegra-camera-platform/modules/module0/drivernode0"; + cam_module0_drivernode1 = "/tegra-camera-platform/modules/module0/drivernode1"; + cam_module1 = "/tegra-camera-platform/modules/module1"; + cam_module1_drivernode0 = "/tegra-camera-platform/modules/module1/drivernode0"; + cam_module1_drivernode1 = "/tegra-camera-platform/modules/module1/drivernode1"; + cam_module2 = "/tegra-camera-platform/modules/module2"; + cam_module2_drivernode0 = "/tegra-camera-platform/modules/module2/drivernode0"; + cam_module2_drivernode1 = "/tegra-camera-platform/modules/module2/drivernode1"; + cam_module3 = "/tegra-camera-platform/modules/module3"; + cam_module3_drivernode0 = "/tegra-camera-platform/modules/module3/drivernode0"; + cam_module3_drivernode1 = "/tegra-camera-platform/modules/module3/drivernode1"; + cam_module4 = "/tegra-camera-platform/modules/module4"; + cam_module4_drivernode0 = "/tegra-camera-platform/modules/module4/drivernode0"; + cam_module4_drivernode1 = "/tegra-camera-platform/modules/module4/drivernode1"; + cam_module5 = "/tegra-camera-platform/modules/module5"; + cam_module5_drivernode0 = "/tegra-camera-platform/modules/module5/drivernode0"; + cam_module5_drivernode1 = "/tegra-camera-platform/modules/module5/drivernode1"; + bcm4359 = "/bcmdhd_pcie_wlan"; + bcm4354 = "/bcmdhd_wlan"; + e2614_gps_wake = "/gps_wake"; + tegra_udrm = "/tegra_udrm"; + }; +}; diff --git a/dts/vm0.dtb b/dts/vm0.dtb new file mode 100644 index 0000000000000000000000000000000000000000..a1eb44119adc573d6e1177f96bf457c542c7a33f Binary files /dev/null and b/dts/vm0.dtb differ diff --git a/dts/vm0.dts b/dts/vm0.dts new file mode 100644 index 0000000000000000000000000000000000000000..16f8ca3978b4fa7f4424119d69b800d751d22b1c --- /dev/null +++ b/dts/vm0.dts @@ -0,0 +1,17653 @@ +/dts-v1/; + +/ { + nvidia,fastboot-usb-pid = <0xee16>; + compatible = "nvidia,quill", "nvidia,p2597-0000+p3310-1000", "nvidia,tegra186"; + nvidia,proc-boardid = "3310:0000:A0"; + nvidia,fastboot-usb-vid = <0x955>; + serial-number = "1421920042248"; + nvidia,dtbbuildtime = "Apr 8 2021", "15:27:51"; + model = "quill"; + nvidia,dtsfilename = "arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dts"; + interrupt-parent = <0x1>; + #address-cells = <0x2>; + #size-cells = <0x2>; + nvidia,boardids = "3310:0000:A0"; + + mttcan1-ivc { + compatible = "bosch,mttcan-ivc"; + status = "disabled"; + mboxes = <0x41 0x4>; + }; + + watchdog@30c0000 { + nvidia,shutdown-timeout = <0x96>; + compatible = "nvidia,tegra-wdt-t18x"; + nvidia,watchdog-index = <0x0>; + nvidia,expiry-count = <0x5>; + nvidia,disable-debug-reset; + nvidia,extend-watchdog-suspend; + status = "okay"; + interrupts = <0x0 0x7 0x4 0x0 0x8 0x4>; + nvidia,timer-index = <0x7>; + phandle = <0xfd>; + reg = <0x0 0x30c0000 0x0 0x10000 0x0 0x3020000 0x0 0x10000 0x0 0x3010000 0x0 0x10000>; + linux,phandle = <0xfd>; + nvidia,enable-on-init; + timeout-sec = <0x78>; + }; + + cpuidle { + compatible = "nvidia,tegra18x-cpuidle"; + status = "okay"; + }; + + ether_qos_virt_test@2490000 { + compatible = "synopsys,dwc_eqos_virt_test"; + status = "disabled"; + reg = <0x0 0x2490000 0x0 0x10000 0x0 0x24a0000 0x0 0x10000>; + }; + + i2c@3190000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x56 0x10 0x10d 0x10 0xdd>; + resets = <0x10 0x16>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1c 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x92>; + reg = <0x0 0x3190000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x186a0>; + dmas = <0x25 0x1a 0x25 0x1a>; + reset-names = "i2c"; + linux,phandle = <0x92>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + aconnect@2a41000 { + power-domains = <0x1f 0x0>; + compatible = "nvidia,tegra210-aconnect"; + clocks = <0x10 0x69 0x10 0x68>; + clock-names = "ape", "apb2ape"; + ranges; + status = "okay"; + #address-cells = <0x2>; + #size-cells = <0x2>; + + ahub { + assigned-clock-parents = <0x10 0x10d>; + compatible = "nvidia,tegra186-axbar"; + wakeup-disable; + clocks = <0x10 0x57 0x10 0xf6 0x10 0x68 0x10 0x69>; + clock-names = "ahub", "parent", "apb2ape", "xbar.ape"; + ranges; + status = "okay"; + #address-cells = <0x2>; + assigned-clock-rates = <0x2b3bb55>; + #size-cells = <0x2>; + assigned-clocks = <0x10 0x57>; + phandle = <0xb8>; + reg = <0x0 0x2900800 0x0 0x800>; + linux,phandle = <0xb8>; + + adx@2903a00 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x2>; + status = "okay"; + phandle = <0x1ad>; + reg = <0x0 0x2903a00 0x0 0x100>; + linux,phandle = <0x1ad>; + }; + + dspk@2905100 { + nvidia,ahub-dspk-id = <0x1>; + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra186-dspk"; + clocks = <0x10 0x99 0x10 0xf6 0x10 0xfe>; + clock-names = "dspk", "pll_a_out0", "sync_dspk"; + status = "okay"; + assigned-clock-rates = <0xbb8000>; + assigned-clocks = <0x10 0x99>; + phandle = <0xcf>; + reg = <0x0 0x2905100 0x0 0x100 0x0 0x2431000 0x0 0x1f0>; + linux,phandle = <0xcf>; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x8 0xfff 0x441 0x1 0x0 0xfff 0x441>; + }; + }; + }; + + mvc@290a200 { + compatible = "nvidia,tegra210-mvc"; + nvidia,ahub-mvc-id = <0x1>; + status = "okay"; + phandle = <0x1b6>; + reg = <0x0 0x290a200 0x0 0x200>; + linux,phandle = <0x1b6>; + }; + + afc@2907100 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x1>; + status = "okay"; + phandle = <0x1b0>; + reg = <0x0 0x2907100 0x0 0x100>; + linux,phandle = <0x1b0>; + }; + + i2s@2901200 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x2b 0x10 0xf6 0x10 0x26b 0x10 0xf9 0x10 0x26b>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x2b>; + phandle = <0xbd>; + nvidia,ahub-i2s-id = <0x2>; + reg = <0x0 0x2901200 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xbd>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + adx@2903800 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x0>; + status = "okay"; + phandle = <0x1ab>; + reg = <0x0 0x2903800 0x0 0x100>; + linux,phandle = <0x1ab>; + }; + + dmic@2904000 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x7a 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x0>; + assigned-clocks = <0x10 0x7a>; + phandle = <0xc5>; + reg = <0x0 0x2904000 0x0 0x100>; + linux,phandle = <0xc5>; + }; + + afc@2907400 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x4>; + status = "okay"; + phandle = <0x1b3>; + reg = <0x0 0x2907400 0x0 0x100>; + linux,phandle = <0x1b3>; + }; + + i2s@2901500 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x9a 0x10 0xf6 0x10 0x26e 0x10 0xfc 0x10 0x26e>; + fsync-width = <0x0>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x9a>; + phandle = <0xc3>; + nvidia,ahub-i2s-id = <0x5>; + reg = <0x0 0x2901500 0x0 0x100>; + pinctrl-0; + bclk-ratio = <0x4>; + linux,phandle = <0xc3>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + sfc@2902200 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x1>; + phandle = <0x1a2>; + reg = <0x0 0x2902200 0x0 0x200>; + linux,phandle = <0x1a2>; + }; + + dmic@2904300 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x97 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x3>; + assigned-clocks = <0x10 0x97>; + phandle = <0xcb>; + reg = <0x0 0x2904300 0x0 0x100>; + linux,phandle = <0xcb>; + }; + + amixer@290bb00 { + nvidia,ahub-amixer-id = <0x0>; + compatible = "nvidia,tegra210-amixer"; + status = "okay"; + phandle = <0x1a6>; + reg = <0x0 0x290bb00 0x0 0x800>; + linux,phandle = <0x1a6>; + }; + + iqc@290e000 { + compatible = "nvidia,tegra210-iqc"; + clocks = <0x10 0x6a>; + clock-names = "iqc"; + status = "okay"; + phandle = <0x1b7>; + reg = <0x0 0x290e000 0x0 0x200>; + nvidia,ahub-iqc-id = <0x0>; + linux,phandle = <0x1b7>; + }; + + amx@2903000 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x0>; + status = "okay"; + phandle = <0x1a7>; + reg = <0x0 0x2903000 0x0 0x100>; + linux,phandle = <0x1a7>; + }; + + dspk@2905000 { + nvidia,ahub-dspk-id = <0x0>; + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra186-dspk"; + clocks = <0x10 0x98 0x10 0xf6 0x10 0xfd>; + clock-names = "dspk", "pll_a_out0", "sync_dspk"; + status = "okay"; + assigned-clock-rates = <0xbb8000>; + assigned-clocks = <0x10 0x98>; + phandle = <0xcd>; + reg = <0x0 0x2905000 0x0 0x100>; + linux,phandle = <0xcd>; + }; + + amx@2903300 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x3>; + status = "okay"; + phandle = <0x1aa>; + reg = <0x0 0x2903300 0x0 0x100>; + linux,phandle = <0x1aa>; + }; + + afc@2907000 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x0>; + status = "okay"; + phandle = <0x1af>; + reg = <0x0 0x2907000 0x0 0x100>; + linux,phandle = <0x1af>; + }; + + i2s@2901100 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x2a 0x10 0xf6 0x10 0x26a 0x10 0xf8 0x10 0x26a>; + fsync-width = <0x0>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x2a>; + phandle = <0xbb>; + nvidia,ahub-i2s-id = <0x1>; + reg = <0x0 0x2901100 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xbb>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + arad@290e400 { + compatible = "nvidia,tegra186-arad"; + status = "okay"; + nvidia,ahub-arad-id = <0x0>; + phandle = <0x1b9>; + reg = <0x0 0x290e400 0x0 0x400>; + linux,phandle = <0x1b9>; + }; + + afc@2907300 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x3>; + status = "okay"; + phandle = <0x1b2>; + reg = <0x0 0x2907300 0x0 0x100>; + linux,phandle = <0x1b2>; + }; + + i2s@2901400 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x55 0x10 0xf6 0x10 0x26d 0x10 0xfb 0x10 0x26d>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x55>; + phandle = <0xc1>; + nvidia,ahub-i2s-id = <0x4>; + reg = <0x0 0x2901400 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xc1>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + dmic@2904200 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x96 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x2>; + assigned-clocks = <0x10 0x96>; + phandle = <0xc9>; + reg = <0x0 0x2904200 0x0 0x100 0x0 0xc303000 0x0 0x1f0>; + linux,phandle = <0xc9>; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x28 0xffff 0x6441 0x1 0x30 0xffff 0x6441>; + }; + }; + }; + + spkprot@2908c00 { + compatible = "nvidia,tegra210-spkprot"; + nvidia,ahub-spkprot-id = <0x0>; + status = "okay"; + phandle = <0x1a5>; + reg = <0x0 0x2908c00 0x0 0x400>; + linux,phandle = <0x1a5>; + }; + + admaif@290f000 { + compatible = "nvidia,tegra186-admaif"; + clocks = <0x10 0x57>; + dma-buffer-size = <0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000>; + clock-names = "ahub"; + status = "okay"; + dma-names = "rx1", "tx1", "rx2", "tx2", "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", "rx9", "tx9", "rx10", "tx10", "rx11", "tx11", "rx12", "tx12", "rx13", "tx13", "rx14", "tx14", "rx15", "tx15", "rx16", "tx16", "rx17", "tx17", "rx18", "tx18", "rx19", "tx19", "rx20", "tx20"; + phandle = <0x1a0>; + reg = <0x0 0x290f000 0x0 0x1000>; + dmas = <0x5f 0x1 0x5f 0x1 0x5f 0x2 0x5f 0x2 0x5f 0x3 0x5f 0x3 0x5f 0x4 0x5f 0x4 0x5f 0x5 0x5f 0x5 0x5f 0x6 0x5f 0x6 0x5f 0x7 0x5f 0x7 0x5f 0x8 0x5f 0x8 0x5f 0x9 0x5f 0x9 0x5f 0xa 0x5f 0xa 0x5f 0xb 0x5f 0xb 0x5f 0xc 0x5f 0xc 0x5f 0xd 0x5f 0xd 0x5f 0xe 0x5f 0xe 0x5f 0xf 0x5f 0xf 0x5f 0x10 0x5f 0x10 0x5f 0x11 0x5f 0x11 0x5f 0x12 0x5f 0x12 0x5f 0x13 0x5f 0x13 0x5f 0x14 0x5f 0x14>; + linux,phandle = <0x1a0>; + }; + + sfc@2902400 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x2>; + phandle = <0x1a3>; + reg = <0x0 0x2902400 0x0 0x200>; + linux,phandle = <0x1a3>; + }; + + mvc@290a000 { + compatible = "nvidia,tegra210-mvc"; + nvidia,ahub-mvc-id = <0x0>; + status = "okay"; + phandle = <0x1b5>; + reg = <0x0 0x290a000 0x0 0x200>; + linux,phandle = <0x1b5>; + }; + + amx@2903200 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x2>; + status = "okay"; + phandle = <0x1a9>; + reg = <0x0 0x2903200 0x0 0x100>; + linux,phandle = <0x1a9>; + }; + + i2s@2901000 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x4f 0x10 0xf6 0x10 0x269 0x10 0xf7 0x10 0x269>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x4f>; + phandle = <0xb9>; + nvidia,ahub-i2s-id = <0x0>; + reg = <0x0 0x2901000 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xb9>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + adx@2903b00 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x3>; + status = "okay"; + phandle = <0x1ae>; + reg = <0x0 0x2903b00 0x0 0x100>; + linux,phandle = <0x1ae>; + }; + + afc@2907200 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x2>; + status = "okay"; + phandle = <0x1b1>; + reg = <0x0 0x2907200 0x0 0x100>; + linux,phandle = <0x1b1>; + }; + + i2s@2901300 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-i2s"; + clocks = <0x10 0x54 0x10 0xf6 0x10 0x26c 0x10 0xfa 0x10 0x26c>; + fsync-width = <0x1f>; + pinctrl-1; + clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync", "clk_sync_input"; + status = "okay"; + assigned-clock-rates = <0x177000>; + assigned-clocks = <0x10 0x54>; + phandle = <0xbf>; + nvidia,ahub-i2s-id = <0x3>; + reg = <0x0 0x2901300 0x0 0x100>; + pinctrl-0; + linux,phandle = <0xbf>; + pinctrl-names = "dap_active", "dap_inactive"; + }; + + adx@2903900 { + compatible = "nvidia,tegra210-adx"; + nvidia,ahub-adx-id = <0x1>; + status = "okay"; + phandle = <0x1ac>; + reg = <0x0 0x2903900 0x0 0x100>; + linux,phandle = <0x1ac>; + }; + + sfc@2902000 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x0>; + phandle = <0x1a1>; + reg = <0x0 0x2902000 0x0 0x200>; + linux,phandle = <0x1a1>; + }; + + dmic@2904100 { + assigned-clock-parents = <0x10 0xf6>; + compatible = "nvidia,tegra210-dmic"; + clocks = <0x10 0x7b 0x10 0xf6>; + clock-names = "dmic", "parent"; + status = "okay"; + assigned-clock-rates = <0x2ee000>; + nvidia,ahub-dmic-id = <0x1>; + assigned-clocks = <0x10 0x7b>; + phandle = <0xc7>; + reg = <0x0 0x2904100 0x0 0x100>; + linux,phandle = <0xc7>; + }; + + ahc@290b900 { + compatible = "nvidia,tegra186-ahc"; + status = "okay"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x38 0x4 0x0>; + phandle = <0x1ba>; + reg = <0x0 0x290b900 0x0 0x200>; + linux,phandle = <0x1ba>; + }; + + afc@2907500 { + compatible = "nvidia,tegra186-afc"; + nvidia,ahub-afc-id = <0x5>; + status = "okay"; + phandle = <0x1b4>; + reg = <0x0 0x2907500 0x0 0x100>; + linux,phandle = <0x1b4>; + }; + + asrc@2910000 { + compatible = "nvidia,tegra186-asrc"; + nvidia,ahub-asrc-id = <0x0>; + status = "okay"; + phandle = <0x1b8>; + reg = <0x0 0x2910000 0x0 0x2000>; + linux,phandle = <0x1b8>; + }; + + ope@2908000 { + compatible = "nvidia,tegra210-ope"; + status = "okay"; + phandle = <0x1bb>; + reg = <0x0 0x2908000 0x0 0x100 0x0 0x2908100 0x0 0x100 0x0 0x2908200 0x0 0x200>; + linux,phandle = <0x1bb>; + nvidia,ahub-ope-id = <0x0>; + + peq@2908100 { + status = "okay"; + }; + + mbdrc@2908200 { + status = "okay"; + }; + }; + + sfc@2902600 { + compatible = "nvidia,tegra210-sfc"; + status = "okay"; + nvidia,ahub-sfc-id = <0x3>; + phandle = <0x1a4>; + reg = <0x0 0x2902600 0x0 0x200>; + linux,phandle = <0x1a4>; + }; + + amx@2903100 { + compatible = "nvidia,tegra210-amx"; + nvidia,ahub-amx-id = <0x1>; + status = "okay"; + phandle = <0x1a8>; + reg = <0x0 0x2903100 0x0 0x100>; + linux,phandle = <0x1a8>; + }; + }; + + rtcpu@2993000 { + compatible = "nvidia,tegra186-ape-ivc"; + clocks = <0x10 0x69 0x10 0x68 0x10 0x8b 0x10 0x8a>; + resets = <0x10 0xbf>; + reg-names = "ape-evp", "ape-amisc", "ast-cpu"; + nvidia,autosuspend-delay-ms = <0x1388>; + clock-names = "ape", "apb2ape", "adspneon", "adsp"; + status = "disabled"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x3e 0x4 0x0 0x0 0x3f 0x4 0x0 0x0 0x54 0x4 0x0 0x0 0x1f 0x4 0x4 0x0 0x30 0x4 0x4 0x0 0x44 0x4 0x4 0x0 0x45 0x4 0x4 0x0 0x47 0x4 0x4 0x0 0x46 0x4 0x4 0x0 0x48 0x4 0x4 0x0 0x49 0x4 0x4 0x0 0x4a 0x4 0x4 0x0 0x4b 0x4 0x4 0x0 0x4e 0x4 0x4 0x0 0x4f 0x4 0x4 0x0 0x50 0x4 0x4 0x0 0x53 0x4 0x4 0x0 0x52 0x4 0x4>; + nvidia,trace = <0x5c 0x4 0x40200000 0x80000>; + nvidia,ivc-channels = <0x5d 0x2 0x40000000 0x10000>; + phandle = <0x19d>; + iommu-group-id = <0x3>; + reg = <0x0 0x2993000 0x0 0x1000 0x0 0x2990000 0x0 0x800 0x0 0x2994000 0x0 0x2000>; + iommus = <0x11 0x2d>; + reset-names = "adsp-all"; + linux,phandle = <0x19d>; + interrupt-names = "adsp-wfi", "adsp-wfe", "wdt-remote"; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + device = <0x5e>; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + nvidia,hsp-shared-mailbox = <0x5e 0x1 0x5e 0x6>; + }; + }; + + agic-controller@2a41000 { + compatible = "nvidia,tegra186-agic"; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "okay"; + #interrupt-cells = <0x4>; + interrupts = <0x0 0x91 0xf04>; + phandle = <0x5b>; + reg = <0x0 0x2a41000 0x0 0x1000 0x0 0x2a42000 0x0 0x2000>; + linux,phandle = <0x5b>; + interrupt-controller; + }; + + agic-controller@2a51000 { + compatible = "nvidia,tegra186-agic"; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "disabled"; + #interrupt-cells = <0x4>; + interrupts = <0x0 0x92 0xf04>; + phandle = <0x19e>; + reg = <0x0 0x2a51000 0x0 0x1000 0x0 0x2a52000 0x0 0x2000>; + linux,phandle = <0x19e>; + interrupt-controller; + }; + + tegra-hsp@29a0000 { + compatible = "nvidia,tegra186-hsp"; + status = "disabled"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x20 0x4 0x0 0x0 0x21 0x4 0x0 0x0 0x22 0x4 0x0 0x0 0x23 0x4 0x0 0x0 0x24 0x4 0x0 0x0 0x25 0x4 0x0 0x0 0x26 0x4 0x0 0x0 0x27 0x4 0x0 0x0 0x28 0x4 0x0 0x0 0x29 0x4 0x0 0x0 0x2a 0x4 0x0 0x0 0x2b 0x4 0x0 0x0 0x2c 0x4 0x0 0x0 0x2d 0x4 0x0 0x0 0x2e 0x4 0x0 0x0 0x2f 0x4 0x0 0x0 0x30 0x4 0x4 0x0 0x31 0x4 0x0 0x0 0x32 0x4 0x0 0x0 0x33 0x4 0x0 0x0 0x34 0x4 0x0>; + phandle = <0x5e>; + reg = <0x0 0x29a0000 0x0 0x90000>; + linux,phandle = <0x5e>; + interrupt-names = "full0", "full1", "full2", "full3", "full4", "full5", "full6", "full7", "empty0", "empty1", "empty2", "empty3", "empty4", "empty5", "empty6", "empty7", "adsp-shared0", "shared1", "shared2", "shared3", "shared4"; + }; + + adsp_audio { + nvidia,adma_ch_cnt = <0x10>; + compatible = "nvidia,tegra186-adsp-audio"; + wakeup-disable; + clocks = <0x10 0x57 0x10 0x69 0x10 0x68>; + num-plugin = <0x5>; + nvidia,adma_ch_start = <0x10>; + clock-names = "ahub", "ape", "apb2ape"; + compr-ops = <0x1>; + status = "okay"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x10 0x4 0x4 0x0 0x11 0x4 0x4 0x0 0x12 0x4 0x4 0x0 0x13 0x4 0x4 0x0 0x14 0x4 0x4 0x0 0x15 0x4 0x4 0x0 0x16 0x4 0x4 0x0 0x17 0x4 0x4 0x0 0x18 0x4 0x4 0x0 0x19 0x4 0x4 0x0 0x1a 0x4 0x4 0x0 0x1b 0x4 0x4 0x0 0x1c 0x4 0x4 0x0 0x1d 0x4 0x4 0x0 0x1e 0x4 0x4 0x0 0x1f 0x4 0x4>; + phandle = <0x1bc>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommus = <0x11 0x1e>; + linux,phandle = <0x1bc>; + + plugin-info-4 { + plugin-name = "aac-dec1"; + widget-name = "AAC-DEC1"; + firmware-name = "nvaacdec.elf"; + }; + + plugin-info-2 { + plugin-name = "spkprot"; + widget-name = "SPKPROT-SW"; + firmware-name = "nvspkprot.elf"; + }; + + plugin-info-5 { + plugin-name = "aec"; + widget-name = "AEC"; + firmware-name = "nvoice.elf"; + }; + + plugin-info-3 { + plugin-name = "src"; + widget-name = "SRC"; + firmware-name = "nvsrc.elf"; + }; + + plugin-info-1 { + plugin-name = "mp3-dec1"; + widget-name = "MP3-DEC1"; + firmware-name = "nvmp3dec.elf"; + }; + }; + + agic-controller@2a61000 { + compatible = "nvidia,tegra186-agic"; + clocks = <0x10 0x69>; + clock-names = "clk"; + status = "disabled"; + #interrupt-cells = <0x4>; + interrupts = <0x0 0x93 0xf04>; + phandle = <0x19f>; + reg = <0x0 0x2a61000 0x0 0x1000 0x0 0x2a62000 0x0 0x2000>; + linux,phandle = <0x19f>; + interrupt-controller; + }; + + adsp@2993000 { + compatible = "nvidia,tegra18x-adsp"; + clocks = <0x10 0x8b 0x10 0x8a 0x10 0x111>; + resets = <0x10 0xbf>; + dma-mask = <0x0 0x5e000000>; + clock-names = "adspneon", "adsp", "aclk"; + status = "okay"; + nvidia,adsp_mem = <0x5ef00000 0x1000000 0x5f700000 0x800000 0x3f813000 0x5000 0x5fd00000 0x200000>; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x29 0x4 0x0 0x0 0x20 0x4 0x0 0x0 0x53 0x4 0x0 0x0 0x3e 0x4 0x0 0x0 0x39 0x4 0x0 0x0 0x41 0x4 0x0 0x0 0x28 0x4 0x4 0x0 0x21 0x4 0x4 0x0 0x22 0x4 0x4 0x0 0x4e 0x4 0x4 0x0 0x4f 0x4 0x4 0x0 0x50 0x4 0x4 0x0 0x4b 0x4 0x4>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + reg = <0x0 0x2993000 0x0 0x1000 0x0 0x2990000 0x0 0x2000 0x0 0x0 0x0 0x1 0x0 0x290c800 0x0 0x1 0x0 0x29b0000 0x0 0x90000 0x0 0x40000000 0x0 0xc0000000 0x0 0x0 0x0 0x1>; + iommus = <0x11 0x1e>; + nvidia,adsp_unit_fpga_reset = <0x7f00040 0x40>; + reset-names = "adspall"; + nvidia,adsp_os_secload; + nvidia,adsp-evp-base = <0x2993700 0x40>; + }; + + adma@2930000 { + #dma-cells = <0x1>; + compatible = "nvidia,tegra186-adma"; + clocks = <0x10 0x57>; + clock-names = "d_audio"; + status = "okay"; + interrupt-parent = <0x5b>; + interrupts = <0x0 0x0 0x4 0x0 0x0 0x1 0x4 0x0 0x0 0x2 0x4 0x0 0x0 0x3 0x4 0x0 0x0 0x4 0x4 0x0 0x0 0x5 0x4 0x0 0x0 0x6 0x4 0x0 0x0 0x7 0x4 0x0 0x0 0x8 0x4 0x0 0x0 0x9 0x4 0x0 0x0 0xa 0x4 0x0 0x0 0xb 0x4 0x0 0x0 0xc 0x4 0x0 0x0 0xd 0x4 0x0 0x0 0xe 0x4 0x0 0x0 0xf 0x4 0x0 0x0 0x10 0x4 0x0 0x0 0x11 0x4 0x0 0x0 0x12 0x4 0x0 0x0 0x13 0x4 0x0 0x0 0x14 0x4 0x0 0x0 0x15 0x4 0x0 0x0 0x16 0x4 0x0 0x0 0x17 0x4 0x0 0x0 0x18 0x4 0x0 0x0 0x19 0x4 0x0 0x0 0x1a 0x4 0x0 0x0 0x1b 0x4 0x0 0x0 0x1c 0x4 0x0 0x0 0x1d 0x4 0x0 0x0 0x1e 0x4 0x0 0x0 0x1f 0x4 0x0>; + phandle = <0x5f>; + reg = <0x0 0x2930000 0x0 0x50000 0x0 0x29f0000 0x0 0x10>; + linux,phandle = <0x5f>; + }; + }; + + generic_pwm_tachometer { + compatible = "generic-pwm-tachometer"; + status = "okay"; + pwms = <0xb2 0x0 0xf4240>; + }; + + sdhci@3400000 { + nvidia,ddr-tap-delay = <0xb>; + nvidia,en-periodic-calib; + cap-mmc-highspeed; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x34 0x10 0x10d 0x10 0x80>; + cap-sd-highspeed; + nvidia,cd-wakeup-capable; + resets = <0x10 0x21>; + pinctrl-1 = <0x1a>; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + pll_source = "pll_p"; + cd-gpios = <0x1b 0x7d 0x0>; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "okay"; + nvidia,max-tap-delay = <0x88>; + interrupts = <0x0 0x3e 0x4>; + bus-width = <0x4>; + ddr-trim-delay = <0x5>; + phandle = <0x100>; + tap-delay = <0xb>; + reg = <0x0 0x3400000 0x0 0x210>; + iommus = <0x11 0x1a>; + pinctrl-0 = <0x19>; + mmc-ocr-mask = <0x3>; + compad-vref-1v8 = <0x2>; + trim-delay = <0x5>; + pwrdet-support; + reset-names = "sdhci"; + cd-inverted; + vmmc-supply = <0x1d>; + uhs-mask = <0x8>; + linux,phandle = <0x100>; + ignore-pm-notify; + wp-inverted; + compad-vref-3v3 = <0x1>; + vqmmc-supply = <0x1c>; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + max-clk-limit = <0xc28cb00>; + wp-gpios = <0x1b 0x7c 0x0>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000503>; + }; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr12 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr25 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + }; + }; + + mttcan@c310000 { + gpio_can_stb = <0x28 0x28 0x0>; + compatible = "nvidia,tegra186-mttcan"; + clocks = <0x10 0xd2 0x10 0xd3 0x10 0x214>; + resets = <0x10 0x3c>; + reg-names = "can-regs", "glue-regs", "msg-ram"; + clock-names = "can", "can_host", "pllaon"; + rx-config = <0x40 0x40 0x40>; + pll_source = "pllaon"; + mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>; + status = "okay"; + interrupts = <0x0 0x28 0x4>; + phandle = <0x1d6>; + reg = <0x0 0xc310000 0x0 0x400 0x0 0xc311000 0x0 0x32 0x0 0xc312000 0x0 0x1000>; + gpio_can_en = <0x28 0x29 0x0>; + reset-names = "can"; + linux,phandle = <0x1d6>; + tx-config = <0x0 0x10 0x0 0x40>; + }; + + aon_spi@c260000 { + compatible = "nvidia,tegra186-aon-spi"; + bus-number = <0x1>; + status = "disabled"; + #address-cells = <0x1>; + mboxes = <0x41 0x2>; + #size-cells = <0x0>; + phandle = <0x187>; + linux,phandle = <0x187>; + spi-max-frequency = <0xb71b00>; + }; + + rtc@c2a0000 { + compatible = "nvidia,tegra18-rtc"; + status = "okay"; + interrupt-parent = <0x3a>; + interrupts = <0x0 0xa 0x4>; + reg = <0x0 0xc2a0000 0x0 0x100>; + }; + + sdhci@3440000 { + nvidia,ddr-tap-delay = <0xb>; + nvidia,en-periodic-calib; + cap-mmc-highspeed; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x4c 0x10 0x10d 0x10 0x80>; + cap-sd-highspeed; + resets = <0x10 0x23>; + pinctrl-1 = <0x15>; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + pll_source = "pll_p"; + only-1-8-v; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "okay"; + nvidia,max-tap-delay = <0x88>; + interrupts = <0x0 0x40 0x4>; + bus-width = <0x4>; + ddr-trim-delay = <0x5>; + phandle = <0xf9>; + tap-delay = <0xb>; + force-non-removable-rescan; + reg = <0x0 0x3440000 0x0 0x210>; + iommus = <0x11 0x18>; + pinctrl-0 = <0x14>; + mmc-ocr-mask = <0x0>; + compad-vref-1v8 = <0x2>; + trim-delay = <0x5>; + pwrdet-support; + reset-names = "sdhci"; + vmmc-supply = <0x12>; + uhs-mask = <0x8>; + linux,phandle = <0xf9>; + non-removable; + ignore-pm-notify; + compad-vref-3v3 = <0x1>; + vqmmc-supply = <0x16>; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + max-clk-limit = <0xc28cb00>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x50b0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr12 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x1 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20007a00>; + }; + + prod_c_sdr25 { + prod = <0x100 0xff0000 0xb0000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20006a76>; + }; + }; + }; + + miscreg@00100000 { + compatible = "nvidia,tegra186-miscreg"; + status = "disabled"; + reg = <0x0 0x100000 0x0 0xf000 0x0 0x10f000 0x0 0x1000>; + }; + + reserved-memory { + ranges; + #address-cells = <0x2>; + #size-cells = <0x2>; + + fb0_carveout { + reg-names = "surface", "lut"; + no-map; + phandle = <0x80>; + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + linux,phandle = <0x80>; + }; + + ramoops_carveout { + compatible = "nvidia,ramoops"; + alignment = <0x0 0x10000>; + status = "disabled"; + no-map; + phandle = <0x1cc>; + reg = <0x2 0x75880000 0x0 0x200000>; + linux,phandle = <0x1cc>; + }; + + vpr-carveout { + reusable; + alignment = <0x0 0x400000>; + alloc-ranges = <0x0 0x80000000 0x0 0x70000000>; + phandle = <0x96>; + linux,phandle = <0x96>; + }; + + fb1_carveout { + reg-names = "surface", "lut"; + no-map; + phandle = <0x81>; + reg = <0x0 0x9607d000 0x0 0x800000 0x0 0x9607a000 0x0 0x2008>; + linux,phandle = <0x81>; + }; + + fb2_carveout { + reg-names = "surface", "lut"; + no-map; + phandle = <0x82>; + reg = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + linux,phandle = <0x82>; + }; + + generic_carveout { + compatible = "nvidia,generic_carveout"; + alignment = <0x0 0x100000>; + alloc-ranges = <0x0 0x0 0x1 0x0>; + status = "disabled"; + no-map; + size = <0x0 0x0>; + phandle = <0x95>; + linux,phandle = <0x95>; + }; + }; + + pwm@32c0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbe 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x67>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x189>; + reg = <0x0 0x32c0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x189>; + #pwm-cells = <0x2>; + }; + + tegra_safety_ivc { + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0x60>; + linux,phandle = <0x60>; + + cmdresp@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-safety-cmd-resp"; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0x0 0x8000>; + }; + + hb@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-safety-hb"; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x1>; + reg = <0x500 0x8500>; + }; + }; + + replicator@0x8040000 { + compatible = "arm,coresight-replicator"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8040000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + reg = <0x1>; + + endpoint { + remote-endpoint = <0xdf>; + phandle = <0xe3>; + linux,phandle = <0xe3>; + }; + }; + + port@2 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe0>; + phandle = <0xe2>; + slave-mode; + linux,phandle = <0xe2>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xde>; + phandle = <0xe4>; + linux,phandle = <0xe4>; + }; + }; + }; + }; + + max16984-cdp { + compatible = "maxim,max16984-tegra186-cdp-phy"; + status = "disabled"; + phandle = <0x1d0>; + #phy-cells = <0x1>; + linux,phandle = <0x1d0>; + }; + + sound_ref { + dma-mask = <0x0 0x5e000000>; + status = "disabled"; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + iommus = <0x11 0x1e>; + }; + + bcmdhd_pcie_wlan { + nv_path = "/vendor/firmware/nvram_4359_b1.txt"; + compatible = "android,bcmdhd_pcie_wlan"; + fw_path = "/vendor/firmware/fw_bcmdhd.bin"; + status = "disabled"; + interrupt-parent = <0x28>; + interrupts = <0x3b 0x14>; + phandle = <0x1e5>; + linux,phandle = <0x1e5>; + wlan-pwr-gpio = <0x1b 0x68 0x0>; + }; + + sce@b000000 { + compatible = "nvidia,tegra186-safety-ivc"; + reg-names = "ast-cpu", "ast-dma"; + status = "disabled"; + nvidia,ivc-channels = <0x60 0x2 0x90000000 0x10000>; + phandle = <0x1bd>; + reg = <0x0 0xb040000 0x0 0x10000 0x0 0xb050000 0x0 0x10000>; + iommus = <0x11 0x1f>; + linux,phandle = <0x1bd>; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + nvidia,hsp-shared-mailbox = <0x58 0x1 0x58 0x6>; + }; + }; + + pmc-iopower { + vddio-cam-supply = <0x3d>; + vddio-sdmmc1-hv-supply = <0x1c>; + vddio-spi-supply = <0x3d>; + compatible = "nvidia,tegra186-pmc-iopower"; + vddio-pex-ctrl-supply = <0x3d>; + vddio-conn-supply = <0x3d>; + pad-names = "ufs", "dbg", "spi", "audio-hv", "ao-hv", "dmic-hv", "sdmmc1-hv", "sdmmc2-hv", "sdmmc3-hv", "dsia", "dsib", "dsic", "dsid", "hdmi-dp0", "hdmi-dp1"; + vddio-sdmmc4-supply = <0x3d>; + vddio-ddr1-supply = <0xb4>; + vddio-mipi-bias-supply = <0x3c>; + vddio-ddr0-supply = <0xb4>; + vddio-audio-supply = <0x3d>; + vddio-sdmmc2-hv-supply = <0x13>; + vddio-uart-supply = <0x3d>; + status = "okay"; + vddio-dbg-supply = <0x3d>; + vddio-ufs-supply = <0x3d>; + vddio-audio-hv-supply = <0x3d>; + vddio-edp-supply = <0x3d>; + vddio-dmic-hv-supply = <0x3d>; + phandle = <0x1d2>; + vddio-sys-supply = <0x3d>; + vddio-sdmmc3-hv-supply = <0x16>; + pad-controllers = <0xb3 0x34 0xa 0x29 0x1 0x35 0xd 0x24 0x25 0x27 0xf 0x10 0x11 0x12 0x18 0x19>; + linux,phandle = <0x1d2>; + vddio-ao-hv-supply = <0xb5>; + vddio-ao-supply = <0x3d>; + }; + + ptm@9840000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x4>; + status = "okay"; + phandle = <0x1d8>; + reg = <0x0 0x9840000 0x0 0x1000>; + linux,phandle = <0x1d8>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd6>; + linux,phandle = <0xd6>; + }; + }; + }; + + actmon@d230000 { + nvidia,sample_period = [14]; + compatible = "nvidia,tegra186-cactmon"; + clocks = <0x10 0xc9>; + resets = <0x10 0x0>; + clock-names = "actmon"; + status = "okay"; + #address-cells = <0x2>; + interrupts = <0x0 0xd2 0x4>; + #size-cells = <0x2>; + reg = <0x0 0xd230000 0x0 0x1000>; + reset-names = "actmon_rst"; + + mc_all { + nvidia,suspend_freq = <0x31ce0>; + nvidia,boost_up_threshold = <0x1e>; + nvidia,up_wmark_window = [03]; + nvidia,boost_down_coef = <0x32>; + nvidia,count_weight = <0x200>; + nvidia,max_dram_channels = [04]; + nvidia,boost_down_threshold = <0x14>; + nvidia,type = <0x1>; + nvidia,down_wmark_window = [02]; + nvidia,reg_offs = <0x100>; + status = "okay"; + nvidia,boost_up_coef = <0xc8>; + #address-cells = <0x1>; + #size-cells = <0x0>; + nvidia,avg_window_log2 = [06]; + nvidia,irq_mask = <0x2>; + nvidia,boost_freq_step = <0x31ce0>; + }; + }; + + nvpmodel { + compatible = "nvidia,nvpmodel"; + status = "okay"; + }; + + tegra-hsp@c150000 { + compatible = "nvidia,tegra186-hsp"; + status = "okay"; + interrupts = <0x0 0x85 0x4 0x0 0x86 0x4 0x0 0x87 0x4 0x0 0x88 0x4>; + phandle = <0xe8>; + reg = <0x0 0xc150000 0x0 0x90000>; + linux,phandle = <0xe8>; + interrupt-names = "shared1", "shared2", "shared3", "shared4"; + }; + + pwm@3290000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbc 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x64>; + clock-names = "pwm", "parent", "slow-parent"; + status = "okay"; + phandle = <0x188>; + reg = <0x0 0x3290000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x188>; + #pwm-cells = <0x2>; + }; + + arm-pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0x0 0x140 0x4 0x0 0x141 0x4 0x0 0x128 0x4 0x0 0x129 0x4 0x0 0x12a 0x4 0x0 0x12b 0x4>; + interrupt-affinity = <0x2 0x3 0x4 0x5 0x6 0x7>; + }; + + axi2apb@23b0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23b0000 0x0 0x1000>; + }; + + tegra186-pm-irq { + compatible = "nvidia,tegra186-pm-irq"; + #interrupt-cells = <0x3>; + interrupt-parent = <0x1>; + phandle = <0x3a>; + linux,phandle = <0x3a>; + interrupt-controller; + }; + + axip2p@2130000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2130000 0x0 0x1000>; + }; + + xotg { + compatible = "nvidia,tegra186-xotg"; + otg-rev = <0x300>; + phy-names = "otg-usb2"; + extcon-cable-names = "id", "vbus"; + status = "okay"; + interrupts = <0x0 0xa7 0x4>; + adp-disable; + phandle = <0xab>; + extcon-cables = <0xa0 0x1 0xa0 0x0>; + phys = <0xa1 0x10>; + #extcon-cells = <0x1>; + linux,phandle = <0xab>; + }; + + vm_service { + compatible = "shyper"; + interrupts = <0x0 0x100 0x1>; + }; + + pmc@c370000 { + compatible = "nvidia,tegra186-aowake"; + status = "okay"; + phandle = <0x1d1>; + nvidia,invert-interrupt; + reg = <0x0 0xc370000 0x0 0x600>; + linux,phandle = <0x1d1>; + }; + + gpio-keys { + compatible = "gpio-keys"; + gpio-keys,name = "gpio-keys"; + + volume_up { + gpios = <0x28 0x39 0x1>; + label = "Volume Up"; + linux,code = <0x73>; + }; + + power { + gpios = <0x28 0x38 0x1>; + label = "Power"; + gpio-key,wakeup; + linux,code = <0x74>; + }; + + volume_down { + gpios = <0x28 0x3a 0x1>; + label = "Volume Down"; + linux,code = <0x72>; + }; + }; + + serial@3110000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0x38 0x10 0x10d>; + resets = <0x10 0x30>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "NILL"; + interrupts = <0x0 0x71 0x4>; + dma-names = "rx", "tx"; + phandle = <0x18d>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3110000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x9 0x25 0x9>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x18d>; + }; + + chipid@100000 { + compatible = "nvidia,tegra186-chipid"; + status = "disabled"; + reg = <0x0 0x100000 0x0 0x10000>; + }; + + power-domain { + compatible = "tegra-power-domains"; + + disc-pd { + compatible = "nvidia,tegra186-disc-pd"; + partition-id = <0x4>; + phandle = <0x197>; + linux,phandle = <0x197>; + #power-domain-cells = <0x0>; + }; + + adsp-pd { + power-domains = <0x45>; + compatible = "nvidia,tegra186-adsp-pd"; + phandle = <0x193>; + linux,phandle = <0x193>; + is_off; + #power-domain-cells = <0x0>; + }; + + ape-pd { + compatible = "nvidia,tegra186-ape-pd"; + clocks = <0x10 0x69 0x10 0x68 0x10 0x8a 0x10 0x111>; + clock-names = "ape", "apb2ape", "adsp", "aclk"; + partition-id = <0x0>; + phandle = <0x45>; + linux,phandle = <0x45>; + is_off; + #power-domain-cells = <0x0>; + }; + + xusba-pd { + compatible = "nvidia,tegra186-xusba-pd"; + partition-id = <0xd>; + phandle = <0x198>; + linux,phandle = <0x198>; + #power-domain-cells = <0x0>; + }; + + disb-pd { + compatible = "nvidia,tegra186-disb-pd"; + partition-id = <0x3>; + phandle = <0x196>; + linux,phandle = <0x196>; + #power-domain-cells = <0x0>; + }; + + sata-pd { + compatible = "nvidia,tegra186-sata-pd"; + partition-id = <0xa>; + phandle = <0x195>; + linux,phandle = <0x195>; + #power-domain-cells = <0x0>; + }; + + xusbc-pd { + compatible = "nvidia,tegra186-xusbc-pd"; + partition-id = <0xf>; + phandle = <0x19a>; + linux,phandle = <0x19a>; + #power-domain-cells = <0x0>; + }; + + disa-pd { + compatible = "nvidia,tegra186-disa-pd"; + partition-id = <0x2>; + phandle = <0x94>; + linux,phandle = <0x94>; + #power-domain-cells = <0x0>; + }; + + pcie-pd { + compatible = "nvidia,tegra186-pcie-pd"; + partition-id = <0x9>; + phandle = <0x194>; + linux,phandle = <0x194>; + is_off; + #power-domain-cells = <0x0>; + }; + + xusbb-pd { + compatible = "nvidia,tegra186-xusbb-pd"; + partition-id = <0xe>; + phandle = <0x199>; + linux,phandle = <0x199>; + #power-domain-cells = <0x0>; + }; + }; + + bpmp_i2c { + compatible = "nvidia,tegra186-bpmp-i2c"; + adapter = <0x5>; + status = "okay"; + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0x17c>; + linux,phandle = <0x17c>; + + spmic@3c { + maxim,avoid-power-off-commands; + compatible = "maxim,max77620"; + maxim,hot-die-threshold-temp = <0x1adb0>; + #thermal-sensor-cells = <0x0>; + gpio-controller; + maxim,enable-clock32k-out; + #interrupt-cells = <0x2>; + interrupt-parent = <0x3a>; + maxim,system-pmic-power-off; + interrupts = <0x0 0xd1 0x0>; + phandle = <0x22>; + reg = <0x3c>; + #gpio-cells = <0x2>; + pinctrl-0 = <0x3b>; + linux,phandle = <0x22>; + pinctrl-names = "default"; + interrupt-controller; + + spmic_gpio_input { + gpios = <0x5 0x0 0x6 0x0>; + gpio-hog; + label = "spmic_gpio_input_5", "spmic_gpio_input_6"; + input; + }; + + backup-battery { + backup-battery-output-resister = <0x64>; + status = "disabled"; + backup-battery-charging-current = <0x64>; + backup-battery-charging-voltage = <0x2dc6c0>; + }; + + pinmux@0 { + phandle = <0x3b>; + linux,phandle = <0x3b>; + + pin_gpio6 { + pins = "gpio6"; + function = "gpio"; + drive-push-pull = <0x1>; + }; + + pin_gpio4 { + pins = "gpio4"; + function = "32k-out1"; + drive-push-pull = <0x1>; + }; + + pin_gpio2 { + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x7>; + maxim,active-fps-power-down-slot = <0x1>; + pins = "gpio2"; + status = "disabled"; + function = "fps-out"; + }; + + pin_gpio0 { + pins = "gpio0"; + function = "gpio"; + }; + + pin_gpio7 { + pins = "gpio7"; + function = "gpio"; + drive-push-pull = <0x1>; + }; + + pin_gpio5 { + pins = "gpio5"; + function = "gpio"; + drive-push-pull = <0x0>; + }; + + pin_gpio3 { + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x1>; + maxim,active-fps-power-down-slot = <0x7>; + pins = "gpio3"; + status = "disabled"; + function = "fps-out"; + }; + + pin_gpio1 { + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x1>; + maxim,active-fps-power-down-slot = <0x3>; + pins = "gpio1"; + function = "fps-out"; + }; + }; + + fps { + + fps0 { + maxim,fps-event-source = <0x0>; + shutdown-fps-time-period-us = <0x280>; + }; + + fps1 { + maxim,fps-event-source = <0x1>; + device-state-on-disabled-event = <0x0>; + shutdown-fps-time-period-us = <0x280>; + }; + + fps2 { + maxim,fps-event-source = <0x0>; + maxim,shutdonw-fps-time-period-us = <0x280>; + }; + }; + + watchdog { + maxim,wdt-clear-time = <0xd>; + maxim,wdt-timeout = <0x10>; + status = "disabled"; + phandle = <0xfe>; + linux,phandle = <0xfe>; + }; + + regulators { + in-ldo6-supply = <0x12>; + in-ldo7-8-supply = <0x3c>; + in-ldo4-supply = <0x12>; + + ldo8 { + maxim,active-fps-source = <0x4>; + phandle = <0x10d>; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "dvdd-pex"; + linux,phandle = <0x10d>; + }; + + ldo6 { + maxim,active-fps-source = <0x3>; + regulator-boot-on; + maxim,ramp-rate-setting = <0x186a0>; + phandle = <0x10c>; + regulator-always-on; + regulator-name = "spmic-ldo6"; + linux,phandle = <0x10c>; + regulator-ramp-delay = <0x186a0>; + }; + + sd2 { + regulator-enable-ramp-delay = <0xfa0>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x0>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x7>; + regulator-init-mode = <0x2>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x5208>; + phandle = <0x12>; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-name = "vdd-1v8"; + linux,phandle = <0x12>; + regulator-ramp-delay = <0x1c2>; + }; + + ldo4 { + regulator-enable-ramp-delay = <0x1a>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x1>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x7>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-disable-ramp-delay = <0x672>; + phandle = <0x17e>; + regulator-always-on; + regulator-name = "vdd-rtc"; + linux,phandle = <0x17e>; + regulator-ramp-delay = <0x80e8>; + }; + + sd0 { + regulator-enable-ramp-delay = <0x116>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x5>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x2>; + regulator-init-mode = <0x2>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x255a8>; + phandle = <0xb4>; + regulator-always-on; + regulator-name = "vddio-ddr"; + linux,phandle = <0xb4>; + regulator-ramp-delay = <0xf5a>; + }; + + ldo2 { + regulator-enable-ramp-delay = <0x98>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x6>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-disable-ramp-delay = <0x36b0>; + phandle = <0xb5>; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-name = "vddio-3v3"; + linux,phandle = <0xb5>; + regulator-ramp-delay = <0x4e20>; + }; + + ldo0 { + regulator-enable-ramp-delay = <0x3e8>; + maxim,active-fps-source = <0x3>; + maxim,active-fps-power-up-slot = <0x3>; + maxim,active-fps-power-down-slot = <0x3>; + maxim,ramp-rate-setting = <0x186a0>; + phandle = <0x10e>; + regulator-name = "spmic-ldo0"; + linux,phandle = <0x10e>; + regulator-ramp-delay = <0x186a0>; + }; + + ldo7 { + regulator-enable-ramp-delay = <0x5f>; + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x4>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + maxim,ramp-rate-setting = <0x186a0>; + regulator-disable-ramp-delay = <0x3a98>; + phandle = <0x89>; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-always-on; + regulator-name = "vdd-pex-1v00"; + linux,phandle = <0x89>; + regulator-ramp-delay = <0x2710>; + }; + + sd3 { + regulator-enable-ramp-delay = <0x23e>; + maxim,active-fps-source = <0x0>; + maxim,active-fps-power-up-slot = <0x6>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x9c40>; + phandle = <0x13>; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-name = "vdd-3v3-sys"; + linux,phandle = <0x13>; + regulator-ramp-delay = <0x157c>; + }; + + ldo5 { + regulator-enable-ramp-delay = <0x135>; + maxim,active-fps-source = <0x4>; + maxim,active-fps-power-up-slot = <0x0>; + maxim,active-fps-power-down-slot = <0x7>; + maxim,ramp-rate-setting = <0x1388>; + regulator-disable-ramp-delay = <0x3e80>; + phandle = <0x16>; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "avdd-ts-hv"; + linux,phandle = <0x16>; + regulator-ramp-delay = <0x20e>; + }; + + sd1 { + regulator-enable-ramp-delay = <0xd3>; + maxim,active-fps-source = <0x1>; + maxim,active-fps-power-up-slot = <0x3>; + regulator-boot-on; + maxim,active-fps-power-down-slot = <0x1>; + regulator-init-mode = <0x2>; + maxim,ramp-rate-setting = <0x6b6c>; + regulator-disable-ramp-delay = <0x9c40>; + phandle = <0x3c>; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x124f80>; + regulator-always-on; + regulator-name = "avdd_dsi_csi"; + linux,phandle = <0x3c>; + regulator-ramp-delay = <0x157c>; + }; + + ldo3 { + regulator-enable-ramp-delay = <0xa0>; + maxim,active-fps-source = <0x3>; + maxim,active-fps-power-up-slot = <0x0>; + maxim,active-fps-power-down-slot = <0x7>; + maxim,ramp-rate-setting = <0x1388>; + regulator-disable-ramp-delay = <0x3e80>; + phandle = <0x1c>; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vddio-sdmmc1"; + linux,phandle = <0x1c>; + regulator-ramp-delay = <0x3e8>; + }; + + ldo1 { + regulator-enable-ramp-delay = <0x3e8>; + maxim,active-fps-source = <0x4>; + maxim,ramp-rate-setting = <0x186a0>; + phandle = <0x17d>; + regulator-name = "spmic-ldo1"; + linux,phandle = <0x17d>; + regulator-ramp-delay = <0x186a0>; + }; + }; + }; + }; + + axip2p@2170000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2170000 0x0 0x1000>; + }; + + i2c@c240000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xda 0x10 0x10d 0x10 0xdd>; + resets = <0x10 0x14>; + scl-gpio = <0x28 0x30 0x0>; + sda-gpio = <0x28 0x31 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1a 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x175>; + reg = <0x0 0xc240000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x16 0x25 0x16>; + reset-names = "i2c"; + linux,phandle = <0x175>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + ak8963@0d { + compatible = "ak,ak89xx"; + magnetic_field_matrix = [01 00 00 00 01 00 00 00 01]; + status = "disabled"; + phandle = <0x111>; + reg = <0xd>; + linux,phandle = <0x111>; + }; + + i2cmux@70 { + vcc-pullup-supply = <0x26>; + compatible = "nxp,pca9546"; + status = "disabled"; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2e>; + phandle = <0x10f>; + reg = <0x70>; + linux,phandle = <0x10f>; + + i2c@0 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0>; + + tas2552.9-0040@40 { + compatible = "ti,tas2552"; + iovdd-supply = <0x2e>; + phandle = <0x117>; + reg = <0x40>; + vbat-supply = <0x26>; + avdd-supply = <0x2f>; + tas2552,pdm_edge_select = <0x0>; + linux,phandle = <0x117>; + }; + + tas2552.9-0041@41 { + compatible = "ti,tas2552"; + iovdd-supply = <0x2e>; + phandle = <0x119>; + reg = <0x41>; + vbat-supply = <0x26>; + avdd-supply = <0x2f>; + tas2552,pdm_edge_select = <0x1>; + linux,phandle = <0x119>; + }; + }; + + i2c@3 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x3>; + + rt5659.12-001a@1a { + gpios = <0x1b 0x4d 0x0>; + compatible = "realtek,rt5658"; + realtek,dmic1-data-pin = <0x2>; + status = "disabled"; + phandle = <0x11b>; + reg = <0x1a>; + realtek,jd-src = <0x1>; + linux,phandle = <0x11b>; + }; + }; + + i2c@1 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x1>; + + ina3221x@41 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x41>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_1V8_AUD"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_5V_AUD"; + ti,shunt-resistor-mohm = <0x1>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_3V3_AUD"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + ina3221x@42 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x42>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_3V3_GYRO"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_3V3_GPS"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_3V3_NFC"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + ina3221x@40 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x40>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_1V8"; + ti,shunt-resistor-mohm = <0x1>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_5V"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_3V3"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + }; + + i2c@2 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x2>; + }; + }; + + rt5659.1-001a@1a { + gpios = <0x1b 0x4d 0x0>; + compatible = "realtek,rt5658"; + realtek,dmic1-data-pin = <0x2>; + status = "disabled"; + phandle = <0x11a>; + reg = <0x1a>; + realtek,jd-src = <0x1>; + linux,phandle = <0x11a>; + }; + + lp8556-backlight-s-wqxga-10-1@2c { + compatible = "ti,lp8556"; + init-brt = [ff]; + pwm-period = <0x9ce1>; + dev-ctrl = [80]; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + disable-on-kernel-charging; + pwm-names = "lp8556"; + status = "disabled"; + bl-name = "pwm-backlight"; + phandle = <0x11d>; + reg = <0x2c>; + pwms = <0x27 0x0 0x9ce1>; + linux,phandle = <0x11d>; + }; + + ov23850_c@36 { + compatible = "nvidia,ov23850"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "7.3998"; + iovdd-reg = "vif"; + vcmvdd-reg = "vvcm"; + vdig-supply = <0x2a>; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x1b 0x89 0x0>; + phandle = <0x136>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x6a 0x0>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x136>; + vif-supply = <0x2b>; + physical_h = "5.5998"; + vvcm-suply = <0x2c>; + + mode0 { + line_length = "5922"; + active_w = "5632"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "600000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "15.5"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = "270"; + min_gain_val = "1.0"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + csi_pixel_bit_depth = "10"; + min_framerate = "3.09135"; + max_framerate = "30"; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + active_h = "3168"; + max_exp_time = "323094"; + mclk_multiplier = "25"; + min_exp_time = "19.74"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x2d>; + bus-width = <0x4>; + phandle = <0x139>; + linux,phandle = <0x139>; + }; + }; + }; + }; + + bmp280@77 { + compatible = "bmp,bmpX80"; + status = "disabled"; + phandle = <0x112>; + reg = <0x77>; + linux,phandle = <0x112>; + }; + + icm20628@68 { + compatible = "invensense,mpu6xxx"; + gyroscope_matrix = [01 00 00 00 01 00 00 00 01]; + vlogic-supply = <0x13>; + gyroscope_uncalibrated_disable = <0x1>; + status = "disabled"; + interrupt-parent = <0x28>; + interrupts = <0x2a 0x1>; + phandle = <0x110>; + quaternion_disable = <0x1>; + vdd-supply = <0x13>; + reg = <0x68>; + accelerometer_matrix = [01 00 00 00 01 00 00 00 01]; + geomagnetic_rotation_vector_disable = <0x1>; + linux,phandle = <0x110>; + }; + + bmi160@69 { + compatible = "bmi,bmi160"; + gyroscope_matrix = [01 00 00 00 01 00 00 00 01]; + vdd_IO-supply = <0x13>; + gyroscope_delay_us_min = <0x4e2>; + status = "disabled"; + interrupt-parent = <0x28>; + interrupts = <0x2a 0x1>; + accelerometer_delay_us_min = <0x4e2>; + vdd-supply = <0x13>; + reg = <0x69>; + accelerometer_matrix = [01 00 00 00 01 00 00 00 01]; + }; + + iqs263@44 { + status = "disabled"; + phandle = <0x17b>; + linux,phandle = <0x17b>; + }; + + gpio@20 { + compatible = "ti,tca6416"; + gpio-controller; + status = "disabled"; + vcc-supply = <0x26>; + phandle = <0xea>; + reg = <0x20>; + #gpio-cells = <0x2>; + linux,phandle = <0xea>; + }; + + cm32180@48 { + compatible = "capella,cm32180"; + light_uncalibrated_hi = <0x17318>; + light_calibrated_hi = <0x1ab3f0>; + gpio_irq = <0x1b 0x44 0x1>; + status = "disabled"; + phandle = <0x113>; + light_uncalibrated_lo = <0x1>; + reg = <0x48>; + light_calibrated_lo = <0x96>; + linux,phandle = <0x113>; + }; + }; + + roc-flush@e080000 { + compatible = "nvidia,tegra186-roc-flush"; + status = "disabled"; + reg = <0x0 0xe080000 0x0 0x10000>; + }; + + cpufreq@e070000 { + compatible = "nvidia,tegra18x-cpufreq"; + nvidia,enable-autocc3 = <0x0 0x1 0x1 0x1>; + cpu_emc_map = <0x79e00 0x31ce0 0x9f600 0x639c0 0x15ae00 0xa2800 0x1d4c00 0x1c7910>; + nvidia,autocc3-freq = <0x0 0x0 0x1 0x0>; + status = "okay"; + reg = <0x0 0xe000000 0x0 0x80000>; + }; + + i2c@3160000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x2f 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x13>; + scl-gpio = <0x1b 0x15 0x0>; + sda-gpio = <0x1b 0x16 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x19 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x106>; + reg = <0x0 0x3160000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x15 0x25 0x15>; + reset-names = "i2c"; + linux,phandle = <0x106>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + ina3221x@43 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x43>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_3V3_SYS_M2"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_3V3_IO_SLP"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_1V8_IO"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + tps65132@3e { + compatible = "ti,tps65132"; + status = "disabled"; + phandle = <0x11c>; + reg = <0x3e>; + linux,phandle = <0x11c>; + + outn { + enable-active-high; + phandle = <0x87>; + regulator-min-microvolt = <0x3d0900>; + regulator-max-microvolt = <0x5b8d80>; + ti,disable-active-discharge; + regulator-name = "outn"; + linux,phandle = <0x87>; + }; + + outp { + enable-active-high; + phandle = <0x86>; + regulator-min-microvolt = <0x3d0900>; + regulator-max-microvolt = <0x5b8d80>; + regulator-name = "outp"; + linux,phandle = <0x86>; + }; + }; + + ina3221x@41 { + compatible = "ti,ina3221x"; + #io-channel-cells = <0x1>; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0xf1>; + reg = <0x41>; + linux,phandle = <0xf1>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_SYS_DDR"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_IN"; + ti,shunt-resistor-mohm = <0x14>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_SYS_CPU"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + gpio@21 { + compatible = "ti,tca6408"; + gpio-controller; + status = "disabled"; + vcc-supply = <0x26>; + phandle = <0x40>; + reg = <0x21>; + #gpio-cells = <0x2>; + linux,phandle = <0x40>; + + vpp-vmm-rails { + gpios = <0x2 0x0>; + gpio-hog; + label = "vmm-en-rail"; + output-high; + }; + }; + + gpio@74 { + compatible = "ti,tca9539"; + gpio-controller; + vcc-supply = <0x26>; + phandle = <0xe9>; + reg = <0x74>; + #gpio-cells = <0x2>; + linux,phandle = <0xe9>; + + touch-rails { + gpios = <0x1 0x0 0x2 0x0>; + gpio-hog; + label = "touch-rail-1", "touch-rail-2"; + output-high; + }; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + compatible = "ti,lp8557"; + init-brt = [ff]; + bl-curve = <0x0 0x1 0x1 0x2 0x2 0x3 0x3 0x4 0x4 0x5 0x5 0x6 0x7 0x7 0x8 0x8 0x9 0x9 0xa 0xa 0xb 0xb 0xc 0xc 0xd 0xe 0xe 0xf 0xf 0x10 0x10 0x11 0x11 0x12 0x12 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x18 0x18 0x19 0x19 0x1a 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1e 0x1e 0x1f 0x1f 0x20 0x21 0x21 0x22 0x22 0x23 0x23 0x24 0x24 0x25 0x25 0x26 0x26 0x27 0x28 0x28 0x29 0x29 0x2a 0x2a 0x2b 0x2b 0x2c 0x2c 0x2d 0x2e 0x2e 0x2f 0x2f 0x30 0x30 0x31 0x31 0x32 0x32 0x33 0x34 0x34 0x35 0x35 0x36 0x36 0x37 0x37 0x38 0x38 0x39 0x39 0x3a 0x3b 0x3b 0x3c 0x3c 0x3d 0x3d 0x3e 0x3e 0x3f 0x3f 0x40 0x41 0x41 0x42 0x42 0x43 0x43 0x44 0x44 0x45 0x45 0x46 0x46 0x47 0x48 0x48 0x49 0x49 0x4a 0x4a 0x4b 0x4b 0x4c 0x4c 0x4d 0x4e 0x4e 0x4f 0x4f 0x50 0x50 0x51 0x51 0x52 0x52 0x53 0x53 0x54 0x55 0x55 0x56 0x56 0x57 0x57 0x58 0x58 0x59 0x59 0x5a 0x5c 0x5e 0x60 0x61 0x63 0x65 0x67 0x69 0x6b 0x6d 0x6e 0x70 0x72 0x74 0x76 0x78 0x7a 0x7b 0x7d 0x7f 0x81 0x83 0x85 0x86 0x88 0x8a 0x8c 0x8e 0x90 0x92 0x93 0x95 0x97 0x99 0x9b 0x9d 0x9f 0xa0 0xa2 0xa4 0xa6 0xa8 0xaa 0xac 0xad 0xaf 0xb1 0xb3 0xb5 0xb7 0xb9 0xba 0xbc 0xbe 0xc0 0xc2 0xc4 0xc6 0xc7 0xc9 0xcb 0xcd 0xcf 0xd1 0xd3 0xd4 0xd6 0xd8 0xda 0xdc 0xde 0xdf 0xe1 0xe3 0xe5 0xe7 0xe9 0xeb 0xec 0xee 0xf0 0xf2 0xf4 0xf6 0xf8 0xf9 0xfb 0xfd 0xff>; + pwm-period = <0x9ce1>; + dev-ctrl = [80]; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + disable-on-kernel-charging; + pwm-names = "lp8557"; + status = "disabled"; + bl-name = "pwm-backlight"; + phandle = <0xf3>; + reg = <0x2c>; + pwms = <0x27 0x0 0x9ce1>; + linux,phandle = <0xf3>; + power-supply = <0x26>; + + rom_14h { + rom-addr = [14]; + rom-val = [9f]; + }; + + rom_13h { + rom-addr = [13]; + rom-val = [01]; + }; + + rom_11h { + rom-addr = [11]; + rom-val = [05]; + }; + }; + + ina3221x@42 { + compatible = "ti,ina3221x"; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x42>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_3V3_SYS"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_MUX"; + ti,shunt-resistor-mohm = <0x14>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_5V0_IO_SYS"; + ti,shunt-resistor-mohm = <0x5>; + reg = <0x1>; + }; + }; + + ina3221x@40 { + compatible = "ti,ina3221x"; + #io-channel-cells = <0x1>; + ti,enable-forced-continuous; + ti,trigger-config = <0x7003>; + #address-cells = <0x1>; + #size-cells = <0x0>; + phandle = <0xf0>; + reg = <0x40>; + linux,phandle = <0xf0>; + ti,continuous-config = <0x7c07>; + + channel@2 { + ti,rail-name = "VDD_4V0_WIFI"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x2>; + }; + + channel@0 { + ti,rail-name = "VDD_SYS_GPU"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x0>; + }; + + channel@1 { + ti,rail-name = "VDD_SYS_SOC"; + ti,shunt-resistor-mohm = <0xa>; + reg = <0x1>; + }; + }; + + gpio@77 { + compatible = "ti,tca9539"; + gpio-controller; + vcc-supply = <0x26>; + phandle = <0x8d>; + reg = <0x77>; + #gpio-cells = <0x2>; + linux,phandle = <0x8d>; + + lcd-bias-rails { + gpios = <0x4 0x0>; + gpio-hog; + label = "lcd-bias-en-rail"; + output-high; + }; + }; + }; + + serial@3150000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xc3 0x10 0x10d>; + resets = <0x10 0x6f>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "disabled"; + interrupts = <0x0 0x75 0x4>; + dma-names = "rx", "tx"; + phandle = <0x191>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3150000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0xc 0x25 0xc>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x191>; + }; + + tegra-hsp@3c00000 { + compatible = "nvidia,tegra186-hsp"; + status = "okay"; + interrupts = <0x0 0xb0 0x4 0x0 0x78 0x4 0x0 0x79 0x4 0x0 0x7a 0x4 0x0 0x7b 0x4 0x0 0x7c 0x4 0x0 0x7d 0x4 0x0 0x7e 0x4 0x0 0x7f 0x4>; + phandle = <0x1d5>; + reg = <0x0 0x3c00000 0x0 0xa0000>; + linux,phandle = <0x1d5>; + interrupt-names = "doorbell", "shared0", "shared1", "shared2", "shared3", "shared4", "shared5", "shared6", "shared7"; + }; + + xudc@3550000 { + compatible = "nvidia,tegra186-xudc"; + clocks = <0x10 0xf3 0x10 0x72 0x10 0xf2 0x10 0xf5>; + otg-controller = <0xab>; + iommu_sodev_map; + avdd-usb-supply = <0x13>; + phy-names = "usb2"; + extcon-cable-names = "vbus"; + status = "okay"; + nvidia,boost-cpu-freq = <0x4b0>; + interrupts = <0x0 0xa6 0x4>; + phandle = <0x1cf>; + extcon-cables = <0xa0 0x0>; + phys = <0x9e>; + reg = <0x0 0x3550000 0x0 0x8000 0x0 0x3558000 0x0 0x1000>; + iommus = <0x11 0x1c>; + nvidia,xusb-padctl = <0x9f>; + #extcon-cells = <0x1>; + linux,phandle = <0x1cf>; + charger-detector = <0xaf>; + }; + + iommu@12000000 { + compatible = "arm,mmu-500"; + #iommu-cells = <0x1>; + #global-interrupts = <0x2>; + status = "okay"; + interrupts = <0x0 0xaa 0x4 0x0 0xab 0x4>; + phandle = <0x11>; + reg = <0x0 0x12000000 0x0 0x1000000>; + linux,phandle = <0x11>; + suspend-save-reg = <0xc390868>; + + domains { + + xusb_host_domain { + address-space = <0x9a>; + sid-list = <0x1b>; + }; + + host1x2_domain { + address-space = <0x99>; + sid-list = <0x3a>; + }; + + sdmmc4a_domain { + address-space = <0x9a>; + sid-list = <0x17>; + }; + + host1x_client_domain { + address-space = <0x99>; + sid-list = <0x3 0x4 0x6 0x7 0x8 0x5 0xa 0xb 0x9 0x2 0x2b 0xc 0xd 0xe 0xf>; + }; + + sdmmc1a_domain { + address-space = <0x9a>; + sid-list = <0x1a>; + }; + + host1x1_domain { + address-space = <0x99>; + sid-list = <0x39>; + }; + + ufshci_domain { + address-space = <0x9a>; + sid-list = <0x15>; + }; + + host1x7_domain { + address-space = <0x99>; + sid-list = <0x3f>; + }; + + bpmp_domain { + address-space = <0x9a>; + sid-list = <0x32>; + }; + + sata2_domain { + address-space = <0x9a>; + sid-list = <0x1d>; + }; + + host1x0_domain { + address-space = <0x99>; + sid-list = <0x38>; + }; + + host1x6_domain { + address-space = <0x99>; + sid-list = <0x3e>; + }; + + sdmmc2a_domain { + address-space = <0x9a>; + sid-list = <0x19>; + }; + + gpu_domain { + address-space = <0x97>; + sid-list = <0x10>; + }; + + ape_domain { + address-space = <0x9b>; + sid-list = <0x1e 0x14>; + }; + + gpcdma_domain { + address-space = <0x9a>; + sid-list = <0x20>; + }; + + rtcpu_domain { + address-space = <0x9d>; + sid-list = <0x2a 0x2d>; + }; + + host1x5_domain { + address-space = <0x99>; + sid-list = <0x3d>; + }; + + hda_domain { + address-space = <0x9a>; + sid-list = <0x12>; + }; + + host1x4_domain { + address-space = <0x99>; + sid-list = <0x3c>; + }; + + xusb_dev_domain { + address-space = <0x9a>; + sid-list = <0x1c>; + }; + + sdmmc3a_domain { + address-space = <0x9a>; + sid-list = <0x18>; + }; + + aon_domain { + address-space = <0x9a>; + sid-list = <0x16>; + }; + + host1x_domain { + address-space = <0x98>; + sid-list = <0x1>; + }; + + smmu_test_domain { + address-space = <0x9a>; + sid-list = <0x33>; + }; + + afi_domain { + address-space = <0x9c>; + sid-list = <0x11>; + }; + + host1x3_domain { + address-space = <0x99>; + sid-list = <0x3b>; + }; + + sce_domain { + address-space = <0x9a>; + sid-list = <0x1f>; + }; + }; + + address-space-prop { + + camera { + iova-size = <0x0 0x20000000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0xa0000000>; + phandle = <0x9d>; + linux,phandle = <0x9d>; + }; + + gpu { + iova-size = <0x3ff 0xffefffff>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x0>; + iova-start = <0x0 0x100000>; + phandle = <0x97>; + linux,phandle = <0x97>; + }; + + pcie_as { + iova-size = <0x0 0xffffffff>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x80000000>; + phandle = <0x9c>; + linux,phandle = <0x9c>; + }; + + host1x_client { + iova-size = <0x1f 0xfffff000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x1000>; + phandle = <0x99>; + linux,phandle = <0x99>; + }; + + ape { + iova-size = <0x0 0x20000000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x40000000>; + phandle = <0x9b>; + linux,phandle = <0x9b>; + }; + + host1x { + iova-size = <0x0 0xfffff000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x1000>; + phandle = <0x98>; + linux,phandle = <0x98>; + }; + + common { + iova-size = <0x0 0x7ff00000>; + num-pf-page = <0x0>; + alignment = <0xfffff>; + gap-page = <0x1>; + iova-start = <0x0 0x80000000>; + phandle = <0x9a>; + linux,phandle = <0x9a>; + }; + }; + }; + + mods-simple-bus { + compatible = "simple-bus"; + device_type = "mods-simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + mods-clocks { + compatible = "nvidia,mods-clocks"; + clocks = <0x10 0x264 0x10 0x261 0x10 0x260 0x10 0x262 0x10 0x37 0x10 0x38 0x10 0xd7 0x10 0x4d 0x10 0xc2 0x10 0xc3 0x10 0xd8 0x10 0x57 0x10 0x68 0x10 0x69 0x10 0x4f 0x10 0x2a 0x10 0x2b 0x10 0x54 0x10 0x55 0x10 0x9a 0x10 0x7a 0x10 0x7b 0x10 0x96 0x10 0x97 0x10 0xdf 0x10 0x2c 0x10 0xee 0x10 0x98 0x10 0x99 0x10 0x6a 0x10 0x6b 0x10 0x7c 0x10 0xb4 0x10 0x33 0x10 0x32 0x10 0x59 0x10 0x5a 0x10 0x5b 0x10 0x49 0x10 0x63 0x10 0x64 0x10 0x65 0x10 0x84 0x10 0x31 0x10 0xde 0x10 0x2e 0x10 0x4a 0x10 0x2f 0x10 0xda 0x10 0x4b 0x10 0x56 0x10 0x30 0x10 0x7d 0x10 0xb6 0x10 0xdb 0x10 0xb7 0x10 0xdc 0x10 0xb8 0x10 0xb9 0x10 0xba 0x10 0x34 0x10 0x35 0x10 0x4c 0x10 0x36 0x10 0x80 0x10 0x6f 0x10 0x70 0x10 0x71 0x10 0x72 0x10 0xf2 0x10 0xf3 0x10 0xf4 0x10 0xf5 0x10 0x95 0x10 0xbb 0x10 0xbc 0x10 0xbd 0x10 0xe1 0x10 0xbe 0x10 0xbf 0x10 0xc0 0x10 0xc1 0x10 0x3a 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0xb2 0x10 0xb3 0x10 0x8c 0x10 0x8d 0x10 0x8e 0x10 0x8f 0x10 0x90 0x10 0x91 0x10 0x92 0x10 0x93 0x10 0x94 0x10 0x130 0x10 0x131 0x10 0xec 0x10 0x12e 0x10 0x12f 0x10 0xa6 0x10 0x10d 0x10 0x10e 0x10 0x204 0x10 0x11e 0x10 0x10f 0x10 0x20d 0x10 0xf6 0x10 0x120 0x10 0x201 0x10 0xb 0x10 0xc 0x10 0xd 0x10 0x209 0x10 0x20a 0x10 0x20c 0x10 0x6e 0x10 0x114 0x10 0x115 0x10 0x116 0x10 0x117 0x10 0x206 0x10 0x10b 0x10 0x207 0x10 0x210 0x10 0x20b 0x10 0x200 0x10 0x6c 0x10 0x6d 0x10 0x105 0x10 0x106 0x10 0x208 0x10 0x215 0x10 0x112 0x10 0x113>; + resets = <0x10 0x2f 0x10 0x30 0x10 0x31 0x10 0x32 0x10 0x84 0x10 0x6f 0x10 0x70 0x10 0x7b 0x10 0x3e 0x10 0x92 0x10 0x58 0x10 0x33 0x10 0x19 0x10 0xb 0x10 0xc 0x10 0xd 0x10 0x90 0x10 0x1f 0x10 0x81 0x10 0x28 0x10 0x29 0x10 0x2a 0x10 0x2b 0x10 0x13 0x10 0x14 0x10 0x15 0x10 0x16 0x10 0x17 0x10 0x18 0x10 0x51 0x10 0x52 0x10 0x53 0x10 0x4d 0x10 0x4e 0x10 0x4f 0x10 0x50 0x10 0x21 0x10 0x22 0x10 0x23 0x10 0x24 0x10 0x35 0x10 0x36 0x10 0x38 0x10 0x3a 0x10 0x63 0x10 0x64 0x10 0x65 0x10 0x66 0x10 0x67 0x10 0x68 0x10 0x69 0x10 0x6a 0x10 0x71 0x10 0x55 0x10 0x6d>; + clock-names = "osc", "clk_m", "clk_32k", "pll_ref", "uarta", "uartb", "uartc", "uartd", "uarte", "uartf", "uartg", "ahub", "apb2ape", "ape", "i2s1", "i2s2", "i2s3", "i2s4", "i2s5", "i2s6", "dmic1", "dmic2", "dmic3", "dmic4", "dmic5", "spdif_in", "spdif_out", "dspk1", "dspk2", "iqc1", "iqc2", "aud_mclk", "nvcsi", "vi", "isp", "extperiph1", "extperiph2", "extperiph3", "extperiph4", "sata", "sata_oob", "sata_iobist", "qspi", "spi1", "spi2", "spi3", "spi4", "i2c1", "i2c2", "i2c3", "i2c4", "i2c5", "i2c6", "i2c7", "i2c8", "i2c9", "i2c10", "i2c12", "i2c13", "i2c14", "sdmmc1", "sdmmc2", "sdmmc3", "sdmmc4", "sdmmc_legacy_tm", "xusb", "xusb_dev", "xusb_host", "xusb_ss", "xusb_core_ss", "xusb_core_dev", "xusb_falcon", "xusb_fs", "axi_cbb", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7", "pwm8", "emc", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "ufshc", "ufsdev_ref", "mphy_l0_rx_symb", "mphy_l0_rx_ls_bit", "mphy_l0_tx_symb", "mphy_l0_tx_ls_3xbit", "mphy_l0_rx_ana", "mphy_l1_rx_ana", "mphy_iobist", "mphy_tx_1mhz_ref", "mphy_core_pll_fixed", "uphy_pll0_pwrseq", "uphy_pll1_pwrseq", "pex_sata_usb_rx_byp", "pex_usb_pad0_mgmt", "pex_usb_pad1_mgmt", "tach", "pllp_out0", "pllp_out5", "pllp", "pllp_div8", "plla", "plla1", "pll_a_out0", "pll_a_out1", "pllc", "pllc_out_isp", "pllc_out_ve", "pllc_out_aon", "pllc2", "pllc3", "pllc4_vco", "pllc4_out", "pllc4_out0", "pllc4_out1", "pllc4_out2", "pllc4_out_mux", "pll_d", "pll_d_out1", "pll_d2", "pll_d3", "pll_dp", "plle", "pllrefe_out", "pllrefe_pll_ref", "pllrefe_out_gated", "pllrefe_out1", "pllrefe_vco", "pllu", "pllu_48M", "pllu_480M"; + status = "disabled"; + reset-names = "uarta", "uartb", "uartc", "uartd", "uarte", "uartf", "uartg", "ape", "dmic5", "aud_mclk", "nvcsi", "vi", "isp", "extperiph1", "extperiph2", "extperiph3", "extperiph4", "sata", "qspi", "spi1", "spi2", "spi3", "spi4", "i2c1", "i2c2", "i2c3", "i2c4", "i2c5", "i2c6", "i2c7", "i2c8", "i2c9", "i2c10", "i2c12", "i2c13", "i2c14", "sdmmc1", "sdmmc2", "sdmmc3", "sdmmc4", "xusb_dev", "xusb_host", "xusb_ss", "axi_cbb", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7", "pwm8", "ufshc", "mphy_iobist", "tach"; + }; + }; + + tegra_udrm { + compatible = "nvidia,tegra-udrm"; + phandle = <0x1e7>; + linux,phandle = <0x1e7>; + }; + + kfuse@0x3830000 { + compatible = "nvidia,tegra186-kfuse"; + clocks = <0x10 0x125>; + clock-names = "kfuse"; + status = "okay"; + reg = <0x0 0x3830000 0x0 0x10000>; + }; + + usb_cd { + compatible = "nvidia,tegra186-usb-cd"; + phy-names = "otg-phy"; + status = "okay"; + phandle = <0xaf>; + phys = <0x9e>; + nvidia,xusb-padctl = <0x9f>; + linux,phandle = <0xaf>; + }; + + eeprom-manager { + boardid-with-revision = <0xcee>; + boardid-with-config = <0xcee>; + data-size = <0x100>; + + bus@2 { + i2c-bus = <0x106>; + + eeprom@0 { + slave-address = <0x50>; + }; + }; + + bus@0 { + i2c-bus = <0x174>; + + eeprom@0 { + label = "cvm"; + slave-address = <0x50>; + }; + + eeprom@1 { + label = "cvb"; + slave-address = <0x57>; + }; + }; + + bus@3 { + i2c-bus = <0x59>; + + eeprom@0 { + label = "cam"; + slave-address = <0x54>; + enable-gpio = <0x2 0x9>; + }; + + eeprom@1 { + label = "cam"; + slave-address = <0x57>; + enable-gpio = <0x2 0x9>; + }; + }; + + bus@1 { + i2c-bus = <0x175>; + + eeprom@0 { + slave-address = <0x51>; + }; + }; + }; + + interrupt-controller@3881000 { + compatible = "arm,cortex-a15-gic"; + status = "okay"; + #interrupt-cells = <0x3>; + interrupts = <0x1 0x9 0xf04>; + phandle = <0x1>; + reg = <0x0 0x3881000 0x0 0x1000 0x0 0x3882000 0x0 0x2000>; + linux,phandle = <0x1>; + interrupt-controller; + }; + + pfsd { + pwm_id = <0x3>; + active_steps = <0xa>; + state_cap = <0x7>; + num_resources = <0x0>; + active_rrd = <0x28 0x2 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1>; + pwm_gpio = <0x28 0x16 0x1>; + status = "okay"; + step_time = <0x64>; + active_rru = <0x28 0x2 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1>; + active_rpm = <0x0 0x3e8 0x7d0 0xbb8 0xfa0 0x1388 0x1770 0x1b58 0x2710 0x2af8>; + pwm_period = <0xb116>; + phandle = <0xed>; + rpm_diff_tolerance = <0x2>; + active_pwm_max = <0x100>; + state_cap_lookup = <0x2 0x2 0x2 0x2 0x3 0x3 0x3 0x4 0x4 0x4>; + linux,phandle = <0xed>; + tach_period = <0x3e8>; + secret = <0x2f>; + }; + + tegra-serr { + compatible = "nvidia,tegra186"; + }; + + mc_sid@2c00000 { + compatible = "nvidia,tegra186-mc-sid"; + status = "okay"; + reg = <0x0 0x2c00000 0x0 0x10000 0x0 0x2c10000 0x0 0x10000>; + }; + + mttcan@c320000 { + gpio_can_stb = <0x28 0x2e 0x0>; + compatible = "nvidia,tegra186-mttcan"; + clocks = <0x10 0xd4 0x10 0xd5 0x10 0x214>; + resets = <0x10 0x3d>; + reg-names = "can-regs", "glue-regs", "msg-ram"; + clock-names = "can", "can_host", "pllaon"; + rx-config = <0x40 0x40 0x40>; + pll_source = "pllaon"; + mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>; + status = "okay"; + interrupts = <0x0 0x2a 0x4>; + phandle = <0x1d7>; + reg = <0x0 0xc320000 0x0 0x400 0x0 0xc321000 0x0 0x32 0x0 0xc322000 0x0 0x1000>; + gpio_can_en = <0x28 0x2f 0x0>; + reset-names = "can"; + linux,phandle = <0x1d7>; + tx-config = <0x0 0x10 0x0 0x40>; + }; + + mailbox@3538000 { + compatible = "nvidia,tegra186-xusb-mbox"; + #mbox-cells = <0x0>; + status = "okay"; + interrupts = <0x0 0xa4 0x4>; + phandle = <0xb0>; + reg = <0x0 0x3538000 0x0 0x1000>; + linux,phandle = <0xb0>; + }; + + ahci-sata@3507000 { + gpios = <0x22 0x7 0x0>; + power-domains = <0x1f 0xa>; + compatible = "nvidia,tegra186-ahci-sata"; + clocks = <0x10 0x63 0x10 0x64 0x10 0x204 0x10 0x10d>; + iommu_sodev_map; + resets = <0x10 0x1f 0x10 0x20>; + reg-names = "sata-ahci", "sata-config", "sata-ipfs", "sata-aux"; + pinctrl-1 = <0x21>; + clock-names = "sata", "sata-oob", "pllp", "pllp-uphy"; + status = "okay"; + interrupts = <0x0 0xc5 0x4>; + phandle = <0x105>; + nvidia,disable-features = "devslp", "dipm"; + reg = <0x0 0x3507000 0x0 0x2000 0x0 0x3501000 0x0 0x6000 0x0 0x3500000 0x0 0x1000 0x0 0x3a90000 0x0 0x10000>; + iommus = <0x11 0x1d>; + pinctrl-0 = <0x20>; + nvidia,link-flags = "min_power"; + reset-names = "sata", "sata-cold"; + linux,phandle = <0x105>; + pinctrl-names = "devslp_active", "devslp_pullup"; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x1 0x52c 0xffffffff 0x31ce0 0x1 0x338 0x10000000 0x10000000>; + }; + }; + }; + + tegra_skin_thermal { + io-channels = <0xf0 0x0 0xf0 0x1 0xf1 0x3>; + compatible = "nvidia,tegra-skin-thermal"; + io-channel-names = "gpu-voltage", "gpu-current", "vddin-power"; + #thermal-sensor-cells = <0x1>; + + power_feature@1 { + rc_k = <0x1>; + type = <0x1>; + resistance = <0x1>; + phandle = <0xf4>; + linux,phandle = <0xf4>; + #power-feature-cells = <0x1>; + }; + + skin-sensor@2 { + thermal-sensor = <0x2>; + hotspot-list = <0xf8>; + }; + + hotspot@2 { + offset = <0x3>; + rc_k = <0x1>; + phandle = <0xf8>; + power-features-list = <0xf2 0xf3 0xf4 0x2>; + reference-sensor = <0xf5>; + linux,phandle = <0xf8>; + }; + + skin-sensor@0 { + thermal-sensor = <0x0>; + hotspot-list = <0xf6 0xf7>; + }; + + hotspot@0 { + offset = <0x3>; + rc_k = <0x1>; + phandle = <0xf6>; + power-features-list = <0xf2 0xf3 0xf4 0x0 0xf4 0x1>; + reference-sensor = <0xf5>; + linux,phandle = <0xf6>; + }; + + power_feature@0 { + rc_k = <0x1>; + type = <0x0>; + resistance = <0x1>; + phandle = <0xf2>; + linux,phandle = <0xf2>; + #power-feature-cells = <0x1>; + }; + + skin-sensor@1 { + thermal-sensor = <0x1>; + hotspot-list = <0xf7>; + }; + + hotspot@1 { + offset = <0x3>; + rc_k = <0x1>; + phandle = <0xf7>; + power-features-list = <0xf2 0xf3>; + reference-sensor = <0xf5>; + linux,phandle = <0xf7>; + }; + }; + + tpiu@8060000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8060000 0x0 0x1000>; + + port { + + enpoint@0 { + remote-endpoint = <0xe3>; + phandle = <0xdf>; + slave-mode; + linux,phandle = <0xdf>; + }; + }; + }; + + xusb_padctl@3520000 { + pinctrl-5 = <0xa7>; + compatible = "nvidia,tegra18x-xusb-padctl"; + avdd_pll_erefeut-supply = <0x12>; + pinctrl-3 = <0xa5>; + resets = <0x10 0x37>; + reg-names = "padctl", "ao"; + pinctrl-1 = <0xa3>; + status = "okay"; + pinctrl-4 = <0xa6>; + phandle = <0x9f>; + vclamp_usb-supply = <0x12>; + pinctrl-2 = <0xa4>; + reg = <0x0 0x3520000 0x0 0x1000 0x0 0x3540000 0x0 0x1000>; + pinctrl-0 = <0xa2>; + reset-names = "padctl"; + avdd_usb-supply = <0x13>; + linux,phandle = <0x9f>; + pinctrl-names = "vbus_en0_default", "vbus_en1_default", "vbus_en0_sfio_tristate", "vbus_en1_sfio_tristate", "vbus_en0_sfio_passthrough", "vbus_en1_sfio_passthrough"; + + prod-settings { + #prod-cells = <0x4>; + + prod_c_hsic0 { + prod = <0x0 0x344 0x7f 0x2d>; + }; + + prod_c_utmi1 { + prod = <0x0 0xc8 0x1fe0000 0xcc0000>; + }; + + prod_c_bias { + prod = <0x0 0x284 0x38 0x38>; + }; + + prod_c_utmi2 { + prod = <0x0 0x108 0x1fe0000 0xcc0000>; + }; + + prod_c_utmi0 { + prod = <0x0 0x88 0x1fe0000 0xcc0000>; + }; + }; + + ports { + + usb3-0 { + status = "okay"; + nvidia,usb2-companion = <0x1>; + }; + + hsic-0 { + status = "disabled"; + }; + + usb2-2 { + vbus-supply = <0xaa>; + mode = "host"; + status = "okay"; + }; + + usb2-0 { + vbus-supply = <0xa8>; + mode = "otg"; + status = "okay"; + nvidia,oc-pin = <0x0>; + }; + + usb3-1 { + status = "disabled"; + nvidia,usb2-companion = <0x1>; + }; + + usb2-1 { + vbus-supply = <0xa9>; + mode = "host"; + status = "okay"; + nvidia,oc-pin = <0x1>; + }; + + usb3-2 { + status = "disabled"; + }; + }; + + pads { + + usb3 { + + lanes { + + usb3-0 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0xae>; + #phy-cells = <0x0>; + linux,phandle = <0xae>; + }; + + usb3-1 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0x108>; + #phy-cells = <0x0>; + linux,phandle = <0x108>; + }; + + usb3-2 { + status = "okay"; + nvidia,function = "xusb"; + #phy-cells = <0x0>; + }; + }; + }; + + hsic { + clocks = <0x10 0x86>; + clock-names = "trk"; + status = "disabled"; + + lanes { + + hsic-0 { + status = "disabled"; + #phy-cells = <0x0>; + }; + }; + }; + + usb2 { + clocks = <0x10 0x87>; + clock-names = "trk"; + + lanes { + + usb2-2 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0xad>; + #phy-cells = <0x0>; + linux,phandle = <0xad>; + }; + + usb2-0 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0x9e>; + #phy-cells = <0x0>; + linux,phandle = <0x9e>; + }; + + usb2-1 { + status = "okay"; + nvidia,function = "xusb"; + phandle = <0xac>; + #phy-cells = <0x0>; + linux,phandle = <0xac>; + }; + }; + }; + }; + }; + + tegra_cec { + compatible = "nvidia,tegra186-cec"; + clocks = <0x10 0x5e>; + clock-names = "cec"; + status = "okay"; + interrupts = <0x0 0xa2 0x4>; + reg = <0x0 0x3960000 0x0 0x1000>; + }; + + __symbols__ { + e3331_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + aon = "/aon@c160000"; + L2_A57 = "/cpus/l2-cache0"; + csi_chan0 = "/host1x/nvcsi@150c0000/channel@0"; + e2614_i2c_mux = "/i2c@c240000/i2cmux@70"; + vdd_hdmi = "/fixed-regulators/regulator@3"; + spdif_dit3 = "/spdif_dit/spdif-dit.3@3"; + cam_module3 = "/tegra-camera-platform/modules/module3"; + dsic_dpd_disable = "/pmc@c360000/dsic-dpd-disable"; + tegra_sce_ivc = "/sce-ivc-channels"; + tegra_dmic1 = "/aconnect@2a41000/ahub/dmic@2904000"; + en_vdd_vcm_2v8 = "/fixed-regulators/regulator@16"; + cam_module1_drivernode0 = "/tegra-camera-platform/modules/module1/drivernode0"; + tegra_amx3 = "/aconnect@2a41000/ahub/amx@2903200"; + e3333_vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + ptm_a57_0_out_port = "/ptm@9840000/port/endpoint"; + spmic_ldo4 = "/bpmp_i2c/spmic@3c/regulators/ldo4"; + tegra_xusb_padctl = "/pinctrl@3520000"; + liimx274_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + spdif_dit10 = "/spdif_dit/spdif-dit.10@a"; + disa_pd = "/power-domain/disa-pd"; + dp_aux_ch0_i2c = "/i2c@31b0000"; + e3333_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + tca6408_21 = "/i2c@3180000/tca6408@21"; + funnel_major_in_port3 = "/funnel_major@8010000/ports/port@4/endpoint"; + tegra_pmc_iopower = "/pmc-iopower"; + eqos_m40 = "/thermal-zones/GPU-therm/trips/eqos-m40@-40000"; + e3333_cam1 = "/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36"; + vpr = "/reserved-memory/vpr-carveout"; + head2 = "/host1x/nvdisplay@15220000"; + dsib_dpd_enable = "/pmc@c360000/dsib-dpd-enable"; + csi_chan0_port1 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1"; + intc = "/interrupt-controller@3881000"; + en_avdd_disp_3v3 = "/fixed-regulators/regulator@8"; + panel_s_edp_uhdtv_15_6_bl = "/backlight/panel-s-edp-uhdtv-15-6-bl"; + ina3221x_40 = "/i2c@3160000/ina3221x@40"; + e3333_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + tegra_asrc = "/aconnect@2a41000/ahub/asrc@2910000"; + tca9546_70 = "/i2c@3180000/tca9546@70"; + gpio_i2c_0_74 = "/i2c@3160000/gpio@74"; + liimx185_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + xusb_padctl = "/xusb_padctl@3520000"; + tegra_i2s1 = "/aconnect@2a41000/ahub/i2s@2901000"; + dspk_2_dai_link = "/sound/nvidia,dai-link-13"; + denver_1 = "/cpus/cpu@1"; + panel_s_wuxga_8_0 = "/host1x/dsi/panel-s-wuxga-8-0"; + cpu_a57_1 = "/cpus/cpu@3"; + cam_module4_drivernode1 = "/tegra-camera-platform/modules/module4/drivernode1"; + spi2 = "/spi@3230000"; + sdmmc2_e_33V_enable = "/pmc@c360000/sdmmc2_e_33V_enable"; + sdmmc2_e_33V_disable = "/pmc@c360000/sdmmc2_e_33V_disable"; + vdd_usb2_5v = "/fixed-regulators/regulator@17"; + tegra_pwm7 = "/pwm@32e0000"; + tegra_xusb_padctl_pinmux_default = "/pinctrl@3520000/pinmux"; + imx274_cam1 = "/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a"; + funnel_minor_in_port0 = "/funnel_minor@8820000/ports/port@2/endpoint"; + en_mdm_pwr_3v7 = "/fixed-regulators/regulator@9"; + vbus_en1_sfio_tristate_state = "/pinmux@2430000/vbus_en1_oc_tristate"; + gen1_i2c = "/i2c@3160000"; + csi_chan3_port1 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1"; + e2614_icm20628 = "/i2c@c240000/icm20628@68"; + vi_port2 = "/host1x/vi@15700000/ports/port@2"; + eqos_m5 = "/thermal-zones/GPU-therm/trips/eqos-m5@-5000"; + aotag = "/thermal-zones/AO-therm"; + tegra_safety_ivc = "/tegra_safety_ivc"; + spdif_dit1 = "/spdif_dit/spdif-dit.1@1"; + e3323_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + cam_module1 = "/tegra-camera-platform/modules/module1"; + pf_iio_ina3221 = "/tegra_skin_thermal/power_feature@1"; + liimx274_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + host1x_ctx7 = "/host1x/ctx7"; + tegra_amx1 = "/aconnect@2a41000/ahub/amx@2903000"; + e3333_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + tegra_iqc1 = "/aconnect@2a41000/ahub/iqc@290e000"; + sdmmc3 = "/sdhci@3440000"; + lp8556_backlight = "/i2c@c240000/lp8556-backlight-s-wqxga-10-1@2c"; + ufs_dpd_disable = "/pmc@c360000/dpd-disable"; + spmic_ldo2 = "/bpmp_i2c/spmic@3c/regulators/ldo2"; + pcie_pd = "/power-domain/pcie-pd"; + tegra_aon_gpio = "/gpio@c2f0000"; + eqos_p65 = "/thermal-zones/GPU-therm/trips/eqos-p65@65000"; + uartf = "/serial@3150000"; + hdmi_dp1_dpd_enable = "/pmc@c360000/hdmi-dp1-dpd-enable"; + funnel_major_out_port0 = "/funnel_major@8010000/ports/port@0/endpoint"; + replicator_out_port1 = "/replicator@0x8040000/ports/port@1/endpoint"; + bpmpthermal = "/bpmp/bpmpthermal"; + funnel_major_in_port1 = "/funnel_major@8010000/ports/port@2/endpoint"; + ptm_a57_2 = "/ptm@9a40000"; + head0 = "/host1x/nvdisplay@15200000"; + liimx185_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + tegra_xotg = "/xotg"; + sor1_hdmi_display = "/host1x/sor1/hdmi-display"; + tegra_dspk1 = "/aconnect@2a41000/ahub/dspk@2905000"; + ser_b = "/i2c@3180000/tca9546@70/i2c@0/max9295_b@60"; + e3322_csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + fb2_reserved = "/reserved-memory/fb2_carveout"; + dsi = "/host1x/dsi"; + spi0 = "/spi@3210000"; + gen9_i2c = "/i2c@31e0000"; + sor0_dp_display = "/host1x/sor/dp-display"; + csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + tegra_wdt = "/watchdog@30c0000"; + csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + tegra_pwm5 = "/pwm@32c0000"; + e3333_ov5693_out5 = "/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36/ports/port@0/endpoint"; + xusbb_pd = "/power-domain/xusbb-pd"; + A57_CORE_POWER_STATES = "/cpus/a57_core_power_states"; + dser = "/i2c@3180000/tca9546@70/i2c@0/max9296@48"; + e3323_ov23850_out0 = "/i2c@3180000/ov23850_a@10/ports/port@0/endpoint"; + tegra_afc5 = "/aconnect@2a41000/ahub/afc@2907400"; + vi_port0 = "/host1x/vi@15700000/ports/port@0"; + e3322_cam4 = "/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + eqos_tx_tri_state_idle = "/pinmux@2430000/eqos_idle"; + tegra_adx4 = "/aconnect@2a41000/ahub/adx@2903b00"; + e3326_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + tegra_xhci = "/xhci@3530000"; + host1x_ctx5 = "/host1x/ctx5"; + DENVER_C7 = "/cpus/denver_core_power_states/c7"; + sdmmc1 = "/sdhci@3400000"; + spmic_ldo0 = "/bpmp_i2c/spmic@3c/regulators/ldo0"; + dsid_dpd_disable = "/pmc@c360000/dsid-dpd-disable"; + imx390_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + e3322_imx219_out5 = "/i2c@3180000/tca9548@77/i2c@5/imx219_f@10/ports/port@0/endpoint"; + cam_module2_drivernode0 = "/tegra-camera-platform/modules/module2/drivernode0"; + tegra_amixer = "/aconnect@2a41000/ahub/amixer@290bb00"; + ape_hsp = "/aconnect@2a41000/tegra-hsp@29a0000"; + eqos_cool_dev = "/ether_qos@2490000/eqos-cool-dev"; + uartd = "/serial@3130000"; + pwr_i2c = "/bpmp_i2c"; + imx390_cam1 = "/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + tegra_sce = "/rtcpu@b000000"; + ptm_a57_0 = "/ptm@9840000"; + tegra_mvc1 = "/aconnect@2a41000/ahub/mvc@290a000"; + e3323_cam0 = "/i2c@3180000/ov23850_a@10"; + dsic_dpd_enable = "/pmc@c360000/dsic-dpd-enable"; + sce_hsp = "/tegra-hsp@b150000"; + dummy_cool_dev = "/dummy-cool-dev"; + vdd_fan = "/fixed-regulators/regulator@13"; + vdd_1v8_aud2 = "/fixed-regulators/regulator@200"; + e3322_csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + tegra_ext_cdp = "/max16984-cdp"; + funnel_bccplex_in_port0 = "/funnel_bccplex@9010000/ports/port@1/endpoint"; + csi_base = "/host1x/nvcsi@150c0000"; + e2614_gps_wake = "/gps_wake"; + dpaux0 = "/host1x/dpaux@155c0000"; + e3322_csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + pwm_fan_shared_data = "/pfsd"; + pinmux = "/pinmux@2430000"; + csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + camera_as = "/iommu@12000000/address-space-prop/camera"; + csi_chan5 = "/host1x/nvcsi@150c0000/channel@5"; + cam_module0_drivernode1 = "/tegra-camera-platform/modules/module0/drivernode1"; + csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + tegra_pwm3 = "/pwm@32a0000"; + qspi6 = "/spi@3270000"; + cam_module5_drivernode1 = "/tegra-camera-platform/modules/module5/drivernode1"; + tegra_udrm = "/tegra_udrm"; + spdif_dit8 = "/spdif_dit/spdif-dit.8@8"; + tegra_ufs = "/ufshci@2450000"; + sdmmc3_e_33V_enable = "/pmc@c360000/sdmmc3_e_33V_enable"; + mipical_prod_c_dphy_dsi_soc_a01 = "/mipical/prod-settings/prod_c_dphy_dsi/soc_a01"; + e3333_ov5693_out3 = "/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36/ports/port@0/endpoint"; + spmic_sd2 = "/bpmp_i2c/spmic@3c/regulators/sd2"; + pcie_as = "/iommu@12000000/address-space-prop/pcie_as"; + vi_base = "/host1x/vi@15700000"; + tegra_afc3 = "/aconnect@2a41000/ahub/afc@2907200"; + mipical_prod_c_cphy_csi_soc_a01 = "/mipical/prod-settings/prod_c_cphy_csi/soc_a01"; + dp_aux_ch1_i2c = "/i2c@3190000"; + e3322_cam2 = "/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + csi_chan2_port0 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0"; + e3333_csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + tegra_adx2 = "/aconnect@2a41000/ahub/adx@2903900"; + e3323_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + host1x_ctx3 = "/host1x/ctx3"; + liimx274_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + en_vdd_cam_1v2 = "/fixed-regulators/regulator@12"; + imx390_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + sdmmc3_e_33V_disable = "/pmc@c360000/sdmmc3_e_33V_disable"; + tegra_xudc = "/xudc@3550000"; + e3322_imx219_out3 = "/i2c@3180000/tca9548@77/i2c@3/imx219_d@10/ports/port@0/endpoint"; + A57_C7 = "/cpus/a57_core_power_states/c7"; + sor1 = "/host1x/sor1"; + e3326_ov5693_out0 = "/i2c@3180000/ov5693_c@36/ports/port@0/endpoint"; + imx390_imx390_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b/ports/port@0/endpoint"; + uartb = "/serial@3110000"; + tegra_ope1 = "/aconnect@2a41000/ahub/ope@2908000"; + e3322_vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + tegra_i2s6 = "/aconnect@2a41000/ahub/i2s@2901500"; + ptm_a57_1_out_port = "/ptm@9940000/port/endpoint"; + spmic_default = "/bpmp_i2c/spmic@3c/pinmux@0"; + vdd_3v3 = "/fixed-regulators/regulator@14"; + tegra_adsp_audio = "/aconnect@2a41000/adsp_audio"; + generic_reserved = "/reserved-memory/generic_carveout"; + csi_chan5_port0 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0"; + hdr40_i2c1 = "/i2c@c240000"; + tegra_sfc4 = "/aconnect@2a41000/ahub/sfc@2902600"; + pf_backlight = "/tegra_skin_thermal/power_feature@0"; + e3322_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + tegra_sound = "/sound"; + disc_pd = "/power-domain/disc-pd"; + xusb_mbox = "/mailbox@3538000"; + vpp_lcd = "/i2c@3160000/tps65132@3e/outp"; + gen2_i2c = "/i2c@c240000"; + e3322_csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + liimx274_imx274_out1 = "/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a/ports/port@0/endpoint"; + adsp_pd = "/power-domain/adsp-pd"; + e3323_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + rt565x_dai_link = "/sound/nvidia,dai-link-1"; + csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + csi_chan3 = "/host1x/nvcsi@150c0000/channel@3"; + csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + tegra_pwm1 = "/pwm@3280000"; + spdif_dit6 = "/spdif_dit/spdif-dit.6@6"; + ser_prim = "/i2c@3180000/tca9546@70/i2c@0/max9295_prim@62"; + sor1_dp_display = "/host1x/sor1/dp-display"; + tegra_dmic4 = "/aconnect@2a41000/ahub/dmic@2904300"; + e3333_ov5693_out1 = "/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36/ports/port@0/endpoint"; + mttcan0 = "/mttcan@c310000"; + spmic_sd0 = "/bpmp_i2c/spmic@3c/regulators/sd0"; + hdr40_snd_link_i2s = "/sound/nvidia,dai-link-1"; + spmic_ldo7 = "/bpmp_i2c/spmic@3c/regulators/ldo7"; + ape_pd = "/power-domain/ape-pd"; + tegra_spkprot = "/aconnect@2a41000/ahub/spkprot@2908c00"; + hdr40_vdd_3v3 = "/fixed-regulators/regulator@14"; + tegra_sata = "/ahci-sata@3507000"; + tegra_afc1 = "/aconnect@2a41000/ahub/afc@2907000"; + spdif_dit13 = "/spdif_dit/spdif-dit.13@d"; + e3322_cam0 = "/i2c@3180000/tca9548@77/i2c@0/imx219_a@10"; + e3333_csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + tegra_tmp451 = "/i2c@c250000/temp-sensor@4c"; + etr_in_port = "/etr@8050000/port/endpoint@0"; + e3333_cam4 = "/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36"; + csi_chan1_port1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1"; + host1x_ctx1 = "/host1x/ctx1"; + tegra_pinctrl = "/pinmux@2430000"; + tegra_axbar = "/aconnect@2a41000/ahub"; + e3322_imx219_out1 = "/i2c@3180000/tca9548@77/i2c@1/imx219_b@10/ports/port@0/endpoint"; + e3333_csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + vdd_usb1_5v = "/fixed-regulators/regulator@5"; + cam_module3_drivernode0 = "/tegra-camera-platform/modules/module3/drivernode0"; + devslp_pullup_state = "/pinmux@2430000/devslp_pullup"; + hdr40_vdd_5v0 = "/fixed-regulators/regulator@0"; + gpio_i2c_0_77 = "/i2c@3160000/gpio@77"; + e3322_vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + tegra_i2s4 = "/aconnect@2a41000/ahub/i2s@2901300"; + e3331_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + hs1 = "/tegra_skin_thermal/hotspot@1"; + liimx185_imx185_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a/ports/port@0/endpoint"; + funnel_bccplex_out_port0 = "/funnel_bccplex@9010000/ports/port@0/endpoint"; + tegra_agic_2 = "/aconnect@2a41000/agic-controller@2a61000"; + tegra_sfc2 = "/aconnect@2a41000/ahub/sfc@2902200"; + csi_chan4_port1 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1"; + dsid_dpd_enable = "/pmc@c360000/dsid-dpd-enable"; + e3322_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + imx390_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + tegra_aowake = "/pmc@c370000"; + vi_port5 = "/host1x/vi@15700000/ports/port@5"; + csi_chan1 = "/host1x/nvcsi@150c0000/channel@1"; + e2614_tas2552_l = "/i2c@c240000/i2cmux@70/i2c@0/tas2552.9-0041@41"; + spdif_dit4 = "/spdif_dit/spdif-dit.4@4"; + cam_module4 = "/tegra-camera-platform/modules/module4"; + e2614_gpio_i2c_1_20 = "/i2c@c240000/gpio@20"; + tegra_vi = "/host1x/vi@15700000"; + tegra_dmic2 = "/aconnect@2a41000/ahub/dmic@2904100"; + cam_module1_drivernode1 = "/tegra-camera-platform/modules/module1/drivernode1"; + tegra_amx4 = "/aconnect@2a41000/ahub/amx@2903300"; + e3333_vi_in4 = "/host1x/vi@15700000/ports/port@4/endpoint"; + tegra_pcie = "/pcie-controller@10003000"; + soft_wdt = "/soft_watchdog"; + spmic_ldo5 = "/bpmp_i2c/spmic@3c/regulators/ldo5"; + dsi_dpd_enable = "/pmc@c360000/dsi-dpd-enable"; + spmic = "/bpmp_i2c/spmic@3c"; + spdif_dit11 = "/spdif_dit/spdif-dit.11@b"; + e2614_bmp280 = "/i2c@c240000/bmp280@77"; + e3333_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + e3333_cam2 = "/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36"; + vdd_1v8_ap = "/fixed-regulators/regulator@101"; + DENVER_C1 = "/cpus/denver_core_power_states/c1"; + aon_spi = "/aon_spi@c260000"; + vdd_bl_en = "/fixed-regulators/regulator@18"; + panel_s_wqxga_10_1 = "/host1x/dsi/panel-s-wqxga-10-1"; + lp8557_backlight = "/i2c@3160000/lp8557-backlight-s-wuxga-8-0@2c"; + max9295_ser0 = "/i2c@3180000/tca9546@70/i2c@0/max9295_a@40"; + ina3221x_41 = "/i2c@3160000/ina3221x@41"; + en_vdd_ts_hv_3v3 = "/fixed-regulators/regulator@7"; + e3333_csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + spmic_wdt = "/bpmp_i2c/spmic@3c/watchdog"; + e3322_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + tegra_i2s2 = "/aconnect@2a41000/ahub/i2s@2901100"; + cpu_a57_2 = "/cpus/cpu@4"; + xusba_pd = "/power-domain/xusba-pd"; + spi3 = "/spi@3240000"; + dsi_dpd_disable = "/pmc@c360000/dsi-dpd-disable"; + aon_hsp = "/tegra-hsp@c150000"; + hdmi_dp0_dpd_disable = "/pmc@c360000/hdmi-dp0-dpd-disable"; + tegra_pwm8 = "/pwm@32f0000"; + ufs_dpd_enable = "/pmc@c360000/dpd-enable"; + bcm4354 = "/bcmdhd_wlan"; + en_vdd_cam_hv_2v8 = "/fixed-regulators/regulator@11"; + e2614_ak8963 = "/i2c@c240000/ak8963@0d"; + cam_i2c = "/i2c@3180000"; + ape_as = "/iommu@12000000/address-space-prop/ape"; + fb0_reserved = "/reserved-memory/fb0_carveout"; + tca9548_77 = "/i2c@3180000/tca9548@77"; + iopad_default = "/pmc@c360000/iopad-defaults"; + vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + replicator_in_port0 = "/replicator@0x8040000/ports/port@2/endpoint"; + vi_port3 = "/host1x/vi@15700000/ports/port@3"; + vbus_en0_default_state = "/pinmux@2430000/vbus_en0_default"; + spdif_dit2 = "/spdif_dit/spdif-dit.2@2"; + funnel_minor_out_port0 = "/funnel_minor@8820000/ports/port@0/endpoint"; + cam_module2 = "/tegra-camera-platform/modules/module2"; + tegra_amx2 = "/aconnect@2a41000/ahub/amx@2903100"; + e3333_vi_in2 = "/host1x/vi@15700000/ports/port@2/endpoint"; + CPU_COST_DENVER = "/energy-costs/core-cost0"; + dis_vdd_1v2 = "/fixed-regulators/regulator@15"; + sdmmc4 = "/sdhci@3460000"; + spmic_ldo3 = "/bpmp_i2c/spmic@3c/regulators/ldo3"; + ptm_bpmp_out_port = "/ptm_bpmp@8a1c000/port/endpoint"; + liimx274_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e2614_cm32180 = "/i2c@c240000/cm32180@48"; + e3326_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e2614_tas2552_r = "/i2c@c240000/i2cmux@70/i2c@0/tas2552.9-0040@40"; + vbus_id_extcon = "/external-connection/extcon@1"; + uartg = "/serial@c290000"; + funnel_major_in_port2 = "/funnel_major@8010000/ports/port@3/endpoint"; + e3333_cam0 = "/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36"; + ptm_a57_3 = "/ptm@9b40000"; + head1 = "/host1x/nvdisplay@15210000"; + host1x_as = "/iommu@12000000/address-space-prop/host1x"; + IPI = "/interrupt-controller"; + csi_chan0_port0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0"; + en_vdd_sys = "/fixed-regulators/regulator@118"; + A57_C1 = "/cpus/a57_core_power_states/c1"; + tegra_dspk2 = "/aconnect@2a41000/ahub/dspk@2905100"; + e3333_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3322_csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + denver_0 = "/cpus/cpu@0"; + cpu_a57_0 = "/cpus/cpu@2"; + cam_module4_drivernode0 = "/tegra-camera-platform/modules/module4/drivernode0"; + spi1 = "/spi@c260000"; + ramoops_reserved = "/reserved-memory/ramoops_carveout"; + csi_out5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1/endpoint@11"; + csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + tegra_pwm6 = "/pwm@32d0000"; + tegra_car = "/clock@5000000"; + imx274_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + ptm_a57_2_out_port = "/ptm@9a40000/port/endpoint"; + e2614_rt5658_i2c3 = "/i2c@c240000/i2cmux@70/i2c@3/rt5659.12-001a@1a"; + e3323_ov23850_out1 = "/i2c@c240000/ov23850_c@36/ports/port@0/endpoint"; + tegra_afc6 = "/aconnect@2a41000/ahub/afc@2907500"; + max9296_dser = "/i2c@3180000/tca9546@70/i2c@0/max9296@48"; + csi_chan3_port0 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0"; + vi_port1 = "/host1x/vi@15700000/ports/port@1"; + e3322_cam5 = "/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + gen7_i2c = "/i2c@31c0000"; + bpmp = "/bpmp"; + spdif_dit0 = "/spdif_dit/spdif-dit.0@0"; + tegra_rtcpu_sce_trace = "/tegra-rtcpu-sce-trace"; + e3323_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + cam_module0 = "/tegra-camera-platform/modules/module0"; + liimx274_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + host1x_ctx6 = "/host1x/ctx6"; + adma = "/aconnect@2a41000/adma@2930000"; + en_vdd_disp_1v8 = "/fixed-regulators/regulator@10"; + e3333_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + panel_s_wuxga_8_0_bl = "/backlight/panel-s-wuxga-8-0-bl"; + tpiu_in_port = "/tpiu@8060000/port/enpoint@0"; + sdmmc2 = "/sdhci@3420000"; + spmic_ldo1 = "/bpmp_i2c/spmic@3c/regulators/ldo1"; + cam_module2_drivernode1 = "/tegra-camera-platform/modules/module2/drivernode1"; + tcp = "/tegra-camera-platform"; + host1x = "/host1x"; + vbus_en0_sfio_passthrough_state = "/pinmux@2430000/vbus_en0_oc_passthrough"; + uarte = "/serial@3140000"; + tegra_usb_cd = "/usb_cd"; + replicator_out_port0 = "/replicator@0x8040000/ports/port@0/endpoint"; + funnel_major_in_port0 = "/funnel_major@8010000/ports/port@1/endpoint"; + vbus_en0_sfio_tristate_state = "/pinmux@2430000/vbus_en0_oc_tristate"; + pinmux_default = "/pinmux@2430000/common"; + ptm_a57_1 = "/ptm@9940000"; + panel_s_edp_uhdtv_15_6 = "/host1x/sor/panel-s-edp-uhdtv-15-6"; + tegra_mvc2 = "/aconnect@2a41000/ahub/mvc@290a200"; + common_as = "/iommu@12000000/address-space-prop/common"; + disb_pd = "/power-domain/disb-pd"; + e3323_cam1 = "/i2c@c240000/ov23850_c@36"; + host1x_client_as = "/iommu@12000000/address-space-prop/host1x_client"; + sata_pd = "/power-domain/sata-pd"; + ser_a = "/i2c@3180000/tca9546@70/i2c@0/max9295_a@40"; + e3322_csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + thermal_fan_est_shared_data = "/tfesd"; + tegra_rtcpu_ape_trace = "/tegra-rtcpu-ape-trace"; + funnel_bccplex_in_port1 = "/funnel_bccplex@9010000/ports/port@2/endpoint"; + etf_in_port = "/etf@8030000/ports/port@0/endpoint"; + panel_s_wqxga_10_1_bl = "/backlight/panel-s-wqxga-10-1-bl"; + dpaux1 = "/host1x/dpaux@15040000"; + csi_out3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@1/endpoint@7"; + csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + tegra_pwm4 = "/pwm@c340000"; + spdif_dit9 = "/spdif_dit/spdif-dit.9@9"; + tegra_agic = "/aconnect@2a41000/agic-controller@2a41000"; + gpcdma = "/dma@2600000"; + e2614_rt5658 = "/i2c@c240000/rt5659.1-001a@1a"; + hdmi_dp1_dpd_disable = "/pmc@c360000/hdmi-dp1-dpd-disable"; + e3333_ov5693_out4 = "/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36/ports/port@0/endpoint"; + tegra_tachometer = "/tachometer@39c0000"; + spmic_sd3 = "/bpmp_i2c/spmic@3c/regulators/sd3"; + tegra_afc4 = "/aconnect@2a41000/ahub/afc@2907300"; + L2_DENVER = "/cpus/l2-cache1"; + e3322_cam3 = "/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + csi_chan2_port1 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1"; + tegra_adx3 = "/aconnect@2a41000/ahub/adx@2903a00"; + e3323_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + host1x_ctx4 = "/host1x/ctx4"; + DENVER_C6 = "/cpus/denver_core_power_states/c6"; + liimx274_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + vdd_usb0_5v = "/fixed-regulators/regulator@4"; + smmu_test = "/smmu_test"; + dspk_1_dai_link = "/sound/nvidia,dai-link-12"; + imx390_csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + imx390_csi_out0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@1/endpoint@1"; + e3322_imx219_out4 = "/i2c@3180000/tca9548@77/i2c@4/imx219_e@10/ports/port@0/endpoint"; + imx390_imx390_out1 = "/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c/ports/port@0/endpoint"; + tegra_safety = "/sce@b000000"; + uartc = "/serial@c280000"; + en_vdd_cam = "/fixed-regulators/regulator@2"; + panel_a_edp_1080p_14_0_bl = "/backlight/panel-a-edp-1080p-14-0-bl"; + e3322_vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + battery_reg = "/fixed-regulators/regulator@0"; + imx390_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b"; + tegra_admaif = "/aconnect@2a41000/ahub/admaif@290f000"; + disp_imp_table = "/host1x/disp_imp_table"; + vbus_en1_default_state = "/pinmux@2430000/vbus_en1_default"; + e3326_cam0 = "/i2c@3180000/ov5693_c@36"; + bcm4359 = "/bcmdhd_pcie_wlan"; + CPU_COST_A57 = "/energy-costs/core-cost1"; + csi_chan5_port1 = "/host1x/nvcsi@150c0000/channel@5/ports/port@1"; + e3322_csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + etf_out_port = "/etf@8030000/ports/port@1/endpoint"; + pm_irq = "/tegra186-pm-irq"; + e3322_csi_in4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0/endpoint@8"; + vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + e3323_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + dsib_dpd_disable = "/pmc@c360000/dsib-dpd-disable"; + csi_out1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@1/endpoint@3"; + csi_chan4 = "/host1x/nvcsi@150c0000/channel@4"; + cam_module0_drivernode0 = "/tegra-camera-platform/modules/module0/drivernode0"; + csi_in1 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0/endpoint@2"; + phy0 = "/ether_qos@2490000/mdio/ethernet-phy@0"; + tegra_pwm2 = "/pwm@3290000"; + cam_module5_drivernode0 = "/tegra-camera-platform/modules/module5/drivernode0"; + spdif_dit7 = "/spdif_dit/spdif-dit.7@7"; + eqos_tx_tri_state_default = "/pinmux@2430000/eqos_default"; + dma_test = "/dma_test"; + e3333_ov5693_out2 = "/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36/ports/port@0/endpoint"; + mttcan1 = "/mttcan@c320000"; + spmic_sd1 = "/bpmp_i2c/spmic@3c/regulators/sd1"; + spmic_ldo8 = "/bpmp_i2c/spmic@3c/regulators/ldo8"; + vmm_lcd = "/i2c@3160000/tps65132@3e/outn"; + tegra_afc2 = "/aconnect@2a41000/ahub/afc@2907100"; + sdmmc1_e_33V_disable = "/pmc@c360000/sdmmc1_e_33V_disable"; + e3322_cam1 = "/i2c@3180000/tca9548@77/i2c@1/imx219_b@10"; + xusbc_pd = "/power-domain/xusbc-pd"; + gpio_i2c_0_21 = "/i2c@3160000/gpio@21"; + e3333_csi_out4 = "/host1x/nvcsi@150c0000/channel@4/ports/port@1/endpoint@9"; + tegra_adx1 = "/aconnect@2a41000/ahub/adx@2903800"; + Tboard_tegra = "/thermal-zones/Tboard_tegra"; + e3333_cam5 = "/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36"; + fb1_reserved = "/reserved-memory/fb1_carveout"; + host1x_ctx2 = "/host1x/ctx2"; + tegra_arad = "/aconnect@2a41000/ahub/arad@290e400"; + lic = "/interrupt-controller@3000000"; + tegra_ahc = "/aconnect@2a41000/ahub/ahc@290b900"; + e3322_imx219_out2 = "/i2c@3180000/tca9548@77/i2c@2/imx219_c@10/ports/port@0/endpoint"; + sor0 = "/host1x/sor"; + e3333_csi_in5 = "/host1x/nvcsi@150c0000/channel@5/ports/port@0/endpoint@10"; + sdmmc1_e_33V_enable = "/pmc@c360000/sdmmc1_e_33V_enable"; + cam_module3_drivernode1 = "/tegra-camera-platform/modules/module3/drivernode1"; + uarta = "/serial@3100000"; + e3322_vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + tegra_i2s5 = "/aconnect@2a41000/ahub/i2s@2901400"; + hs2 = "/tegra_skin_thermal/hotspot@2"; + DENVER_CORE_POWER_STATES = "/cpus/denver_core_power_states"; + e2614_iqs263 = "/i2c@c240000/iqs263@44"; + liimx185_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + e3331_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx318_a@10"; + hdr40_i2c0 = "/i2c@3160000"; + tegra_sfc3 = "/aconnect@2a41000/ahub/sfc@2902400"; + mipical_prod_c_dphy_csi_soc_a01 = "/mipical/prod-settings/prod_c_dphy_csi/soc_a01"; + e3326_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + e3322_csi_in2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@0/endpoint@4"; + vi_in3 = "/host1x/vi@15700000/ports/port@3/endpoint"; + imx390_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + liimx274_imx274_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a/ports/port@0/endpoint"; + gen8_i2c = "/i2c@c250000"; + hsp_top = "/tegra-hsp@3c00000"; + csi_chan2 = "/host1x/nvcsi@150c0000/channel@2"; + en_vdd_sdcard1 = "/fixed-regulators/regulator@1"; + spdif_dit5 = "/spdif_dit/spdif-dit.5@5"; + cam_module5 = "/tegra-camera-platform/modules/module5"; + tegra_dmic3 = "/aconnect@2a41000/ahub/dmic@2904200"; + e3333_ov5693_out0 = "/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36/ports/port@0/endpoint"; + e3333_vi_in5 = "/host1x/vi@15700000/ports/port@5/endpoint"; + eqos_p100 = "/thermal-zones/GPU-therm/trips/eqos-p100@100000"; + spmic_ldo6 = "/bpmp_i2c/spmic@3c/regulators/ldo6"; + gpu_as = "/iommu@12000000/address-space-prop/gpu"; + hdmi_dp0_dpd_enable = "/pmc@c360000/hdmi-dp0-dpd-enable"; + spdif_dit12 = "/spdif_dit/spdif-dit.12@c"; + die_temp_thresh = "/thermal-zones/PMIC-Die/trips/hot-die"; + Tdiode_tegra = "/thermal-zones/Tdiode_tegra"; + ptm_a57_3_out_port = "/ptm@9b40000/port/endpoint"; + e3333_csi_out2 = "/host1x/nvcsi@150c0000/channel@2/ports/port@1/endpoint@5"; + sor0_hdmi_display = "/host1x/sor/hdmi-display"; + e3333_cam3 = "/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36"; + csi_chan1_port0 = "/host1x/nvcsi@150c0000/channel@1/ports/port@0"; + host1x_ctx0 = "/host1x/ctx0"; + pca9570_a_24 = "/i2c@3180000/tca9546@70/i2c@0/pca9570_a@24"; + eqos_p30 = "/thermal-zones/GPU-therm/trips/eqos-p30@30000"; + tegra_main_gpio = "/gpio@2200000"; + e3331_imx318_out0 = "/i2c@3180000/tca9546@70/i2c@0/imx318_a@10/ports/port@0/endpoint"; + stm_out_port = "/stm@8070000/port/endpoint"; + se = "/se_elp@3ad0000"; + e3322_imx219_out0 = "/i2c@3180000/tca9548@77/i2c@0/imx219_a@10/ports/port@0/endpoint"; + max9295_ser1 = "/i2c@3180000/tca9546@70/i2c@0/max9295_b@60"; + tegra_pmc = "/pmc@c360000"; + e3333_csi_in3 = "/host1x/nvcsi@150c0000/channel@3/ports/port@0/endpoint@6"; + e3322_vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + tegra_i2s3 = "/aconnect@2a41000/ahub/i2s@2901200"; + en_vdd_ts_1v8 = "/fixed-regulators/regulator@6"; + hs0 = "/tegra_skin_thermal/hotspot@0"; + e3331_vi_in0 = "/host1x/vi@15700000/ports/port@0/endpoint"; + max9295_prim = "/i2c@3180000/tca9546@70/i2c@0/max9295_prim@62"; + panel_a_edp_1080p_14_0 = "/host1x/sor/panel-a-edp-1080p-14-0"; + cpu_a57_3 = "/cpus/cpu@5"; + smmu = "/iommu@12000000"; + tegra_ape = "/aconnect@2a41000/rtcpu@2993000"; + vbus_en1_sfio_passthrough_state = "/pinmux@2430000/vbus_en1_oc_passthrough"; + tegra_agic_1 = "/aconnect@2a41000/agic-controller@2a51000"; + imx185_cam0 = "/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a"; + tegra_sfc1 = "/aconnect@2a41000/ahub/sfc@2902000"; + tegra_ape_ivc = "/ape-ivc-channels"; + csi_chan4_port0 = "/host1x/nvcsi@150c0000/channel@4/ports/port@0"; + e3322_csi_in0 = "/host1x/nvcsi@150c0000/channel@0/ports/port@0/endpoint@0"; + devslp_active_state = "/pinmux@2430000/devslp_active"; + vi_in1 = "/host1x/vi@15700000/ports/port@1/endpoint"; + vi_port4 = "/host1x/vi@15700000/ports/port@4"; + }; + + pwm@32d0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbf 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x68>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x18a>; + reg = <0x0 0x32d0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x18a>; + #pwm-cells = <0x2>; + }; + + pinctrl@3520000 { + pinctrl-5 = <0xa2>; + compatible = "nvidia,tegra186-xusb-padctl"; + clocks = <0x10 0x6f 0x10 0x215 0x10 0x87 0x10 0x86>; + avdd_pll_erefeut-supply = <0x12>; + pinctrl-3 = <0xa6>; + resets = <0x10 0x37>; + reg-names = "padctl", "ao"; + pinctrl-1 = <0xa4>; + vbus-3-supply = <0x26>; + clock-names = "xusb_clk", "utmipll", "usb2_trk", "hsic_trk"; + vbus-2-supply = <0xaa>; + vddio-hsic-supply = <0x26>; + pinctrl-6 = <0xa3>; + status = "okay"; + interrupts = <0x0 0xa7 0x4>; + vbus-1-supply = <0xa9>; + mbox-names = "xusb"; + mboxes = <0xb0>; + pinctrl-4 = <0xa7>; + phandle = <0xa1>; + vclamp_usb-supply = <0x12>; + pinctrl-2 = <0xa5>; + vbus-0-supply = <0xa8>; + reg = <0x0 0x3520000 0x0 0x1000 0x0 0x3540000 0x0 0x1000>; + pinctrl-0 = <0xb1>; + reset-names = "padctl_rst"; + avdd_usb-supply = <0x13>; + #phy-cells = <0x1>; + linux,phandle = <0xa1>; + pinctrl-names = "default", "vbus_en0_sfio_tristate", "vbus_en1_sfio_tristate", "vbus_en0_sfio_passthrough", "vbus_en1_sfio_passthrough", "vbus_en0_default", "vbus_en1_default"; + + pinmux { + phandle = <0xb1>; + linux,phandle = <0xb1>; + + e3325-usb3-std-A-SS { + nvidia,lanes = "usb3-0"; + nvidia,port-cap = <0x1>; + status = "disabled"; + }; + + usb2-micro-AB { + nvidia,lanes = "otg-0"; + nvidia,port-cap = <0x3>; + nvidia,function = "xusb"; + nvidia,oc-pin = <0x0>; + }; + + usb2-std-A-port2 { + nvidia,lanes = "otg-1"; + nvidia,port-cap = <0x1>; + nvidia,function = "xusb"; + nvidia,oc-pin = <0x1>; + }; + + usb3-std-A-port2 { + nvidia,lanes = "usb3-1"; + nvidia,port-cap = <0x1>; + nvidia,oc-pin = <0x1>; + }; + + e3325-usb3-std-A-HS { + nvidia,lanes = "otg-2"; + nvidia,port-cap = <0x1>; + status = "disabled"; + nvidia,function = "xusb"; + }; + }; + }; + + pinmux@2430000 { + compatible = "nvidia,tegra186-pinmux"; + status = "okay"; + phandle = <0xb7>; + reg = <0x0 0x2430000 0x0 0x15000 0x0 0xc300000 0x0 0x4000>; + pinctrl-0 = <0x1e>; + #gpio-range-cells = <0x3>; + linux,phandle = <0xb7>; + pinctrl-names = "default"; + + vbus_en1_oc_passthrough { + phandle = <0xa7>; + linux,phandle = <0xa7>; + + usb_vbus_en1_pl5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,tristate = <0x0>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + + eqos_idle { + phandle = <0x42>; + linux,phandle = <0x42>; + + eqos { + nvidia,pins = "eqos_td3_pe4", "eqos_td2_pe3", "eqos_td1_pe2", "eqos_td0_pe1", "eqos_txc_pe0", "eqos_tx_ctl_pe5"; + nvidia,tristate = <0x1>; + }; + }; + + devslp_active { + phandle = <0x20>; + linux,phandle = <0x20>; + + sata { + nvidia,enable-input = <0x0>; + nvidia,pins = "pex_l2_clkreq_n_pa6"; + nvidia,lpdr = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "sata"; + nvidia,pull = <0x0>; + }; + }; + + vbus_en0_default { + phandle = <0xa2>; + linux,phandle = <0xa2>; + + usb_vbus_en0_pl4 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "rsvd1"; + }; + }; + + devslp_pullup { + phandle = <0x21>; + linux,phandle = <0x21>; + + sata { + nvidia,pins = "pex_l2_clkreq_n_pa6"; + nvidia,function = "sata"; + nvidia,pull = <0x2>; + }; + }; + + eqos_default { + phandle = <0x43>; + linux,phandle = <0x43>; + + eqos { + nvidia,pins = "eqos_td3_pe4", "eqos_td2_pe3", "eqos_td1_pe2", "eqos_td0_pe1", "eqos_txc_pe0", "eqos_tx_ctl_pe5"; + nvidia,tristate = <0x0>; + }; + }; + + vbus_en0_oc_passthrough { + phandle = <0xa6>; + linux,phandle = <0xa6>; + + usb_vbus_en0_pl4 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,tristate = <0x0>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + + vbus_en0_oc_tristate { + phandle = <0xa4>; + linux,phandle = <0xa4>; + + usb_vbus_en0_pl4 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en0_pl4"; + nvidia,tristate = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + + vbus_en1_default { + phandle = <0xa3>; + linux,phandle = <0xa3>; + + usb_vbus_en1_pl5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "rsvd1"; + }; + }; + + common { + phandle = <0x1e>; + linux,phandle = <0x1e>; + + gpio_edp2_pp5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "gpio_edp2_pp5"; + nvidia,tristate = <0x1>; + status = "okay"; + nvidia,pull = <0x2>; + }; + + gpio_edp3_pp6 { + nvidia,enable-input = <0x0>; + nvidia,pins = "gpio_edp3_pp6"; + nvidia,tristate = <0x0>; + status = "okay"; + nvidia,pull = <0x0>; + }; + }; + + vbus_en1_oc_tristate { + phandle = <0xa5>; + linux,phandle = <0xa5>; + + usb_vbus_en1_pl5 { + nvidia,enable-input = <0x1>; + nvidia,pins = "usb_vbus_en1_pl5"; + nvidia,tristate = <0x1>; + nvidia,io-high-voltage = <0x1>; + nvidia,function = "usb"; + }; + }; + }; + + soft_watchdog { + compatible = "softdog-platform"; + status = "disabled"; + phandle = <0xff>; + linux,phandle = <0xff>; + }; + + energy-costs { + + core-cost0 { + idle-cost-data = <0x80>; + phandle = <0xb>; + busy-cost-data = <0x400 0x400>; + linux,phandle = <0xb>; + }; + + core-cost1 { + idle-cost-data = <0x80>; + phandle = <0xe>; + busy-cost-data = <0x2f0 0x400>; + linux,phandle = <0xe>; + }; + }; + + ptm@9b40000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x7>; + status = "okay"; + phandle = <0x1db>; + reg = <0x0 0x9b40000 0x0 0x1000>; + linux,phandle = <0x1db>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd9>; + linux,phandle = <0xd9>; + }; + }; + }; + + pwm@c340000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xe1>; + resets = <0x10 0x66>; + clock-names = "pwm"; + status = "okay"; + phandle = <0xec>; + reg = <0x0 0xc340000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0xec>; + #pwm-cells = <0x2>; + }; + + axip2p@2100000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2100000 0x0 0x1000>; + }; + + spi@3230000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0x2e 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x2a>; + clock-names = "spi", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p", "clk_m"; + status = "disabled"; + #address-cells = <0x1>; + interrupts = <0x0 0x26 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x184>; + reg = <0x0 0x3230000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x11 0x25 0x11>; + reset-names = "spi"; + linux,phandle = <0x184>; + }; + + hda@3510000 { + compatible = "nvidia,tegra30-hda"; + clocks = <0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + resets = <0x10 0xf 0x10 0x10 0x10 0x11>; + clock-names = "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + status = "okay"; + interrupts = <0x0 0xa1 0x4>; + reg = <0x0 0x3510000 0x0 0x10000>; + iommus = <0x11 0x12>; + reset-names = "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + }; + + psci { + compatible = "arm,psci-1.0"; + cpu_suspend = <0xc4000001>; + cpu_on = <0xc4000003>; + status = "okay"; + cpu_off = <0x84000002>; + method = "smc"; + }; + + i2c@31a0000 { + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + firmware { + + android { + compatible = "android,firmware"; + serialno = "1421920042248"; + hardware = "quill"; + + fstab { + compatible = "android,fstab"; + + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/3460000.sdhci/by-name/vendor"; + type = "ext4"; + fsmgr_flags = "wait,avb"; + mnt_flags = "ro"; + }; + + odm { + compatible = "android,odm"; + dev = "/dev/block/platform/3460000.sdhci/by-name/odm"; + type = "ext4"; + fsmgr_flags = "wait,avb"; + mnt_flags = "ro"; + }; + }; + + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,kernel,kernel-dtb,kernel-dtbo,APP,vendor,SOS"; + }; + }; + }; + + axi2apb@23c0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23c0000 0x0 0x1000>; + }; + + xhci@3530000 { + compatible = "nvidia,tegra186-xhci"; + clocks = <0x10 0x71 0x10 0xf4 0x10 0x72 0x10 0xf2 0x10 0x261 0x10 0xf5 0x10 0x215 0x10 0x261 0x10 0x200>; + otg-controller = <0xab>; + iommu_sodev_map; + clock-names = "xusb_host", "xusb_falcon_src", "xusb_ss", "xusb_ss_src", "xusb_hs_src", "xusb_fs_src", "pll_u_480m", "clk_m", "pll_e"; + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0"; + avdd_pll_utmip-supply = <0x12>; + extcon-cable-names = "id"; + hvdd_usb-supply = <0x12>; + status = "okay"; + interrupt-parent = <0x3a>; + interrupts = <0x0 0xa3 0x4 0x0 0xa4 0x4 0x0 0xa7 0x4>; + phandle = <0x107>; + extcon-cables = <0xa0 0x1>; + phys = <0x9e 0xac 0xad 0xae>; + reg = <0x0 0x3530000 0x0 0x8000 0x0 0x3538000 0x0 0x1000>; + iommus = <0x11 0x1b>; + nvidia,boost_cpu_freq = <0x4b0>; + nvidia,xusb-padctl = <0x9f>; + #extcon-cells = <0x1>; + linux,phandle = <0x107>; + avddio_usb-supply = <0x13>; + }; + + axip2p@2140000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2140000 0x0 0x1000>; + }; + + bluedroid_pm { + compatible = "nvidia,tegra-bluedroid_pm"; + id = <0x0>; + interrupt-parent = <0x28>; + interrupts = <0x3c 0x1>; + bluedroid_pm,ext-wake-gpio = <0x1b 0xa4 0x0>; + phandle = <0x10b>; + avdd-supply = <0x26>; + linux,phandle = <0x10b>; + bluedroid_pm,host-wake-gpio = <0x28 0x3c 0x0>; + dvdd-supply = <0x12>; + bluedroid_pm,reset-gpio = <0x1b 0x3d 0x0>; + }; + + spi@3270000 { + compatible = "nvidia,tegra186-qspi"; + clocks = <0x10 0x84 0x10 0x135 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x81>; + clock-names = "qspi", "qspi_out", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p"; + status = "disabled"; + #address-cells = <0x1>; + interrupts = <0x0 0x23 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x186>; + reg = <0x0 0x3270000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x5 0x25 0x5>; + reset-names = "qspi"; + linux,phandle = <0x186>; + + prod-settings { + + prod { + prod = <0x4 0x7cff 0x0>; + }; + }; + }; + + tfesd { + polling_period = <0x44c>; + tzp_governor_name = "pid_thermal_gov"; + toffset = <0x0>; + phandle = <0xef>; + ndevs = <0x3>; + linux,phandle = <0xef>; + cdev_type = "pwm-fan"; + secret = <0x25>; + + dev2 { + coeffs = <0x1e 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + dev_data = "MCPU-therm"; + }; + + dev3 { + coeffs = <0x28 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + dev_data = "GPU-therm"; + }; + + dev1 { + coeffs = <0x1e 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + dev_data = "BCPU-therm"; + }; + }; + + tegra-pmc-blink-pwm { + compatible = "nvidia,tegra210-pmc-blink-pwm"; + status = "disabled"; + }; + + i2c@31e0000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xb7 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x53>; + scl-gpio = <0x1b 0x5a 0x0>; + sda-gpio = <0x1b 0x5b 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x21 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x180>; + reg = <0x0 0x31e0000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x1f 0x25 0x1f>; + reset-names = "i2c"; + linux,phandle = <0x180>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + axip2p@2180000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2180000 0x0 0x1000>; + }; + + i2c@c250000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xdb 0x10 0x10d 0x10 0xdd>; + resets = <0x10 0x52>; + scl-gpio = <0x28 0x18 0x0>; + sda-gpio = <0x28 0x19 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x20 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x174>; + reg = <0x0 0xc250000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x0 0x25 0x0>; + reset-names = "i2c"; + linux,phandle = <0x174>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + temp-sensor@4c { + compatible = "ti,tmp451"; + extended-rage = <0x1>; + sensor-name = "tmp451-ext"; + supported-hwrev = <0x1>; + #thermal-sensor-cells = <0x1>; + offset = <0xffffffd4>; + conv-rate = <0x6>; + status = "okay"; + interrupt-parent = <0x28>; + temp-alert-gpio = <0x28 0x10 0x0>; + interrupts = <0x10 0x8>; + phandle = <0x53>; + vdd-supply = <0x3d>; + reg = <0x4c>; + linux,phandle = <0x53>; + + ext { + shutdown-limit = <0x6b>; + }; + + loc { + shutdown-limit = <0x6b>; + }; + }; + }; + + tegra-rtcpu-sce-trace { + nvidia,enable-printk; + nvidia,log-prefix = "[SCE]"; + phandle = <0x56>; + linux,phandle = <0x56>; + nvidia,interval-ms = <0x32>; + }; + + fixed-regulators { + compatible = "simple-bus"; + device_type = "fixed-regulators"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + regulator@3 { + regulator-enable-ramp-delay = <0x2e9>; + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0xc 0x1>; + regulator-disable-ramp-delay = <0x12110>; + phandle = <0x8a>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x3>; + regulator-max-microvolt = <0x4c4b40>; + regulator-always-on; + regulator-name = "vdd-hdmi"; + linux,phandle = <0x8a>; + }; + + regulator@200 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xea 0xb 0x1>; + status = "disabled"; + phandle = <0x2f>; + regulator-min-microvolt = <0x1b7740>; + reg = <0xc8>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vdd-1v8-aud2"; + linux,phandle = <0x2f>; + }; + + regulator@18 { + compatible = "regulator-fixed-sync"; + phandle = <0x88>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x12>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vdd-sys-bl"; + linux,phandle = <0x88>; + }; + + regulator@1 { + regulator-enable-ramp-delay = <0x460>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x1b 0x7e 0x0>; + regulator-disable-ramp-delay = <0x4074>; + phandle = <0x1d>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x1>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "en-vdd-sd"; + linux,phandle = <0x1d>; + }; + + regulator@16 { + compatible = "regulator-fixed-sync"; + enable-active-high; + phandle = <0x2c>; + regulator-min-microvolt = <0x2ab980>; + reg = <0x10>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "en-vdd-vcm-2v8"; + linux,phandle = <0x2c>; + }; + + regulator@14 { + compatible = "regulator-fixed-sync"; + phandle = <0x2e>; + regulator-min-microvolt = <0x325aa0>; + reg = <0xe>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vdd-3v3"; + linux,phandle = <0x2e>; + }; + + regulator@8 { + regulator-enable-ramp-delay = <0xd8>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0x3 0x0>; + regulator-disable-ramp-delay = <0xa7f8>; + phandle = <0x84>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x8>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "en-vdd-disp-3v3"; + linux,phandle = <0x84>; + }; + + regulator@12 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x8d 0xa 0x0>; + phandle = <0x34>; + regulator-min-microvolt = <0x124f80>; + reg = <0xc>; + regulator-max-microvolt = <0x124f80>; + regulator-name = "en-vdd-cam-1v2"; + linux,phandle = <0x34>; + }; + + regulator@6 { + regulator-enable-ramp-delay = <0xad>; + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0x1 0x1>; + regulator-disable-ramp-delay = <0x32c8>; + phandle = <0x3f>; + regulator-min-microvolt = <0x1b7740>; + reg = <0x6>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-name = "en-vdd-ts-1v8"; + linux,phandle = <0x3f>; + }; + + regulator@10 { + regulator-enable-ramp-delay = <0xb2>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0x9 0x1>; + regulator-disable-ramp-delay = <0x2710>; + phandle = <0x85>; + regulator-min-microvolt = <0x1b7740>; + reg = <0xa>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "en-vdd-disp-1v8"; + linux,phandle = <0x85>; + }; + + regulator@4 { + regulator-enable-ramp-delay = <0x3b1>; + compatible = "regulator-fixed-sync"; + gpio-open-drain; + enable-active-high; + gpio = <0x1b 0x5c 0x0>; + regulator-disable-ramp-delay = <0xa5a>; + phandle = <0xa8>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x4>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-usb0-5v"; + linux,phandle = <0xa8>; + }; + + regulator@2 { + regulator-enable-ramp-delay = <0x6c>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x8d 0x9 0x1>; + regulator-disable-ramp-delay = <0x4b0>; + phandle = <0x2b>; + regulator-min-microvolt = <0x1b7740>; + reg = <0x2>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "en-vdd-cam"; + linux,phandle = <0x2b>; + }; + + regulator@17 { + compatible = "regulator-fixed-sync"; + gpio = <0xe9 0x0 0x0>; + phandle = <0xaa>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x11>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-usb2-5v"; + linux,phandle = <0xaa>; + }; + + regulator@0 { + compatible = "regulator-fixed"; + phandle = <0x26>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x0>; + regulator-max-microvolt = <0x4c4b40>; + regulator-always-on; + regulator-name = "vdd-ac-bat"; + linux,phandle = <0x26>; + }; + + regulator@15 { + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0xa 0x1>; + phandle = <0x1df>; + regulator-min-microvolt = <0x124f80>; + reg = <0xf>; + regulator-max-microvolt = <0x124f80>; + regulator-always-on; + regulator-name = "dis-vdd-1v2"; + linux,phandle = <0x1df>; + }; + + regulator@9 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0x7 0x1>; + phandle = <0x1de>; + regulator-min-microvolt = <0x387520>; + reg = <0x9>; + regulator-max-microvolt = <0x387520>; + regulator-name = "en-mdm-pwr-3v7"; + linux,phandle = <0x1de>; + }; + + regulator@101 { + compatible = "regulator-fixed"; + regulator-boot-on; + phandle = <0x3d>; + regulator-min-microvolt = <0x1b7740>; + reg = <0x65>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + regulator-name = "vdd-1v8-ap"; + linux,phandle = <0x3d>; + }; + + regulator@13 { + compatible = "regulator-fixed-sync"; + gpio = <0xe9 0x4 0x0>; + phandle = <0xee>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0xd>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-fan"; + linux,phandle = <0xee>; + }; + + regulator@7 { + regulator-enable-ramp-delay = <0xf5>; + compatible = "regulator-fixed-sync"; + regulator-boot-on; + enable-active-high; + gpio = <0xe9 0x2 0x1>; + regulator-disable-ramp-delay = <0xa7f8>; + phandle = <0x3e>; + regulator-min-microvolt = <0x325aa0>; + reg = <0x7>; + regulator-max-microvolt = <0x325aa0>; + regulator-always-on; + regulator-name = "en-vdd-ts-hv-3v3"; + linux,phandle = <0x3e>; + }; + + regulator@11 { + regulator-enable-ramp-delay = <0x1388>; + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0xe9 0xd 0x1>; + regulator-disable-ramp-delay = <0x153d8>; + phandle = <0x29>; + regulator-min-microvolt = <0x2ab980>; + reg = <0xb>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "en-vdd-cam-hv-2v8"; + linux,phandle = <0x29>; + }; + + regulator@5 { + regulator-enable-ramp-delay = <0x320>; + compatible = "regulator-fixed-sync"; + gpio-open-drain; + enable-active-high; + gpio = <0x1b 0x5d 0x0>; + regulator-disable-ramp-delay = <0x32c8>; + phandle = <0xa9>; + regulator-min-microvolt = <0x4c4b40>; + reg = <0x5>; + regulator-max-microvolt = <0x4c4b40>; + regulator-name = "vdd-usb1-5v"; + linux,phandle = <0xa9>; + }; + + regulator@118 { + compatible = "regulator-fixed-sync"; + enable-active-high; + gpio = <0x8d 0x3 0x1>; + phandle = <0x2a>; + regulator-min-microvolt = <0x124f80>; + reg = <0x76>; + regulator-max-microvolt = <0x124f80>; + regulator-name = "en-vdd-sys"; + linux,phandle = <0x2a>; + }; + }; + + aliases { + i2c3 = "/i2c@3190000"; + spi2 = "/spi@3230000"; + i2c1 = "/i2c@c240000"; + spi0 = "/spi@3210000"; + sdhci2 = "/sdhci@3440000"; + serial5 = "/serial@3150000"; + i2c8 = "/i2c@31e0000"; + sdhci0 = "/sdhci@3400000"; + serial3 = "/serial@3130000"; + i2c6 = "/i2c@31c0000"; + serial1 = "/serial@3110000"; + rtc0 = "/bpmp_i2c/spmic@3c"; + i2c4 = "/bpmp_i2c"; + spi3 = "/spi@3240000"; + i2c2 = "/i2c@3180000"; + spi1 = "/spi@c260000"; + i2c0 = "/i2c@3160000"; + sdhci3 = "/sdhci@3460000"; + serial6 = "/serial@c290000"; + sdhci1 = "/sdhci@3420000"; + serial4 = "/serial@3140000"; + i2c7 = "/i2c@c250000"; + spi6 = "/spi@3270000"; + serial2 = "/serial@c280000"; + rtc1 = "/rtc@c2a0000"; + i2c5 = "/i2c@31b0000"; + tegra-camera-rtcpu = "/rtcpu@b000000"; + spi4 = "/aon_spi@c260000"; + serial0 = "/serial@3100000"; + }; + + chosen { + ecid = "00000001646ca6c218000000010001c0"; + stdout-path = "/serial@3100000"; + bootargs = "earlycon=uart8250,mmio32,0x3100000 console=ttyS0,115200n8 root=/dev/sda1 rw audit=0 usbcore.old_scheme_first=1 default_hugepagesz=32M hugepagesz=32M hugepages=4"; + nvidia,ether-mac = "48:b0:2d:0e:6e:9e"; + nvidia,bluetooth-mac = "48:b0:2d:0e:6e:9d"; + nvidia,wifi-mac = "48:b0:2d:0e:6e:9c"; + board-has-eeprom; + nvidia,tegra-joint_xpu_rail; + + reset { + + pmic-reset-reason { + reason = "NIL_OR_MORE_THAN_1_BIT"; + register-value = "0x00"; + }; + + pmc-reset-reason { + reset-level = [31 00]; + reset-source = "MAINSWRST"; + }; + }; + + plugin-manager { + cvm = "3310-1000-D00"; + + odm-data { + disable-pmic-wdt = <0x1>; + no-battery = <0x1>; + enable-debug-console = <0x1>; + enable-xusb-on-uphy-lane0 = <0x1>; + normal-flashed = <0x1>; + disable-tegra-wdt = <0x1>; + enable-pcie-on-uphy-lane1 = <0x1>; + android-build = <0x1>; + enable-sata-on-uphy-lane5 = <0x1>; + enable-denver-wdt = <0x1>; + enable-pcie-on-uphy-lane4 = <0x1>; + disable-sdmmc-hwcq = <0x1>; + enable-pcie-on-uphy-lane2 = <0x1>; + }; + + chip-id { + A02P = <0x1>; + }; + + configs { + 3310-misc-config = <0x0>; + 3310-touch-config = <0x0>; + 3310-modem-config = <0x0>; + 3310-mem-type = <0x0>; + 3310-power-config = <0x0>; + 3310-display-config = <0x0>; + }; + + ids { + 3310-1000-D00 = "/i2c@c250000:module@0x50"; + 2597-0000-900 = "/i2c@c250000:module@0x57"; + 3310-1000-D00-K = <0x1>; + 3326-1000-000 = "/i2c@3180000:module@0x54"; + + connection { + + i2c@c250000 { + + module@0x50 { + 3310-1000-D00 = "/i2c@c250000:module@0x50"; + }; + + module@0x57 { + 2597-0000-900 = "/i2c@c250000:module@0x57"; + }; + }; + + i2c@3180000 { + + module@0x54 { + 3326-1000-000 = "/i2c@3180000:module@0x54"; + }; + }; + }; + }; + }; + }; + + external-connection { + compatible = "simple-bus"; + device_type = "external-connection"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + extcon@1 { + gpios = <0x1b 0x9f 0x0 0x22 0x0 0x0>; + compatible = "extcon-gpio-states"; + wakeup-source; + extcon-gpio,cable-states = <0x3 0x0 0x0 0x2 0x1 0x2 0x2 0x1>; + phandle = <0xa0>; + reg = <0x1>; + extcon-gpio,wait-for-gpio-scan = <0x0>; + #extcon-cells = <0x1>; + extcon-gpio,out-cable-names = <0x1 0x2 0x0>; + linux,phandle = <0xa0>; + extcon-gpio,name = "VBUS"; + }; + + disp-state { + compatible = "extcon-disp-state"; + #extcon-cells = <0x1>; + }; + }; + + axi2apb@2390000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2390000 0x0 0x1000>; + }; + + e3333_lens_ov5693@P5V27C { + min_focus_distance = "0.0"; + f_number = "2.0"; + hyper_focal = "0.0"; + aperture = "2.0"; + focal_length = "2.67"; + }; + + vivid-driver { + + instance0 { + + mode0 { + line_length = "2200"; + active_w = "1920"; + vert_front_porch = [34 00]; + horz_back_porch = "148"; + embedded_metadata_height = [31 00]; + pixel_t = "bayer_bggr10"; + pix_clk_hz = "74250000"; + max_gain_val = "256"; + vert_back_porch = "36"; + vert_sync = [35 00]; + readout_orientation = "90"; + min_gain_val = [31 00]; + tegra_sinterface = "host"; + min_framerate = [31 00]; + max_framerate = "30"; + horz_sync = "44"; + gain_factor = "16"; + framerate_factor = [31 00]; + active_h = "1080"; + max_exp_time = "999994"; + horz_front_porch = "88"; + min_exp_time = "34"; + }; + }; + }; + + serial@c280000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xd7 0x10 0x10d>; + resets = <0x10 0x31>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "NILL"; + interrupts = <0x0 0x72 0x4>; + dma-names = "rx", "tx"; + phandle = <0x18e>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0xc280000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x3 0x25 0x3>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x18e>; + }; + + ptm@9a40000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x6>; + status = "okay"; + phandle = <0x1da>; + reg = <0x0 0x9a40000 0x0 0x1000>; + linux,phandle = <0x1da>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd8>; + linux,phandle = <0xd8>; + }; + }; + }; + + tegra-rtcpu-ape-trace { + nvidia,enable-printk; + nvidia,log-prefix = "[APE]"; + phandle = <0x5c>; + linux,phandle = <0x5c>; + nvidia,interval-ms = <0x32>; + }; + + cluster_clk_priv@e090000 { + compatible = "nvidia,t18x-cluster-clk-priv"; + status = "okay"; + #address-cells = <0x2>; + #size-cells = <0x2>; + reg = <0x0 0xe090000 0x0 0xfff0 0x0 0xe0a0000 0x0 0xfff0 0x0 0xe0b0000 0x0 0xfff0 0x0 0xe0c0000 0x0 0xfff0 0x0 0xe0d0000 0x0 0xfff0>; + }; + + plugin-manager { + status = "disabled"; + + fragement@1 { + odm-data = "disable-denver-wdt"; + + override@0 { + target = <0xb3>; + + _overlay_ { + nvidia,enable-halt-in-fiq; + }; + }; + }; + + fragment-500-pcie-config { + ids = ">=3310-1000-500"; + + override@0 { + target = <0x109>; + + _overlay_ { + + pci@2,0 { + nvidia,num-lanes = <0x0>; + }; + + pci@1,0 { + nvidia,num-lanes = <0x4>; + }; + + pci@3,0 { + nvidia,num-lanes = <0x1>; + }; + }; + }; + }; + + fragment-500-xusb-config { + ids = ">=3310-1000-500"; + + override@1 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "okay"; + nvidia,usb2-companion = <0x1>; + }; + + usb3-1 { + status = "disabled"; + }; + }; + }; + }; + + override@0 { + target = <0x107>; + + _overlay_ { + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0"; + phys = <0x9e 0xac 0xad 0xae>; + }; + }; + }; + + fragment-e3323@0 { + ids = "3323-1000-*"; + + override@11 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "e3323_bottom_CH06P1"; + status = "okay"; + position = "bottom"; + orientation = [33 00]; + }; + }; + + override@18 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@8 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@26 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@16 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x138>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@6 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3323_lens_ov23850@CH06P1/"; + }; + }; + + override@24 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + max_pixel_rate = <0xb71b0>; + num_csi_lanes = <0x8>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@14 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x124>; + + _overlay_ { + badge = "e3323_top_CH06P1"; + status = "okay"; + position = "top"; + orientation = [33 00]; + }; + }; + + override@22 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x64>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "ov23850 2-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov23850_a@10"; + }; + }; + + override@20 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@0 { + target = <0x135>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3323_lens_ov23850@CH06P1/"; + }; + }; + + override@25 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x5e 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@15 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x125>; + + _overlay_ { + devname = "ov23850 1-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@c240000/ov23850_c@36"; + }; + }; + + override@23 { + target = <0x6e>; + + _overlay_ { + remote-endpoint = <0x64>; + status = "okay"; + }; + }; + + override@13 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@3 { + target = <0x136>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x2d>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x139>; + status = "okay"; + bus-width = <0x4>; + }; + }; + }; + + fragement@8 { + odm-data = "enable-sdmmc-hwcq"; + + override@0 { + target = <0x101>; + + _overlay_ { + nvidia,enable-hwcq; + }; + }; + }; + + fragment-p3310-c00-pmic { + ids = ">=3310-1000-800"; + + override@0 { + target = <0x10c>; + + _overlay_ { + maxim,active-fps-source = <0x3>; + }; + }; + }; + + fragment-sdwake-p3310-1000-300 { + ids = ">=3310-1000-300"; + + override@102 { + target = <0x1d>; + + _overlay_ { + gpio = <0x1b 0x7e 0x0>; + }; + }; + + override@100 { + target = <0x1e>; + + _overlay_ { + + gpio_edp2_pp5 { + status = "okay"; + }; + + gpio_edp3_pp6 { + status = "okay"; + }; + }; + }; + + override@103 { + target = <0x100>; + + _overlay_ { + nvidia,cd-wakeup-capable; + cd-gpios = <0x1b 0x7d 0x0>; + }; + }; + + override@101 { + target = <0x1b>; + + _overlay_ { + + sdmmc-wake-support-input { + status = "okay"; + }; + + sdmmc-wake-support-output { + status = "okay"; + }; + }; + }; + }; + + fragment-e3326@0 { + ids = "3326-*"; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "e3326_front_P5V27C"; + status = "okay"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@14 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "ov5693 2-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov5693_c@36"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x134>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@0 { + target = <0x132>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@15 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3326_lens_ov5693@P5V27C/"; + }; + }; + }; + + fragement-pmon-p3310-1000-300 { + ids = ">=3310-1000-300", "3310-1000-200-F"; + + override@1 { + target = <0xf1>; + + _overlay_ { + + channel@2 { + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@0 { + ti,shunt-resistor-mohm = <0x5>; + }; + + channel@1 { + ti,shunt-resistor-mohm = <0xa>; + }; + }; + }; + + override@0 { + target = <0xf0>; + + _overlay_ { + + channel@0 { + ti,shunt-resistor-mohm = <0xa>; + }; + + channel@1 { + ti,shunt-resistor-mohm = <0xa>; + }; + }; + }; + }; + + fragment-e3320-a01@1 { + ids = "3320-1000-100", "3320-1000-200"; + + overrides@4 { + target = <0x106>; + + _overlay_ { + + gpio@21 { + status = "okay"; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + status = "okay"; + }; + }; + }; + + overrides@2 { + target = <0x85>; + + _overlay_ { + gpio = <0x40 0x0 0x0>; + }; + }; + + overrides@3 { + target = <0xb6>; + + _overlay_ { + + dsi { + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + + overrides@1 { + target = <0x11c>; + + _overlay_ { + status = "okay"; + + outn { + ti,enable-gpio = <0x40 0x2 0x0>; + delete-target-property = "ti,disable-active-discharge"; + ti,active-discharge-gpio = <0x40 0x3 0x0>; + ti,active-discharge-time = <0x7d0>; + }; + + outp { + ti,enable-gpio = <0x8d 0x4 0x0>; + }; + }; + }; + }; + + fragement@6 { + odm-data = "mods-build"; + + override@1 { + target = <0xa1>; + + _overlay_ { + delete-target-property = "mboxes"; + }; + }; + + override@4 { + target = <0x100>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@2 { + target = <0x25>; + + _overlay_ { + nvidia,bypass-smmu; + }; + }; + + override@0 { + target = <0xb0>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@7 { + target = <0xb6>; + + _overlay_ { + + dsi { + nvidia,dsi-csi-loopback; + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + + nvdisplay@15210000 { + win-mask = <0xc>; + status = "okay"; + }; + + sor1 { + status = "okay"; + + hdmi-display { + status = "okay"; + }; + + dp-display { + status = "disabled"; + }; + }; + + nvdisplay@15220000 { + win-mask = <0x30>; + status = "okay"; + }; + + sor { + status = "okay"; + + hdmi-display { + status = "disabled"; + }; + + panel-s-edp-uhdtv-15-6 { + + smartdimmer { + status = "disabled"; + }; + }; + + dp-display { + status = "okay"; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + + nvdisplay@15200000 { + win-mask = <0x3>; + status = "okay"; + }; + }; + }; + + override@5 { + target = <0x101>; + + _overlay_ { + delete-target-property = "nvidia,enable-hwcq"; + }; + }; + + override@3 { + target = <0xf9>; + + _overlay_ { + status = "disabled"; + }; + }; + }; + + fragment-500-e3325-pcie { + odm-data = "enable-pcie-on-uphy-lane0"; + ids = ">=3310-1000-500"; + enable-override-on-all-matches; + + override@1 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "disabled"; + }; + }; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + pcie0_lane2_mux { + status = "okay"; + }; + }; + }; + + override@0 { + target = <0x107>; + + _overlay_ { + phy-names = "usb2-0", "usb2-1", "usb2-2"; + phys = <0x9e 0xac 0xad>; + }; + }; + }; + + fragement@4 { + odm-data = "enable-pmic-wdt", "enable-denver-wdt"; + + override@0 { + target = <0xff>; + + _overlay_ { + status = "disabled"; + }; + }; + }; + + fragment-e2614-b00@2 { + ids = "2614-0000-100"; + + overrides@0 { + target = <0x11b>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x115>; + + _overlay_ { + codec-dai = <0x11b>; + }; + }; + }; + + fragment-e3331@0 { + ids = "3331-*"; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + badge = "e3331_rear_22N02A"; + status = "okay"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + max_pixel_rate = <0x27100>; + num_csi_lanes = <0x3>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x3>; + }; + }; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + devname = "imx318 30-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx318_a@10"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "cam0-rst"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x172>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x173>; + status = "okay"; + bus-width = <0x3>; + }; + }; + }; + + fragment-p3310-c03 { + ids = ">=3310-1000-B00"; + + override@1 { + target = <0x10d>; + + _overlay_ { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "dvdd-pex"; + }; + }; + + override@2 { + target = <0x10e>; + + _overlay_ { + maxim,active-fps-source = <0x3>; + }; + }; + + override@3 { + target = <0x89>; + + _overlay_ { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + }; + }; + }; + + fragment-e3322@0 { + ids = "3322-*"; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@68 { + target = <0x39>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x6b>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@58 { + target = <0x159>; + + _overlay_ { + status = "okay"; + }; + }; + + override@48 { + target = <0x70>; + + _overlay_ { + remote-endpoint = <0x68>; + status = "okay"; + }; + }; + + override@38 { + target = <0x168>; + + _overlay_ { + status = "okay"; + }; + }; + + override@66 { + target = <0x15f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@28 { + target = <0x140>; + + _overlay_ { + badge = "e3322_centerright_P5V27C"; + status = "okay"; + position = "centerright"; + orientation = [31 00]; + }; + }; + + override@56 { + target = <0x157>; + + _overlay_ { + status = "okay"; + }; + }; + + override@18 { + target = <0x125>; + + _overlay_ { + devname = "imx219 31-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/imx219_b@10"; + }; + }; + + override@46 { + target = <0x37>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x67>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@712 { + target = <0x28>; + + _overlay_ { + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@8 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@36 { + target = <0x147>; + + _overlay_ { + status = "okay"; + }; + }; + + override@64 { + target = <0x15e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x6e>; + + _overlay_ { + remote-endpoint = <0x64>; + status = "okay"; + }; + }; + + override@54 { + target = <0x6a>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x71>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@16 { + target = <0x165>; + + _overlay_ { + status = "okay"; + }; + }; + + override@44 { + target = <0x14d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@72 { + target = <0x35>; + + _overlay_ { + + tca6408_21_input { + gpios = <0x6 0x0 0x7 0x0>; + gpio-hog; + status = "okay"; + label = "tca6408_21_input_6", "tca6408_21_input_7"; + input; + }; + + tca6408_21_outlow { + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + badge = "e3322_bottomleft_P5V27C"; + status = "okay"; + position = "bottomleft"; + orientation = [31 00]; + }; + }; + + override@34 { + target = <0x145>; + + _overlay_ { + status = "okay"; + }; + }; + + override@62 { + target = <0x15c>; + + _overlay_ { + devname = "imx219 35-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + }; + }; + + override@24 { + target = <0x2d>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x166>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@52 { + target = <0x154>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@42 { + target = <0x14c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@70 { + target = <0x72>; + + _overlay_ { + remote-endpoint = <0x6c>; + status = "okay"; + }; + }; + + override@4 { + target = <0x13b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@32 { + target = <0x66>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6f>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@60 { + target = <0x16a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@22 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@50 { + target = <0x152>; + + _overlay_ { + badge = "e3322_bottomright_P5V27C"; + status = "okay"; + position = "bottomright"; + orientation = [31 00]; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@40 { + target = <0x14a>; + + _overlay_ { + devname = "imx219 33-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + }; + }; + + override@69 { + target = <0x162>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0xc>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@30 { + target = <0x142>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@59 { + target = <0x71>; + + _overlay_ { + remote-endpoint = <0x6a>; + status = "okay"; + }; + }; + + override@20 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@49 { + target = <0x169>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@39 { + target = <0x149>; + + _overlay_ { + badge = "e3322_topleft_P5V27C"; + status = "okay"; + position = "topleft"; + orientation = [31 00]; + }; + }; + + override@67 { + target = <0x160>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@29 { + target = <0x141>; + + _overlay_ { + devname = "imx219 32-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + }; + }; + + override@57 { + target = <0x38>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x69>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@19 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@47 { + target = <0x150>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@37 { + target = <0x6f>; + + _overlay_ { + remote-endpoint = <0x66>; + status = "okay"; + }; + }; + + override@65 { + target = <0x6c>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x72>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@27 { + target = <0x167>; + + _overlay_ { + status = "okay"; + }; + }; + + override@55 { + target = <0x156>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x124>; + + _overlay_ { + badge = "e3322_centerleft_P5V27C"; + status = "okay"; + position = "centerleft"; + orientation = [31 00]; + }; + }; + + override@45 { + target = <0x14e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + devname = "imx219 30-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@0/imx219_a@10"; + }; + }; + + override@35 { + target = <0x36>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x65>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@63 { + target = <0x15d>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@25 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@53 { + target = <0x155>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@43 { + target = <0x68>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x70>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + gpios = <0x8d 0x0>; + gpio-hog; + status = "okay"; + label = "cam0-rst"; + output-high; + }; + + camera-control-output-low { + gpios = <0x88 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x163>; + + _overlay_ { + status = "okay"; + }; + }; + + override@33 { + target = <0x144>; + + _overlay_ { + status = "okay"; + }; + }; + + override@61 { + target = <0x15b>; + + _overlay_ { + badge = "e3322_topright_P5V27C"; + status = "okay"; + position = "topright"; + orientation = [31 00]; + }; + }; + + override@23 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@51 { + target = <0x153>; + + _overlay_ { + devname = "imx219 34-0010"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x164>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@41 { + target = <0x14b>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + + override@3 { + target = <0x35>; + + _overlay_ { + status = "okay"; + }; + }; + + override@31 { + target = <0x143>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x64>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x2>; + }; + }; + }; + + soc-prod-a01-fragment { + chip-id = "A01", "A01P"; + + override@1 { + target = <0xfb>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0xfc>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0xfa>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragement@2 { + odm-data = "enable-pmic-wdt"; + + override@0 { + target = <0xfe>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-e3325-xusb { + odm-data = "enable-xusb-on-uphy-lane0"; + ids = "<3310-1000-500"; + enable-override-on-all-matches; + + override@1 { + target = <0x107>; + + _overlay_ { + phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0", "usb3-1"; + phys = <0x9e 0xac 0xad 0xae 0x108>; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + e3325_sdio_rst { + status = "okay"; + }; + + e3325_lane0_mux { + status = "okay"; + }; + }; + }; + + override@0 { + target = <0x9f>; + + _overlay_ { + + ports { + + usb3-0 { + status = "okay"; + }; + }; + }; + }; + + override@3 { + target = <0x109>; + + _overlay_ { + + pci@2,0 { + nvidia,num-lanes = <0x1>; + }; + + pci@1,0 { + nvidia,num-lanes = <0x2>; + }; + + pci@3,0 { + nvidia,num-lanes = <0x1>; + }; + }; + }; + }; + + fragment-p3310-c00-camera { + ids = ">=3310-1000-800", ">=3489-0000-200", ">=3489-0888-300"; + + override@1 { + target = <0x136>; + + _overlay_ { + pwdn-gpios = <0x1b 0x6a 0x0>; + }; + }; + + override@2 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x6a 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + }; + }; + + override@3 { + target = <0x13a>; + + _overlay_ { + pwdn-gpios = <0x1b 0x6a 0x0>; + }; + }; + }; + + fragment-imx390@0 { + ids = "LPRD-001"; + + override@11 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx390_rear"; + status = "okay"; + position = "rear"; + orientation = [31 00]; + }; + }; + + override@18 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@8 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x31>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@24 { + target = <0x32>; + + _overlay_ { + status = "okay"; + }; + }; + + override@14 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x61>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@4 { + target = <0x124>; + + _overlay_ { + badge = "imx390_front"; + status = "okay"; + position = "front"; + orientation = [31 00]; + }; + }; + + override@22 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x2>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x3d0900>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@12 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx390 30-001b"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_a@1b"; + }; + }; + + override@20 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x64>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x2>; + vc-id = <0x1>; + }; + }; + + override@0 { + target = <0x120>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x2d>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x63>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@9 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + vc-id = <0x0>; + }; + }; + + override@27 { + target = <0x33>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@25 { + target = <0x131>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x125>; + + _overlay_ { + devname = "imx390 30-001c"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + }; + }; + + override@23 { + target = <0x130>; + + _overlay_ { + vcc-pullup-supply = <0x26>; + status = "okay"; + }; + }; + + override@13 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@3 { + target = <0x123>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-p3310-c01 { + ids = ">=3310-1000-900"; + + override@1 { + target = <0x3b>; + + _overlay_ { + + pin_gpio2 { + status = "disabled"; + }; + + pin_gpio3 { + status = "disabled"; + }; + }; + }; + + override@0 { + target = <0x10c>; + + _overlay_ { + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + fragment-e3320-a00@1 { + ids = "3320-1000-000", "3320-1100-000"; + + overrides@2 { + target = <0xb6>; + + _overlay_ { + + dsi { + status = "okay"; + nvidia,active-panel = <0x102>; + + panel-s-wuxga-8-0 { + status = "okay"; + }; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + + overrides@3 { + target = <0x106>; + + _overlay_ { + + gpio@21 { + status = "okay"; + }; + + lp8557-backlight-s-wuxga-8-0@2c { + status = "okay"; + }; + }; + }; + + overrides@1 { + target = <0x11c>; + + _overlay_ { + status = "okay"; + + outn { + ti,enable-gpio = <0x40 0x3 0x0>; + }; + + outp { + ti,enable-gpio = <0x40 0x2 0x0>; + }; + }; + }; + }; + + fragement@0 { + odm-data = "enable-denver-wdt"; + + override@0 { + target = <0xfd>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-comms-a00-chip { + ids = "<3310-1000-500"; + + override@1 { + target = <0x1b>; + + _overlay_ { + + wifi-wake-ap { + gpios = <0x10 0x0>; + status = "okay"; + }; + + wifi-enable { + gpios = <0xe 0x0>; + }; + }; + }; + + override@0 { + target = <0x10a>; + + _overlay_ { + pwr-retry-cnt = <0x0>; + interrupt-parent = <0x1b>; + interrupts = <0x10 0x14>; + delete-target-property = "wlan-pwr-gpio"; + sdhci-host = <0xf9>; + }; + }; + + override@3 { + target = <0x28>; + + _overlay_ { + + wifi-wake-ap { + status = "disabled"; + }; + }; + }; + }; + + fragement@9 { + odm-data = "enable-ufs-on-uphy-lane5"; + + override@1 { + target = <0x105>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@0 { + target = <0x104>; + + _overlay_ { + status = "okay"; + }; + }; + + override@3 { + target = <0x106>; + + _overlay_ { + + gpio@76 { + + sata_lane5_mux { + status = "disabled"; + }; + + ufs_lane5_mux { + status = "okay"; + }; + }; + }; + }; + }; + + fragment-e2614-common@0 { + ids = "2614-0000-*"; + + overrides@14 { + target = <0x110>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@8 { + target = <0x2f>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@12 { + target = <0x116>; + + _overlay_ { + cpu-dai-name = "DSPK2"; + codec-dai = <0x117>; + codec-dai-name = "tas2552-amplifier"; + cpu-dai = <0xcf>; + }; + }; + + overrides@6 { + target = <0x113>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@10 { + target = <0x114>; + + _overlay_ { + nvidia,num-codec-link = <0xd>; + nvidia,audio-routing = "x Headphone Jack", "x HPO L Playback", "x Headphone Jack", "x HPO R Playback", "x IN1P", "x Mic Jack", "x Int Spk", "x SPO Playback", "x DMIC L1", "x Int Mic", "x DMIC L2", "x Int Mic", "x DMIC R1", "x Int Mic", "x DMIC R2", "x Int Mic", "y Headphone", "y OUT", "y IN", "y Mic", "z Headphone", "z OUT", "z IN", "z Mic", "m Headphone", "m OUT", "m IN", "m Mic", "n Headphone", "n OUT", "n IN", "n Mic", "o Headphone", "o OUT", "o IN", "o Mic", "a IN", "a Mic", "b IN", "b Mic", "c IN", "c Mic", "d IN", "d Mic", "d1 Headphone", "d1 OUT", "d2 Headphone", "d2 OUT", "d3 Headphone", "d3 OUT"; + }; + }; + + overrides@4 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@17 { + target = <0x113>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@2 { + target = <0x110>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@15 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@0 { + target = <0x10f>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@13 { + target = <0x118>; + + _overlay_ { + cpu-dai-name = "DSPK2"; + codec-dai = <0x119>; + codec-dai-name = "tas2552-amplifier"; + cpu-dai = <0xcf>; + }; + }; + + overrides@11 { + target = <0x115>; + + _overlay_ { + codec-dai-name = "rt5659-aif1"; + link-name = "rt565x-playback"; + }; + }; + + overrides@5 { + target = <0x112>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@3 { + target = <0x111>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@16 { + target = <0x112>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@1 { + target = <0xea>; + + _overlay_ { + status = "okay"; + }; + }; + }; + + fragment-e2614-a00@1 { + ids = "2614-0000-000"; + + overrides@0 { + target = <0x11a>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x115>; + + _overlay_ { + codec-dai = <0x11a>; + }; + }; + }; + + fragment-p3310-c00-comm { + ids = ">=3310-1000-800"; + + override@0 { + target = <0x10b>; + + _overlay_ { + bluedroid_pm,reset-gpio = <0x1b 0x3d 0x0>; + }; + }; + }; + + fragment-imx274@0 { + ids = "LPRD-002002"; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx274_bottom_A6V26"; + status = "okay"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@18 { + target = <0x123>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x16d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@14 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx274 30-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x16f>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@0 { + target = <0x16e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x124>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x120>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@15 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + gpios = <0x8d 0x0>; + gpio-hog; + status = "okay"; + label = "cam0-rst"; + output-high; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + }; + + fragement-pmon-p3310-1000-800 { + ids = ">=3310-1000-800"; + + override@0 { + target = <0xf1>; + + _overlay_ { + + channel@2 { + ti,rail-name = "VDD_SYS_DDR"; + }; + + channel@0 { + ti,shunt-resistor-mohm = <0x14>; + }; + }; + }; + }; + + fragement@7 { + odm-data = "enable-high-speed-uart"; + + override@0 { + target = <0x103>; + + _overlay_ { + compatible = "nvidia,tegra186-hsuart"; + resets = <0x10 0x2f>; + early-print-console-channel; + reset-names = "serial"; + }; + }; + }; + + fragment-e1824-a00@3 { + ids = "1824-1100-001"; + + overrides@0 { + target = <0xb6>; + + _overlay_ { + + sor { + status = "okay"; + nvidia,active-panel = <0x11f>; + + panel-s-edp-uhdtv-15-6 { + nvidia,is_ext_dp_panel = <0x0>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + status = "okay"; + nvidia,en-vmm-vpp-with-i2c-config; + + smartdimmer { + status = "okay"; + }; + + disp-default-out { + nvidia,out-parent-clk = "plld3"; + }; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + }; + + fragment-e3333@0 { + ids = "3333-*"; + + override@11 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@68 { + target = <0x39>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x161>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@1 { + target = <0x128>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@58 { + target = <0x159>; + + _overlay_ { + status = "okay"; + }; + }; + + override@48 { + target = <0x70>; + + _overlay_ { + remote-endpoint = <0x68>; + status = "okay"; + }; + }; + + override@38 { + target = <0x148>; + + _overlay_ { + status = "okay"; + }; + }; + + override@66 { + target = <0x15f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@28 { + target = <0x140>; + + _overlay_ { + badge = "e3333_centerright_P5V27C"; + status = "okay"; + position = "centerright"; + orientation = [31 00]; + }; + }; + + override@56 { + target = <0x157>; + + _overlay_ { + status = "okay"; + }; + }; + + override@18 { + target = <0x125>; + + _overlay_ { + devname = "ov5693 31-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/ov5693_b@36"; + }; + }; + + override@46 { + target = <0x37>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x14f>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@712 { + target = <0x28>; + + _overlay_ { + + camera-control-output-high { + status = "okay"; + }; + + camera-control-output-low { + status = "okay"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@8 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@36 { + target = <0x147>; + + _overlay_ { + status = "okay"; + }; + }; + + override@64 { + target = <0x15e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@26 { + target = <0x6e>; + + _overlay_ { + remote-endpoint = <0x64>; + status = "okay"; + }; + }; + + override@54 { + target = <0x6a>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x71>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@16 { + target = <0x13a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@44 { + target = <0x14d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@72 { + target = <0x35>; + + _overlay_ { + + tca6408_21_input { + status = "disabled"; + }; + + tca6408_21_outlow { + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0 0x6 0x0 0x7 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5", "tca6408_21_outlow_6", "tca6408_21_outlow_7"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + }; + + override@6 { + target = <0x121>; + + _overlay_ { + badge = "e3333_bottomleft_P5V27C"; + status = "okay"; + position = "bottomleft"; + orientation = [31 00]; + }; + }; + + override@34 { + target = <0x145>; + + _overlay_ { + status = "okay"; + }; + }; + + override@62 { + target = <0x15c>; + + _overlay_ { + devname = "ov5693 35-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/ov5693_f@36"; + }; + }; + + override@24 { + target = <0x2d>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x13e>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@52 { + target = <0x154>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@14 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@42 { + target = <0x14c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@70 { + target = <0x72>; + + _overlay_ { + remote-endpoint = <0x6c>; + status = "okay"; + }; + }; + + override@4 { + target = <0x13b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@32 { + target = <0x66>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6f>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@60 { + target = <0x15a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@22 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@50 { + target = <0x152>; + + _overlay_ { + badge = "e3333_bottomright_P5V27C"; + status = "okay"; + position = "bottomright"; + orientation = [31 00]; + }; + }; + + override@12 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@40 { + target = <0x14a>; + + _overlay_ { + devname = "ov5693 33-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/ov5693_d@36"; + }; + }; + + override@69 { + target = <0x162>; + + _overlay_ { + status = "okay"; + }; + }; + + override@2 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + max_pixel_rate = <0x30d40>; + num_csi_lanes = <0xc>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@30 { + target = <0x142>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@59 { + target = <0x71>; + + _overlay_ { + remote-endpoint = <0x6a>; + status = "okay"; + }; + }; + + override@20 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@49 { + target = <0x151>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@39 { + target = <0x149>; + + _overlay_ { + badge = "e3333_topleft_P5V27C"; + status = "okay"; + position = "topleft"; + orientation = [31 00]; + }; + }; + + override@67 { + target = <0x160>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x6>; + }; + }; + + override@29 { + target = <0x141>; + + _overlay_ { + devname = "ov5693 32-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/ov5693_c@36"; + }; + }; + + override@57 { + target = <0x38>; + + _overlay_ { + port-index = <0x4>; + remote-endpoint = <0x158>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@19 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@47 { + target = <0x150>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@37 { + target = <0x6f>; + + _overlay_ { + remote-endpoint = <0x66>; + status = "okay"; + }; + }; + + override@65 { + target = <0x6c>; + + _overlay_ { + port-index = <0x5>; + remote-endpoint = <0x72>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@27 { + target = <0x13f>; + + _overlay_ { + status = "okay"; + }; + }; + + override@55 { + target = <0x156>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x124>; + + _overlay_ { + badge = "e3333_centerleft_P5V27C"; + status = "okay"; + position = "centerleft"; + orientation = [31 00]; + }; + }; + + override@45 { + target = <0x14e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@73 { + target = <0x59>; + + _overlay_ { + compatible = "nvidia,tegra186-i2c"; + }; + }; + + override@7 { + target = <0x122>; + + _overlay_ { + devname = "ov5693 30-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@0/ov5693_a@36"; + }; + }; + + override@35 { + target = <0x36>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x146>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@63 { + target = <0x15d>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@25 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@53 { + target = <0x155>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@43 { + target = <0x68>; + + _overlay_ { + port-index = <0x3>; + remote-endpoint = <0x70>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@71 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + status = "disabled"; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x5e 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@5 { + target = <0x13c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@33 { + target = <0x144>; + + _overlay_ { + status = "okay"; + }; + }; + + override@61 { + target = <0x15b>; + + _overlay_ { + badge = "e3333_topright_P5V27C"; + status = "okay"; + position = "topright"; + orientation = [31 00]; + }; + }; + + override@23 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@51 { + target = <0x153>; + + _overlay_ { + devname = "ov5693 34-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/ov5693_e@36"; + }; + }; + + override@13 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x13d>; + status = "okay"; + bus-width = <0x2>; + }; + }; + + override@41 { + target = <0x14b>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + }; + }; + + override@3 { + target = <0x35>; + + _overlay_ { + status = "okay"; + }; + }; + + override@31 { + target = <0x143>; + + _overlay_ { + status = "okay"; + }; + }; + + override@21 { + target = <0x64>; + + _overlay_ { + port-index = <0x1>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x2>; + }; + }; + }; + + fragment-imx185@0 { + ids = "LPRD-002001"; + + override@11 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx185_bottom_liimx185"; + status = "okay"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@18 { + target = <0x124>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@8 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@16 { + target = <0x120>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@6 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@14 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@12 { + target = <0x6d>; + + _overlay_ { + remote-endpoint = <0x62>; + status = "okay"; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx185 30-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a"; + }; + }; + + override@10 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x16c>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@0 { + target = <0x16b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x123>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@7 { + target = <0x128>; + + _overlay_ { + num-channels = <0x1>; + }; + }; + + override@15 { + target = <0x16d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + }; + }; + }; + + fragment-e1639-sharp-25x16@2 { + ids = "1639-1000-001"; + + overrides@4 { + target = <0xb6>; + + _overlay_ { + + dsi { + status = "okay"; + }; + + nvdisplay@15200000 { + status = "okay"; + }; + }; + }; + + overrides@2 { + target = <0x102>; + + _overlay_ { + status = "disabled"; + }; + }; + + overrides@0 { + target = <0x11d>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@3 { + target = <0x11e>; + + _overlay_ { + status = "okay"; + }; + }; + + overrides@1 { + target = <0x88>; + + _overlay_ { + regulator-boot-on; + enable-active-high; + gpio = <0x28 0xb 0x1>; + regulator-always-on; + }; + }; + }; + + fragment-imx274-dual@0 { + ids = "LPRD-dual-imx274-002"; + + override@11 { + target = <0x62>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@1 { + target = <0x121>; + + _overlay_ { + badge = "imx274_bottom_A6V26"; + status = "okay"; + position = "bottom"; + orientation = [30 00]; + }; + }; + + override@18 { + target = <0x6d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@8 { + target = <0x5a>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@26 { + target = <0x1b>; + + _overlay_ { + + camera-control-output-high { + gpios = <0x8d 0x0 0x88 0x0>; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam1-rst"; + output-high; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + }; + + override@16 { + target = <0x30>; + + _overlay_ { + port-index = <0x0>; + remote-endpoint = <0x16f>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@6 { + target = <0x125>; + + _overlay_ { + devname = "imx274 31-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@1/imx274_c@1a"; + }; + }; + + override@24 { + target = <0x12f>; + + _overlay_ { + isp_bw_margin_pct = <0x19>; + num_csi_lanes = <0x8>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + vi_bw_margin_pct = <0x19>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + }; + }; + + override@14 { + target = <0x129>; + + _overlay_ { + status = "okay"; + }; + }; + + override@4 { + target = <0x170>; + + _overlay_ { + status = "okay"; + }; + }; + + override@22 { + target = <0x12e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@12 { + target = <0x64>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x6e>; + status = "okay"; + bus-width = <0x4>; + }; + }; + + override@2 { + target = <0x122>; + + _overlay_ { + devname = "imx274 30-001a"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx274_a@1a"; + }; + }; + + override@20 { + target = <0x12d>; + + _overlay_ { + status = "okay"; + }; + }; + + override@10 { + target = <0x127>; + + _overlay_ { + status = "okay"; + }; + }; + + override@0 { + target = <0x16e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@19 { + target = <0x12c>; + + _overlay_ { + status = "okay"; + }; + }; + + override@9 { + target = <0x126>; + + _overlay_ { + status = "okay"; + }; + }; + + override@17 { + target = <0x12b>; + + _overlay_ { + status = "okay"; + }; + }; + + override@7 { + target = <0x137>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + + override@25 { + target = <0x130>; + + _overlay_ { + status = "okay"; + }; + }; + + override@15 { + target = <0x12a>; + + _overlay_ { + status = "okay"; + }; + }; + + override@5 { + target = <0x124>; + + _overlay_ { + badge = "imx274_top_A6V26"; + status = "okay"; + position = "top"; + orientation = [30 00]; + }; + }; + + override@23 { + target = <0x6e>; + + _overlay_ { + status = "okay"; + }; + }; + + override@13 { + target = <0x128>; + + _overlay_ { + num-channels = <0x2>; + }; + }; + + override@3 { + target = <0x133>; + + _overlay_ { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + }; + }; + + override@21 { + target = <0x2d>; + + _overlay_ { + port-index = <0x2>; + remote-endpoint = <0x171>; + status = "okay"; + bus-width = <0x4>; + }; + }; + }; + + fragment-e3320-dp { + ids = ">=3320-1000-000", ">=3320-1100-000"; + + override@0 { + target = <0xb6>; + + _overlay_ { + + nvdisplay@15220000 { + status = "okay"; + }; + + sor { + status = "okay"; + + dp-display { + status = "okay"; + }; + }; + + dpaux@155c0000 { + status = "okay"; + }; + }; + }; + }; + + fragement@10 { + odm-data = "enable-ufs-on-uphy-lane4"; + + override@1 { + target = <0x105>; + + _overlay_ { + status = "disabled"; + }; + }; + + override@0 { + target = <0x104>; + + _overlay_ { + status = "okay"; + }; + }; + + override@3 { + target = <0x106>; + + _overlay_ { + + gpio@76 { + + pcie0_lane4_mux { + status = "disabled"; + }; + + ufs_lane4_mux { + status = "okay"; + }; + + sata_lane5_mux { + status = "disabled"; + }; + + ufs_lane5_mux { + status = "okay"; + }; + }; + }; + }; + }; + + fragment-devslp@0 { + ids = ">=3310-1000-200"; + + override@1 { + target = <0x3b>; + + _overlay_ { + + pin_gpio7 { + drive-push-pull = <0x1>; + }; + }; + }; + + override@0 { + target = <0x105>; + + _overlay_ { + gpios = <0x22 0x7 0x0>; + }; + }; + }; + }; + + combined-uart { + compatible = "nvidia,tegra186-combined-uart"; + status = "NILL"; + interrupts = <0x0 0x78 0x4>; + reg = <0x0 0x3c10000 0x0 0x4 0x0 0xc168000 0x0 0x4 0x0 0x3c00000 0x0 0x1000>; + }; + + sdhci@3420000 { + nvidia,ddr-tap-delay = <0xb>; + cap-mmc-highspeed; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x35 0x10 0x10d 0x10 0x80>; + mmc-ddr-1_8v; + cap-sd-highspeed; + resets = <0x10 0x22>; + pinctrl-1 = <0x18>; + nvidia,is-emmc; + clock-names = "sdmmc", "pll_p", "sdmmc_legacy_tm"; + pll_source = "pll_p"; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "disabled"; + nvidia,max-tap-delay = <0x88>; + interrupts = <0x0 0x3f 0x4>; + bus-width = <0x8>; + ddr-trim-delay = <0x5>; + phandle = <0x17a>; + tap-delay = <0xb>; + reg = <0x0 0x3420000 0x0 0x210>; + iommus = <0x11 0x19>; + pinctrl-0 = <0x17>; + mmc-ocr-mask = <0x0>; + compad-vref-1v8 = <0x2>; + trim-delay = <0x5>; + pwrdet-support; + reset-names = "sdhci"; + vmmc-supply = <0x13>; + linux,phandle = <0x17a>; + non-removable; + ignore-pm-notify; + compad-vref-3v3 = <0x1>; + mmc-hs200-1_8v; + vqmmc-supply = <0x12>; + pinctrl-names = "sdmmc_e_33v_enable", "sdmmc_e_33v_disable"; + max-clk-limit = <0xbebc200>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_sdr104 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod { + prod = <0x100 0x1fff002e 0x50b0028 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_sdr50 { + prod = <0x100 0xff0000 0xb0000 0x1c0 0xe000 0x8000 0x1e0 0xf 0x2 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x5090000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs400 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + }; + }; + + bthrot_cdev { + compatible = "nvidia,tegra18x-balanced-throttle"; + clocks = <0x10 0x242 0x10 0x243 0x10 0x136 0x10 0x3a>; + clock-names = "mcpu", "bcpu", "gpu", "emc"; + + skin_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x1d8760 0x1d8760 0x1314c4 0xffffffff 0x1d2658 0x1d2658 0x12cf9c 0xffffffff 0x1cc550 0x1cc550 0x128a74 0xffffffff 0x1c6448 0x1c6448 0x12454c 0xffffffff 0x1c0340 0x1c0340 0x120025 0xffffffff 0x1ba238 0x1ba238 0x11bafd 0xffffffff 0x1b4130 0x1b4130 0x1175d5 0xffffffff 0x1ae028 0x1ae028 0x1130ad 0xffffffff 0x1a7f20 0x1a7f20 0x10eb85 0xffffffff 0x1a1e18 0x1a1e18 0x10a65d 0xffffffff 0x19bd10 0x19bd10 0x106136 0xffffffff 0x195c08 0x195c08 0x101c0e 0xffffffff 0x18fb00 0x18fb00 0xfd6e6 0xffffffff 0x1899f8 0x1899f8 0xf91be 0xffffffff 0x1838f0 0x1838f0 0xf4c96 0xffffffff 0x17d7e8 0x17d7e8 0xf076e 0xffffffff 0x1776e0 0x1776e0 0xec246 0xffffffff 0x1715d8 0x1715d8 0xe7d1f 0xffffffff 0x16b4d0 0x16b4d0 0xe37f7 0xffffffff 0x1653c8 0x1653c8 0xdf2cf 0xffffffff 0x15f2c0 0x15f2c0 0xdada7 0xffffffff 0x1591b8 0x1591b8 0xd687f 0xffffffff 0x1530b0 0x1530b0 0xd2357 0xffffffff 0x14cfa8 0x14cfa8 0xcde30 0xffffffff 0x146ea0 0x146ea0 0xc9908 0xffffffff 0x140d98 0x140d98 0xc53e0 0xffffffff 0x13ac90 0x13ac90 0xc0eb8 0xffffffff 0x134b88 0x134b88 0xbc990 0xffffffff 0x12ea80 0x12ea80 0xb8468 0xffffffff 0x128978 0x128978 0xb3f40 0xffffffff 0x122870 0x122870 0xafa19 0xffffffff 0x11c768 0x11c768 0xab4f1 0xffffffff 0x116660 0x116660 0xa6fc9 0xffffffff 0x110558 0x110558 0xa2aa1 0xffffffff 0x10a450 0x10a450 0x9e579 0xffffffff 0x104348 0x104348 0x9a051 0xffffffff 0xfe240 0xfe240 0x95b2a 0xffffffff 0xf8138 0xf8138 0x91602 0xffffffff 0xf2030 0xf2030 0x8d0da 0xffffffff 0xebf28 0xebf28 0x88bb2 0xffffffff 0xe5e20 0xe5e20 0x8468a 0xffffffff 0xdfd18 0xdfd18 0x80162 0xffffffff 0xd9c10 0xd9c10 0x7bc3a 0xffffffff 0xd3b08 0xd3b08 0x77713 0xffffffff 0xcda00 0xcda00 0x731eb 0xffffffff 0xc78f8 0xc78f8 0x6ecc3 0xffffffff 0xc17f0 0xc17f0 0x6a79b 0xffffffff 0xbb6e8 0xbb6e8 0x66273 0xffffffff 0xb55e0 0xb55e0 0x61d4b 0xffffffff 0xaf4d8 0xaf4d8 0x5d824 0xffffffff 0xa93d0 0xa93d0 0x592fc 0xffffffff 0xa32c8 0xa32c8 0x54dd4 0xffffffff 0x9d1c0 0x9d1c0 0x508ac 0xffffffff 0x970b8 0x970b8 0x4c384 0xffffffff 0x90fb0 0x90fb0 0x47e5c 0xffffffff 0x8aea8 0x8aea8 0x43934 0xffffffff 0x84da0 0x84da0 0x3f40d 0xffffffff 0x7ec98 0x7ec98 0x3aee5 0xffffffff 0x78b90 0x78b90 0x369bd 0xffffffff 0x72a88 0x72a88 0x32495 0xffffffff 0x6c980 0x6c980 0x2df6d 0xffffffff 0x66878 0x66878 0x29a45 0xffffffff 0x60770 0x60770 0x2551e 0xffffffff 0x5a668 0x5a668 0x20ff6 0xffffffff 0x54560 0x54560 0x1cace 0xffffffff 0x4e458 0x4e458 0x185a6 0xffffffff>; + cooling-max-state = <0x42>; + #cooling-cells = <0x2>; + cdev-type = "skin-balanced"; + }; + + gpu_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x1d8760 0x1d8760 0x12b31c 0xffffffff 0x1d2658 0x1d2658 0x125ce2 0xffffffff 0x1cc550 0x1cc550 0x1206a9 0xffffffff 0x1c6448 0x1c6448 0x11b06f 0xffffffff 0x1c0340 0x1c0340 0x115a36 0xffffffff 0x1ba238 0x1ba238 0x1103fc 0xffffffff 0x1b4130 0x1b4130 0x10adc3 0xffffffff 0x1ae028 0x1ae028 0x105789 0xffffffff 0x1a7f20 0x1a7f20 0x100150 0xffffffff 0x1a1e18 0x1a1e18 0xfab16 0xffffffff 0x19bd10 0x19bd10 0xf54dd 0xffffffff 0x195c08 0x195c08 0xefea3 0xffffffff 0x18fb00 0x18fb00 0xea86a 0xffffffff 0x1899f8 0x1899f8 0xe5230 0xffffffff 0x1838f0 0x1838f0 0xdfbf7 0xffffffff 0x17d7e8 0x17d7e8 0xda5bd 0xffffffff 0x1776e0 0x1776e0 0xd4f84 0xffffffff 0x1715d8 0x1715d8 0xcf94a 0xffffffff 0x16b4d0 0x16b4d0 0xca310 0xffffffff 0x1653c8 0x1653c8 0xc4cd7 0xffffffff 0x15f2c0 0x15f2c0 0xbf69d 0xffffffff 0x1591b8 0x1591b8 0xba064 0xffffffff 0x1530b0 0x1530b0 0xb4a2a 0xffffffff 0x14cfa8 0x14cfa8 0xaf3f1 0xffffffff 0x146ea0 0x146ea0 0xa9db7 0xffffffff 0x140d98 0x140d98 0xa477e 0xffffffff 0x13ac90 0x13ac90 0x9f144 0xffffffff 0x134b88 0x134b88 0x99b0b 0xffffffff 0x12ea80 0x12ea80 0x944d1 0xffffffff 0x128978 0x128978 0x8ee98 0xffffffff 0x122870 0x122870 0x8985e 0xffffffff 0x11c768 0x11c768 0x84225 0xffffffff 0x116660 0x116660 0x7ebeb 0xffffffff 0x110558 0x110558 0x795b2 0xffffffff 0x10a450 0x10a450 0x73f78 0xffffffff 0x104348 0x104348 0x6e93e 0xffffffff 0xfe240 0xfe240 0x69305 0xffffffff 0xf8138 0xf8138 0x63ccb 0xffffffff 0xf2030 0xf2030 0x5e692 0xffffffff 0xebf28 0xebf28 0x59058 0xffffffff 0xe5e20 0xe5e20 0x53a1f 0xffffffff 0xdfd18 0xdfd18 0x4e3e5 0xffffffff 0xd9c10 0xd9c10 0x48dac 0xffffffff 0xd3b08 0xd3b08 0x43772 0xffffffff 0xcda00 0xcda00 0x3e139 0xffffffff 0xc78f8 0xc78f8 0x38aff 0xffffffff 0xc17f0 0xc17f0 0x334c6 0xffffffff 0xbb6e8 0xbb6e8 0x2de8c 0xffffffff 0xb55e0 0xb55e0 0x28853 0xffffffff 0xaf4d8 0xaf4d8 0x23219 0xffffffff 0xa93d0 0xa93d0 0x1dbe0 0xffffffff 0xa32c8 0xa32c8 0x185a6 0xffffffff>; + phandle = <0x52>; + cooling-max-state = <0x34>; + #cooling-cells = <0x2>; + linux,phandle = <0x52>; + cdev-type = "gpu-balanced"; + }; + + cpu_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x1d8760 0x1d8760 0xffffffff 0xffffffff 0x1d2658 0x1d2658 0xffffffff 0xffffffff 0x1cc550 0x1cc550 0xffffffff 0xffffffff 0x1c6448 0x1c6448 0xffffffff 0xffffffff 0x1c0340 0x1c0340 0xffffffff 0xffffffff 0x1ba238 0x1ba238 0xffffffff 0xffffffff 0x1b4130 0x1b4130 0xffffffff 0xffffffff 0x1ae028 0x1ae028 0xffffffff 0xffffffff 0x1a7f20 0x1a7f20 0xffffffff 0xffffffff 0x1a1e18 0x1a1e18 0xffffffff 0xffffffff 0x19bd10 0x19bd10 0x13d814 0xffffffff 0x195c08 0x195c08 0x1382cc 0xffffffff 0x18fb00 0x18fb00 0x132d84 0xffffffff 0x1899f8 0x1899f8 0x12d83d 0xffffffff 0x1838f0 0x1838f0 0x1282f5 0xffffffff 0x17d7e8 0x17d7e8 0x122dad 0xffffffff 0x1776e0 0x1776e0 0x11d865 0xffffffff 0x1715d8 0x1715d8 0x11831d 0xffffffff 0x16b4d0 0x16b4d0 0x112dd5 0xffffffff 0x1653c8 0x1653c8 0x10d88e 0xffffffff 0x15f2c0 0x15f2c0 0x108346 0xffffffff 0x1591b8 0x1591b8 0x102dfe 0xffffffff 0x1530b0 0x1530b0 0xfd8b6 0xffffffff 0x14cfa8 0x14cfa8 0xf836e 0xffffffff 0x146ea0 0x146ea0 0xf2e27 0xffffffff 0x140d98 0x140d98 0xed8df 0xffffffff 0x13ac90 0x13ac90 0xe8397 0xffffffff 0x134b88 0x134b88 0xe2e4f 0xffffffff 0x12ea80 0x12ea80 0xdd907 0xffffffff 0x128978 0x128978 0xd83bf 0xffffffff 0x122870 0x122870 0xd2e78 0xffffffff 0x11c768 0x11c768 0xcd930 0xffffffff 0x116660 0x116660 0xc83e8 0xffffffff 0x110558 0x110558 0xc2ea0 0xffffffff 0x10a450 0x10a450 0xbd958 0xffffffff 0x104348 0x104348 0xb8411 0xffffffff 0xfe240 0xfe240 0xb2ec9 0xffffffff 0xf8138 0xf8138 0xad981 0xffffffff 0xf2030 0xf2030 0xa8439 0xffffffff 0xebf28 0xebf28 0xa2ef1 0xffffffff 0xe5e20 0xe5e20 0x9d9a9 0xffffffff 0xdfd18 0xdfd18 0x98462 0xffffffff 0xd9c10 0xd9c10 0x92f1a 0xffffffff 0xd3b08 0xd3b08 0x8d9d2 0xffffffff 0xcda00 0xcda00 0x8848a 0xffffffff 0xc78f8 0xc78f8 0x82f42 0xffffffff 0xc17f0 0xc17f0 0x7d9fb 0xffffffff 0xbb6e8 0xbb6e8 0x784b3 0xffffffff 0xb55e0 0xb55e0 0x72f6b 0xffffffff 0xaf4d8 0xaf4d8 0x6da23 0xffffffff 0xa93d0 0xa93d0 0x684db 0xffffffff 0xa32c8 0xa32c8 0x62f93 0xffffffff 0x9d1c0 0x9d1c0 0x5da4c 0xffffffff 0x970b8 0x970b8 0x58504 0xffffffff 0x90fb0 0x90fb0 0x52fbc 0xffffffff 0x8aea8 0x8aea8 0x4da74 0xffffffff 0x84da0 0x84da0 0x4852c 0xffffffff 0x7ec98 0x7ec98 0x42fe5 0xffffffff 0x78b90 0x78b90 0x3da9d 0xffffffff 0x72a88 0x72a88 0x38555 0xffffffff 0x6c980 0x6c980 0x3300d 0xffffffff 0x66878 0x66878 0x2dac5 0xffffffff 0x60770 0x60770 0x2857d 0xffffffff 0x5a668 0x5a668 0x23036 0xffffffff 0x54560 0x54560 0x1daee 0xffffffff 0x4e458 0x4e458 0x185a6 0xffffffff>; + phandle = <0x49>; + cooling-max-state = <0x42>; + #cooling-cells = <0x2>; + linux,phandle = <0x49>; + cdev-type = "cpu-balanced"; + }; + + emergency_balanced { + cooling-min-state = <0x0>; + throttle_table = <0x111ed0 0x111ed0 0x5f758 0x60ae0>; + phandle = <0x55>; + cooling-max-state = <0x1>; + #cooling-cells = <0x2>; + linux,phandle = <0x55>; + cdev-type = "emergency-balanced"; + }; + }; + + ufshci@2450000 { + compatible = "tegra,ufs_variant"; + clocks = <0x10 0x94 0x10 0x8e 0x10 0x93 0x10 0x90 0x10 0x8c 0x10 0x8f 0x10 0x8d 0x10 0x91 0x10 0x27a 0x10 0xb2 0x10 0xb3 0x10 0x10d 0x10 0x261>; + nvidia,enable-wlu-scsi-device-add; + resets = <0x10 0x56 0x10 0x57 0x10 0x94 0x10 0x95 0x10 0x93 0x10 0x71 0x10 0x72 0x10 0xc0>; + nvidia,max-pwm-gear = <0x4>; + nvidia,enable-x2-config; + nvidia,enable-hs-mode; + pinctrl-1 = <0x24>; + nvidia,max-hs-gear = <0x3>; + clock-names = "mphy_core_pll_fixed", "mphy_l0_tx_symb", "mphy_tx_1mhz_ref", "mphy_l0_rx_ana", "mphy_l0_rx_symb", "mphy_l0_tx_ls_3xbit", "mphy_l0_rx_ls_bit", "mphy_l1_rx_ana", "mphy_force_ls_mode", "ufshc", "ufsdev_ref", "pll_p", "clk_m"; + vccq-max-microamp = <0x0>; + nvidia,enable-rx-calib; + vcc-max-microamp = <0x0>; + nvidia,enable-hibern8-war; + status = "disabled"; + interrupts = <0x0 0x2c 0x4>; + vccq2-max-microamp = <0x0>; + phandle = <0x104>; + reg = <0x0 0x2450000 0x0 0x4000>; + iommus = <0x11 0x15>; + pinctrl-0 = <0x23>; + reset-names = "mphy-l0-rx-rst", "mphy-l0-tx-rst", "mphy-l1-rx-rst", "mphy-l1-tx-rst", "mphy-clk-ctl-rst", "ufs-rst", "ufs-axi-m-rst", "ufshc-lp-rst"; + linux,phandle = <0x104>; + nvidia,mask-fast-auto-mode; + pinctrl-names = "ufs_dpd_enable", "ufs_dpd_disable"; + + ufs_variant { + compatible = "tegra,ufs_variant"; + }; + }; + + pwm@32a0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbd 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x65>; + clock-names = "pwm", "parent", "slow-parent"; + status = "okay"; + phandle = <0xeb>; + reg = <0x0 0x32a0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0xeb>; + #pwm-cells = <0x2>; + }; + + thermal-zones { + status = "okay"; + + GPU-therm { + thermal-sensors = <0x47 0x6>; + polling-delay = <0x0>; + polling-delay-passive = <0xfa>; + status = "okay"; + + trips { + + eqos-m40@-40000 { + hysteresis = <0x1388>; + temperature = <0xffff63c0>; + type = "active"; + phandle = <0x4b>; + linux,phandle = <0x4b>; + }; + + eqos-p30@30000 { + hysteresis = <0x1388>; + temperature = <0x7530>; + type = "active"; + phandle = <0x4e>; + linux,phandle = <0x4e>; + }; + + trip_critical { + hysteresis = <0x0>; + temperature = <0x18894>; + type = "critical"; + writable; + }; + + eqos-p100@100000 { + hysteresis = <0x1388>; + temperature = <0x186a0>; + type = "active"; + phandle = <0x50>; + linux,phandle = <0x50>; + }; + + trip_bthrot { + hysteresis = <0x0>; + temperature = <0x1750c>; + type = "passive"; + phandle = <0x51>; + writable; + linux,phandle = <0x51>; + }; + + eqos-p65@65000 { + hysteresis = <0x1388>; + temperature = <0xfde8>; + type = "active"; + phandle = <0x4f>; + linux,phandle = <0x4f>; + }; + + eqos-m5@-5000 { + hysteresis = <0x1388>; + temperature = <0xffffec78>; + type = "active"; + phandle = <0x4d>; + linux,phandle = <0x4d>; + }; + }; + + cooling-maps { + + map_eqos_m5 { + trip = <0x4d>; + cooling-device = <0x4c 0x2 0x2>; + cdev-type = "tegra-eqos"; + }; + + map0 { + trip = <0x51>; + cooling-device = <0x52 0xffffffff 0xffffffff>; + cdev-type = "gpu-balanced"; + }; + + map_eqos_p30 { + trip = <0x4e>; + cooling-device = <0x4c 0x3 0x3>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_m40 { + trip = <0x4b>; + cooling-device = <0x4c 0x1 0x1>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_p65 { + trip = <0x4f>; + cooling-device = <0x4c 0x4 0x4>; + cdev-type = "tegra-eqos"; + }; + + map_eqos_p100 { + trip = <0x50>; + cooling-device = <0x4c 0x5 0x5>; + cdev-type = "tegra-eqos"; + }; + }; + + thermal-zone-params { + governor-name = "step_wise"; + }; + }; + + AO-therm { + thermal-sensors = <0x47 0x6>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "disabled"; + phandle = <0xe7>; + linux,phandle = <0xe7>; + }; + + MCPU-therm { + thermal-sensors = <0x47 0x4>; + polling-delay = <0x0>; + polling-delay-passive = <0x1f4>; + status = "okay"; + + trips { + + trip_critical { + hysteresis = <0x0>; + temperature = <0x18894>; + type = "critical"; + writable; + }; + + trip_bthrot { + hysteresis = <0x0>; + temperature = <0x1750c>; + type = "passive"; + phandle = <0x4a>; + writable; + linux,phandle = <0x4a>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x4a>; + cooling-device = <0x49 0xffffffff 0xffffffff>; + cdev-type = "cpu-balanced"; + }; + }; + + thermal-zone-params { + governor-name = "step_wise"; + }; + }; + + BCPU-therm { + thermal-sensors = <0x47 0x2>; + polling-delay = <0x0>; + polling-delay-passive = <0x1f4>; + status = "okay"; + + trips { + + trip_critical { + hysteresis = <0x0>; + temperature = <0x18894>; + type = "critical"; + writable; + }; + + trip_bthrot { + hysteresis = <0x0>; + temperature = <0x1750c>; + type = "passive"; + phandle = <0x48>; + writable; + linux,phandle = <0x48>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x48>; + cooling-device = <0x49 0xffffffff 0xffffffff>; + cdev-type = "cpu-balanced"; + }; + }; + + thermal-zone-params { + governor-name = "step_wise"; + }; + }; + + PLL-therm { + thermal-sensors = <0x47 0x5>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "okay"; + }; + + PMIC-Die { + thermal-sensors = <0x22>; + polling-delay = <0x0>; + polling-delay-passive = <0x0>; + + trips { + + hot-die { + hysteresis = <0x0>; + temperature = <0x1d4c0>; + type = "active"; + phandle = <0x54>; + linux,phandle = <0x54>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x54>; + contribution = <0x64>; + cooling-device = <0x55 0xffffffff 0xffffffff>; + cdev-type = "emergency-balanced"; + }; + }; + }; + + Tboard_tegra { + thermal-sensors = <0x53 0x0>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "okay"; + phandle = <0xf5>; + linux,phandle = <0xf5>; + + trips { + + trip_critical { + hysteresis = <0x1>; + temperature = <0x1a1f8>; + type = "critical"; + }; + }; + + thermal-zone-params { + governor-name = "pid_thermal_gov"; + }; + }; + + Tdiode_tegra { + thermal-sensors = <0x53 0x1>; + polling-delay = <0x0>; + polling-delay-passive = <0x3e8>; + status = "okay"; + phandle = <0x19b>; + linux,phandle = <0x19b>; + + trips { + + trip_critical { + hysteresis = <0x0>; + temperature = <0x1a1f8>; + type = "critical"; + writable; + }; + }; + + thermal-zone-params { + governor-name = "pid_thermal_gov"; + }; + }; + }; + + aon@c160000 { + compatible = "nvidia,tegra186-aon"; + nvidia,ivc-rx-ss = <0x2>; + nvidia,ivc-dbg-enable-ss = <0x0>; + nvidia,hsp-shared-mailbox-names = "ivc-pair"; + nvidia,hsp-shared-mailbox = <0xe8 0x2>; + #mbox-cells = <0x1>; + status = "okay"; + nvidia,ivc-carveout-size-ss = <0x1>; + phandle = <0x41>; + nvidia,ivc-tx-ss = <0x3>; + reg = <0x0 0xc1a0000 0x0 0x40000>; + iommus = <0x11 0x16>; + linux,phandle = <0x41>; + nvidia,ivc-carveout-base-ss = <0x0>; + + ivc-channels@80000000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + + ivc_aon_echo@0 { + nvidia,frame-size = <0x40>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0x0 0x10000>; + }; + + ivc_can1@d000 { + nvidia,frame-size = <0x80>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0xd000 0x1d000>; + }; + + ivc_aon_spi@600 { + nvidia,frame-size = <0x6080>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x2>; + reg = <0x600 0x10600>; + }; + + ivc_aon_aondbg@480 { + nvidia,frame-size = <0x80>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x2>; + reg = <0x480 0x10480>; + }; + + ivc_can0@c780 { + nvidia,frame-size = <0x80>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x10>; + reg = <0xc780 0x1c780>; + }; + + ivc_aon_shub@d880 { + nvidia,frame-size = <0x100>; + reg-names = "rx", "tx"; + nvidia,frame-count = <0x4>; + reg = <0xd880 0x1d880>; + }; + }; + }; + + sdhci@3460000 { + nvidia,ddr-tap-delay = <0x9>; + cap-mmc-highspeed; + nvidia,en-periodic-cflush; + nvidia,enable-hwcq; + compatible = "nvidia,tegra186-sdhci"; + clocks = <0x10 0x36 0x10 0x10d 0x10 0x114 0x10 0x80>; + mmc-ddr-1_8v; + cap-sd-highspeed; + resets = <0x10 0x24>; + nvidia,parent_clk_list = "pll_p", "pll_p", "pll_p", "pll_p", "pll_p", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0", "pll_c4_out0"; + nvidia,is-emmc; + nvidia,clk-en-before-freq-update; + clock-names = "sdmmc", "pll_p", "pll_c4_out0", "sdmmc_legacy_tm"; + pll_source = "pll_p", "pll_c4_out0"; + only-1-8-v; + keep-power-in-suspend; + nvidia,min-tap-delay = <0x54>; + ddr-clk-limit = <0x2dc6c00>; + status = "NILL"; + nvidia,max-tap-delay = <0x88>; + nvidia,enable-strobe-mode; + interrupts = <0x0 0x41 0x4>; + bus-width = <0x8>; + nvidia,periodic-cflush-to = <0x64>; + ddr-trim-delay = <0x5>; + mmc-hs400-1_8v; + phandle = <0x101>; + calib-1v8-offsets = <0x505>; + tap-delay = <0x9>; + mmc-hs400-enhanced-strobe; + reg = <0x0 0x3460000 0x0 0x210>; + iommus = <0x11 0x17>; + mmc-ocr-mask = <0x0>; + compad-vref-1v8 = <0x7>; + trim-delay = <0x5>; + reset-names = "sdhci"; + vmmc-supply = <0x13>; + uhs-mask = <0x0>; + linux,phandle = <0x101>; + nvidia,set-parent-clk; + non-removable; + ignore-pm-notify; + compad-vref-3v3 = <0x7>; + calib-3v3-offsets = <0x505>; + mmc-hs200-1_8v; + vqmmc-supply = <0x12>; + max-clk-limit = <0xbb288cc>; + + prod-settings { + #prod-cells = <0x3>; + + prod { + prod = <0x100 0x1fff002e 0x5090028 0x10c 0x3f00 0x3f00 0x1c0 0xbfc1ff8 0x8000050 0x1c4 0x77 0x0 0x120 0x20001 0x1 0x128 0x43000000 0x0>; + }; + + prod_c_hs { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ddr52 { + prod = <0x100 0x1fff0000 0x5090000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_ds { + prod = <0x100 0xff0000 0x90000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000000>; + }; + + prod_c_hs200 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000505>; + }; + + prod_c_hs533 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x2000 0x1e0 0xf 0x7 0x1e4 0x20000000 0x20000505>; + }; + + prod_c_hs400 { + prod = <0x100 0xff0000 0x90000 0x1c0 0xe000 0x4000 0x10c 0x3f00 0x3f00 0x1e0 0xf 0x7 0x1e4 0x20007f7f 0x20000505>; + }; + }; + }; + + vi-bypass@15700000 { + compatible = "nvidia,tegra186-vi-bypass"; + status = "okay"; + }; + + etf@8030000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + clocks = <0x10 0xc4>; + coresight-default-sink; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8030000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe2>; + phandle = <0xe0>; + linux,phandle = <0xe0>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe1>; + phandle = <0xda>; + slave-mode; + linux,phandle = <0xda>; + }; + }; + }; + }; + + pwm@32e0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xc0 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x69>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x18b>; + reg = <0x0 0x32e0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x18b>; + #pwm-cells = <0x2>; + }; + + aondbg { + compatible = "nvidia,tegra186-aondbg"; + mboxes = <0x41 0x1>; + }; + + pwm-fan { + active_pwm = <0x0 0x50 0x78 0xa0 0xff 0xff 0xff 0xff 0xff 0xff>; + compatible = "pwm-fan"; + vdd-fan-supply = <0xee>; + status = "okay"; + shared_data = <0xed>; + pwms = <0xec 0x0 0xb116>; + #pwm-cells = <0x1>; + }; + + funnel_major@8010000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8010000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@3 { + reg = <0x2>; + + endpoint { + remote-endpoint = <0xdc>; + phandle = <0xe5>; + slave-mode; + linux,phandle = <0xe5>; + }; + }; + + port@1 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xdb>; + phandle = <0xd5>; + slave-mode; + linux,phandle = <0xd5>; + }; + }; + + port@4 { + reg = <0x3>; + + endpoint { + remote-endpoint = <0xdd>; + phandle = <0xd2>; + slave-mode; + linux,phandle = <0xd2>; + }; + }; + + port@2 { + reg = <0x1>; + + endpoint { + phandle = <0x1dd>; + slave-mode; + linux,phandle = <0x1dd>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xda>; + phandle = <0xe1>; + linux,phandle = <0xe1>; + }; + }; + }; + }; + + gps_wake { + compatible = "gps-wake"; + gps-wakeup-gpio = <0x1b 0x85 0x0>; + status = "disabled"; + gps-enable-gpio = <0xea 0x8 0x0>; + phandle = <0x1e6>; + linux,phandle = <0x1e6>; + }; + + tegra-carveouts { + compatible = "nvidia,carveouts-t18x"; + memory-region = <0x95 0x96>; + }; + + bpmp { + carveout-start = <0x77800000>; + compatible = "nvidia,tegra186-bpmp"; + carveout-size = <0x200000>; + status = "okay"; + phandle = <0x1f>; + reg = <0x0 0xd000000 0x0 0x800000 0x0 0x3004e000 0x0 0x1000 0x0 0x3004f000 0x0 0x1000>; + iommus = <0x11 0x32>; + linux,phandle = <0x1f>; + #power-domain-cells = <0x1>; + + bpmpthermal { + compatible = "nvidia,tegra186-bpmp-thermal"; + #thermal-sensor-cells = <0x1>; + status = "okay"; + phandle = <0x47>; + linux,phandle = <0x47>; + }; + }; + + axip2p@2110000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2110000 0x0 0x1000>; + }; + + spi@3240000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0x4a 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x2b>; + clock-names = "spi", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p", "clk_m"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x27 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x185>; + reg = <0x0 0x3240000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x12 0x25 0x12>; + reset-names = "spi"; + linux,phandle = <0x185>; + + spi@1 { + compatible = "spidev"; + reg = <0x1>; + spi-max-frequency = <0x1f78a40>; + + controller-data { + nvidia,tx-clk-tap-delay = <0x16>; + nvidia,enable-hw-based-cs; + nvidia,rx-clk-tap-delay = <0x8>; + }; + }; + + spi@0 { + compatible = "spidev"; + reg = <0x0>; + spi-max-frequency = <0x1f78a40>; + + controller-data { + nvidia,tx-clk-tap-delay = <0x16>; + nvidia,enable-hw-based-cs; + nvidia,rx-clk-tap-delay = <0x8>; + }; + }; + }; + + timer@3020000 { + compatible = "nvidia,tegra186-timer"; + wdt-count = <0x3>; + tmr-count = <0xa>; + status = "okay"; + interrupts = <0x0 0x0 0x4 0x0 0x1 0x4 0x0 0x2 0x4 0x0 0x3 0x4 0x0 0x4 0x4 0x0 0x5 0x4 0x0 0x6 0x4>; + reg = <0x0 0x3010000 0x0 0xe0000>; + clock-frequency = <0x124f800>; + }; + + host1x { + nvidia,nb-channels = <0x3c>; + compatible = "nvidia,tegra186-host1x", "simple-bus"; + clocks = <0x10 0x39 0x10 0xc9>; + wakeup_capable; + resets = <0x10 0x12>; + nvidia,nb-hw-pts = <0x240>; + clock-names = "host1x", "actmon"; + nvidia,ch-base = <0x0>; + ranges; + status = "okay"; + #address-cells = <0x2>; + interrupts = <0x0 0x109 0x4 0x0 0x107 0x4>; + nvidia,nb-pts = <0x23c>; + #size-cells = <0x2>; + phandle = <0xb6>; + nvidia,pts-base = <0x0>; + reg = <0x0 0x13e10000 0x0 0x10000 0x0 0x13e00000 0x0 0x10000 0x0 0x13ec0000 0x0 0x40000>; + iommus = <0x11 0x1 0x11 0x40 0x11 0x41 0x11 0x42 0x11 0x43 0x11 0x44 0x11 0x45 0x11 0x46 0x11 0x47>; + nvidia,vmid = <0x1>; + linux,phandle = <0xb6>; + + ctx3 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c1>; + iommus = <0x11 0x3b>; + linux,phandle = <0x1c1>; + }; + + nvdec@15480000 { + power-domains = <0x1f 0x6>; + compatible = "nvidia,tegra186-nvdec"; + clocks = <0x10 0x81 0x10 0x125>; + resets = <0x10 0x7d>; + clock-names = "nvdec", "kfuse"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15480000 0x0 0x40000>; + iommus = <0x11 0x6>; + }; + + tsec@15500000 { + compatible = "nvidia,tegra186-tsec"; + clocks = <0x10 0x51>; + resets = <0x10 0x2e>; + clock-names = "tsec"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15500000 0x0 0x40000>; + iommus = <0x11 0xa>; + }; + + dpaux@15040000 { + power-domains = <0x94>; + compatible = "nvidia,tegra186-dpaux1"; + clocks = <0x10 0x5f>; + resets = <0x10 0x7c>; + clock-names = "dpaux1"; + nvidia,dpaux-ctrlnum = <0x1>; + status = "okay"; + interrupts = <0x0 0xa0 0x4>; + phandle = <0x91>; + reg = <0x0 0x15040000 0x0 0x40000>; + reset-names = "dpaux1"; + linux,phandle = <0x91>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_dpaux_hdmi { + prod = <0x124 0x700 0x400>; + }; + + prod_c_dpaux_dp { + prod = <0x124 0x37fe 0x24c2>; + }; + }; + }; + + ctx1 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1bf>; + iommus = <0x11 0x39>; + linux,phandle = <0x1bf>; + }; + + dsi { + compatible = "nvidia,tegra186-dsi"; + clocks = <0x10 0x73 0x10 0x75 0x10 0x76 0x10 0x77 0x10 0xe7 0x10 0xe8 0x10 0xe9 0x10 0xea>; + resets = <0x10 0x6 0x10 0x7 0x10 0x3f 0x10 0x40 0x10 0x91>; + nvidia,enable-hs-clk-in-lp-mode = <0x1>; + clock-names = "dsi", "dsia_lp", "dsib", "dsib_lp", "dsic", "dsic_lp", "dsid", "dsid_lp"; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + phandle = <0x83>; + reg = <0x0 0x15300000 0x0 0x40000 0x0 0x15400000 0x0 0x40000 0x0 0x15900000 0x0 0x40000 0x0 0x15940000 0x0 0x40000 0x0 0x15880000 0x0 0x10000>; + reset-names = "dsia", "dsib", "dsic", "dsid", "dsi_padctrl"; + linux,phandle = <0x83>; + + prod-settings { + #prod-cells = <0x3>; + + dsi-padctrl-prod { + prod = <0x1c 0x7 0x0 0x20 0x1 0x0 0x24 0x3f0fc3f 0x0 0x28 0x333333 0x0 0x30 0xffffff 0x0 0x34 0xffffff 0x777777 0x4c 0x7 0x0 0x50 0x1 0x0 0x54 0x3f0fc3f 0x0 0x58 0x333333 0x0 0x60 0xffffff 0x0 0x64 0xffffff 0x777777 0x7c 0x7 0x0 0x80 0x1 0x0 0x84 0x3f0fc3f 0x0 0x88 0x333333 0x0 0x90 0xffffff 0x0 0x94 0xffffff 0x777777 0xac 0x7 0x0 0xb0 0x1 0x0 0xb4 0x3f0fc3f 0x0 0xb8 0x333333 0x0 0xc0 0xffffff 0x0 0xc4 0xffffff 0x777777>; + }; + }; + + panel-s-wuxga-8-0 { + nvidia,dsi-ganged-type = <0x1>; + compatible = "s,wuxga-8-0"; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-ganged-swap-links = <0x1>; + nvidia,dsi-refresh-rate = <0x3c>; + nvidia,dsi-video-burst-mode = <0x0>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-video-clock-mode = <0x0>; + nvidia,panel-bl-en-gpio = <0x28 0xb 0x1>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + nvidia,dsi-n-init-cmd = <0x3>; + nvidia,dsi-suspend-stop-stream-late = <0x1>; + nvidia,panel-en-gpio = <0x8d 0x4 0x1>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-init-cmd = <0x0 0x5 0x11 0x0 0x0 0x3 0xa 0x0 0x5 0x29 0x0 0x0>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-video-data-type = <0x0>; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + phandle = <0x102>; + nvidia,dsi-suspend-cmd = <0x0 0x5 0x28 0x0 0x0 0x3 0x3 0x0 0x5 0x10 0x0 0x0 0x3 0xa>; + nvidia,dsi-n-suspend-cmd = <0x4>; + nvidia,dsi-pkt-seq = <0x1 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff>; + nvidia,dsi-instance = <0x0>; + nvidia,dsi-panel-reset = <0x1>; + nvidia,default_color_space = <0x0>; + nvidia,en-vmm-vpp-with-i2c-config; + linux,phandle = <0x102>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,panel-bl-pwm-gpio = <0x28 0x8 0x1>; + + cmu { + nvidia,cmu-csc = <0x100 0x0 0x0 0x0 0x100 0x0 0x0 0x0 0x100>; + nvidia,cmu-lut2 = <0x0 0x1 0x2 0x2 0x3 0x4 0x5 0x6 0x6 0x7 0x8 0x9 0xa 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0xf 0x10 0x10 0x11 0x12 0x12 0x13 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x17 0x18 0x18 0x19 0x19 0x19 0x1a 0x1a 0x1b 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1d 0x1e 0x1e 0x1e 0x1f 0x1f 0x1f 0x20 0x20 0x20 0x21 0x21 0x21 0x22 0x22 0x22 0x22 0x23 0x23 0x23 0x24 0x24 0x24 0x25 0x25 0x25 0x25 0x26 0x26 0x26 0x26 0x27 0x27 0x27 0x28 0x28 0x28 0x28 0x29 0x29 0x29 0x29 0x2a 0x2a 0x2a 0x2a 0x2b 0x2b 0x2b 0x2b 0x2b 0x2c 0x2c 0x2c 0x2c 0x2d 0x2d 0x2d 0x2d 0x2e 0x2e 0x2e 0x2e 0x2e 0x2f 0x2f 0x2f 0x2f 0x30 0x30 0x30 0x30 0x30 0x31 0x31 0x31 0x31 0x31 0x32 0x32 0x32 0x32 0x32 0x33 0x33 0x33 0x33 0x33 0x34 0x34 0x34 0x34 0x34 0x35 0x35 0x35 0x35 0x35 0x36 0x36 0x36 0x36 0x36 0x37 0x37 0x37 0x37 0x37 0x37 0x38 0x38 0x38 0x38 0x38 0x39 0x39 0x39 0x39 0x39 0x39 0x3a 0x3a 0x3a 0x3a 0x3a 0x3a 0x3b 0x3b 0x3b 0x3b 0x3b 0x3b 0x3c 0x3c 0x3c 0x3c 0x3c 0x3c 0x3d 0x3d 0x3d 0x3d 0x3d 0x3d 0x3e 0x3e 0x3e 0x3e 0x3e 0x3e 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x40 0x40 0x40 0x40 0x40 0x40 0x40 0x41 0x41 0x41 0x41 0x41 0x41 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x44 0x44 0x44 0x44 0x44 0x44 0x44 0x45 0x45 0x45 0x45 0x45 0x45 0x45 0x46 0x46 0x46 0x46 0x46 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x49 0x49 0x49 0x49 0x49 0x49 0x49 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x63 0x63 0x63 0x63 0x63 0x63 0x63 0x64 0x65 0x65 0x66 0x67 0x67 0x68 0x69 0x69 0x6a 0x6b 0x6b 0x6c 0x6d 0x6d 0x6e 0x6f 0x6f 0x70 0x71 0x71 0x72 0x73 0x73 0x74 0x74 0x75 0x76 0x76 0x77 0x77 0x78 0x78 0x79 0x7a 0x7a 0x7b 0x7b 0x7c 0x7c 0x7d 0x7e 0x7e 0x7f 0x7f 0x80 0x80 0x81 0x81 0x82 0x82 0x83 0x83 0x84 0x84 0x85 0x85 0x86 0x86 0x87 0x87 0x88 0x88 0x89 0x89 0x8a 0x8a 0x8b 0x8b 0x8c 0x8c 0x8d 0x8d 0x8e 0x8e 0x8f 0x8f 0x90 0x90 0x91 0x91 0x91 0x92 0x92 0x93 0x93 0x94 0x94 0x95 0x95 0x96 0x96 0x96 0x97 0x97 0x98 0x98 0x99 0x99 0x99 0x9a 0x9a 0x9b 0x9b 0x9c 0x9c 0x9c 0x9d 0x9d 0x9e 0x9e 0x9e 0x9f 0x9f 0xa0 0xa0 0xa0 0xa1 0xa1 0xa2 0xa2 0xa2 0xa3 0xa3 0xa4 0xa4 0xa4 0xa5 0xa5 0xa6 0xa6 0xa6 0xa7 0xa7 0xa7 0xa8 0xa8 0xa9 0xa9 0xa9 0xaa 0xaa 0xaa 0xab 0xab 0xac 0xac 0xac 0xad 0xad 0xad 0xae 0xae 0xae 0xaf 0xaf 0xb0 0xb0 0xb0 0xb1 0xb1 0xb1 0xb2 0xb2 0xb2 0xb3 0xb3 0xb3 0xb4 0xb4 0xb4 0xb5 0xb5 0xb6 0xb6 0xb6 0xb7 0xb7 0xb7 0xb8 0xb8 0xb8 0xb9 0xb9 0xb9 0xba 0xba 0xba 0xbb 0xbb 0xbb 0xbc 0xbc 0xbc 0xbd 0xbd 0xbd 0xbd 0xbe 0xbe 0xbe 0xbf 0xbf 0xbf 0xc0 0xc0 0xc0 0xc1 0xc1 0xc1 0xc2 0xc2 0xc2 0xc3 0xc3 0xc3 0xc4 0xc4 0xc4 0xc4 0xc5 0xc5 0xc5 0xc6 0xc6 0xc6 0xc7 0xc7 0xc7 0xc8 0xc8 0xc8 0xc8 0xc9 0xc9 0xc9 0xca 0xca 0xca 0xca 0xcb 0xcb 0xcb 0xcc 0xcc 0xcc 0xcd 0xcd 0xcd 0xcd 0xce 0xce 0xce 0xcf 0xcf 0xcf 0xcf 0xd0 0xd0 0xd0 0xd1 0xd1 0xd1 0xd1 0xd2 0xd2 0xd2 0xd3 0xd3 0xd3 0xd3 0xd4 0xd4 0xd4 0xd5 0xd5 0xd5 0xd5 0xd6 0xd6 0xd6 0xd6 0xd7 0xd7 0xd7 0xd8 0xd8 0xd8 0xd8 0xd9 0xd9 0xd9 0xd9 0xda 0xda 0xda 0xdb 0xdb 0xdb 0xdb 0xdc 0xdc 0xdc 0xdc 0xdd 0xdd 0xdd 0xdd 0xde 0xde 0xde 0xdf 0xdf 0xdf 0xdf 0xe0 0xe0 0xe0 0xe0 0xe1 0xe1 0xe1 0xe1 0xe2 0xe2 0xe2 0xe2 0xe3 0xe3 0xe3 0xe3 0xe4 0xe4 0xe4 0xe4 0xe5 0xe5 0xe5 0xe5 0xe6 0xe6 0xe6 0xe6 0xe7 0xe7 0xe7 0xe7 0xe8 0xe8 0xe8 0xe8 0xe9 0xe9 0xe9 0xe9 0xea 0xea 0xea 0xea 0xeb 0xeb 0xeb 0xeb 0xec 0xec 0xec 0xec 0xed 0xed 0xed 0xed 0xee 0xee 0xee 0xee 0xef 0xef 0xef 0xef 0xf0 0xf0 0xf0 0xf0 0xf0 0xf1 0xf1 0xf1 0xf1 0xf2 0xf2 0xf2 0xf2 0xf3 0xf3 0xf3 0xf3 0xf4 0xf4 0xf4 0xf4 0xf4 0xf5 0xf5 0xf5 0xf5 0xf6 0xf6 0xf6 0xf6 0xf7 0xf7 0xf7 0xf7 0xf7 0xf8 0xf8 0xf8 0xf8 0xf9 0xf9 0xf9 0xf9 0xf9 0xfa 0xfa 0xfa 0xfa 0xfb 0xfb 0xfb 0xfb 0xfb 0xfc 0xfc 0xfc 0xfc 0xfd 0xfd 0xfd 0xfd 0xfd 0xfe 0xfe 0xfe 0xfe 0xff 0xff>; + }; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,turn-on-brightness = <0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "disabled"; + nvidia,smooth-k-incr = <0x4>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,turn-off-brightness = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,backlight_table = <0xff 0xf3 0xe8 0xde 0xd4 0xcb 0xc2 0xba 0xb3 0xab 0xa5 0x9e 0x98 0x92 0x8d 0x88 0x83 0x7e 0x7a 0x76 0x72 0x6e 0x6a 0x67 0x64 0x60 0x5d 0x5a 0x58 0x55 0x53 0x50 0x4e 0x4c 0x49 0x47 0x45 0x43 0x42 0x40 0x3e 0x3d 0x3b 0x3a 0x38 0x37 0x35 0x34 0x33 0x31 0x30>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,sw-update-delay = <0x0>; + nvidia,gain_table = <0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4000 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x4144 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x428c 0x4250 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x43d4 0x42b4 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x451c 0x44e0 0x4304 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4664 0x4660 0x4570 0x4318 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x47ac 0x4768 0x45e8 0x433c 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f4 0x48f0 0x482c 0x4644 0x4354 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a3c 0x4a00 0x48c4 0x4688 0x4368 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4b84 0x4af4 0x4960 0x46e0 0x4388 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ccc 0x4ca8 0x4ba8 0x49c0 0x4708 0x4390 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4e14 0x4db0 0x4c60 0x4a34 0x4748 0x43ac 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f5c 0x4f48 0x4e78 0x4cd4 0x4a6c 0x475c 0x43ac 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x50a0 0x5060 0x4f44 0x4d60 0x4ac4 0x478c 0x43c0 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x51e8 0x5158 0x4ff8 0x4dd8 0x4b14 0x47b4 0x43d0 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5330 0x5314 0x5238 0x5098 0x4e44 0x4b54 0x47d8 0x43dc 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5478 0x5424 0x5300 0x5124 0x4ea4 0x4b90 0x47f8 0x43e8 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55c0 0x55b8 0x5518 0x53b4 0x51a4 0x4ef8 0x4bc4 0x4814 0x43f0 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x5708 0x56dc 0x55f4 0x5458 0x5214 0x4f44 0x4bf0 0x4828 0x43f8 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x5850 0x57e8 0x56bc 0x54e8 0x527c 0x4f88 0x4c18 0x483c 0x4400 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5998 0x5990 0x58f4 0x579c 0x559c 0x5308 0x4ff4 0x4c64 0x486c 0x4414 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ae0 0x5ab8 0x59d4 0x5840 0x5614 0x5358 0x5024 0x4c80 0x4878 0x4418 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5c28 0x5bd8 0x5ac4 0x5908 0x56b4 0x53d8 0x5084 0x4cc4 0x48a4 0x4428 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d70 0x5d68 0x5cd0 0x5b80 0x5990 0x5714 0x5418 0x50a8 0x4cd8 0x48ac 0x442c 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5eb8 0x5e9c 0x5dd4 0x5c58 0x5a40 0x57a0 0x5484 0x50fc 0x4d10 0x48cc 0x443c 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x5fc4 0x5ecc 0x5d24 0x5ae8 0x5828 0x54ec 0x514c 0x4d48 0x48f0 0x4448 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x6144 0x60c4 0x5f8c 0x5db4 0x5b50 0x586c 0x5518 0x5160 0x4d50 0x48f0 0x4448 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x628c 0x6280 0x61cc 0x606c 0x5e6c 0x5be4 0x58e0 0x5574 0x51a4 0x4d80 0x490c 0x4454 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63d4 0x63ac 0x62cc 0x6140 0x5f1c 0x5c70 0x5950 0x55cc 0x51e4 0x4dac 0x4928 0x4460 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x651c 0x64cc 0x63c0 0x6208 0x5fc0 0x5cf8 0x59bc 0x561c 0x5220 0x4dd4 0x4940 0x446c 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x6664 0x65e0 0x64a4 0x62c8 0x605c 0x5d78 0x5a20 0x5668 0x525c 0x4dfc 0x4958 0x4474 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x67ac 0x679c 0x66e8 0x6584 0x6380 0x60f4 0x5df0 0x5a80 0x56b0 0x5290 0x4e20 0x4970 0x4480 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68f4 0x68c8 0x67e8 0x6654 0x642c 0x6180 0x5e60 0x5ad8 0x56f4 0x52c0 0x4e44 0x4984 0x4488 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x6a3c 0x69ec 0x68d8 0x6720 0x64d4 0x6208 0x5ecc 0x5b2c 0x5734 0x52f0 0x4e60 0x4994 0x4490 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b84 0x6b80 0x6b00 0x69c0 0x67e0 0x6570 0x6288 0x5f30 0x5b7c 0x5770 0x531c 0x4e80 0x49a8 0x4494 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6ccc 0x6cc4 0x6c24 0x6acc 0x68d0 0x6648 0x6344 0x5fd8 0x5c08 0x57e4 0x5378 0x4ec4 0x49d4 0x44ac 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6e14 0x6df8 0x6d28 0x6ba0 0x6980 0x66d8 0x63b8 0x6034 0x5c50 0x5818 0x539c 0x4edc 0x49e0 0x44b0 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f5c 0x6f1c 0x6e1c 0x6c6c 0x6a28 0x6760 0x6428 0x6088 0x5c90 0x584c 0x53c0 0x4ef4 0x49ec 0x44b4 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x70a0 0x7034 0x6f04 0x6d30 0x6ac8 0x67e0 0x648c 0x60d8 0x5cd0 0x5878 0x53e0 0x4f08 0x49f8 0x44bc 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x71e8 0x7160 0x7014 0x6e24 0x6ba4 0x68a4 0x6538 0x616c 0x5d4c 0x58e0 0x5430 0x4f44 0x4a20 0x44cc 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7330 0x7320 0x7264 0x70ec 0x6ed4 0x6c34 0x6918 0x6594 0x61b4 0x5d84 0x5908 0x544c 0x4f54 0x4a2c 0x44d0 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x7478 0x745c 0x7384 0x71f0 0x6fc0 0x6d04 0x69d4 0x6638 0x6244 0x5dfc 0x5968 0x5498 0x4f90 0x4a50 0x44e0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x75c0 0x7580 0x7474 0x72b8 0x7064 0x6d88 0x6a3c 0x668c 0x6280 0x5e28 0x598c 0x54b0 0x4f9c 0x4a58 0x44e4 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x7708 0x76b0 0x758c 0x73b4 0x7144 0x6e54 0x6af0 0x6728 0x6308 0x5e9c 0x59e8 0x54f8 0x4fd4 0x4a78 0x44f4 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x7850 0x77c0 0x766c 0x746c 0x71d8 0x6ec8 0x6b4c 0x6770 0x6340 0x5ec4 0x5a04 0x550c 0x4fdc 0x4a80 0x44f8 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7998 0x7990 0x78e4 0x7774 0x755c 0x72b0 0x6f88 0x6bf8 0x6804 0x63c0 0x5f30 0x5a5c 0x5550 0x5010 0x4aa0 0x4504 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ae0 0x7ac0 0x79e0 0x7844 0x7604 0x7338 0x6ff4 0x6c48 0x6844 0x63ec 0x5f50 0x5a74 0x5560 0x5018 0x4aa4 0x4508 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7c28 0x7bf8 0x7afc 0x7940 0x76e8 0x7404 0x70ac 0x6cec 0x68d0 0x6468 0x5fb8 0x5ac8 0x55a0 0x5048 0x4ac4 0x4514 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d70 0x7d2c 0x7c10 0x7a3c 0x77cc 0x74d0 0x7160 0x6d8c 0x695c 0x64dc 0x601c 0x5b18 0x55e0 0x5078 0x4ae0 0x4524 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7eb8 0x7e40 0x7cf4 0x7af4 0x785c 0x7544 0x71bc 0x6dd0 0x6990 0x6504 0x6034 0x5b28 0x55ec 0x507c 0x4ae4 0x4524 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x8000 0x7ffc 0x7f68 0x7e00 0x7be4 0x7938 0x7608 0x7268 0x6e68 0x6a14 0x6574 0x6094 0x5b78 0x5628 0x50a8 0x4b00 0x4530>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x1>; + }; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x2>; + nvidia,out-yres = <0x870>; + nvidia,out-height = <0xac>; + nvidia,out-width = <0x6b>; + }; + + display-timings { + + 1200x1920-32-60Hz { + hsync-len = <0x1>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x6b>; + vfront-porch = <0x1f1>; + nvidia,v-ref-to-sync = <0xb>; + vsync-len = <0x1>; + vactive = <0x780>; + hback-porch = <0x14>; + clock-frequency = <0xb845d40>; + hactive = <0x4b0>; + vback-porch = <0x7>; + }; + }; + + nvdisp-cmu { + nvidia,cmu-lut = <0x6000 0x6000 0x6000 0x6191 0x6191 0x6191 0x6322 0x6322 0x6322 0x643b 0x643b 0x643b 0x64ba 0x64ba 0x64ba 0x6539 0x6539 0x6539 0x65b8 0x65b8 0x65b8 0x6637 0x6637 0x6637 0x66b6 0x66b6 0x66b6 0x6735 0x6735 0x6735 0x67b4 0x67b4 0x67b4 0x6826 0x6826 0x6826 0x687d 0x687d 0x687d 0x68d4 0x68d4 0x68d4 0x692b 0x692b 0x692b 0x6983 0x6983 0x6983 0x69da 0x69da 0x69da 0x6a31 0x6a31 0x6a31 0x6a88 0x6a88 0x6a88 0x6ae0 0x6ae0 0x6ae0 0x6b37 0x6b37 0x6b37 0x6b8e 0x6b8e 0x6b8e 0x6be5 0x6be5 0x6be5 0x6c28 0x6c28 0x6c28 0x6c5b 0x6c5b 0x6c5b 0x6c8e 0x6c8e 0x6c8e 0x6cc1 0x6cc1 0x6cc1 0x6cf4 0x6cf4 0x6cf4 0x6d27 0x6d27 0x6d27 0x6d5a 0x6d5a 0x6d5a 0x6d8d 0x6d8d 0x6d8d 0x6dbf 0x6dbf 0x6dbf 0x6df2 0x6df2 0x6df2 0x6e25 0x6e25 0x6e25 0x6e58 0x6e58 0x6e58 0x6e8b 0x6e8b 0x6e8b 0x6ebe 0x6ebe 0x6ebe 0x6ef1 0x6ef1 0x6ef1 0x6f24 0x6f24 0x6f24 0x6f57 0x6f57 0x6f57 0x6f8a 0x6f8a 0x6f8a 0x6fbd 0x6fbd 0x6fbd 0x6ff0 0x6ff0 0x6ff0 0x701a 0x701a 0x701a 0x7037 0x7037 0x7037 0x7053 0x7053 0x7053 0x706f 0x706f 0x706f 0x708c 0x708c 0x708c 0x70a8 0x70a8 0x70a8 0x70c5 0x70c5 0x70c5 0x70e1 0x70e1 0x70e1 0x70fe 0x70fe 0x70fe 0x711a 0x711a 0x711a 0x7136 0x7136 0x7136 0x7153 0x7153 0x7153 0x716f 0x716f 0x716f 0x718c 0x718c 0x718c 0x71a8 0x71a8 0x71a8 0x71c4 0x71c4 0x71c4 0x71e1 0x71e1 0x71e1 0x71fd 0x71fd 0x71fd 0x721a 0x721a 0x721a 0x7236 0x7236 0x7236 0x7253 0x7253 0x7253 0x726f 0x726f 0x726f 0x728b 0x728b 0x728b 0x72a8 0x72a8 0x72a8 0x72c4 0x72c4 0x72c4 0x72e1 0x72e1 0x72e1 0x72fd 0x72fd 0x72fd 0x731a 0x731a 0x731a 0x7336 0x7336 0x7336 0x7352 0x7352 0x7352 0x736f 0x736f 0x736f 0x738b 0x738b 0x738b 0x73a8 0x73a8 0x73a8 0x73c4 0x73c4 0x73c4 0x73e1 0x73e1 0x73e1 0x73fd 0x73fd 0x73fd 0x741b 0x741b 0x741b 0x743f 0x743f 0x743f 0x7463 0x7463 0x7463 0x7486 0x7486 0x7486 0x74aa 0x74aa 0x74aa 0x74ce 0x74ce 0x74ce 0x74f2 0x74f2 0x74f2 0x7516 0x7516 0x7516 0x753a 0x753a 0x753a 0x755d 0x755d 0x755d 0x7581 0x7581 0x7581 0x75a5 0x75a5 0x75a5 0x75c9 0x75c9 0x75c9 0x75ed 0x75ed 0x75ed 0x7611 0x7611 0x7611 0x7634 0x7634 0x7634 0x7658 0x7658 0x7658 0x767c 0x767c 0x767c 0x76a0 0x76a0 0x76a0 0x76c4 0x76c4 0x76c4 0x76e8 0x76e8 0x76e8 0x770b 0x770b 0x770b 0x772f 0x772f 0x772f 0x7753 0x7753 0x7753 0x7777 0x7777 0x7777 0x779b 0x779b 0x779b 0x77bf 0x77bf 0x77bf 0x77e2 0x77e2 0x77e2 0x7806 0x7806 0x7806 0x7825 0x7825 0x7825 0x7840 0x7840 0x7840 0x785b 0x785b 0x785b 0x7876 0x7876 0x7876 0x7891 0x7891 0x7891 0x78ac 0x78ac 0x78ac 0x78c7 0x78c7 0x78c7 0x78e2 0x78e2 0x78e2 0x78fd 0x78fd 0x78fd 0x7918 0x7918 0x7918 0x7933 0x7933 0x7933 0x794e 0x794e 0x794e 0x7969 0x7969 0x7969 0x7984 0x7984 0x7984 0x799f 0x799f 0x799f 0x79ba 0x79ba 0x79ba 0x79d5 0x79d5 0x79d5 0x79f0 0x79f0 0x79f0 0x7a0b 0x7a0b 0x7a0b 0x7a26 0x7a26 0x7a26 0x7a41 0x7a41 0x7a41 0x7a5c 0x7a5c 0x7a5c 0x7a77 0x7a77 0x7a77 0x7a92 0x7a92 0x7a92 0x7aad 0x7aad 0x7aad 0x7ac8 0x7ac8 0x7ac8 0x7ae3 0x7ae3 0x7ae3 0x7afe 0x7afe 0x7afe 0x7b19 0x7b19 0x7b19 0x7b34 0x7b34 0x7b34 0x7b4f 0x7b4f 0x7b4f 0x7b6a 0x7b6a 0x7b6a 0x7b85 0x7b85 0x7b85 0x7ba0 0x7ba0 0x7ba0 0x7bbb 0x7bbb 0x7bbb 0x7bd5 0x7bd5 0x7bd5 0x7bf0 0x7bf0 0x7bf0 0x7c0b 0x7c0b 0x7c0b 0x7c23 0x7c23 0x7c23 0x7c35 0x7c35 0x7c35 0x7c47 0x7c47 0x7c47 0x7c59 0x7c59 0x7c59 0x7c6b 0x7c6b 0x7c6b 0x7c7d 0x7c7d 0x7c7d 0x7c90 0x7c90 0x7c90 0x7ca2 0x7ca2 0x7ca2 0x7cb4 0x7cb4 0x7cb4 0x7cc6 0x7cc6 0x7cc6 0x7cd8 0x7cd8 0x7cd8 0x7cea 0x7cea 0x7cea 0x7cfc 0x7cfc 0x7cfc 0x7d0f 0x7d0f 0x7d0f 0x7d21 0x7d21 0x7d21 0x7d33 0x7d33 0x7d33 0x7d45 0x7d45 0x7d45 0x7d57 0x7d57 0x7d57 0x7d69 0x7d69 0x7d69 0x7d7b 0x7d7b 0x7d7b 0x7d8e 0x7d8e 0x7d8e 0x7da0 0x7da0 0x7da0 0x7db2 0x7db2 0x7db2 0x7dc4 0x7dc4 0x7dc4 0x7dd6 0x7dd6 0x7dd6 0x7de8 0x7de8 0x7de8 0x7dfa 0x7dfa 0x7dfa 0x7e0d 0x7e0d 0x7e0d 0x7e1f 0x7e1f 0x7e1f 0x7e31 0x7e31 0x7e31 0x7e43 0x7e43 0x7e43 0x7e55 0x7e55 0x7e55 0x7e67 0x7e67 0x7e67 0x7e79 0x7e79 0x7e79 0x7e8c 0x7e8c 0x7e8c 0x7e9e 0x7e9e 0x7e9e 0x7eb0 0x7eb0 0x7eb0 0x7ec2 0x7ec2 0x7ec2 0x7ed4 0x7ed4 0x7ed4 0x7ee6 0x7ee6 0x7ee6 0x7ef8 0x7ef8 0x7ef8 0x7f0b 0x7f0b 0x7f0b 0x7f1d 0x7f1d 0x7f1d 0x7f2f 0x7f2f 0x7f2f 0x7f41 0x7f41 0x7f41 0x7f53 0x7f53 0x7f53 0x7f65 0x7f65 0x7f65 0x7f77 0x7f77 0x7f77 0x7f8a 0x7f8a 0x7f8a 0x7f9c 0x7f9c 0x7f9c 0x7fae 0x7fae 0x7fae 0x7fc0 0x7fc0 0x7fc0 0x7fd2 0x7fd2 0x7fd2 0x7fe4 0x7fe4 0x7fe4 0x7ff7 0x7ff7 0x7ff7 0x8009 0x8009 0x8009 0x801b 0x801b 0x801b 0x802b 0x802b 0x802b 0x803a 0x803a 0x803a 0x804a 0x804a 0x804a 0x8059 0x8059 0x8059 0x8069 0x8069 0x8069 0x8078 0x8078 0x8078 0x8087 0x8087 0x8087 0x8097 0x8097 0x8097 0x80a6 0x80a6 0x80a6 0x80b6 0x80b6 0x80b6 0x80c5 0x80c5 0x80c5 0x80d5 0x80d5 0x80d5 0x80e4 0x80e4 0x80e4 0x80f4 0x80f4 0x80f4 0x8103 0x8103 0x8103 0x8112 0x8112 0x8112 0x8122 0x8122 0x8122 0x8131 0x8131 0x8131 0x8141 0x8141 0x8141 0x8150 0x8150 0x8150 0x8160 0x8160 0x8160 0x816f 0x816f 0x816f 0x817e 0x817e 0x817e 0x818e 0x818e 0x818e 0x819d 0x819d 0x819d 0x81ad 0x81ad 0x81ad 0x81bc 0x81bc 0x81bc 0x81cc 0x81cc 0x81cc 0x81db 0x81db 0x81db 0x81eb 0x81eb 0x81eb 0x81fa 0x81fa 0x81fa 0x8209 0x8209 0x8209 0x8219 0x8219 0x8219 0x8228 0x8228 0x8228 0x8238 0x8238 0x8238 0x8247 0x8247 0x8247 0x8257 0x8257 0x8257 0x8266 0x8266 0x8266 0x8275 0x8275 0x8275 0x8285 0x8285 0x8285 0x8294 0x8294 0x8294 0x82a4 0x82a4 0x82a4 0x82b3 0x82b3 0x82b3 0x82c3 0x82c3 0x82c3 0x82d2 0x82d2 0x82d2 0x82e2 0x82e2 0x82e2 0x82f1 0x82f1 0x82f1 0x8300 0x8300 0x8300 0x8310 0x8310 0x8310 0x831f 0x831f 0x831f 0x832f 0x832f 0x832f 0x833e 0x833e 0x833e 0x834e 0x834e 0x834e 0x835d 0x835d 0x835d 0x836c 0x836c 0x836c 0x837c 0x837c 0x837c 0x838b 0x838b 0x838b 0x839b 0x839b 0x839b 0x83aa 0x83aa 0x83aa 0x83ba 0x83ba 0x83ba 0x83c9 0x83c9 0x83c9 0x83d8 0x83d8 0x83d8 0x83e8 0x83e8 0x83e8 0x83f7 0x83f7 0x83f7 0x8407 0x8407 0x8407 0x8416 0x8416 0x8416 0x8425 0x8425 0x8425 0x8431 0x8431 0x8431 0x843d 0x843d 0x843d 0x8449 0x8449 0x8449 0x8455 0x8455 0x8455 0x8462 0x8462 0x8462 0x846e 0x846e 0x846e 0x847a 0x847a 0x847a 0x8486 0x8486 0x8486 0x8492 0x8492 0x8492 0x849e 0x849e 0x849e 0x84aa 0x84aa 0x84aa 0x84b6 0x84b6 0x84b6 0x84c2 0x84c2 0x84c2 0x84ce 0x84ce 0x84ce 0x84da 0x84da 0x84da 0x84e7 0x84e7 0x84e7 0x84f3 0x84f3 0x84f3 0x84ff 0x84ff 0x84ff 0x850b 0x850b 0x850b 0x8517 0x8517 0x8517 0x8523 0x8523 0x8523 0x852f 0x852f 0x852f 0x853b 0x853b 0x853b 0x8547 0x8547 0x8547 0x8553 0x8553 0x8553 0x855f 0x855f 0x855f 0x856c 0x856c 0x856c 0x8578 0x8578 0x8578 0x8584 0x8584 0x8584 0x8590 0x8590 0x8590 0x859c 0x859c 0x859c 0x85a8 0x85a8 0x85a8 0x85b4 0x85b4 0x85b4 0x85c0 0x85c0 0x85c0 0x85cc 0x85cc 0x85cc 0x85d8 0x85d8 0x85d8 0x85e4 0x85e4 0x85e4 0x85f0 0x85f0 0x85f0 0x85fd 0x85fd 0x85fd 0x8609 0x8609 0x8609 0x8615 0x8615 0x8615 0x8621 0x8621 0x8621 0x862d 0x862d 0x862d 0x8639 0x8639 0x8639 0x8645 0x8645 0x8645 0x8651 0x8651 0x8651 0x865d 0x865d 0x865d 0x8669 0x8669 0x8669 0x8675 0x8675 0x8675 0x8682 0x8682 0x8682 0x868e 0x868e 0x868e 0x869a 0x869a 0x869a 0x86a6 0x86a6 0x86a6 0x86b2 0x86b2 0x86b2 0x86be 0x86be 0x86be 0x86ca 0x86ca 0x86ca 0x86d6 0x86d6 0x86d6 0x86e2 0x86e2 0x86e2 0x86ee 0x86ee 0x86ee 0x86fa 0x86fa 0x86fa 0x8707 0x8707 0x8707 0x8713 0x8713 0x8713 0x871f 0x871f 0x871f 0x872b 0x872b 0x872b 0x8737 0x8737 0x8737 0x8743 0x8743 0x8743 0x874f 0x874f 0x874f 0x875b 0x875b 0x875b 0x8767 0x8767 0x8767 0x8773 0x8773 0x8773 0x877f 0x877f 0x877f 0x878b 0x878b 0x878b 0x8798 0x8798 0x8798 0x87a4 0x87a4 0x87a4 0x87b0 0x87b0 0x87b0 0x87bc 0x87bc 0x87bc 0x87c8 0x87c8 0x87c8 0x87d4 0x87d4 0x87d4 0x87e0 0x87e0 0x87e0 0x87ec 0x87ec 0x87ec 0x87f8 0x87f8 0x87f8 0x8804 0x8804 0x8804 0x8810 0x8810 0x8810 0x881d 0x881d 0x881d 0x8829 0x8829 0x8829 0x8834 0x8834 0x8834 0x883f 0x883f 0x883f 0x884b 0x884b 0x884b 0x8856 0x8856 0x8856 0x8862 0x8862 0x8862 0x886d 0x886d 0x886d 0x8879 0x8879 0x8879 0x8884 0x8884 0x8884 0x8890 0x8890 0x8890 0x889b 0x889b 0x889b 0x88a6 0x88a6 0x88a6 0x88b2 0x88b2 0x88b2 0x88bd 0x88bd 0x88bd 0x88c9 0x88c9 0x88c9 0x88d4 0x88d4 0x88d4 0x88e0 0x88e0 0x88e0 0x88eb 0x88eb 0x88eb 0x88f6 0x88f6 0x88f6 0x8902 0x8902 0x8902 0x890d 0x890d 0x890d 0x8919 0x8919 0x8919 0x8924 0x8924 0x8924 0x8930 0x8930 0x8930 0x893b 0x893b 0x893b 0x8947 0x8947 0x8947 0x8952 0x8952 0x8952 0x895d 0x895d 0x895d 0x8969 0x8969 0x8969 0x8974 0x8974 0x8974 0x8980 0x8980 0x8980 0x898b 0x898b 0x898b 0x8997 0x8997 0x8997 0x89a2 0x89a2 0x89a2 0x89ae 0x89ae 0x89ae 0x89b9 0x89b9 0x89b9 0x89c4 0x89c4 0x89c4 0x89d0 0x89d0 0x89d0 0x89db 0x89db 0x89db 0x89e7 0x89e7 0x89e7 0x89f2 0x89f2 0x89f2 0x89fe 0x89fe 0x89fe 0x8a09 0x8a09 0x8a09 0x8a15 0x8a15 0x8a15 0x8a20 0x8a20 0x8a20 0x8a2b 0x8a2b 0x8a2b 0x8a37 0x8a37 0x8a37 0x8a42 0x8a42 0x8a42 0x8a4e 0x8a4e 0x8a4e 0x8a59 0x8a59 0x8a59 0x8a65 0x8a65 0x8a65 0x8a70 0x8a70 0x8a70 0x8a7b 0x8a7b 0x8a7b 0x8a87 0x8a87 0x8a87 0x8a92 0x8a92 0x8a92 0x8a9e 0x8a9e 0x8a9e 0x8aa9 0x8aa9 0x8aa9 0x8ab5 0x8ab5 0x8ab5 0x8ac0 0x8ac0 0x8ac0 0x8acc 0x8acc 0x8acc 0x8ad7 0x8ad7 0x8ad7 0x8ae2 0x8ae2 0x8ae2 0x8aee 0x8aee 0x8aee 0x8af9 0x8af9 0x8af9 0x8b05 0x8b05 0x8b05 0x8b10 0x8b10 0x8b10 0x8b1c 0x8b1c 0x8b1c 0x8b27 0x8b27 0x8b27 0x8b33 0x8b33 0x8b33 0x8b3e 0x8b3e 0x8b3e 0x8b49 0x8b49 0x8b49 0x8b55 0x8b55 0x8b55 0x8b60 0x8b60 0x8b60 0x8b6c 0x8b6c 0x8b6c 0x8b77 0x8b77 0x8b77 0x8b83 0x8b83 0x8b83 0x8b8e 0x8b8e 0x8b8e 0x8b99 0x8b99 0x8b99 0x8ba5 0x8ba5 0x8ba5 0x8bb0 0x8bb0 0x8bb0 0x8bbc 0x8bbc 0x8bbc 0x8bc7 0x8bc7 0x8bc7 0x8bd3 0x8bd3 0x8bd3 0x8bde 0x8bde 0x8bde 0x8bea 0x8bea 0x8bea 0x8bf5 0x8bf5 0x8bf5 0x8c00 0x8c00 0x8c00 0x8c0c 0x8c0c 0x8c0c 0x8c17 0x8c17 0x8c17 0x8c23 0x8c23 0x8c23 0x8c2e 0x8c2e 0x8c2e 0x8c38 0x8c38 0x8c38 0x8c43 0x8c43 0x8c43 0x8c4d 0x8c4d 0x8c4d 0x8c58 0x8c58 0x8c58 0x8c62 0x8c62 0x8c62 0x8c6c 0x8c6c 0x8c6c 0x8c77 0x8c77 0x8c77 0x8c81 0x8c81 0x8c81 0x8c8c 0x8c8c 0x8c8c 0x8c96 0x8c96 0x8c96 0x8ca0 0x8ca0 0x8ca0 0x8cab 0x8cab 0x8cab 0x8cb5 0x8cb5 0x8cb5 0x8cc0 0x8cc0 0x8cc0 0x8cca 0x8cca 0x8cca 0x8cd4 0x8cd4 0x8cd4 0x8cdf 0x8cdf 0x8cdf 0x8ce9 0x8ce9 0x8ce9 0x8cf4 0x8cf4 0x8cf4 0x8cfe 0x8cfe 0x8cfe 0x8d09 0x8d09 0x8d09 0x8d13 0x8d13 0x8d13 0x8d1d 0x8d1d 0x8d1d 0x8d28 0x8d28 0x8d28 0x8d32 0x8d32 0x8d32 0x8d3d 0x8d3d 0x8d3d 0x8d47 0x8d47 0x8d47 0x8d51 0x8d51 0x8d51 0x8d5c 0x8d5c 0x8d5c 0x8d66 0x8d66 0x8d66 0x8d71 0x8d71 0x8d71 0x8d7b 0x8d7b 0x8d7b 0x8d85 0x8d85 0x8d85 0x8d90 0x8d90 0x8d90 0x8d9a 0x8d9a 0x8d9a 0x8da5 0x8da5 0x8da5 0x8daf 0x8daf 0x8daf 0x8db9 0x8db9 0x8db9 0x8dc4 0x8dc4 0x8dc4 0x8dce 0x8dce 0x8dce 0x8dd9 0x8dd9 0x8dd9 0x8de3 0x8de3 0x8de3 0x8ded 0x8ded 0x8ded 0x8df8 0x8df8 0x8df8 0x8e02 0x8e02 0x8e02 0x8e0d 0x8e0d 0x8e0d 0x8e17 0x8e17 0x8e17 0x8e22 0x8e22 0x8e22 0x8e2c 0x8e2c 0x8e2c 0x8e36 0x8e36 0x8e36 0x8e41 0x8e41 0x8e41 0x8e4b 0x8e4b 0x8e4b 0x8e56 0x8e56 0x8e56 0x8e60 0x8e60 0x8e60 0x8e6a 0x8e6a 0x8e6a 0x8e75 0x8e75 0x8e75 0x8e7f 0x8e7f 0x8e7f 0x8e8a 0x8e8a 0x8e8a 0x8e94 0x8e94 0x8e94 0x8e9e 0x8e9e 0x8e9e 0x8ea9 0x8ea9 0x8ea9 0x8eb3 0x8eb3 0x8eb3 0x8ebe 0x8ebe 0x8ebe 0x8ec8 0x8ec8 0x8ec8 0x8ed2 0x8ed2 0x8ed2 0x8edd 0x8edd 0x8edd 0x8ee7 0x8ee7 0x8ee7 0x8ef2 0x8ef2 0x8ef2 0x8efc 0x8efc 0x8efc 0x8f07 0x8f07 0x8f07 0x8f11 0x8f11 0x8f11 0x8f1b 0x8f1b 0x8f1b 0x8f26 0x8f26 0x8f26 0x8f30 0x8f30 0x8f30 0x8f3b 0x8f3b 0x8f3b 0x8f45 0x8f45 0x8f45 0x8f4f 0x8f4f 0x8f4f 0x8f5a 0x8f5a 0x8f5a 0x8f64 0x8f64 0x8f64 0x8f6f 0x8f6f 0x8f6f 0x8f79 0x8f79 0x8f79 0x8f83 0x8f83 0x8f83 0x8f8e 0x8f8e 0x8f8e 0x8f98 0x8f98 0x8f98 0x8fa3 0x8fa3 0x8fa3 0x8fad 0x8fad 0x8fad 0x8fb7 0x8fb7 0x8fb7 0x8fc2 0x8fc2 0x8fc2 0x8fcc 0x8fcc 0x8fcc 0x8fd7 0x8fd7 0x8fd7 0x8fe1 0x8fe1 0x8fe1 0x8feb 0x8feb 0x8feb 0x8ff6 0x8ff6 0x8ff6 0x9000 0x9000 0x9000 0x900b 0x900b 0x900b 0x9015 0x9015 0x9015 0x9020 0x9020 0x9020 0x902a 0x902a 0x902a 0x9034 0x9034 0x9034 0x903e 0x903e 0x903e 0x9048 0x9048 0x9048 0x9052 0x9052 0x9052 0x905c 0x905c 0x905c 0x9066 0x9066 0x9066 0x9070 0x9070 0x9070 0x907a 0x907a 0x907a 0x9084 0x9084 0x9084 0x908e 0x908e 0x908e 0x9098 0x9098 0x9098 0x90a2 0x90a2 0x90a2 0x90ac 0x90ac 0x90ac 0x90b6 0x90b6 0x90b6 0x90c0 0x90c0 0x90c0 0x90ca 0x90ca 0x90ca 0x90d4 0x90d4 0x90d4 0x90de 0x90de 0x90de 0x90e8 0x90e8 0x90e8 0x90f2 0x90f2 0x90f2 0x90fc 0x90fc 0x90fc 0x9106 0x9106 0x9106 0x9110 0x9110 0x9110 0x911a 0x911a 0x911a 0x9123 0x9123 0x9123 0x912d 0x912d 0x912d 0x9137 0x9137 0x9137 0x9141 0x9141 0x9141 0x914b 0x914b 0x914b 0x9155 0x9155 0x9155 0x915f 0x915f 0x915f 0x9169 0x9169 0x9169 0x9173 0x9173 0x9173 0x917d 0x917d 0x917d 0x9187 0x9187 0x9187 0x9191 0x9191 0x9191 0x919b 0x919b 0x919b 0x91a5 0x91a5 0x91a5 0x91af 0x91af 0x91af 0x91b9 0x91b9 0x91b9 0x91c3 0x91c3 0x91c3 0x91cd 0x91cd 0x91cd 0x91d7 0x91d7 0x91d7 0x91e1 0x91e1 0x91e1 0x91eb 0x91eb 0x91eb 0x91f5 0x91f5 0x91f5 0x91ff 0x91ff 0x91ff 0x9209 0x9209 0x9209 0x9213 0x9213 0x9213 0x921d 0x921d 0x921d 0x9227 0x9227 0x9227 0x9231 0x9231 0x9231 0x923b 0x923b 0x923b 0x9245 0x9245 0x9245 0x924f 0x924f 0x924f 0x9259 0x9259 0x9259 0x9263 0x9263 0x9263 0x926d 0x926d 0x926d 0x9277 0x9277 0x9277 0x9281 0x9281 0x9281 0x928b 0x928b 0x928b 0x9295 0x9295 0x9295 0x929f 0x929f 0x929f 0x92a8 0x92a8 0x92a8 0x92b2 0x92b2 0x92b2 0x92bc 0x92bc 0x92bc 0x92c6 0x92c6 0x92c6 0x92d0 0x92d0 0x92d0 0x92da 0x92da 0x92da 0x92e4 0x92e4 0x92e4 0x92ee 0x92ee 0x92ee 0x92f8 0x92f8 0x92f8 0x9302 0x9302 0x9302 0x930c 0x930c 0x930c 0x9316 0x9316 0x9316 0x9320 0x9320 0x9320 0x932a 0x932a 0x932a 0x9334 0x9334 0x9334 0x933e 0x933e 0x933e 0x9348 0x9348 0x9348 0x9352 0x9352 0x9352 0x935c 0x935c 0x935c 0x9366 0x9366 0x9366 0x9370 0x9370 0x9370 0x937a 0x937a 0x937a 0x9384 0x9384 0x9384 0x938e 0x938e 0x938e 0x9398 0x9398 0x9398 0x93a2 0x93a2 0x93a2 0x93ac 0x93ac 0x93ac 0x93b6 0x93b6 0x93b6 0x93c0 0x93c0 0x93c0 0x93ca 0x93ca 0x93ca 0x93d4 0x93d4 0x93d4 0x93de 0x93de 0x93de 0x93e8 0x93e8 0x93e8 0x93f2 0x93f2 0x93f2 0x93fc 0x93fc 0x93fc 0x9406 0x9406 0x9406 0x9410 0x9410 0x9410 0x941a 0x941a 0x941a 0x9423 0x9423 0x9423 0x942d 0x942d 0x942d 0x9437 0x9437 0x9437 0x9440 0x9440 0x9440 0x9449 0x9449 0x9449 0x9451 0x9451 0x9451 0x945a 0x945a 0x945a 0x9463 0x9463 0x9463 0x946c 0x946c 0x946c 0x9475 0x9475 0x9475 0x947e 0x947e 0x947e 0x9486 0x9486 0x9486 0x948f 0x948f 0x948f 0x9498 0x9498 0x9498 0x94a1 0x94a1 0x94a1 0x94aa 0x94aa 0x94aa 0x94b3 0x94b3 0x94b3 0x94bb 0x94bb 0x94bb 0x94c4 0x94c4 0x94c4 0x94cd 0x94cd 0x94cd 0x94d6 0x94d6 0x94d6 0x94df 0x94df 0x94df 0x94e8 0x94e8 0x94e8 0x94f0 0x94f0 0x94f0 0x94f9 0x94f9 0x94f9 0x9502 0x9502 0x9502 0x950b 0x950b 0x950b 0x9514 0x9514 0x9514 0x951d 0x951d 0x951d 0x9525 0x9525 0x9525 0x952e 0x952e 0x952e 0x9537 0x9537 0x9537 0x9540 0x9540 0x9540 0x9549 0x9549 0x9549 0x9552 0x9552 0x9552 0x955a 0x955a 0x955a 0x9563 0x9563 0x9563 0x956c 0x956c 0x956c 0x9575 0x9575 0x9575 0x957e 0x957e 0x957e 0x9587 0x9587 0x9587 0x958f 0x958f 0x958f 0x9598 0x9598 0x9598 0x95a1 0x95a1 0x95a1 0x95aa 0x95aa 0x95aa 0x95b3 0x95b3 0x95b3 0x95bc 0x95bc 0x95bc 0x95c4 0x95c4 0x95c4 0x95cd 0x95cd 0x95cd 0x95d6 0x95d6 0x95d6 0x95df 0x95df 0x95df 0x95e8 0x95e8 0x95e8 0x95f1 0x95f1 0x95f1 0x95f9 0x95f9 0x95f9 0x9602 0x9602 0x9602 0x960b 0x960b 0x960b 0x9614 0x9614 0x9614 0x961d 0x961d 0x961d 0x9626 0x9626 0x9626 0x962e 0x962e 0x962e 0x9637 0x9637 0x9637 0x9640 0x9640 0x9640 0x9649 0x9649 0x9649 0x9652 0x9652 0x9652 0x965b 0x965b 0x965b 0x9663 0x9663 0x9663 0x966c 0x966c 0x966c 0x9675 0x9675 0x9675 0x967e 0x967e 0x967e 0x9687 0x9687 0x9687 0x9690 0x9690 0x9690 0x9698 0x9698 0x9698 0x96a1 0x96a1 0x96a1 0x96aa 0x96aa 0x96aa 0x96b3 0x96b3 0x96b3 0x96bc 0x96bc 0x96bc 0x96c5 0x96c5 0x96c5 0x96cd 0x96cd 0x96cd 0x96d6 0x96d6 0x96d6 0x96df 0x96df 0x96df 0x96e8 0x96e8 0x96e8 0x96f1 0x96f1 0x96f1 0x96f9 0x96f9 0x96f9 0x9702 0x9702 0x9702 0x970b 0x970b 0x970b 0x9714 0x9714 0x9714 0x971d 0x971d 0x971d 0x9726 0x9726 0x9726 0x972e 0x972e 0x972e 0x9737 0x9737 0x9737 0x9740 0x9740 0x9740 0x9749 0x9749 0x9749 0x9752 0x9752 0x9752 0x975b 0x975b 0x975b 0x9763 0x9763 0x9763 0x976c 0x976c 0x976c 0x9775 0x9775 0x9775 0x977e 0x977e 0x977e 0x9787 0x9787 0x9787 0x9790 0x9790 0x9790 0x9798 0x9798 0x9798 0x97a1 0x97a1 0x97a1 0x97aa 0x97aa 0x97aa 0x97b3 0x97b3 0x97b3 0x97bc 0x97bc 0x97bc 0x97c5 0x97c5 0x97c5 0x97cd 0x97cd 0x97cd 0x97d6 0x97d6 0x97d6 0x97df 0x97df 0x97df 0x97e8 0x97e8 0x97e8 0x97f1 0x97f1 0x97f1 0x97fa 0x97fa 0x97fa 0x9802 0x9802 0x9802 0x980b 0x980b 0x980b 0x9814 0x9814 0x9814 0x981d 0x981d 0x981d 0x9826 0x9826 0x9826 0x982f 0x982f 0x982f 0x9837 0x9837 0x9837 0x983f 0x983f 0x983f 0x9847 0x9847 0x9847 0x984f 0x984f 0x984f 0x9857 0x9857 0x9857 0x985f 0x985f 0x985f 0x9867 0x9867 0x9867 0x986e 0x986e 0x986e 0x9876 0x9876 0x9876 0x987e 0x987e 0x987e 0x9886 0x9886 0x9886 0x988e 0x988e 0x988e 0x9896 0x9896 0x9896 0x989e 0x989e 0x989e 0x98a5 0x98a5 0x98a5 0x98ad 0x98ad 0x98ad 0x98b5 0x98b5 0x98b5 0x98bd 0x98bd 0x98bd 0x98c5 0x98c5 0x98c5 0x98cd 0x98cd 0x98cd 0x98d5 0x98d5 0x98d5 0x98dc 0x98dc 0x98dc 0x98e4 0x98e4 0x98e4 0x98ec 0x98ec 0x98ec 0x98f4 0x98f4 0x98f4 0x98fc 0x98fc 0x98fc 0x9904 0x9904 0x9904 0x990c 0x990c 0x990c 0x9913 0x9913 0x9913 0x991b 0x991b 0x991b 0x9923 0x9923 0x9923 0x992b 0x992b 0x992b 0x9933 0x9933 0x9933 0x993b 0x993b 0x993b 0x9943 0x9943 0x9943 0x994a 0x994a 0x994a 0x9952 0x9952 0x9952 0x995a 0x995a 0x995a 0x9962 0x9962 0x9962 0x996a 0x996a 0x996a 0x9972 0x9972 0x9972 0x997a 0x997a 0x997a 0x9981 0x9981 0x9981 0x9989 0x9989 0x9989 0x9991 0x9991 0x9991 0x9999 0x9999 0x9999 0x99a1 0x99a1 0x99a1 0x99a9 0x99a9 0x99a9 0x99b1 0x99b1 0x99b1 0x99b8 0x99b8 0x99b8 0x99c0 0x99c0 0x99c0 0x99c8 0x99c8 0x99c8 0x99d0 0x99d0 0x99d0 0x99d8 0x99d8 0x99d8 0x99e0 0x99e0 0x99e0 0x99e8 0x99e8 0x99e8 0x99ef 0x99ef 0x99ef 0x99f7 0x99f7 0x99f7 0x99ff 0x99ff 0x99ff 0x9a07 0x9a07 0x9a07 0x9a0f 0x9a0f 0x9a0f 0x9a17 0x9a17 0x9a17 0x9a1f 0x9a1f 0x9a1f 0x9a26 0x9a26 0x9a26 0x9a2e 0x9a2e 0x9a2e 0x9a36 0x9a36 0x9a36 0x9a3e 0x9a3e 0x9a3e 0x9a46 0x9a46 0x9a46 0x9a4e 0x9a4e 0x9a4e 0x9a56 0x9a56 0x9a56 0x9a5d 0x9a5d 0x9a5d 0x9a65 0x9a65 0x9a65 0x9a6d 0x9a6d 0x9a6d 0x9a75 0x9a75 0x9a75 0x9a7d 0x9a7d 0x9a7d 0x9a85 0x9a85 0x9a85 0x9a8d 0x9a8d 0x9a8d 0x9a94 0x9a94 0x9a94 0x9a9c 0x9a9c 0x9a9c 0x9aa4 0x9aa4 0x9aa4 0x9aac 0x9aac 0x9aac 0x9ab4 0x9ab4 0x9ab4 0x9abc 0x9abc 0x9abc 0x9ac4 0x9ac4 0x9ac4 0x9acb 0x9acb 0x9acb 0x9ad3 0x9ad3 0x9ad3 0x9adb 0x9adb 0x9adb 0x9ae3 0x9ae3 0x9ae3 0x9aeb 0x9aeb 0x9aeb 0x9af3 0x9af3 0x9af3 0x9afb 0x9afb 0x9afb 0x9b02 0x9b02 0x9b02 0x9b0a 0x9b0a 0x9b0a 0x9b12 0x9b12 0x9b12 0x9b1a 0x9b1a 0x9b1a 0x9b22 0x9b22 0x9b22 0x9b2a 0x9b2a 0x9b2a 0x9b32 0x9b32 0x9b32 0x9b39 0x9b39 0x9b39 0x9b41 0x9b41 0x9b41 0x9b49 0x9b49 0x9b49 0x9b51 0x9b51 0x9b51 0x9b59 0x9b59 0x9b59 0x9b61 0x9b61 0x9b61 0x9b69 0x9b69 0x9b69 0x9b70 0x9b70 0x9b70 0x9b78 0x9b78 0x9b78 0x9b80 0x9b80 0x9b80 0x9b88 0x9b88 0x9b88 0x9b90 0x9b90 0x9b90 0x9b98 0x9b98 0x9b98 0x9ba0 0x9ba0 0x9ba0 0x9ba7 0x9ba7 0x9ba7 0x9baf 0x9baf 0x9baf 0x9bb7 0x9bb7 0x9bb7 0x9bbf 0x9bbf 0x9bbf 0x9bc7 0x9bc7 0x9bc7 0x9bcf 0x9bcf 0x9bcf 0x9bd7 0x9bd7 0x9bd7 0x9bde 0x9bde 0x9bde 0x9be6 0x9be6 0x9be6 0x9bee 0x9bee 0x9bee 0x9bf6 0x9bf6 0x9bf6 0x9bfe 0x9bfe 0x9bfe 0x9c06 0x9c06 0x9c06 0x9c0e 0x9c0e 0x9c0e 0x9c15 0x9c15 0x9c15 0x9c1d 0x9c1d 0x9c1d 0x9c25 0x9c25 0x9c25 0x9c2d 0x9c2d 0x9c2d 0x9c35 0x9c35 0x9c35 0x9c3d 0x9c3d 0x9c3d 0x9c44 0x9c44 0x9c44 0x9c4b 0x9c4b 0x9c4b 0x9c53 0x9c53 0x9c53 0x9c5a 0x9c5a 0x9c5a 0x9c61 0x9c61 0x9c61 0x9c69 0x9c69 0x9c69 0x9c70 0x9c70 0x9c70 0x9c77 0x9c77 0x9c77 0x9c7f 0x9c7f 0x9c7f 0x9c86 0x9c86 0x9c86 0x9c8d 0x9c8d 0x9c8d 0x9c95 0x9c95 0x9c95 0x9c9c 0x9c9c 0x9c9c 0x9ca3 0x9ca3 0x9ca3 0x9cab 0x9cab 0x9cab 0x9cb2 0x9cb2 0x9cb2 0x9cb9 0x9cb9 0x9cb9 0x9cc1 0x9cc1 0x9cc1 0x9cc8 0x9cc8 0x9cc8 0x9ccf 0x9ccf 0x9ccf 0x9cd7 0x9cd7 0x9cd7 0x9cde 0x9cde 0x9cde 0x9ce5 0x9ce5 0x9ce5 0x9ced 0x9ced 0x9ced 0x9cf4 0x9cf4 0x9cf4 0x9cfb 0x9cfb 0x9cfb 0x9d03 0x9d03 0x9d03 0x9d0a 0x9d0a 0x9d0a 0x9d12 0x9d12 0x9d12 0x9d19 0x9d19 0x9d19 0x9d20 0x9d20 0x9d20 0x9d28 0x9d28 0x9d28 0x9d2f 0x9d2f 0x9d2f 0x9d36 0x9d36 0x9d36 0x9d3e 0x9d3e 0x9d3e 0x9d45 0x9d45 0x9d45 0x9d4c 0x9d4c 0x9d4c 0x9d54 0x9d54 0x9d54 0x9d5b 0x9d5b 0x9d5b 0x9d62 0x9d62 0x9d62 0x9d6a 0x9d6a 0x9d6a 0x9d71 0x9d71 0x9d71 0x9d78 0x9d78 0x9d78 0x9d80 0x9d80 0x9d80 0x9d87 0x9d87 0x9d87 0x9d8e 0x9d8e 0x9d8e 0x9d96 0x9d96 0x9d96 0x9d9d 0x9d9d 0x9d9d 0x9da4 0x9da4 0x9da4 0x9dac 0x9dac 0x9dac 0x9db3 0x9db3 0x9db3 0x9dba 0x9dba 0x9dba 0x9dc2 0x9dc2 0x9dc2 0x9dc9 0x9dc9 0x9dc9 0x9dd0 0x9dd0 0x9dd0 0x9dd8 0x9dd8 0x9dd8 0x9ddf 0x9ddf 0x9ddf 0x9de6 0x9de6 0x9de6 0x9dee 0x9dee 0x9dee 0x9df5 0x9df5 0x9df5 0x9dfc 0x9dfc 0x9dfc 0x9e04 0x9e04 0x9e04 0x9e0b 0x9e0b 0x9e0b 0x9e13 0x9e13 0x9e13 0x9e1a 0x9e1a 0x9e1a 0x9e21 0x9e21 0x9e21 0x9e29 0x9e29 0x9e29 0x9e30 0x9e30 0x9e30 0x9e37 0x9e37 0x9e37 0x9e3f 0x9e3f 0x9e3f 0x9e46 0x9e46 0x9e46 0x9e4d 0x9e4d 0x9e4d 0x9e55 0x9e55 0x9e55 0x9e5c 0x9e5c 0x9e5c 0x9e63 0x9e63 0x9e63 0x9e6b 0x9e6b 0x9e6b 0x9e72 0x9e72 0x9e72 0x9e79 0x9e79 0x9e79 0x9e81 0x9e81 0x9e81 0x9e88 0x9e88 0x9e88 0x9e8f 0x9e8f 0x9e8f 0x9e97 0x9e97 0x9e97 0x9e9e 0x9e9e 0x9e9e 0x9ea5 0x9ea5 0x9ea5 0x9ead 0x9ead 0x9ead 0x9eb4 0x9eb4 0x9eb4 0x9ebb 0x9ebb 0x9ebb 0x9ec3 0x9ec3 0x9ec3 0x9eca 0x9eca 0x9eca 0x9ed1 0x9ed1 0x9ed1 0x9ed9 0x9ed9 0x9ed9 0x9ee0 0x9ee0 0x9ee0 0x9ee7 0x9ee7 0x9ee7 0x9eef 0x9eef 0x9eef 0x9ef6 0x9ef6 0x9ef6 0x9efd 0x9efd 0x9efd 0x9f05 0x9f05 0x9f05 0x9f0c 0x9f0c 0x9f0c 0x9f14 0x9f14 0x9f14 0x9f1b 0x9f1b 0x9f1b 0x9f22 0x9f22 0x9f22 0x9f2a 0x9f2a 0x9f2a 0x9f31 0x9f31 0x9f31 0x9f38 0x9f38 0x9f38 0x9f40 0x9f40 0x9f40 0x9f47 0x9f47 0x9f47 0x9f4e 0x9f4e 0x9f4e 0x9f56 0x9f56 0x9f56 0x9f5d 0x9f5d 0x9f5d 0x9f64 0x9f64 0x9f64 0x9f6c 0x9f6c 0x9f6c 0x9f73 0x9f73 0x9f73 0x9f7a 0x9f7a 0x9f7a 0x9f82 0x9f82 0x9f82 0x9f89 0x9f89 0x9f89 0x9f90 0x9f90 0x9f90 0x9f98 0x9f98 0x9f98 0x9f9f 0x9f9f 0x9f9f 0x9fa6 0x9fa6 0x9fa6 0x9fae 0x9fae 0x9fae 0x9fb5 0x9fb5 0x9fb5 0x9fbc 0x9fbc 0x9fbc 0x9fc4 0x9fc4 0x9fc4 0x9fcb 0x9fcb 0x9fcb 0x9fd2 0x9fd2 0x9fd2 0x9fda 0x9fda 0x9fda 0x9fe1 0x9fe1 0x9fe1 0x9fe8 0x9fe8 0x9fe8 0x9ff0 0x9ff0 0x9ff0 0x9ff7 0x9ff7 0x9ff7 0x9fff 0x9fff 0x9fff>; + nvidia,panel-csc = <0xd581 0x2979 0xc5 0x0 0x831 0xcac1 0x20c 0x0 0x189 0x625 0xcc4a 0x0>; + }; + }; + + panel-s-wqxga-10-1 { + nvidia,dsi-ganged-type = <0x1>; + compatible = "s,wqxga-10-1"; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-refresh-rate = <0x3d>; + nvidia,dsi-lp00-pre-panel-wakeup = <0x1>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-video-clock-mode = <0x1>; + nvidia,panel-rst-gpio = <0x1b 0x7b 0x1>; + nvidia,dsi-n-init-cmd = <0x10>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-init-cmd = <0x0 0x29 0x3 0x0 0x0 0x10 0x0 0x2a 0x0 0x0 0x1 0x14 0x0 0x5 0x0 0x0 0x0 0x1 0x14 0x0 0x29 0x3 0x0 0x0 0x10 0x1 0x1 0x0 0x0 0x1 0x14 0x0 0x5 0x0 0x0 0x0 0x1 0x14 0x0 0x5 0x35 0x0 0x0 0x1 0x14 0x0 0x5 0x11 0x0 0x0 0x1 0x78 0x0 0x5 0x29 0x0 0x0 0x1 0x14 0x3 0x1 0x1 0x78>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-video-data-type = <0x1>; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + nvidia,dsi-rated-refresh-rate = <0x3c>; + phandle = <0x11e>; + nvidia,dsi-suspend-cmd = <0x0 0x5 0x28 0x0 0x0 0x1 0x32 0x0 0x5 0x10 0x0 0x0 0x1 0xc8 0x0 0x5 0x34 0x0 0x0 0x1 0x14>; + nvidia,dsi-n-suspend-cmd = <0x6>; + nvidia,dsi-instance = <0x0>; + nvidia,dsi-panel-reset = <0x1>; + nvidia,dsi-te-polarity-low = <0x1>; + linux,phandle = <0x11e>; + nvidia,dsi-suspend-aggr = <0x3>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,panel-bl-pwm-gpio = <0x28 0x8 0x1>; + + cmu { + nvidia,cmu-csc = <0x105 0x3d5 0x24 0x3ea 0x121 0x3c1 0x2 0xa 0xf4>; + nvidia,cmu-lut2 = <0x0 0x1 0x2 0x2 0x3 0x4 0x5 0x6 0x6 0x7 0x8 0x9 0xa 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0xf 0x10 0x10 0x11 0x12 0x12 0x13 0x13 0x14 0x14 0x15 0x15 0x16 0x16 0x17 0x17 0x17 0x18 0x18 0x19 0x19 0x19 0x1a 0x1a 0x1b 0x1b 0x1b 0x1c 0x1c 0x1d 0x1d 0x1d 0x1e 0x1e 0x1e 0x1f 0x1f 0x1f 0x20 0x20 0x20 0x21 0x21 0x21 0x22 0x22 0x22 0x22 0x23 0x23 0x23 0x24 0x24 0x24 0x25 0x25 0x25 0x25 0x26 0x26 0x26 0x26 0x27 0x27 0x27 0x28 0x28 0x28 0x28 0x29 0x29 0x29 0x29 0x2a 0x2a 0x2a 0x2a 0x2b 0x2b 0x2b 0x2b 0x2b 0x2c 0x2c 0x2c 0x2c 0x2d 0x2d 0x2d 0x2d 0x2e 0x2e 0x2e 0x2e 0x2e 0x2f 0x2f 0x2f 0x2f 0x30 0x30 0x30 0x30 0x30 0x31 0x31 0x31 0x31 0x31 0x32 0x32 0x32 0x32 0x32 0x33 0x33 0x33 0x33 0x33 0x34 0x34 0x34 0x34 0x34 0x35 0x35 0x35 0x35 0x35 0x36 0x36 0x36 0x36 0x36 0x37 0x37 0x37 0x37 0x37 0x37 0x38 0x38 0x38 0x38 0x38 0x39 0x39 0x39 0x39 0x39 0x39 0x3a 0x3a 0x3a 0x3a 0x3a 0x3a 0x3b 0x3b 0x3b 0x3b 0x3b 0x3b 0x3c 0x3c 0x3c 0x3c 0x3c 0x3c 0x3d 0x3d 0x3d 0x3d 0x3d 0x3d 0x3e 0x3e 0x3e 0x3e 0x3e 0x3e 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x40 0x40 0x40 0x40 0x40 0x40 0x40 0x41 0x41 0x41 0x41 0x41 0x41 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x44 0x44 0x44 0x44 0x44 0x44 0x44 0x45 0x45 0x45 0x45 0x45 0x45 0x45 0x46 0x46 0x46 0x46 0x46 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x48 0x49 0x49 0x49 0x49 0x49 0x49 0x49 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4a 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4b 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4c 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4d 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4e 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x50 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x52 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x53 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x54 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x56 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x58 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x59 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5b 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5c 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5d 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5e 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x5f 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x60 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x62 0x63 0x63 0x63 0x63 0x63 0x63 0x63 0x64 0x65 0x65 0x66 0x67 0x67 0x68 0x69 0x69 0x6a 0x6b 0x6b 0x6c 0x6d 0x6d 0x6e 0x6f 0x6f 0x70 0x71 0x71 0x72 0x73 0x73 0x74 0x74 0x75 0x76 0x76 0x77 0x77 0x78 0x78 0x79 0x7a 0x7a 0x7b 0x7b 0x7c 0x7c 0x7d 0x7e 0x7e 0x7f 0x7f 0x80 0x80 0x81 0x81 0x82 0x82 0x83 0x83 0x84 0x84 0x85 0x85 0x86 0x86 0x87 0x87 0x88 0x88 0x89 0x89 0x8a 0x8a 0x8b 0x8b 0x8c 0x8c 0x8d 0x8d 0x8e 0x8e 0x8f 0x8f 0x90 0x90 0x91 0x91 0x91 0x92 0x92 0x93 0x93 0x94 0x94 0x95 0x95 0x96 0x96 0x96 0x97 0x97 0x98 0x98 0x99 0x99 0x99 0x9a 0x9a 0x9b 0x9b 0x9c 0x9c 0x9c 0x9d 0x9d 0x9e 0x9e 0x9e 0x9f 0x9f 0xa0 0xa0 0xa0 0xa1 0xa1 0xa2 0xa2 0xa2 0xa3 0xa3 0xa4 0xa4 0xa4 0xa5 0xa5 0xa6 0xa6 0xa6 0xa7 0xa7 0xa7 0xa8 0xa8 0xa9 0xa9 0xa9 0xaa 0xaa 0xaa 0xab 0xab 0xac 0xac 0xac 0xad 0xad 0xad 0xae 0xae 0xae 0xaf 0xaf 0xb0 0xb0 0xb0 0xb1 0xb1 0xb1 0xb2 0xb2 0xb2 0xb3 0xb3 0xb3 0xb4 0xb4 0xb4 0xb5 0xb5 0xb6 0xb6 0xb6 0xb7 0xb7 0xb7 0xb8 0xb8 0xb8 0xb9 0xb9 0xb9 0xba 0xba 0xba 0xbb 0xbb 0xbb 0xbc 0xbc 0xbc 0xbd 0xbd 0xbd 0xbd 0xbe 0xbe 0xbe 0xbf 0xbf 0xbf 0xc0 0xc0 0xc0 0xc1 0xc1 0xc1 0xc2 0xc2 0xc2 0xc3 0xc3 0xc3 0xc4 0xc4 0xc4 0xc4 0xc5 0xc5 0xc5 0xc6 0xc6 0xc6 0xc7 0xc7 0xc7 0xc8 0xc8 0xc8 0xc8 0xc9 0xc9 0xc9 0xca 0xca 0xca 0xca 0xcb 0xcb 0xcb 0xcc 0xcc 0xcc 0xcd 0xcd 0xcd 0xcd 0xce 0xce 0xce 0xcf 0xcf 0xcf 0xcf 0xd0 0xd0 0xd0 0xd1 0xd1 0xd1 0xd1 0xd2 0xd2 0xd2 0xd3 0xd3 0xd3 0xd3 0xd4 0xd4 0xd4 0xd5 0xd5 0xd5 0xd5 0xd6 0xd6 0xd6 0xd6 0xd7 0xd7 0xd7 0xd8 0xd8 0xd8 0xd8 0xd9 0xd9 0xd9 0xd9 0xda 0xda 0xda 0xdb 0xdb 0xdb 0xdb 0xdc 0xdc 0xdc 0xdc 0xdd 0xdd 0xdd 0xdd 0xde 0xde 0xde 0xdf 0xdf 0xdf 0xdf 0xe0 0xe0 0xe0 0xe0 0xe1 0xe1 0xe1 0xe1 0xe2 0xe2 0xe2 0xe2 0xe3 0xe3 0xe3 0xe3 0xe4 0xe4 0xe4 0xe4 0xe5 0xe5 0xe5 0xe5 0xe6 0xe6 0xe6 0xe6 0xe7 0xe7 0xe7 0xe7 0xe8 0xe8 0xe8 0xe8 0xe9 0xe9 0xe9 0xe9 0xea 0xea 0xea 0xea 0xeb 0xeb 0xeb 0xeb 0xec 0xec 0xec 0xec 0xed 0xed 0xed 0xed 0xee 0xee 0xee 0xee 0xef 0xef 0xef 0xef 0xf0 0xf0 0xf0 0xf0 0xf0 0xf1 0xf1 0xf1 0xf1 0xf2 0xf2 0xf2 0xf2 0xf3 0xf3 0xf3 0xf3 0xf4 0xf4 0xf4 0xf4 0xf4 0xf5 0xf5 0xf5 0xf5 0xf6 0xf6 0xf6 0xf6 0xf7 0xf7 0xf7 0xf7 0xf7 0xf8 0xf8 0xf8 0xf8 0xf9 0xf9 0xf9 0xf9 0xf9 0xfa 0xfa 0xfa 0xfa 0xfb 0xfb 0xfb 0xfb 0xfb 0xfc 0xfc 0xfc 0xfc 0xfd 0xfd 0xfd 0xfd 0xfd 0xfe 0xfe 0xfe 0xfe 0xff 0xff>; + }; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,turn-on-brightness = <0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "disabled"; + nvidia,smooth-k-incr = <0x4>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,turn-off-brightness = <0x0>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,sw-update-delay = <0x0>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x1>; + }; + + disp-default-out { + nvidia,out-xres = <0xa00>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-flags = <0x20>; + nvidia,out-type = <0x2>; + nvidia,out-yres = <0x640>; + nvidia,out-height = <0x87>; + nvidia,out-width = <0xd8>; + nvidia,out-rotation = <0xb4>; + }; + + display-timings { + + 2560x1600-32 { + hsync-len = <0x20>; + nvidia,h-ref-to-sync = <0x0>; + hfront-porch = <0x148>; + vfront-porch = <0x2>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x1>; + vactive = <0x640>; + hback-porch = <0x50>; + clock-frequency = <0x118a1cc0>; + hactive = <0xa00>; + vback-porch = <0x5>; + }; + }; + }; + + panel-null-dsi-hotplug { + nvidia,dsi-ganged-type = <0x1>; + compatible = "null,dsi-hotplug"; + nvidia,dsi-virtual-channel = <0x0>; + nvidia,dsi-ganged-swap-links = <0x1>; + nvidia,dsi-video-burst-mode = <0x0>; + nvidia,dsi-power-saving-suspend = <0x1>; + nvidia,dsi-ganged-write-to-all-links = <0x1>; + nvidia,dsi-video-clock-mode = <0x0>; + nvidia,dsi-suspend-stop-stream-late = <0x1>; + nvidia,dsi-pixel-format = <0x3>; + nvidia,dsi-ulpm-not-support = <0x1>; + nvidia,dsi-video-data-type = <0x0>; + nvidia,dsi-controller-vs = <0x1>; + status = "disabled"; + nvidia,edid = <0xffffff 0xffffff00 0x10ac68a0 0x55344b31 0x1c160103 0x80351e78 0xea9265a6 0x55559f28 0xd5054a5 0x4b00714f 0x8180d1c0 0x1010101 0x1010101 0x101023a 0x80187138 0x2d40582c 0x4500132b 0x2100001e 0xff 0x573856 0x59393237 0x41314b34 0x550a0000 0xfc0044 0x454c4c20 0x53543234 0x32304c0a 0xfd 0x384c1e 0x5311000a 0x20202020 0x20200198>; + nvidia,dsi-pkt-seq = <0x1 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff 0x21 0x0 0x40000000 0xff 0x21 0x0 0x3e 0x3 0x19 0x4 0xff>; + nvidia,dsi-instance = <0x0>; + nvidia,default_color_space = <0x0>; + nvidia,dsi-n-data-lanes = <0x8>; + nvidia,dsi-hdmi-bridge = <0x1>; + + smartdimmer { + status = "disabled"; + }; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-parent-clk = "pll_d"; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x2>; + nvidia,out-yres = <0x870>; + }; + + nvdisp-cmu { + nvidia,cmu-lut = <0x6000 0x6000 0x6000 0x6191 0x6191 0x6191 0x6322 0x6322 0x6322 0x643b 0x643b 0x643b 0x64ba 0x64ba 0x64ba 0x6539 0x6539 0x6539 0x65b8 0x65b8 0x65b8 0x6637 0x6637 0x6637 0x66b6 0x66b6 0x66b6 0x6735 0x6735 0x6735 0x67b4 0x67b4 0x67b4 0x6826 0x6826 0x6826 0x687d 0x687d 0x687d 0x68d4 0x68d4 0x68d4 0x692b 0x692b 0x692b 0x6983 0x6983 0x6983 0x69da 0x69da 0x69da 0x6a31 0x6a31 0x6a31 0x6a88 0x6a88 0x6a88 0x6ae0 0x6ae0 0x6ae0 0x6b37 0x6b37 0x6b37 0x6b8e 0x6b8e 0x6b8e 0x6be5 0x6be5 0x6be5 0x6c28 0x6c28 0x6c28 0x6c5b 0x6c5b 0x6c5b 0x6c8e 0x6c8e 0x6c8e 0x6cc1 0x6cc1 0x6cc1 0x6cf4 0x6cf4 0x6cf4 0x6d27 0x6d27 0x6d27 0x6d5a 0x6d5a 0x6d5a 0x6d8d 0x6d8d 0x6d8d 0x6dbf 0x6dbf 0x6dbf 0x6df2 0x6df2 0x6df2 0x6e25 0x6e25 0x6e25 0x6e58 0x6e58 0x6e58 0x6e8b 0x6e8b 0x6e8b 0x6ebe 0x6ebe 0x6ebe 0x6ef1 0x6ef1 0x6ef1 0x6f24 0x6f24 0x6f24 0x6f57 0x6f57 0x6f57 0x6f8a 0x6f8a 0x6f8a 0x6fbd 0x6fbd 0x6fbd 0x6ff0 0x6ff0 0x6ff0 0x701a 0x701a 0x701a 0x7037 0x7037 0x7037 0x7053 0x7053 0x7053 0x706f 0x706f 0x706f 0x708c 0x708c 0x708c 0x70a8 0x70a8 0x70a8 0x70c5 0x70c5 0x70c5 0x70e1 0x70e1 0x70e1 0x70fe 0x70fe 0x70fe 0x711a 0x711a 0x711a 0x7136 0x7136 0x7136 0x7153 0x7153 0x7153 0x716f 0x716f 0x716f 0x718c 0x718c 0x718c 0x71a8 0x71a8 0x71a8 0x71c4 0x71c4 0x71c4 0x71e1 0x71e1 0x71e1 0x71fd 0x71fd 0x71fd 0x721a 0x721a 0x721a 0x7236 0x7236 0x7236 0x7253 0x7253 0x7253 0x726f 0x726f 0x726f 0x728b 0x728b 0x728b 0x72a8 0x72a8 0x72a8 0x72c4 0x72c4 0x72c4 0x72e1 0x72e1 0x72e1 0x72fd 0x72fd 0x72fd 0x731a 0x731a 0x731a 0x7336 0x7336 0x7336 0x7352 0x7352 0x7352 0x736f 0x736f 0x736f 0x738b 0x738b 0x738b 0x73a8 0x73a8 0x73a8 0x73c4 0x73c4 0x73c4 0x73e1 0x73e1 0x73e1 0x73fd 0x73fd 0x73fd 0x741b 0x741b 0x741b 0x743f 0x743f 0x743f 0x7463 0x7463 0x7463 0x7486 0x7486 0x7486 0x74aa 0x74aa 0x74aa 0x74ce 0x74ce 0x74ce 0x74f2 0x74f2 0x74f2 0x7516 0x7516 0x7516 0x753a 0x753a 0x753a 0x755d 0x755d 0x755d 0x7581 0x7581 0x7581 0x75a5 0x75a5 0x75a5 0x75c9 0x75c9 0x75c9 0x75ed 0x75ed 0x75ed 0x7611 0x7611 0x7611 0x7634 0x7634 0x7634 0x7658 0x7658 0x7658 0x767c 0x767c 0x767c 0x76a0 0x76a0 0x76a0 0x76c4 0x76c4 0x76c4 0x76e8 0x76e8 0x76e8 0x770b 0x770b 0x770b 0x772f 0x772f 0x772f 0x7753 0x7753 0x7753 0x7777 0x7777 0x7777 0x779b 0x779b 0x779b 0x77bf 0x77bf 0x77bf 0x77e2 0x77e2 0x77e2 0x7806 0x7806 0x7806 0x7825 0x7825 0x7825 0x7840 0x7840 0x7840 0x785b 0x785b 0x785b 0x7876 0x7876 0x7876 0x7891 0x7891 0x7891 0x78ac 0x78ac 0x78ac 0x78c7 0x78c7 0x78c7 0x78e2 0x78e2 0x78e2 0x78fd 0x78fd 0x78fd 0x7918 0x7918 0x7918 0x7933 0x7933 0x7933 0x794e 0x794e 0x794e 0x7969 0x7969 0x7969 0x7984 0x7984 0x7984 0x799f 0x799f 0x799f 0x79ba 0x79ba 0x79ba 0x79d5 0x79d5 0x79d5 0x79f0 0x79f0 0x79f0 0x7a0b 0x7a0b 0x7a0b 0x7a26 0x7a26 0x7a26 0x7a41 0x7a41 0x7a41 0x7a5c 0x7a5c 0x7a5c 0x7a77 0x7a77 0x7a77 0x7a92 0x7a92 0x7a92 0x7aad 0x7aad 0x7aad 0x7ac8 0x7ac8 0x7ac8 0x7ae3 0x7ae3 0x7ae3 0x7afe 0x7afe 0x7afe 0x7b19 0x7b19 0x7b19 0x7b34 0x7b34 0x7b34 0x7b4f 0x7b4f 0x7b4f 0x7b6a 0x7b6a 0x7b6a 0x7b85 0x7b85 0x7b85 0x7ba0 0x7ba0 0x7ba0 0x7bbb 0x7bbb 0x7bbb 0x7bd5 0x7bd5 0x7bd5 0x7bf0 0x7bf0 0x7bf0 0x7c0b 0x7c0b 0x7c0b 0x7c23 0x7c23 0x7c23 0x7c35 0x7c35 0x7c35 0x7c47 0x7c47 0x7c47 0x7c59 0x7c59 0x7c59 0x7c6b 0x7c6b 0x7c6b 0x7c7d 0x7c7d 0x7c7d 0x7c90 0x7c90 0x7c90 0x7ca2 0x7ca2 0x7ca2 0x7cb4 0x7cb4 0x7cb4 0x7cc6 0x7cc6 0x7cc6 0x7cd8 0x7cd8 0x7cd8 0x7cea 0x7cea 0x7cea 0x7cfc 0x7cfc 0x7cfc 0x7d0f 0x7d0f 0x7d0f 0x7d21 0x7d21 0x7d21 0x7d33 0x7d33 0x7d33 0x7d45 0x7d45 0x7d45 0x7d57 0x7d57 0x7d57 0x7d69 0x7d69 0x7d69 0x7d7b 0x7d7b 0x7d7b 0x7d8e 0x7d8e 0x7d8e 0x7da0 0x7da0 0x7da0 0x7db2 0x7db2 0x7db2 0x7dc4 0x7dc4 0x7dc4 0x7dd6 0x7dd6 0x7dd6 0x7de8 0x7de8 0x7de8 0x7dfa 0x7dfa 0x7dfa 0x7e0d 0x7e0d 0x7e0d 0x7e1f 0x7e1f 0x7e1f 0x7e31 0x7e31 0x7e31 0x7e43 0x7e43 0x7e43 0x7e55 0x7e55 0x7e55 0x7e67 0x7e67 0x7e67 0x7e79 0x7e79 0x7e79 0x7e8c 0x7e8c 0x7e8c 0x7e9e 0x7e9e 0x7e9e 0x7eb0 0x7eb0 0x7eb0 0x7ec2 0x7ec2 0x7ec2 0x7ed4 0x7ed4 0x7ed4 0x7ee6 0x7ee6 0x7ee6 0x7ef8 0x7ef8 0x7ef8 0x7f0b 0x7f0b 0x7f0b 0x7f1d 0x7f1d 0x7f1d 0x7f2f 0x7f2f 0x7f2f 0x7f41 0x7f41 0x7f41 0x7f53 0x7f53 0x7f53 0x7f65 0x7f65 0x7f65 0x7f77 0x7f77 0x7f77 0x7f8a 0x7f8a 0x7f8a 0x7f9c 0x7f9c 0x7f9c 0x7fae 0x7fae 0x7fae 0x7fc0 0x7fc0 0x7fc0 0x7fd2 0x7fd2 0x7fd2 0x7fe4 0x7fe4 0x7fe4 0x7ff7 0x7ff7 0x7ff7 0x8009 0x8009 0x8009 0x801b 0x801b 0x801b 0x802b 0x802b 0x802b 0x803a 0x803a 0x803a 0x804a 0x804a 0x804a 0x8059 0x8059 0x8059 0x8069 0x8069 0x8069 0x8078 0x8078 0x8078 0x8087 0x8087 0x8087 0x8097 0x8097 0x8097 0x80a6 0x80a6 0x80a6 0x80b6 0x80b6 0x80b6 0x80c5 0x80c5 0x80c5 0x80d5 0x80d5 0x80d5 0x80e4 0x80e4 0x80e4 0x80f4 0x80f4 0x80f4 0x8103 0x8103 0x8103 0x8112 0x8112 0x8112 0x8122 0x8122 0x8122 0x8131 0x8131 0x8131 0x8141 0x8141 0x8141 0x8150 0x8150 0x8150 0x8160 0x8160 0x8160 0x816f 0x816f 0x816f 0x817e 0x817e 0x817e 0x818e 0x818e 0x818e 0x819d 0x819d 0x819d 0x81ad 0x81ad 0x81ad 0x81bc 0x81bc 0x81bc 0x81cc 0x81cc 0x81cc 0x81db 0x81db 0x81db 0x81eb 0x81eb 0x81eb 0x81fa 0x81fa 0x81fa 0x8209 0x8209 0x8209 0x8219 0x8219 0x8219 0x8228 0x8228 0x8228 0x8238 0x8238 0x8238 0x8247 0x8247 0x8247 0x8257 0x8257 0x8257 0x8266 0x8266 0x8266 0x8275 0x8275 0x8275 0x8285 0x8285 0x8285 0x8294 0x8294 0x8294 0x82a4 0x82a4 0x82a4 0x82b3 0x82b3 0x82b3 0x82c3 0x82c3 0x82c3 0x82d2 0x82d2 0x82d2 0x82e2 0x82e2 0x82e2 0x82f1 0x82f1 0x82f1 0x8300 0x8300 0x8300 0x8310 0x8310 0x8310 0x831f 0x831f 0x831f 0x832f 0x832f 0x832f 0x833e 0x833e 0x833e 0x834e 0x834e 0x834e 0x835d 0x835d 0x835d 0x836c 0x836c 0x836c 0x837c 0x837c 0x837c 0x838b 0x838b 0x838b 0x839b 0x839b 0x839b 0x83aa 0x83aa 0x83aa 0x83ba 0x83ba 0x83ba 0x83c9 0x83c9 0x83c9 0x83d8 0x83d8 0x83d8 0x83e8 0x83e8 0x83e8 0x83f7 0x83f7 0x83f7 0x8407 0x8407 0x8407 0x8416 0x8416 0x8416 0x8425 0x8425 0x8425 0x8431 0x8431 0x8431 0x843d 0x843d 0x843d 0x8449 0x8449 0x8449 0x8455 0x8455 0x8455 0x8462 0x8462 0x8462 0x846e 0x846e 0x846e 0x847a 0x847a 0x847a 0x8486 0x8486 0x8486 0x8492 0x8492 0x8492 0x849e 0x849e 0x849e 0x84aa 0x84aa 0x84aa 0x84b6 0x84b6 0x84b6 0x84c2 0x84c2 0x84c2 0x84ce 0x84ce 0x84ce 0x84da 0x84da 0x84da 0x84e7 0x84e7 0x84e7 0x84f3 0x84f3 0x84f3 0x84ff 0x84ff 0x84ff 0x850b 0x850b 0x850b 0x8517 0x8517 0x8517 0x8523 0x8523 0x8523 0x852f 0x852f 0x852f 0x853b 0x853b 0x853b 0x8547 0x8547 0x8547 0x8553 0x8553 0x8553 0x855f 0x855f 0x855f 0x856c 0x856c 0x856c 0x8578 0x8578 0x8578 0x8584 0x8584 0x8584 0x8590 0x8590 0x8590 0x859c 0x859c 0x859c 0x85a8 0x85a8 0x85a8 0x85b4 0x85b4 0x85b4 0x85c0 0x85c0 0x85c0 0x85cc 0x85cc 0x85cc 0x85d8 0x85d8 0x85d8 0x85e4 0x85e4 0x85e4 0x85f0 0x85f0 0x85f0 0x85fd 0x85fd 0x85fd 0x8609 0x8609 0x8609 0x8615 0x8615 0x8615 0x8621 0x8621 0x8621 0x862d 0x862d 0x862d 0x8639 0x8639 0x8639 0x8645 0x8645 0x8645 0x8651 0x8651 0x8651 0x865d 0x865d 0x865d 0x8669 0x8669 0x8669 0x8675 0x8675 0x8675 0x8682 0x8682 0x8682 0x868e 0x868e 0x868e 0x869a 0x869a 0x869a 0x86a6 0x86a6 0x86a6 0x86b2 0x86b2 0x86b2 0x86be 0x86be 0x86be 0x86ca 0x86ca 0x86ca 0x86d6 0x86d6 0x86d6 0x86e2 0x86e2 0x86e2 0x86ee 0x86ee 0x86ee 0x86fa 0x86fa 0x86fa 0x8707 0x8707 0x8707 0x8713 0x8713 0x8713 0x871f 0x871f 0x871f 0x872b 0x872b 0x872b 0x8737 0x8737 0x8737 0x8743 0x8743 0x8743 0x874f 0x874f 0x874f 0x875b 0x875b 0x875b 0x8767 0x8767 0x8767 0x8773 0x8773 0x8773 0x877f 0x877f 0x877f 0x878b 0x878b 0x878b 0x8798 0x8798 0x8798 0x87a4 0x87a4 0x87a4 0x87b0 0x87b0 0x87b0 0x87bc 0x87bc 0x87bc 0x87c8 0x87c8 0x87c8 0x87d4 0x87d4 0x87d4 0x87e0 0x87e0 0x87e0 0x87ec 0x87ec 0x87ec 0x87f8 0x87f8 0x87f8 0x8804 0x8804 0x8804 0x8810 0x8810 0x8810 0x881d 0x881d 0x881d 0x8829 0x8829 0x8829 0x8834 0x8834 0x8834 0x883f 0x883f 0x883f 0x884b 0x884b 0x884b 0x8856 0x8856 0x8856 0x8862 0x8862 0x8862 0x886d 0x886d 0x886d 0x8879 0x8879 0x8879 0x8884 0x8884 0x8884 0x8890 0x8890 0x8890 0x889b 0x889b 0x889b 0x88a6 0x88a6 0x88a6 0x88b2 0x88b2 0x88b2 0x88bd 0x88bd 0x88bd 0x88c9 0x88c9 0x88c9 0x88d4 0x88d4 0x88d4 0x88e0 0x88e0 0x88e0 0x88eb 0x88eb 0x88eb 0x88f6 0x88f6 0x88f6 0x8902 0x8902 0x8902 0x890d 0x890d 0x890d 0x8919 0x8919 0x8919 0x8924 0x8924 0x8924 0x8930 0x8930 0x8930 0x893b 0x893b 0x893b 0x8947 0x8947 0x8947 0x8952 0x8952 0x8952 0x895d 0x895d 0x895d 0x8969 0x8969 0x8969 0x8974 0x8974 0x8974 0x8980 0x8980 0x8980 0x898b 0x898b 0x898b 0x8997 0x8997 0x8997 0x89a2 0x89a2 0x89a2 0x89ae 0x89ae 0x89ae 0x89b9 0x89b9 0x89b9 0x89c4 0x89c4 0x89c4 0x89d0 0x89d0 0x89d0 0x89db 0x89db 0x89db 0x89e7 0x89e7 0x89e7 0x89f2 0x89f2 0x89f2 0x89fe 0x89fe 0x89fe 0x8a09 0x8a09 0x8a09 0x8a15 0x8a15 0x8a15 0x8a20 0x8a20 0x8a20 0x8a2b 0x8a2b 0x8a2b 0x8a37 0x8a37 0x8a37 0x8a42 0x8a42 0x8a42 0x8a4e 0x8a4e 0x8a4e 0x8a59 0x8a59 0x8a59 0x8a65 0x8a65 0x8a65 0x8a70 0x8a70 0x8a70 0x8a7b 0x8a7b 0x8a7b 0x8a87 0x8a87 0x8a87 0x8a92 0x8a92 0x8a92 0x8a9e 0x8a9e 0x8a9e 0x8aa9 0x8aa9 0x8aa9 0x8ab5 0x8ab5 0x8ab5 0x8ac0 0x8ac0 0x8ac0 0x8acc 0x8acc 0x8acc 0x8ad7 0x8ad7 0x8ad7 0x8ae2 0x8ae2 0x8ae2 0x8aee 0x8aee 0x8aee 0x8af9 0x8af9 0x8af9 0x8b05 0x8b05 0x8b05 0x8b10 0x8b10 0x8b10 0x8b1c 0x8b1c 0x8b1c 0x8b27 0x8b27 0x8b27 0x8b33 0x8b33 0x8b33 0x8b3e 0x8b3e 0x8b3e 0x8b49 0x8b49 0x8b49 0x8b55 0x8b55 0x8b55 0x8b60 0x8b60 0x8b60 0x8b6c 0x8b6c 0x8b6c 0x8b77 0x8b77 0x8b77 0x8b83 0x8b83 0x8b83 0x8b8e 0x8b8e 0x8b8e 0x8b99 0x8b99 0x8b99 0x8ba5 0x8ba5 0x8ba5 0x8bb0 0x8bb0 0x8bb0 0x8bbc 0x8bbc 0x8bbc 0x8bc7 0x8bc7 0x8bc7 0x8bd3 0x8bd3 0x8bd3 0x8bde 0x8bde 0x8bde 0x8bea 0x8bea 0x8bea 0x8bf5 0x8bf5 0x8bf5 0x8c00 0x8c00 0x8c00 0x8c0c 0x8c0c 0x8c0c 0x8c17 0x8c17 0x8c17 0x8c23 0x8c23 0x8c23 0x8c2e 0x8c2e 0x8c2e 0x8c38 0x8c38 0x8c38 0x8c43 0x8c43 0x8c43 0x8c4d 0x8c4d 0x8c4d 0x8c58 0x8c58 0x8c58 0x8c62 0x8c62 0x8c62 0x8c6c 0x8c6c 0x8c6c 0x8c77 0x8c77 0x8c77 0x8c81 0x8c81 0x8c81 0x8c8c 0x8c8c 0x8c8c 0x8c96 0x8c96 0x8c96 0x8ca0 0x8ca0 0x8ca0 0x8cab 0x8cab 0x8cab 0x8cb5 0x8cb5 0x8cb5 0x8cc0 0x8cc0 0x8cc0 0x8cca 0x8cca 0x8cca 0x8cd4 0x8cd4 0x8cd4 0x8cdf 0x8cdf 0x8cdf 0x8ce9 0x8ce9 0x8ce9 0x8cf4 0x8cf4 0x8cf4 0x8cfe 0x8cfe 0x8cfe 0x8d09 0x8d09 0x8d09 0x8d13 0x8d13 0x8d13 0x8d1d 0x8d1d 0x8d1d 0x8d28 0x8d28 0x8d28 0x8d32 0x8d32 0x8d32 0x8d3d 0x8d3d 0x8d3d 0x8d47 0x8d47 0x8d47 0x8d51 0x8d51 0x8d51 0x8d5c 0x8d5c 0x8d5c 0x8d66 0x8d66 0x8d66 0x8d71 0x8d71 0x8d71 0x8d7b 0x8d7b 0x8d7b 0x8d85 0x8d85 0x8d85 0x8d90 0x8d90 0x8d90 0x8d9a 0x8d9a 0x8d9a 0x8da5 0x8da5 0x8da5 0x8daf 0x8daf 0x8daf 0x8db9 0x8db9 0x8db9 0x8dc4 0x8dc4 0x8dc4 0x8dce 0x8dce 0x8dce 0x8dd9 0x8dd9 0x8dd9 0x8de3 0x8de3 0x8de3 0x8ded 0x8ded 0x8ded 0x8df8 0x8df8 0x8df8 0x8e02 0x8e02 0x8e02 0x8e0d 0x8e0d 0x8e0d 0x8e17 0x8e17 0x8e17 0x8e22 0x8e22 0x8e22 0x8e2c 0x8e2c 0x8e2c 0x8e36 0x8e36 0x8e36 0x8e41 0x8e41 0x8e41 0x8e4b 0x8e4b 0x8e4b 0x8e56 0x8e56 0x8e56 0x8e60 0x8e60 0x8e60 0x8e6a 0x8e6a 0x8e6a 0x8e75 0x8e75 0x8e75 0x8e7f 0x8e7f 0x8e7f 0x8e8a 0x8e8a 0x8e8a 0x8e94 0x8e94 0x8e94 0x8e9e 0x8e9e 0x8e9e 0x8ea9 0x8ea9 0x8ea9 0x8eb3 0x8eb3 0x8eb3 0x8ebe 0x8ebe 0x8ebe 0x8ec8 0x8ec8 0x8ec8 0x8ed2 0x8ed2 0x8ed2 0x8edd 0x8edd 0x8edd 0x8ee7 0x8ee7 0x8ee7 0x8ef2 0x8ef2 0x8ef2 0x8efc 0x8efc 0x8efc 0x8f07 0x8f07 0x8f07 0x8f11 0x8f11 0x8f11 0x8f1b 0x8f1b 0x8f1b 0x8f26 0x8f26 0x8f26 0x8f30 0x8f30 0x8f30 0x8f3b 0x8f3b 0x8f3b 0x8f45 0x8f45 0x8f45 0x8f4f 0x8f4f 0x8f4f 0x8f5a 0x8f5a 0x8f5a 0x8f64 0x8f64 0x8f64 0x8f6f 0x8f6f 0x8f6f 0x8f79 0x8f79 0x8f79 0x8f83 0x8f83 0x8f83 0x8f8e 0x8f8e 0x8f8e 0x8f98 0x8f98 0x8f98 0x8fa3 0x8fa3 0x8fa3 0x8fad 0x8fad 0x8fad 0x8fb7 0x8fb7 0x8fb7 0x8fc2 0x8fc2 0x8fc2 0x8fcc 0x8fcc 0x8fcc 0x8fd7 0x8fd7 0x8fd7 0x8fe1 0x8fe1 0x8fe1 0x8feb 0x8feb 0x8feb 0x8ff6 0x8ff6 0x8ff6 0x9000 0x9000 0x9000 0x900b 0x900b 0x900b 0x9015 0x9015 0x9015 0x9020 0x9020 0x9020 0x902a 0x902a 0x902a 0x9034 0x9034 0x9034 0x903e 0x903e 0x903e 0x9048 0x9048 0x9048 0x9052 0x9052 0x9052 0x905c 0x905c 0x905c 0x9066 0x9066 0x9066 0x9070 0x9070 0x9070 0x907a 0x907a 0x907a 0x9084 0x9084 0x9084 0x908e 0x908e 0x908e 0x9098 0x9098 0x9098 0x90a2 0x90a2 0x90a2 0x90ac 0x90ac 0x90ac 0x90b6 0x90b6 0x90b6 0x90c0 0x90c0 0x90c0 0x90ca 0x90ca 0x90ca 0x90d4 0x90d4 0x90d4 0x90de 0x90de 0x90de 0x90e8 0x90e8 0x90e8 0x90f2 0x90f2 0x90f2 0x90fc 0x90fc 0x90fc 0x9106 0x9106 0x9106 0x9110 0x9110 0x9110 0x911a 0x911a 0x911a 0x9123 0x9123 0x9123 0x912d 0x912d 0x912d 0x9137 0x9137 0x9137 0x9141 0x9141 0x9141 0x914b 0x914b 0x914b 0x9155 0x9155 0x9155 0x915f 0x915f 0x915f 0x9169 0x9169 0x9169 0x9173 0x9173 0x9173 0x917d 0x917d 0x917d 0x9187 0x9187 0x9187 0x9191 0x9191 0x9191 0x919b 0x919b 0x919b 0x91a5 0x91a5 0x91a5 0x91af 0x91af 0x91af 0x91b9 0x91b9 0x91b9 0x91c3 0x91c3 0x91c3 0x91cd 0x91cd 0x91cd 0x91d7 0x91d7 0x91d7 0x91e1 0x91e1 0x91e1 0x91eb 0x91eb 0x91eb 0x91f5 0x91f5 0x91f5 0x91ff 0x91ff 0x91ff 0x9209 0x9209 0x9209 0x9213 0x9213 0x9213 0x921d 0x921d 0x921d 0x9227 0x9227 0x9227 0x9231 0x9231 0x9231 0x923b 0x923b 0x923b 0x9245 0x9245 0x9245 0x924f 0x924f 0x924f 0x9259 0x9259 0x9259 0x9263 0x9263 0x9263 0x926d 0x926d 0x926d 0x9277 0x9277 0x9277 0x9281 0x9281 0x9281 0x928b 0x928b 0x928b 0x9295 0x9295 0x9295 0x929f 0x929f 0x929f 0x92a8 0x92a8 0x92a8 0x92b2 0x92b2 0x92b2 0x92bc 0x92bc 0x92bc 0x92c6 0x92c6 0x92c6 0x92d0 0x92d0 0x92d0 0x92da 0x92da 0x92da 0x92e4 0x92e4 0x92e4 0x92ee 0x92ee 0x92ee 0x92f8 0x92f8 0x92f8 0x9302 0x9302 0x9302 0x930c 0x930c 0x930c 0x9316 0x9316 0x9316 0x9320 0x9320 0x9320 0x932a 0x932a 0x932a 0x9334 0x9334 0x9334 0x933e 0x933e 0x933e 0x9348 0x9348 0x9348 0x9352 0x9352 0x9352 0x935c 0x935c 0x935c 0x9366 0x9366 0x9366 0x9370 0x9370 0x9370 0x937a 0x937a 0x937a 0x9384 0x9384 0x9384 0x938e 0x938e 0x938e 0x9398 0x9398 0x9398 0x93a2 0x93a2 0x93a2 0x93ac 0x93ac 0x93ac 0x93b6 0x93b6 0x93b6 0x93c0 0x93c0 0x93c0 0x93ca 0x93ca 0x93ca 0x93d4 0x93d4 0x93d4 0x93de 0x93de 0x93de 0x93e8 0x93e8 0x93e8 0x93f2 0x93f2 0x93f2 0x93fc 0x93fc 0x93fc 0x9406 0x9406 0x9406 0x9410 0x9410 0x9410 0x941a 0x941a 0x941a 0x9423 0x9423 0x9423 0x942d 0x942d 0x942d 0x9437 0x9437 0x9437 0x9440 0x9440 0x9440 0x9449 0x9449 0x9449 0x9451 0x9451 0x9451 0x945a 0x945a 0x945a 0x9463 0x9463 0x9463 0x946c 0x946c 0x946c 0x9475 0x9475 0x9475 0x947e 0x947e 0x947e 0x9486 0x9486 0x9486 0x948f 0x948f 0x948f 0x9498 0x9498 0x9498 0x94a1 0x94a1 0x94a1 0x94aa 0x94aa 0x94aa 0x94b3 0x94b3 0x94b3 0x94bb 0x94bb 0x94bb 0x94c4 0x94c4 0x94c4 0x94cd 0x94cd 0x94cd 0x94d6 0x94d6 0x94d6 0x94df 0x94df 0x94df 0x94e8 0x94e8 0x94e8 0x94f0 0x94f0 0x94f0 0x94f9 0x94f9 0x94f9 0x9502 0x9502 0x9502 0x950b 0x950b 0x950b 0x9514 0x9514 0x9514 0x951d 0x951d 0x951d 0x9525 0x9525 0x9525 0x952e 0x952e 0x952e 0x9537 0x9537 0x9537 0x9540 0x9540 0x9540 0x9549 0x9549 0x9549 0x9552 0x9552 0x9552 0x955a 0x955a 0x955a 0x9563 0x9563 0x9563 0x956c 0x956c 0x956c 0x9575 0x9575 0x9575 0x957e 0x957e 0x957e 0x9587 0x9587 0x9587 0x958f 0x958f 0x958f 0x9598 0x9598 0x9598 0x95a1 0x95a1 0x95a1 0x95aa 0x95aa 0x95aa 0x95b3 0x95b3 0x95b3 0x95bc 0x95bc 0x95bc 0x95c4 0x95c4 0x95c4 0x95cd 0x95cd 0x95cd 0x95d6 0x95d6 0x95d6 0x95df 0x95df 0x95df 0x95e8 0x95e8 0x95e8 0x95f1 0x95f1 0x95f1 0x95f9 0x95f9 0x95f9 0x9602 0x9602 0x9602 0x960b 0x960b 0x960b 0x9614 0x9614 0x9614 0x961d 0x961d 0x961d 0x9626 0x9626 0x9626 0x962e 0x962e 0x962e 0x9637 0x9637 0x9637 0x9640 0x9640 0x9640 0x9649 0x9649 0x9649 0x9652 0x9652 0x9652 0x965b 0x965b 0x965b 0x9663 0x9663 0x9663 0x966c 0x966c 0x966c 0x9675 0x9675 0x9675 0x967e 0x967e 0x967e 0x9687 0x9687 0x9687 0x9690 0x9690 0x9690 0x9698 0x9698 0x9698 0x96a1 0x96a1 0x96a1 0x96aa 0x96aa 0x96aa 0x96b3 0x96b3 0x96b3 0x96bc 0x96bc 0x96bc 0x96c5 0x96c5 0x96c5 0x96cd 0x96cd 0x96cd 0x96d6 0x96d6 0x96d6 0x96df 0x96df 0x96df 0x96e8 0x96e8 0x96e8 0x96f1 0x96f1 0x96f1 0x96f9 0x96f9 0x96f9 0x9702 0x9702 0x9702 0x970b 0x970b 0x970b 0x9714 0x9714 0x9714 0x971d 0x971d 0x971d 0x9726 0x9726 0x9726 0x972e 0x972e 0x972e 0x9737 0x9737 0x9737 0x9740 0x9740 0x9740 0x9749 0x9749 0x9749 0x9752 0x9752 0x9752 0x975b 0x975b 0x975b 0x9763 0x9763 0x9763 0x976c 0x976c 0x976c 0x9775 0x9775 0x9775 0x977e 0x977e 0x977e 0x9787 0x9787 0x9787 0x9790 0x9790 0x9790 0x9798 0x9798 0x9798 0x97a1 0x97a1 0x97a1 0x97aa 0x97aa 0x97aa 0x97b3 0x97b3 0x97b3 0x97bc 0x97bc 0x97bc 0x97c5 0x97c5 0x97c5 0x97cd 0x97cd 0x97cd 0x97d6 0x97d6 0x97d6 0x97df 0x97df 0x97df 0x97e8 0x97e8 0x97e8 0x97f1 0x97f1 0x97f1 0x97fa 0x97fa 0x97fa 0x9802 0x9802 0x9802 0x980b 0x980b 0x980b 0x9814 0x9814 0x9814 0x981d 0x981d 0x981d 0x9826 0x9826 0x9826 0x982f 0x982f 0x982f 0x9837 0x9837 0x9837 0x983f 0x983f 0x983f 0x9847 0x9847 0x9847 0x984f 0x984f 0x984f 0x9857 0x9857 0x9857 0x985f 0x985f 0x985f 0x9867 0x9867 0x9867 0x986e 0x986e 0x986e 0x9876 0x9876 0x9876 0x987e 0x987e 0x987e 0x9886 0x9886 0x9886 0x988e 0x988e 0x988e 0x9896 0x9896 0x9896 0x989e 0x989e 0x989e 0x98a5 0x98a5 0x98a5 0x98ad 0x98ad 0x98ad 0x98b5 0x98b5 0x98b5 0x98bd 0x98bd 0x98bd 0x98c5 0x98c5 0x98c5 0x98cd 0x98cd 0x98cd 0x98d5 0x98d5 0x98d5 0x98dc 0x98dc 0x98dc 0x98e4 0x98e4 0x98e4 0x98ec 0x98ec 0x98ec 0x98f4 0x98f4 0x98f4 0x98fc 0x98fc 0x98fc 0x9904 0x9904 0x9904 0x990c 0x990c 0x990c 0x9913 0x9913 0x9913 0x991b 0x991b 0x991b 0x9923 0x9923 0x9923 0x992b 0x992b 0x992b 0x9933 0x9933 0x9933 0x993b 0x993b 0x993b 0x9943 0x9943 0x9943 0x994a 0x994a 0x994a 0x9952 0x9952 0x9952 0x995a 0x995a 0x995a 0x9962 0x9962 0x9962 0x996a 0x996a 0x996a 0x9972 0x9972 0x9972 0x997a 0x997a 0x997a 0x9981 0x9981 0x9981 0x9989 0x9989 0x9989 0x9991 0x9991 0x9991 0x9999 0x9999 0x9999 0x99a1 0x99a1 0x99a1 0x99a9 0x99a9 0x99a9 0x99b1 0x99b1 0x99b1 0x99b8 0x99b8 0x99b8 0x99c0 0x99c0 0x99c0 0x99c8 0x99c8 0x99c8 0x99d0 0x99d0 0x99d0 0x99d8 0x99d8 0x99d8 0x99e0 0x99e0 0x99e0 0x99e8 0x99e8 0x99e8 0x99ef 0x99ef 0x99ef 0x99f7 0x99f7 0x99f7 0x99ff 0x99ff 0x99ff 0x9a07 0x9a07 0x9a07 0x9a0f 0x9a0f 0x9a0f 0x9a17 0x9a17 0x9a17 0x9a1f 0x9a1f 0x9a1f 0x9a26 0x9a26 0x9a26 0x9a2e 0x9a2e 0x9a2e 0x9a36 0x9a36 0x9a36 0x9a3e 0x9a3e 0x9a3e 0x9a46 0x9a46 0x9a46 0x9a4e 0x9a4e 0x9a4e 0x9a56 0x9a56 0x9a56 0x9a5d 0x9a5d 0x9a5d 0x9a65 0x9a65 0x9a65 0x9a6d 0x9a6d 0x9a6d 0x9a75 0x9a75 0x9a75 0x9a7d 0x9a7d 0x9a7d 0x9a85 0x9a85 0x9a85 0x9a8d 0x9a8d 0x9a8d 0x9a94 0x9a94 0x9a94 0x9a9c 0x9a9c 0x9a9c 0x9aa4 0x9aa4 0x9aa4 0x9aac 0x9aac 0x9aac 0x9ab4 0x9ab4 0x9ab4 0x9abc 0x9abc 0x9abc 0x9ac4 0x9ac4 0x9ac4 0x9acb 0x9acb 0x9acb 0x9ad3 0x9ad3 0x9ad3 0x9adb 0x9adb 0x9adb 0x9ae3 0x9ae3 0x9ae3 0x9aeb 0x9aeb 0x9aeb 0x9af3 0x9af3 0x9af3 0x9afb 0x9afb 0x9afb 0x9b02 0x9b02 0x9b02 0x9b0a 0x9b0a 0x9b0a 0x9b12 0x9b12 0x9b12 0x9b1a 0x9b1a 0x9b1a 0x9b22 0x9b22 0x9b22 0x9b2a 0x9b2a 0x9b2a 0x9b32 0x9b32 0x9b32 0x9b39 0x9b39 0x9b39 0x9b41 0x9b41 0x9b41 0x9b49 0x9b49 0x9b49 0x9b51 0x9b51 0x9b51 0x9b59 0x9b59 0x9b59 0x9b61 0x9b61 0x9b61 0x9b69 0x9b69 0x9b69 0x9b70 0x9b70 0x9b70 0x9b78 0x9b78 0x9b78 0x9b80 0x9b80 0x9b80 0x9b88 0x9b88 0x9b88 0x9b90 0x9b90 0x9b90 0x9b98 0x9b98 0x9b98 0x9ba0 0x9ba0 0x9ba0 0x9ba7 0x9ba7 0x9ba7 0x9baf 0x9baf 0x9baf 0x9bb7 0x9bb7 0x9bb7 0x9bbf 0x9bbf 0x9bbf 0x9bc7 0x9bc7 0x9bc7 0x9bcf 0x9bcf 0x9bcf 0x9bd7 0x9bd7 0x9bd7 0x9bde 0x9bde 0x9bde 0x9be6 0x9be6 0x9be6 0x9bee 0x9bee 0x9bee 0x9bf6 0x9bf6 0x9bf6 0x9bfe 0x9bfe 0x9bfe 0x9c06 0x9c06 0x9c06 0x9c0e 0x9c0e 0x9c0e 0x9c15 0x9c15 0x9c15 0x9c1d 0x9c1d 0x9c1d 0x9c25 0x9c25 0x9c25 0x9c2d 0x9c2d 0x9c2d 0x9c35 0x9c35 0x9c35 0x9c3d 0x9c3d 0x9c3d 0x9c44 0x9c44 0x9c44 0x9c4b 0x9c4b 0x9c4b 0x9c53 0x9c53 0x9c53 0x9c5a 0x9c5a 0x9c5a 0x9c61 0x9c61 0x9c61 0x9c69 0x9c69 0x9c69 0x9c70 0x9c70 0x9c70 0x9c77 0x9c77 0x9c77 0x9c7f 0x9c7f 0x9c7f 0x9c86 0x9c86 0x9c86 0x9c8d 0x9c8d 0x9c8d 0x9c95 0x9c95 0x9c95 0x9c9c 0x9c9c 0x9c9c 0x9ca3 0x9ca3 0x9ca3 0x9cab 0x9cab 0x9cab 0x9cb2 0x9cb2 0x9cb2 0x9cb9 0x9cb9 0x9cb9 0x9cc1 0x9cc1 0x9cc1 0x9cc8 0x9cc8 0x9cc8 0x9ccf 0x9ccf 0x9ccf 0x9cd7 0x9cd7 0x9cd7 0x9cde 0x9cde 0x9cde 0x9ce5 0x9ce5 0x9ce5 0x9ced 0x9ced 0x9ced 0x9cf4 0x9cf4 0x9cf4 0x9cfb 0x9cfb 0x9cfb 0x9d03 0x9d03 0x9d03 0x9d0a 0x9d0a 0x9d0a 0x9d12 0x9d12 0x9d12 0x9d19 0x9d19 0x9d19 0x9d20 0x9d20 0x9d20 0x9d28 0x9d28 0x9d28 0x9d2f 0x9d2f 0x9d2f 0x9d36 0x9d36 0x9d36 0x9d3e 0x9d3e 0x9d3e 0x9d45 0x9d45 0x9d45 0x9d4c 0x9d4c 0x9d4c 0x9d54 0x9d54 0x9d54 0x9d5b 0x9d5b 0x9d5b 0x9d62 0x9d62 0x9d62 0x9d6a 0x9d6a 0x9d6a 0x9d71 0x9d71 0x9d71 0x9d78 0x9d78 0x9d78 0x9d80 0x9d80 0x9d80 0x9d87 0x9d87 0x9d87 0x9d8e 0x9d8e 0x9d8e 0x9d96 0x9d96 0x9d96 0x9d9d 0x9d9d 0x9d9d 0x9da4 0x9da4 0x9da4 0x9dac 0x9dac 0x9dac 0x9db3 0x9db3 0x9db3 0x9dba 0x9dba 0x9dba 0x9dc2 0x9dc2 0x9dc2 0x9dc9 0x9dc9 0x9dc9 0x9dd0 0x9dd0 0x9dd0 0x9dd8 0x9dd8 0x9dd8 0x9ddf 0x9ddf 0x9ddf 0x9de6 0x9de6 0x9de6 0x9dee 0x9dee 0x9dee 0x9df5 0x9df5 0x9df5 0x9dfc 0x9dfc 0x9dfc 0x9e04 0x9e04 0x9e04 0x9e0b 0x9e0b 0x9e0b 0x9e13 0x9e13 0x9e13 0x9e1a 0x9e1a 0x9e1a 0x9e21 0x9e21 0x9e21 0x9e29 0x9e29 0x9e29 0x9e30 0x9e30 0x9e30 0x9e37 0x9e37 0x9e37 0x9e3f 0x9e3f 0x9e3f 0x9e46 0x9e46 0x9e46 0x9e4d 0x9e4d 0x9e4d 0x9e55 0x9e55 0x9e55 0x9e5c 0x9e5c 0x9e5c 0x9e63 0x9e63 0x9e63 0x9e6b 0x9e6b 0x9e6b 0x9e72 0x9e72 0x9e72 0x9e79 0x9e79 0x9e79 0x9e81 0x9e81 0x9e81 0x9e88 0x9e88 0x9e88 0x9e8f 0x9e8f 0x9e8f 0x9e97 0x9e97 0x9e97 0x9e9e 0x9e9e 0x9e9e 0x9ea5 0x9ea5 0x9ea5 0x9ead 0x9ead 0x9ead 0x9eb4 0x9eb4 0x9eb4 0x9ebb 0x9ebb 0x9ebb 0x9ec3 0x9ec3 0x9ec3 0x9eca 0x9eca 0x9eca 0x9ed1 0x9ed1 0x9ed1 0x9ed9 0x9ed9 0x9ed9 0x9ee0 0x9ee0 0x9ee0 0x9ee7 0x9ee7 0x9ee7 0x9eef 0x9eef 0x9eef 0x9ef6 0x9ef6 0x9ef6 0x9efd 0x9efd 0x9efd 0x9f05 0x9f05 0x9f05 0x9f0c 0x9f0c 0x9f0c 0x9f14 0x9f14 0x9f14 0x9f1b 0x9f1b 0x9f1b 0x9f22 0x9f22 0x9f22 0x9f2a 0x9f2a 0x9f2a 0x9f31 0x9f31 0x9f31 0x9f38 0x9f38 0x9f38 0x9f40 0x9f40 0x9f40 0x9f47 0x9f47 0x9f47 0x9f4e 0x9f4e 0x9f4e 0x9f56 0x9f56 0x9f56 0x9f5d 0x9f5d 0x9f5d 0x9f64 0x9f64 0x9f64 0x9f6c 0x9f6c 0x9f6c 0x9f73 0x9f73 0x9f73 0x9f7a 0x9f7a 0x9f7a 0x9f82 0x9f82 0x9f82 0x9f89 0x9f89 0x9f89 0x9f90 0x9f90 0x9f90 0x9f98 0x9f98 0x9f98 0x9f9f 0x9f9f 0x9f9f 0x9fa6 0x9fa6 0x9fa6 0x9fae 0x9fae 0x9fae 0x9fb5 0x9fb5 0x9fb5 0x9fbc 0x9fbc 0x9fbc 0x9fc4 0x9fc4 0x9fc4 0x9fcb 0x9fcb 0x9fcb 0x9fd2 0x9fd2 0x9fd2 0x9fda 0x9fda 0x9fda 0x9fe1 0x9fe1 0x9fe1 0x9fe8 0x9fe8 0x9fe8 0x9ff0 0x9ff0 0x9ff0 0x9ff7 0x9ff7 0x9ff7 0x9fff 0x9fff 0x9fff>; + nvidia,panel-csc = <0xd581 0x2979 0xc5 0x0 0x831 0xcac1 0x20c 0x0 0x189 0x625 0xcc4a 0x0>; + }; + }; + }; + + se@15830000 { + compatible = "nvidia,tegra186-se3-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "rsa"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15830000 0x0 0x10000>; + iommus = <0x11 0xe>; + opcode_addr = <0x604>; + }; + + isp@15600000 { + power-domains = <0x1f 0x5>; + compatible = "nvidia,tegra186-isp"; + clocks = <0x10 0x32>; + resets = <0x10 0x19>; + clock-names = "isp"; + status = "okay"; + interrupts = <0x0 0xcd 0x4>; + iommu-group-id = <0x1>; + reg = <0x0 0x15600000 0x0 0x40000>; + iommus = <0x11 0x5>; + }; + + nvdisplay@15210000 { + pinctrl-5 = <0x79>; + nvidia,fb-flags = <0x1>; + compatible = "nvidia,tegra186-dc"; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x206 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x10b 0x10 0x3a>; + pinctrl-3 = <0x77>; + nvidia,cmu-enable = <0x1>; + vdd_hdmi_5v0-supply = <0x8a>; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x5a>; + pinctrl-1 = <0x75>; + nvidia,dc-connector = <0x8b>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "pll_d", "plld2", "plld3", "pllp_display", "pll_d_out1", "disp2_emc"; + pinctrl-10 = <0x7e>; + pinctrl-8 = <0x7c>; + win-mask = <0x38>; + avdd_hdmi-supply = <0x89>; + pinctrl-6 = <0x7a>; + status = "okay"; + fb_reserved = <0x81>; + interrupts = <0x0 0x9a 0x4>; + pinctrl-4 = <0x78>; + nvidia,emc-clk-rate = <0x11e1a300>; + phandle = <0x1c7>; + iommu-group-id = <0x1>; + avdd_hdmi_pll-supply = <0x12>; + pinctrl-2 = <0x76>; + nvidia,dc-flags = <0x1>; + reg = <0x0 0x15210000 0x0 0x10000>; + iommus = <0x11 0x9>; + pinctrl-0 = <0x74>; + iommu-direct-regions = <0x80 0x81 0x82>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head1"; + pinctrl-11 = <0x7f>; + nvidia,fb-win = <0x3>; + pinctrl-9 = <0x7d>; + nvidia,dc-or-node = "/host1x/sor1"; + linux,phandle = <0x1c7>; + nvidia,dc-ctrlnum = <0x1>; + pinctrl-7 = <0x7b>; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + nvidia,fb-bpp = <0x20>; + }; + + sor1 { + nvidia,dpaux = <0x91>; + compatible = "nvidia,tegra186-sor1"; + clocks = <0x10 0x5d 0x10 0x27 0x10 0x268 0x10 0x129 0x10 0x20b 0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + resets = <0x10 0x6c 0x10 0xf 0x10 0x10 0x10 0x11>; + clock-names = "sor1_ref", "sor_safe", "sor1_pad_clkout", "sor1", "pll_dp", "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + status = "okay"; + nvidia,xbar-ctrl = <0x0 0x1 0x2 0x3 0x4>; + interrupts = <0x0 0x9e 0x4>; + phandle = <0x8b>; + nvidia,sor-ctrlnum = <0x1>; + reg = <0x0 0x15580000 0x0 0x40000>; + reset-names = "sor1", "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + nvidia,ddc-i2c-bus = <0x92>; + linux,phandle = <0x8b>; + nvidia,hpd-gpio = <0x1b 0x79 0x1>; + nvidia,active-panel = <0x93>; + + prod-settings { + #prod-cells = <0x3>; + prod_list_hdmi_soc = "prod_c_hdmi_0m_54m", "prod_c_hdmi_54m_111m", "prod_c_hdmi_111m_223m", "prod_c_hdmi_223m_300m", "prod_c_hdmi_300m_600m"; + + prod_c_75M { + prod = <0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_hdmi_111m_223m { + prod = <0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hbr2 { + prod = <0x590 0xf00000 0x400000>; + }; + + prod_c_rbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_hdmi_223m_300m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_0m_54m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_600M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_300M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_54M { + prod = <0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hdmi_54m_111m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_150M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_300m_600m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_dp { + prod = <0x58c 0xf0f0f10 0x5050310 0x590 0x3000100 0x100 0x594 0xf0000000 0x0 0x598 0x2ff0 0x2440 0x59c 0x401800 0x0 0x5a0 0x400000 0x400000 0x5a8 0xff000000 0x34000000 0x70 0xffffffff 0x0 0x180 0x1 0x1>; + }; + }; + + hdmi-display { + compatible = "hdmi,display"; + generic-infoframe-type = <0x87>; + status = "okay"; + phandle = <0x93>; + linux,phandle = <0x93>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld2"; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x2>; + nvidia,out-type = <0x1>; + nvidia,out-yres = <0x870>; + }; + }; + + dp-display { + compatible = "dp, display"; + nvidia,is_ext_dp_panel = <0x1>; + status = "disabled"; + phandle = <0x1cb>; + linux,phandle = <0x1cb>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld2"; + nvidia,out-order = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + nvidia,out-yres = <0x870>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + + display-timings { + + 1920x1080-32 { + hsync-len = <0x2c>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x58>; + vfront-porch = <0x4>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x5>; + vactive = <0x438>; + hback-porch = <0x94>; + clock-frequency = <0x8d9ee20>; + hactive = <0x780>; + vback-porch = <0x24>; + }; + + 720x480-32 { + hsync-len = <0x3e>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x10>; + vfront-porch = <0x9>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x6>; + vactive = <0x1e0>; + hback-porch = <0x3c>; + clock-frequency = <0x19bfcc0>; + hactive = <0x2d0>; + vback-porch = <0x1e>; + }; + }; + + lt-data { + + tegra-dp-pe-regs { + pc2_l0 = <0x0 0x8 0x12 0x24 0x1 0xe 0x1d 0x1 0x13 0x0>; + pc2_l3 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l1 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l2 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + }; + + tegra-dp-vs-regs { + pc2_l0 = <0x13 0x19 0x1e 0x28 0x1e 0x25 0x2d 0x28 0x32 0x39>; + pc2_l3 = <0x11 0x14 0x17 0x1f 0x19 0x1e 0x24 0x22 0x2a 0x32>; + pc2_l1 = <0x12 0x17 0x1b 0x25 0x1c 0x23 0x2a 0x25 0x2f 0x37>; + pc2_l2 = <0x12 0x16 0x1a 0x22 0x1b 0x20 0x27 0x24 0x2d 0x35>; + }; + + tegra-dp-pc-regs { + pc2_l0 = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + pc2_l3 = <0x5 0x9 0xb 0x12 0x9 0xd 0x12 0xb 0xf 0x12>; + pc2_l1 = <0x2 0x2 0x4 0x5 0x2 0x4 0x5 0x4 0x5 0x5>; + pc2_l2 = <0x4 0x5 0x8 0xb 0x5 0x9 0xb 0x8 0xa 0xb>; + }; + + tegra-dp-tx-pu { + pc2_l0 = <0x22 0x33 0x44 0x66 0x33 0x44 0x66 0x44 0x66 0x66>; + pc2_l3 = <0x22 0x22 0x22 0x44 0x33 0x33 0x44 0x44 0x44 0x66>; + pc2_l1 = <0x22 0x22 0x33 0x55 0x33 0x44 0x55 0x44 0x55 0x66>; + pc2_l2 = <0x22 0x22 0x33 0x44 0x33 0x33 0x44 0x44 0x55 0x66>; + }; + }; + }; + }; + + dc_common { + compatible = "nvidia,tegra_dc_common"; + nvidia,disp_imp_table = <0x73>; + nvidia,valid_heads = <0x3>; + reg = <0x0 0x15200000 0x0 0x30000>; + }; + + ctx6 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c4>; + iommus = <0x11 0x3e>; + linux,phandle = <0x1c4>; + }; + + tsecb@15100000 { + compatible = "nvidia,tegra186-tsec"; + clocks = <0x10 0x89>; + resets = <0x10 0x82>; + clock-names = "tsecb"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15100000 0x0 0x40000>; + iommus = <0x11 0xb>; + }; + + se@15840000 { + compatible = "nvidia,tegra186-se4-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "sha"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15840000 0x0 0x10000>; + iommus = <0x11 0xf>; + opcode_addr = <0x104>; + }; + + nvdisplay@15220000 { + pinctrl-5 = <0x79>; + nvidia,fb-flags = <0x1>; + compatible = "nvidia,tegra186-dc"; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x3a>; + pinctrl-3 = <0x77>; + nvidia,cmu-enable = <0x1>; + vdd_hdmi_5v0-supply = <0x26>; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x5b>; + pinctrl-1 = <0x75>; + vdd-dp-pad-supply = <0x26>; + nvidia,dc-connector = <0x8c>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "plld2", "plld3", "pllp_display", "disp3_emc"; + vdd-dp-pwr-supply = <0x26>; + pinctrl-10 = <0x7e>; + pinctrl-8 = <0x7c>; + win-mask = <0x0>; + pinctrl-6 = <0x7a>; + status = "disabled"; + fb_reserved = <0x82>; + interrupts = <0x0 0x9b 0x4>; + pinctrl-4 = <0x78>; + vdd-edp-sec-mode-supply = <0x26>; + nvidia,emc-clk-rate = <0x11e1a300>; + avdd-dp-pll-supply = <0x26>; + phandle = <0x1c8>; + iommu-group-id = <0x1>; + pinctrl-2 = <0x76>; + nvidia,dc-flags = <0x1>; + reg = <0x0 0x15220000 0x0 0x10000>; + iommus = <0x11 0x9>; + pinctrl-0 = <0x74>; + iommu-direct-regions = <0x80 0x81 0x82>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head2"; + pinctrl-11 = <0x7f>; + pinctrl-9 = <0x7d>; + nvidia,dc-or-node = "/host1x/sor"; + linux,phandle = <0x1c8>; + nvidia,dc-ctrlnum = <0x2>; + pinctrl-7 = <0x7b>; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + nvidia,fb-bpp = <0x20>; + }; + + ctx4 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c2>; + iommus = <0x11 0x3c>; + linux,phandle = <0x1c2>; + }; + + sor { + nvidia,dpaux = <0x8e>; + compatible = "nvidia,tegra186-sor"; + clocks = <0x10 0x61 0x10 0x27 0x10 0x267 0x10 0x128 0x10 0x20b 0x10 0x10d 0x10 0x88 0x10 0x66 0x10 0x58 0x10 0x62>; + resets = <0x10 0x27 0x10 0xf 0x10 0x10 0x10 0x11>; + clock-names = "sor0_ref", "sor_safe", "sor0_pad_clkout", "sor0", "pll_dp", "pllp_out0", "maud", "hda", "hda2codec_2x", "hda2hdmi"; + status = "disabled"; + nvidia,xbar-ctrl = <0x0 0x1 0x2 0x3 0x4>; + phandle = <0x8c>; + nvidia,sor-ctrlnum = <0x0>; + reg = <0x0 0x15540000 0x0 0x40000>; + reset-names = "sor0", "hda_rst", "hda2codec_2x_rst", "hda2hdmi_rst"; + nvidia,ddc-i2c-bus = <0x8f>; + linux,phandle = <0x8c>; + nvidia,hpd-gpio = <0x1b 0x78 0x1>; + nvidia,active-panel = <0x90>; + + prod-settings { + #prod-cells = <0x3>; + prod_list_hdmi_soc = "prod_c_hdmi_0m_54m", "prod_c_hdmi_54m_111m", "prod_c_hdmi_111m_223m", "prod_c_hdmi_223m_300m", "prod_c_hdmi_300m_600m"; + + prod_c_75M { + prod = <0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_hdmi_111m_223m { + prod = <0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hbr2 { + prod = <0x590 0xf00000 0x400000>; + }; + + prod_c_rbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_hdmi_223m_300m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_0m_54m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hbr { + prod = <0x590 0xf00000 0x300000>; + }; + + prod_c_600M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_300M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x404000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_54M { + prod = <0x58c 0xf0f0f00 0x5050000 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x0 0x5a8 0xff000000 0x54000000>; + }; + + prod_c_hdmi_54m_111m { + prod = <0x138 0xffffffff 0x333a3a3a 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050100 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x44000000>; + }; + + prod_c_150M { + prod = <0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301f00 0x598 0xff000ff0 0x38000440 0x138 0xffffffff 0x373a3a3a 0x148 0xffffffff 0x0 0x5a0 0x40ff00 0x400000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_hdmi_300m_600m { + prod = <0x138 0xffffffff 0x333d3d3d 0x148 0xffffffff 0x0 0x58c 0xf0f0f00 0x5050300 0x590 0xf01f00 0x301900 0x598 0xff000ff0 0x38000440 0x5a0 0x40ff00 0x406000 0x5a8 0xff000000 0x34000000>; + }; + + prod_c_dp { + prod = <0x58c 0xf0f0f10 0x5050310 0x590 0x3000100 0x100 0x594 0xf0000000 0x0 0x598 0x2ff0 0x2440 0x59c 0x401800 0x0 0x5a0 0x400000 0x400000 0x5a8 0xff000000 0x34000000 0x70 0xffffffff 0x0 0x180 0x1 0x1>; + }; + }; + + panel-a-edp-1080p-14-0 { + compatible = "a-edp,1080p-14-0"; + nvidia,tx-pu-disable = <0x1>; + status = "disabled"; + phandle = <0x1ca>; + linux,phandle = <0x1ca>; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "okay"; + nvidia,smooth-k-incr = <0x40>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x0>; + }; + + disp-default-out { + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "pll_d_out0"; + nvidia,out-order = <0x0>; + nvidia,out-depth = <0x12>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + }; + + hdmi-display { + compatible = "hdmi,display"; + generic-infoframe-type = <0x87>; + status = "disabled"; + phandle = <0x1c9>; + linux,phandle = <0x1c9>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld3"; + nvidia,out-order = <0x0>; + nvidia,out-flags = <0x2>; + nvidia,out-type = <0x1>; + nvidia,out-yres = <0x870>; + }; + }; + + panel-s-edp-uhdtv-15-6 { + compatible = "s-edp,uhdtv-15-6"; + nvidia,tx-pu-disable = <0x1>; + status = "disabled"; + phandle = <0x11f>; + linux,phandle = <0x11f>; + nvidia,panel-bl-pwm-gpio = <0x28 0xd 0x0>; + + smartdimmer { + nvidia,hw-update-delay = <0x0>; + nvidia,use-vpulse2 = <0x1>; + nvidia,soft-clipping-threshold = <0x80>; + nvidia,lut = <0xff 0xff 0xff 0xc7 0xc7 0xc7 0x99 0x99 0x99 0x74 0x74 0x74 0x55 0x55 0x55 0x3b 0x3b 0x3b 0x24 0x24 0x24 0x11 0x11 0x11 0x0 0x0 0x0>; + nvidia,bin-width = <0xffffffff>; + nvidia,aggressiveness = <0x5>; + nvidia,blp = <0x400 0xff>; + nvidia,bltf = <0x39 0x41 0x49 0x52 0x5c 0x67 0x72 0x7d 0x8a 0x96 0xa4 0xb2 0xc1 0xd0 0xe0 0xf1>; + nvidia,use-vid-luma = <0x0>; + nvidia,phase-in-settings = <0x0>; + status = "disabled"; + nvidia,smooth-k-incr = <0x40>; + nvidia,bl-device-name = "pwm-backlight"; + nvidia,fc = <0x0 0x0>; + nvidia,soft-clipping-enable = <0x1>; + nvidia,coeff = <0x5 0x9 0x2>; + nvidia,phase-in-adjustments = <0x0>; + nvidia,use-auto-pwm = <0x0>; + nvidia,sd-window-enable = <0x0>; + nvidia,k-limit = <0xc8>; + nvidia,k-limit-enable = <0x1>; + nvidia,smooth-k-enable = <0x0>; + }; + + disp-default-out { + nvidia,out-xres = <0xf00>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "pll_d_out0"; + nvidia,out-order = <0x0>; + nvidia,out-depth = <0x18>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + nvidia,out-yres = <0x870>; + nvidia,out-height = <0xc2>; + nvidia,out-width = <0x15a>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + + display-timings { + + 3840x2160-32 { + hsync-len = <0x20>; + nvidia,h-ref-to-sync = <0x1>; + hfront-porch = <0x30>; + vfront-porch = <0x3>; + nvidia,v-ref-to-sync = <0x1>; + vsync-len = <0x5>; + vactive = <0x870>; + hback-porch = <0x50>; + clock-frequency = <0x1f1e7610>; + hactive = <0xf00>; + vback-porch = <0x36>; + }; + }; + }; + + dp-display { + compatible = "dp, display"; + nvidia,is_ext_dp_panel = <0x1>; + status = "disabled"; + phandle = <0x90>; + linux,phandle = <0x90>; + + disp-default-out { + nvidia,out-xres = <0x1000>; + nvidia,out-align = <0x0>; + nvidia,out-parent-clk = "plld3"; + nvidia,out-order = <0x0>; + nvidia,out-pins = <0x1 0x0 0x2 0x0 0x3 0x0 0x0 0x1>; + nvidia,out-flags = <0x0>; + nvidia,out-type = <0x3>; + nvidia,out-yres = <0x870>; + }; + + dp-lt-settings { + + lt-setting@2 { + nvidia,load-adj = <0x6>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x1 0x1 0x1 0x1>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@0 { + nvidia,load-adj = <0x3>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + + lt-setting@1 { + nvidia,load-adj = <0x4>; + nvidia,post-cursor = <0x0 0x0 0x0 0x0>; + nvidia,lane-preemphasis = <0x0 0x0 0x0 0x0>; + nvidia,tx-pu = <0x0>; + nvidia,drive-current = <0x0 0x0 0x0 0x0>; + }; + }; + + lt-data { + + tegra-dp-pe-regs { + pc2_l0 = <0x0 0x8 0x12 0x24 0x1 0xe 0x1d 0x1 0x13 0x0>; + pc2_l3 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l1 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + pc2_l2 = <0x0 0x8 0x12 0x24 0x0 0xe 0x1d 0x0 0x13 0x0>; + }; + + tegra-dp-vs-regs { + pc2_l0 = <0x13 0x19 0x1e 0x28 0x1e 0x25 0x2d 0x28 0x32 0x39>; + pc2_l3 = <0x11 0x14 0x17 0x1f 0x19 0x1e 0x24 0x22 0x2a 0x32>; + pc2_l1 = <0x12 0x17 0x1b 0x25 0x1c 0x23 0x2a 0x25 0x2f 0x37>; + pc2_l2 = <0x12 0x16 0x1a 0x22 0x1b 0x20 0x27 0x24 0x2d 0x35>; + }; + + tegra-dp-pc-regs { + pc2_l0 = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + pc2_l3 = <0x5 0x9 0xb 0x12 0x9 0xd 0x12 0xb 0xf 0x12>; + pc2_l1 = <0x2 0x2 0x4 0x5 0x2 0x4 0x5 0x4 0x5 0x5>; + pc2_l2 = <0x4 0x5 0x8 0xb 0x5 0x9 0xb 0x8 0xa 0xb>; + }; + + tegra-dp-tx-pu { + pc2_l0 = <0x22 0x33 0x44 0x66 0x33 0x44 0x66 0x44 0x66 0x66>; + pc2_l3 = <0x22 0x22 0x22 0x44 0x33 0x33 0x44 0x44 0x44 0x66>; + pc2_l1 = <0x22 0x22 0x33 0x55 0x33 0x44 0x55 0x44 0x55 0x66>; + pc2_l2 = <0x22 0x22 0x33 0x44 0x33 0x33 0x44 0x44 0x55 0x66>; + }; + }; + }; + }; + + ctx2 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c0>; + iommus = <0x11 0x3a>; + linux,phandle = <0x1c0>; + }; + + dpaux@155c0000 { + power-domains = <0x94>; + compatible = "nvidia,tegra186-dpaux"; + clocks = <0x10 0x60>; + resets = <0x10 0x5>; + clock-names = "dpaux"; + nvidia,dpaux-ctrlnum = <0x0>; + status = "disabled"; + interrupts = <0x0 0x9f 0x4>; + phandle = <0x8e>; + reg = <0x0 0x155c0000 0x0 0x40000>; + reset-names = "dpaux"; + linux,phandle = <0x8e>; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_dpaux_hdmi { + prod = <0x124 0x700 0x400>; + }; + + prod_c_dpaux_dp { + prod = <0x124 0x37fe 0x24c2>; + }; + }; + }; + + se@15810000 { + compatible = "nvidia,tegra186-se1-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "drbg"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15810000 0x0 0x10000>; + iommus = <0x11 0xc>; + opcode_addr = <0x204>; + }; + + ctx0 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1be>; + iommus = <0x11 0x38>; + linux,phandle = <0x1be>; + }; + + nvcsi@150c0000 { + num-channels = <0x1>; + power-domains = <0x1f 0xb>; + compatible = "nvidia,tegra186-nvcsi"; + clocks = <0x10 0xb4 0x10 0xb5 0x10 0x20e 0x10 0x10d>; + resets = <0x10 0x58>; + num-ports = <0x6>; + clock-names = "nvcsi", "nvcsilp", "nvcsi_parent", "nvcsilp_parent"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x77 0x4>; + #size-cells = <0x0>; + phandle = <0x128>; + iommu-group-id = <0x1>; + reg = <0x0 0x150c0000 0x0 0x40000>; + iommus = <0x11 0x2>; + nvidia,csi_regulator = "avdd_dsi_csi"; + linux,phandle = <0x128>; + + channel@4 { + status = "disabled"; + phandle = <0x156>; + reg = <0x4>; + linux,phandle = <0x156>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x159>; + reg = <0x1>; + linux,phandle = <0x159>; + + endpoint@9 { + remote-endpoint = <0x6a>; + status = "disabled"; + phandle = <0x71>; + linux,phandle = <0x71>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x157>; + reg = <0x0>; + linux,phandle = <0x157>; + + endpoint@8 { + port-index = <0x4>; + remote-endpoint = <0x69>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x38>; + linux,phandle = <0x38>; + }; + }; + }; + }; + + channel@2 { + status = "disabled"; + phandle = <0x144>; + reg = <0x2>; + linux,phandle = <0x144>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x147>; + reg = <0x1>; + linux,phandle = <0x147>; + + endpoint@5 { + remote-endpoint = <0x66>; + status = "disabled"; + phandle = <0x6f>; + linux,phandle = <0x6f>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x145>; + reg = <0x0>; + linux,phandle = <0x145>; + + endpoint@4 { + port-index = <0x2>; + remote-endpoint = <0x65>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x36>; + linux,phandle = <0x36>; + }; + }; + }; + }; + + channel@0 { + status = "okay"; + phandle = <0x129>; + reg = <0x0>; + linux,phandle = <0x129>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "okay"; + phandle = <0x12b>; + reg = <0x1>; + linux,phandle = <0x12b>; + + endpoint@1 { + remote-endpoint = <0x62>; + status = "okay"; + phandle = <0x6d>; + linux,phandle = <0x6d>; + }; + }; + + port@0 { + status = "okay"; + phandle = <0x12a>; + reg = <0x0>; + linux,phandle = <0x12a>; + + endpoint@0 { + port-index = <0x2>; + remote-endpoint = <0x134>; + status = "okay"; + bus-width = <0x2>; + phandle = <0x30>; + linux,phandle = <0x30>; + }; + }; + }; + }; + + channel@5 { + status = "disabled"; + phandle = <0x15f>; + reg = <0x5>; + linux,phandle = <0x15f>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x162>; + reg = <0x1>; + linux,phandle = <0x162>; + + endpoint@11 { + remote-endpoint = <0x6c>; + status = "disabled"; + phandle = <0x72>; + linux,phandle = <0x72>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x160>; + reg = <0x0>; + linux,phandle = <0x160>; + + endpoint@10 { + port-index = <0x5>; + remote-endpoint = <0x6b>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x39>; + linux,phandle = <0x39>; + }; + }; + }; + }; + + channel@3 { + status = "disabled"; + phandle = <0x14d>; + reg = <0x3>; + linux,phandle = <0x14d>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x150>; + reg = <0x1>; + linux,phandle = <0x150>; + + endpoint@7 { + remote-endpoint = <0x68>; + status = "disabled"; + phandle = <0x70>; + linux,phandle = <0x70>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x14e>; + reg = <0x0>; + linux,phandle = <0x14e>; + + endpoint@6 { + port-index = <0x3>; + remote-endpoint = <0x67>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x37>; + linux,phandle = <0x37>; + }; + }; + }; + }; + + channel@1 { + status = "disabled"; + phandle = <0x12c>; + reg = <0x1>; + linux,phandle = <0x12c>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + status = "disabled"; + phandle = <0x12e>; + reg = <0x1>; + linux,phandle = <0x12e>; + + endpoint@3 { + remote-endpoint = <0x64>; + status = "disabled"; + phandle = <0x6e>; + linux,phandle = <0x6e>; + }; + }; + + port@0 { + status = "disabled"; + phandle = <0x12d>; + reg = <0x0>; + linux,phandle = <0x12d>; + + endpoint@2 { + port-index = <0x0>; + remote-endpoint = <0x63>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x2d>; + linux,phandle = <0x2d>; + }; + }; + }; + }; + }; + + nvjpg@15380000 { + power-domains = <0x1f 0x7>; + compatible = "nvidia,tegra186-nvjpg"; + clocks = <0x10 0x82>; + resets = <0x10 0x7f>; + clock-names = "nvjpg"; + status = "okay"; + interrupts = <0x0 0xc6 0x4>; + iommu-group-id = <0x1>; + reg = <0x0 0x15380000 0x0 0x40000>; + iommus = <0x11 0x8>; + }; + + disp_imp_table { + num_settings = <0x6>; + status = "okay"; + phandle = <0x73>; + linux,phandle = <0x73>; + + disp_imp_settings_4 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0xc5c5e20>; + nvidia,total_disp_bw_without_catchup = <0x0 0x522d80>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0xc28cb00>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0x5a6568>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_2 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0x10d69ba0>; + nvidia,total_disp_bw_without_catchup = <0x0 0x9ab000>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x13d62000>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0xaa2828>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_0 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0x1550d920>; + nvidia,total_disp_bw_without_catchup = <0x0 0xe80800>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x27ac4000>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0xff3bd8>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_5 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0xa1f3f60>; + nvidia,total_disp_bw_without_catchup = <0x0 0x2b8180>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x6146580>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0x2fdb2c>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_3 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0xe997ce0>; + nvidia,total_disp_bw_without_catchup = <0x0 0x740400>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x13d62000>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0x7f9dec>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + disp_imp_settings_1 { + nvidia,win_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_win_fetch_slots = [00 01]; + nvidia,win_fetch_meter_slots = <0x10001 0x10001 0x10001>; + nvidia,disp_min_hubclk = <0x0 0x1313ba60>; + nvidia,total_disp_bw_without_catchup = <0x0 0xc15c00>; + nvidia,imp_head_mapping = [00 01 02]; + nvidia,disp_emc_floor = <0x0 0x1fa97800>; + nvidia,cursor_fetch_meter_slots = [00 01 00 01 00 01]; + nvidia,win_thread_groups = [00 01 02 03 04 05]; + nvidia,win_pipe_meter_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + nvidia,total_disp_bw_with_catchup = <0x0 0xd4b200>; + nvidia,cursor_mempool_buffer_entries = <0x0 0x10 0x0 0x10 0x0 0x10>; + nvidia,imp_win_mapping = [00 01 02 03 04 05]; + nvidia,cursor_pipe_meter_values = <0x0 0x0 0x0>; + nvidia,total_cursor_fetch_slots = [00 01]; + nvidia,win_mempool_buffer_entries = <0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331 0x0 0x331>; + nvidia,cursor_dvfs_watermark_values = <0x0 0x0 0x0 0x0 0x0 0x0>; + }; + }; + + ctx7 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c5>; + iommus = <0x11 0x3f>; + linux,phandle = <0x1c5>; + }; + + nvenc@154c0000 { + power-domains = <0x1f 0x8>; + compatible = "nvidia,tegra186-nvenc"; + clocks = <0x10 0x83>; + resets = <0x10 0x7e>; + clock-names = "nvenc"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x154c0000 0x0 0x40000>; + iommus = <0x11 0x7>; + }; + + se@15820000 { + compatible = "nvidia,tegra186-se2-nvhost"; + clocks = <0x10 0x67>; + resets = <0x10 0x25>; + clock-names = "se"; + supported-algos = "aes", "cmac"; + status = "okay"; + iommu-group-id = <0x1>; + reg = <0x0 0x15820000 0x0 0x10000>; + iommus = <0x11 0xd>; + opcode_addr = <0x404>; + }; + + vic@15340000 { + power-domains = <0x1f 0xc>; + compatible = "nvidia,tegra186-vic"; + clocks = <0x10 0x7f>; + resets = <0x10 0x34>; + clock-names = "vic"; + status = "okay"; + interrupts = <0x0 0xce 0x4>; + iommu-group-id = <0x1>; + reg = <0x0 0x15340000 0x0 0x40000>; + iommus = <0x11 0x3>; + }; + + ctx5 { + compatible = "nvidia,tegra186-iommu-context"; + status = "okay"; + phandle = <0x1c3>; + iommus = <0x11 0x3d>; + linux,phandle = <0x1c3>; + }; + + vi@15700000 { + num-channels = <0x1>; + power-domains = <0x1f 0xb>; + compatible = "nvidia,tegra186-vi"; + clocks = <0x10 0x33 0x10 0xb4 0x10 0xb5>; + avdd_dsi_csi-supply = <0x3c>; + resets = <0x10 0x33 0x10 0x8f>; + clock-names = "vi", "nvcsi", "nvcsilp"; + status = "okay"; + interrupts = <0x0 0xc9 0x4 0x0 0xca 0x4 0x0 0xcb 0x4>; + phandle = <0x5a>; + iommu-group-id = <0x1>; + reg = <0x0 0x15700000 0x0 0x100000>; + iommus = <0x11 0x4>; + reset-names = "vi", "tsctnvi"; + linux,phandle = <0x5a>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@5 { + status = "disabled"; + phandle = <0x15e>; + reg = <0x5>; + linux,phandle = <0x15e>; + + endpoint { + port-index = <0x5>; + remote-endpoint = <0x72>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x6c>; + vc-id = <0x0>; + linux,phandle = <0x6c>; + }; + }; + + port@3 { + status = "disabled"; + phandle = <0x14c>; + reg = <0x3>; + linux,phandle = <0x14c>; + + endpoint { + port-index = <0x3>; + remote-endpoint = <0x70>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x68>; + vc-id = <0x0>; + linux,phandle = <0x68>; + }; + }; + + port@1 { + status = "disabled"; + phandle = <0x127>; + reg = <0x1>; + linux,phandle = <0x127>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x6e>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x64>; + vc-id = <0x0>; + linux,phandle = <0x64>; + }; + }; + + port@4 { + status = "disabled"; + phandle = <0x155>; + reg = <0x4>; + linux,phandle = <0x155>; + + endpoint { + port-index = <0x4>; + remote-endpoint = <0x71>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x6a>; + vc-id = <0x0>; + linux,phandle = <0x6a>; + }; + }; + + port@2 { + status = "disabled"; + phandle = <0x143>; + reg = <0x2>; + linux,phandle = <0x143>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x6f>; + status = "disabled"; + bus-width = <0x2>; + phandle = <0x66>; + vc-id = <0x0>; + linux,phandle = <0x66>; + }; + }; + + port@0 { + status = "okay"; + phandle = <0x126>; + reg = <0x0>; + linux,phandle = <0x126>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x6d>; + status = "okay"; + bus-width = <0x2>; + phandle = <0x62>; + vc-id = <0x0>; + linux,phandle = <0x62>; + }; + }; + }; + }; + + nvdisplay@15200000 { + pinctrl-5 = <0x79>; + nvidia,fb-flags = <0x1>; + compatible = "nvidia,tegra186-dc"; + clocks = <0x10 0x9c 0x10 0x9e 0x10 0x9b 0x10 0x9f 0x10 0xa0 0x10 0x9d 0x10 0x206 0x10 0x207 0x10 0x210 0x10 0x10d 0x10 0x10b 0x10 0x3a>; + pinctrl-3 = <0x77>; + nvidia,cmu-enable = <0x1>; + avdd_dsi_csi-supply = <0x3c>; + vdd_hdmi_5v0-supply = <0x8a>; + resets = <0x10 0x5c 0x10 0x5d 0x10 0x5e 0x10 0x5f 0x10 0x60 0x10 0x61 0x10 0x62 0x10 0x59>; + outn-supply = <0x87>; + vdd_lcd_bl-supply = <0x26>; + pinctrl-1 = <0x75>; + nvidia,dc-connector = <0x83>; + clock-names = "nvdisplay_disp", "nvdisplayhub", "nvdisplay_p0", "nvdisplay_p1", "nvdisplay_p2", "nvdisp_dsc", "pll_d", "plld2", "plld3", "pllp_display", "pll_d_out1", "disp1_emc"; + pinctrl-10 = <0x7e>; + pinctrl-8 = <0x7c>; + outp-supply = <0x86>; + win-mask = <0x7>; + avdd_hdmi-supply = <0x89>; + pinctrl-6 = <0x7a>; + status = "disabled"; + fb_reserved = <0x80>; + interrupts = <0x0 0x99 0x4>; + pinctrl-4 = <0x78>; + phandle = <0x1c6>; + iommu-group-id = <0x1>; + avdd_hdmi_pll-supply = <0x12>; + pinctrl-2 = <0x76>; + dvdd_lcd-supply = <0x85>; + nvidia,dc-flags = <0x1>; + reg = <0x0 0x15200000 0x0 0x10000>; + iommus = <0x11 0x9>; + pinctrl-0 = <0x74>; + iommu-direct-regions = <0x80 0x81 0x82>; + reset-names = "misc", "wgrp0", "wgrp1", "wgrp2", "wgrp3", "wgrp4", "wgrp5", "head0"; + pinctrl-11 = <0x7f>; + nvidia,fb-win = <0x0>; + pinctrl-9 = <0x7d>; + nvidia,emc-rate = <0x11e1a300>; + nvidia,dc-or-node = "/host1x/dsi"; + linux,phandle = <0x1c6>; + nvidia,dc-ctrlnum = <0x0>; + vdd_lcd_bl_en-supply = <0x88>; + pinctrl-7 = <0x7b>; + pinctrl-names = "dsi-dpd-disable", "dsi-dpd-enable", "dsib-dpd-disable", "dsib-dpd-enable", "dsic-dpd-disable", "dsic-dpd-enable", "dsid-dpd-disable", "dsid-dpd-enable", "hdmi-dp0-dpd-disable", "hdmi-dp0-dpd-enable", "hdmi-dp1-dpd-disable", "hdmi-dp1-dpd-enable"; + nvidia,fb-bpp = <0x20>; + avdd_lcd-supply = <0x84>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + status = "okay"; + interrupts = <0x1 0xd 0x3f08 0x1 0xe 0x3f08 0x1 0xb 0x3f08 0x1 0xa 0x3f08>; + }; + + i2c@31b0000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x7d 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x18>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1e 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x8f>; + reg = <0x0 0x31b0000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x186a0>; + dmas = <0x25 0x1e 0x25 0x1e>; + reset-names = "i2c"; + linux,phandle = <0x8f>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + axi2apb@23d0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23d0000 0x0 0x1000>; + }; + + gpio@2200000 { + compatible = "nvidia,tegra186-gpio"; + reg-names = "security", "gpio"; + gpio-controller; + gpio-ranges = <0xb7 0x0 0x0 0x90 0xb7 0x90 0x98 0x8 0xb7 0x98 0xb8 0x10 0xb7 0xa8 0xd8 0x18>; + status = "okay"; + #interrupt-cells = <0x2>; + interrupts = <0x0 0x2f 0x4 0x0 0x32 0x4 0x0 0x35 0x4 0x0 0x38 0x4 0x0 0x3b 0x4 0x0 0xb4 0x4>; + phandle = <0x1b>; + reg = <0x0 0x2200000 0x0 0x10000 0x0 0x2210000 0x0 0x10000>; + #gpio-cells = <0x2>; + linux,phandle = <0x1b>; + interrupt-controller; + + camera-control-output-high { + gpios = <0x8d 0x0>; + gpio-hog; + status = "disabled"; + label = "cam0-rst"; + output-high; + }; + + wifi_over_pcie { + gpios = <0x8c 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "wifi-over-pcie"; + }; + + sdmmc-wake-support-input { + gpios = <0x7d 0x0>; + gpio-hog; + status = "okay"; + label = "sdmmc-wake-input"; + input; + }; + + wifi-wake-ap { + gpio-hog; + status = "disabled"; + label = "wifi-wake-ap"; + input; + }; + + e3325_sdio_rst { + gpios = <0xe 0x0>; + gpio-hog; + status = "disabled"; + label = "e3325-sdio-rst"; + output-high; + }; + + wifi-enable { + gpios = <0x68 0x0>; + gpio-hog; + line-name = "wifi-enable"; + output-high; + }; + + camera-control-output-low { + gpios = <0x8d 0x0 0x88 0x0 0x89 0x0 0x6a 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "cam0-rst", "cam0-pwdn", "cam1-rst", "cam1-pwdn"; + }; + + e3325_lane0_mux { + gpios = <0xc 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "e3325-lane0-mux"; + }; + + pcie0_lane2_mux { + gpios = <0x8b 0x0>; + output-low; + gpio-hog; + status = "disabled"; + label = "pcie-lane2-mux"; + }; + + sdmmc-wake-support-output { + gpios = <0x7e 0x0>; + output-low; + gpio-hog; + status = "okay"; + label = "sdmmc-wake-output"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + + memory@90000000 { + device_type = "memory"; + reg = <0x0 0x90000000 0x0 0x60000000 0x0 0xf0200000 0x1 0x0>; + }; + + axip2p@2150000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2150000 0x0 0x1000>; + }; + + sce-ivc-channels { + phandle = <0x57>; + linux,phandle = <0x57>; + + ivccontrol@52c0 { + nvidia,frame-size = <0x140>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture-control"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture-control"; + }; + + ivccapture@72c0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture"; + }; + + dbg@7c00 { + nvidia,frame-size = <0x180>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-dbg"; + nvidia,service = "debug"; + }; + + echo@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-echo"; + nvidia,service = "echo"; + }; + + dbg@7e00 { + nvidia,frame-size = <0x2000>; + compatible = "nvidia,tegra186-camera-ivc-protocol-debug"; + nvidia,ivc-timeout = <0x32>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,test-timeout = <0x1388>; + nvidia,service = "debug"; + }; + + mods@32c0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-camera-ivc-protocol-mods"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,service = "mods"; + }; + + i2c@480 { + nvidia,frame-size = <0x80>; + compatible = "nvidia,tegra186-camera-ivc-rpc-i2c-single"; + device = <0x59>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x8>; + status = "okay"; + nvidia,version = <0x0>; + nvidia,service = "i2c-single"; + }; + + vinotify@12c0 { + nvidia,frame-size = <0x80>; + compatible = "nvidia,tegra186-camera-ivc-protocol-vinotify"; + device = <0x5a>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x40>; + nvidia,version = <0x0>; + nvidia,service = "vinotify"; + }; + }; + + serial@3130000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0x4d 0x10 0x10d>; + resets = <0x10 0x32>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "NILL"; + interrupts = <0x0 0x73 0x4>; + dma-names = "tx"; + phandle = <0x18f>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3130000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x13 0x25 0x13>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x18f>; + }; + + axip2p@2190000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2190000 0x0 0x1000>; + }; + + se_elp@3ad0000 { + compatible = "nvidia,tegra186-se-elp"; + clocks = <0x10 0x67>; + clock-names = "se"; + status = "okay"; + interrupts = <0x0 0x11b 0x4>; + phandle = <0x1d4>; + reg = <0x0 0x3ad0000 0x0 0x10000 0x0 0x3ae0000 0x0 0x10000>; + linux,phandle = <0x1d4>; + pka1-rsa-priority = <0x12c>; + }; + + gpio@c2f0000 { + compatible = "nvidia,tegra186-gpio-aon"; + reg-names = "security", "gpio"; + gpio-controller; + gpio-ranges = <0xb7 0x0 0x90 0x8 0xb7 0x8 0xa0 0x18 0xb7 0x20 0xc8 0x10 0xb7 0x30 0xf0 0x10>; + status = "okay"; + #interrupt-cells = <0x2>; + interrupts = <0x0 0x3c 0x4>; + phandle = <0x28>; + reg = <0x0 0xc2f0000 0x0 0x1000 0x0 0xc2f1000 0x0 0x1000>; + #gpio-cells = <0x2>; + linux,phandle = <0x28>; + interrupt-controller; + + camera-control-output-high { + status = "disabled"; + }; + + wifi-wake-ap { + gpios = <0x3b 0x0>; + gpio-hog; + label = "wifi-wake-ap"; + input; + }; + + camera-control-output-low { + status = "disabled"; + }; + + camera-control-input { + status = "disabled"; + }; + }; + + mttcan0-ivc { + compatible = "bosch,mttcan-ivc"; + status = "disabled"; + mboxes = <0x41 0x3>; + }; + + i2c@3180000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0x4b 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x15>; + scl-gpio = <0x1b 0x72 0x0>; + sda-gpio = <0x1b 0x73 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1b 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x59>; + reg = <0x0 0x3180000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x17 0x25 0x17>; + reset-names = "i2c"; + linux,phandle = <0x59>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + + tca9548@77 { + force_bus_start = <0x1e>; + compatible = "nxp,pca9548"; + skip_mux_detect; + status = "disabled"; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2b>; + phandle = <0x13b>; + reg = <0x77>; + linux,phandle = <0x13b>; + + i2c@0 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0>; + + imx219_a@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x59>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1"; + dovdd-supply = <0x2b>; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x0 0x0>; + phandle = <0x163>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x163>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x164>; + linux,phandle = <0x164>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_a@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x13c>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x88 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x13c>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x13d>; + linux,phandle = <0x13d>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + i2c@5 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x5>; + + imx219_f@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x5a>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video5"; + avdd-reg = "vana"; + clock-names = "extperiph2"; + dovdd-supply = <0x2b>; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x5 0x0>; + phandle = <0x16a>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x16a>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x5>; + remote-endpoint = <0x39>; + bus-width = <0x2>; + phandle = <0x6b>; + linux,phandle = <0x6b>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_f@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video5"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x7 0x0>; + phandle = <0x15a>; + reg = <0x36>; + pwdn-gpios = <0x35 0x6 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x15a>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x5>; + remote-endpoint = <0x39>; + bus-width = <0x2>; + phandle = <0x161>; + linux,phandle = <0x161>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_f"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + i2c@3 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x3>; + + imx219_d@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x5a>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video3"; + avdd-reg = "vana"; + clock-names = "extperiph2"; + dovdd-supply = <0x2b>; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x3 0x0>; + phandle = <0x168>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x168>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x3>; + remote-endpoint = <0x37>; + bus-width = <0x2>; + phandle = <0x67>; + linux,phandle = <0x67>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_d@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video3"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x3 0x0>; + phandle = <0x148>; + reg = <0x36>; + pwdn-gpios = <0x35 0x2 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x148>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x3>; + remote-endpoint = <0x37>; + bus-width = <0x2>; + phandle = <0x14f>; + linux,phandle = <0x14f>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_d"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + i2c@1 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x1>; + + ov5693_b@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x89 0x0>; + phandle = <0x13a>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x6a 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x13a>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x1>; + remote-endpoint = <0x2d>; + bus-width = <0x2>; + phandle = <0x13e>; + linux,phandle = <0x13e>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + + imx219_b@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x59>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph1"; + dovdd-supply = <0x2b>; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x1 0x0>; + phandle = <0x165>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x165>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x1>; + remote-endpoint = <0x2d>; + bus-width = <0x2>; + phandle = <0x166>; + linux,phandle = <0x166>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_b"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + }; + + i2c@4 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x4>; + + ov5693_e@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x5a 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video4"; + avdd-reg = "vana"; + clock-names = "extperiph2", "pllp_grtba"; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x5 0x0>; + phandle = <0x151>; + reg = <0x36>; + pwdn-gpios = <0x35 0x4 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x151>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x4>; + remote-endpoint = <0x38>; + bus-width = <0x2>; + phandle = <0x158>; + linux,phandle = <0x158>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + + imx219_e@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x5a>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video4"; + avdd-reg = "vana"; + clock-names = "extperiph2"; + dovdd-supply = <0x2b>; + mclk = "extperiph2"; + status = "disabled"; + reset-gpios = <0x35 0x4 0x0>; + phandle = <0x169>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x169>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x4>; + remote-endpoint = <0x38>; + bus-width = <0x2>; + phandle = <0x69>; + linux,phandle = <0x69>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_e"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + }; + + i2c@2 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x2>; + + imx219_c@10 { + compatible = "nvidia,imx219"; + clocks = <0x10 0x59>; + sensor_model = "imx219"; + physical_w = "5.095"; + iovdd-reg = "dovdd"; + vdig-supply = <0x2a>; + devnode = "video2"; + avdd-reg = "vana"; + clock-names = "extperiph1"; + dovdd-supply = <0x2b>; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x2 0x0>; + phandle = <0x167>; + reg = <0x10>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x167>; + physical_h = "4.930"; + + mode0 { + default_framerate = "21000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "224000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1462526"; + default_exp_time = "2495"; + max_framerate = "21000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "2464"; + max_exp_time = "683709"; + mclk_multiplier = "18.67"; + min_exp_time = "13"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x36>; + bus-width = <0x2>; + phandle = <0x65>; + linux,phandle = <0x65>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode1 { + default_framerate = "28000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "3264"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "28000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1848"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode4 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1280"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "169600000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "3448"; + active_w = "1920"; + embedded_metadata_height = [32 00]; + pixel_phase = "rggb"; + pix_clk_hz = "182400000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "170"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "2000000"; + default_exp_time = "2495"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "683709"; + mclk_multiplier = "9.33"; + min_exp_time = "13"; + }; + }; + + ov5693_c@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video2"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x35 0x1 0x0>; + phandle = <0x13f>; + reg = <0x36>; + pwdn-gpios = <0x35 0x0 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + linux,phandle = <0x13f>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x36>; + bus-width = <0x2>; + phandle = <0x146>; + linux,phandle = <0x146>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + }; + + ov23850_a@10 { + compatible = "nvidia,ov23850"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "7.3998"; + iovdd-reg = "vif"; + vcmvdd-reg = "vvcm"; + vdig-supply = <0x2a>; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x135>; + reg = <0x10>; + pwdn-gpios = <0x1b 0x88 0x0>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x135>; + vif-supply = <0x2b>; + physical_h = "5.5998"; + vvcm-suply = <0x2c>; + + mode0 { + line_length = "5922"; + active_w = "5632"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "600000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "15.5"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = "270"; + min_gain_val = "1.0"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + csi_pixel_bit_depth = "10"; + min_framerate = "3.09135"; + max_framerate = "30"; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + active_h = "3168"; + max_exp_time = "323094"; + mclk_multiplier = "25"; + min_exp_time = "19.74"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x4>; + phandle = <0x138>; + linux,phandle = <0x138>; + }; + }; + }; + }; + + tca6408@21 { + compatible = "ti,tca6408"; + gpio-controller; + status = "disabled"; + vcc-supply = <0x2b>; + phandle = <0x35>; + reg = <0x21>; + #gpio-cells = <0x2>; + linux,phandle = <0x35>; + + tca6408_21_input { + gpios = <0x6 0x0 0x7 0x0>; + gpio-hog; + status = "disabled"; + label = "tca6408_21_input_6", "tca6408_21_input_7"; + input; + }; + + tca6408_21_outlow { + gpios = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0>; + output-low; + gpio-hog; + label = "tca6408_21_outlow_0", "tca6408_21_outlow_1", "tca6408_21_outlow_2", "tca6408_21_outlow_3", "tca6408_21_outlow_4", "tca6408_21_outlow_5"; + }; + + tca6408_21_outhigh { + status = "disabled"; + }; + }; + + tca9546@70 { + force_bus_start = <0x1e>; + compatible = "nxp,pca9546"; + vcc_lp = "vcc"; + skip_mux_detect = "yes"; + status = "disabled"; + #address-cells = <0x1>; + #size-cells = <0x0>; + vcc-supply = <0x2b>; + phandle = <0x130>; + reg = <0x70>; + linux,phandle = <0x130>; + vif-supply = <0x2b>; + + i2c@0 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0>; + + imx390_a@1b { + post_crop_frame_drop = [30 00]; + compatible = "nvidia,imx390"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx390"; + physical_w = "15.0"; + use_decibel_gain = "true"; + clock-names = "extperiph1", "pllp_grtba"; + def-addr = <0x1a>; + nvidia,gmsl-dser-device = <0x32>; + mclk = "extperiph1"; + nvidia,gmsl-ser-device = <0x31>; + status = "disabled"; + use_sensor_mode_id = "true"; + phandle = <0x120>; + reg = <0x1b>; + linux,phandle = <0x120>; + physical_h = "12.5"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2200"; + active_w = "1920"; + embedded_metadata_height = [30 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "300"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "30000000"; + default_exp_time = "33333"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + mclk_khz = "24000"; + vc_id = [30 00]; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + serdes_pix_clk_hz = "833333333"; + max_exp_time = "33333"; + min_exp_time = "59"; + }; + + gmsl-link { + streams = "ued-u1", "raw12"; + csi-mode = "1x4"; + num-lanes = <0x2>; + st-vc = <0x0>; + src-csi-port = [62 00]; + serdes-csi-link = [61 00]; + vc-id = <0x0>; + dst-csi-port = [61 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x61>; + vc-id = <0x0>; + linux,phandle = <0x61>; + }; + }; + }; + }; + + max9295_b@60 { + compatible = "nvidia,max9295"; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + phandle = <0x33>; + reg = <0x60>; + linux,phandle = <0x33>; + }; + + imx390_b@1c { + post_crop_frame_drop = [30 00]; + compatible = "nvidia,imx390"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx390"; + physical_w = "15.0"; + use_decibel_gain = "true"; + clock-names = "extperiph1", "pllp_grtba"; + def-addr = <0x1a>; + nvidia,gmsl-dser-device = <0x32>; + mclk = "extperiph1"; + nvidia,gmsl-ser-device = <0x33>; + status = "disabled"; + use_sensor_mode_id = "true"; + phandle = <0x123>; + reg = <0x1c>; + linux,phandle = <0x123>; + physical_h = "12.5"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "4400"; + active_w = "1920"; + embedded_metadata_height = [30 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "300"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "30000000"; + default_exp_time = "33333"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + mclk_khz = "24000"; + vc_id = [31 00]; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + serdes_pix_clk_hz = "833333333"; + max_exp_time = "33333"; + min_exp_time = "59"; + }; + + gmsl-link { + streams = "ued-u1", "raw12"; + csi-mode = "1x4"; + num-lanes = <0x2>; + st-vc = <0x0>; + src-csi-port = [62 00]; + serdes-csi-link = [62 00]; + vc-id = <0x1>; + dst-csi-port = [61 00]; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x2d>; + bus-width = <0x2>; + phandle = <0x63>; + vc-id = <0x1>; + linux,phandle = <0x63>; + }; + }; + }; + }; + + imx318_a@10 { + compatible = "nvidia,imx318"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx318"; + has-eeprom; + physical_w = "6.811"; + iovdd-reg = "vif"; + vdig-supply = <0x2a>; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x172>; + reg = <0x10>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + dvdd-reg = "vdig"; + linux,phandle = <0x172>; + vif-supply = <0x2b>; + physical_h = "5.254"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "5488"; + active_w = "5488"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "750000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [33 00]; + inherent_gain = [31 00]; + max_gain_val = "256"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = "16"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "16"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "CPHY"; + mclk_khz = "24000"; + cil_settletime = "20"; + gain_factor = "16"; + framerate_factor = "1000000"; + active_h = "4112"; + max_exp_time = "550385"; + mclk_multiplier = "31.25"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x3>; + phandle = <0x173>; + linux,phandle = <0x173>; + }; + }; + }; + }; + + imx274_a@1a { + compatible = "nvidia,imx274"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx274"; + has-eeprom; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + delayed_gain = "true"; + reset-gpios = <0x1b 0x8d 0x0>; + fuse_id_start_addr = <0x5b>; + phandle = <0x16e>; + reg = <0x1a>; + vana-supply = <0x29>; + linux,phandle = <0x16e>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3840"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "44400000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "2160"; + max_exp_time = "478696"; + mclk_multiplier = "24"; + min_exp_time = "44"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x4>; + phandle = <0x16f>; + linux,phandle = <0x16f>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1936"; + num_of_left_margin_pixels = [36 00]; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "38"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "15649"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [36 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "2264"; + max_exp_time = "15649"; + mclk_multiplier = "24"; + min_exp_time = "859"; + }; + + mode1 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "184611"; + mclk_multiplier = "24"; + min_exp_time = "58"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3856"; + num_of_left_margin_pixels = "12"; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "50"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "30000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_a"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "20480"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [30 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "4448"; + max_exp_time = "20480"; + mclk_multiplier = "24"; + min_exp_time = "864"; + }; + }; + + max9296@48 { + compatible = "nvidia,max9296"; + csi-mode = "2x4"; + vdd_cam_1v2-supply = <0x34>; + max-src = <0x2>; + status = "disabled"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x32>; + reg = <0x48>; + linux,phandle = <0x32>; + }; + + max9295_prim@62 { + compatible = "nvidia,max9295"; + is-prim-ser; + status = "disabled"; + phandle = <0x131>; + reg = <0x62>; + linux,phandle = <0x131>; + }; + + max9295_a@40 { + compatible = "nvidia,max9295"; + nvidia,gmsl-dser-device = <0x32>; + status = "disabled"; + phandle = <0x31>; + reg = <0x40>; + linux,phandle = <0x31>; + }; + + pca9570_a@24 { + compatible = "nvidia,pca9570"; + channel = [61 00]; + drive_ic = "DRV8838"; + status = "disabled"; + phandle = <0x16d>; + reg = <0x24>; + linux,phandle = <0x16d>; + }; + + imx185_a@1a { + post_crop_frame_drop = [30 00]; + compatible = "nvidia,imx185"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx185"; + physical_w = "15.0"; + use_decibel_gain = "true"; + devnode = "video0"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + delayed_gain = "true"; + reset-gpios = <0x1b 0x8d 0x0>; + use_sensor_mode_id = "true"; + phandle = <0x16b>; + reg = <0x1a>; + linux,phandle = <0x16b>; + physical_h = "12.5"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2200"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = [32 00]; + min_exp_time = "30"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x0>; + remote-endpoint = <0x30>; + bus-width = <0x4>; + phandle = <0x16c>; + linux,phandle = <0x16c>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "2640"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "178200000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = "4.8"; + min_exp_time = "30"; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2640"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "89100000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = "2.4"; + min_exp_time = "30"; + }; + + mode4 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2200"; + control_point_y_0 = [30 00]; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "74250000"; + dynamic_pixel_bit_depth = "16"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_pwl"; + control_point_x_2 = "16384"; + num_lanes = [34 00]; + control_point_x_0 = [30 00]; + inherent_gain = [31 00]; + max_gain_val = "120"; + control_point_y_3 = "3712"; + min_hdr_ratio = "16"; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = "16"; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + control_point_y_1 = "2048"; + min_framerate = "1500000"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + control_point_x_3 = "65536"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + control_point_x_1 = "2048"; + num_control_point = [34 00]; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = [32 00]; + control_point_y_2 = "2944"; + min_exp_time = "2433"; + }; + + mode2 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "2200"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "148500000"; + dynamic_pixel_bit_depth = "12"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "480"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "no"; + readout_orientation = [30 00]; + min_gain_val = [30 00]; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_a"; + step_gain_val = [33 00]; + default_gain = [30 00]; + csi_pixel_bit_depth = "12"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "37125"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "660000"; + mclk_multiplier = [34 00]; + min_exp_time = "30"; + }; + }; + }; + + i2c@1 { + i2c-mux,deselect-on-exit; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x1>; + + imx274_c@1a { + compatible = "nvidia,imx274"; + clocks = <0x10 0x59 0x10 0x10d>; + sensor_model = "imx274"; + has-eeprom; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video1"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "disabled"; + delayed_gain = "true"; + reset-gpios = <0x1b 0x88 0x0>; + fuse_id_start_addr = <0x63>; + phandle = <0x170>; + reg = <0x1a>; + vana-supply = <0x29>; + linux,phandle = <0x170>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3840"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "44400000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "2160"; + max_exp_time = "478696"; + mclk_multiplier = "24"; + min_exp_time = "44"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x2d>; + bus-width = <0x4>; + phandle = <0x171>; + linux,phandle = <0x171>; + }; + }; + }; + + mode3 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1936"; + num_of_left_margin_pixels = [36 00]; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "38"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "15649"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [36 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "2264"; + max_exp_time = "15649"; + mclk_multiplier = "24"; + min_exp_time = "859"; + }; + + mode1 { + default_framerate = "60000000"; + step_exp_time = [31 00]; + line_length = "4160"; + active_w = "1920"; + embedded_metadata_height = [31 00]; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "177000000"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "16667"; + max_framerate = "60000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "1000000"; + framerate_factor = "1000000"; + active_h = "1080"; + max_exp_time = "184611"; + mclk_multiplier = "24"; + min_exp_time = "58"; + }; + + mode2 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "4208"; + active_w = "3856"; + num_of_left_margin_pixels = "12"; + embedded_metadata_height = [31 00]; + num_of_lines_offset_0 = "50"; + pixel_phase = "rggb"; + pix_clk_hz = "576000000"; + dynamic_pixel_bit_depth = "10"; + dpcm_enable = "false"; + mode_type = "bayer_wdr_dol"; + num_of_exposure = [32 00]; + num_lanes = [34 00]; + inherent_gain = [31 00]; + max_gain_val = "30000000"; + min_hdr_ratio = "32"; + discontinuous_clk = "yes"; + readout_orientation = [30 00]; + min_gain_val = "1000000"; + max_hdr_ratio = "32"; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "1000000"; + csi_pixel_bit_depth = "10"; + min_framerate = "1500000"; + default_exp_time = "20480"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + num_of_right_margin_pixels = [30 00]; + mclk_khz = "24000"; + cil_settletime = [30 00]; + num_of_ignored_lines = "14"; + gain_factor = "1000000"; + framerate_factor = "1000000"; + num_of_ignored_pixels = [34 00]; + active_h = "4448"; + max_exp_time = "20480"; + mclk_multiplier = "24"; + min_exp_time = "864"; + }; + }; + }; + }; + + ov5693_c@36 { + compatible = "nvidia,ov5693"; + clocks = <0x10 0x59 0x10 0x10d>; + physical_w = "3.674"; + iovdd-reg = "vif"; + devnode = "video0"; + avdd-reg = "vana"; + clock-names = "extperiph1", "pllp_grtba"; + mclk = "extperiph1"; + status = "okay"; + reset-gpios = <0x1b 0x8d 0x0>; + phandle = <0x132>; + reg = <0x36>; + pwdn-gpios = <0x1b 0x88 0x0>; + clock-frequency = <0x16e3600>; + vana-supply = <0x29>; + vertical-flip = "true"; + linux,phandle = <0x132>; + vif-supply = <0x2b>; + physical_h = "2.738"; + + mode0 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1944"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0x0>; + + endpoint { + port-index = <0x2>; + remote-endpoint = <0x30>; + bus-width = <0x2>; + phandle = <0x134>; + linux,phandle = <0x134>; + }; + }; + }; + + mode1 { + default_framerate = "30000000"; + step_exp_time = [31 00]; + line_length = "2688"; + active_w = "2592"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "1816577"; + default_exp_time = "33334"; + max_framerate = "30000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "1458"; + max_exp_time = "550385"; + mclk_multiplier = "6.67"; + min_exp_time = "34"; + }; + + mode2 { + default_framerate = "120000000"; + step_exp_time = [31 00]; + line_length = "1752"; + active_w = "1280"; + embedded_metadata_height = [30 00]; + pixel_phase = "bggr"; + pix_clk_hz = "160000000"; + dpcm_enable = "false"; + mode_type = "bayer"; + num_lanes = [32 00]; + inherent_gain = [31 00]; + max_gain_val = "160"; + min_hdr_ratio = [31 00]; + discontinuous_clk = "yes"; + readout_orientation = "90"; + min_gain_val = "10"; + max_hdr_ratio = [31 00]; + tegra_sinterface = "serial_c"; + step_gain_val = [31 00]; + default_gain = "10"; + csi_pixel_bit_depth = "10"; + min_framerate = "2787078"; + default_exp_time = "8334"; + max_framerate = "120000000"; + exposure_factor = "1000000"; + step_framerate = [31 00]; + phy_mode = "DPHY"; + mclk_khz = "24000"; + cil_settletime = [30 00]; + gain_factor = "10"; + framerate_factor = "1000000"; + active_h = "720"; + max_exp_time = "358733"; + mclk_multiplier = "6.67"; + min_exp_time = "22"; + }; + }; + }; + + thermal-fan-est { + compatible = "thermal-fan-est"; + active_hysteresis = <0x0 0x3a98 0x2328 0x2328 0x2710 0x0 0x0 0x0 0x0 0x0>; + num_resources = <0x0>; + shared_data = <0xef>; + active_trip_temps = <0x0 0xc738 0xee48 0x11558 0x14050 0x222e0 0x249f0 0x27100 0x29810 0x2bf20>; + trip_length = <0xa>; + }; + + smmu_test { + compatible = "nvidia,smmu_test"; + phandle = <0x1cd>; + iommus = <0x11 0x33>; + linux,phandle = <0x1cd>; + }; + + efuse@3820000 { + compatible = "nvidia,tegra186-efuse", "nvidia,tegra210-efuse"; + clocks = <0x10 0x0>; + clock-names = "fuse"; + status = "okay"; + reg = <0x0 0x3820000 0x0 0x600>; + nvidia,clock-always-on; + + efuse-burn { + compatible = "nvidia,tegra186-efuse-burn"; + clocks = <0x10 0x261>; + clock-names = "clk_m"; + nvidia,tz = <0xe7>; + status = "okay"; + nvidia,temp-range = <0xfa0 0x18a88>; + }; + }; + + sound { + assigned-clock-parents = <0x10 0x10f 0x10 0xf6>; + compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x"; + clocks = <0x10 0x10f 0x10 0xf6 0x10 0x7c>; + resets = <0x10 0x92>; + nvidia,num-codec-link = <0xc>; + dma-mask = <0x0 0x5e000000>; + nvidia,model = "tegra-snd-t186ref-mobile-rt565x"; + clock-names = "pll_a", "pll_a_out0", "extern1"; + nvidia,xbar = <0xb8>; + status = "okay"; + assigned-clocks = <0x10 0xf6 0x10 0x7c>; + phandle = <0x114>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + nvidia,audio-routing = "x Headphone", "x OUT", "x IN", "x Mic", "y Headphone", "y OUT", "y IN", "y Mic", "z Headphone", "z OUT", "z IN", "z Mic", "m Headphone", "m OUT", "m IN", "m Mic", "n Headphone", "n OUT", "n IN", "n Mic", "o Headphone", "o OUT", "o IN", "o Mic", "a IN", "a Mic", "b IN", "b Mic", "c IN", "c Mic", "d IN", "d Mic", "d1 Headphone", "d1 OUT", "d3 Headphone", "d3 OUT"; + mclk-fs = <0x100>; + iommus = <0x11 0x1e>; + reset-names = "extern1_rst"; + linux,phandle = <0x114>; + + nvidia,dai-link-8 { + cpu-dai-name = "DMIC2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc8>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [62 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc7>; + format = "i2s"; + link-name = "spdif-dit-8"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-6 { + cpu-dai-name = "I2S6"; + ignore_suspend; + num-channel = <0x1>; + codec-dai = <0xc4>; + srate = <0x1f40>; + tx-mask = <0xff>; + status = "okay"; + name-prefix = [6f 00]; + bitclock-inversion; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc3>; + rx-mask = <0xff>; + format = "dsp_a"; + link-name = "spdif-dit-6"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-13 { + cpu-dai-name = "DSPK2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xd1>; + srate = <0xbb80>; + status = "okay"; + name-prefix = "d2"; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcf>; + phandle = <0x118>; + format = "i2s"; + linux,phandle = <0x118>; + link-name = "dspk-playback-r"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-4 { + cpu-dai-name = "I2S4"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc0>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [6d 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xbf>; + format = "i2s"; + link-name = "spdif-dit-3"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-11 { + cpu-dai-name = "DSPK1"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xce>; + srate = <0xbb80>; + status = "okay"; + name-prefix = "d3"; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcd>; + format = "i2s"; + link-name = "dspk1-playback"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-2 { + cpu-dai-name = "I2S2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xbc>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [79 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xbb>; + format = "i2s"; + link-name = "spdif-dit-1"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-9 { + cpu-dai-name = "DMIC3"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xca>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [63 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc9>; + format = "i2s"; + link-name = "spdif-dit-9"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-7 { + cpu-dai-name = "DMIC1"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc6>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [61 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc5>; + format = "i2s"; + link-name = "spdif-dit-7"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-5 { + cpu-dai-name = "I2S5"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xc2>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [6e 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xc1>; + format = "i2s"; + link-name = "spdif-dit-4"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-12 { + cpu-dai-name = "DSPK2"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xd0>; + srate = <0xbb80>; + status = "okay"; + name-prefix = "d1"; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcf>; + phandle = <0x116>; + format = "i2s"; + linux,phandle = <0x116>; + link-name = "dspk-playback-l"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-3 { + cpu-dai-name = "I2S3"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xbe>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [7a 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xbd>; + format = "i2s"; + link-name = "spdif-dit-2"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-10 { + cpu-dai-name = "DMIC4"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xcc>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [64 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xcb>; + format = "i2s"; + link-name = "spdif-dit-10"; + bit-format = "s16_le"; + }; + + nvidia,dai-link-1 { + cpu-dai-name = "I2S1"; + ignore_suspend; + num-channel = <0x2>; + codec-dai = <0xba>; + srate = <0xbb80>; + status = "okay"; + name-prefix = [78 00]; + codec-dai-name = "dit-hifi"; + cpu-dai = <0xb9>; + phandle = <0x115>; + format = "i2s"; + linux,phandle = <0x115>; + link-name = "spdif-dit-0"; + bit-format = "s16_le"; + }; + }; + + interrupt-controller@3000000 { + compatible = "nvidia,tegra-gic"; + status = "disabled"; + phandle = <0x1d3>; + reg = <0x0 0x3000000 0x0 0x800 0x0 0x3000800 0x0 0x800 0x0 0x3001000 0x0 0x800 0x0 0x3001800 0x0 0x800 0x0 0x3002000 0x0 0x800 0x0 0x3002800 0x0 0x800 0x0 0x3003000 0x0 0x800 0x0 0x3003800 0x0 0x800 0x0 0x300f800 0x0 0x800>; + linux,phandle = <0x1d3>; + interrupt-controller; + }; + + tegra-virtual-camera-platform { + isp_bw_margin_pct = <0x19>; + isp_peak_byte_per_pixel = <0x5>; + + modules { + + module0 { + badge = "vivid_front_instance0"; + position = "front"; + orientation = [31 00]; + + drivernode0 { + devname = "tegra-vivid-000"; + pcl_id = "v4l2_sensor_virtual"; + proc-device-tree = "/proc/device-tree/vivid-driver/instances/instance0"; + }; + }; + }; + }; + + mc { + compatible = "nvidia,tegra-t18x-mc"; + ecc_int_mask = <0x1c00>; + int_mask = <0xf3140>; + status = "okay"; + interrupts = <0x0 0xdf 0x4 0x0 0xe0 0x4>; + reg-ranges = <0x1>; + reg = <0x0 0x2c10000 0x0 0x10000 0x0 0x2c20000 0x0 0x10000 0x0 0x2c30000 0x0 0x10000 0x0 0x2c40000 0x0 0x10000 0x0 0x2c50000 0x0 0x10000 0x0 0x2c60000 0x0 0x10000 0x0 0x2c70000 0x0 0x10000 0x0 0x2c80000 0x0 0x10000 0x0 0x2c90000 0x0 0x10000 0x0 0x2ca0000 0x0 0x10000>; + channels = <0x4>; + }; + + serial@c290000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xd8 0x10 0x10d>; + resets = <0x10 0x70>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "disabled"; + interrupts = <0x0 0x76 0x4>; + dma-names = "rx", "tx"; + phandle = <0x192>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0xc290000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x2 0x25 0x2>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x192>; + }; + + dummy-cool-dev { + compatible = "dummy-cooling-dev"; + status = "disabled"; + phandle = <0x1e4>; + #cooling-cells = <0x2>; + linux,phandle = <0x1e4>; + }; + + tachometer@39c0000 { + pulse-per-rev = <0x2>; + compatible = "nvidia,pwm-tegra186-tachometer"; + clocks = <0x10 0xa6>; + resets = <0x10 0x6d>; + clock-names = "tach"; + capture-window-length = <0x8>; + status = "okay"; + phandle = <0xb2>; + reg = <0x0 0x39c0000 0x0 0x10>; + reset-names = "tach"; + linux,phandle = <0xb2>; + #pwm-cells = <0x2>; + }; + + etr@8050000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8050000 0x0 0x1000>; + + port { + + endpoint@0 { + remote-endpoint = <0xe4>; + phandle = <0xde>; + slave-mode; + linux,phandle = <0xde>; + }; + }; + }; + + clock@5000000 { + compatible = "nvidia,tegra18x-car"; + #reset-cells = <0x1>; + status = "okay"; + #clock-cells = <0x1>; + phandle = <0x10>; + reg = <0x0 0x5000000 0x0 0x1000000>; + linux,phandle = <0x10>; + }; + + trusty { + compatible = "android,trusty-smc-v1"; + ranges; + status = "NILL"; + #address-cells = <0x2>; + #size-cells = <0x2>; + + fiq { + compatible = "android,trusty-fiq-v1"; + }; + + log { + compatible = "android,trusty-log-v1"; + }; + + irq { + interrupt-ranges = <0x0 0xf 0x0 0x10 0x1f 0x1 0x20 0x1ae 0x2>; + compatible = "android,trusty-irq-v1"; + interrupt-templates = <0x46 0x0 0x1 0x1 0x1 0x0 0x1 0x1 0x0 0x0>; + }; + + virtio { + compatible = "android,trusty-virtio-v1"; + }; + + ote { + compatible = "android,trusty-ote-v1"; + }; + }; + + tegra-hsp@b150000 { + compatible = "nvidia,tegra186-hsp"; + resets = <0x10 0xba>; + status = "okay"; + interrupts = <0x0 0x8d 0x4 0x0 0x8e 0x4 0x0 0x8f 0x4 0x0 0x90 0x4>; + phandle = <0x58>; + reg = <0x0 0xb150000 0x0 0x90000>; + reset-names = "hsp"; + linux,phandle = <0x58>; + interrupt-names = "shared1", "shared2", "shared3", "shared4"; + }; + + funnel_minor@8820000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8820000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@2 { + reg = <0x2>; + + endpoint { + remote-endpoint = <0xe6>; + phandle = <0xd4>; + slave-mode; + linux,phandle = <0xd4>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xe5>; + phandle = <0xdc>; + linux,phandle = <0xdc>; + }; + }; + }; + }; + + rtcpu@b000000 { + nvidia,nb-channels = <0x2>; + compatible = "nvidia,tegra186-sce-ivc"; + clocks = <0x10 0xe6 0x10 0xe4>; + resets = <0x10 0xbb 0x10 0xb8 0x10 0xb5 0x10 0xb6 0x10 0xb7 0x10 0xb9 0x10 0xbc 0x10 0xbd 0x10 0xbe 0x10 0xb4 0x10 0xb3>; + nvidia,clock-rates = <0x6146580 0x6146580 0x6ddd000 0x1c3a9000>; + reg-names = "sce-evp", "sce-pm", "sce-cfg", "ast-cpu", "ast-dma"; + nvidia,autosuspend-delay-ms = <0x1388>; + nvidia,memory-bw = <0xffffffff>; + clock-names = "sce-apb", "sce-cpu-nic"; + nvidia,reset-group-2 = "sce-nreset", "sce-nsysporeset"; + nvidia,ch-base = <0x3c>; + status = "okay"; + interrupts = <0x0 0x10 0x4>; + nvidia,nb-pts = <0x4>; + nvidia,trace = <0x56 0x4 0x70100000 0x100000>; + nvidia,ivc-channels = <0x57 0x2 0x90000000 0x10000>; + phandle = <0x19c>; + nvidia,pts-base = <0x23c>; + iommu-resv-regions = <0x0 0x0 0x0 0xa0000000 0x0 0xc0000000 0xffffffff 0xffffffff>; + reg = <0x0 0xb000000 0x0 0x1000 0x0 0xb1f0000 0x0 0x40000 0x0 0xb230000 0x0 0x10000 0x0 0xb040000 0x0 0x10000 0x0 0xb050000 0x0 0x10000>; + iommus = <0x11 0x2a>; + reset-names = "tsctnsce", "sce-pm", "sce-dbgresetn", "sce-presetdbgn", "sce-actmon", "sce-dma", "sce-tke", "sce-gte", "sce-cfg", "sce-nreset", "sce-nsysporeset"; + linux,phandle = <0x19c>; + interrupt-names = "wdt-remote"; + nvidia,reset-group-1 = "tsctnsce", "sce-pm", "sce-dbgresetn", "sce-presetdbgn", "sce-actmon", "sce-dma", "sce-tke", "sce-gte", "sce-cfg"; + + hsp { + compatible = "nvidia,tegra186-hsp-mailbox"; + nvidia,hsp-shared-mailbox-names = "ivc-pair", "cmd-pair"; + nvidia,hsp-shared-mailbox = <0x58 0x1 0x58 0x6>; + }; + }; + + tegra-firmwares { + osl = "unavailable"; + mb1-bct = "unavailable"; + mb2 = "unavailable"; + status = "okay"; + qb = "unavailable"; + mb1 = "unavailable"; + }; + + nvdumper { + compatible = "nvidia,tegra186-nvdumper"; + status = "disabled"; + }; + + dma_test { + compatible = "nvidia,dma_test"; + phandle = <0x1ce>; + linux,phandle = <0x1ce>; + }; + + ape-ivc-channels { + phandle = <0x5d>; + linux,phandle = <0x5d>; + + ivccontrol@52c0 { + nvidia,frame-size = <0x140>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture-control"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture-control"; + }; + + ivccapture@72c0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra186-camera-ivc-protocol-capture"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,service = "capture"; + }; + + dbg@7c00 { + nvidia,frame-size = <0x180>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-dbg"; + nvidia,service = "debug"; + }; + + echo@0 { + nvidia,frame-size = <0x40>; + compatible = "nvidia,tegra-ivc-cdev"; + nvidia,group = <0x1>; + nvidia,frame-count = <0x10>; + nvidia,version = <0x0>; + nvidia,devname = "camchar-echo"; + nvidia,service = "echo"; + }; + + dbg@7e00 { + nvidia,frame-size = <0x2000>; + compatible = "nvidia,tegra186-camera-ivc-protocol-debug"; + nvidia,ivc-timeout = <0x32>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x1>; + nvidia,version = <0x0>; + nvidia,test-timeout = <0x1388>; + nvidia,service = "debug"; + }; + + vinotify@12c0 { + nvidia,frame-size = <0x80>; + compatible = "nvidia,tegra186-camera-ivc-protocol-vinotify"; + device = <0x5a>; + nvidia,group = <0x1>; + nvidia,frame-count = <0x40>; + nvidia,version = <0x0>; + nvidia,service = "vinotify"; + }; + }; + + spi@c260000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0xde 0x10 0x10d 0x10 0x264>; + resets = <0x10 0x29>; + clock-names = "spi", "pll_p", "osc"; + nvidia,clk-parents = "pll_p", "osc"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x25 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x183>; + reg = <0x0 0xc260000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0x10 0x25 0x10>; + reset-names = "spi"; + linux,phandle = <0x183>; + spi-max-frequency = <0xb71b00>; + + prod-settings { + + prod_c_cs0 { + prod = <0x4 0xfc0 0x400>; + }; + }; + + spi-touch-sharp19x12@0 { + x-max = <0x2580>; + reset-gpio = <0x28 0x3 0x0>; + compatible = "sharp,lr388k7_ts"; + flip-y = <0x1>; + clock-sel-gpio = <0x40 0x1 0x0>; + y-max = <0x3c00>; + touch-num-max = <0xa>; + status = "okay"; + interrupt-parent = <0x28>; + interrupts = <0x2f 0x1>; + z-max = <0xffff>; + reg = <0x0>; + flip-x = <0x1>; + avdd-supply = <0x3e>; + platform-id = <0x1>; + irq-gpio = <0x28 0x2f 0x1>; + spi-max-frequency = <0xb71b00>; + dvdd-supply = <0x3f>; + }; + }; + + denver-pmu { + compatible = "nvidia,denver15-pmu"; + interrupts = <0x0 0x122 0x4>; + interrupt-affinity = <0x2>; + }; + + eqos_ape@2990000 { + compatible = "nvidia,tegra18x-eqos-ape"; + wakeup-disable; + clocks = <0x10 0x69 0x10 0xf6 0x10 0x10f>; + clock-names = "eqos_ape.ape", "pll_a_out0", "pll_a"; + status = "disabled"; + reg = <0x0 0x2990054 0x0 0x4 0x0 0x29900c0 0x0 0x28>; + }; + + mipical { + compatible = "nvidia, tegra186-mipical"; + clocks = <0x10 0x74 0x10 0x7e>; + resets = <0x10 0x1c>; + clock-names = "mipi_cal", "uart_fs_mipi_cal"; + status = "okay"; + reg = <0x0 0x3990000 0x0 0x10000>; + reset-names = "mipi_cal"; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_cphy_csi { + prod = <0x18 0xf81f 0x0 0x1c 0xf81f 0x0 0x20 0xf81f 0x0 0x24 0xf81f 0x0 0x28 0xf81f 0x0 0x2c 0xf81f 0x0>; + + soc_a01 { + prod = <0x18 0xf81f 0x8010 0x1c 0xf81f 0x8010 0x20 0xf81f 0x8010 0x24 0xf81f 0x8010 0x28 0xf81f 0x8010 0x2c 0xf81f 0x8010>; + status = "disabled"; + phandle = <0xfa>; + linux,phandle = <0xfa>; + }; + }; + + prod { + prod = <0x4 0x3f000012 0x2a000010 0x18 0x40000000 0x0 0x1c 0x40000000 0x0 0x20 0x40000000 0x0 0x24 0x40000000 0x0 0x28 0x40000000 0x0 0x2c 0x40000000 0x0 0x3c 0x1f00 0x200 0x40 0x1f00 0x200 0x44 0x1f00 0x200 0x48 0x1f00 0x200 0x5c 0x1 0x0 0x60 0xf0f0f 0x0 0x64 0xf0ffff5 0x10010 0x68 0x4000001f 0x0 0x6c 0x4000001f 0x0 0x74 0x4000001f 0x0 0x78 0x4000001f 0x0>; + }; + + prod_c_dphy_dsi { + prod = <0x3c 0x1f1f1f 0x0 0x40 0x1f1f1f 0x0 0x44 0x1f1f1f 0x0 0x48 0x1f1f1f 0x0 0x68 0x1f0000 0x70000 0x6c 0x1f0000 0x70000 0x74 0x1f0000 0x70000 0x78 0x1f0000 0x70000>; + + soc_a01 { + prod = <0x3c 0x1f1f1f 0x101010 0x40 0x1f1f1f 0x101010 0x44 0x1f1f1f 0x101010 0x48 0x1f1f1f 0x101010 0x68 0x1f0000 0x100000 0x6c 0x1f0000 0x100000 0x74 0x1f0000 0x100000 0x78 0x1f0000 0x100000>; + status = "disabled"; + phandle = <0xfc>; + linux,phandle = <0xfc>; + }; + }; + + prod_c_dphy_csi { + prod = <0x18 0xf81f 0x0 0x1c 0xf81f 0x0 0x20 0xf81f 0x0 0x24 0xf81f 0x0 0x28 0xf81f 0x0 0x2c 0xf81f 0x0>; + + soc_a01 { + prod = <0x18 0xf81f 0x8010 0x1c 0xf81f 0x8010 0x20 0xf81f 0x8010 0x24 0xf81f 0x8010 0x28 0xf81f 0x8010 0x2c 0xf81f 0x8010>; + status = "disabled"; + phandle = <0xfb>; + linux,phandle = <0xfb>; + }; + }; + }; + }; + + e3326_lens_ov5693@P5V27C { + min_focus_distance = "0.0"; + f_number = "2.0"; + hyper_focal = "0.0"; + aperture = "2.0"; + focal_length = "2.67"; + }; + + e3323_lens_ov23850@CH06P1 { + min_focus_distance = "10.0"; + f_number = "2.2"; + hyper_focal = "0.2"; + aperture = "2.2"; + focal_length = "4.73"; + }; + + tegra-camera-platform { + isp_bw_margin_pct = <0x19>; + compatible = "nvidia, tegra-camera-platform"; + max_pixel_rate = <0xb71b0>; + num_csi_lanes = <0x4>; + vi_peak_byte_per_pixel = <0x2>; + max_lane_speed = <0x16e360>; + phandle = <0x12f>; + tpg_max_iso = <0x3bc400>; + vi_bw_margin_pct = <0x19>; + linux,phandle = <0x12f>; + min_bits_per_pixel = <0xa>; + isp_peak_byte_per_pixel = <0x5>; + + modules { + + module4 { + badge = "e3322_bottomright_A815P2"; + status = "disabled"; + phandle = <0x152>; + position = "bottomright"; + linux,phandle = <0x152>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x154>; + linux,phandle = <0x154>; + }; + + drivernode0 { + devname = "imx219 34-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/imx219_e@10"; + phandle = <0x153>; + linux,phandle = <0x153>; + }; + }; + + module2 { + badge = "e3322_centerright_A815P2"; + status = "disabled"; + phandle = <0x140>; + position = "centerright"; + linux,phandle = <0x140>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x142>; + linux,phandle = <0x142>; + }; + + drivernode0 { + devname = "imx219 32-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/imx219_c@10"; + phandle = <0x141>; + linux,phandle = <0x141>; + }; + }; + + module0 { + badge = "e3326_front_P5V27C"; + status = "okay"; + phandle = <0x121>; + position = "rear"; + linux,phandle = <0x121>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "okay"; + proc-device-tree = "/proc/device-tree/e3326_lens_ov5693@P5V27C/"; + phandle = <0x133>; + linux,phandle = <0x133>; + }; + + drivernode0 { + devname = "ov5693 2-0036"; + pcl_id = "v4l2_sensor"; + status = "okay"; + proc-device-tree = "/proc/device-tree/i2c@3180000/ov5693_c@36"; + phandle = <0x122>; + linux,phandle = <0x122>; + }; + }; + + module5 { + badge = "e3322_topright_A815P2"; + status = "disabled"; + phandle = <0x15b>; + position = "topright"; + linux,phandle = <0x15b>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x15d>; + linux,phandle = <0x15d>; + }; + + drivernode0 { + devname = "imx219 35-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/imx219_f@10"; + phandle = <0x15c>; + linux,phandle = <0x15c>; + }; + }; + + module3 { + badge = "e3322_topleft_A815P2"; + status = "disabled"; + phandle = <0x149>; + position = "topleft"; + linux,phandle = <0x149>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/e3333_lens_ov5693@P5V27C/"; + phandle = <0x14b>; + linux,phandle = <0x14b>; + }; + + drivernode0 { + devname = "imx219 33-0010"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/imx219_d@10"; + phandle = <0x14a>; + linux,phandle = <0x14a>; + }; + }; + + module1 { + badge = "imx390_front"; + status = "disabled"; + phandle = <0x124>; + position = "front"; + linux,phandle = <0x124>; + orientation = [31 00]; + + drivernode1 { + pcl_id = "v4l2_lens"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/lens_imx274@A6V26/"; + phandle = <0x137>; + linux,phandle = <0x137>; + }; + + drivernode0 { + devname = "imx390 30-001c"; + pcl_id = "v4l2_sensor"; + status = "disabled"; + proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx390_b@1c"; + phandle = <0x125>; + linux,phandle = <0x125>; + }; + }; + }; + }; + + aon_shub { + compatible = "nvidia,tegra186_aon_shub"; + status = "disabled"; + mboxes = <0x41 0x5>; + }; + + pwm@32f0000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xc1 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x6a>; + clock-names = "pwm", "parent", "slow-parent"; + status = "disabled"; + phandle = <0x18c>; + reg = <0x0 0x32f0000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x18c>; + #pwm-cells = <0x2>; + }; + + cpus { + status = "disabled"; + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu@3 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x5>; + reg = <0x0 0x101>; + linux,phandle = <0x5>; + }; + + l2-cache1 { + compatible = "cache"; + cache-level = <0x2>; + cache-unified; + phandle = <0xa>; + linux,phandle = <0xa>; + }; + + cpu@1 { + compatible = "nvidia,denver", "arm,armv8"; + cpu-idle-states = <0x8 0x9>; + device_type = "cpu"; + sched-energy-costs = <0xb 0xb>; + capacity-dmips-mhz = <0x400>; + cpu-ipc = <0x400>; + next-level-cache = <0xa>; + enable-method = "psci"; + status = "NILL"; + phandle = <0x3>; + reg = <0x0 0x1>; + linux,phandle = <0x3>; + }; + + cpu-map { + + cluster1 { + + core0 { + cpu = <0x4>; + }; + + core3 { + cpu = <0x7>; + }; + + core1 { + cpu = <0x5>; + }; + + core2 { + cpu = <0x6>; + }; + }; + + cluster0 { + }; + }; + + cpu@4 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x6>; + reg = <0x0 0x102>; + linux,phandle = <0x6>; + }; + + a57_cluster_power_states { + compatible = "nvidia,tegra186-cpuidle-a57-cluster"; + + cc6 { + state-name = "Cluster powergate"; + power = <0x13>; + pmstate = <0x6>; + status = "okay"; + wakeup-latency-us = <0x15e>; + min-residency-us = <0x1388>; + }; + + cc7 { + state-name = "Cluster railgate"; + power = <0x5>; + pmstate = <0x7>; + status = "disabled"; + wakeup-latency-us = <0x50>; + min-residency-us = <0x320>; + }; + + cc1 { + state-name = "Cluster clock gated"; + power = <0x41>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + }; + }; + + denver_core_power_states { + compatible = "nvidia,tegra186-cpuidle-denver"; + phandle = <0x178>; + linux,phandle = <0x178>; + + c1 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Clock gated"; + power = <0x46>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + phandle = <0x179>; + linux,phandle = <0x179>; + min-residency-us = <0x1>; + }; + + c6 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Virtual core powergate"; + arm,psci-suspend-param = <0x6>; + power = <0x3c>; + pmstate = <0x6>; + status = "okay"; + wakeup-latency-us = <0xbe>; + phandle = <0x8>; + linux,phandle = <0x8>; + min-residency-us = <0xffffffff>; + }; + + c7 { + compatible = "nvidia,tegra186-cpuidle-denver"; + state-name = "Core powergate"; + arm,psci-suspend-param = <0x40000007>; + power = <0x3c>; + pmstate = <0x7>; + status = "okay"; + wakeup-latency-us = <0x230>; + phandle = <0x9>; + linux,phandle = <0x9>; + min-residency-us = <0xffffffff>; + }; + }; + + cpu@2 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x4>; + reg = <0x0 0x100>; + linux,phandle = <0x4>; + }; + + a57_core_power_states { + compatible = "nvidia,tegra186-cpuidle-a57"; + phandle = <0x176>; + linux,phandle = <0x176>; + + c1 { + compatible = "nvidia,tegra186-cpuidle-a57"; + state-name = "Clock gated"; + power = <0x46>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + phandle = <0x177>; + linux,phandle = <0x177>; + min-residency-us = <0x1>; + }; + + c7 { + compatible = "nvidia,tegra186-cpuidle-a57"; + state-name = "Core powergate"; + arm,psci-suspend-param = <0x40000007>; + power = <0x3c>; + pmstate = <0x7>; + status = "okay"; + wakeup-latency-us = <0x82>; + phandle = <0xc>; + linux,phandle = <0xc>; + min-residency-us = <0xffffffff>; + }; + }; + + l2-cache0 { + compatible = "cache"; + cache-level = <0x2>; + cache-unified; + phandle = <0xd>; + linux,phandle = <0xd>; + }; + + a57_crossover_thresholds { + compatible = "nvidia,tegra186-cpuidle-a57-thresholds"; + + thresholds { + crossover_cc1_cc6 = <0x1388>; + crossover_cc1_cc7 = <0x2bc>; + }; + }; + + cpu@0 { + compatible = "nvidia,denver", "arm,armv8"; + cpu-idle-states = <0x8 0x9>; + device_type = "cpu"; + sched-energy-costs = <0xb 0xb>; + capacity-dmips-mhz = <0x400>; + cpu-ipc = <0x400>; + next-level-cache = <0xa>; + enable-method = "psci"; + status = "NILL"; + phandle = <0x2>; + reg = <0x0 0x0>; + linux,phandle = <0x2>; + }; + + denver_cluster_power_states { + compatible = "nvidia,tegra186-cpuidle-denver-cluster"; + + cc6 { + state-name = "Cluster powergate"; + power = <0x13>; + pmstate = <0x6>; + status = "okay"; + wakeup-latency-us = <0x1c2>; + min-residency-us = <0x1388>; + }; + + cc7 { + state-name = "Cluster railgate"; + power = <0x5>; + pmstate = <0x7>; + status = "disabled"; + wakeup-latency-us = <0x50>; + min-residency-us = <0x320>; + }; + + cc1 { + state-name = "Cluster clock gated"; + power = <0x41>; + pmstate = <0x1>; + status = "okay"; + wakeup-latency-us = <0x1>; + min-residency-us = <0x1>; + }; + }; + + denver_crossover_thresholds { + compatible = "nvidia,tegra186-cpuidle-denver-thresholds"; + + thresholds { + crossover_c1_c6 = <0x3e8>; + crossover_cc1_cc6 = <0x1388>; + crossover_cc1_cc7 = <0x4e20>; + }; + }; + + cpu@5 { + compatible = "arm,cortex-a57-64bit", "arm,armv8"; + cpu-idle-states = <0xc>; + device_type = "cpu"; + sched-energy-costs = <0xe 0xe>; + capacity-dmips-mhz = <0x2f0>; + cpu-ipc = <0x2f0>; + next-level-cache = <0xd>; + enable-method = "psci"; + status = "okay"; + phandle = <0x7>; + reg = <0x0 0x103>; + linux,phandle = <0x7>; + }; + }; + + spi@3210000 { + compatible = "nvidia,tegra186-spi"; + clocks = <0x10 0x31 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x28>; + clock-names = "spi", "pll_p", "clk_m"; + nvidia,clk-parents = "pll_p", "clk_m"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x24 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x182>; + reg = <0x0 0x3210000 0x0 0x10000>; + iommus = <0x11 0x20>; + dmas = <0x25 0xf 0x25 0xf>; + reset-names = "spi"; + linux,phandle = <0x182>; + }; + + dma@2600000 { + #dma-cells = <0x1>; + compatible = "nvidia,tegra186-gpcdma"; + resets = <0x10 0x46>; + nvidia,preallocated-descs = <0x20>; + status = "okay"; + interrupts = <0x0 0x4b 0x4 0x0 0x4c 0x4 0x0 0x4d 0x4 0x0 0x4e 0x4 0x0 0x4f 0x4 0x0 0x50 0x4 0x0 0x51 0x4 0x0 0x52 0x4 0x0 0x53 0x4 0x0 0x54 0x4 0x0 0x55 0x4 0x0 0x56 0x4 0x0 0x57 0x4 0x0 0x58 0x4 0x0 0x59 0x4 0x0 0x5a 0x4 0x0 0x5b 0x4 0x0 0x5c 0x4 0x0 0x5d 0x4 0x0 0x5e 0x4 0x0 0x5f 0x4 0x0 0x60 0x4 0x0 0x61 0x4 0x0 0x62 0x4 0x0 0x63 0x4 0x0 0x64 0x4 0x0 0x65 0x4 0x0 0x66 0x4 0x0 0x67 0x4 0x0 0x68 0x4 0x0 0x69 0x4 0x0 0x6a 0x4 0x0 0x6b 0x4>; + phandle = <0x25>; + reg = <0x0 0x2600000 0x0 0x210000>; + iommus = <0x11 0x20>; + reset-names = "gpcdma"; + linux,phandle = <0x25>; + nvidia,preallocate-sg = <0x20>; + }; + + backlight { + status = "okay"; + + panel-s-wuxga-8-0-bl { + compatible = "s,wuxga-8-0-bl"; + default-brightness = <0xbf>; + default-charge-brightness = <0x70>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xb 0xc 0xd 0xe 0xf 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xdf 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfd 0xfe 0xff>; + status = "disabled"; + phandle = <0x1e0>; + max-brightness = <0xff>; + pwms = <0x27 0x0 0x9ce1>; + linux,phandle = <0x1e0>; + }; + + panel-a-edp-1080p-14-0-bl { + compatible = "a-edp,1080p-14-0-bl"; + default-brightness = <0xe0>; + bl-measured = <0x0 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0x9 0xa 0xb 0xc 0xd 0xd 0xe 0xf 0x10 0x11 0x11 0x12 0x13 0x14 0x15 0x16 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x20 0x21 0x22 0x23 0x24 0x25 0x25 0x26 0x27 0x28 0x29 0x2a 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8d 0x8e 0x8f 0x90 0x92 0x93 0x94 0x95 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xb0 0xb1 0xb2 0xb3 0xb4 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc2 0xc3 0xc4 0xc5 0xc6 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xdb 0xdc 0xdd 0xde 0xe0 0xe1 0xe2 0xe3 0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xee 0xef 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xff>; + status = "disabled"; + phandle = <0x1e3>; + max-brightness = <0xff>; + pwms = <0x27 0x0 0xf4240>; + linux,phandle = <0x1e3>; + }; + + panel-s-wqxga-10-1-bl { + compatible = "s,wqxga-10-1-bl"; + default-brightness = <0xe0>; + bl-measured = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc6 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe8 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff>; + status = "disabled"; + phandle = <0x1e1>; + max-brightness = <0xff>; + pwms = <0x27 0x0 0xf4240>; + linux,phandle = <0x1e1>; + }; + + panel-s-edp-uhdtv-15-6-bl { + compatible = "s-edp,uhdtv-15-6-bl"; + default-brightness = <0xe0>; + status = "disabled"; + phandle = <0x1e2>; + max-brightness = <0xff>; + pwms = <0xeb 0x0 0x4c4b40>; + linux,phandle = <0x1e2>; + }; + }; + + pwm@3280000 { + compatible = "nvidia,tegra186-pwm"; + clocks = <0x10 0xbb 0x10 0x10d 0x10 0x261>; + resets = <0x10 0x63>; + clock-names = "pwm", "parent", "slow-parent"; + status = "okay"; + phandle = <0x27>; + reg = <0x0 0x3280000 0x0 0x10000>; + reset-names = "pwm"; + linux,phandle = <0x27>; + #pwm-cells = <0x2>; + }; + + axi2apb@23a0000 { + compatible = "nvidia,tegra186-AXI2APB-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x23a0000 0x0 0x1000>; + }; + + hsp_top { + status = "okay"; + }; + + bwmgr { + compatible = "nvidia,bwmgr"; + clocks = <0x10 0x3a>; + clock-names = "emc"; + status = "okay"; + }; + + axip2p@2120000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2120000 0x0 0x1000>; + }; + + ether_qos@2490000 { + phy-handle = <0x44>; + nvidia,rxq_enable_ctrl = <0x2 0x2 0x2 0x2>; + compatible = "nvidia,eqos"; + clocks = <0x10 0xa7 0x10 0xa8 0x10 0xef 0x10 0xf0 0x10 0x95>; + nvidia,csr_clock_speed = <0x19>; + vddio_enet-supply = <0x13>; + iommu_sodev_map; + resets = <0x10 0x45>; + nvidia,phy-max-frame-size = <0xa>; + vddio_sys_enet_bias-supply = <0x12>; + reg-names = "eqos_base"; + pinctrl-1 = <0x43>; + phy_pllvdd-supply = <0x3c>; + nvidia,brcm_phy_apd_mode; + nvidia,phy-reset-gpio = <0x1b 0x64 0x0>; + nvidia,pause_frames = <0x0>; + clock-names = "eqos_axi", "eqos_rx", "eqos_ptp_ref", "eqos_tx", "axi_cbb"; + nvidia,rx_riwt = <0x7c>; + phy_vdd_1v8-supply = <0x12>; + nvidia,ptp_ref_clock_speed = <0x7d>; + status = "okay"; + interrupts = <0x0 0xc2 0x4 0x0 0xc3 0x4 0x0 0xbe 0x4 0x0 0xba 0x4 0x0 0xbf 0x4 0x0 0xbb 0x4 0x0 0xc0 0x4 0x0 0xbc 0x4 0x0 0xc1 0x4 0x0 0xbd 0x4>; + phy_ovdd_rgmii-supply = <0x13>; + nvidia,chan_napi_quota = <0x40 0x40 0x40 0x40>; + nvidia,iso_bw = <0x14000>; + iommu-group-id = <0x2>; + iommu-resv-regions = <0x0 0x0 0x0 0x40000000 0x0 0x60000000 0xffffffff 0xffffffff>; + nvidia,local-mac-address = <0x0 0x0 0x0 0x0 0x0 0x0>; + reg = <0x0 0x2490000 0x0 0x10000>; + phy-mode = "rgmii"; + iommus = <0x11 0x14>; + pinctrl-0 = <0x42>; + reset-names = "eqos_rst"; + nvidia,use_tagged_ptp; + nvidia,ptp_dma_ch = <0x3>; + nvidia,eth_iso_enable = <0x1>; + pinctrl-names = "idle", "default"; + nvidia,queue_prio = <0x0 0x1 0x2 0x3>; + + mdio { + compatible = "nvidia,eqos-mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + ethernet-phy@0 { + interrupt-parent = <0x1b>; + interrupts = <0x65 0x8>; + phandle = <0x44>; + reg = <0x0>; + linux,phandle = <0x44>; + }; + }; + + prod-settings { + #prod-cells = <0x4>; + + prod { + prod = <0x0 0x8800 0xdff7ffff 0x8000007>; + }; + }; + + eqos-cool-dev { + cooling-min-state = <0x0>; + phandle = <0x4c>; + cooling-max-state = <0x5>; + #cooling-cells = <0x2>; + linux,phandle = <0x4c>; + }; + }; + + pcie-controller@10003000 { + power-domains = <0x1f 0x9>; + hvdd-pex-pll-supply = <0x12>; + compatible = "nvidia,tegra186-pcie"; + clocks = <0x10 0x4 0x10 0x3 0x10 0x261 0x10 0x200>; + vddio-pexctl-aud-supply = <0x12>; + iommu_sodev_map; + resets = <0x10 0x1 0x10 0x1d 0x10 0x1e>; + reg-names = "pads", "afi", "cs"; + hvdd-pex-supply = <0x12>; + device_type = "pci"; + dvdd-pex-supply = <0x89>; + clock-names = "afi", "pex", "clk_m", "pll_e"; + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + ranges = <0x82000000 0x0 0x10000000 0x0 0x10000000 0x0 0x1000 0x82000000 0x0 0x10001000 0x0 0x10001000 0x0 0x1000 0x82000000 0x0 0x10004000 0x0 0x10004000 0x0 0x1000 0x81000000 0x0 0x0 0x0 0x40001000 0x0 0x10000 0x82000000 0x0 0x40100000 0x0 0x40100000 0x0 0x7f00000 0xc2000000 0x0 0x48000000 0x0 0x48000000 0x0 0x38000000>; + status = "okay"; + #interrupt-cells = <0x1>; + bus-range = <0x0 0xff>; + #address-cells = <0x3>; + interrupts = <0x0 0x48 0x4 0x0 0x49 0x4>; + interrupt-map = <0x0 0x0 0x0 0x0 0x1 0x0 0x48 0x4>; + #size-cells = <0x2>; + phandle = <0x109>; + reg = <0x0 0x10003000 0x0 0x800 0x0 0x10003800 0x0 0x800 0x0 0x40000000 0x0 0x1000>; + iommus = <0x11 0x11>; + reset-names = "afi", "pex", "pcie_x"; + linux,phandle = <0x109>; + interrupt-names = "intr", "msi"; + + prod-settings { + #prod-cells = <0x3>; + + prod_c_pad { + prod = <0xc8 0xffffffff 0x80b880b8 0xcc 0xffffffff 0x480b8>; + }; + }; + + pci@2,0 { + nvidia,afi-ctl-offset = <0x118>; + assigned-addresses = <0x82001000 0x0 0x10001000 0x0 0x1000>; + device_type = "pci"; + nvidia,num-lanes = <0x0>; + ranges; + status = "disabled"; + #address-cells = <0x3>; + #size-cells = <0x2>; + reg = <0x1000 0x0 0x0 0x0 0x0>; + nvidia,disable-aspm-states = <0xf>; + }; + + pci@1,0 { + nvidia,afi-ctl-offset = <0x110>; + assigned-addresses = <0x82000800 0x0 0x10000000 0x0 0x1000>; + device_type = "pci"; + nvidia,num-lanes = <0x4>; + nvidia,disable-clock-request; + ranges; + status = "okay"; + #address-cells = <0x3>; + #size-cells = <0x2>; + reg = <0x800 0x0 0x0 0x0 0x0>; + nvidia,disable-aspm-states = <0xf>; + }; + + pci@3,0 { + nvidia,afi-ctl-offset = <0x19c>; + assigned-addresses = <0x82001800 0x0 0x10004000 0x0 0x1000>; + device_type = "pci"; + nvidia,num-lanes = <0x1>; + ranges; + status = "okay"; + #address-cells = <0x3>; + #size-cells = <0x2>; + reg = <0x1800 0x0 0x0 0x0 0x0>; + nvidia,disable-aspm-states = <0xf>; + }; + }; + + stm@8070000 { + compatible = "arm,coresight-stm", "arm,primecell"; + clocks = <0x10 0xc4>; + reg-names = "stm-base", "stm-stimulus-base"; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8070000 0x0 0x1000 0x0 0xa000000 0x0 0x180000>; + + port { + + endpoint { + remote-endpoint = <0xd2>; + phandle = <0xdd>; + linux,phandle = <0xdd>; + }; + }; + }; + + pmc@c360000 { + #padcontroller-cells = <0x1>; + compatible = "nvidia,tegra186-pmc"; + nvidia,restrict-voltage-switch; + status = "okay"; + phandle = <0xb3>; + reg = <0x0 0xc360000 0x0 0x400 0x0 0xc390000 0x0 0x2fff>; + pinctrl-0 = <0xf>; + linux,phandle = <0xb3>; + pinctrl-names = "default"; + + sdmmc2_e_33V_enable { + phandle = <0x17>; + linux,phandle = <0x17>; + + sdmmc2 { + pins = "sdmmc2-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + sdmmc2_e_33V_disable { + phandle = <0x18>; + linux,phandle = <0x18>; + + sdmmc2 { + pins = "sdmmc2-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + dsib-dpd-enable { + phandle = <0x77>; + linux,phandle = <0x77>; + + dsib-pad-lowpower-enable { + low-power-enable; + pins = "dsib"; + }; + }; + + hdmi-dp1-dpd-disable { + phandle = <0x7e>; + linux,phandle = <0x7e>; + + hdmi-dp1-pad-lowpower-disable { + pins = "hdmi-dp1"; + low-power-disable; + }; + }; + + sdmmc3_e_33V_enable { + phandle = <0x14>; + linux,phandle = <0x14>; + + sdmmc3 { + pins = "sdmmc3-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + dsib-dpd-disable { + phandle = <0x76>; + linux,phandle = <0x76>; + + dsib-pad-lowpower-disable { + pins = "dsib"; + low-power-disable; + }; + }; + + dsic-dpd-enable { + phandle = <0x79>; + linux,phandle = <0x79>; + + dsic-pad-lowpower-enable { + low-power-enable; + pins = "dsic"; + }; + }; + + sdmmc3_e_33V_disable { + phandle = <0x15>; + linux,phandle = <0x15>; + + sdmmc3 { + pins = "sdmmc3-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + dsic-dpd-disable { + phandle = <0x78>; + linux,phandle = <0x78>; + + dsic-pad-lowpower-disable { + pins = "dsic"; + low-power-disable; + }; + }; + + dpd-enable { + phandle = <0x23>; + linux,phandle = <0x23>; + + ufs { + low-power-enable; + pins = "ufs"; + }; + }; + + dsid-dpd-enable { + phandle = <0x7b>; + linux,phandle = <0x7b>; + + dsid-pad-lowpower-enable { + low-power-enable; + pins = "dsid"; + }; + }; + + hdmi-dp0-dpd-enable { + phandle = <0x7d>; + linux,phandle = <0x7d>; + + hdmi-dp0-pad-lowpower-enable { + low-power-enable; + pins = "hdmi-dp0"; + }; + }; + + iopad-defaults { + phandle = <0xf>; + linux,phandle = <0xf>; + + sdmmc-io-pads { + pins = "sdmmc1-hv", "sdmmc2-hv", "sdmmc3-hv"; + nvidia,enable-voltage-switching; + }; + }; + + dsi-dpd-enable { + phandle = <0x75>; + linux,phandle = <0x75>; + + dsi-pad-lowpower-enable { + low-power-enable; + pins = "dsi"; + }; + }; + + dpd-disable { + phandle = <0x24>; + linux,phandle = <0x24>; + + ufs { + pins = "ufs"; + low-power-disable; + }; + }; + + dsid-dpd-disable { + phandle = <0x7a>; + linux,phandle = <0x7a>; + + dsidpad-lowpower-disable { + pins = "dsid"; + low-power-disable; + }; + }; + + hdmi-dp1-dpd-enable { + phandle = <0x7f>; + linux,phandle = <0x7f>; + + hdmi-dp1-pad-lowpower-enable { + low-power-enable; + pins = "hdmi-dp1"; + }; + }; + + sdmmc1_e_33V_disable { + phandle = <0x1a>; + linux,phandle = <0x1a>; + + sdmmc1 { + pins = "sdmmc1-hv"; + nvidia,power-source-voltage = <0x0>; + }; + }; + + sdmmc1_e_33V_enable { + phandle = <0x19>; + linux,phandle = <0x19>; + + sdmmc1 { + pins = "sdmmc1-hv"; + nvidia,power-source-voltage = <0x1>; + }; + }; + + hdmi-dp0-dpd-disable { + phandle = <0x7c>; + linux,phandle = <0x7c>; + + hdmi-dp0-pad-lowpower-disable { + pins = "hdmi-dp0"; + low-power-disable; + }; + }; + + dsi-dpd-disable { + phandle = <0x74>; + linux,phandle = <0x74>; + + dsi-pad-lowpower-disable { + pins = "dsi"; + low-power-disable; + }; + }; + }; + + bcmdhd_wlan { + nv_path = "/vendor/firmware/nvram_quill_4354.txt"; + compatible = "android,bcmdhd_wlan"; + fw_path = "/vendor/firmware/fw_bcmdhd_4354.bin"; + pwr-retry-cnt = <0x5>; + status = "okay"; + interrupt-parent = <0x28>; + interrupts = <0x3b 0x14>; + phandle = <0x10a>; + linux,phandle = <0x10a>; + wlan-pwr-gpio = <0x1b 0x68 0x0>; + sdhci-host = <0xf9>; + }; + + generic-system-config { + compatible = "nvidia,tegra186-system-config"; + status = "disabled"; + }; + + hardwood { + compatible = "nvidia,denver-hardwood"; + interrupts = <0x0 0x18 0x4>; + }; + + funnel_bccplex@9010000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x9010000 0x0 0x1000>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@1 { + reg = <0x0>; + + endpoint { + phandle = <0x1dc>; + slave-mode; + linux,phandle = <0x1dc>; + }; + }; + + port@2 { + reg = <0x1>; + + endpoint { + remote-endpoint3 = <0xd9>; + remote-endpoint1 = <0xd7>; + remote-endpoint2 = <0xd8>; + phandle = <0xd3>; + remote-endpoint0 = <0xd6>; + slave-mode; + linux,phandle = <0xd3>; + }; + }; + + port@0 { + reg = <0x0>; + + endpoint { + remote-endpoint = <0xd5>; + phandle = <0xdb>; + linux,phandle = <0xdb>; + }; + }; + }; + }; + + serial@3100000 { + compatible = "nvidia,tegra20-uart", "nvidia,tegra186-hsuart"; + clocks = <0x10 0x37 0x10 0x10d>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + console-port; + clock-names = "serial", "parent"; + sqa-automation-port; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "okay"; + interrupts = <0x0 0x70 0x4>; + dma-names = "rx", "tx"; + phandle = <0x103>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3100000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x8 0x25 0x8>; + reg-shift = <0x2>; + linux,phandle = <0x103>; + }; + + i2c@31c0000 { + compatible = "nvidia,tegra186-i2c"; + clocks = <0x10 0xb6 0x10 0x10d 0x10 0x5c>; + resets = <0x10 0x51>; + scl-gpio = <0x1b 0x58 0x0>; + sda-gpio = <0x1b 0x59 0x0>; + clock-names = "div-clk", "parent", "slow-clk"; + status = "okay"; + #address-cells = <0x1>; + interrupts = <0x0 0x1f 0x4>; + #size-cells = <0x0>; + dma-names = "rx", "tx"; + phandle = <0x17f>; + reg = <0x0 0x31c0000 0x0 0x100>; + iommus = <0x11 0x20>; + clock-frequency = <0x61a80>; + dmas = <0x25 0x1b 0x25 0x1b>; + reset-names = "i2c"; + linux,phandle = <0x17f>; + + prod-settings { + + prod_c_fm { + prod = <0x6c 0xffff0000 0x190000 0x94 0x3f00 0x200>; + }; + + prod_c_hs { + prod = <0x6c 0xffff 0x2 0x9c 0x3f00 0x300>; + }; + + prod_c_sm { + prod = <0x6c 0xffff0000 0x160000 0x94 0x3f00 0x300>; + }; + + prod_c_fmplus { + prod = <0x6c 0xffff0000 0x100000 0x94 0x3f00 0x200>; + }; + }; + }; + + axip2p@2160000 { + compatible = "nvidia,tegra186-AXIP2P-bridge"; + timeout = <0x17ae8>; + clocks = <0x10 0x95>; + clock-names = "axi_cbb"; + status = "okay"; + reg = <0x0 0x2160000 0x0 0x1000>; + }; + + lens_imx274@A6V26 { + min_focus_distance = "0.0"; + f_number = "2.0"; + hyper_focal = "0.0"; + aperture = "2.2"; + focal_length = "5.00"; + }; + + serial@3140000 { + compatible = "nvidia,tegra186-hsuart"; + clocks = <0x10 0xc2 0x10 0x10d>; + resets = <0x10 0x84>; + nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>; + clock-names = "serial", "parent"; + nvidia,tolerance-low-range = <0x0>; + nvidia,tolerance-high-range = <0x4>; + status = "disabled"; + interrupts = <0x0 0x74 0x4>; + dma-names = "rx", "tx"; + phandle = <0x190>; + nvidia,memory-clients = <0xe>; + reg = <0x0 0x3140000 0x0 0x40>; + iommus = <0x11 0x20>; + dmas = <0x25 0x14 0x25 0x14>; + reg-shift = <0x2>; + reset-names = "serial"; + linux,phandle = <0x190>; + }; + + spdif_dit { + compatible = "simple-bus"; + device_type = "spdif-dit"; + status = "okay"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + spdif-dit.10@a { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xcc>; + reg = <0xa>; + linux,phandle = <0xcc>; + }; + + spdif-dit.0@0 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xba>; + reg = <0x0>; + linux,phandle = <0xba>; + }; + + spdif-dit.7@7 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc6>; + reg = <0x7>; + linux,phandle = <0xc6>; + }; + + spdif-dit.11@b { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xd0>; + reg = <0xb>; + linux,phandle = <0xd0>; + }; + + spdif-dit.1@1 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xbc>; + reg = <0x1>; + linux,phandle = <0xbc>; + }; + + spdif-dit.8@8 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc8>; + reg = <0x8>; + linux,phandle = <0xc8>; + }; + + spdif-dit.12@c { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xd1>; + reg = <0xc>; + linux,phandle = <0xd1>; + }; + + spdif-dit.2@2 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xbe>; + reg = <0x2>; + linux,phandle = <0xbe>; + }; + + spdif-dit.9@9 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xca>; + reg = <0x9>; + linux,phandle = <0xca>; + }; + + spdif-dit.13@d { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xce>; + reg = <0xd>; + linux,phandle = <0xce>; + }; + + spdif-dit.3@3 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc0>; + reg = <0x3>; + linux,phandle = <0xc0>; + }; + + spdif-dit.4@4 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc2>; + reg = <0x4>; + linux,phandle = <0xc2>; + }; + + spdif-dit.5@5 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0x181>; + reg = <0x5>; + linux,phandle = <0x181>; + }; + + spdif-dit.6@6 { + compatible = "linux,spdif-dit"; + status = "okay"; + phandle = <0xc4>; + reg = <0x6>; + linux,phandle = <0xc4>; + }; + }; + + interrupt-controller { + compatible = "android,CustomIPI"; + #interrupt-cells = <0x1>; + phandle = <0x46>; + linux,phandle = <0x46>; + interrupt-controller; + }; + + ptm_bpmp@8a1c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + status = "okay"; + reg = <0x0 0x8a1c000 0x0 0x1000>; + + port { + + endpoint { + remote-endpoint = <0xd4>; + phandle = <0xe6>; + linux,phandle = <0xe6>; + }; + }; + }; + + ptm@9940000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + clocks = <0x10 0xc4>; + clock-names = "apb_pclk"; + cpu = <0x5>; + status = "okay"; + phandle = <0x1d9>; + reg = <0x0 0x9940000 0x0 0x1000>; + linux,phandle = <0x1d9>; + + port { + + endpoint { + remote-endpoint = <0xd3>; + phandle = <0xd7>; + linux,phandle = <0xd7>; + }; + }; + }; + + tegra_fiq_debugger { + compatible = "nvidia,fiq-debugger"; + interrupts = <0x0 0x11 0x4>; + use-console-port; + }; + + gp10b { + compatible = "nvidia,tegra186-gp10b", "nvidia,gp10b"; + clocks = <0x10 0x136 0x10 0x1>; + access-vpr-phys; + resets = <0x10 0xe>; + clock-names = "gpu", "gpu_sys"; + fuse-overrides = <0x228 0x9999>; + status = "okay"; + interrupts = <0x0 0x46 0x4 0x0 0x47 0x4>; + dma-noncont; + reg = <0x0 0x17000000 0x0 0x1000000 0x0 0x18000000 0x0 0x1000000 0x0 0x3b41000 0x0 0x1000>; + iommus = <0x11 0x10>; + nvidia,host1x = <0xb6>; + interrupt-names = "stall", "nonstall"; + }; +}; diff --git a/image/BMA b/image/BMA new file mode 100755 index 0000000000000000000000000000000000000000..fb9a8e56c53d95fc7e570c24f500d66d934b09e8 Binary files /dev/null and b/image/BMA differ diff --git a/image/Image_pi4 b/image/Image_pi4 new file mode 100644 index 0000000000000000000000000000000000000000..70c7f4a64acc1a7920062031cfe28755ba34aa68 Binary files /dev/null and b/image/Image_pi4 differ diff --git a/image/Image_pi4_5.4.78 b/image/Image_pi4_5.4.78 new file mode 100755 index 0000000000000000000000000000000000000000..944daa0a55b5d3ef947a2c47d6d29c1654b69467 Binary files /dev/null and b/image/Image_pi4_5.4.78 differ diff --git a/image/Image_pi4_5.4.83 b/image/Image_pi4_5.4.83 new file mode 100755 index 0000000000000000000000000000000000000000..758839c42bcfb9c95290c855eee698dd0ee6b5ab Binary files /dev/null and b/image/Image_pi4_5.4.83 differ diff --git a/image/Image_pi4_5.4.83_tlb b/image/Image_pi4_5.4.83_tlb new file mode 100755 index 0000000000000000000000000000000000000000..8927f9e93edef783637961ec84da69c2ef97ea0c Binary files /dev/null and b/image/Image_pi4_5.4.83_tlb differ diff --git a/image/Image_pi4_vm1 b/image/Image_pi4_vm1 new file mode 100644 index 0000000000000000000000000000000000000000..4c4e24b08654d2400c9acc021b30da291ed75ed4 Binary files /dev/null and b/image/Image_pi4_vm1 differ diff --git a/image/Image_tegra b/image/Image_tegra new file mode 100644 index 0000000000000000000000000000000000000000..0f1bd89f05e5af0592a6b42f6d9b4598a285feeb Binary files /dev/null and b/image/Image_tegra differ diff --git a/image/Image_vanilla b/image/Image_vanilla new file mode 100755 index 0000000000000000000000000000000000000000..6a91609ef60930143b0b22f9f72467f9a9518d83 Binary files /dev/null and b/image/Image_vanilla differ diff --git a/image/L4T b/image/L4T new file mode 100755 index 0000000000000000000000000000000000000000..3ea3c9d516e47a8daa459bac0278c62d99f71603 Binary files /dev/null and b/image/L4T differ diff --git a/image/L4T_no_patch b/image/L4T_no_patch new file mode 100755 index 0000000000000000000000000000000000000000..f01186462ed80b230107bb5d5e9b8a328318323f Binary files /dev/null and b/image/L4T_no_patch differ diff --git a/image/initrd.gz b/image/initrd.gz new file mode 100755 index 0000000000000000000000000000000000000000..57ce6b5207ad93a42b5f224d4d2a640e8d928bea Binary files /dev/null and b/image/initrd.gz differ diff --git a/image/net_rootfs.cpio b/image/net_rootfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..00de70a832f5845374edcb0dd1225b83d50a9a4e Binary files /dev/null and b/image/net_rootfs.cpio differ diff --git a/image/pi4.dtb b/image/pi4.dtb new file mode 100644 index 0000000000000000000000000000000000000000..fe24fc59626da59aa564b4ed80d1abb644eb6537 Binary files /dev/null and b/image/pi4.dtb differ diff --git a/image/pi4_0.dtb b/image/pi4_0.dtb new file mode 100644 index 0000000000000000000000000000000000000000..fe24fc59626da59aa564b4ed80d1abb644eb6537 Binary files /dev/null and b/image/pi4_0.dtb differ diff --git a/image/pi4_0.dts b/image/pi4_0.dts new file mode 100644 index 0000000000000000000000000000000000000000..846c34c3e9f6d2d0ca74584e18b4a1f2bc596d3b --- /dev/null +++ b/image/pi4_0.dts @@ -0,0 +1,1973 @@ +/dts-v1/; + +/memreserve/ 0x0000000000000000 0x0000000000080000; +/ { + compatible = "raspberrypi,4-model-b\0brcm,bcm2711"; + model = "Raspberry Pi 4 Model B"; + #address-cells = <0x02>; + #size-cells = <0x02>; + interrupt-parent = <0x01>; + + aliases { + serial0 = "/soc/serial@7e201400"; + ethernet0 = "/scb/ethernet@7d580000"; + audio = "/soc/mailbox@7e00b840/bcm2835_audio"; + aux = "/soc/aux@7e215000"; + sound = "/soc/sound"; + soc = "/soc"; + dma = "/soc/dma@7e007000"; + watchdog = "/soc/watchdog@7e100000"; + random = "/soc/rng@7e104000"; + mailbox = "/soc/mailbox@7e00b880"; + gpio = "/soc/gpio@7e200000"; + i2s = "/soc/i2s@7e203000"; + i2c0 = "/soc/i2c0mux/i2c@0"; + i2c1 = "/soc/i2c@7e804000"; + i2c10 = "/soc/i2c0mux/i2c@1"; + spi0 = "/soc/spi@7e204000"; + spi1 = "/soc/spi@7e215080"; + spi2 = "/soc/spi@7e2150c0"; + usb = "/soc/usb@7e980000"; + leds = "/leds"; + fb = "/soc/fb"; + thermal = "/soc/avs-monitor@7d5d2000/thermal"; + axiperf = "/soc/axiperf"; + i2c3 = "/soc/i2c@7e205600"; + i2c4 = "/soc/i2c@7e205800"; + i2c5 = "/soc/i2c@7e205a00"; + i2c6 = "/soc/i2c@7e205c00"; + pcie0 = "/scb/pcie@7d500000"; + }; + + chosen { + bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1 console=ttyAMA0,115200n8 root=/dev/sda1 rootfstype=ext4 rw audit=0 rootwait default_hugepagesz=32M hugepagesz=32M hugepages=4"; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x01>; + ranges; + phandle = <0x3d>; + + linux,cma { + compatible = "shared-dma-pool"; + size = <0x4000000>; + reusable; + linux,cma-default; + alloc-ranges = <0x00 0x00 0x30000000>; + phandle = <0x3e>; + }; + }; + + thermal-zones { + + cpu-thermal { + polling-delay-passive = <0x00>; + polling-delay = <0x3e8>; + coefficients = <0xfffffe19 0x641b8>; + thermal-sensors = <0x02>; + phandle = <0x3f>; + + cooling-maps { + }; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges = <0x7e000000 0x00 0xfe000000 0x1800000 0x7c000000 0x00 0xfc000000 0x2000000 0x40000000 0x00 0xff800000 0x800000>; + dma-ranges = <0xc0000000 0x00 0x00 0x40000000>; + phandle = <0x40>; + + timer@7e003000 { + compatible = "brcm,bcm2835-system-timer"; + reg = <0x7e003000 0x1000>; + interrupts = <0x00 0x40 0x04 0x00 0x41 0x04 0x00 0x42 0x04 0x00 0x43 0x04>; + clock-frequency = <0xf4240>; + phandle = <0x41>; + }; + + txp@7e004000 { + compatible = "brcm,bcm2835-txp"; + reg = <0x7e004000 0x20>; + interrupts = <0x00 0x4b 0x04>; + status = "disabled"; + phandle = <0x42>; + }; + + cprman@7e101000 { + compatible = "brcm,bcm2711-cprman"; + #clock-cells = <0x01>; + reg = <0x7e101000 0x2000>; + clocks = <0x03 0x04 0x00 0x04 0x01 0x04 0x02 0x05 0x00 0x05 0x01 0x05 0x02>; + firmware = <0x06>; + phandle = <0x07>; + }; + + rng@7e104000 { + compatible = "brcm,bcm2711-rng200"; + reg = <0x7e104000 0x10>; + interrupts = <0x00 0x7d 0x04>; + status = "okay"; + phandle = <0x32>; + }; + + mailbox@7e00b880 { + compatible = "brcm,bcm2835-mbox"; + reg = <0x7e00b880 0x40>; + interrupts = <0x00 0x21 0x04>; + #mbox-cells = <0x00>; + phandle = <0x1f>; + }; + + gpio@7e200000 { + compatible = "brcm,bcm2711-gpio\0brcm,bcm2835-gpio"; + reg = <0x7e200000 0xb4>; + interrupts = <0x00 0x71 0x04 0x00 0x72 0x04>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + pinctrl-names = "default"; + phandle = <0x0e>; + + dpi_gpio0 { + brcm,pins = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>; + brcm,function = <0x06>; + phandle = <0x43>; + }; + + emmc_gpio22 { + brcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>; + brcm,function = <0x07>; + phandle = <0x44>; + }; + + emmc_gpio34 { + brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02 0x02 0x02 0x02 0x02>; + phandle = <0x45>; + }; + + emmc_gpio48 { + brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>; + brcm,function = <0x07>; + phandle = <0x21>; + }; + + gpclk0_gpio4 { + brcm,pins = <0x04>; + brcm,function = <0x04>; + phandle = <0x46>; + }; + + gpclk1_gpio5 { + brcm,pins = <0x05>; + brcm,function = <0x04>; + phandle = <0x47>; + }; + + gpclk1_gpio42 { + brcm,pins = <0x2a>; + brcm,function = <0x04>; + phandle = <0x48>; + }; + + gpclk1_gpio44 { + brcm,pins = <0x2c>; + brcm,function = <0x04>; + phandle = <0x49>; + }; + + gpclk2_gpio6 { + brcm,pins = <0x06>; + brcm,function = <0x04>; + phandle = <0x4a>; + }; + + gpclk2_gpio43 { + brcm,pins = <0x2b>; + brcm,function = <0x04>; + brcm,pull = <0x00>; + phandle = <0x4b>; + }; + + i2c0_gpio0 { + brcm,pins = <0x00 0x01>; + brcm,function = <0x04>; + phandle = <0x10>; + }; + + i2c0_gpio28 { + brcm,pins = <0x1c 0x1d>; + brcm,function = <0x04>; + phandle = <0x4c>; + }; + + i2c0_gpio44 { + brcm,pins = <0x2c 0x2d>; + brcm,function = <0x05>; + phandle = <0x11>; + }; + + i2c1_gpio2 { + brcm,pins = <0x02 0x03>; + brcm,function = <0x04>; + phandle = <0x4d>; + }; + + i2c1_gpio44 { + brcm,pins = <0x2c 0x2d>; + brcm,function = <0x06>; + phandle = <0x4e>; + }; + + jtag_gpio22 { + brcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>; + brcm,function = <0x03>; + phandle = <0x4f>; + }; + + pcm_gpio18 { + brcm,pins = <0x12 0x13 0x14 0x15>; + brcm,function = <0x04>; + phandle = <0x50>; + }; + + pcm_gpio28 { + brcm,pins = <0x1c 0x1d 0x1e 0x1f>; + brcm,function = <0x06>; + phandle = <0x51>; + }; + + sdhost_gpio48 { + brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>; + brcm,function = <0x04>; + phandle = <0x52>; + }; + + spi0_gpio7 { + brcm,pins = <0x07 0x08 0x09 0x0a 0x0b>; + brcm,function = <0x04>; + phandle = <0x53>; + }; + + spi0_gpio35 { + brcm,pins = <0x23 0x24 0x25 0x26 0x27>; + brcm,function = <0x04>; + phandle = <0x54>; + }; + + spi1_gpio16 { + brcm,pins = <0x10 0x11 0x12 0x13 0x14 0x15>; + brcm,function = <0x03>; + phandle = <0x55>; + }; + + spi2_gpio40 { + brcm,pins = <0x28 0x29 0x2a 0x2b 0x2c 0x2d>; + brcm,function = <0x03>; + phandle = <0x56>; + }; + + uart0_gpio14 { + brcm,pins = <0x0e 0x0f>; + brcm,function = <0x04>; + phandle = <0x57>; + }; + + uart0_ctsrts_gpio16 { + brcm,pins = <0x10 0x11>; + brcm,function = <0x07>; + phandle = <0x58>; + }; + + uart0_ctsrts_gpio30 { + brcm,pins = <0x1e 0x1f>; + brcm,function = <0x07>; + brcm,pull = <0x02 0x00>; + phandle = <0x59>; + }; + + uart0_gpio32 { + brcm,pins = <0x20 0x21>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02>; + phandle = <0x5a>; + }; + + uart0_gpio36 { + brcm,pins = <0x24 0x25>; + brcm,function = <0x06>; + phandle = <0x5b>; + }; + + uart0_ctsrts_gpio38 { + brcm,pins = <0x26 0x27>; + brcm,function = <0x06>; + phandle = <0x5c>; + }; + + uart1_gpio14 { + brcm,pins = <0x0e 0x0f>; + brcm,function = <0x02>; + phandle = <0x5d>; + }; + + uart1_ctsrts_gpio16 { + brcm,pins = <0x10 0x11>; + brcm,function = <0x02>; + phandle = <0x5e>; + }; + + uart1_gpio32 { + brcm,pins = <0x20 0x21>; + brcm,function = <0x02>; + phandle = <0x5f>; + }; + + uart1_ctsrts_gpio30 { + brcm,pins = <0x1e 0x1f>; + brcm,function = <0x02>; + phandle = <0x60>; + }; + + uart1_gpio40 { + brcm,pins = <0x28 0x29>; + brcm,function = <0x02>; + phandle = <0x61>; + }; + + uart1_ctsrts_gpio42 { + brcm,pins = <0x2a 0x2b>; + brcm,function = <0x02>; + phandle = <0x62>; + }; + + gpclk0_gpio49 { + phandle = <0x63>; + + pin-gpclk { + pins = "gpio49"; + function = "alt1"; + bias-disable; + }; + }; + + gpclk1_gpio50 { + phandle = <0x64>; + + pin-gpclk { + pins = "gpio50"; + function = "alt1"; + bias-disable; + }; + }; + + gpclk2_gpio51 { + phandle = <0x65>; + + pin-gpclk { + pins = "gpio51"; + function = "alt1"; + bias-disable; + }; + }; + + i2c0_gpio46 { + phandle = <0x66>; + + pin-sda { + function = "alt0"; + pins = "gpio46"; + bias-pull-up; + }; + + pin-scl { + function = "alt0"; + pins = "gpio47"; + bias-disable; + }; + }; + + i2c1_gpio46 { + phandle = <0x67>; + + pin-sda { + function = "alt1"; + pins = "gpio46"; + bias-pull-up; + }; + + pin-scl { + function = "alt1"; + pins = "gpio47"; + bias-disable; + }; + }; + + i2c3_gpio2 { + phandle = <0x68>; + + pin-sda { + function = "alt5"; + pins = "gpio2"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio3"; + bias-disable; + }; + }; + + i2c3_gpio4 { + phandle = <0x69>; + + pin-sda { + function = "alt5"; + pins = "gpio4"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio5"; + bias-disable; + }; + }; + + i2c4_gpio6 { + phandle = <0x6a>; + + pin-sda { + function = "alt5"; + pins = "gpio6"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio7"; + bias-disable; + }; + }; + + i2c4_gpio8 { + phandle = <0x6b>; + + pin-sda { + function = "alt5"; + pins = "gpio8"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio9"; + bias-disable; + }; + }; + + i2c5_gpio10 { + phandle = <0x6c>; + + pin-sda { + function = "alt5"; + pins = "gpio10"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio11"; + bias-disable; + }; + }; + + i2c5_gpio12 { + phandle = <0x6d>; + + pin-sda { + function = "alt5"; + pins = "gpio12"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio13"; + bias-disable; + }; + }; + + i2c6_gpio0 { + phandle = <0x6e>; + + pin-sda { + function = "alt5"; + pins = "gpio0"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio1"; + bias-disable; + }; + }; + + i2c6_gpio22 { + phandle = <0x6f>; + + pin-sda { + function = "alt5"; + pins = "gpio22"; + bias-pull-up; + }; + + pin-scl { + function = "alt5"; + pins = "gpio23"; + bias-disable; + }; + }; + + i2c_slave_gpio8 { + phandle = <0x70>; + + pins-i2c-slave { + pins = "gpio8\0gpio9\0gpio10\0gpio11"; + function = "alt3"; + }; + }; + + jtag_gpio48 { + phandle = <0x71>; + + pins-jtag { + pins = "gpio48\0gpio49\0gpio50\0gpio51\0gpio52\0gpio53"; + function = "alt4"; + }; + }; + + mii_gpio28 { + phandle = <0x72>; + + pins-mii { + pins = "gpio28\0gpio29\0gpio30\0gpio31"; + function = "alt4"; + }; + }; + + mii_gpio36 { + phandle = <0x73>; + + pins-mii { + pins = "gpio36\0gpio37\0gpio38\0gpio39"; + function = "alt5"; + }; + }; + + pcm_gpio50 { + phandle = <0x74>; + + pins-pcm { + pins = "gpio50\0gpio51\0gpio52\0gpio53"; + function = "alt2"; + }; + }; + + pwm0_0_gpio12 { + phandle = <0x75>; + + pin-pwm { + pins = "gpio12"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_0_gpio18 { + phandle = <0x76>; + + pin-pwm { + pins = "gpio18"; + function = "alt5"; + bias-disable; + }; + }; + + pwm1_0_gpio40 { + phandle = <0x19>; + + pin-pwm { + pins = "gpio40"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_1_gpio13 { + phandle = <0x77>; + + pin-pwm { + pins = "gpio13"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_1_gpio19 { + phandle = <0x78>; + + pin-pwm { + pins = "gpio19"; + function = "alt5"; + bias-disable; + }; + }; + + pwm1_1_gpio41 { + phandle = <0x1a>; + + pin-pwm { + pins = "gpio41"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_1_gpio45 { + phandle = <0x79>; + + pin-pwm { + pins = "gpio45"; + function = "alt0"; + bias-disable; + }; + }; + + pwm0_0_gpio52 { + phandle = <0x7a>; + + pin-pwm { + pins = "gpio52"; + function = "alt1"; + bias-disable; + }; + }; + + pwm0_1_gpio53 { + phandle = <0x7b>; + + pin-pwm { + pins = "gpio53"; + function = "alt1"; + bias-disable; + }; + }; + + rgmii_gpio35 { + phandle = <0x7c>; + + pin-start-stop { + pins = "gpio35"; + function = "alt4"; + }; + + pin-rx-ok { + pins = "gpio36"; + function = "alt4"; + }; + }; + + rgmii_irq_gpio34 { + phandle = <0x7d>; + + pin-irq { + pins = "gpio34"; + function = "alt5"; + }; + }; + + rgmii_irq_gpio39 { + phandle = <0x7e>; + + pin-irq { + pins = "gpio39"; + function = "alt4"; + }; + }; + + rgmii_mdio_gpio28 { + phandle = <0x7f>; + + pins-mdio { + pins = "gpio28\0gpio29"; + function = "alt5"; + }; + }; + + rgmii_mdio_gpio37 { + phandle = <0x80>; + + pins-mdio { + pins = "gpio37\0gpio38"; + function = "alt4"; + }; + }; + + spi0_gpio46 { + phandle = <0x81>; + + pins-spi { + pins = "gpio46\0gpio47\0gpio48\0gpio49"; + function = "alt2"; + }; + }; + + spi2_gpio46 { + phandle = <0x82>; + + pins-spi { + pins = "gpio46\0gpio47\0gpio48\0gpio49\0gpio50"; + function = "alt5"; + }; + }; + + spi3_gpio0 { + phandle = <0x83>; + + pins-spi { + pins = "gpio0\0gpio1\0gpio2\0gpio3"; + function = "alt3"; + }; + }; + + spi4_gpio4 { + phandle = <0x84>; + + pins-spi { + pins = "gpio4\0gpio5\0gpio6\0gpio7"; + function = "alt3"; + }; + }; + + spi5_gpio12 { + phandle = <0x85>; + + pins-spi { + pins = "gpio12\0gpio13\0gpio14\0gpio15"; + function = "alt3"; + }; + }; + + spi6_gpio18 { + phandle = <0x86>; + + pins-spi { + pins = "gpio18\0gpio19\0gpio20\0gpio21"; + function = "alt3"; + }; + }; + + uart2_gpio0 { + phandle = <0x87>; + + pin-tx { + pins = "gpio0"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio1"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart2_ctsrts_gpio2 { + phandle = <0x88>; + + pin-cts { + pins = "gpio2"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio3"; + function = "alt4"; + bias-disable; + }; + }; + + uart3_gpio4 { + phandle = <0x89>; + + pin-tx { + pins = "gpio4"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio5"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart3_ctsrts_gpio6 { + phandle = <0x8a>; + + pin-cts { + pins = "gpio6"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio7"; + function = "alt4"; + bias-disable; + }; + }; + + uart4_gpio8 { + phandle = <0x8b>; + + pin-tx { + pins = "gpio8"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio9"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart4_ctsrts_gpio10 { + phandle = <0x8c>; + + pin-cts { + pins = "gpio10"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio11"; + function = "alt4"; + bias-disable; + }; + }; + + uart5_gpio12 { + phandle = <0x8d>; + + pin-tx { + pins = "gpio12"; + function = "alt4"; + bias-disable; + }; + + pin-rx { + pins = "gpio13"; + function = "alt4"; + bias-pull-up; + }; + }; + + uart5_ctsrts_gpio14 { + phandle = <0x8e>; + + pin-cts { + pins = "gpio14"; + function = "alt4"; + bias-pull-up; + }; + + pin-rts { + pins = "gpio15"; + function = "alt4"; + bias-disable; + }; + }; + + gpioout { + brcm,pins = <0x06>; + brcm,function = <0x01>; + phandle = <0x8f>; + }; + + alt0 { + brcm,pins = <0x04 0x05 0x07 0x08 0x09 0x0a 0x0b>; + brcm,function = <0x04>; + phandle = <0x90>; + }; + + dpi_18bit_gpio0 { + brcm,pins = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15>; + brcm,function = <0x06>; + phandle = <0x91>; + }; + + spi0_pins { + brcm,pins = <0x09 0x0a 0x0b>; + brcm,function = <0x04>; + phandle = <0x0c>; + }; + + spi0_cs_pins { + brcm,pins = <0x08 0x07>; + brcm,function = <0x01>; + phandle = <0x0d>; + }; + + spi3_pins { + brcm,pins = <0x01 0x02 0x03>; + brcm,function = <0x07>; + phandle = <0x92>; + }; + + spi3_cs_pins { + brcm,pins = <0x00 0x18>; + brcm,function = <0x01>; + phandle = <0x93>; + }; + + spi4_pins { + brcm,pins = <0x05 0x06 0x07>; + brcm,function = <0x07>; + phandle = <0x94>; + }; + + spi4_cs_pins { + brcm,pins = <0x04 0x19>; + brcm,function = <0x01>; + phandle = <0x95>; + }; + + spi5_pins { + brcm,pins = <0x0d 0x0e 0x0f>; + brcm,function = <0x07>; + phandle = <0x96>; + }; + + spi5_cs_pins { + brcm,pins = <0x0c 0x1a>; + brcm,function = <0x01>; + phandle = <0x97>; + }; + + spi6_pins { + brcm,pins = <0x13 0x14 0x15>; + brcm,function = <0x07>; + phandle = <0x98>; + }; + + spi6_cs_pins { + brcm,pins = <0x12 0x1b>; + brcm,function = <0x01>; + phandle = <0x99>; + }; + + i2c0 { + brcm,pins = <0x00 0x01>; + brcm,function = <0x04>; + brcm,pull = <0x02>; + phandle = <0x9a>; + }; + + i2c1 { + brcm,pins = <0x02 0x03>; + brcm,function = <0x04>; + brcm,pull = <0x02>; + phandle = <0x16>; + }; + + i2c3 { + brcm,pins = <0x04 0x05>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9b>; + }; + + i2c4 { + brcm,pins = <0x08 0x09>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9c>; + }; + + i2c5 { + brcm,pins = <0x0c 0x0d>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9d>; + }; + + i2c6 { + brcm,pins = <0x16 0x17>; + brcm,function = <0x02>; + brcm,pull = <0x02>; + phandle = <0x9e>; + }; + + i2s { + brcm,pins = <0x12 0x13 0x14 0x15>; + brcm,function = <0x04>; + phandle = <0x0b>; + }; + + sdio_pins { + brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02 0x02 0x02 0x02 0x02>; + phandle = <0x22>; + }; + + bt_pins { + brcm,pins = "-"; + brcm,function = <0x00>; + brcm,pull = <0x02>; + phandle = <0x09>; + }; + + uart0_pins { + brcm,pins = <0x20 0x21>; + brcm,function = <0x07>; + brcm,pull = <0x00 0x02>; + phandle = <0x08>; + }; + + uart1_pins { + brcm,pins; + brcm,function; + brcm,pull; + phandle = <0x14>; + }; + + uart2_pins { + brcm,pins = <0x00 0x01>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0x9f>; + }; + + uart3_pins { + brcm,pins = <0x04 0x05>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0xa0>; + }; + + uart4_pins { + brcm,pins = <0x08 0x09>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0xa1>; + }; + + uart5_pins { + brcm,pins = <0x0c 0x0d>; + brcm,function = <0x03>; + brcm,pull = <0x00 0x02>; + phandle = <0xa2>; + }; + + audio_pins { + brcm,pins = <0x28 0x29>; + brcm,function = <0x04>; + phandle = <0x20>; + }; + }; + + serial@7e201400 { + compatible = "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; + reg = <0x7e201400 0x200>; + interrupts = <0x00 0x79 0x04>; + clocks = <0x07 0x13 0x07 0x14>; + clock-names = "uartclk\0apb_pclk"; + arm,primecell-periphid = <0x241011>; + uart-has-rtscts; + status = "okay"; + cts-event-workaround; + phandle = <0x2a>; + }; + + i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; + reg = <0x7e203000 0x24>; + clocks = <0x07 0x1f>; + status = "disabled"; + #sound-dai-cells = <0x00>; + dmas = <0x0a 0x02 0x0a 0x03>; + dma-names = "tx\0rx"; + pinctrl-names = "default"; + pinctrl-0 = <0x0b>; + phandle = <0x2c>; + }; + + spi@7e204000 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204000 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + dmas = <0x0a 0x06 0x0a 0x07>; + dma-names = "tx\0rx"; + pinctrl-names = "default"; + pinctrl-0 = <0x0c 0x0d>; + cs-gpios = <0x0e 0x08 0x01 0x0e 0x07 0x01>; + phandle = <0x2d>; + + spidev@0 { + compatible = "spidev"; + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + spi-max-frequency = <0x7735940>; + phandle = <0xa3>; + }; + + spidev@1 { + compatible = "spidev"; + reg = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + spi-max-frequency = <0x7735940>; + phandle = <0xa4>; + }; + }; + + i2c@7e205000 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205000 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + clock-frequency = <0x186a0>; + phandle = <0x0f>; + }; + + i2c0mux { + compatible = "i2c-mux-pinctrl"; + #address-cells = <0x01>; + #size-cells = <0x00>; + i2c-parent = <0x0f>; + pinctrl-names = "i2c0\0i2c_csi_dsi"; + status = "disabled"; + pinctrl-0 = <0x10>; + pinctrl-1 = <0x11>; + phandle = <0x2e>; + + i2c@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0xa5>; + }; + + i2c@1 { + reg = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0xa6>; + }; + }; + + dpi@7e208000 { + compatible = "brcm,bcm2835-dpi"; + reg = <0x7e208000 0x8c>; + clocks = <0x07 0x14 0x07 0x2c>; + clock-names = "core\0pixel"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xa7>; + }; + + dsi@7e209000 { + compatible = "brcm,bcm2835-dsi0"; + reg = <0x7e209000 0x78>; + interrupts = <0x00 0x64 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + clocks = <0x07 0x20 0x07 0x2f 0x07 0x31>; + clock-names = "phy\0escape\0pixel"; + clock-output-names = "dsi0_byte\0dsi0_ddr2\0dsi0_ddr"; + status = "disabled"; + power-domains = <0x12 0x11>; + phandle = <0x04>; + }; + + aux@7e215000 { + compatible = "brcm,bcm2835-aux"; + #clock-cells = <0x01>; + reg = <0x7e215000 0x08>; + clocks = <0x07 0x14>; + phandle = <0x13>; + }; + + spi@7e215080 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e215080 0x40>; + interrupts = <0x00 0x5d 0x04>; + clocks = <0x13 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xa8>; + }; + + spi@7e2150c0 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e2150c0 0x40>; + interrupts = <0x00 0x5d 0x04>; + clocks = <0x13 0x02>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xa9>; + }; + + pwm@7e20c000 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c000 0x28>; + clocks = <0x07 0x1e>; + assigned-clocks = <0x07 0x1e>; + assigned-clock-rates = <0x989680>; + #pwm-cells = <0x02>; + status = "disabled"; + phandle = <0xaa>; + }; + + hvs@7e400000 { + compatible = "brcm,bcm2835-hvs"; + reg = <0x7e400000 0x6000>; + interrupts = <0x00 0x61 0x04>; + clocks = <0x15 0x04>; + status = "disabled"; + phandle = <0xab>; + }; + + dsi@7e700000 { + compatible = "brcm,bcm2835-dsi1"; + reg = <0x7e700000 0x8c>; + interrupts = <0x00 0x6c 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + clocks = <0x07 0x23 0x07 0x30 0x07 0x32>; + clock-names = "phy\0escape\0pixel"; + clock-output-names = "dsi1_byte\0dsi1_ddr2\0dsi1_ddr"; + status = "disabled"; + power-domains = <0x12 0x12>; + phandle = <0x05>; + }; + + i2c@7e804000 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e804000 0x1000>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <0x16>; + clock-frequency = <0x186a0>; + phandle = <0x2f>; + }; + + vec@7e806000 { + compatible = "brcm,bcm2835-vec"; + reg = <0x7e806000 0x1000>; + clocks = <0x07 0x18>; + interrupts = <0x00 0x7b 0x04>; + status = "disabled"; + power-domains = <0x12 0x07>; + phandle = <0xac>; + }; + + usb@7e980000 { + compatible = "brcm,bcm2708-usb"; + reg = <0x7e980000 0x10000 0x7e00b200 0x200>; + interrupts = <0x00 0x49 0x04 0x00 0x28 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x17>; + clock-names = "otg"; + phys = <0x18>; + phy-names = "usb2-phy"; + power-domains = <0x12 0x06>; + interrupt-names = "usb\0soft"; + status = "disabled"; + phandle = <0xad>; + }; + + local_intc@40000000 { + compatible = "brcm,bcm2836-l1-intc"; + reg = <0x40000000 0x100>; + phandle = <0xae>; + }; + + avs-monitor@7d5d2000 { + compatible = "brcm,bcm2711-avs-monitor\0syscon\0simple-mfd"; + reg = <0x7d5d2000 0xf00>; + phandle = <0xaf>; + + thermal { + compatible = "brcm,bcm2711-thermal"; + #thermal-sensor-cells = <0x00>; + phandle = <0x02>; + }; + }; + + dma@7e007000 { + compatible = "brcm,bcm2835-dma"; + reg = <0x7e007000 0xb00>; + interrupts = <0x00 0x50 0x04 0x00 0x51 0x04 0x00 0x52 0x04 0x00 0x53 0x04 0x00 0x54 0x04 0x00 0x55 0x04 0x00 0x56 0x04 0x00 0x57 0x04 0x00 0x57 0x04 0x00 0x58 0x04 0x00 0x58 0x04>; + interrupt-names = "dma0\0dma1\0dma2\0dma3\0dma4\0dma5\0dma6\0dma7\0dma8\0dma9\0dma10"; + #dma-cells = <0x01>; + brcm,dma-channel-mask = <0x1f5>; + phandle = <0x0a>; + }; + + watchdog@7e100000 { + compatible = "brcm,bcm2835-pm\0brcm,bcm2835-pm-wdt"; + #power-domain-cells = <0x01>; + #reset-cells = <0x01>; + reg = <0x7e100000 0x114 0x7e00a000 0x24 0x7ec11000 0x20>; + clocks = <0x07 0x15 0x07 0x1d 0x07 0x17 0x07 0x16>; + clock-names = "v3d\0peri_image\0h264\0isp"; + system-power-controller; + phandle = <0x31>; + }; + + spi@7e204600 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204600 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb4>; + }; + + spi@7e204800 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204800 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb5>; + }; + + spi@7e204a00 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204a00 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb6>; + }; + + spi@7e204c00 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204c00 0x200>; + interrupts = <0x00 0x76 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb7>; + }; + + i2c@7e205600 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205600 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb8>; + }; + + i2c@7e205800 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205800 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xb9>; + }; + + i2c@7e205a00 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205a00 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xba>; + }; + + i2c@7e205c00 { + compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c"; + reg = <0x7e205c00 0x200>; + interrupts = <0x00 0x75 0x04>; + clocks = <0x07 0x14>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xbb>; + }; + + pixelvalve@7e206000 { + compatible = "brcm,bcm2711-pixelvalve0"; + reg = <0x7e206000 0x100>; + interrupts = <0x00 0x6d 0x04>; + status = "disabled"; + phandle = <0xbc>; + }; + + pixelvalve@7e207000 { + compatible = "brcm,bcm2711-pixelvalve1"; + reg = <0x7e207000 0x100>; + interrupts = <0x00 0x6e 0x04>; + status = "disabled"; + phandle = <0xbd>; + }; + + pixelvalve@7e20a000 { + compatible = "brcm,bcm2711-pixelvalve2"; + reg = <0x7e20a000 0x100>; + interrupts = <0x00 0x65 0x04>; + status = "disabled"; + phandle = <0xbe>; + }; + + pwm@7e20c800 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c800 0x28>; + clocks = <0x07 0x1e>; + assigned-clocks = <0x07 0x1e>; + assigned-clock-rates = <0x989680>; + #pwm-cells = <0x02>; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <0x19 0x1a>; + phandle = <0xbf>; + }; + + pixelvalve@7e216000 { + compatible = "brcm,bcm2711-pixelvalve4"; + reg = <0x7e216000 0x100>; + interrupts = <0x00 0x6e 0x04>; + status = "disabled"; + phandle = <0xc0>; + }; + + pixelvalve@7ec12000 { + compatible = "brcm,bcm2711-pixelvalve3"; + reg = <0x7ec12000 0x100>; + interrupts = <0x00 0x6a 0x04>; + status = "disabled"; + phandle = <0xc1>; + }; + + clock@7ef00000 { + compatible = "brcm,brcm2711-dvp"; + reg = <0x7ef00000 0x10>; + clocks = <0x1b>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + phandle = <0x1c>; + }; + + hdmi@7ef00700 { + compatible = "brcm,bcm2711-hdmi0"; + reg = <0x7ef00700 0x300 0x7ef00300 0x200 0x7ef00f00 0x80 0x7ef00f80 0x80 0x7ef01b00 0x200 0x7ef01f00 0x400 0x7ef00200 0x80 0x7ef04300 0x100 0x7ef20000 0x100 0x7ef00100 0x30>; + reg-names = "hdmi\0dvp\0phy\0rm\0packet\0metadata\0csc\0cec\0hd\0intr2"; + clocks = <0x15 0x0d>; + clock-names = "hdmi"; + resets = <0x1c 0x00>; + ddc = <0x1d>; + dmas = <0x0a 0x0a>; + dma-names = "audio-rx"; + interrupts = <0x00 0x60 0x04>; + status = "disabled"; + phandle = <0xc2>; + }; + + i2c@7ef04500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef04500 0x100 0x7ef00b00 0x300>; + reg-names = "bsc\0auto-i2c"; + clock-frequency = <0x17cdc>; + status = "disabled"; + phandle = <0x1d>; + }; + + hdmi@7ef05700 { + compatible = "brcm,bcm2711-hdmi1"; + reg = <0x7ef05700 0x300 0x7ef05300 0x200 0x7ef05f00 0x80 0x7ef05f80 0x80 0x7ef06b00 0x200 0x7ef06f00 0x400 0x7ef00280 0x80 0x7ef09300 0x100 0x7ef20000 0x100 0x7ef00100 0x30>; + reg-names = "hdmi\0dvp\0phy\0rm\0packet\0metadata\0csc\0cec\0hd\0intr2"; + ddc = <0x1e>; + clocks = <0x15 0x0d>; + clock-names = "hdmi"; + resets = <0x1c 0x01>; + dmas = <0x0a 0x11>; + dma-names = "audio-rx"; + interrupts = <0x00 0x60 0x04>; + status = "disabled"; + phandle = <0xc3>; + }; + + i2c@7ef09500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef09500 0x100 0x7ef05b00 0x300>; + reg-names = "bsc\0auto-i2c"; + clock-frequency = <0x17cdc>; + status = "disabled"; + phandle = <0x1e>; + }; + + firmware { + compatible = "raspberrypi,bcm2835-firmware\0simple-bus"; + mboxes = <0x1f>; + dma-ranges; + phandle = <0x06>; + + gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; + #gpio-cells = <0x02>; + gpio-line-names = "BT_ON\0WL_ON\0PWR_LED_OFF\0GLOBAL_RESET\0VDD_SD_IO_SEL\0CAM_GPIO\0SD_PWR_ON\0SD_OC_N"; + status = "okay"; + phandle = <0x29>; + }; + }; + + power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <0x06>; + #power-domain-cells = <0x01>; + phandle = <0x12>; + }; + + firmwarekms@7e600000 { + compatible = "raspberrypi,rpi-firmware-kms"; + reg = <0x7e600000 0x100>; + interrupts = <0x00 0x70 0x04>; + brcm,firmware = <0x06>; + status = "disabled"; + phandle = <0xc5>; + }; + + smi@7e600000 { + compatible = "brcm,bcm2835-smi"; + reg = <0x7e600000 0x100>; + interrupts = <0x00 0x70 0x04>; + clocks = <0x07 0x2a>; + assigned-clocks = <0x07 0x2a>; + assigned-clock-rates = <0x7735940>; + dmas = <0x0a 0x04>; + dma-names = "rx-tx"; + status = "disabled"; + phandle = <0xc6>; + }; + + csi@7e800000 { + compatible = "brcm,bcm2835-unicam"; + reg = <0x7e800000 0x800 0x7e802000 0x04>; + interrupts = <0x00 0x66 0x04>; + clocks = <0x07 0x2d>; + clock-names = "lp"; + power-domains = <0x12 0x0c>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + status = "disabled"; + phandle = <0xc7>; + }; + + csi@7e801000 { + compatible = "brcm,bcm2835-unicam"; + reg = <0x7e801000 0x800 0x7e802004 0x04>; + interrupts = <0x00 0x67 0x04>; + clocks = <0x07 0x2e>; + clock-names = "lp"; + power-domains = <0x12 0x0d>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #clock-cells = <0x01>; + status = "disabled"; + phandle = <0xc8>; + + port { + + endpoint { + data-lanes = <0x01 0x02>; + }; + }; + }; + + axiperf { + compatible = "brcm,bcm2835-axiperf"; + reg = <0x7e009800 0x100 0x7ee08000 0x100>; + firmware = <0x06>; + status = "disabled"; + phandle = <0x36>; + }; + + gpiomem { + compatible = "brcm,bcm2835-gpiomem"; + reg = <0x7e200000 0x1000>; + }; + + fb { + compatible = "brcm,bcm2708-fb"; + firmware = <0x06>; + status = "okay"; + phandle = <0xc9>; + }; + + vcsm { + compatible = "raspberrypi,bcm2835-vcsm"; + firmware = <0x06>; + status = "okay"; + phandle = <0xca>; + }; + + sound { + status = "disabled"; + phandle = <0xcb>; + }; + }; + + clocks { + + clk-osc { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-output-names = "osc"; + clock-frequency = <0x337f980>; + phandle = <0x03>; + }; + + clk-usb { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-output-names = "otg"; + clock-frequency = <0x1c9c3800>; + phandle = <0x17>; + }; + }; + + phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0x00>; + phandle = <0x18>; + }; + + gpu { + compatible = "brcm,bcm2711-vc5"; + status = "disabled"; + phandle = <0xcc>; + }; + + clk-108M { + #clock-cells = <0x00>; + compatible = "fixed-clock"; + clock-frequency = <0x66ff300>; + clock-output-names = "108MHz-clock"; + phandle = <0x1b>; + }; + + firmware-clocks { + compatible = "raspberrypi,firmware-clocks"; + raspberrypi,firmware = <0x06>; + #clock-cells = <0x01>; + phandle = <0x15>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf08 0x01 0x0e 0xf08 0x01 0x0b 0xf08 0x01 0x0a 0xf08>; + arm,cpu-registers-not-fw-configured; + }; + + cpus { + #address-cells = <0x01>; + #size-cells = <0x00>; + + cpu@0 { + reg = <0x00>; + compatible = "arm,cortex-a72"; + device_type = "cpu"; + enable-method = "psci"; + phandle = <0x23>; + }; + }; + + scb { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x7c000000 0x00 0xfc000000 0x00 0x3800000 0x00 0x40000000 0x00 0xff800000 0x00 0x800000 0x06 0x00 0x06 0x00 0x00 0x40000000 0x00 0x00 0x00 0x00 0x00 0xfc000000>; + dma-ranges = <0x00 0x00 0x00 0x00 0x00 0xfc000000 0x01 0x00 0x01 0x00 0x01 0x00>; + phandle = <0xce>; + + pcie@7d500000 { + compatible = "brcm,bcm2711-pcie"; + reg = <0x00 0x7d500000 0x00 0x9310>; + device_type = "pci"; + #address-cells = <0x03>; + #interrupt-cells = <0x01>; + #size-cells = <0x02>; + interrupts = <0x00 0x94 0x04 0x00 0x94 0x04>; + interrupt-names = "pcie\0msi"; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x01 0x00 0x8f 0x04>; + msi-controller; + msi-parent = <0x27>; + ranges = <0x2000000 0x00 0xf8000000 0x06 0x00 0x00 0x4000000>; + dma-ranges = <0x2000000 0x00 0x00 0x00 0x00 0x00 0xc0000000>; + brcm,enable-ssc; + phandle = <0x27>; + }; + + ethernet@7d580000 { + compatible = "brcm,bcm2711-genet-v5\0brcm,genet-v5"; + reg = <0x00 0x7d580000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + interrupts = <0x00 0x9d 0x04 0x00 0x9e 0x04>; + status = "okay"; + phy-handle = <0x28>; + phy-mode = "rgmii-rxid"; + phandle = <0xcf>; + local-mac-address = [dc a6 32 74 0a 64]; + + mdio@e14 { + compatible = "brcm,genet-mdio-v5"; + reg = <0xe14 0x08>; + reg-names = "mdio"; + #address-cells = <0x00>; + #size-cells = <0x01>; + phandle = <0xd0>; + + ethernet-phy@1 { + reg = <0x01>; + led-modes = <0x00 0x08>; + phandle = <0x28>; + }; + }; + }; + + dma@7e007b00 { + compatible = "brcm,bcm2711-dma"; + reg = <0x00 0x7e007b00 0x00 0x400>; + interrupts = <0x00 0x59 0x04 0x00 0x5a 0x04 0x00 0x5b 0x04 0x00 0x5c 0x04>; + interrupt-names = "dma11\0dma12\0dma13\0dma14"; + #dma-cells = <0x01>; + brcm,dma-channel-mask = <0x7000>; + phandle = <0x3a>; + }; + + xhci@7e9c0000 { + compatible = "generic-xhci"; + status = "disabled"; + reg = <0x00 0x7e9c0000 0x00 0x100000>; + interrupts = <0x00 0xb0 0x04>; + phandle = <0xd1>; + }; + + hevc-decoder@7eb00000 { + compatible = "raspberrypi,rpivid-hevc-decoder"; + reg = <0x00 0x7eb00000 0x00 0x10000>; + status = "okay"; + }; + + rpivid-local-intc@7eb10000 { + compatible = "raspberrypi,rpivid-local-intc"; + reg = <0x00 0x7eb10000 0x00 0x1000>; + status = "okay"; + interrupts = <0x00 0x62 0x04>; + }; + + h264-decoder@7eb20000 { + compatible = "raspberrypi,rpivid-h264-decoder"; + reg = <0x00 0x7eb20000 0x00 0x10000>; + status = "okay"; + }; + + vp9-decoder@7eb30000 { + compatible = "raspberrypi,rpivid-vp9-decoder"; + reg = <0x00 0x7eb30000 0x00 0x10000>; + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + phandle = <0xd2>; + + act { + label = "led0"; + default-state = "keep"; + linux,default-trigger = "mmc0"; + gpios = <0x0e 0x2a 0x00>; + phandle = <0x38>; + }; + + pwr { + label = "led1"; + gpios = <0x29 0x02 0x01>; + linux,default-trigger = "default-on"; + phandle = <0x39>; + }; + }; + + __overrides__ { + cam0-pwdn-ctrl; + cam0-pwdn; + cam0-led-ctrl; + cam0-led; + cache_line_size; + uart0 = "\0\0\0*status"; + uart1 = "\0\0\0+status"; + i2s = "\0\0\0,status"; + spi = "\0\0\0-status"; + i2c0 = [00 00 00 0f 73 74 61 74 75 73 00 00 00 00 2e 73 74 61 74 75 73 00]; + i2c1 = "\0\0\0/status"; + i2c0_baudrate = [00 00 00 0f 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00]; + i2c1_baudrate = "\0\0\0/clock-frequency:0"; + audio = "\0\0\0status"; + watchdog = [00 00 01 73 74 61 74 75 73 00]; + random = [00 00 02 73 74 61 74 75 73 00]; + axiperf = [00 00 06 73 74 61 74 75 73 00]; + arm_freq; + act_led_gpio = "\0\0\08gpios:4"; + act_led_activelow = "\0\0\08gpios:8"; + act_led_trigger = "\0\0\08linux,default-trigger"; + pwr_led_gpio = "\0\0\09gpios:4"; + pwr_led_activelow = "\0\0\09gpios:8"; + pwr_led_trigger = "\0\0\09linux,default-trigger"; + eth_led0 = "\0\0\0(led-modes:0"; + eth_led1 = "\0\0\0(led-modes:4"; + spi_dma4 = <0x2d 0x646d6173 0x3a303d00 0x3a 0x2d 0x646d6173 0x3a383d00 0x3a>; + }; + + fixedregulator_3v3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <0x325aa0>; + regulator-min-microvolt = <0x325aa0>; + regulator-name = "3v3"; + phandle = <0xd3>; + }; + + fixedregulator_5v0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <0x4c4b40>; + regulator-min-microvolt = <0x4c4b40>; + regulator-name = "5v0"; + phandle = <0xd4>; + }; + + v3dbus { + compatible = "simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x02>; + ranges = <0x7c500000 0x00 0xfc500000 0x00 0x3300000 0x40000000 0x00 0xff800000 0x00 0x800000>; + dma-ranges = <0x00 0x00 0x00 0x04 0x00>; + phandle = <0xd5>; + + v3d@7ec04000 { + compatible = "brcm,2711-v3d"; + reg = <0x7ec00000 0x00 0x4000 0x7ec04000 0x00 0x4000>; + reg-names = "hub\0core0"; + power-domains = <0x31 0x01>; + resets = <0x31 0x00>; + clocks = <0x15 0x05>; + clocks-names = "v3d"; + interrupts = <0x00 0x4a 0x04>; + status = "disabled"; + phandle = <0xd6>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + status = "okay"; + }; + + interrupt-controller@fff841000 { + interrupt-controller; + #interrupt-cells = <0x03>; + compatible = "arm,gic-400"; + reg = <0x0f 0xff841000 0x00 0x1000 0x0f 0xff842000 0x00 0x2000>; + phandle = <0x01>; + }; + + memory@200000 { + device_type = "memory"; + reg = <0x00 0x200000 0x00 0x3de00000>; + }; + + virtio_net@fa000800 { + dma-coherent; + compatible = "virtio,mmio"; + interrupts = <0x00 0x17 0x01>; + reg = <0x00 0xfa000800 0x00 0x400>; + }; + + virtio_console@fa000c00 { + dma-coherent; + compatible = "virtio,mmio"; + interrupts = <0x00 0x20 0x01>; + reg = <0x00 0xfa000c00 0x00 0x1000>; + }; + + virtio_console@fa002000 { + dma-coherent; + compatible = "virtio,mmio"; + interrupts = <0x00 0x18 0x01>; + reg = <0x00 0xfa002000 0x00 0x1000>; + }; + + vm_service { + compatible = "shyper"; + interrupts = <0x00 0x10 0x01>; + }; +}; diff --git a/image/pi4_fin.dtb b/image/pi4_fin.dtb new file mode 100644 index 0000000000000000000000000000000000000000..d855798972284675732077a5ff19d80a5acbdbc9 Binary files /dev/null and b/image/pi4_fin.dtb differ diff --git a/image/rootfs.cpio b/image/rootfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..60e06f368d54d6376ca277516c6e4828fd649401 Binary files /dev/null and b/image/rootfs.cpio differ diff --git a/image/rootfs_ssh.cpio b/image/rootfs_ssh.cpio new file mode 100755 index 0000000000000000000000000000000000000000..19e97134accd03616ccd1a3616da08d0063fb0b9 Binary files /dev/null and b/image/rootfs_ssh.cpio differ diff --git a/image/sbma.bin b/image/sbma.bin new file mode 100755 index 0000000000000000000000000000000000000000..0c7f3e68000cfb6e873422a21939c4edffa07514 Binary files /dev/null and b/image/sbma.bin differ diff --git a/image/vm0.dtb b/image/vm0.dtb new file mode 100644 index 0000000000000000000000000000000000000000..a1eb44119adc573d6e1177f96bf457c542c7a33f Binary files /dev/null and b/image/vm0.dtb differ diff --git a/image/vm1_arch_Image b/image/vm1_arch_Image new file mode 100755 index 0000000000000000000000000000000000000000..6dbd6bf18083a693cae5ba31cb3f554e62d26dbd Binary files /dev/null and b/image/vm1_arch_Image differ diff --git a/lib/libfdt-binding.a b/lib/libfdt-binding.a new file mode 100644 index 0000000000000000000000000000000000000000..e582b27180f38def26de3e69c9aa3529159e8953 Binary files /dev/null and b/lib/libfdt-binding.a differ diff --git a/lib/libtegra.a b/lib/libtegra.a new file mode 100644 index 0000000000000000000000000000000000000000..3500a618de3e1085b19b8a26cdcb5c2122371f83 Binary files /dev/null and b/lib/libtegra.a differ diff --git a/lib/tegra186_emmc.c.o b/lib/tegra186_emmc.c.o new file mode 100644 index 0000000000000000000000000000000000000000..3670f357ba5390e42cb84cb068844d4c3ab56bc1 Binary files /dev/null and b/lib/tegra186_emmc.c.o differ diff --git a/libfdt-binding/.gitignore b/libfdt-binding/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1b26c7816f645916f2c9e150bdd97c72142a0db1 --- /dev/null +++ b/libfdt-binding/.gitignore @@ -0,0 +1,9 @@ +/target + + +# Added by cargo +# +# already existing elements were commented out + +#/target +Cargo.lock diff --git a/libfdt-binding/CMakeLists.txt b/libfdt-binding/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0d27691a898c6bd5313984fb9f526910335b147e --- /dev/null +++ b/libfdt-binding/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.9) +project(libfdt-binding) + +# set(CMAKE_BUILD_TYPE "Release") + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_COMPILER aarch64-elf-gcc) +set(CMAKE_ASM_COMPILER aarch64-elf-gcc) +# set(CMAKE_C_FLAGS_RELEASE "-O3") + +include_directories(.) + +add_library(fdt-binding STATIC + "fdt.c" + "fdt.h" + "fdt_addresses.c" + "fdt_check.c" + "fdt_empty_tree.c" + "fdt_overlay.c" + "fdt_ro.c" + "fdt_rw.c" + "fdt_strerror.c" + "fdt_sw.c" + "fdt_wip.c" + "libfdt.h" + "libfdt_env.h" + "libfdt_internal.h" + "wrapper.c" + "wrapper.h" + "mystr.c" +) diff --git a/libfdt-binding/Cargo.toml b/libfdt-binding/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..0d2d370ab671bca17037d5ccde6b24489c956ef5 --- /dev/null +++ b/libfdt-binding/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "fdt" +version = "0.1.0" +edition = "2021" +build = "build.rs" + +[build-dependencies] +bindgen = "0.59.1" diff --git a/libfdt-binding/README.md b/libfdt-binding/README.md new file mode 100644 index 0000000000000000000000000000000000000000..017316b49dcbfc59f20b5b8c1805ae45e876d550 --- /dev/null +++ b/libfdt-binding/README.md @@ -0,0 +1,4 @@ +1. build `libfdt-binding.a` with cmake +2. copy `libfdt-binding.a` to Rust link search path +3. add `cargo:rustc-link-lib=static=fdt-binding` to `build.rs` +4. add `libfdt-binding` crate to `Cargo.toml` \ No newline at end of file diff --git a/libfdt-binding/build.rs b/libfdt-binding/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..9269360ae475e23c0b685840d910abc14a8891a4 --- /dev/null +++ b/libfdt-binding/build.rs @@ -0,0 +1,33 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +extern crate bindgen; + +use std::env; +use std::path::PathBuf; + +fn main() { + println!("cargo:rerun-if-changed=wrapper.h"); + + let bindings = bindgen::Builder::default() + .clang_arg("-target") + .clang_arg("aarch64") + .use_core() + .ctypes_prefix("myctypes") + .header("wrapper.h") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/libfdt-binding/fdt.c b/libfdt-binding/fdt.c new file mode 100644 index 0000000000000000000000000000000000000000..0de3a1c70ef101d96d813fc752c9b5479c25175e --- /dev/null +++ b/libfdt-binding/fdt.c @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +/* + * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks + * that the given buffer contains what appears to be a flattened + * device tree with sane information in its header. + */ +int32_t fdt_ro_probe_(const void *fdt) { + uint32_t totalsize = fdt_totalsize(fdt); + + if (can_assume(VALID_DTB)) + return totalsize; + + /* The device tree must be at an 8-byte aligned address */ + if ((uintptr_t) fdt & 7) + return -FDT_ERR_ALIGNMENT; + + if (fdt_magic(fdt) == FDT_MAGIC) { + /* Complete tree */ + if (!can_assume(LATEST)) { + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + if (fdt_last_comp_version(fdt) > + FDT_LAST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + } + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + /* Unfinished sequential-write blob */ + if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0) + return -FDT_ERR_BADSTATE; + } else { + return -FDT_ERR_BADMAGIC; + } + + if (totalsize < INT32_MAX) + return totalsize; + else + return -FDT_ERR_TRUNCATED; +} + +static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off) { + return (off >= hdrsize) && (off <= totalsize); +} + +static int check_block_(uint32_t hdrsize, uint32_t totalsize, + uint32_t base, uint32_t size) { + if (!check_off_(hdrsize, totalsize, base)) + return 0; /* block start out of bounds */ + if ((base + size) < base) + return 0; /* overflow */ + if (!check_off_(hdrsize, totalsize, base + size)) + return 0; /* block end out of bounds */ + return 1; +} + +size_t fdt_header_size_(uint32_t version) { + if (version <= 1) + return FDT_V1_SIZE; + else if (version <= 2) + return FDT_V2_SIZE; + else if (version <= 3) + return FDT_V3_SIZE; + else if (version <= 16) + return FDT_V16_SIZE; + else + return FDT_V17_SIZE; +} + +size_t fdt_header_size(const void *fdt) { + return can_assume(LATEST) ? FDT_V17_SIZE : + fdt_header_size_(fdt_version(fdt)); +} + +int fdt_check_header(const void *fdt) { + size_t hdrsize; + + /* The device tree must be at an 8-byte aligned address */ + if ((uintptr_t) fdt & 7) + return -FDT_ERR_ALIGNMENT; + + if (fdt_magic(fdt) != FDT_MAGIC) + return -FDT_ERR_BADMAGIC; + if (!can_assume(LATEST)) { + if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + || (fdt_last_comp_version(fdt) > + FDT_LAST_SUPPORTED_VERSION)) + return -FDT_ERR_BADVERSION; + if (fdt_version(fdt) < fdt_last_comp_version(fdt)) + return -FDT_ERR_BADVERSION; + } + hdrsize = fdt_header_size(fdt); + if (!can_assume(VALID_DTB)) { + + if ((fdt_totalsize(fdt) < hdrsize) + || (fdt_totalsize(fdt) > INT_MAX)) + return -FDT_ERR_TRUNCATED; + + /* Bounds check memrsv block */ + if (!check_off_(hdrsize, fdt_totalsize(fdt), + fdt_off_mem_rsvmap(fdt))) + return -FDT_ERR_TRUNCATED; + } + + if (!can_assume(VALID_DTB)) { + /* Bounds check structure block */ + if (!can_assume(LATEST) && fdt_version(fdt) < 17) { + if (!check_off_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_struct(fdt))) + return -FDT_ERR_TRUNCATED; + } else { + if (!check_block_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_struct(fdt), + fdt_size_dt_struct(fdt))) + return -FDT_ERR_TRUNCATED; + } + + /* Bounds check strings block */ + if (!check_block_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_strings(fdt), + fdt_size_dt_strings(fdt))) + return -FDT_ERR_TRUNCATED; + } + + return 0; +} + +const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) { + unsigned int uoffset = offset; + unsigned int absoffset = offset + fdt_off_dt_struct(fdt); + + if (offset < 0) + return NULL; + + if (!can_assume(VALID_INPUT)) + if ((absoffset < uoffset) + || ((absoffset + len) < absoffset) + || (absoffset + len) > fdt_totalsize(fdt)) + return NULL; + + if (can_assume(LATEST) || fdt_version(fdt) >= 0x11) + if (((uoffset + len) < uoffset) + || ((offset + len) > fdt_size_dt_struct(fdt))) + return NULL; + + return fdt_offset_ptr_(fdt, offset); +} + +uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) { + const fdt32_t *tagp, *lenp; + uint32_t tag; + int offset = startoffset; + const char *p; + + *nextoffset = -FDT_ERR_TRUNCATED; + tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); + if (!can_assume(VALID_DTB) && !tagp) + return FDT_END; /* premature end */ + tag = fdt32_to_cpu(*tagp); + offset += FDT_TAGSIZE; + + *nextoffset = -FDT_ERR_BADSTRUCTURE; + switch (tag) { + case FDT_BEGIN_NODE: + /* skip name */ + do { + p = fdt_offset_ptr(fdt, offset++, 1); + } while (p && (*p != '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + break; + + case FDT_PROP: + lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); + if (!can_assume(VALID_DTB) && !lenp) + return FDT_END; /* premature end */ + /* skip-name offset, length and value */ + offset += sizeof(struct fdt_property) - FDT_TAGSIZE + + fdt32_to_cpu(*lenp); + if (!can_assume(LATEST) && + fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && + ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) + offset += 4; + break; + + case FDT_END: + case FDT_END_NODE: + case FDT_NOP: + break; + + default: + return FDT_END; + } + + if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) + return FDT_END; /* premature end */ + + *nextoffset = FDT_TAGALIGN(offset); + return tag; +} + +int fdt_check_node_offset_(const void *fdt, int offset) { + if (!can_assume(VALID_INPUT) + && ((offset < 0) || (offset % FDT_TAGSIZE))) + return -FDT_ERR_BADOFFSET; + + if (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + + return offset; +} + +int fdt_check_prop_offset_(const void *fdt, int offset) { + if (!can_assume(VALID_INPUT) + && ((offset < 0) || (offset % FDT_TAGSIZE))) + return -FDT_ERR_BADOFFSET; + + if (fdt_next_tag(fdt, offset, &offset) != FDT_PROP) + return -FDT_ERR_BADOFFSET; + + return offset; +} + +int fdt_next_node(const void *fdt, int offset, int *depth) { + int nextoffset = 0; + uint32_t tag; + + if (offset >= 0) + if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0) + return nextoffset; + + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_PROP: + case FDT_NOP: + break; + + case FDT_BEGIN_NODE: + if (depth) + (*depth)++; + break; + + case FDT_END_NODE: + if (depth && ((--(*depth)) < 0)) + return nextoffset; + break; + + case FDT_END: + if ((nextoffset >= 0) + || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) + return -FDT_ERR_NOTFOUND; + else + return nextoffset; + } + } while (tag != FDT_BEGIN_NODE); + + return offset; +} + +int fdt_first_subnode(const void *fdt, int offset) { + int depth = 0; + + offset = fdt_next_node(fdt, offset, &depth); + if (offset < 0 || depth != 1) + return -FDT_ERR_NOTFOUND; + + return offset; +} + +int fdt_next_subnode(const void *fdt, int offset) { + int depth = 1; + + /* + * With respect to the parent, the depth of the next subnode will be + * the same as the last. + */ + do { + offset = fdt_next_node(fdt, offset, &depth); + if (offset < 0 || depth < 1) + return -FDT_ERR_NOTFOUND; + } while (depth > 1); + + return offset; +} + +const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) { + int len = strlen(s) + 1; + const char *last = strtab + tabsize - len; + const char *p; + + for (p = strtab; p <= last; p++) + if (memcmp(p, s, len) == 0) + return p; + return NULL; +} + +int fdt_move(const void *fdt, void *buf, int bufsize) { + if (!can_assume(VALID_INPUT) && bufsize < 0) + return -FDT_ERR_NOSPACE; + + FDT_RO_PROBE(fdt); + + if (fdt_totalsize(fdt) > (unsigned int) bufsize) + return -FDT_ERR_NOSPACE; + + memmove(buf, fdt, fdt_totalsize(fdt)); + return 0; +} diff --git a/libfdt-binding/fdt.h b/libfdt-binding/fdt.h new file mode 100644 index 0000000000000000000000000000000000000000..f2e68807f277c5009641c54f5198bebb7cb1c28f --- /dev/null +++ b/libfdt-binding/fdt.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ +#ifndef FDT_H +#define FDT_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * Copyright 2012 Kim Phillips, Freescale Semiconductor. + */ + +#ifndef __ASSEMBLY__ + +struct fdt_header { + fdt32_t magic; /* magic word FDT_MAGIC */ + fdt32_t totalsize; /* total size of DT block */ + fdt32_t off_dt_struct; /* offset to structure */ + fdt32_t off_dt_strings; /* offset to strings */ + fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ + fdt32_t version; /* format version */ + fdt32_t last_comp_version; /* last compatible version */ + + /* version 2 fields below */ + fdt32_t boot_cpuid_phys; /* Which physical CPU id we're + booting on */ + /* version 3 fields below */ + fdt32_t size_dt_strings; /* size of the strings block */ + + /* version 17 fields below */ + fdt32_t size_dt_struct; /* size of the structure block */ +}; + +struct fdt_reserve_entry { + fdt64_t address; + fdt64_t size; +}; + +struct fdt_node_header { + fdt32_t tag; + char name[0]; +}; + +struct fdt_property { + fdt32_t tag; + fdt32_t len; + fdt32_t nameoff; + char data[0]; +}; + +#endif /* !__ASSEMBLY */ + +#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ +#define FDT_TAGSIZE sizeof(fdt32_t) + +#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ +#define FDT_END_NODE 0x2 /* End node */ +#define FDT_PROP 0x3 /* Property: name off, + size, content */ +#define FDT_NOP 0x4 /* nop */ +#define FDT_END 0x9 + +#define FDT_V1_SIZE (7*sizeof(fdt32_t)) +#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) +#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) +#define FDT_V16_SIZE FDT_V3_SIZE +#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) + +#endif /* FDT_H */ diff --git a/libfdt-binding/fdt_addresses.c b/libfdt-binding/fdt_addresses.c new file mode 100644 index 0000000000000000000000000000000000000000..9a82cd0ba2f9714c748d40ba75cd61cb6fe25005 --- /dev/null +++ b/libfdt-binding/fdt_addresses.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2014 David Gibson + * Copyright (C) 2018 embedded brains GmbH + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int fdt_cells(const void *fdt, int nodeoffset, const char *name) +{ + const fdt32_t *c; + uint32_t val; + int len; + + c = fdt_getprop(fdt, nodeoffset, name, &len); + if (!c) + return len; + + if (len != sizeof(*c)) + return -FDT_ERR_BADNCELLS; + + val = fdt32_to_cpu(*c); + if (val > FDT_MAX_NCELLS) + return -FDT_ERR_BADNCELLS; + + return (int)val; +} + +int fdt_address_cells(const void *fdt, int nodeoffset) +{ + int val; + + val = fdt_cells(fdt, nodeoffset, "#address-cells"); + if (val == 0) + return -FDT_ERR_BADNCELLS; + if (val == -FDT_ERR_NOTFOUND) + return 2; + return val; +} + +int fdt_size_cells(const void *fdt, int nodeoffset) +{ + int val; + + val = fdt_cells(fdt, nodeoffset, "#size-cells"); + if (val == -FDT_ERR_NOTFOUND) + return 1; + return val; +} + +/* This function assumes that [address|size]_cells is 1 or 2 */ +int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, + const char *name, uint64_t addr, uint64_t size) +{ + int addr_cells, size_cells, ret; + uint8_t data[sizeof(fdt64_t) * 2], *prop; + + ret = fdt_address_cells(fdt, parent); + if (ret < 0) + return ret; + addr_cells = ret; + + ret = fdt_size_cells(fdt, parent); + if (ret < 0) + return ret; + size_cells = ret; + + /* check validity of address */ + prop = data; + if (addr_cells == 1) { + if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size)) + return -FDT_ERR_BADVALUE; + + fdt32_st(prop, (uint32_t)addr); + } else if (addr_cells == 2) { + fdt64_st(prop, addr); + } else { + return -FDT_ERR_BADNCELLS; + } + + /* check validity of size */ + prop += addr_cells * sizeof(fdt32_t); + if (size_cells == 1) { + if (size > UINT32_MAX) + return -FDT_ERR_BADVALUE; + + fdt32_st(prop, (uint32_t)size); + } else if (size_cells == 2) { + fdt64_st(prop, size); + } else { + return -FDT_ERR_BADNCELLS; + } + + return fdt_appendprop(fdt, nodeoffset, name, data, + (addr_cells + size_cells) * sizeof(fdt32_t)); +} diff --git a/libfdt-binding/fdt_check.c b/libfdt-binding/fdt_check.c new file mode 100644 index 0000000000000000000000000000000000000000..fa410a86e28289a93ac9931bb3f7f64b9ecc548c --- /dev/null +++ b/libfdt-binding/fdt_check.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +int fdt_check_full(const void *fdt, size_t bufsize) +{ + int err; + int num_memrsv; + int offset, nextoffset = 0; + uint32_t tag; + unsigned int depth = 0; + const void *prop; + const char *propname; + bool expect_end = false; + + if (bufsize < FDT_V1_SIZE) + return -FDT_ERR_TRUNCATED; + if (bufsize < fdt_header_size(fdt)) + return -FDT_ERR_TRUNCATED; + err = fdt_check_header(fdt); + if (err != 0) + return err; + if (bufsize < fdt_totalsize(fdt)) + return -FDT_ERR_TRUNCATED; + + num_memrsv = fdt_num_mem_rsv(fdt); + if (num_memrsv < 0) + return num_memrsv; + + while (1) { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + if (nextoffset < 0) + return nextoffset; + + /* If we see two root nodes, something is wrong */ + if (expect_end && tag != FDT_END) + return -FDT_ERR_BADSTRUCTURE; + + switch (tag) { + case FDT_NOP: + break; + + case FDT_END: + if (depth != 0) + return -FDT_ERR_BADSTRUCTURE; + return 0; + + case FDT_BEGIN_NODE: + depth++; + if (depth > INT_MAX) + return -FDT_ERR_BADSTRUCTURE; + + /* The root node must have an empty name */ + if (depth == 1) { + const char *name; + int len; + + name = fdt_get_name(fdt, offset, &len); + if (*name || len) + return -FDT_ERR_BADSTRUCTURE; + } + break; + + case FDT_END_NODE: + if (depth == 0) + return -FDT_ERR_BADSTRUCTURE; + depth--; + if (depth == 0) + expect_end = true; + break; + + case FDT_PROP: + prop = fdt_getprop_by_offset(fdt, offset, &propname, + &err); + if (!prop) + return err; + break; + + default: + return -FDT_ERR_INTERNAL; + } + } +} diff --git a/libfdt-binding/fdt_empty_tree.c b/libfdt-binding/fdt_empty_tree.c new file mode 100644 index 0000000000000000000000000000000000000000..49d54d44b8e78be6d110c41db97312ef66ff89aa --- /dev/null +++ b/libfdt-binding/fdt_empty_tree.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2012 David Gibson, IBM Corporation. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +int fdt_create_empty_tree(void *buf, int bufsize) +{ + int err; + + err = fdt_create(buf, bufsize); + if (err) + return err; + + err = fdt_finish_reservemap(buf); + if (err) + return err; + + err = fdt_begin_node(buf, ""); + if (err) + return err; + + err = fdt_end_node(buf); + if (err) + return err; + + err = fdt_finish(buf); + if (err) + return err; + + return fdt_open_into(buf, buf, bufsize); +} diff --git a/libfdt-binding/fdt_overlay.c b/libfdt-binding/fdt_overlay.c new file mode 100644 index 0000000000000000000000000000000000000000..d217e79b672299f858a9b242e724e13cb53f110f --- /dev/null +++ b/libfdt-binding/fdt_overlay.c @@ -0,0 +1,882 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2016 Free Electrons + * Copyright (C) 2016 NextThing Co. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +/** + * overlay_get_target_phandle - retrieves the target phandle of a fragment + * @fdto: pointer to the device tree overlay blob + * @fragment: node offset of the fragment in the overlay + * + * overlay_get_target_phandle() retrieves the target phandle of an + * overlay fragment when that fragment uses a phandle (target + * property) instead of a path (target-path property). + * + * returns: + * the phandle pointed by the target property + * 0, if the phandle was not found + * -1, if the phandle was malformed + */ +static uint32_t overlay_get_target_phandle(const void *fdto, int fragment) +{ + const fdt32_t *val; + int len; + + val = fdt_getprop(fdto, fragment, "target", &len); + if (!val) + return 0; + + if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1)) + return (uint32_t)-1; + + return fdt32_to_cpu(*val); +} + +/** + * overlay_get_target - retrieves the offset of a fragment's target + * @fdt: Base device tree blob + * @fdto: Device tree overlay blob + * @fragment: node offset of the fragment in the overlay + * @pathp: pointer which receives the path of the target (or NULL) + * + * overlay_get_target() retrieves the target offset in the base + * device tree of a fragment, no matter how the actual targeting is + * done (through a phandle or a path) + * + * returns: + * the targeted node offset in the base device tree + * Negative error code on error + */ +static int overlay_get_target(const void *fdt, const void *fdto, + int fragment, char const **pathp) +{ + uint32_t phandle; + const char *path = NULL; + int path_len = 0, ret; + + /* Try first to do a phandle based lookup */ + phandle = overlay_get_target_phandle(fdto, fragment); + if (phandle == (uint32_t)-1) + return -FDT_ERR_BADPHANDLE; + + /* no phandle, try path */ + if (!phandle) { + /* And then a path based lookup */ + path = fdt_getprop(fdto, fragment, "target-path", &path_len); + if (path) + ret = fdt_path_offset(fdt, path); + else + ret = path_len; + } else + ret = fdt_node_offset_by_phandle(fdt, phandle); + + /* + * If we haven't found either a target or a + * target-path property in a node that contains a + * __overlay__ subnode (we wouldn't be called + * otherwise), consider it a improperly written + * overlay + */ + if (ret < 0 && path_len == -FDT_ERR_NOTFOUND) + ret = -FDT_ERR_BADOVERLAY; + + /* return on error */ + if (ret < 0) + return ret; + + /* return pointer to path (if available) */ + if (pathp) + *pathp = path ? path : NULL; + + return ret; +} + +/** + * overlay_phandle_add_offset - Increases a phandle by an offset + * @fdt: Base device tree blob + * @node: Device tree overlay blob + * @name: Name of the property to modify (phandle or linux,phandle) + * @delta: offset to apply + * + * overlay_phandle_add_offset() increments a node phandle by a given + * offset. + * + * returns: + * 0 on success. + * Negative error code on error + */ +static int overlay_phandle_add_offset(void *fdt, int node, + const char *name, uint32_t delta) +{ + const fdt32_t *val; + uint32_t adj_val; + int len; + + val = fdt_getprop(fdt, node, name, &len); + if (!val) + return len; + + if (len != sizeof(*val)) + return -FDT_ERR_BADPHANDLE; + + adj_val = fdt32_to_cpu(*val); + if ((adj_val + delta) < adj_val) + return -FDT_ERR_NOPHANDLES; + + adj_val += delta; + if (adj_val == (uint32_t)-1) + return -FDT_ERR_NOPHANDLES; + + return fdt_setprop_inplace_u32(fdt, node, name, adj_val); +} + +/** + * overlay_adjust_node_phandles - Offsets the phandles of a node + * @fdto: Device tree overlay blob + * @node: Offset of the node we want to adjust + * @delta: Offset to shift the phandles of + * + * overlay_adjust_node_phandles() adds a constant to all the phandles + * of a given node. This is mainly use as part of the overlay + * application process, when we want to update all the overlay + * phandles to not conflict with the overlays of the base device tree. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_adjust_node_phandles(void *fdto, int node, + uint32_t delta) +{ + int child; + int ret; + + ret = overlay_phandle_add_offset(fdto, node, "phandle", delta); + if (ret && ret != -FDT_ERR_NOTFOUND) + return ret; + + ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta); + if (ret && ret != -FDT_ERR_NOTFOUND) + return ret; + + fdt_for_each_subnode(child, fdto, node) { + ret = overlay_adjust_node_phandles(fdto, child, delta); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay + * @fdto: Device tree overlay blob + * @delta: Offset to shift the phandles of + * + * overlay_adjust_local_phandles() adds a constant to all the + * phandles of an overlay. This is mainly use as part of the overlay + * application process, when we want to update all the overlay + * phandles to not conflict with the overlays of the base device tree. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_adjust_local_phandles(void *fdto, uint32_t delta) +{ + /* + * Start adjusting the phandles from the overlay root + */ + return overlay_adjust_node_phandles(fdto, 0, delta); +} + +/** + * overlay_update_local_node_references - Adjust the overlay references + * @fdto: Device tree overlay blob + * @tree_node: Node offset of the node to operate on + * @fixup_node: Node offset of the matching local fixups node + * @delta: Offset to shift the phandles of + * + * overlay_update_local_nodes_references() update the phandles + * pointing to a node within the device tree overlay by adding a + * constant delta. + * + * This is mainly used as part of a device tree application process, + * where you want the device tree overlays phandles to not conflict + * with the ones from the base device tree before merging them. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_update_local_node_references(void *fdto, + int tree_node, + int fixup_node, + uint32_t delta) +{ + int fixup_prop; + int fixup_child; + int ret; + + fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { + const fdt32_t *fixup_val; + const char *tree_val; + const char *name; + int fixup_len; + int tree_len; + int i; + + fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, + &name, &fixup_len); + if (!fixup_val) + return fixup_len; + + if (fixup_len % sizeof(uint32_t)) + return -FDT_ERR_BADOVERLAY; + fixup_len /= sizeof(uint32_t); + + tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); + if (!tree_val) { + if (tree_len == -FDT_ERR_NOTFOUND) + return -FDT_ERR_BADOVERLAY; + + return tree_len; + } + + for (i = 0; i < fixup_len; i++) { + fdt32_t adj_val; + uint32_t poffset; + + poffset = fdt32_to_cpu(fixup_val[i]); + + /* + * phandles to fixup can be unaligned. + * + * Use a memcpy for the architectures that do + * not support unaligned accesses. + */ + memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); + + adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta); + + ret = fdt_setprop_inplace_namelen_partial(fdto, + tree_node, + name, + strlen(name), + poffset, + &adj_val, + sizeof(adj_val)); + if (ret == -FDT_ERR_NOSPACE) + return -FDT_ERR_BADOVERLAY; + + if (ret) + return ret; + } + } + + fdt_for_each_subnode(fixup_child, fdto, fixup_node) { + const char *fixup_child_name = fdt_get_name(fdto, fixup_child, + NULL); + int tree_child; + + tree_child = fdt_subnode_offset(fdto, tree_node, + fixup_child_name); + if (tree_child == -FDT_ERR_NOTFOUND) + return -FDT_ERR_BADOVERLAY; + if (tree_child < 0) + return tree_child; + + ret = overlay_update_local_node_references(fdto, + tree_child, + fixup_child, + delta); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_update_local_references - Adjust the overlay references + * @fdto: Device tree overlay blob + * @delta: Offset to shift the phandles of + * + * overlay_update_local_references() update all the phandles pointing + * to a node within the device tree overlay by adding a constant + * delta to not conflict with the base overlay. + * + * This is mainly used as part of a device tree application process, + * where you want the device tree overlays phandles to not conflict + * with the ones from the base device tree before merging them. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_update_local_references(void *fdto, uint32_t delta) +{ + int fixups; + + fixups = fdt_path_offset(fdto, "/__local_fixups__"); + if (fixups < 0) { + /* There's no local phandles to adjust, bail out */ + if (fixups == -FDT_ERR_NOTFOUND) + return 0; + + return fixups; + } + + /* + * Update our local references from the root of the tree + */ + return overlay_update_local_node_references(fdto, 0, fixups, + delta); +} + +/** + * overlay_fixup_one_phandle - Set an overlay phandle to the base one + * @fdt: Base Device Tree blob + * @fdto: Device tree overlay blob + * @symbols_off: Node offset of the symbols node in the base device tree + * @path: Path to a node holding a phandle in the overlay + * @path_len: number of path characters to consider + * @name: Name of the property holding the phandle reference in the overlay + * @name_len: number of name characters to consider + * @poffset: Offset within the overlay property where the phandle is stored + * @label: Label of the node referenced by the phandle + * + * overlay_fixup_one_phandle() resolves an overlay phandle pointing to + * a node in the base device tree. + * + * This is part of the device tree overlay application process, when + * you want all the phandles in the overlay to point to the actual + * base dt nodes. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_fixup_one_phandle(void *fdt, void *fdto, + int symbols_off, + const char *path, uint32_t path_len, + const char *name, uint32_t name_len, + int poffset, const char *label) +{ + const char *symbol_path; + uint32_t phandle; + fdt32_t phandle_prop; + int symbol_off, fixup_off; + int prop_len; + + if (symbols_off < 0) + return symbols_off; + + symbol_path = fdt_getprop(fdt, symbols_off, label, + &prop_len); + if (!symbol_path) + return prop_len; + + symbol_off = fdt_path_offset(fdt, symbol_path); + if (symbol_off < 0) + return symbol_off; + + phandle = fdt_get_phandle(fdt, symbol_off); + if (!phandle) + return -FDT_ERR_NOTFOUND; + + fixup_off = fdt_path_offset_namelen(fdto, path, path_len); + if (fixup_off == -FDT_ERR_NOTFOUND) + return -FDT_ERR_BADOVERLAY; + if (fixup_off < 0) + return fixup_off; + + phandle_prop = cpu_to_fdt32(phandle); + return fdt_setprop_inplace_namelen_partial(fdto, fixup_off, + name, name_len, poffset, + &phandle_prop, + sizeof(phandle_prop)); +}; + +/** + * overlay_fixup_phandle - Set an overlay phandle to the base one + * @fdt: Base Device Tree blob + * @fdto: Device tree overlay blob + * @symbols_off: Node offset of the symbols node in the base device tree + * @property: Property offset in the overlay holding the list of fixups + * + * overlay_fixup_phandle() resolves all the overlay phandles pointed + * to in a __fixups__ property, and updates them to match the phandles + * in use in the base device tree. + * + * This is part of the device tree overlay application process, when + * you want all the phandles in the overlay to point to the actual + * base dt nodes. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, + int property) +{ + const char *value; + const char *label; + int len; + + value = fdt_getprop_by_offset(fdto, property, + &label, &len); + if (!value) { + if (len == -FDT_ERR_NOTFOUND) + return -FDT_ERR_INTERNAL; + + return len; + } + + do { + const char *path, *name, *fixup_end; + const char *fixup_str = value; + uint32_t path_len, name_len; + uint32_t fixup_len; + char *sep, *endptr; + int poffset, ret; + + fixup_end = memchr(value, '\0', len); + if (!fixup_end) + return -FDT_ERR_BADOVERLAY; + fixup_len = fixup_end - fixup_str; + + len -= fixup_len + 1; + value += fixup_len + 1; + + path = fixup_str; + sep = memchr(fixup_str, ':', fixup_len); + if (!sep || *sep != ':') + return -FDT_ERR_BADOVERLAY; + + path_len = sep - path; + if (path_len == (fixup_len - 1)) + return -FDT_ERR_BADOVERLAY; + + fixup_len -= path_len + 1; + name = sep + 1; + sep = memchr(name, ':', fixup_len); + if (!sep || *sep != ':') + return -FDT_ERR_BADOVERLAY; + + name_len = sep - name; + if (!name_len) + return -FDT_ERR_BADOVERLAY; + + poffset = strtoul(sep + 1, &endptr, 10); + if ((*endptr != '\0') || (endptr <= (sep + 1))) + return -FDT_ERR_BADOVERLAY; + + ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, + path, path_len, name, name_len, + poffset, label); + if (ret) + return ret; + } while (len > 0); + + return 0; +} + +/** + * overlay_fixup_phandles - Resolve the overlay phandles to the base + * device tree + * @fdt: Base Device Tree blob + * @fdto: Device tree overlay blob + * + * overlay_fixup_phandles() resolves all the overlay phandles pointing + * to nodes in the base device tree. + * + * This is one of the steps of the device tree overlay application + * process, when you want all the phandles in the overlay to point to + * the actual base dt nodes. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_fixup_phandles(void *fdt, void *fdto) +{ + int fixups_off, symbols_off; + int property; + + /* We can have overlays without any fixups */ + fixups_off = fdt_path_offset(fdto, "/__fixups__"); + if (fixups_off == -FDT_ERR_NOTFOUND) + return 0; /* nothing to do */ + if (fixups_off < 0) + return fixups_off; + + /* And base DTs without symbols */ + symbols_off = fdt_path_offset(fdt, "/__symbols__"); + if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND))) + return symbols_off; + + fdt_for_each_property_offset(property, fdto, fixups_off) { + int ret; + + ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_apply_node - Merges a node into the base device tree + * @fdt: Base Device Tree blob + * @target: Node offset in the base device tree to apply the fragment to + * @fdto: Device tree overlay blob + * @node: Node offset in the overlay holding the changes to merge + * + * overlay_apply_node() merges a node into a target base device tree + * node pointed. + * + * This is part of the final step in the device tree overlay + * application process, when all the phandles have been adjusted and + * resolved and you just have to merge overlay into the base device + * tree. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_apply_node(void *fdt, int target, + void *fdto, int node) +{ + int property; + int subnode; + + fdt_for_each_property_offset(property, fdto, node) { + const char *name; + const void *prop; + int prop_len; + int ret; + + prop = fdt_getprop_by_offset(fdto, property, &name, + &prop_len); + if (prop_len == -FDT_ERR_NOTFOUND) + return -FDT_ERR_INTERNAL; + if (prop_len < 0) + return prop_len; + + ret = fdt_setprop(fdt, target, name, prop, prop_len); + if (ret) + return ret; + } + + fdt_for_each_subnode(subnode, fdto, node) { + const char *name = fdt_get_name(fdto, subnode, NULL); + int nnode; + int ret; + + nnode = fdt_add_subnode(fdt, target, name); + if (nnode == -FDT_ERR_EXISTS) { + nnode = fdt_subnode_offset(fdt, target, name); + if (nnode == -FDT_ERR_NOTFOUND) + return -FDT_ERR_INTERNAL; + } + + if (nnode < 0) + return nnode; + + ret = overlay_apply_node(fdt, nnode, fdto, subnode); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_merge - Merge an overlay into its base device tree + * @fdt: Base Device Tree blob + * @fdto: Device tree overlay blob + * + * overlay_merge() merges an overlay into its base device tree. + * + * This is the next to last step in the device tree overlay application + * process, when all the phandles have been adjusted and resolved and + * you just have to merge overlay into the base device tree. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_merge(void *fdt, void *fdto) +{ + int fragment; + + fdt_for_each_subnode(fragment, fdto, 0) { + int overlay; + int target; + int ret; + + /* + * Each fragments will have an __overlay__ node. If + * they don't, it's not supposed to be merged + */ + overlay = fdt_subnode_offset(fdto, fragment, "__overlay__"); + if (overlay == -FDT_ERR_NOTFOUND) + continue; + + if (overlay < 0) + return overlay; + + target = overlay_get_target(fdt, fdto, fragment, NULL); + if (target < 0) + return target; + + ret = overlay_apply_node(fdt, target, fdto, overlay); + if (ret) + return ret; + } + + return 0; +} + +static int get_path_len(const void *fdt, int nodeoffset) +{ + int len = 0, namelen; + const char *name; + + FDT_RO_PROBE(fdt); + + for (;;) { + name = fdt_get_name(fdt, nodeoffset, &namelen); + if (!name) + return namelen; + + /* root? we're done */ + if (namelen == 0) + break; + + nodeoffset = fdt_parent_offset(fdt, nodeoffset); + if (nodeoffset < 0) + return nodeoffset; + len += namelen + 1; + } + + /* in case of root pretend it's "/" */ + if (len == 0) + len++; + return len; +} + +/** + * overlay_symbol_update - Update the symbols of base tree after a merge + * @fdt: Base Device Tree blob + * @fdto: Device tree overlay blob + * + * overlay_symbol_update() updates the symbols of the base tree with the + * symbols of the applied overlay + * + * This is the last step in the device tree overlay application + * process, allowing the reference of overlay symbols by subsequent + * overlay operations. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_symbol_update(void *fdt, void *fdto) +{ + int root_sym, ov_sym, prop, path_len, fragment, target; + int len, frag_name_len, ret, rel_path_len; + const char *s, *e; + const char *path; + const char *name; + const char *frag_name; + const char *rel_path; + const char *target_path; + char *buf; + void *p; + + ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__"); + + /* if no overlay symbols exist no problem */ + if (ov_sym < 0) + return 0; + + root_sym = fdt_subnode_offset(fdt, 0, "__symbols__"); + + /* it no root symbols exist we should create them */ + if (root_sym == -FDT_ERR_NOTFOUND) + root_sym = fdt_add_subnode(fdt, 0, "__symbols__"); + + /* any error is fatal now */ + if (root_sym < 0) + return root_sym; + + /* iterate over each overlay symbol */ + fdt_for_each_property_offset(prop, fdto, ov_sym) { + path = fdt_getprop_by_offset(fdto, prop, &name, &path_len); + if (!path) + return path_len; + + /* verify it's a string property (terminated by a single \0) */ + if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1]) + return -FDT_ERR_BADVALUE; + + /* keep end marker to avoid strlen() */ + e = path + path_len; + + if (*path != '/') + return -FDT_ERR_BADVALUE; + + /* get fragment name first */ + s = strchr(path + 1, '/'); + if (!s) { + /* Symbol refers to something that won't end + * up in the target tree */ + continue; + } + + frag_name = path + 1; + frag_name_len = s - path - 1; + + /* verify format; safe since "s" lies in \0 terminated prop */ + len = sizeof("/__overlay__/") - 1; + if ((e - s) > len && (memcmp(s, "/__overlay__/", len) == 0)) { + /* //__overlay__/ */ + rel_path = s + len; + rel_path_len = e - rel_path - 1; + } else if ((e - s) == len + && (memcmp(s, "/__overlay__", len - 1) == 0)) { + /* //__overlay__ */ + rel_path = ""; + rel_path_len = 0; + } else { + /* Symbol refers to something that won't end + * up in the target tree */ + continue; + } + + /* find the fragment index in which the symbol lies */ + ret = fdt_subnode_offset_namelen(fdto, 0, frag_name, + frag_name_len); + /* not found? */ + if (ret < 0) + return -FDT_ERR_BADOVERLAY; + fragment = ret; + + /* an __overlay__ subnode must exist */ + ret = fdt_subnode_offset(fdto, fragment, "__overlay__"); + if (ret < 0) + return -FDT_ERR_BADOVERLAY; + + /* get the target of the fragment */ + ret = overlay_get_target(fdt, fdto, fragment, &target_path); + if (ret < 0) + return ret; + target = ret; + + /* if we have a target path use */ + if (!target_path) { + ret = get_path_len(fdt, target); + if (ret < 0) + return ret; + len = ret; + } else { + len = strlen(target_path); + } + + ret = fdt_setprop_placeholder(fdt, root_sym, name, + len + (len > 1) + rel_path_len + 1, &p); + if (ret < 0) + return ret; + + if (!target_path) { + /* again in case setprop_placeholder changed it */ + ret = overlay_get_target(fdt, fdto, fragment, &target_path); + if (ret < 0) + return ret; + target = ret; + } + + buf = p; + if (len > 1) { /* target is not root */ + if (!target_path) { + ret = fdt_get_path(fdt, target, buf, len + 1); + if (ret < 0) + return ret; + } else + memcpy(buf, target_path, len + 1); + + } else + len--; + + buf[len] = '/'; + memcpy(buf + len + 1, rel_path, rel_path_len); + buf[len + 1 + rel_path_len] = '\0'; + } + + return 0; +} + +int fdt_overlay_apply(void *fdt, void *fdto) +{ + uint32_t delta; + int ret; + + FDT_RO_PROBE(fdt); + FDT_RO_PROBE(fdto); + + ret = fdt_find_max_phandle(fdt, &delta); + if (ret) + goto err; + + ret = overlay_adjust_local_phandles(fdto, delta); + if (ret) + goto err; + + ret = overlay_update_local_references(fdto, delta); + if (ret) + goto err; + + ret = overlay_fixup_phandles(fdt, fdto); + if (ret) + goto err; + + ret = overlay_merge(fdt, fdto); + if (ret) + goto err; + + ret = overlay_symbol_update(fdt, fdto); + if (ret) + goto err; + + /* + * The overlay has been damaged, erase its magic. + */ + fdt_set_magic(fdto, ~0); + + return 0; + +err: + /* + * The overlay might have been damaged, erase its magic. + */ + fdt_set_magic(fdto, ~0); + + /* + * The base device tree might have been damaged, erase its + * magic. + */ + fdt_set_magic(fdt, ~0); + + return ret; +} diff --git a/libfdt-binding/fdt_ro.c b/libfdt-binding/fdt_ro.c new file mode 100644 index 0000000000000000000000000000000000000000..17584da25760b0ecb4b821335a0e4df61977b85f --- /dev/null +++ b/libfdt-binding/fdt_ro.c @@ -0,0 +1,859 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int fdt_nodename_eq_(const void *fdt, int offset, + const char *s, int len) +{ + int olen; + const char *p = fdt_get_name(fdt, offset, &olen); + + if (!p || olen < len) + /* short match */ + return 0; + + if (memcmp(p, s, len) != 0) + return 0; + + if (p[len] == '\0') + return 1; + else if (!memchr(s, '@', len) && (p[len] == '@')) + return 1; + else + return 0; +} + +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) +{ + int32_t totalsize; + uint32_t absoffset; + size_t len; + int err; + const char *s, *n; + + if (can_assume(VALID_INPUT)) { + s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; + + if (lenp) + *lenp = strlen(s); + return s; + } + totalsize = fdt_ro_probe_(fdt); + err = totalsize; + if (totalsize < 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + absoffset = stroffset + fdt_off_dt_strings(fdt); + if (absoffset >= (unsigned)totalsize) + goto fail; + len = totalsize - absoffset; + + if (fdt_magic(fdt) == FDT_MAGIC) { + if (stroffset < 0) + goto fail; + if (can_assume(LATEST) || fdt_version(fdt) >= 17) { + if ((unsigned)stroffset >= fdt_size_dt_strings(fdt)) + goto fail; + if ((fdt_size_dt_strings(fdt) - stroffset) < len) + len = fdt_size_dt_strings(fdt) - stroffset; + } + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + unsigned int sw_stroffset = -stroffset; + + if ((stroffset >= 0) || + (sw_stroffset > fdt_size_dt_strings(fdt))) + goto fail; + if (sw_stroffset < len) + len = sw_stroffset; + } else { + err = -FDT_ERR_INTERNAL; + goto fail; + } + + s = (const char *)fdt + absoffset; + n = memchr(s, '\0', len); + if (!n) { + /* missing terminating NULL */ + err = -FDT_ERR_TRUNCATED; + goto fail; + } + + if (lenp) + *lenp = n - s; + return s; + +fail: + if (lenp) + *lenp = err; + return NULL; +} + +const char *fdt_string(const void *fdt, int stroffset) +{ + return fdt_get_string(fdt, stroffset, NULL); +} + +static int fdt_string_eq_(const void *fdt, int stroffset, + const char *s, int len) +{ + int slen; + const char *p = fdt_get_string(fdt, stroffset, &slen); + + return p && (slen == len) && (memcmp(p, s, len) == 0); +} + +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max = 0; + int offset = -1; + + while (true) { + uint32_t value; + + offset = fdt_next_node(fdt, offset, NULL); + if (offset < 0) { + if (offset == -FDT_ERR_NOTFOUND) + break; + + return offset; + } + + value = fdt_get_phandle(fdt, offset); + + if (value > max) + max = value; + } + + if (phandle) + *phandle = max; + + return 0; +} + +int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max; + int err; + + err = fdt_find_max_phandle(fdt, &max); + if (err < 0) + return err; + + if (max == FDT_MAX_PHANDLE) + return -FDT_ERR_NOPHANDLES; + + if (phandle) + *phandle = max + 1; + + return 0; +} + +static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) +{ + unsigned int offset = n * sizeof(struct fdt_reserve_entry); + unsigned int absoffset = fdt_off_mem_rsvmap(fdt) + offset; + + if (!can_assume(VALID_INPUT)) { + if (absoffset < fdt_off_mem_rsvmap(fdt)) + return NULL; + if (absoffset > fdt_totalsize(fdt) - + sizeof(struct fdt_reserve_entry)) + return NULL; + } + return fdt_mem_rsv_(fdt, n); +} + +int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) +{ + const struct fdt_reserve_entry *re; + + FDT_RO_PROBE(fdt); + re = fdt_mem_rsv(fdt, n); + if (!can_assume(VALID_INPUT) && !re) + return -FDT_ERR_BADOFFSET; + + *address = fdt64_ld_(&re->address); + *size = fdt64_ld_(&re->size); + return 0; +} + +int fdt_num_mem_rsv(const void *fdt) +{ + int i; + const struct fdt_reserve_entry *re; + + for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { + if (fdt64_ld_(&re->size) == 0) + return i; + } + return -FDT_ERR_TRUNCATED; +} + +static int nextprop_(const void *fdt, int offset) +{ + uint32_t tag; + int nextoffset; + + do { + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_END: + if (nextoffset >= 0) + return -FDT_ERR_BADSTRUCTURE; + else + return nextoffset; + + case FDT_PROP: + return offset; + } + offset = nextoffset; + } while (tag == FDT_NOP); + + return -FDT_ERR_NOTFOUND; +} + +int fdt_subnode_offset_namelen(const void *fdt, int offset, + const char *name, int namelen) +{ + int depth; + + FDT_RO_PROBE(fdt); + + for (depth = 0; + (offset >= 0) && (depth >= 0); + offset = fdt_next_node(fdt, offset, &depth)) + if ((depth == 1) + && fdt_nodename_eq_(fdt, offset, name, namelen)) + return offset; + + if (depth < 0) + return -FDT_ERR_NOTFOUND; + return offset; /* error */ +} + +int fdt_subnode_offset(const void *fdt, int parentoffset, + const char *name) +{ + return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); +} + +int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) +{ + const char *end = path + namelen; + const char *p = path; + int offset = 0; + + FDT_RO_PROBE(fdt); + + /* see if we have an alias */ + if (*path != '/') { + const char *q = memchr(path, '/', end - p); + + if (!q) + q = end; + + p = fdt_get_alias_namelen(fdt, p, q - p); + if (!p) + return -FDT_ERR_BADPATH; + offset = fdt_path_offset(fdt, p); + + p = q; + } + + while (p < end) { + const char *q; + + while (*p == '/') { + p++; + if (p == end) + return offset; + } + q = memchr(p, '/', end - p); + if (! q) + q = end; + + offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); + if (offset < 0) + return offset; + + p = q; + } + + return offset; +} + +int fdt_path_offset(const void *fdt, const char *path) +{ + return fdt_path_offset_namelen(fdt, path, strlen(path)); +} + +const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) +{ + const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset); + const char *nameptr; + int err; + + if (((err = fdt_ro_probe_(fdt)) < 0) + || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) + goto fail; + + nameptr = nh->name; + + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { + /* + * For old FDT versions, match the naming conventions of V16: + * give only the leaf name (after all /). The actual tree + * contents are loosely checked. + */ + const char *leaf; + leaf = strrchr(nameptr, '/'); + if (leaf == NULL) { + err = -FDT_ERR_BADSTRUCTURE; + goto fail; + } + nameptr = leaf+1; + } + + if (len) + *len = strlen(nameptr); + + return nameptr; + + fail: + if (len) + *len = err; + return NULL; +} + +int fdt_first_property_offset(const void *fdt, int nodeoffset) +{ + int offset; + + if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) + return offset; + + return nextprop_(fdt, offset); +} + +int fdt_next_property_offset(const void *fdt, int offset) +{ + if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) + return offset; + + return nextprop_(fdt, offset); +} + +static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, + int offset, + int *lenp) +{ + int err; + const struct fdt_property *prop; + + if (!can_assume(VALID_INPUT) && + (err = fdt_check_prop_offset_(fdt, offset)) < 0) { + if (lenp) + *lenp = err; + return NULL; + } + + prop = fdt_offset_ptr_(fdt, offset); + + if (lenp) + *lenp = fdt32_ld_(&prop->len); + + return prop; +} + +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, + int offset, + int *lenp) +{ + /* Prior to version 16, properties may need realignment + * and this API does not work. fdt_getprop_*() will, however. */ + + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { + if (lenp) + *lenp = -FDT_ERR_BADVERSION; + return NULL; + } + + return fdt_get_property_by_offset_(fdt, offset, lenp); +} + +static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, + int offset, + const char *name, + int namelen, + int *lenp, + int *poffset) +{ + for (offset = fdt_first_property_offset(fdt, offset); + (offset >= 0); + (offset = fdt_next_property_offset(fdt, offset))) { + const struct fdt_property *prop; + + prop = fdt_get_property_by_offset_(fdt, offset, lenp); + if (!can_assume(LIBFDT_FLAWLESS) && !prop) { + offset = -FDT_ERR_INTERNAL; + break; + } + if (fdt_string_eq_(fdt, fdt32_ld_(&prop->nameoff), + name, namelen)) { + if (poffset) + *poffset = offset; + return prop; + } + } + + if (lenp) + *lenp = offset; + return NULL; +} + + +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int offset, + const char *name, + int namelen, int *lenp) +{ + /* Prior to version 16, properties may need realignment + * and this API does not work. fdt_getprop_*() will, however. */ + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { + if (lenp) + *lenp = -FDT_ERR_BADVERSION; + return NULL; + } + + return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp, + NULL); +} + + +const struct fdt_property *fdt_get_property(const void *fdt, + int nodeoffset, + const char *name, int *lenp) +{ + return fdt_get_property_namelen(fdt, nodeoffset, name, + strlen(name), lenp); +} + +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const char *name, int namelen, int *lenp) +{ + int poffset; + const struct fdt_property *prop; + + prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp, + &poffset); + if (!prop) + return NULL; + + /* Handle realignment */ + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && + (poffset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8) + return prop->data + 4; + return prop->data; +} + +const void *fdt_getprop_by_offset(const void *fdt, int offset, + const char **namep, int *lenp) +{ + const struct fdt_property *prop; + + prop = fdt_get_property_by_offset_(fdt, offset, lenp); + if (!prop) + return NULL; + if (namep) { + const char *name; + int namelen; + + if (!can_assume(VALID_INPUT)) { + name = fdt_get_string(fdt, fdt32_ld_(&prop->nameoff), + &namelen); + if (!name) { + if (lenp) + *lenp = namelen; + return NULL; + } + *namep = name; + } else { + *namep = fdt_string(fdt, fdt32_ld_(&prop->nameoff)); + } + } + + /* Handle realignment */ + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && + (offset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8) + return prop->data + 4; + return prop->data; +} + +const void *fdt_getprop(const void *fdt, int nodeoffset, + const char *name, int *lenp) +{ + return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); +} + +uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) +{ + const fdt32_t *php; + int len; + + /* FIXME: This is a bit sub-optimal, since we potentially scan + * over all the properties twice. */ + php = fdt_getprop(fdt, nodeoffset, "phandle", &len); + if (!php || (len != sizeof(*php))) { + php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); + if (!php || (len != sizeof(*php))) + return 0; + } + + return fdt32_ld_(php); +} + +const char *fdt_get_alias_namelen(const void *fdt, + const char *name, int namelen) +{ + int aliasoffset; + + aliasoffset = fdt_path_offset(fdt, "/aliases"); + if (aliasoffset < 0) + return NULL; + + return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); +} + +const char *fdt_get_alias(const void *fdt, const char *name) +{ + return fdt_get_alias_namelen(fdt, name, strlen(name)); +} + +int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) +{ + int pdepth = 0, p = 0; + int offset, depth, namelen; + const char *name; + + FDT_RO_PROBE(fdt); + + if (buflen < 2) + return -FDT_ERR_NOSPACE; + + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + while (pdepth > depth) { + do { + p--; + } while (buf[p-1] != '/'); + pdepth--; + } + + if (pdepth >= depth) { + name = fdt_get_name(fdt, offset, &namelen); + if (!name) + return namelen; + if ((p + namelen + 1) <= buflen) { + memcpy(buf + p, name, namelen); + p += namelen; + buf[p++] = '/'; + pdepth++; + } + } + + if (offset == nodeoffset) { + if (pdepth < (depth + 1)) + return -FDT_ERR_NOSPACE; + + if (p > 1) /* special case so that root path is "/", not "" */ + p--; + buf[p] = '\0'; + return 0; + } + } + + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + + return offset; /* error from fdt_next_node() */ +} + +int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, + int supernodedepth, int *nodedepth) +{ + int offset, depth; + int supernodeoffset = -FDT_ERR_INTERNAL; + + FDT_RO_PROBE(fdt); + + if (supernodedepth < 0) + return -FDT_ERR_NOTFOUND; + + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + if (depth == supernodedepth) + supernodeoffset = offset; + + if (offset == nodeoffset) { + if (nodedepth) + *nodedepth = depth; + + if (supernodedepth > depth) + return -FDT_ERR_NOTFOUND; + else + return supernodeoffset; + } + } + + if (!can_assume(VALID_INPUT)) { + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + } + + return offset; /* error from fdt_next_node() */ +} + +int fdt_node_depth(const void *fdt, int nodeoffset) +{ + int nodedepth; + int err; + + err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); + if (err) + return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err : + -FDT_ERR_INTERNAL; + return nodedepth; +} + +int fdt_parent_offset(const void *fdt, int nodeoffset) +{ + int nodedepth = fdt_node_depth(fdt, nodeoffset); + + if (nodedepth < 0) + return nodedepth; + return fdt_supernode_atdepth_offset(fdt, nodeoffset, + nodedepth - 1, NULL); +} + +int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, + const char *propname, + const void *propval, int proplen) +{ + int offset; + const void *val; + int len; + + FDT_RO_PROBE(fdt); + + /* FIXME: The algorithm here is pretty horrible: we scan each + * property of a node in fdt_getprop(), then if that didn't + * find what we want, we scan over them again making our way + * to the next node. Still it's the easiest to implement + * approach; performance can come later. */ + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + val = fdt_getprop(fdt, offset, propname, &len); + if (val && (len == proplen) + && (memcmp(val, propval, len) == 0)) + return offset; + } + + return offset; /* error from fdt_next_node() */ +} + +int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) +{ + int offset; + + if ((phandle == 0) || (phandle == ~0U)) + return -FDT_ERR_BADPHANDLE; + + FDT_RO_PROBE(fdt); + + /* FIXME: The algorithm here is pretty horrible: we + * potentially scan each property of a node in + * fdt_get_phandle(), then if that didn't find what + * we want, we scan over them again making our way to the next + * node. Still it's the easiest to implement approach; + * performance can come later. */ + for (offset = fdt_next_node(fdt, -1, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + if (fdt_get_phandle(fdt, offset) == phandle) + return offset; + } + + return offset; /* error from fdt_next_node() */ +} + +int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) +{ + int len = strlen(str); + const char *p; + + while (listlen >= len) { + if (memcmp(str, strlist, len+1) == 0) + return 1; + p = memchr(strlist, '\0', listlen); + if (!p) + return 0; /* malformed strlist.. */ + listlen -= (p-strlist) + 1; + strlist = p + 1; + } + return 0; +} + +int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property) +{ + const char *list, *end; + int length, count = 0; + + list = fdt_getprop(fdt, nodeoffset, property, &length); + if (!list) + return length; + + end = list + length; + + while (list < end) { + length = strnlen(list, end - list) + 1; + + /* Abort if the last string isn't properly NUL-terminated. */ + if (list + length > end) + return -FDT_ERR_BADVALUE; + + list += length; + count++; + } + + return count; +} + +int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, + const char *string) +{ + int length, len, idx = 0; + const char *list, *end; + + list = fdt_getprop(fdt, nodeoffset, property, &length); + if (!list) + return length; + + len = strlen(string) + 1; + end = list + length; + + while (list < end) { + length = strnlen(list, end - list) + 1; + + /* Abort if the last string isn't properly NUL-terminated. */ + if (list + length > end) + return -FDT_ERR_BADVALUE; + + if (length == len && memcmp(list, string, length) == 0) + return idx; + + list += length; + idx++; + } + + return -FDT_ERR_NOTFOUND; +} + +const char *fdt_stringlist_get(const void *fdt, int nodeoffset, + const char *property, int idx, + int *lenp) +{ + const char *list, *end; + int length; + + list = fdt_getprop(fdt, nodeoffset, property, &length); + if (!list) { + if (lenp) + *lenp = length; + + return NULL; + } + + end = list + length; + + while (list < end) { + length = strnlen(list, end - list) + 1; + + /* Abort if the last string isn't properly NUL-terminated. */ + if (list + length > end) { + if (lenp) + *lenp = -FDT_ERR_BADVALUE; + + return NULL; + } + + if (idx == 0) { + if (lenp) + *lenp = length - 1; + + return list; + } + + list += length; + idx--; + } + + if (lenp) + *lenp = -FDT_ERR_NOTFOUND; + + return NULL; +} + +int fdt_node_check_compatible(const void *fdt, int nodeoffset, + const char *compatible) +{ + const void *prop; + int len; + + prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); + if (!prop) + return len; + + return !fdt_stringlist_contains(prop, len, compatible); +} + +int fdt_node_offset_by_compatible(const void *fdt, int startoffset, + const char *compatible) +{ + int offset, err; + + FDT_RO_PROBE(fdt); + + /* FIXME: The algorithm here is pretty horrible: we scan each + * property of a node in fdt_node_check_compatible(), then if + * that didn't find what we want, we scan over them again + * making our way to the next node. Still it's the easiest to + * implement approach; performance can come later. */ + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + err = fdt_node_check_compatible(fdt, offset, compatible); + if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) + return err; + else if (err == 0) + return offset; + } + + return offset; /* error from fdt_next_node() */ +} diff --git a/libfdt-binding/fdt_rw.c b/libfdt-binding/fdt_rw.c new file mode 100644 index 0000000000000000000000000000000000000000..2fbb545f9cb608becf46b03a7be4de793f2768f5 --- /dev/null +++ b/libfdt-binding/fdt_rw.c @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int fdt_blocks_misordered_(const void *fdt, + int mem_rsv_size, int struct_size) +{ + return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) + || (fdt_off_dt_struct(fdt) < + (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) + || (fdt_off_dt_strings(fdt) < + (fdt_off_dt_struct(fdt) + struct_size)) + || (fdt_totalsize(fdt) < + (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); +} + +static int fdt_rw_probe_(void *fdt) +{ + if (can_assume(VALID_DTB)) + return 0; + FDT_RO_PROBE(fdt); + + if (!can_assume(LATEST) && fdt_version(fdt) < 17) + return -FDT_ERR_BADVERSION; + if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), + fdt_size_dt_struct(fdt))) + return -FDT_ERR_BADLAYOUT; + if (!can_assume(LATEST) && fdt_version(fdt) > 17) + fdt_set_version(fdt, 17); + + return 0; +} + +#define FDT_RW_PROBE(fdt) \ + { \ + int err_; \ + if ((err_ = fdt_rw_probe_(fdt)) != 0) \ + return err_; \ + } + +static inline unsigned int fdt_data_size_(void *fdt) +{ + return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); +} + +static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) +{ + char *p = splicepoint; + unsigned int dsize = fdt_data_size_(fdt); + size_t soff = p - (char *)fdt; + + if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize)) + return -FDT_ERR_BADOFFSET; + if ((p < (char *)fdt) || (dsize + newlen < (unsigned)oldlen)) + return -FDT_ERR_BADOFFSET; + if (dsize - oldlen + newlen > fdt_totalsize(fdt)) + return -FDT_ERR_NOSPACE; + memmove(p + newlen, p + oldlen, ((char *)fdt + dsize) - (p + oldlen)); + return 0; +} + +static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p, + int oldn, int newn) +{ + int delta = (newn - oldn) * sizeof(*p); + int err; + err = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); + if (err) + return err; + fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); + fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); + return 0; +} + +static int fdt_splice_struct_(void *fdt, void *p, + int oldlen, int newlen) +{ + int delta = newlen - oldlen; + int err; + + if ((err = fdt_splice_(fdt, p, oldlen, newlen))) + return err; + + fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); + fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); + return 0; +} + +/* Must only be used to roll back in case of error */ +static void fdt_del_last_string_(void *fdt, const char *s) +{ + int newlen = strlen(s) + 1; + + fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) - newlen); +} + +static int fdt_splice_string_(void *fdt, int newlen) +{ + void *p = (char *)fdt + + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); + int err; + + if ((err = fdt_splice_(fdt, p, 0, newlen))) + return err; + + fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); + return 0; +} + +/** + * fdt_find_add_string_() - Find or allocate a string + * + * @fdt: pointer to the device tree to check/adjust + * @s: string to find/add + * @allocated: Set to 0 if the string was found, 1 if not found and so + * allocated. Ignored if can_assume(NO_ROLLBACK) + * @return offset of string in the string table (whether found or added) + */ +static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) +{ + char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); + const char *p; + char *new; + int len = strlen(s) + 1; + int err; + + if (!can_assume(NO_ROLLBACK)) + *allocated = 0; + + p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s); + if (p) + /* found it */ + return (p - strtab); + + new = strtab + fdt_size_dt_strings(fdt); + err = fdt_splice_string_(fdt, len); + if (err) + return err; + + if (!can_assume(NO_ROLLBACK)) + *allocated = 1; + + memcpy(new, s, len); + return (new - strtab); +} + +int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) +{ + struct fdt_reserve_entry *re; + int err; + + FDT_RW_PROBE(fdt); + + re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); + err = fdt_splice_mem_rsv_(fdt, re, 0, 1); + if (err) + return err; + + re->address = cpu_to_fdt64(address); + re->size = cpu_to_fdt64(size); + return 0; +} + +int fdt_del_mem_rsv(void *fdt, int n) +{ + struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); + + FDT_RW_PROBE(fdt); + + if (n >= fdt_num_mem_rsv(fdt)) + return -FDT_ERR_NOTFOUND; + + return fdt_splice_mem_rsv_(fdt, re, 1, 0); +} + +static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, + int len, struct fdt_property **prop) +{ + int oldlen; + int err; + + *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); + if (!*prop) + return oldlen; + + if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), + FDT_TAGALIGN(len)))) + return err; + + (*prop)->len = cpu_to_fdt32(len); + return 0; +} + +static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, + int len, struct fdt_property **prop) +{ + int proplen; + int nextoffset; + int namestroff; + int err; + int allocated; + + if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) + return nextoffset; + + namestroff = fdt_find_add_string_(fdt, name, &allocated); + if (namestroff < 0) + return namestroff; + + *prop = fdt_offset_ptr_w_(fdt, nextoffset); + proplen = sizeof(**prop) + FDT_TAGALIGN(len); + + err = fdt_splice_struct_(fdt, *prop, 0, proplen); + if (err) { + /* Delete the string if we failed to add it */ + if (!can_assume(NO_ROLLBACK) && allocated) + fdt_del_last_string_(fdt, name); + return err; + } + + (*prop)->tag = cpu_to_fdt32(FDT_PROP); + (*prop)->nameoff = cpu_to_fdt32(namestroff); + (*prop)->len = cpu_to_fdt32(len); + return 0; +} + +int fdt_set_name(void *fdt, int nodeoffset, const char *name) +{ + char *namep; + int oldlen, newlen; + int err; + + FDT_RW_PROBE(fdt); + + namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); + if (!namep) + return oldlen; + + newlen = strlen(name); + + err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1), + FDT_TAGALIGN(newlen+1)); + if (err) + return err; + + memcpy(namep, name, newlen+1); + return 0; +} + +int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, + int len, void **prop_data) +{ + struct fdt_property *prop; + int err; + + FDT_RW_PROBE(fdt); + + err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); + if (err == -FDT_ERR_NOTFOUND) + err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); + if (err) + return err; + + *prop_data = prop->data; + return 0; +} + +int fdt_setprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len) +{ + void *prop_data; + int err; + + err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data); + if (err) + return err; + + if (len) + memcpy(prop_data, val, len); + return 0; +} + +int fdt_appendprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len) +{ + struct fdt_property *prop; + int err, oldlen, newlen; + + FDT_RW_PROBE(fdt); + + prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); + if (prop) { + newlen = len + oldlen; + err = fdt_splice_struct_(fdt, prop->data, + FDT_TAGALIGN(oldlen), + FDT_TAGALIGN(newlen)); + if (err) + return err; + prop->len = cpu_to_fdt32(newlen); + memcpy(prop->data + oldlen, val, len); + } else { + err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); + if (err) + return err; + memcpy(prop->data, val, len); + } + return 0; +} + +int fdt_delprop(void *fdt, int nodeoffset, const char *name) +{ + struct fdt_property *prop; + int len, proplen; + + FDT_RW_PROBE(fdt); + + prop = fdt_get_property_w(fdt, nodeoffset, name, &len); + if (!prop) + return len; + + proplen = sizeof(*prop) + FDT_TAGALIGN(len); + return fdt_splice_struct_(fdt, prop, proplen, 0); +} + +int fdt_add_subnode_namelen(void *fdt, int parentoffset, + const char *name, int namelen) +{ + struct fdt_node_header *nh; + int offset, nextoffset; + int nodelen; + int err; + uint32_t tag; + fdt32_t *endtag; + + FDT_RW_PROBE(fdt); + + offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); + if (offset >= 0) + return -FDT_ERR_EXISTS; + else if (offset != -FDT_ERR_NOTFOUND) + return offset; + + /* Try to place the new node after the parent's properties */ + tag = fdt_next_tag(fdt, parentoffset, &nextoffset); + /* the fdt_subnode_offset_namelen() should ensure this never hits */ + if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE)) + return -FDT_ERR_INTERNAL; + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + } while ((tag == FDT_PROP) || (tag == FDT_NOP)); + + nh = fdt_offset_ptr_w_(fdt, offset); + nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; + + err = fdt_splice_struct_(fdt, nh, 0, nodelen); + if (err) + return err; + + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); + memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); + memcpy(nh->name, name, namelen); + endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE); + *endtag = cpu_to_fdt32(FDT_END_NODE); + + return offset; +} + +int fdt_add_subnode(void *fdt, int parentoffset, const char *name) +{ + return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); +} + +int fdt_del_node(void *fdt, int nodeoffset) +{ + int endoffset; + + FDT_RW_PROBE(fdt); + + endoffset = fdt_node_end_offset_(fdt, nodeoffset); + if (endoffset < 0) + return endoffset; + + return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset), + endoffset - nodeoffset, 0); +} + +static void fdt_packblocks_(const char *old, char *new, + int mem_rsv_size, int struct_size) +{ + int mem_rsv_off, struct_off, strings_off; + + mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8); + struct_off = mem_rsv_off + mem_rsv_size; + strings_off = struct_off + struct_size; + + memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size); + fdt_set_off_mem_rsvmap(new, mem_rsv_off); + + memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size); + fdt_set_off_dt_struct(new, struct_off); + fdt_set_size_dt_struct(new, struct_size); + + memmove(new + strings_off, old + fdt_off_dt_strings(old), + fdt_size_dt_strings(old)); + fdt_set_off_dt_strings(new, strings_off); + fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); +} + +int fdt_open_into(const void *fdt, void *buf, int bufsize) +{ + int err; + int mem_rsv_size, struct_size; + int newsize; + const char *fdtstart = fdt; + const char *fdtend = fdtstart + fdt_totalsize(fdt); + char *tmp; + + FDT_RO_PROBE(fdt); + + mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) + * sizeof(struct fdt_reserve_entry); + + if (can_assume(LATEST) || fdt_version(fdt) >= 17) { + struct_size = fdt_size_dt_struct(fdt); + } else if (fdt_version(fdt) == 16) { + struct_size = 0; + while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) + ; + if (struct_size < 0) + return struct_size; + } else { + return -FDT_ERR_BADVERSION; + } + + if (can_assume(LIBFDT_ORDER) || + !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { + /* no further work necessary */ + err = fdt_move(fdt, buf, bufsize); + if (err) + return err; + fdt_set_version(buf, 17); + fdt_set_size_dt_struct(buf, struct_size); + fdt_set_totalsize(buf, bufsize); + return 0; + } + + /* Need to reorder */ + newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size + + struct_size + fdt_size_dt_strings(fdt); + + if (bufsize < newsize) + return -FDT_ERR_NOSPACE; + + /* First attempt to build converted tree at beginning of buffer */ + tmp = buf; + /* But if that overlaps with the old tree... */ + if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { + /* Try right after the old tree instead */ + tmp = (char *)(uintptr_t)fdtend; + if ((tmp + newsize) > ((char *)buf + bufsize)) + return -FDT_ERR_NOSPACE; + } + + fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size); + memmove(buf, tmp, newsize); + + fdt_set_magic(buf, FDT_MAGIC); + fdt_set_totalsize(buf, bufsize); + fdt_set_version(buf, 17); + fdt_set_last_comp_version(buf, 16); + fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); + + return 0; +} + +int fdt_pack(void *fdt) +{ + int mem_rsv_size; + + FDT_RW_PROBE(fdt); + + mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) + * sizeof(struct fdt_reserve_entry); + fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); + fdt_set_totalsize(fdt, fdt_data_size_(fdt)); + + return 0; +} diff --git a/libfdt-binding/fdt_strerror.c b/libfdt-binding/fdt_strerror.c new file mode 100644 index 0000000000000000000000000000000000000000..b4356931b06d6a6d01ffec217ce9b3e13ba5cf3a --- /dev/null +++ b/libfdt-binding/fdt_strerror.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +struct fdt_errtabent { + const char *str; +}; + +#define FDT_ERRTABENT(val) \ + [(val)] = { .str = #val, } + +static struct fdt_errtabent fdt_errtable[] = { + FDT_ERRTABENT(FDT_ERR_NOTFOUND), + FDT_ERRTABENT(FDT_ERR_EXISTS), + FDT_ERRTABENT(FDT_ERR_NOSPACE), + + FDT_ERRTABENT(FDT_ERR_BADOFFSET), + FDT_ERRTABENT(FDT_ERR_BADPATH), + FDT_ERRTABENT(FDT_ERR_BADPHANDLE), + FDT_ERRTABENT(FDT_ERR_BADSTATE), + + FDT_ERRTABENT(FDT_ERR_TRUNCATED), + FDT_ERRTABENT(FDT_ERR_BADMAGIC), + FDT_ERRTABENT(FDT_ERR_BADVERSION), + FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), + FDT_ERRTABENT(FDT_ERR_BADLAYOUT), + FDT_ERRTABENT(FDT_ERR_INTERNAL), + FDT_ERRTABENT(FDT_ERR_BADNCELLS), + FDT_ERRTABENT(FDT_ERR_BADVALUE), + FDT_ERRTABENT(FDT_ERR_BADOVERLAY), + FDT_ERRTABENT(FDT_ERR_NOPHANDLES), + FDT_ERRTABENT(FDT_ERR_BADFLAGS), +}; +#define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))) + +const char *fdt_strerror(int errval) +{ + if (errval > 0) + return ""; + else if (errval == 0) + return ""; + else if (-errval < FDT_ERRTABSIZE) { + const char *s = fdt_errtable[-errval].str; + + if (s) + return s; + } + + return ""; +} diff --git a/libfdt-binding/fdt_sw.c b/libfdt-binding/fdt_sw.c new file mode 100644 index 0000000000000000000000000000000000000000..4c569ee7eb0d1810d385aaaa3a11172c512e783e --- /dev/null +++ b/libfdt-binding/fdt_sw.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int fdt_sw_probe_(void *fdt) +{ + if (!can_assume(VALID_INPUT)) { + if (fdt_magic(fdt) == FDT_MAGIC) + return -FDT_ERR_BADSTATE; + else if (fdt_magic(fdt) != FDT_SW_MAGIC) + return -FDT_ERR_BADMAGIC; + } + + return 0; +} + +#define FDT_SW_PROBE(fdt) \ + { \ + int err; \ + if ((err = fdt_sw_probe_(fdt)) != 0) \ + return err; \ + } + +/* 'memrsv' state: Initial state after fdt_create() + * + * Allowed functions: + * fdt_add_reservemap_entry() + * fdt_finish_reservemap() [moves to 'struct' state] + */ +static int fdt_sw_probe_memrsv_(void *fdt) +{ + int err = fdt_sw_probe_(fdt); + if (err) + return err; + + if (!can_assume(VALID_INPUT) && fdt_off_dt_strings(fdt) != 0) + return -FDT_ERR_BADSTATE; + return 0; +} + +#define FDT_SW_PROBE_MEMRSV(fdt) \ + { \ + int err; \ + if ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \ + return err; \ + } + +/* 'struct' state: Enter this state after fdt_finish_reservemap() + * + * Allowed functions: + * fdt_begin_node() + * fdt_end_node() + * fdt_property*() + * fdt_finish() [moves to 'complete' state] + */ +static int fdt_sw_probe_struct_(void *fdt) +{ + int err = fdt_sw_probe_(fdt); + if (err) + return err; + + if (!can_assume(VALID_INPUT) && + fdt_off_dt_strings(fdt) != fdt_totalsize(fdt)) + return -FDT_ERR_BADSTATE; + return 0; +} + +#define FDT_SW_PROBE_STRUCT(fdt) \ + { \ + int err; \ + if ((err = fdt_sw_probe_struct_(fdt)) != 0) \ + return err; \ + } + +static inline uint32_t sw_flags(void *fdt) +{ + /* assert: (fdt_magic(fdt) == FDT_SW_MAGIC) */ + return fdt_last_comp_version(fdt); +} + +/* 'complete' state: Enter this state after fdt_finish() + * + * Allowed functions: none + */ + +static void *fdt_grab_space_(void *fdt, size_t len) +{ + unsigned int offset = fdt_size_dt_struct(fdt); + unsigned int spaceleft; + + spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) + - fdt_size_dt_strings(fdt); + + if ((offset + len < offset) || (offset + len > spaceleft)) + return NULL; + + fdt_set_size_dt_struct(fdt, offset + len); + return fdt_offset_ptr_w_(fdt, offset); +} + +int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags) +{ + const int hdrsize = FDT_ALIGN(sizeof(struct fdt_header), + sizeof(struct fdt_reserve_entry)); + void *fdt = buf; + + if (bufsize < hdrsize) + return -FDT_ERR_NOSPACE; + + if (flags & ~FDT_CREATE_FLAGS_ALL) + return -FDT_ERR_BADFLAGS; + + memset(buf, 0, bufsize); + + /* + * magic and last_comp_version keep intermediate state during the fdt + * creation process, which is replaced with the proper FDT format by + * fdt_finish(). + * + * flags should be accessed with sw_flags(). + */ + fdt_set_magic(fdt, FDT_SW_MAGIC); + fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); + fdt_set_last_comp_version(fdt, flags); + + fdt_set_totalsize(fdt, bufsize); + + fdt_set_off_mem_rsvmap(fdt, hdrsize); + fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); + fdt_set_off_dt_strings(fdt, 0); + + return 0; +} + +int fdt_create(void *buf, int bufsize) +{ + return fdt_create_with_flags(buf, bufsize, 0); +} + +int fdt_resize(void *fdt, void *buf, int bufsize) +{ + size_t headsize, tailsize; + char *oldtail, *newtail; + + FDT_SW_PROBE(fdt); + + if (bufsize < 0) + return -FDT_ERR_NOSPACE; + + headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); + tailsize = fdt_size_dt_strings(fdt); + + if (!can_assume(VALID_DTB) && + headsize + tailsize > fdt_totalsize(fdt)) + return -FDT_ERR_INTERNAL; + + if ((headsize + tailsize) > (unsigned)bufsize) + return -FDT_ERR_NOSPACE; + + oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize; + newtail = (char *)buf + bufsize - tailsize; + + /* Two cases to avoid clobbering data if the old and new + * buffers partially overlap */ + if (buf <= fdt) { + memmove(buf, fdt, headsize); + memmove(newtail, oldtail, tailsize); + } else { + memmove(newtail, oldtail, tailsize); + memmove(buf, fdt, headsize); + } + + fdt_set_totalsize(buf, bufsize); + if (fdt_off_dt_strings(buf)) + fdt_set_off_dt_strings(buf, bufsize); + + return 0; +} + +int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) +{ + struct fdt_reserve_entry *re; + int offset; + + FDT_SW_PROBE_MEMRSV(fdt); + + offset = fdt_off_dt_struct(fdt); + if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) + return -FDT_ERR_NOSPACE; + + re = (struct fdt_reserve_entry *)((char *)fdt + offset); + re->address = cpu_to_fdt64(addr); + re->size = cpu_to_fdt64(size); + + fdt_set_off_dt_struct(fdt, offset + sizeof(*re)); + + return 0; +} + +int fdt_finish_reservemap(void *fdt) +{ + int err = fdt_add_reservemap_entry(fdt, 0, 0); + + if (err) + return err; + + fdt_set_off_dt_strings(fdt, fdt_totalsize(fdt)); + return 0; +} + +int fdt_begin_node(void *fdt, const char *name) +{ + struct fdt_node_header *nh; + int namelen; + + FDT_SW_PROBE_STRUCT(fdt); + + namelen = strlen(name) + 1; + nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); + if (! nh) + return -FDT_ERR_NOSPACE; + + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); + memcpy(nh->name, name, namelen); + return 0; +} + +int fdt_end_node(void *fdt) +{ + fdt32_t *en; + + FDT_SW_PROBE_STRUCT(fdt); + + en = fdt_grab_space_(fdt, FDT_TAGSIZE); + if (! en) + return -FDT_ERR_NOSPACE; + + *en = cpu_to_fdt32(FDT_END_NODE); + return 0; +} + +static int fdt_add_string_(void *fdt, const char *s) +{ + char *strtab = (char *)fdt + fdt_totalsize(fdt); + unsigned int strtabsize = fdt_size_dt_strings(fdt); + unsigned int len = strlen(s) + 1; + unsigned int struct_top, offset; + + offset = strtabsize + len; + struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); + if (fdt_totalsize(fdt) - offset < struct_top) + return 0; /* no more room :( */ + + memcpy(strtab - offset, s, len); + fdt_set_size_dt_strings(fdt, strtabsize + len); + return -offset; +} + +/* Must only be used to roll back in case of error */ +static void fdt_del_last_string_(void *fdt, const char *s) +{ + int strtabsize = fdt_size_dt_strings(fdt); + int len = strlen(s) + 1; + + fdt_set_size_dt_strings(fdt, strtabsize - len); +} + +static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) +{ + char *strtab = (char *)fdt + fdt_totalsize(fdt); + int strtabsize = fdt_size_dt_strings(fdt); + const char *p; + + *allocated = 0; + + p = fdt_find_string_(strtab - strtabsize, strtabsize, s); + if (p) + return p - strtab; + + *allocated = 1; + + return fdt_add_string_(fdt, s); +} + +int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) +{ + struct fdt_property *prop; + int nameoff; + int allocated; + + FDT_SW_PROBE_STRUCT(fdt); + + /* String de-duplication can be slow, _NO_NAME_DEDUP skips it */ + if (sw_flags(fdt) & FDT_CREATE_FLAG_NO_NAME_DEDUP) { + allocated = 1; + nameoff = fdt_add_string_(fdt, name); + } else { + nameoff = fdt_find_add_string_(fdt, name, &allocated); + } + if (nameoff == 0) + return -FDT_ERR_NOSPACE; + + prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); + if (! prop) { + if (allocated) + fdt_del_last_string_(fdt, name); + return -FDT_ERR_NOSPACE; + } + + prop->tag = cpu_to_fdt32(FDT_PROP); + prop->nameoff = cpu_to_fdt32(nameoff); + prop->len = cpu_to_fdt32(len); + *valp = prop->data; + return 0; +} + +int fdt_property(void *fdt, const char *name, const void *val, int len) +{ + void *ptr; + int ret; + + ret = fdt_property_placeholder(fdt, name, len, &ptr); + if (ret) + return ret; + memcpy(ptr, val, len); + return 0; +} + +int fdt_finish(void *fdt) +{ + char *p = (char *)fdt; + fdt32_t *end; + int oldstroffset, newstroffset; + uint32_t tag; + int offset, nextoffset; + + FDT_SW_PROBE_STRUCT(fdt); + + /* Add terminator */ + end = fdt_grab_space_(fdt, sizeof(*end)); + if (! end) + return -FDT_ERR_NOSPACE; + *end = cpu_to_fdt32(FDT_END); + + /* Relocate the string table */ + oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); + newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); + memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); + fdt_set_off_dt_strings(fdt, newstroffset); + + /* Walk the structure, correcting string offsets */ + offset = 0; + while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { + if (tag == FDT_PROP) { + struct fdt_property *prop = + fdt_offset_ptr_w_(fdt, offset); + int nameoff; + + nameoff = fdt32_to_cpu(prop->nameoff); + nameoff += fdt_size_dt_strings(fdt); + prop->nameoff = cpu_to_fdt32(nameoff); + } + offset = nextoffset; + } + if (nextoffset < 0) + return nextoffset; + + /* Finally, adjust the header */ + fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); + + /* And fix up fields that were keeping intermediate state. */ + fdt_set_last_comp_version(fdt, FDT_LAST_COMPATIBLE_VERSION); + fdt_set_magic(fdt, FDT_MAGIC); + + return 0; +} diff --git a/libfdt-binding/fdt_wip.c b/libfdt-binding/fdt_wip.c new file mode 100644 index 0000000000000000000000000000000000000000..c2d7566a67dcf114cb15e0e233c8bff126744365 --- /dev/null +++ b/libfdt-binding/fdt_wip.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, + const char *name, int namelen, + uint32_t idx, const void *val, + int len) +{ + void *propval; + int proplen; + + propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen, + &proplen); + if (!propval) + return proplen; + + if ((unsigned)proplen < (len + idx)) + return -FDT_ERR_NOSPACE; + + memcpy((char *)propval + idx, val, len); + return 0; +} + +int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + const void *val, int len) +{ + const void *propval; + int proplen; + + propval = fdt_getprop(fdt, nodeoffset, name, &proplen); + if (!propval) + return proplen; + + if (proplen != len) + return -FDT_ERR_NOSPACE; + + return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name, + strlen(name), 0, + val, len); +} + +static void fdt_nop_region_(void *start, int len) +{ + fdt32_t *p; + + for (p = start; (char *)p < ((char *)start + len); p++) + *p = cpu_to_fdt32(FDT_NOP); +} + +int fdt_nop_property(void *fdt, int nodeoffset, const char *name) +{ + struct fdt_property *prop; + int len; + + prop = fdt_get_property_w(fdt, nodeoffset, name, &len); + if (!prop) + return len; + + fdt_nop_region_(prop, len + sizeof(*prop)); + + return 0; +} + +int fdt_node_end_offset_(void *fdt, int offset) +{ + int depth = 0; + + while ((offset >= 0) && (depth >= 0)) + offset = fdt_next_node(fdt, offset, &depth); + + return offset; +} + +int fdt_nop_node(void *fdt, int nodeoffset) +{ + int endoffset; + + endoffset = fdt_node_end_offset_(fdt, nodeoffset); + if (endoffset < 0) + return endoffset; + + fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0), + endoffset - nodeoffset); + return 0; +} diff --git a/libfdt-binding/libfdt.h b/libfdt-binding/libfdt.h new file mode 100644 index 0000000000000000000000000000000000000000..73467f75c58db22b85b44ab9bda9aa17aa199e87 --- /dev/null +++ b/libfdt-binding/libfdt.h @@ -0,0 +1,2122 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ +#ifndef LIBFDT_H +#define LIBFDT_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FDT_FIRST_SUPPORTED_VERSION 0x02 +#define FDT_LAST_COMPATIBLE_VERSION 0x10 +#define FDT_LAST_SUPPORTED_VERSION 0x11 + +/* Error codes: informative error codes */ +#define FDT_ERR_NOTFOUND 1 + /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ +#define FDT_ERR_EXISTS 2 + /* FDT_ERR_EXISTS: Attempted to create a node or property which + * already exists */ +#define FDT_ERR_NOSPACE 3 + /* FDT_ERR_NOSPACE: Operation needed to expand the device + * tree, but its buffer did not have sufficient space to + * contain the expanded tree. Use fdt_open_into() to move the + * device tree to a buffer with more space. */ + +/* Error codes: codes for bad parameters */ +#define FDT_ERR_BADOFFSET 4 + /* FDT_ERR_BADOFFSET: Function was passed a structure block + * offset which is out-of-bounds, or which points to an + * unsuitable part of the structure for the operation. */ +#define FDT_ERR_BADPATH 5 + /* FDT_ERR_BADPATH: Function was passed a badly formatted path + * (e.g. missing a leading / for a function which requires an + * absolute path) */ +#define FDT_ERR_BADPHANDLE 6 + /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle. + * This can be caused either by an invalid phandle property + * length, or the phandle value was either 0 or -1, which are + * not permitted. */ +#define FDT_ERR_BADSTATE 7 + /* FDT_ERR_BADSTATE: Function was passed an incomplete device + * tree created by the sequential-write functions, which is + * not sufficiently complete for the requested operation. */ + +/* Error codes: codes for bad device tree blobs */ +#define FDT_ERR_TRUNCATED 8 + /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly + * terminated (overflows, goes outside allowed bounds, or + * isn't properly terminated). */ +#define FDT_ERR_BADMAGIC 9 + /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a + * device tree at all - it is missing the flattened device + * tree magic number. */ +#define FDT_ERR_BADVERSION 10 + /* FDT_ERR_BADVERSION: Given device tree has a version which + * can't be handled by the requested operation. For + * read-write functions, this may mean that fdt_open_into() is + * required to convert the tree to the expected version. */ +#define FDT_ERR_BADSTRUCTURE 11 + /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt + * structure block or other serious error (e.g. misnested + * nodes, or subnodes preceding properties). */ +#define FDT_ERR_BADLAYOUT 12 + /* FDT_ERR_BADLAYOUT: For read-write functions, the given + * device tree has it's sub-blocks in an order that the + * function can't handle (memory reserve map, then structure, + * then strings). Use fdt_open_into() to reorganize the tree + * into a form suitable for the read-write operations. */ + +/* "Can't happen" error indicating a bug in libfdt */ +#define FDT_ERR_INTERNAL 13 + /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. + * Should never be returned, if it is, it indicates a bug in + * libfdt itself. */ + +/* Errors in device tree content */ +#define FDT_ERR_BADNCELLS 14 + /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells + * or similar property with a bad format or value */ + +#define FDT_ERR_BADVALUE 15 + /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected + * value. For example: a property expected to contain a string list + * is not NUL-terminated within the length of its value. */ + +#define FDT_ERR_BADOVERLAY 16 + /* FDT_ERR_BADOVERLAY: The device tree overlay, while + * correctly structured, cannot be applied due to some + * unexpected or missing value, property or node. */ + +#define FDT_ERR_NOPHANDLES 17 + /* FDT_ERR_NOPHANDLES: The device tree doesn't have any + * phandle available anymore without causing an overflow */ + +#define FDT_ERR_BADFLAGS 18 + /* FDT_ERR_BADFLAGS: The function was passed a flags field that + * contains invalid flags or an invalid combination of flags. */ + +#define FDT_ERR_ALIGNMENT 19 + /* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte + * aligned. */ + +#define FDT_ERR_MAX 19 + +/* constants */ +#define FDT_MAX_PHANDLE 0xfffffffe + /* Valid values for phandles range from 1 to 2^32-2. */ + +/**********************************************************************/ +/* Low-level functions (you probably don't need these) */ +/**********************************************************************/ + +#ifndef SWIG /* This function is not useful in Python */ +const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); +#endif +static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) +{ + return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); +} + +uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); + +/* + * External helpers to access words from a device tree blob. They're built + * to work even with unaligned pointers on platforms (such as ARMv5) that don't + * like unaligned loads and stores. + */ +static inline uint32_t fdt32_ld(const fdt32_t *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint32_t)bp[0] << 24) + | ((uint32_t)bp[1] << 16) + | ((uint32_t)bp[2] << 8) + | bp[3]; +} + +static inline void fdt32_st(void *property, uint32_t value) +{ + uint8_t *bp = (uint8_t *)property; + + bp[0] = value >> 24; + bp[1] = (value >> 16) & 0xff; + bp[2] = (value >> 8) & 0xff; + bp[3] = value & 0xff; +} + +static inline uint64_t fdt64_ld(const fdt64_t *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint64_t)bp[0] << 56) + | ((uint64_t)bp[1] << 48) + | ((uint64_t)bp[2] << 40) + | ((uint64_t)bp[3] << 32) + | ((uint64_t)bp[4] << 24) + | ((uint64_t)bp[5] << 16) + | ((uint64_t)bp[6] << 8) + | bp[7]; +} + +static inline void fdt64_st(void *property, uint64_t value) +{ + uint8_t *bp = (uint8_t *)property; + + bp[0] = value >> 56; + bp[1] = (value >> 48) & 0xff; + bp[2] = (value >> 40) & 0xff; + bp[3] = (value >> 32) & 0xff; + bp[4] = (value >> 24) & 0xff; + bp[5] = (value >> 16) & 0xff; + bp[6] = (value >> 8) & 0xff; + bp[7] = value & 0xff; +} + +/**********************************************************************/ +/* Traversal functions */ +/**********************************************************************/ + +int fdt_next_node(const void *fdt, int offset, int *depth); + +/** + * fdt_first_subnode() - get offset of first direct subnode + * @fdt: FDT blob + * @offset: Offset of node to check + * + * Return: offset of first subnode, or -FDT_ERR_NOTFOUND if there is none + */ +int fdt_first_subnode(const void *fdt, int offset); + +/** + * fdt_next_subnode() - get offset of next direct subnode + * @fdt: FDT blob + * @offset: Offset of previous subnode + * + * After first calling fdt_first_subnode(), call this function repeatedly to + * get direct subnodes of a parent node. + * + * Return: offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more + * subnodes + */ +int fdt_next_subnode(const void *fdt, int offset); + +/** + * fdt_for_each_subnode - iterate over all subnodes of a parent + * + * @node: child node (int, lvalue) + * @fdt: FDT blob (const void *) + * @parent: parent node (int) + * + * This is actually a wrapper around a for loop and would be used like so: + * + * fdt_for_each_subnode(node, fdt, parent) { + * Use node + * ... + * } + * + * if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { + * Error handling + * } + * + * Note that this is implemented as a macro and @node is used as + * iterator in the loop. The parent variable be constant or even a + * literal. + */ +#define fdt_for_each_subnode(node, fdt, parent) \ + for (node = fdt_first_subnode(fdt, parent); \ + node >= 0; \ + node = fdt_next_subnode(fdt, node)) + +/**********************************************************************/ +/* General functions */ +/**********************************************************************/ +#define fdt_get_header(fdt, field) \ + (fdt32_ld(&((const struct fdt_header *)(fdt))->field)) +#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) +#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) +#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) +#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) +#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) +#define fdt_version(fdt) (fdt_get_header(fdt, version)) +#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) +#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) +#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) +#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) + +#define fdt_set_hdr_(name) \ + static inline void fdt_set_##name(void *fdt, uint32_t val) \ + { \ + struct fdt_header *fdth = (struct fdt_header *)fdt; \ + fdth->name = cpu_to_fdt32(val); \ + } +fdt_set_hdr_(magic); +fdt_set_hdr_(totalsize); +fdt_set_hdr_(off_dt_struct); +fdt_set_hdr_(off_dt_strings); +fdt_set_hdr_(off_mem_rsvmap); +fdt_set_hdr_(version); +fdt_set_hdr_(last_comp_version); +fdt_set_hdr_(boot_cpuid_phys); +fdt_set_hdr_(size_dt_strings); +fdt_set_hdr_(size_dt_struct); +#undef fdt_set_hdr_ + +/** + * fdt_header_size - return the size of the tree's header + * @fdt: pointer to a flattened device tree + * + * Return: size of DTB header in bytes + */ +size_t fdt_header_size(const void *fdt); + +/** + * fdt_header_size_ - internal function to get header size from a version number + * @version: devicetree version number + * + * Return: size of DTB header in bytes + */ +size_t fdt_header_size_(uint32_t version); + +/** + * fdt_check_header - sanity check a device tree header + * @fdt: pointer to data which might be a flattened device tree + * + * fdt_check_header() checks that the given buffer contains what + * appears to be a flattened device tree, and that the header contains + * valid information (to the extent that can be determined from the + * header alone). + * + * returns: + * 0, if the buffer appears to contain a valid device tree + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_TRUNCATED, standard meanings, as above + */ +int fdt_check_header(const void *fdt); + +/** + * fdt_move - move a device tree around in memory + * @fdt: pointer to the device tree to move + * @buf: pointer to memory where the device is to be moved + * @bufsize: size of the memory space at buf + * + * fdt_move() relocates, if possible, the device tree blob located at + * fdt to the buffer at buf of size bufsize. The buffer may overlap + * with the existing device tree blob at fdt. Therefore, + * fdt_move(fdt, fdt, fdt_totalsize(fdt)) + * should always succeed. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +int fdt_move(const void *fdt, void *buf, int bufsize); + +/**********************************************************************/ +/* Read-only functions */ +/**********************************************************************/ + +int fdt_check_full(const void *fdt, size_t bufsize); + +/** + * fdt_get_string - retrieve a string from the strings block of a device tree + * @fdt: pointer to the device tree blob + * @stroffset: offset of the string within the strings block (native endian) + * @lenp: optional pointer to return the string's length + * + * fdt_get_string() retrieves a pointer to a single string from the + * strings block of the device tree blob at fdt, and optionally also + * returns the string's length in *lenp. + * + * returns: + * a pointer to the string, on success + * NULL, if stroffset is out of bounds, or doesn't point to a valid string + */ +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp); + +/** + * fdt_string - retrieve a string from the strings block of a device tree + * @fdt: pointer to the device tree blob + * @stroffset: offset of the string within the strings block (native endian) + * + * fdt_string() retrieves a pointer to a single string from the + * strings block of the device tree blob at fdt. + * + * returns: + * a pointer to the string, on success + * NULL, if stroffset is out of bounds, or doesn't point to a valid string + */ +const char *fdt_string(const void *fdt, int stroffset); + +/** + * fdt_find_max_phandle - find and return the highest phandle in a tree + * @fdt: pointer to the device tree blob + * @phandle: return location for the highest phandle value found in the tree + * + * fdt_find_max_phandle() finds the highest phandle value in the given device + * tree. The value returned in @phandle is only valid if the function returns + * success. + * + * returns: + * 0 on success or a negative error code on failure + */ +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle); + +/** + * fdt_get_max_phandle - retrieves the highest phandle in a tree + * @fdt: pointer to the device tree blob + * + * fdt_get_max_phandle retrieves the highest phandle in the given + * device tree. This will ignore badly formatted phandles, or phandles + * with a value of 0 or -1. + * + * This function is deprecated in favour of fdt_find_max_phandle(). + * + * returns: + * the highest phandle on success + * 0, if no phandle was found in the device tree + * -1, if an error occurred + */ +static inline uint32_t fdt_get_max_phandle(const void *fdt) +{ + uint32_t phandle; + int err; + + err = fdt_find_max_phandle(fdt, &phandle); + if (err < 0) + return (uint32_t)-1; + + return phandle; +} + +/** + * fdt_generate_phandle - return a new, unused phandle for a device tree blob + * @fdt: pointer to the device tree blob + * @phandle: return location for the new phandle + * + * Walks the device tree blob and looks for the highest phandle value. On + * success, the new, unused phandle value (one higher than the previously + * highest phandle value in the device tree blob) will be returned in the + * @phandle parameter. + * + * Return: 0 on success or a negative error-code on failure + */ +int fdt_generate_phandle(const void *fdt, uint32_t *phandle); + +/** + * fdt_num_mem_rsv - retrieve the number of memory reserve map entries + * @fdt: pointer to the device tree blob + * + * Returns the number of entries in the device tree blob's memory + * reservation map. This does not include the terminating 0,0 entry + * or any other (0,0) entries reserved for expansion. + * + * returns: + * the number of entries + */ +int fdt_num_mem_rsv(const void *fdt); + +/** + * fdt_get_mem_rsv - retrieve one memory reserve map entry + * @fdt: pointer to the device tree blob + * @n: index of reserve map entry + * @address: pointer to 64-bit variable to hold the start address + * @size: pointer to 64-bit variable to hold the size of the entry + * + * On success, @address and @size will contain the address and size of + * the n-th reserve map entry from the device tree blob, in + * native-endian format. + * + * returns: + * 0, on success + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); + +/** + * fdt_subnode_offset_namelen - find a subnode based on substring + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to locate + * @namelen: number of characters of name to consider + * + * Identical to fdt_subnode_offset(), but only examine the first + * namelen characters of name for matching the subnode name. This is + * useful for finding subnodes based on a portion of a larger string, + * such as a full path. + * + * Return: offset of the subnode or -FDT_ERR_NOTFOUND if name not found. + */ +#ifndef SWIG /* Not available in Python */ +int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, + const char *name, int namelen); +#endif +/** + * fdt_subnode_offset - find a subnode of a given node + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to locate + * + * fdt_subnode_offset() finds a subnode of the node at structure block + * offset parentoffset with the given name. name may include a unit + * address, in which case fdt_subnode_offset() will find the subnode + * with that unit address, or the unit address may be omitted, in + * which case fdt_subnode_offset() will find an arbitrary subnode + * whose name excluding unit address matches the given name. + * + * returns: + * structure block offset of the requested subnode (>=0), on success + * -FDT_ERR_NOTFOUND, if the requested subnode does not exist + * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE + * tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); + +/** + * fdt_path_offset_namelen - find a tree node by its full path + * @fdt: pointer to the device tree blob + * @path: full path of the node to locate + * @namelen: number of characters of path to consider + * + * Identical to fdt_path_offset(), but only consider the first namelen + * characters of path as the path name. + * + * Return: offset of the node or negative libfdt error value otherwise + */ +#ifndef SWIG /* Not available in Python */ +int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); +#endif + +/** + * fdt_path_offset - find a tree node by its full path + * @fdt: pointer to the device tree blob + * @path: full path of the node to locate + * + * fdt_path_offset() finds a node of a given path in the device tree. + * Each path component may omit the unit address portion, but the + * results of this are undefined if any such path component is + * ambiguous (that is if there are multiple nodes at the relevant + * level matching the given component, differentiated only by unit + * address). + * + * returns: + * structure block offset of the node with the requested path (>=0), on + * success + * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid + * -FDT_ERR_NOTFOUND, if the requested node does not exist + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_path_offset(const void *fdt, const char *path); + +/** + * fdt_get_name - retrieve the name of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of the starting node + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_get_name() retrieves the name (including unit address) of the + * device tree node at structure block offset nodeoffset. If lenp is + * non-NULL, the length of this name is also returned, in the integer + * pointed to by lenp. + * + * returns: + * pointer to the node's name, on success + * If lenp is non-NULL, *lenp contains the length of that name + * (>=0) + * NULL, on error + * if lenp is non-NULL *lenp contains an error code (<0): + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE + * tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); + +/** + * fdt_first_property_offset - find the offset of a node's first property + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of a node + * + * fdt_first_property_offset() finds the first property of the node at + * the given structure block offset. + * + * returns: + * structure block offset of the property (>=0), on success + * -FDT_ERR_NOTFOUND, if the requested node has no properties + * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_first_property_offset(const void *fdt, int nodeoffset); + +/** + * fdt_next_property_offset - step through a node's properties + * @fdt: pointer to the device tree blob + * @offset: structure block offset of a property + * + * fdt_next_property_offset() finds the property immediately after the + * one at the given structure block offset. This will be a property + * of the same node as the given property. + * + * returns: + * structure block offset of the next property (>=0), on success + * -FDT_ERR_NOTFOUND, if the given property is the last in its node + * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_next_property_offset(const void *fdt, int offset); + +/** + * fdt_for_each_property_offset - iterate over all properties of a node + * + * @property: property offset (int, lvalue) + * @fdt: FDT blob (const void *) + * @node: node offset (int) + * + * This is actually a wrapper around a for loop and would be used like so: + * + * fdt_for_each_property_offset(property, fdt, node) { + * Use property + * ... + * } + * + * if ((property < 0) && (property != -FDT_ERR_NOTFOUND)) { + * Error handling + * } + * + * Note that this is implemented as a macro and property is used as + * iterator in the loop. The node variable can be constant or even a + * literal. + */ +#define fdt_for_each_property_offset(property, fdt, node) \ + for (property = fdt_first_property_offset(fdt, node); \ + property >= 0; \ + property = fdt_next_property_offset(fdt, property)) + +/** + * fdt_get_property_by_offset - retrieve the property at a given offset + * @fdt: pointer to the device tree blob + * @offset: offset of the property to retrieve + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_get_property_by_offset() retrieves a pointer to the + * fdt_property structure within the device tree blob at the given + * offset. If lenp is non-NULL, the length of the property value is + * also returned, in the integer pointed to by lenp. + * + * Note that this code only works on device tree versions >= 16. fdt_getprop() + * works on all versions. + * + * returns: + * pointer to the structure representing the property + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, + int offset, + int *lenp); + +/** + * fdt_get_property_namelen - find a property based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_get_property(), but only examine the first namelen + * characters of name for matching the property name. + * + * Return: pointer to the structure representing the property, or NULL + * if not found + */ +#ifndef SWIG /* Not available in Python */ +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int nodeoffset, + const char *name, + int namelen, int *lenp); +#endif + +/** + * fdt_get_property - find a given property in a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_get_property() retrieves a pointer to the fdt_property + * structure within the device tree blob corresponding to the property + * named 'name' of the node at offset nodeoffset. If lenp is + * non-NULL, the length of the property value is also returned, in the + * integer pointed to by lenp. + * + * returns: + * pointer to the structure representing the property + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_NOTFOUND, node does not have named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE + * tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, + const char *name, int *lenp); +static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, + const char *name, + int *lenp) +{ + return (struct fdt_property *)(uintptr_t) + fdt_get_property(fdt, nodeoffset, name, lenp); +} + +/** + * fdt_getprop_by_offset - retrieve the value of a property at a given offset + * @fdt: pointer to the device tree blob + * @offset: offset of the property to read + * @namep: pointer to a string variable (will be overwritten) or NULL + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_getprop_by_offset() retrieves a pointer to the value of the + * property at structure block offset 'offset' (this will be a pointer + * to within the device blob itself, not a copy of the value). If + * lenp is non-NULL, the length of the property value is also + * returned, in the integer pointed to by lenp. If namep is non-NULL, + * the property's namne will also be returned in the char * pointed to + * by namep (this will be a pointer to within the device tree's string + * block, not a new copy of the name). + * + * returns: + * pointer to the property's value + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * if namep is non-NULL *namep contiains a pointer to the property + * name. + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +#ifndef SWIG /* This function is not useful in Python */ +const void *fdt_getprop_by_offset(const void *fdt, int offset, + const char **namep, int *lenp); +#endif + +/** + * fdt_getprop_namelen - get property value based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_getprop(), but only examine the first namelen + * characters of name for matching the property name. + * + * Return: pointer to the property's value or NULL on error + */ +#ifndef SWIG /* Not available in Python */ +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const char *name, int namelen, int *lenp); +static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, + const char *name, int namelen, + int *lenp) +{ + return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, + namelen, lenp); +} +#endif + +/** + * fdt_getprop - retrieve the value of a given property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_getprop() retrieves a pointer to the value of the property + * named @name of the node at offset @nodeoffset (this will be a + * pointer to within the device blob itself, not a copy of the value). + * If @lenp is non-NULL, the length of the property value is also + * returned, in the integer pointed to by @lenp. + * + * returns: + * pointer to the property's value + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_NOTFOUND, node does not have named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE + * tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +const void *fdt_getprop(const void *fdt, int nodeoffset, + const char *name, int *lenp); +static inline void *fdt_getprop_w(void *fdt, int nodeoffset, + const char *name, int *lenp) +{ + return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); +} + +/** + * fdt_get_phandle - retrieve the phandle of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of the node + * + * fdt_get_phandle() retrieves the phandle of the device tree node at + * structure block offset nodeoffset. + * + * returns: + * the phandle of the node at nodeoffset, on success (!= 0, != -1) + * 0, if the node has no phandle, or another error occurs + */ +uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); + +/** + * fdt_get_alias_namelen - get alias based on substring + * @fdt: pointer to the device tree blob + * @name: name of the alias th look up + * @namelen: number of characters of name to consider + * + * Identical to fdt_get_alias(), but only examine the first @namelen + * characters of @name for matching the alias name. + * + * Return: a pointer to the expansion of the alias named @name, if it exists, + * NULL otherwise + */ +#ifndef SWIG /* Not available in Python */ +const char *fdt_get_alias_namelen(const void *fdt, + const char *name, int namelen); +#endif + +/** + * fdt_get_alias - retrieve the path referenced by a given alias + * @fdt: pointer to the device tree blob + * @name: name of the alias th look up + * + * fdt_get_alias() retrieves the value of a given alias. That is, the + * value of the property named @name in the node /aliases. + * + * returns: + * a pointer to the expansion of the alias named 'name', if it exists + * NULL, if the given alias or the /aliases node does not exist + */ +const char *fdt_get_alias(const void *fdt, const char *name); + +/** + * fdt_get_path - determine the full path of a node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose path to find + * @buf: character buffer to contain the returned path (will be overwritten) + * @buflen: size of the character buffer at buf + * + * fdt_get_path() computes the full path of the node at offset + * nodeoffset, and records that path in the buffer at buf. + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset. + * + * returns: + * 0, on success + * buf contains the absolute path of the node at + * nodeoffset, as a NUL-terminated string. + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) + * characters and will not fit in the given buffer. + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); + +/** + * fdt_supernode_atdepth_offset - find a specific ancestor of a node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose parent to find + * @supernodedepth: depth of the ancestor to find + * @nodedepth: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_supernode_atdepth_offset() finds an ancestor of the given node + * at a specific depth from the root (where the root itself has depth + * 0, its immediate subnodes depth 1 and so forth). So + * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); + * will always return 0, the offset of the root node. If the node at + * nodeoffset has depth D, then: + * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); + * will return nodeoffset itself. + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset. + * + * returns: + * structure block offset of the node at node offset's ancestor + * of depth supernodedepth (>=0), on success + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of + * nodeoffset + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, + int supernodedepth, int *nodedepth); + +/** + * fdt_node_depth - find the depth of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose parent to find + * + * fdt_node_depth() finds the depth of a given node. The root node + * has depth 0, its immediate subnodes depth 1 and so forth. + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset. + * + * returns: + * depth of the node at nodeoffset (>=0), on success + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_depth(const void *fdt, int nodeoffset); + +/** + * fdt_parent_offset - find the parent of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose parent to find + * + * fdt_parent_offset() locates the parent node of a given node (that + * is, it finds the offset of the node which contains the node at + * nodeoffset as a subnode). + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset, *twice*. + * + * returns: + * structure block offset of the parent of the node at nodeoffset + * (>=0), on success + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_parent_offset(const void *fdt, int nodeoffset); + +/** + * fdt_node_offset_by_prop_value - find nodes with a given property value + * @fdt: pointer to the device tree blob + * @startoffset: only find nodes after this offset + * @propname: property name to check + * @propval: property value to search for + * @proplen: length of the value in propval + * + * fdt_node_offset_by_prop_value() returns the offset of the first + * node after startoffset, which has a property named propname whose + * value is of length proplen and has value equal to propval; or if + * startoffset is -1, the very first such node in the tree. + * + * To iterate through all nodes matching the criterion, the following + * idiom can be used: + * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, + * propval, proplen); + * while (offset != -FDT_ERR_NOTFOUND) { + * // other code here + * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, + * propval, proplen); + * } + * + * Note the -1 in the first call to the function, if 0 is used here + * instead, the function will never locate the root node, even if it + * matches the criterion. + * + * returns: + * structure block offset of the located node (>= 0, >startoffset), + * on success + * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the + * tree after startoffset + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, + const char *propname, + const void *propval, int proplen); + +/** + * fdt_node_offset_by_phandle - find the node with a given phandle + * @fdt: pointer to the device tree blob + * @phandle: phandle value + * + * fdt_node_offset_by_phandle() returns the offset of the node + * which has the given phandle value. If there is more than one node + * in the tree with the given phandle (an invalid tree), results are + * undefined. + * + * returns: + * structure block offset of the located node (>= 0), on success + * -FDT_ERR_NOTFOUND, no node with that phandle exists + * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); + +/** + * fdt_node_check_compatible - check a node's compatible property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of a tree node + * @compatible: string to match against + * + * fdt_node_check_compatible() returns 0 if the given node contains a + * @compatible property with the given string as one of its elements, + * it returns non-zero otherwise, or on error. + * + * returns: + * 0, if the node has a 'compatible' property listing the given string + * 1, if the node has a 'compatible' property, but it does not list + * the given string + * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property + * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_check_compatible(const void *fdt, int nodeoffset, + const char *compatible); + +/** + * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value + * @fdt: pointer to the device tree blob + * @startoffset: only find nodes after this offset + * @compatible: 'compatible' string to match against + * + * fdt_node_offset_by_compatible() returns the offset of the first + * node after startoffset, which has a 'compatible' property which + * lists the given compatible string; or if startoffset is -1, the + * very first such node in the tree. + * + * To iterate through all nodes matching the criterion, the following + * idiom can be used: + * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); + * while (offset != -FDT_ERR_NOTFOUND) { + * // other code here + * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); + * } + * + * Note the -1 in the first call to the function, if 0 is used here + * instead, the function will never locate the root node, even if it + * matches the criterion. + * + * returns: + * structure block offset of the located node (>= 0, >startoffset), + * on success + * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the + * tree after startoffset + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_offset_by_compatible(const void *fdt, int startoffset, + const char *compatible); + +/** + * fdt_stringlist_contains - check a string list property for a string + * @strlist: Property containing a list of strings to check + * @listlen: Length of property + * @str: String to search for + * + * This is a utility function provided for convenience. The list contains + * one or more strings, each terminated by \0, as is found in a device tree + * "compatible" property. + * + * Return: 1 if the string is found in the list, 0 not found, or invalid list + */ +int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); + +/** + * fdt_stringlist_count - count the number of strings in a string list + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of a tree node + * @property: name of the property containing the string list + * + * Return: + * the number of strings in the given property + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated + * -FDT_ERR_NOTFOUND if the property does not exist + */ +int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property); + +/** + * fdt_stringlist_search - find a string in a string list and return its index + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of a tree node + * @property: name of the property containing the string list + * @string: string to look up in the string list + * + * Note that it is possible for this function to succeed on property values + * that are not NUL-terminated. That's because the function will stop after + * finding the first occurrence of @string. This can for example happen with + * small-valued cell properties, such as #address-cells, when searching for + * the empty string. + * + * return: + * the index of the string in the list of strings + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated + * -FDT_ERR_NOTFOUND if the property does not exist or does not contain + * the given string + */ +int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, + const char *string); + +/** + * fdt_stringlist_get() - obtain the string at a given index in a string list + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of a tree node + * @property: name of the property containing the string list + * @index: index of the string to return + * @lenp: return location for the string length or an error code on failure + * + * Note that this will successfully extract strings from properties with + * non-NUL-terminated values. For example on small-valued cell properties + * this function will return the empty string. + * + * If non-NULL, the length of the string (on success) or a negative error-code + * (on failure) will be stored in the integer pointer to by lenp. + * + * Return: + * A pointer to the string at the given index in the string list or NULL on + * failure. On success the length of the string will be stored in the memory + * location pointed to by the lenp parameter, if non-NULL. On failure one of + * the following negative error codes will be returned in the lenp parameter + * (if non-NULL): + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated + * -FDT_ERR_NOTFOUND if the property does not exist + */ +const char *fdt_stringlist_get(const void *fdt, int nodeoffset, + const char *property, int index, + int *lenp); + +/**********************************************************************/ +/* Read-only functions (addressing related) */ +/**********************************************************************/ + +/** + * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells + * + * This is the maximum value for #address-cells, #size-cells and + * similar properties that will be processed by libfdt. IEE1275 + * requires that OF implementations handle values up to 4. + * Implementations may support larger values, but in practice higher + * values aren't used. + */ +#define FDT_MAX_NCELLS 4 + +/** + * fdt_address_cells - retrieve address size for a bus represented in the tree + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node to find the address size for + * + * When the node has a valid #address-cells property, returns its value. + * + * returns: + * 0 <= n < FDT_MAX_NCELLS, on success + * 2, if the node has no #address-cells property + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + * #address-cells property + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_address_cells(const void *fdt, int nodeoffset); + +/** + * fdt_size_cells - retrieve address range size for a bus represented in the + * tree + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node to find the address range size for + * + * When the node has a valid #size-cells property, returns its value. + * + * returns: + * 0 <= n < FDT_MAX_NCELLS, on success + * 1, if the node has no #size-cells property + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + * #size-cells property + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_size_cells(const void *fdt, int nodeoffset); + + +/**********************************************************************/ +/* Write-in-place functions */ +/**********************************************************************/ + +/** + * fdt_setprop_inplace_namelen_partial - change a property's value, + * but not its size + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @namelen: number of characters of name to consider + * @idx: index of the property to change in the array + * @val: pointer to data to replace the property value with + * @len: length of the property value + * + * Identical to fdt_setprop_inplace(), but modifies the given property + * starting from the given index, and using only the first characters + * of the name. It is useful when you want to manipulate only one value of + * an array and you have a string that doesn't end with \0. + * + * Return: 0 on success, negative libfdt error value otherwise + */ +#ifndef SWIG /* Not available in Python */ +int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, + const char *name, int namelen, + uint32_t idx, const void *val, + int len); +#endif + +/** + * fdt_setprop_inplace - change a property's value, but not its size + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: pointer to data to replace the property value with + * @len: length of the property value + * + * fdt_setprop_inplace() replaces the value of a given property with + * the data in val, of length len. This function cannot change the + * size of a property, and so will only work if len is equal to the + * current length of the property. + * + * This function will alter only the bytes in the blob which contain + * the given property value, and will not alter or move any other part + * of the tree. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, if len is not equal to the property's current length + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +#ifndef SWIG /* Not available in Python */ +int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + const void *val, int len); +#endif + +/** + * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 32-bit integer value to replace the property with + * + * fdt_setprop_inplace_u32() replaces the value of a given property + * with the 32-bit integer value in val, converting val to big-endian + * if necessary. This function cannot change the size of a property, + * and so will only work if the property already exists and has length + * 4. + * + * This function will alter only the bytes in the blob which contain + * the given property value, and will not alter or move any other part + * of the tree. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, + const char *name, uint32_t val) +{ + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); +} + +/** + * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 64-bit integer value to replace the property with + * + * fdt_setprop_inplace_u64() replaces the value of a given property + * with the 64-bit integer value in val, converting val to big-endian + * if necessary. This function cannot change the size of a property, + * and so will only work if the property already exists and has length + * 8. + * + * This function will alter only the bytes in the blob which contain + * the given property value, and will not alter or move any other part + * of the tree. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, if the property's length is not equal to 8 + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, + const char *name, uint64_t val) +{ + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); +} + +/** + * fdt_setprop_inplace_cell - change the value of a single-cell property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node containing the property + * @name: name of the property to change the value of + * @val: new value of the 32-bit cell + * + * This is an alternative name for fdt_setprop_inplace_u32() + * Return: 0 on success, negative libfdt error number otherwise. + */ +static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, + const char *name, uint32_t val) +{ + return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val); +} + +/** + * fdt_nop_property - replace a property with nop tags + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to nop + * @name: name of the property to nop + * + * fdt_nop_property() will replace a given property's representation + * in the blob with FDT_NOP tags, effectively removing it from the + * tree. + * + * This function will alter only the bytes in the blob which contain + * the property, and will not alter or move any other part of the + * tree. + * + * returns: + * 0, on success + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_nop_property(void *fdt, int nodeoffset, const char *name); + +/** + * fdt_nop_node - replace a node (subtree) with nop tags + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node to nop + * + * fdt_nop_node() will replace a given node's representation in the + * blob, including all its subnodes, if any, with FDT_NOP tags, + * effectively removing it from the tree. + * + * This function will alter only the bytes in the blob which contain + * the node and its properties and subnodes, and will not alter or + * move any other part of the tree. + * + * returns: + * 0, on success + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_nop_node(void *fdt, int nodeoffset); + +/**********************************************************************/ +/* Sequential write functions */ +/**********************************************************************/ + +/* fdt_create_with_flags flags */ +#define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1 + /* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property + * names in the fdt. This can result in faster creation times, but + * a larger fdt. */ + +#define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP) + +/** + * fdt_create_with_flags - begin creation of a new fdt + * @buf: pointer to memory allocated where fdt will be created + * @bufsize: size of the memory space at fdt + * @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0. + * + * fdt_create_with_flags() begins the process of creating a new fdt with + * the sequential write interface. + * + * fdt creation process must end with fdt_finished() to produce a valid fdt. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt + * -FDT_ERR_BADFLAGS, flags is not valid + */ +int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags); + +/** + * fdt_create - begin creation of a new fdt + * @buf: pointer to memory allocated where fdt will be created + * @bufsize: size of the memory space at fdt + * + * fdt_create() is equivalent to fdt_create_with_flags() with flags=0. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt + */ +int fdt_create(void *buf, int bufsize); + +int fdt_resize(void *fdt, void *buf, int bufsize); +int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); +int fdt_finish_reservemap(void *fdt); +int fdt_begin_node(void *fdt, const char *name); +int fdt_property(void *fdt, const char *name, const void *val, int len); +static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val) +{ + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_property(fdt, name, &tmp, sizeof(tmp)); +} +static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) +{ + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_property(fdt, name, &tmp, sizeof(tmp)); +} + +#ifndef SWIG /* Not available in Python */ +static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) +{ + return fdt_property_u32(fdt, name, val); +} +#endif + +/** + * fdt_property_placeholder - add a new property and return a ptr to its value + * + * @fdt: pointer to the device tree blob + * @name: name of property to add + * @len: length of property value in bytes + * @valp: returns a pointer to where where the value should be placed + * + * returns: + * 0, on success + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_NOSPACE, standard meanings + */ +int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); + +#define fdt_property_string(fdt, name, str) \ + fdt_property(fdt, name, str, strlen(str)+1) +int fdt_end_node(void *fdt); +int fdt_finish(void *fdt); + +/**********************************************************************/ +/* Read-write functions */ +/**********************************************************************/ + +int fdt_create_empty_tree(void *buf, int bufsize); +int fdt_open_into(const void *fdt, void *buf, int bufsize); +int fdt_pack(void *fdt); + +/** + * fdt_add_mem_rsv - add one memory reserve map entry + * @fdt: pointer to the device tree blob + * @address: 64-bit start address of the reserve map entry + * @size: 64-bit size of the reserved region + * + * Adds a reserve map entry to the given blob reserving a region at + * address address of length size. + * + * This function will insert data into the reserve map and will + * therefore change the indexes of some entries in the table. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new reservation entry + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); + +/** + * fdt_del_mem_rsv - remove a memory reserve map entry + * @fdt: pointer to the device tree blob + * @n: entry to remove + * + * fdt_del_mem_rsv() removes the n-th memory reserve map entry from + * the blob. + * + * This function will delete data from the reservation table and will + * therefore change the indexes of some entries in the table. + * + * returns: + * 0, on success + * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there + * are less than n+1 reserve map entries) + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_del_mem_rsv(void *fdt, int n); + +/** + * fdt_set_name - change the name of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of a node + * @name: name to give the node + * + * fdt_set_name() replaces the name (including unit address, if any) + * of the given node with the given string. NOTE: this function can't + * efficiently check if the new name is unique amongst the given + * node's siblings; results are undefined if this function is invoked + * with a name equal to one of the given node's siblings. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob + * to contain the new name + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +int fdt_set_name(void *fdt, int nodeoffset, const char *name); + +/** + * fdt_setprop - create or change a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: pointer to data to set the property value to + * @len: length of the property value + * + * fdt_setprop() sets the value of the named property in the given + * node to the given value and length, creating the property if it + * does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_setprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len); + +/** + * fdt_setprop_placeholder - allocate space for a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @len: length of the property value + * @prop_data: return pointer to property data + * + * fdt_setprop_placeholer() allocates the named property in the given node. + * If the property exists it is resized. In either case a pointer to the + * property data is returned. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, + int len, void **prop_data); + +/** + * fdt_setprop_u32 - set a property to a 32-bit integer + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 32-bit integer value for the property (native endian) + * + * fdt_setprop_u32() sets the value of the named property in the given + * node to the given 32-bit integer value (converting to big-endian if + * necessary), or creates a new property with that value if it does + * not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, + uint32_t val) +{ + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); +} + +/** + * fdt_setprop_u64 - set a property to a 64-bit integer + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 64-bit integer value for the property (native endian) + * + * fdt_setprop_u64() sets the value of the named property in the given + * node to the given 64-bit integer value (converting to big-endian if + * necessary), or creates a new property with that value if it does + * not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, + uint64_t val) +{ + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); +} + +/** + * fdt_setprop_cell - set a property to a single cell value + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 32-bit integer value for the property (native endian) + * + * This is an alternative name for fdt_setprop_u32() + * + * Return: 0 on success, negative libfdt error value otherwise. + */ +static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, + uint32_t val) +{ + return fdt_setprop_u32(fdt, nodeoffset, name, val); +} + +/** + * fdt_setprop_string - set a property to a string value + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @str: string value for the property + * + * fdt_setprop_string() sets the value of the named property in the + * given node to the given string value (using the length of the + * string to determine the new length of the property), or creates a + * new property with that value if it does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +#define fdt_setprop_string(fdt, nodeoffset, name, str) \ + fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) + + +/** + * fdt_setprop_empty - set a property to an empty value + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * + * fdt_setprop_empty() sets the value of the named property in the + * given node to an empty (zero length) value, or creates a new empty + * property if it does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +#define fdt_setprop_empty(fdt, nodeoffset, name) \ + fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) + +/** + * fdt_appendprop - append to or create a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to append to + * @val: pointer to data to append to the property value + * @len: length of the data to append to the property value + * + * fdt_appendprop() appends the value to the named property in the + * given node, creating the property if it does not already exist. + * + * This function may insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_appendprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len); + +/** + * fdt_appendprop_u32 - append a 32-bit integer value to a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 32-bit integer value to append to the property (native endian) + * + * fdt_appendprop_u32() appends the given 32-bit integer value + * (converting to big-endian if necessary) to the value of the named + * property in the given node, or creates a new property with that + * value if it does not already exist. + * + * This function may insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, + const char *name, uint32_t val) +{ + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); +} + +/** + * fdt_appendprop_u64 - append a 64-bit integer value to a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 64-bit integer value to append to the property (native endian) + * + * fdt_appendprop_u64() appends the given 64-bit integer value + * (converting to big-endian if necessary) to the value of the named + * property in the given node, or creates a new property with that + * value if it does not already exist. + * + * This function may insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, + const char *name, uint64_t val) +{ + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); +} + +/** + * fdt_appendprop_cell - append a single cell value to a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 32-bit integer value to append to the property (native endian) + * + * This is an alternative name for fdt_appendprop_u32() + * + * Return: 0 on success, negative libfdt error value otherwise. + */ +static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, + const char *name, uint32_t val) +{ + return fdt_appendprop_u32(fdt, nodeoffset, name, val); +} + +/** + * fdt_appendprop_string - append a string to a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @str: string value to append to the property + * + * fdt_appendprop_string() appends the given string to the value of + * the named property in the given node, or creates a new property + * with that value if it does not already exist. + * + * This function may insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +#define fdt_appendprop_string(fdt, nodeoffset, name, str) \ + fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) + +/** + * fdt_appendprop_addrrange - append a address range property + * @fdt: pointer to the device tree blob + * @parent: offset of the parent node + * @nodeoffset: offset of the node to add a property at + * @name: name of property + * @addr: start address of a given range + * @size: size of a given range + * + * fdt_appendprop_addrrange() appends an address range value (start + * address and size) to the value of the named property in the given + * node, or creates a new property with that value if it does not + * already exist. + * If "name" is not specified, a default "reg" is used. + * Cell sizes are determined by parent's #address-cells and #size-cells. + * + * This function may insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + * #address-cells property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADVALUE, addr or size doesn't fit to respective cells size + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain a new property + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, + const char *name, uint64_t addr, uint64_t size); + +/** + * fdt_delprop - delete a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to nop + * @name: name of the property to nop + * + * fdt_del_property() will delete the given property. + * + * This function will delete data from the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_delprop(void *fdt, int nodeoffset, const char *name); + +/** + * fdt_add_subnode_namelen - creates a new node based on substring + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to create + * @namelen: number of characters of name to consider + * + * Identical to fdt_add_subnode(), but use only the first @namelen + * characters of @name as the name of the new node. This is useful for + * creating subnodes based on a portion of a larger string, such as a + * full path. + * + * Return: structure block offset of the created subnode (>=0), + * negative libfdt error value otherwise + */ +#ifndef SWIG /* Not available in Python */ +int fdt_add_subnode_namelen(void *fdt, int parentoffset, + const char *name, int namelen); +#endif + +/** + * fdt_add_subnode - creates a new node + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to locate + * + * fdt_add_subnode() creates a new node as a subnode of the node at + * structure block offset parentoffset, with the given name (which + * should include the unit address, if any). + * + * This function will insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * structure block offset of the created nodeequested subnode (>=0), on + * success + * -FDT_ERR_NOTFOUND, if the requested subnode does not exist + * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE + * tag + * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of + * the given name + * -FDT_ERR_NOSPACE, if there is insufficient free space in the + * blob to contain the new node + * -FDT_ERR_NOSPACE + * -FDT_ERR_BADLAYOUT + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_add_subnode(void *fdt, int parentoffset, const char *name); + +/** + * fdt_del_node - delete a node (subtree) + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node to nop + * + * fdt_del_node() will remove the given node, including all its + * subnodes if any, from the blob. + * + * This function will delete data from the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_del_node(void *fdt, int nodeoffset); + +/** + * fdt_overlay_apply - Applies a DT overlay on a base DT + * @fdt: pointer to the base device tree blob + * @fdto: pointer to the device tree overlay blob + * + * fdt_overlay_apply() will apply the given device tree overlay on the + * given base device tree. + * + * Expect the base device tree to be modified, even if the function + * returns an error. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there's not enough space in the base device tree + * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or + * properties in the base DT + * -FDT_ERR_BADPHANDLE, + * -FDT_ERR_BADOVERLAY, + * -FDT_ERR_NOPHANDLES, + * -FDT_ERR_INTERNAL, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADOFFSET, + * -FDT_ERR_BADPATH, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_overlay_apply(void *fdt, void *fdto); + +/**********************************************************************/ +/* Debugging / informational functions */ +/**********************************************************************/ + +const char *fdt_strerror(int errval); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBFDT_H */ diff --git a/libfdt-binding/libfdt_env.h b/libfdt-binding/libfdt_env.h new file mode 100644 index 0000000000000000000000000000000000000000..6d028a4fbd2facf734d92eca7d9316b3fec7057c --- /dev/null +++ b/libfdt-binding/libfdt_env.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ +#ifndef LIBFDT_ENV_H +#define LIBFDT_ENV_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * Copyright 2012 Kim Phillips, Freescale Semiconductor. + */ + +#include +#include +#include +#include +#include + +#ifdef __CHECKER__ +#define FDT_FORCE __attribute__((force)) +#define FDT_BITWISE __attribute__((bitwise)) +#else +#define FDT_FORCE +#define FDT_BITWISE +#endif + +typedef uint16_t FDT_BITWISE fdt16_t; +typedef uint32_t FDT_BITWISE fdt32_t; +typedef uint64_t FDT_BITWISE fdt64_t; + +#define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n]) +#define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1)) +#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \ + (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3)) +#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \ + (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \ + (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \ + (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7)) + +static inline uint16_t fdt16_to_cpu(fdt16_t x) +{ + return (FDT_FORCE uint16_t)CPU_TO_FDT16(x); +} +static inline fdt16_t cpu_to_fdt16(uint16_t x) +{ + return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x); +} + +static inline uint32_t fdt32_to_cpu(fdt32_t x) +{ + return (FDT_FORCE uint32_t)CPU_TO_FDT32(x); +} +static inline fdt32_t cpu_to_fdt32(uint32_t x) +{ + return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x); +} + +static inline uint64_t fdt64_to_cpu(fdt64_t x) +{ + return (FDT_FORCE uint64_t)CPU_TO_FDT64(x); +} +static inline fdt64_t cpu_to_fdt64(uint64_t x) +{ + return (FDT_FORCE fdt64_t)CPU_TO_FDT64(x); +} +#undef CPU_TO_FDT64 +#undef CPU_TO_FDT32 +#undef CPU_TO_FDT16 +#undef EXTRACT_BYTE + +#ifdef __APPLE__ +#include + +/* strnlen() is not available on Mac OS < 10.7 */ +# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \ + MAC_OS_X_VERSION_10_7) + +#define strnlen fdt_strnlen + +/* + * fdt_strnlen: returns the length of a string or max_count - which ever is + * smallest. + * Input 1 string: the string whose size is to be determined + * Input 2 max_count: the maximum value returned by this function + * Output: length of the string or max_count (the smallest of the two) + */ +static inline size_t fdt_strnlen(const char *string, size_t max_count) +{ + const char *p = memchr(string, 0, max_count); + return p ? p - string : max_count; +} + +#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < + MAC_OS_X_VERSION_10_7) */ + +#endif /* __APPLE__ */ + +#endif /* LIBFDT_ENV_H */ diff --git a/libfdt-binding/libfdt_internal.h b/libfdt-binding/libfdt_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..16bda1906a7b335519b9f748d1be6110de551e79 --- /dev/null +++ b/libfdt-binding/libfdt_internal.h @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ +#ifndef LIBFDT_INTERNAL_H +#define LIBFDT_INTERNAL_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + */ +#include + +#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) + +int32_t fdt_ro_probe_(const void *fdt); +#define FDT_RO_PROBE(fdt) \ + { \ + int32_t totalsize_; \ + if ((totalsize_ = fdt_ro_probe_(fdt)) < 0) \ + return totalsize_; \ + } + +int fdt_check_node_offset_(const void *fdt, int offset); +int fdt_check_prop_offset_(const void *fdt, int offset); +const char *fdt_find_string_(const char *strtab, int tabsize, const char *s); +int fdt_node_end_offset_(void *fdt, int nodeoffset); + +static inline const void *fdt_offset_ptr_(const void *fdt, int offset) +{ + return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; +} + +static inline void *fdt_offset_ptr_w_(void *fdt, int offset) +{ + return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset); +} + +static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n) +{ + const struct fdt_reserve_entry *rsv_table = + (const struct fdt_reserve_entry *) + ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); + + return rsv_table + n; +} +static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) +{ + return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n); +} + +/* + * Internal helpers to access tructural elements of the device tree + * blob (rather than for exaple reading integers from within property + * values). We assume that we are either given a naturally aligned + * address for the platform or if we are not, we are on a platform + * where unaligned memory reads will be handled in a graceful manner. + * If not the external helpers fdtXX_ld() from libfdt.h can be used + * instead. + */ +static inline uint32_t fdt32_ld_(const fdt32_t *p) +{ + return fdt32_to_cpu(*p); +} + +static inline uint64_t fdt64_ld_(const fdt64_t *p) +{ + return fdt64_to_cpu(*p); +} + +#define FDT_SW_MAGIC (~FDT_MAGIC) + +/**********************************************************************/ +/* Checking controls */ +/**********************************************************************/ + +#ifndef FDT_ASSUME_MASK +#define FDT_ASSUME_MASK 0 +#endif + +/* + * Defines assumptions which can be enabled. Each of these can be enabled + * individually. For maximum safety, don't enable any assumptions! + * + * For minimal code size and no safety, use ASSUME_PERFECT at your own risk. + * You should have another method of validating the device tree, such as a + * signature or hash check before using libfdt. + * + * For situations where security is not a concern it may be safe to enable + * ASSUME_SANE. + */ +enum { + /* + * This does essentially no checks. Only the latest device-tree + * version is correctly handled. Inconsistencies or errors in the device + * tree may cause undefined behaviour or crashes. Invalid parameters + * passed to libfdt may do the same. + * + * If an error occurs when modifying the tree it may leave the tree in + * an intermediate (but valid) state. As an example, adding a property + * where there is insufficient space may result in the property name + * being added to the string table even though the property itself is + * not added to the struct section. + * + * Only use this if you have a fully validated device tree with + * the latest supported version and wish to minimise code size. + */ + ASSUME_PERFECT = 0xff, + + /* + * This assumes that the device tree is sane. i.e. header metadata + * and basic hierarchy are correct. + * + * With this assumption enabled, normal device trees produced by libfdt + * and the compiler should be handled safely. Malicious device trees and + * complete garbage may cause libfdt to behave badly or crash. Truncated + * device trees (e.g. those only partially loaded) can also cause + * problems. + * + * Note: Only checks that relate exclusively to the device tree itself + * (not the parameters passed to libfdt) are disabled by this + * assumption. This includes checking headers, tags and the like. + */ + ASSUME_VALID_DTB = 1 << 0, + + /* + * This builds on ASSUME_VALID_DTB and further assumes that libfdt + * functions are called with valid parameters, i.e. not trigger + * FDT_ERR_BADOFFSET or offsets that are out of bounds. It disables any + * extensive checking of parameters and the device tree, making various + * assumptions about correctness. + * + * It doesn't make sense to enable this assumption unless + * ASSUME_VALID_DTB is also enabled. + */ + ASSUME_VALID_INPUT = 1 << 1, + + /* + * This disables checks for device-tree version and removes all code + * which handles older versions. + * + * Only enable this if you know you have a device tree with the latest + * version. + */ + ASSUME_LATEST = 1 << 2, + + /* + * This assumes that it is OK for a failed addition to the device tree, + * due to lack of space or some other problem, to skip any rollback + * steps (such as dropping the property name from the string table). + * This is safe to enable in most circumstances, even though it may + * leave the tree in a sub-optimal state. + */ + ASSUME_NO_ROLLBACK = 1 << 3, + + /* + * This assumes that the device tree components appear in a 'convenient' + * order, i.e. the memory reservation block first, then the structure + * block and finally the string block. + * + * This order is not specified by the device-tree specification, + * but is expected by libfdt. The device-tree compiler always created + * device trees with this order. + * + * This assumption disables a check in fdt_open_into() and removes the + * ability to fix the problem there. This is safe if you know that the + * device tree is correctly ordered. See fdt_blocks_misordered_(). + */ + ASSUME_LIBFDT_ORDER = 1 << 4, + + /* + * This assumes that libfdt itself does not have any internal bugs. It + * drops certain checks that should never be needed unless libfdt has an + * undiscovered bug. + * + * This can generally be considered safe to enable. + */ + ASSUME_LIBFDT_FLAWLESS = 1 << 5, +}; + +/** + * can_assume_() - check if a particular assumption is enabled + * + * @mask: Mask to check (ASSUME_...) + * @return true if that assumption is enabled, else false + */ +static inline bool can_assume_(int mask) +{ + return FDT_ASSUME_MASK & mask; +} + +/** helper macros for checking assumptions */ +#define can_assume(_assume) can_assume_(ASSUME_ ## _assume) + +#endif /* LIBFDT_INTERNAL_H */ diff --git a/libfdt-binding/mystr.c b/libfdt-binding/mystr.c new file mode 100644 index 0000000000000000000000000000000000000000..bf7f882f9fc09bbf266cfce14c0dfb1591c7e98f --- /dev/null +++ b/libfdt-binding/mystr.c @@ -0,0 +1,76 @@ +void *memcpy(void *dst, const void *src, unsigned long count); + +int memcmp(const void *vl, const void *vr, unsigned long n) { + const unsigned char *l = vl, *r = vr; + for (; n && *l == *r; n--, l++, r++) + ; + return n ? *l - *r : 0; +} + +void *memchr(const void *src, int c, unsigned long n) { + const unsigned char *s = src; + c = (unsigned char)c; + for (; n && *s != c; s++, n--) + ; + return n ? (void *)s : 0; +} + +void *memmove(void *dest, const void *src, unsigned long n) { + char *d = dest; + const char *s = src; + + if (d == s) + return d; + if ((unsigned long)s - (unsigned long)d - n <= -2 * n) + return memcpy(d, s, n); + + if (d < s) { + for (; n; n--) + *d++ = *s++; + } else { + while (n) + n--, d[n] = s[n]; + } + + return dest; +} + +unsigned long strlen(const char *s) { + const char *a = s; + for (; *s; s++) + ; + return s - a; +} + +unsigned long strnlen(const char *s, unsigned long n) { + const char *p = memchr(s, 0, n); + return p ? (unsigned long)(p - s) : n; +} + +static char *strchrnul(const char *s, int c) { + c = (unsigned char)c; + if (!c) + return (char *)s + strlen(s); + for (; *s && *(unsigned char *)s != c; s++) + ; + return (char *)s; +} + +char *strchr(const char *s, int c) { + char *r = strchrnul(s, c); + return *(unsigned char *)r == (unsigned char)c ? r : 0; +} + +static void *memrchr(const void *m, int c, unsigned long n) { + const unsigned char *s = m; + c = (unsigned char)c; + while (n--) + if (s[n] == c) + return (void *)(s + n); + return 0; +} + + +char *strrchr(const char *s, int c) { return memrchr(s, c, strlen(s) + 1); } + + diff --git a/libfdt-binding/src/lib.rs b/libfdt-binding/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..4349a14c269cefe487c33e2c2f69016cee5dff9b --- /dev/null +++ b/libfdt-binding/src/lib.rs @@ -0,0 +1,36 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +#![no_std] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +pub mod myctypes { + pub type c_void = core::ffi::c_void; + + pub type c_char = u8; + pub type c_schar = i8; + pub type c_uchar = u8; + + pub type c_short = i16; + pub type c_ushort = u16; + + pub type c_int = i32; + pub type c_uint = u32; + + pub type c_long = i64; + pub type c_ulong = u64; + + pub type c_longlong = i64; + pub type c_ulonglong = u64; +} + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/libfdt-binding/wrapper.c b/libfdt-binding/wrapper.c new file mode 100644 index 0000000000000000000000000000000000000000..62886eecdb0410854ea1b683227fcc1fe8adb167 --- /dev/null +++ b/libfdt-binding/wrapper.c @@ -0,0 +1,298 @@ +#include "wrapper.h" +#include "libfdt.h" + +#define PAGE_SIZE 4096 + +int fdt_remove_node(void *fdt, const char *path) { + int node = fdt_path_offset(fdt, path); + if (node < 0) { + return -1; + } + fdt_del_node(fdt, node); + return 0; +} + +int fdt_disable_node(void *fdt, const char *path) { + int len = 0; + int node = fdt_path_offset(fdt, path); + if (node < 0) { + return -1; + } + const char *prop = fdt_getprop(fdt, node, "status", &len); + if (prop == NULL) { + fdt_setprop_string(fdt, node, "status", "disabled"); + return 0; + } + fdt_setprop_inplace(fdt, node, "status", "NILL", len); + return 0; +} + +void fdt_add_virtio(void *fdt, const char *name, uint32_t spi_irq, + uint64_t address) { + int root = fdt_path_offset(fdt, "/"); + int node = fdt_add_subnode(fdt, root, name); + fdt_setprop(fdt, node, "dma-coherent", NULL, 0); + fdt_setprop_string(fdt, node, "compatible", "virtio,mmio"); + fdt32_t irq[3] = { + cpu_to_fdt32(0), + cpu_to_fdt32(spi_irq), + cpu_to_fdt32(0x1), + }; + fdt_setprop(fdt, node, "interrupts", irq, sizeof(irq)); + fdt64_t addr[2] = { + cpu_to_fdt64(address), + cpu_to_fdt64(0x400), + }; + fdt_setprop(fdt, node, "reg", addr, sizeof(addr)); +} + +void fdt_add_vm_service(void *fdt, uint32_t spi_irq, uint64_t address, + uint64_t len) { + int root = fdt_path_offset(fdt, "/"); + int node = fdt_add_subnode(fdt, root, "vm_service"); + fdt_setprop_string(fdt, node, "compatible", "shyper"); + fdt32_t irq[3] = { + cpu_to_fdt32(0), + cpu_to_fdt32(spi_irq), + cpu_to_fdt32(0x1), + }; + fdt_setprop(fdt, node, "interrupts", irq, sizeof(irq)); + if (address != 0 && len != 0) { + fdt64_t addr[2] = { + cpu_to_fdt64(address), + cpu_to_fdt64(len), + }; + fdt_setprop(fdt, node, "reg", addr, sizeof(addr)); + } +} + +void fdt_add_timer(void *fdt, uint32_t trigger_lvl) { + int root = fdt_path_offset(fdt, "/"); + int node = fdt_add_subnode(fdt, root, "timer"); + fdt_setprop_string(fdt, node, "compatible", "arm,armv8-timer"); + fdt32_t irq[12] = { + cpu_to_fdt32(0x1), cpu_to_fdt32(0xd), cpu_to_fdt32(trigger_lvl), + cpu_to_fdt32(0x1), cpu_to_fdt32(0xe), cpu_to_fdt32(trigger_lvl), + cpu_to_fdt32(0x1), cpu_to_fdt32(0xb), cpu_to_fdt32(trigger_lvl), + cpu_to_fdt32(0x1), cpu_to_fdt32(0xa), cpu_to_fdt32(trigger_lvl), + }; + fdt_setprop(fdt, node, "interrupts", irq, sizeof(irq)); +} + +void fdt_add_vm_service_blk(void *fdt, uint32_t spi_irq) { + int root = fdt_path_offset(fdt, "/"); + int node = fdt_add_subnode(fdt, root, "vm_service_blk"); + fdt_setprop_string(fdt, node, "compatible", "shyper_blk"); + fdt32_t irq[3] = { + cpu_to_fdt32(0), + cpu_to_fdt32(spi_irq), + cpu_to_fdt32(0x1), + }; + fdt_setprop(fdt, node, "interrupts", irq, sizeof(irq)); +} + +void fdt_add_cpu(void *fdt, uint64_t linear_id, uint8_t core_id, + uint8_t cluster_id, const char *compatible) { + // NOTE: this function assumes cpu-map does NOT exist and #address-cells = <2> + char node_name[32] = "cpu@x"; + node_name[4] = linear_id + '0'; + int cpus = fdt_path_offset(fdt, "/cpus"); + int node = fdt_add_subnode(fdt, cpus, node_name); + fdt_setprop_string(fdt, node, "compatible", compatible); + fdt_setprop_string(fdt, node, "device_type", "cpu"); + fdt_setprop_string(fdt, node, "enable-method", "psci"); + fdt32_t reg[2] = { + cpu_to_fdt32(0), + cpu_to_fdt32(cluster_id << 8 | core_id), + }; + fdt_setprop(fdt, node, "reg", reg, sizeof(reg)); +} + +void fdt_set_bootcmd(void *fdt, const char *cmdline) { + int node; + node = fdt_path_offset(fdt, "/chosen"); + fdt_setprop_string(fdt, node, "bootargs", cmdline); +} + +void fdt_set_initrd(void *fdt, uint32_t start, uint32_t end) { + // NOTE: linux,initrd-start/end only has one cell (uint32_t) + int node; + node = fdt_path_offset(fdt, "/chosen"); + fdt32_t addr = cpu_to_fdt32((uint32_t)start); + fdt_setprop(fdt, node, "linux,initrd-start", &addr, sizeof(fdt32_t)); + addr = cpu_to_fdt32(end); + fdt_setprop(fdt, node, "linux,initrd-end", &addr, sizeof(fdt32_t)); +} + +void fdt_set_memory(void *fdt, uint64_t region_num, + const struct region *regions, const char *node_name) { + // NOTE: this function dose NOT assume memory_node existed + int r; +#define FDT_MEMORY_REGION_MAX 4 + if (region_num == 0) { + return; + } + if (region_num > FDT_MEMORY_REGION_MAX) { + region_num = FDT_MEMORY_REGION_MAX; + } + int existed = fdt_node_offset_by_prop_value(fdt, 0, "device_type", "memory", + (int)strlen("memory") + 1); + if (existed > 0) { + fdt_del_node(fdt, existed); + } + + int node; + int root = fdt_path_offset(fdt, "/"); + node = fdt_add_subnode(fdt, root, node_name); + if (node < 0) { + return; + } + r = fdt_setprop_string(fdt, node, "device_type", "memory"); + if (r < 0) { + return; + } + + fdt64_t addr[FDT_MEMORY_REGION_MAX * 2]; + for (uint64_t i = 0; i < region_num; ++i) { + addr[2 * i] = cpu_to_fdt64(regions[i].ipa_start); + addr[2 * i + 1] = cpu_to_fdt64(regions[i].length); + } + r = fdt_setprop(fdt, node, "reg", addr, + (int)region_num * 2 * (int)sizeof(fdt64_t)); + if (r < 0) { + return; + } +} + +void fdt_clear_initrd(void *fdt) { + int node; + node = fdt_path_offset(fdt, "/chosen"); + if (node < 0) { + return; + } + fdt_delprop(fdt, node, "linux,initrd-start"); + fdt_delprop(fdt, node, "linux,initrd-end"); +} + +int fdt_setup_gic(void *fdt, uint64_t gicd_addr, uint64_t gicc_addr, + const char *node_name) { + int r; + int node; + node = fdt_node_offset_by_compatible(fdt, 0, "arm,cortex-a15-gic"); + if (node < 0) { + node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-400"); + if (node < 0) { + return 0; + } + } + fdt64_t addr[4] = { + cpu_to_fdt64(gicd_addr), + cpu_to_fdt64(0x1000), + cpu_to_fdt64(gicc_addr), + cpu_to_fdt64(0x2000), + }; + r = fdt_setprop(fdt, node, "reg", addr, sizeof(addr)); + fdt_nop_property(fdt, node, "interrupts"); + if (r < 0) { + return 0; + } + r = fdt_set_name(fdt, node, node_name); + return 1; +} + +void fdt_setup_serial(void *fdt, const char *compatible, uint64_t addr, + uint32_t spi_irq) { + int r; + int node; + node = fdt_node_offset_by_compatible(fdt, 0, compatible); + if (node < 0) { + return; + } + fdt64_t reg[2] = { + cpu_to_fdt64(addr), + cpu_to_fdt64(0x1000), + }; + r = fdt_setprop(fdt, node, "reg", reg, sizeof(reg)); + if (r < 0) { + return; + } + fdt32_t irq[3] = { + cpu_to_fdt32(0), + cpu_to_fdt32(spi_irq), + cpu_to_fdt32(0x4), + }; + r = fdt_setprop(fdt, node, "interrupts", irq, sizeof(irq)); + if (r < 0) { + return; + } + r = fdt_setprop_string(fdt, node, "status", "okay"); + if (r < 0) { + return; + } + r = fdt_set_name(fdt, node, "serial@0"); +} + +void fdt_set_stdout_path(void *fdt, const char *p) { + int r; + int node; + node = fdt_path_offset(fdt, "/chosen"); + if (node < 0) { + return; + } + r = fdt_setprop_string(fdt, node, "stdout-path", p); +} + +void fdt_clear_stdout_path(void *fdt) { + int node; + node = fdt_path_offset(fdt, "/chosen"); + fdt_delprop(fdt, node, "stdout-path"); +} + +static inline uint64_t round_up(uint64_t value, uint64_t to) { + return ((value + to - 1) / to) * to; +} + +void fdt_enlarge(void *fdt) { + int old_size = fdt_totalsize(fdt); + int new_size = (int)round_up(fdt_totalsize(fdt), PAGE_SIZE) + PAGE_SIZE; + fdt_open_into(fdt, fdt, new_size); +} + +uint64_t fdt_size(void *fdt) { return fdt_totalsize(fdt); } + +int fdt_setup_pmu(void *fdt, const char *compatible, const uint32_t *spi_irq, + uint32_t spi_irq_len, const uint32_t *irq_affi, + uint32_t irq_affi_len) { + const int MAX_LEN = 8; + int r = 0; + if (spi_irq_len != irq_affi_len || spi_irq_len >= MAX_LEN) { + return -1; + } + size_t len = spi_irq_len; + int node = fdt_node_offset_by_compatible(fdt, 0, compatible); + if (node < 0) { + return -1; + } + fdt_delprop(fdt, node, "interrupts"); + fdt_delprop(fdt, node, "interrupt-affinity"); + + fdt32_t irq[3 * MAX_LEN]; + for (size_t i = 0; i < len; i++) { + irq[3 * i] = cpu_to_fdt32(0); + irq[3 * i + 1] = cpu_to_fdt32(spi_irq[i]); + irq[3 * i + 2] = cpu_to_fdt32(0x4); + } + r = fdt_setprop(fdt, node, "interrupts", irq, sizeof(irq[0]) * 3 * len); + if (r < 0) { + return r; + } + fdt32_t affi[MAX_LEN]; + for (size_t i = 0; i < len; i++) { + affi[i] = cpu_to_fdt32(irq_affi[i]); + } + r = fdt_setprop(fdt, node, "interrupt-affinity", affi, sizeof(affi[0]) * len); + if (r < 0) { + return r; + } + return r; +} diff --git a/libfdt-binding/wrapper.h b/libfdt-binding/wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..8f2b7de38e0f4725b1894adc979371dfa8797ee0 --- /dev/null +++ b/libfdt-binding/wrapper.h @@ -0,0 +1,61 @@ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long uint64_t; + +// Note: this module assume +// 1. template uses #size-cells = <0x2> and #address-cells = <0x2> +// 2. `chosen` node exists + +struct region { + uint64_t ipa_start; + uint64_t length; +}; + +int fdt_remove_node(void *fdt, const char *path); + +int fdt_disable_node(void *fdt, const char *path); + +void fdt_add_virtio(void *fdt, const char *name, uint32_t spi_irq, + uint64_t address); + +void fdt_add_vm_service(void *fdt, uint32_t spi_irq, uint64_t address, + uint64_t len); + +void fdt_add_timer(void *fdt, uint32_t trigger_lvl); + +void fdt_add_vm_service_blk(void *fdt, uint32_t spi_irq); + +void fdt_add_cpu(void *fdt, uint64_t linear_id, uint8_t core_id, + uint8_t cluster_id, const char *compatible); + +void fdt_set_bootcmd(void *fdt, const char *cmdline); + +void fdt_set_initrd(void *fdt, uint32_t start, uint32_t end); + +void fdt_set_memory(void *fdt, uint64_t region_num, + const struct region *regions, const char *node_name); + +void fdt_clear_initrd(void *fdt); + +int fdt_setup_gic(void *fdt, uint64_t gicd_addr, uint64_t gicc_addr, + const char *node_name); + +void fdt_setup_serial(void *fdt, const char *compatible, uint64_t addr, + uint32_t spi_irq); + +void fdt_set_stdout_path(void *fdt, const char *p); + +void fdt_clear_stdout_path(void *fdt); + +void fdt_enlarge(void *fdt); + +uint64_t fdt_size(void *fdt); + +int fdt_pack(void *fdt); + +int fdt_del_mem_rsv(void *fdt, int n); + +int fdt_setup_pmu(void *fdt, const char *compatible, const uint32_t *spi_irq, + uint32_t spi_irq_len, const uint32_t *irq_affi, + uint32_t irq_affi_len); diff --git a/pi4_upload_release b/pi4_upload_release new file mode 100644 index 0000000000000000000000000000000000000000..46e3dcc21b2d491c7f984f4cdcab194981e97b91 --- /dev/null +++ b/pi4_upload_release @@ -0,0 +1,12 @@ +#!/bin/bash + +bin="./target/aarch64-pi4/release" +tftp="root@192.168.106.153:/tftp" + +rust-objcopy ${bin}/rust_shyper -O binary ${bin}/shyper.bin +mkimage -n shyper -A arm64 -O linux -T kernel -C none -a 0xF0080000 -e 0xF0080000 \ +-d ${bin}/shyper.bin ${bin}/shyperImage +echo "*** Upload Image Rust_Image_pi ***" + +scp ${bin}/shyperImage ${tftp}/Rust_Image_pi +scp ./image/pi4_fin.dtb ${tftp}/pi4_dtb \ No newline at end of file diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000000000000000000000000000000000000..fdd6c8279e69072a5fc91749d1be46f6f8f00bc6 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly-2022-09-14 diff --git a/src/arch/aarch64/cache.S b/src/arch/aarch64/cache.S new file mode 100644 index 0000000000000000000000000000000000000000..3a2209953de6690ac12c530c536a48efa4b59dbc --- /dev/null +++ b/src/arch/aarch64/cache.S @@ -0,0 +1,27 @@ +// void cache_invalidate_d(u64 start, u64 length); +.global cache_invalidate_d +cache_invalidate_d: + add x2, x0, x1 /* calculate the end address */ + bic x0, x0, #(64 - 1) /* align the start with a cache line */ +1: + dc ivac, x0 /* invalidate cache to PoC by VA */ + add x0, x0, #64 + cmp x0, x2 + blt 1b + mov x0, xzr + dsb sy + ret + +// void cache_clean_invalidate_d(u64 start, u64 length); +.global cache_clean_invalidate_d +cache_clean_invalidate_d: + add x2, x0, x1 /* calculate the end address */ + bic x0, x0, #(64 - 1) /* align the start with a cache line */ +1: + dc civac, x0 /* invalidate cache to PoC by VA */ + add x0, x0, #64 + cmp x0, x2 + blt 1b + mov x0, xzr + dsb sy + ret diff --git a/src/arch/aarch64/context_frame.rs b/src/arch/aarch64/context_frame.rs new file mode 100644 index 0000000000000000000000000000000000000000..f8544bc7e89c196f6a5213c94879aef9711b7b65 --- /dev/null +++ b/src/arch/aarch64/context_frame.rs @@ -0,0 +1,445 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::arch::global_asm; +use core::fmt::Formatter; + +use cortex_a::registers::*; + +use crate::arch::{GICD, GicState}; + +global_asm!(include_str!("fpsimd.S")); + +extern "C" { + pub fn fpsimd_save_ctx(fpsimd_addr: usize); + pub fn fpsimd_restore_ctx(fpsimd_addr: usize); +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct Aarch64ContextFrame { + gpr: [u64; 31], + pub spsr: u64, + elr: u64, + sp: u64, +} + +impl core::fmt::Display for Aarch64ContextFrame { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { + for i in 0..31 { + write!(f, "x{:02}: {:016x} ", i, self.gpr[i])?; + if (i + 1) % 2 == 0 { + write!(f, "\n")?; + } + } + writeln!(f, "spsr:{:016x}", self.spsr)?; + write!(f, "elr: {:016x}", self.elr)?; + writeln!(f, " sp: {:016x}", self.sp)?; + Ok(()) + } +} + +impl crate::arch::ContextFrameTrait for Aarch64ContextFrame { + fn new(pc: usize, sp: usize, arg: usize) -> Self { + let mut r = Aarch64ContextFrame { + gpr: [0; 31], + spsr: (SPSR_EL1::M::EL1h + + SPSR_EL1::I::Masked + + SPSR_EL1::F::Masked + + SPSR_EL1::A::Masked + + SPSR_EL1::D::Masked) + .value as u64, + elr: pc as u64, + sp: sp as u64, + }; + r.set_argument(arg); + r + } + + fn exception_pc(&self) -> usize { + self.elr as usize + } + + fn set_exception_pc(&mut self, pc: usize) { + self.elr = pc as u64; + } + + fn stack_pointer(&self) -> usize { + self.sp as usize + } + + fn set_stack_pointer(&mut self, sp: usize) { + self.sp = sp as u64; + } + + fn set_argument(&mut self, arg: usize) { + self.gpr[0] = arg as u64; + } + + fn set_gpr(&mut self, index: usize, val: usize) { + self.gpr[index] = val as u64; + } + + fn gpr(&self, index: usize) -> usize { + self.gpr[index] as usize + } +} + +impl Aarch64ContextFrame { + pub fn default() -> Aarch64ContextFrame { + Aarch64ContextFrame { + gpr: [0; 31], + spsr: (SPSR_EL1::M::EL1h + + SPSR_EL1::I::Masked + + SPSR_EL1::F::Masked + + SPSR_EL1::A::Masked + + SPSR_EL1::D::Masked) + .value as u64, + elr: 0, + sp: 0, + } + } +} + +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone, Debug)] +pub struct VmCtxFpsimd { + fpsimd: [u64; 64], + fpsr: u32, + fpcr: u32, +} + +impl VmCtxFpsimd { + pub fn default() -> VmCtxFpsimd { + VmCtxFpsimd { + fpsimd: [0; 64], + fpsr: 0, + fpcr: 0, + } + } + + pub fn reset(&mut self) { + self.fpsr = 0; + self.fpcr = 0; + self.fpsimd.iter_mut().for_each(|x| *x = 0); + } +} + +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone, Default)] +pub struct GicIrqState { + pub id: u64, + pub enable: u8, + pub pend: u8, + pub active: u8, + pub priority: u8, + pub target: u8, +} + +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone, Default)] +pub struct GicContext { + irq_num: usize, + pub irq_state: [GicIrqState; 10], + // hard code for vm irq num max + gicv_ctlr: u32, + gicv_pmr: u32, +} + +impl GicContext { + pub fn add_irq(&mut self, id: u64) { + let idx = self.irq_num; + self.irq_state[idx].id = id; + self.irq_state[idx].enable = ((GICD.is_enabler(id as usize / 32) >> (id & 32)) & 1) as u8; + // self.irq_state[idx].pend = id; + // self.irq_state[idx].active = id; + self.irq_state[idx].priority = GICD.prio(id as usize) as u8; + self.irq_state[idx].target = GICD.trgt(id as usize) as u8; + self.irq_num += 1; + } + + pub fn set_gicv_ctlr(&mut self, ctlr: u32) { + self.gicv_ctlr = ctlr; + } + + pub fn set_gicv_pmr(&mut self, pmr: u32) { + self.gicv_pmr = pmr; + } + + pub fn gicv_ctlr(&self) -> u32 { + self.gicv_ctlr + } + + pub fn gicv_pmr(&self) -> u32 { + self.gicv_pmr + } +} + +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone)] +pub struct VmContext { + // generic timer + pub cntvoff_el2: u64, + cntp_cval_el0: u64, + cntv_cval_el0: u64, + pub cntkctl_el1: u32, + pub cntvct_el0: u64, + cntp_ctl_el0: u32, + cntv_ctl_el0: u32, + cntp_tval_el0: u32, + cntv_tval_el0: u32, + + // vpidr and vmpidr + vpidr_el2: u32, + pub vmpidr_el2: u64, + + // 64bit EL1/EL0 register + sp_el0: u64, + sp_el1: u64, + elr_el1: u64, + spsr_el1: u32, + pub sctlr_el1: u32, + actlr_el1: u64, + cpacr_el1: u32, + ttbr0_el1: u64, + ttbr1_el1: u64, + tcr_el1: u64, + esr_el1: u32, + far_el1: u64, + par_el1: u64, + mair_el1: u64, + amair_el1: u64, + vbar_el1: u64, + contextidr_el1: u32, + tpidr_el0: u64, + tpidr_el1: u64, + tpidrro_el0: u64, + + // hypervisor context + pub hcr_el2: u64, + cptr_el2: u64, + hstr_el2: u64, + pub pmcr_el0: u64, + pub vtcr_el2: u64, + + // exception + far_el2: u64, + hpfar_el2: u64, + fpsimd: VmCtxFpsimd, + pub gic_state: GicState, +} + +impl VmContext { + pub fn default() -> VmContext { + VmContext { + // generic timer + cntvoff_el2: 0, + cntp_cval_el0: 0, + cntv_cval_el0: 0, + cntkctl_el1: 0, + cntvct_el0: 0, + cntp_ctl_el0: 0, + cntv_ctl_el0: 0, + cntp_tval_el0: 0, + cntv_tval_el0: 0, + + // vpidr and vmpidr + vpidr_el2: 0, + vmpidr_el2: 0, + + // 64bit EL1/EL0 register + sp_el0: 0, + sp_el1: 0, + elr_el1: 0, + spsr_el1: 0, + sctlr_el1: 0, + actlr_el1: 0, + cpacr_el1: 0, + ttbr0_el1: 0, + ttbr1_el1: 0, + tcr_el1: 0, + esr_el1: 0, + far_el1: 0, + par_el1: 0, + mair_el1: 0, + amair_el1: 0, + vbar_el1: 0, + contextidr_el1: 0, + tpidr_el0: 0, + tpidr_el1: 0, + tpidrro_el0: 0, + + // hypervisor context + hcr_el2: 0, + cptr_el2: 0, + hstr_el2: 0, + + // exception + pmcr_el0: 0, + vtcr_el2: 0, + far_el2: 0, + hpfar_el2: 0, + fpsimd: VmCtxFpsimd::default(), + gic_state: GicState::default(), + } + } + + pub fn reset(&mut self) { + self.cntvoff_el2 = 0; + self.cntp_cval_el0 = 0; + self.cntv_cval_el0 = 0; + self.cntp_tval_el0 = 0; + self.cntv_tval_el0 = 0; + self.cntkctl_el1 = 0; + self.cntvct_el0 = 0; + self.cntp_ctl_el0 = 0; + self.vpidr_el2 = 0; + self.vmpidr_el2 = 0; + self.sp_el0 = 0; + self.sp_el1 = 0; + self.elr_el1 = 0; + self.spsr_el1 = 0; + self.sctlr_el1 = 0; + self.actlr_el1 = 0; + self.cpacr_el1 = 0; + self.ttbr0_el1 = 0; + self.ttbr1_el1 = 0; + self.tcr_el1 = 0; + self.esr_el1 = 0; + self.far_el1 = 0; + self.par_el1 = 0; + self.mair_el1 = 0; + self.amair_el1 = 0; + self.vbar_el1 = 0; + self.contextidr_el1 = 0; + self.tpidr_el0 = 0; + self.tpidr_el1 = 0; + self.tpidrro_el0 = 0; + self.hcr_el2 = 0; + self.cptr_el2 = 0; + self.hstr_el2 = 0; + self.far_el2 = 0; + self.hpfar_el2 = 0; + self.fpsimd.reset(); + } + + pub fn ext_regs_store(&mut self) { + mrs!(self.cntvoff_el2, CNTVOFF_EL2); + // MRS!(self.cntp_cval_el0, CNTP_CVAL_EL0); + mrs!(self.cntv_cval_el0, CNTV_CVAL_EL0); + mrs!(self.cntkctl_el1, CNTKCTL_EL1, "x"); + mrs!(self.cntp_ctl_el0, CNTP_CTL_EL0, "x"); + mrs!(self.cntv_ctl_el0, CNTV_CTL_EL0, "x"); + mrs!(self.cntp_tval_el0, CNTP_TVAL_EL0, "x"); + mrs!(self.cntv_tval_el0, CNTV_TVAL_EL0, "x"); + mrs!(self.cntvct_el0, CNTVCT_EL0); + // MRS!("self.vpidr_el2, VPIDR_EL2, "x"); + mrs!(self.vmpidr_el2, VMPIDR_EL2); + + mrs!(self.sp_el0, SP_EL0); + mrs!(self.sp_el1, SP_EL1); + mrs!(self.elr_el1, ELR_EL1); + mrs!(self.spsr_el1, SPSR_EL1, "x"); + mrs!(self.sctlr_el1, SCTLR_EL1, "x"); + mrs!(self.cpacr_el1, CPACR_EL1, "x"); + mrs!(self.ttbr0_el1, TTBR0_EL1); + mrs!(self.ttbr1_el1, TTBR1_EL1); + mrs!(self.tcr_el1, TCR_EL1); + mrs!(self.esr_el1, ESR_EL1, "x"); + mrs!(self.far_el1, FAR_EL1); + mrs!(self.par_el1, PAR_EL1); + mrs!(self.mair_el1, MAIR_EL1); + mrs!(self.amair_el1, AMAIR_EL1); + mrs!(self.vbar_el1, VBAR_EL1); + mrs!(self.contextidr_el1, CONTEXTIDR_EL1, "x"); + mrs!(self.tpidr_el0, TPIDR_EL0); + mrs!(self.tpidr_el1, TPIDR_EL1); + mrs!(self.tpidrro_el0, TPIDRRO_EL0); + + mrs!(self.pmcr_el0, PMCR_EL0); + mrs!(self.vtcr_el2, VTCR_EL2); + mrs!(self.hcr_el2, HCR_EL2); + // MRS!(self.cptr_el2, CPTR_EL2); + // MRS!(self.hstr_el2, HSTR_EL2); + // MRS!(self.far_el2, FAR_EL2); + // MRS!(self.hpfar_el2, HPFAR_EL2); + mrs!(self.actlr_el1, ACTLR_EL1); + // println!("save sctlr {:x}", self.sctlr_el1); + } + + pub fn ext_regs_restore(&self) { + // println!("restore CNTV_CTL_EL0 {:x}", self.cntv_ctl_el0); + // println!("restore CNTV_CVAL_EL0 {:x}", self.cntv_cval_el0); + msr!(CNTVOFF_EL2, self.cntvoff_el2); + // MSR!(CNTP_CVAL_EL0, self.cntp_cval_el0); + msr!(CNTV_CVAL_EL0, self.cntv_cval_el0); + msr!(CNTKCTL_EL1, self.cntkctl_el1, "x"); + // MSR!(CNTP_CTL_EL0, self.cntp_ctl_el0, "x"); + msr!(CNTV_CTL_EL0, self.cntv_ctl_el0, "x"); + // MSR!(CNTP_TVAL_EL0, {0:x}", in(reg) self.cntp_tval_el0, "x"); + // MSR!(CNTV_TVAL_EL0, {0:x}", in(reg) self.cntv_tval_el0, "x"); + + // MSR!(VPIDR_EL2, self.vpidr_el2, "x"); + msr!(VMPIDR_EL2, self.vmpidr_el2); + + msr!(SP_EL0, self.sp_el0); + msr!(SP_EL1, self.sp_el1); + msr!(ELR_EL1, self.elr_el1); + msr!(SPSR_EL1, self.spsr_el1, "x"); + msr!(SCTLR_EL1, self.sctlr_el1, "x"); + msr!(CPACR_EL1, self.cpacr_el1, "x"); + msr!(TTBR0_EL1, self.ttbr0_el1); + msr!(TTBR1_EL1, self.ttbr1_el1); + msr!(TCR_EL1, self.tcr_el1); + msr!(ESR_EL1, self.esr_el1, "x"); + msr!(FAR_EL1, self.far_el1); + msr!(PAR_EL1, self.par_el1); + msr!(MAIR_EL1, self.mair_el1); + msr!(AMAIR_EL1, self.amair_el1); + msr!(VBAR_EL1, self.vbar_el1); + msr!(CONTEXTIDR_EL1, self.contextidr_el1, "x"); + msr!(TPIDR_EL0, self.tpidr_el0); + msr!(TPIDR_EL1, self.tpidr_el1); + msr!(TPIDRRO_EL0, self.tpidrro_el0); + + msr!(PMCR_EL0, self.pmcr_el0); + msr!(VTCR_EL2, self.vtcr_el2); + msr!(HCR_EL2, self.hcr_el2); + // MSR!(CPTR_EL2, self.cptr_el2); + // MSR!(HSTR_EL2, self.hstr_el2); + // MSR!(FAR_EL2, self.far_el2); + // MSR!(HPFAR_EL2, self.hpfar_el2); + msr!(ACTLR_EL1, self.actlr_el1); + } + + pub fn fpsimd_save_context(&self) { + unsafe { + fpsimd_save_ctx(&self.fpsimd as *const _ as usize); + } + } + + pub fn fpsimd_restore_context(&self) { + unsafe { + fpsimd_restore_ctx(&self.fpsimd as *const _ as usize); + } + } + + pub fn gic_save_state(&mut self) { + self.gic_state.save_state(); + } + + pub fn gic_restore_state(&self) { + self.gic_state.restore_state(); + } +} diff --git a/src/arch/aarch64/cpu.rs b/src/arch/aarch64/cpu.rs new file mode 100644 index 0000000000000000000000000000000000000000..b045ce0aaa0dc6f581827bccf1548cb9959c11f9 --- /dev/null +++ b/src/arch/aarch64/cpu.rs @@ -0,0 +1,28 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use cortex_a::registers::DAIF; +use tock_registers::interfaces::*; + +/// Mask (disable) interrupt from perspective of CPU +#[inline(always)] +pub fn cpu_interrupt_mask() { + DAIF.write(DAIF::I::Masked) +} + +/// Unmask (enable) interrupt from perspective of CPU +#[inline(always)] +pub fn cpu_interrupt_unmask() { + DAIF.write(DAIF::I::Unmasked) +} + +pub fn cpu_daif() -> u64 { + DAIF.read(DAIF::I) +} diff --git a/src/arch/aarch64/exception.S b/src/arch/aarch64/exception.S new file mode 100644 index 0000000000000000000000000000000000000000..9feed208d48d553ab093769be760291a05672e4e --- /dev/null +++ b/src/arch/aarch64/exception.S @@ -0,0 +1,123 @@ +.macro VECTOR handler + sub sp, sp, #(0x110) + stp x0, x1, [sp, #(0 * 16)] + stp x2, x3, [sp, #(1 * 16)] + stp x4, x5, [sp, #(2 * 16)] + stp x6, x7, [sp, #(3 * 16)] + stp x8, x9, [sp, #(4 * 16)] + stp x10,x11, [sp, #(5 * 16)] + stp x12,x13, [sp, #(6 * 16)] + stp x14,x15, [sp, #(7 * 16)] + stp x16,x17, [sp, #(8 * 16)] + stp x18,x19, [sp, #(9 * 16)] + stp x20,x21, [sp, #(10 * 16)] + stp x22,x23, [sp, #(11 * 16)] + stp x24,x25, [sp, #(12 * 16)] + stp x26,x27, [sp, #(13 * 16)] + stp x28,x29, [sp, #(14 * 16)] + mrs x1, spsr_el2 + stp x30, x1, [sp, #(15 * 16)] + mrs x0, elr_el2 + mov x1, sp + add x1, x1, #(0x110) + stp x0, x1, [sp, #(16 * 16)] + mov x0, sp + bl \handler + b context_pop +.endm + +.macro VECTOR_DISABLED +1: wfe + b 1b +.endm + + +.section .text.vectors +.align 11 +.global vectors +vectors: + +// Current exception level with SP_EL0. +.org 0x000 + VECTOR current_el_sp0_synchronous +.org 0x080 + VECTOR current_el_sp0_irq +.org 0x100 + VECTOR_DISABLED +.org 0x180 + VECTOR current_el_sp0_serror + +// Current exception level with SP_ELx, x > 0. +.org 0x200 + VECTOR current_el_spx_synchronous +.org 0x280 + VECTOR current_el_spx_irq +.org 0x300 + VECTOR_DISABLED // FIQ +.org 0x380 + VECTOR current_el_spx_serror + +// Lower exception level, aarch64 +.org 0x400 + VECTOR lower_aarch64_synchronous +.org 0x480 + VECTOR lower_aarch64_irq +.org 0x500 + VECTOR_DISABLED // FIQ +.org 0x580 + VECTOR lower_aarch64_serror + +// Lower exception level, aarch32 +.org 0x600 + VECTOR_DISABLED +.org 0x680 + VECTOR_DISABLED +.org 0x700 + VECTOR_DISABLED +.org 0x780 + VECTOR_DISABLED +.org 0x800 + +.global context_vm_entry +context_vm_entry: + mov sp, x0 +context_pop: + ldr x0, [sp, #(31 * 8)] // spsr + ldr x1, [sp, #(32 * 8)] // elr + msr spsr_el2, x0 + msr elr_el2, x1 + ldp x0, x1, [sp, #(0 * 16)] + ldp x2, x3, [sp, #(1 * 16)] + ldp x4, x5, [sp, #(2 * 16)] + ldp x6, x7, [sp, #(3 * 16)] + ldp x8, x9, [sp, #(4 * 16)] + ldp x10,x11, [sp, #(5 * 16)] + ldp x12,x13, [sp, #(6 * 16)] + ldp x14,x15, [sp, #(7 * 16)] + ldp x16,x17, [sp, #(8 * 16)] + ldp x18,x19, [sp, #(9 * 16)] + ldp x20,x21, [sp, #(10 * 16)] + ldp x22,x23, [sp, #(11 * 16)] + ldp x24,x25, [sp, #(12 * 16)] + ldp x26,x27, [sp, #(13 * 16)] + ldp x28,x29, [sp, #(14 * 16)] + ldr x30, [sp, #(15 * 16)] + add sp, sp, #(0x110) + eret + +.global fresh_cpu +fresh_cpu: + sub sp, sp, #8 + str x0, [sp] + + ldr x0, =vectors + msr vbar_el2, x0 + + ldr x0, [sp] + add sp, sp, #8 + ret + +.global fresh_hyper +fresh_hyper: + bl fresh_cpu + b context_vm_entry \ No newline at end of file diff --git a/src/arch/aarch64/exception.rs b/src/arch/aarch64/exception.rs new file mode 100644 index 0000000000000000000000000000000000000000..eb5fff3733fa55c7b93be60a2defeaf0ad356ecc --- /dev/null +++ b/src/arch/aarch64/exception.rs @@ -0,0 +1,310 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::arch::global_asm; + +use tock_registers::interfaces::*; + +use crate::arch::{ContextFrameTrait, data_abort_handler, hvc_handler, smc_handler}; +use crate::arch::{gicc_clear_current_irq, gicc_get_current_irq}; +use crate::arch::ContextFrame; +use crate::kernel::{active_vm_id, current_cpu, FRESH_IRQ_LOGIC_LOCK, FRESH_LOGIC_LOCK, fresh_status, FreshStatus}; +use crate::kernel::interrupt_handler; +use crate::lib::time_current_us; + +// use crate::lib::time_current_us; + +global_asm!(include_str!("exception.S")); + +#[inline(always)] +pub fn exception_esr() -> usize { + cortex_a::registers::ESR_EL2.get() as usize +} + +#[inline(always)] +pub fn exception_esr_el1() -> usize { + cortex_a::registers::ESR_EL1.get() as usize +} + +#[inline(always)] +fn exception_class() -> usize { + (exception_esr() >> 26) & 0b111111 +} + +#[inline(always)] +fn exception_far() -> usize { + cortex_a::registers::FAR_EL2.get() as usize +} + +#[inline(always)] +fn exception_hpfar() -> usize { + let hpfar: u64; + mrs!(hpfar, HPFAR_EL2); + hpfar as usize +} + +#[allow(non_upper_case_globals)] +const ESR_ELx_S1PTW_SHIFT: usize = 7; +#[allow(non_upper_case_globals)] +const ESR_ELx_S1PTW: usize = 1 << ESR_ELx_S1PTW_SHIFT; + +macro_rules! arm_at { + ($at_op:expr, $addr:expr) => { + unsafe { + core::arch::asm!(concat!("AT ", $at_op, ", {0}"), in(reg) $addr, options(nomem, nostack)); + core::arch::asm!("isb"); + } + }; +} + +fn translate_far_to_hpfar(far: usize) -> Result { + /* + * We have + * PAR[PA_Shift - 1 : 12] = PA[PA_Shift - 1 : 12] + * HPFAR[PA_Shift - 9 : 4] = FIPA[PA_Shift - 1 : 12] + */ + // #define PAR_TO_HPFAR(par) (((par) & GENMASK_ULL(PHYS_MASK_SHIFT - 1, 12)) >> 8) + fn par_to_far(par: u64) -> u64 { + let mask = ((1 << (52 - 12)) - 1) << 12; + (par & mask) >> 8 + } + + use cortex_a::registers::PAR_EL1; + + let par = PAR_EL1.get(); + arm_at!("s1e1r", far); + let tmp = PAR_EL1.get(); + PAR_EL1.set(par); + if (tmp & PAR_EL1::F::TranslationAborted.value) != 0 { + Err(()) + } else { + Ok(par_to_far(tmp) as usize) + } +} + +// addr be ipa +#[inline(always)] +pub fn exception_fault_addr() -> usize { + let far = exception_far(); + let hpfar = if (exception_esr() & ESR_ELx_S1PTW) == 0 && exception_data_abort_is_permission_fault() { + translate_far_to_hpfar(far).unwrap_or_else(|_| { + println!("error happen in translate_far_to_hpfar"); + 0 + }) + } else { + exception_hpfar() + }; + (far & 0xfff) | (hpfar << 8) +} + +/// \return 1 means 32-bit instruction, 0 means 16-bit instruction +#[inline(always)] +fn exception_instruction_length() -> usize { + (exception_esr() >> 25) & 1 +} + +#[inline(always)] +pub fn exception_next_instruction_step() -> usize { + 2 + 2 * exception_instruction_length() +} + +#[inline(always)] +pub fn exception_iss() -> usize { + exception_esr() & ((1 << 25) - 1) +} + +#[inline(always)] +pub fn exception_data_abort_handleable() -> bool { + (!(exception_iss() & (1 << 10)) | (exception_iss() & (1 << 24))) != 0 +} + +#[inline(always)] +pub fn exception_data_abort_is_translate_fault() -> bool { + (exception_iss() & 0b111111 & (0xf << 2)) == 4 +} + +#[inline(always)] +pub fn exception_data_abort_is_permission_fault() -> bool { + (exception_iss() & 0b111111 & (0xf << 2)) == 12 +} + +#[inline(always)] +pub fn exception_data_abort_access_width() -> usize { + 1 << ((exception_iss() >> 22) & 0b11) +} + +#[inline(always)] +pub fn exception_data_abort_access_is_write() -> bool { + (exception_iss() & (1 << 6)) != 0 +} + +#[inline(always)] +pub fn exception_data_abort_access_in_stage2() -> bool { + (exception_iss() & (1 << 7)) != 0 +} + +#[inline(always)] +pub fn exception_data_abort_access_reg() -> usize { + (exception_iss() >> 16) & 0b11111 +} + +#[inline(always)] +pub fn exception_data_abort_access_reg_width() -> usize { + 4 + 4 * ((exception_iss() >> 15) & 1) +} + +#[inline(always)] +pub fn exception_data_abort_access_is_sign_ext() -> bool { + ((exception_iss() >> 21) & 1) != 0 +} + +#[no_mangle] +extern "C" fn current_el_sp0_synchronous() { + panic!("current_el_sp0_synchronous"); +} + +#[no_mangle] +extern "C" fn current_el_sp0_irq() { + // lower_aarch64_irq(ctx); + panic!("current_el_sp0_irq"); +} + +#[no_mangle] +extern "C" fn current_el_sp0_serror() { + panic!("current_el0_serror"); +} + +#[no_mangle] +#[inline(never)] +extern "C" fn current_el_spx_synchronous() { + panic!( + "current_elx_synchronous core[{}] elr_el2 {:016x} sp_el0 {:016x}\n sp_el1 {:016x} sp_sel {:016x}\n", + current_cpu().id, + cortex_a::registers::ELR_EL2.get(), + cortex_a::registers::SP_EL0.get(), + cortex_a::registers::SP_EL1.get(), + cortex_a::registers::SPSel.get(), + ); +} + +#[no_mangle] +extern "C" fn current_el_spx_irq(ctx: *mut ContextFrame) { + // println!("current_el_spx_irq"); + lower_aarch64_irq(ctx); +} + +#[no_mangle] +extern "C" fn current_el_spx_serror() { + panic!("current_elx_serror"); +} + +#[no_mangle] +extern "C" fn lower_aarch64_synchronous(ctx: *mut ContextFrame) { + // println!("lower_aarch64_synchronous"); + let status = fresh_status(); + if status != FreshStatus::None { + if status != FreshStatus::Finish { + println!("lower_aarch64_synchronous: illegal fresh status {:#?}", status); + let time0 = time_current_us(); + FRESH_LOGIC_LOCK.lock(); + let time1 = time_current_us(); + println!("lower_aarch64_synchronous: wait live update {} us", time1 - time0); + } + } + current_cpu().set_ctx(ctx); + match exception_class() { + 0x24 => { + // println!("Core[{}] data_abort_handler", cpu_id()); + data_abort_handler(); + } + 0x17 => { + smc_handler(); + } + 0x16 => { + hvc_handler(); + } + _ => unsafe { + println!( + "x0 {:x}, x1 {:x}, x29 {:x}", + (*ctx).gpr(0), + (*ctx).gpr(1), + (*ctx).gpr(29) + ); + panic!( + "core {} vm {}: handler not presents for EC_{} @ipa 0x{:x}, @pc 0x{:x}", + current_cpu().id, + active_vm_id(), + exception_class(), + exception_fault_addr(), + (*ctx).exception_pc() + ); + }, + } + current_cpu().clear_ctx(); +} + +#[no_mangle] +extern "C" fn lower_aarch64_irq(ctx: *mut ContextFrame) { + current_cpu().set_ctx(ctx); + let (id, src) = gicc_get_current_irq(); + // if current_cpu().id == 2 { + // println!( + // "Core[{}] lower_aarch64_irq {} 0x{:x} x30 {:x} x19 {:x} x0 {:x}", + // current_cpu().id, + // id, + // current_cpu().get_elr(), + // current_cpu().get_gpr(30), + // current_cpu().get_gpr(19), + // current_cpu().get_gpr(0) + // ); + // } + match fresh_status() { + FreshStatus::FreshVM | FreshStatus::Start => { + // if active_vm().unwrap().has_interrupt(id) { + // println!("lower_aarch64_irq: wait for fresh vm and vcpu"); + // let time0 = time_current_us(); + FRESH_IRQ_LOGIC_LOCK.lock(); + // let time1 = time_current_us(); + // println!("lower_aarch64_irq: wait {} us", time1 - time0); + // } else { + // FRESH_LOGIC_LOCK.lock(); + // } + } + // FreshStatus::FreshVCPU => { + // if !active_vm().unwrap().has_interrupt(id) { + // FRESH_LOGIC_LOCK.lock(); + // } + // } + _ => {} + } + + if id >= 1022 { + return; + } + // use crate::lib::time_current_us; + // let begin = time_current_us(); + let handled_by_hypervisor = interrupt_handler(id, src); + // let end = time_current_us(); + + gicc_clear_current_irq(handled_by_hypervisor); + current_cpu().clear_ctx(); + // if current_cpu().active_vcpu.is_some() + // && current_cpu().active_vcpu.as_ref().unwrap().vm().is_some() + // && active_vm_id() == 2 + // && current_cpu().id == 2 + // { + // println!("Core{} VM2 end lower_aarch64_irq irq {}", current_cpu().id, id); + // } +} + +#[no_mangle] +extern "C" fn lower_aarch64_serror() { + panic!("lower aarch64 serror"); +} diff --git a/src/arch/aarch64/fpsimd.S b/src/arch/aarch64/fpsimd.S new file mode 100644 index 0000000000000000000000000000000000000000..c7fc48ea0c1255164c384cdfb9aef8fef5714d2c --- /dev/null +++ b/src/arch/aarch64/fpsimd.S @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * FP/SIMD state saving and restoring macros + * + * Copyright (C) 2012 ARM Ltd. + * Author: Catalin Marinas + */ + +.macro fpsimd_save state, tmpnr + stp q0, q1, [\state, #16 * 0] + stp q2, q3, [\state, #16 * 2] + stp q4, q5, [\state, #16 * 4] + stp q6, q7, [\state, #16 * 6] + stp q8, q9, [\state, #16 * 8] + stp q10, q11, [\state, #16 * 10] + stp q12, q13, [\state, #16 * 12] + stp q14, q15, [\state, #16 * 14] + stp q16, q17, [\state, #16 * 16] + stp q18, q19, [\state, #16 * 18] + stp q20, q21, [\state, #16 * 20] + stp q22, q23, [\state, #16 * 22] + stp q24, q25, [\state, #16 * 24] + stp q26, q27, [\state, #16 * 26] + stp q28, q29, [\state, #16 * 28] + stp q30, q31, [\state, #16 * 30]! + mrs x\tmpnr, fpsr + str w\tmpnr, [\state, #16 * 2] + mrs x\tmpnr, fpcr + str w\tmpnr, [\state, #16 * 2 + 4] +.endm + +.macro fpsimd_restore_fpcr state, tmp + /* + * Writes to fpcr may be self-synchronising, so avoid restoring + * the register if it hasn't changed. + */ + mrs \tmp, fpcr + cmp \tmp, \state + b.eq 9999f + msr fpcr, \state +9999: +.endm + +/* Clobbers \state */ +.macro fpsimd_restore state, tmpnr + ldp q0, q1, [\state, #16 * 0] + ldp q2, q3, [\state, #16 * 2] + ldp q4, q5, [\state, #16 * 4] + ldp q6, q7, [\state, #16 * 6] + ldp q8, q9, [\state, #16 * 8] + ldp q10, q11, [\state, #16 * 10] + ldp q12, q13, [\state, #16 * 12] + ldp q14, q15, [\state, #16 * 14] + ldp q16, q17, [\state, #16 * 16] + ldp q18, q19, [\state, #16 * 18] + ldp q20, q21, [\state, #16 * 20] + ldp q22, q23, [\state, #16 * 22] + ldp q24, q25, [\state, #16 * 24] + ldp q26, q27, [\state, #16 * 26] + ldp q28, q29, [\state, #16 * 28] + ldp q30, q31, [\state, #16 * 30]! + ldr w\tmpnr, [\state, #16 * 2] + msr fpsr, x\tmpnr + ldr w\tmpnr, [\state, #16 * 2 + 4] + fpsimd_restore_fpcr x\tmpnr, \state +.endm + +// void fpsimd_save_ctx(u64 *ctx) +.global fpsimd_save_ctx +fpsimd_save_ctx: + fpsimd_save x0 9 + ret + +// void fpsimd_restore_ctx(u64 *ctx) +.global fpsimd_restore_ctx +fpsimd_restore_ctx: + fpsimd_restore x0 9 + ret diff --git a/src/arch/aarch64/gic.rs b/src/arch/aarch64/gic.rs new file mode 100644 index 0000000000000000000000000000000000000000..150a0ef9cc56c4cccb55f4bb36e10bc1a05b5b19 --- /dev/null +++ b/src/arch/aarch64/gic.rs @@ -0,0 +1,701 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::collections::BTreeSet; + +use spin::Mutex; +use tock_registers::*; +use tock_registers::interfaces::*; +use tock_registers::registers::*; + +use crate::board::{PLATFORM_GICC_BASE, PLATFORM_GICD_BASE, PLATFORM_GICH_BASE}; +use crate::kernel::current_cpu; +use crate::kernel::INTERRUPT_NUM_MAX; +use crate::lib::{bit_extract, trace}; + +// GICD BITS +const GICD_CTLR_EN_BIT: usize = 0x1; + +// GICC BITS +pub const GICC_CTLR_EN_BIT: usize = 0x1; +pub const GICC_CTLR_EOIMODENS_BIT: usize = 1 << 9; + +// GICH BITS +const GICH_HCR_LRENPIE_BIT: usize = 1 << 2; + +pub const GIC_SGIS_NUM: usize = 16; +const GIC_PPIS_NUM: usize = 16; +pub const GIC_INTS_MAX: usize = INTERRUPT_NUM_MAX; +pub const GIC_PRIVINT_NUM: usize = GIC_SGIS_NUM + GIC_PPIS_NUM; +pub const GIC_SPI_MAX: usize = INTERRUPT_NUM_MAX - GIC_PRIVINT_NUM; +pub const GIC_PRIO_BITS: usize = 8; +pub const GIC_TARGET_BITS: usize = 8; +pub const GIC_TARGETS_MAX: usize = GIC_TARGET_BITS; +pub const GIC_CONFIG_BITS: usize = 2; + +const GIC_INT_REGS_NUM: usize = GIC_INTS_MAX / 32; +const GIC_PRIO_REGS_NUM: usize = GIC_INTS_MAX * 8 / 32; +const GIC_TARGET_REGS_NUM: usize = GIC_INTS_MAX * 8 / 32; +const GIC_CONFIG_REGS_NUM: usize = GIC_INTS_MAX * 2 / 32; +const GIC_SEC_REGS_NUM: usize = GIC_INTS_MAX * 2 / 32; +pub const GIC_SGI_REGS_NUM: usize = GIC_SGIS_NUM * 8 / 32; + +pub const GIC_LIST_REGS_NUM: usize = 64; + +pub const GICD_TYPER_CPUNUM_OFF: usize = 5; +// pub const GICD_TYPER_CPUNUM_LEN: usize = 3; +pub const GICD_TYPER_CPUNUM_MSK: usize = 0b11111; + +pub static GIC_LRS_NUM: Mutex = Mutex::new(0); + +static GICD_LOCK: Mutex<()> = Mutex::new(()); + +pub static INTERRUPT_EN_SET: Mutex> = Mutex::new(BTreeSet::new()); + +pub fn add_en_interrupt(id: usize) { + if id < GIC_PRIVINT_NUM { + return; + } + let mut set = INTERRUPT_EN_SET.lock(); + set.insert(id); +} + +pub fn show_en_interrupt() { + let set = INTERRUPT_EN_SET.lock(); + print!("en irq set: "); + for irq in set.iter() { + print!("{} ", irq); + } + print!("\n"); +} + +#[derive(Copy, Clone, Debug)] +pub enum IrqState { + IrqSInactive, + IrqSPend, + IrqSActive, + IrqSPendActive, +} + +impl IrqState { + pub fn num_to_state(num: usize) -> IrqState { + match num { + 0 => IrqState::IrqSInactive, + 1 => IrqState::IrqSPend, + 2 => IrqState::IrqSActive, + 3 => IrqState::IrqSPendActive, + _ => panic!("num_to_state: illegal irq state"), + } + } + + pub fn to_num(&self) -> usize { + match self { + IrqState::IrqSInactive => 0, + IrqState::IrqSPend => 1, + IrqState::IrqSActive => 2, + IrqState::IrqSPendActive => 3, + } + } +} + +pub struct GicDesc { + pub gicd_addr: usize, + pub gicc_addr: usize, + pub gich_addr: usize, + pub gicv_addr: usize, + pub maintenance_int_id: usize, +} + +register_structs! { + #[allow(non_snake_case)] + pub GicDistributorBlock { + (0x0000 => CTLR: ReadWrite), + (0x0004 => TYPER: ReadOnly), + (0x0008 => IIDR: ReadOnly), + (0x000c => reserve0), + (0x0080 => IGROUPR: [ReadWrite; GIC_INT_REGS_NUM]), + (0x0100 => ISENABLER: [ReadWrite; GIC_INT_REGS_NUM]), + (0x0180 => ICENABLER: [ReadWrite; GIC_INT_REGS_NUM]), + (0x0200 => ISPENDR: [ReadWrite; GIC_INT_REGS_NUM]), + (0x0280 => ICPENDR: [ReadWrite; GIC_INT_REGS_NUM]), + (0x0300 => ISACTIVER: [ReadWrite; GIC_INT_REGS_NUM]), + (0x0380 => ICACTIVER: [ReadWrite; GIC_INT_REGS_NUM]), + (0x0400 => IPRIORITYR: [ReadWrite; GIC_PRIO_REGS_NUM]), + (0x0800 => ITARGETSR: [ReadWrite; GIC_TARGET_REGS_NUM]), + (0x0c00 => ICFGR: [ReadWrite; GIC_CONFIG_REGS_NUM]), + (0x0d00 => reserve1), + (0x0e00 => NSACR: [ReadWrite; GIC_SEC_REGS_NUM]), + (0x0f00 => SGIR: WriteOnly), + (0x0f04 => reserve2), + (0x0f10 => CPENDSGIR: [ReadWrite; GIC_SGI_REGS_NUM]), + (0x0f20 => SPENDSGIR: [ReadWrite; GIC_SGI_REGS_NUM]), + (0x0f30 => _reserved_3), + (0x1000 => @END), + } +} + +pub struct GicDistributor { + base_addr: usize, +} + +impl core::ops::Deref for GicDistributor { + type Target = GicDistributorBlock; + fn deref(&self) -> &Self::Target { + if self.base_addr < 0x1000 { + panic!("illegal gicd addr {}", self.base_addr); + } + unsafe { &*self.ptr() } + } +} + +impl GicDistributor { + const fn new(base_addr: usize) -> GicDistributor { + GicDistributor { base_addr } + } + + pub fn ptr(&self) -> *const GicDistributorBlock { + self.base_addr as *const GicDistributorBlock + } + + pub fn is_enabler(&self, idx: usize) -> u32 { + self.ISENABLER[idx].get() + } + + pub fn is_activer(&self, idx: usize) -> u32 { + self.ISACTIVER[idx].get() + } + + pub fn is_pender(&self, idx: usize) -> u32 { + self.ISPENDR[idx].get() + } + + pub fn cpendsgir(&self, idx: usize) -> u32 { + self.CPENDSGIR[idx].get() + } + + pub fn igroup(&self, idx: usize) -> u32 { + self.IGROUPR[idx].get() + } + + pub fn ipriorityr(&self, idx: usize) -> u32 { + self.IPRIORITYR[idx].get() + } + + pub fn itargetsr(&self, idx: usize) -> u32 { + self.ITARGETSR[idx].get() + } + + pub fn ctlr(&self) -> u32 { + self.CTLR.get() + } + + pub fn icfgr(&self, idx: usize) -> u32 { + self.ICFGR[idx].get() + } + + pub fn ic_enabler(&self, idx: usize) -> u32 { + self.ICENABLER[idx].get() + } + + fn global_init(&self) { + let int_num = gic_max_spi(); + + for i in GIC_PRIVINT_NUM / 32..int_num / 32 { + self.ICENABLER[i].set(u32::MAX); + self.ICPENDR[i].set(u32::MAX); + self.ICACTIVER[i].set(u32::MAX); + } + + for i in GIC_PRIVINT_NUM / 4..int_num * 8 / 32 { + self.IPRIORITYR[i].set(u32::MAX); + self.ITARGETSR[i].set(0); + } + + let prev = self.CTLR.get(); + self.CTLR.set(prev | GICD_CTLR_EN_BIT as u32); + } + + fn cpu_init(&self) { + for i in 0..GIC_PRIVINT_NUM / 32 { + /* + * Make sure all private interrupts are not enabled, non pending, + * non active. + */ + self.ICENABLER[i].set(u32::MAX); + self.ICPENDR[i].set(u32::MAX); + self.ICACTIVER[i].set(u32::MAX); + } + + /* Clear any pending SGIs. */ + for i in 0..(GIC_SGIS_NUM * 8) / 32 { + self.CPENDSGIR[i].set(u32::MAX); + } + + /* All interrupts have lowest priority possible by default */ + for i in 0..(GIC_PRIVINT_NUM * 8) / 32 { + self.IPRIORITYR[i].set(u32::MAX); + } + } + + pub fn send_sgi(&self, cpu_if: usize, sgi_num: usize) { + // println!("Core {} send ipi to cpu {}", cpu_id(), cpu_if); + self.SGIR.set(((1 << (16 + cpu_if)) | (sgi_num & 0b1111)) as u32); + } + + pub fn prio(&self, int_id: usize) -> usize { + let idx = (int_id * 8) / 32; + let off = (int_id * 8) % 32; + ((self.IPRIORITYR[idx].get() >> off) & 0xff) as usize + } + + pub fn set_prio(&self, int_id: usize, prio: u8) { + let idx = (int_id * 8) / 32; + let off = (int_id * 8) % 32; + let mask: u32 = 0b11111111 << off; + + let lock = GICD_LOCK.lock(); + let prev = self.IPRIORITYR[idx].get(); + let value = (prev & !mask) | (((prio as u32) << off) & mask); + self.IPRIORITYR[idx].set(value); + drop(lock); + } + + pub fn trgt(&self, int_id: usize) -> usize { + let idx = (int_id * 8) / 32; + let off = (int_id * 8) % 32; + ((self.ITARGETSR[idx].get() >> off) & 0xff) as usize + } + + pub fn set_trgt(&self, int_id: usize, trgt: u8) { + let idx = (int_id * 8) / 32; + let off = (int_id * 8) % 32; + let mask: u32 = 0b11111111 << off; + + let lock = GICD_LOCK.lock(); + let prev = self.ITARGETSR[idx].get(); + let value = (prev & !mask) | (((trgt as u32) << off) & mask); + // println!("idx {}, val {:x}", idx, value); + self.ITARGETSR[idx].set(value); + drop(lock); + } + + pub fn set_enable(&self, int_id: usize, en: bool) { + // println!("gicd::set_enbale: en {}, int_id {}", en, int_id); + let idx = int_id / 32; + let bit = 1 << (int_id % 32); + + let lock = GICD_LOCK.lock(); + if en { + add_en_interrupt(int_id); + self.ISENABLER[idx].set(bit); + } else { + self.ICENABLER[idx].set(bit); + } + drop(lock); + } + + pub fn set_pend(&self, int_id: usize, pend: bool) { + let lock = GICD_LOCK.lock(); + if gic_is_sgi(int_id) { + let reg_ind = int_id / 4; + let off = (int_id % 4) * 8; + if pend { + self.SPENDSGIR[reg_ind].set(1 << (off + current_cpu().id)); + } else { + self.CPENDSGIR[reg_ind].set(0b11111111 << off); + } + } else { + let reg_ind = int_id / 32; + let mask = 1 << int_id % 32; + if pend { + self.ISPENDR[reg_ind].set(mask); + } else { + self.ICPENDR[reg_ind].set(mask); + } + } + + drop(lock); + } + + pub fn set_act(&self, int_id: usize, act: bool) { + let reg_ind = int_id / 32; + let mask = 1 << int_id % 32; + + let lock = GICD_LOCK.lock(); + if act { + self.ISACTIVER[reg_ind].set(mask); + } else { + self.ICACTIVER[reg_ind].set(mask); + } + drop(lock); + } + + pub fn set_state(&self, int_id: usize, state: usize) { + self.set_act(int_id, (state & 2) != 0); + self.set_pend(int_id, (state & 1) != 0); + } + + pub fn set_icfgr(&self, int_id: usize, cfg: u8) { + let lock = GICD_LOCK.lock(); + let reg_ind = (int_id * GIC_CONFIG_BITS) / 32; + let off = (int_id * GIC_CONFIG_BITS) % 32; + let mask = 0b11 << off; + + let icfgr = self.ICFGR[reg_ind].get(); + self.ICFGR[reg_ind].set((icfgr & !mask) | (((cfg as u32) << off) & mask)); + drop(lock); + } + + pub fn typer(&self) -> u32 { + self.TYPER.get() + } + + pub fn iidr(&self) -> u32 { + self.IIDR.get() + } + + pub fn state(&self, int_id: usize) -> usize { + let reg_ind = int_id / 32; + let mask = 1 << int_id % 32; + + let lock = GICD_LOCK.lock(); + let pend = if (self.ISPENDR[reg_ind].get() & mask) != 0 { + 1 + } else { + 0 + }; + let act = if (self.ISACTIVER[reg_ind].get() & mask) != 0 { + 2 + } else { + 0 + }; + drop(lock); + return pend | act; + } +} + +register_structs! { + #[allow(non_snake_case)] + pub GicCpuInterfaceBlock { + (0x0000 => CTLR: ReadWrite), // CPU Interface Control Register + (0x0004 => PMR: ReadWrite), // Interrupt Priority Mask Register + (0x0008 => BPR: ReadWrite), // Binary Point Register + (0x000c => IAR: ReadOnly), // Interrupt Acknowledge Register + (0x0010 => EOIR: WriteOnly), // End of Interrupt Register + (0x0014 => RPR: ReadOnly), // Running Priority Register + (0x0018 => HPPIR: ReadOnly), // Highest Priority Pending Interrupt Register + (0x001c => ABPR: ReadWrite), // Aliased Binary Point Register + (0x0020 => AIAR: ReadOnly), // Aliased Interrupt Acknowledge Register + (0x0024 => AEOIR: WriteOnly), // Aliased End of Interrupt Register + (0x0028 => AHPPIR: ReadOnly), // Aliased Highest Priority Pending Interrupt Register + (0x002c => reserved_0), + (0x00d0 => APR: [ReadWrite; 4]), // Active Priorities Register + (0x00e0 => NSAPR: [ReadWrite; 4]), // Non-secure Active Priorities Register + (0x00f0 => reserved_1), + (0x00fc => IIDR: ReadOnly), // CPU Interface Identification Register + (0x0100 => reserved_2), + (0x1000 => DIR: WriteOnly), // Deactivate Interrupt Register + (0x1004 => reserved_3), + (0x2000 => @END), + } +} + +pub struct GicCpuInterface { + base_addr: usize, +} + +impl core::ops::Deref for GicCpuInterface { + type Target = GicCpuInterfaceBlock; + fn deref(&self) -> &Self::Target { + if self.base_addr < 0x1000 { + panic!("illegal gicc addr {}", self.base_addr); + } + unsafe { &*self.ptr() } + } +} + +impl GicCpuInterface { + pub const fn new(base_addr: usize) -> GicCpuInterface { + GicCpuInterface { base_addr } + } + + pub fn ptr(&self) -> *const GicCpuInterfaceBlock { + self.base_addr as *const GicCpuInterfaceBlock + } + + fn init(&self) { + for i in 0..gich_lrs_num() { + GICH.LR[i].set(0); + } + + self.PMR.set(u32::MAX); + let ctlr_prev = self.CTLR.get(); + // println!( + // "ctlr: {:x}, gich_lrs_num {}", + // ctlr_prev | GICC_CTLR_EN_BIT as u32 | GICC_CTLR_EOImodeNS_BIT as u32, + // gich_lrs_num() + // ); + self.CTLR + .set(ctlr_prev | GICC_CTLR_EN_BIT as u32 | GICC_CTLR_EOIMODENS_BIT as u32); + + let hcr_prev = GICH.HCR.get(); + GICH.HCR.set(hcr_prev | GICH_HCR_LRENPIE_BIT as u32); + } + + pub fn set_dir(&self, dir: u32) { + self.DIR.set(dir); + } + + pub fn hppir(&self) -> u32 { + self.HPPIR.get() + } + + pub fn rpr(&self) -> u32 { + self.RPR.get() + } + + pub fn bpr(&self) -> u32 { + self.BPR.get() + } + + pub fn abpr(&self) -> u32 { + self.ABPR.get() + } + + pub fn apr(&self, idx: usize) -> u32 { + self.APR[idx].get() + } + + pub fn nsapr(&self, idx: usize) -> u32 { + self.NSAPR[idx].get() + } +} + +register_structs! { + #[allow(non_snake_case)] + pub GicHypervisorInterfaceBlock { + (0x0000 => HCR: ReadWrite), + (0x0004 => VTR: ReadOnly), + (0x0008 => VMCR: ReadWrite), + (0x000c => reserve0), + (0x0010 => MISR: ReadOnly), + (0x0014 => reserve1), + (0x0020 => EISR: [ReadOnly; GIC_LIST_REGS_NUM / 32]), + (0x0028 => reserve2), + (0x0030 => ELRSR: [ReadOnly; GIC_LIST_REGS_NUM / 32]), + (0x0038 => reserve3), + (0x00f0 => APR: ReadWrite), + (0x00f4 => reserve4), + (0x0100 => LR: [ReadWrite; GIC_LIST_REGS_NUM]), + (0x0200 => reserve5), + (0x1000 => @END), + } +} + +pub struct GicHypervisorInterface { + base_addr: usize, +} + +impl core::ops::Deref for GicHypervisorInterface { + type Target = GicHypervisorInterfaceBlock; + fn deref(&self) -> &Self::Target { + if trace() && self.base_addr < 0x1000 { + panic!(""); + } + unsafe { &*self.ptr() } + } +} + +impl GicHypervisorInterface { + const fn new(base_addr: usize) -> GicHypervisorInterface { + GicHypervisorInterface { base_addr } + } + + pub fn ptr(&self) -> *const GicHypervisorInterfaceBlock { + self.base_addr as *const GicHypervisorInterfaceBlock + } + + pub fn hcr(&self) -> u32 { + self.HCR.get() + } + + pub fn set_hcr(&self, hcr: u32) { + self.HCR.set(hcr); + } + + pub fn elrsr(&self, elsr_idx: usize) -> u32 { + self.ELRSR[elsr_idx].get() + } + + pub fn eisr(&self, eisr_idx: usize) -> u32 { + self.EISR[eisr_idx].get() + } + + pub fn lr(&self, lr_idx: usize) -> u32 { + self.LR[lr_idx].get() + } + + pub fn misr(&self) -> u32 { + self.MISR.get() + } + + pub fn apr(&self) -> u32 { + self.APR.get() + } + + pub fn set_lr(&self, lr_idx: usize, val: u32) { + self.LR[lr_idx].set(val) + } +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GicState { + pub hcr: u32, + eisr: [u32; GIC_LIST_REGS_NUM / 32], + elrsr: [u32; GIC_LIST_REGS_NUM / 32], + apr: u32, + pub lr: [u32; GIC_LIST_REGS_NUM], + pub ctlr: u32, +} + +impl GicState { + pub fn default() -> GicState { + GicState { + hcr: 0, + eisr: [0; GIC_LIST_REGS_NUM / 32], + elrsr: [0; GIC_LIST_REGS_NUM / 32], + apr: 0, + lr: [0; GIC_LIST_REGS_NUM], + ctlr: 0, + } + } + + pub fn save_state(&mut self) { + self.hcr = GICH.hcr(); + self.apr = GICH.APR.get(); + for i in 0..(GIC_LIST_REGS_NUM / 32) { + self.eisr[i] = GICH.eisr(i); + self.elrsr[i] = GICH.elrsr(i); + } + // println!("save state"); + // println!("GICH hcr {:x}", self.hcr); + // println!("GICH apr {:x}", self.apr); + // println!("GICH eisr {:x}", self.eisr[0]); + // println!("GICH elrsr {:x}", self.elrsr[0]); + for i in 0..gich_lrs_num() { + if self.elrsr[0] & 1 << i == 0 { + self.lr[i] = GICH.lr(i); + } else { + self.lr[i] = 0; + } + // println!("GICH_LR[{}] {:x}", i, GICH.lr(i)); + } + self.ctlr = GICC.CTLR.get(); + } + + pub fn restore_state(&self) { + // println!("before restore"); + // println!("GICH hcr {:x}", GICH.hcr()); + // println!("GICC ctlr {:x}", GICC.CTLR.get()); + // for i in 0..gich_lrs_num() { + // println!("lr[{}] {:x}", i, GICH.lr(i)); + // } + + // println!("after restore state"); + GICH.set_hcr(self.hcr); + GICH.APR.set(self.apr); + // println!("GICH hcr {:x}", self.hcr); + // println!("GICH apr {:x}", self.apr); + + for i in 0..gich_lrs_num() { + // println!("lr[{}] {:x}", i, self.lr[i]); + GICH.set_lr(i, self.lr[i]); + } + GICC.CTLR.set(self.ctlr); + // println!("GICC ctlr {:x}", self.ctlr); + } +} + +pub static GICD: GicDistributor = GicDistributor::new(PLATFORM_GICD_BASE + 0x8_0000_0000); +pub static GICC: GicCpuInterface = GicCpuInterface::new(PLATFORM_GICC_BASE + 0x8_0000_0000); +pub static GICH: GicHypervisorInterface = GicHypervisorInterface::new(PLATFORM_GICH_BASE + 0x8_0000_0000); + +#[inline(always)] +pub fn gich_lrs_num() -> usize { + let vtr = GICH.VTR.get(); + ((vtr & 0b11111) + 1) as usize +} + +#[inline(always)] +pub fn gic_max_spi() -> usize { + let typer = GICD.TYPER.get(); + let value = typer & 0b11111; + (32 * (value + 1)) as usize +} + +pub fn gic_glb_init() { + set_gic_lrs(gich_lrs_num()); + GICD.global_init(); +} + +pub fn gic_cpu_init() { + GICD.cpu_init(); + GICC.init(); +} + +pub fn gic_cpu_reset() { + GICC.init(); +} + +pub fn gic_is_priv(int_id: usize) -> bool { + int_id < GIC_PRIVINT_NUM +} + +pub fn gic_is_sgi(int_id: usize) -> bool { + int_id < GIC_SGIS_NUM +} + +pub fn gicc_clear_current_irq(for_hypervisor: bool) { + let irq = current_cpu().current_irq as u32; + if irq == 0 { + return; + } + let gicc = &GICC; + gicc.EOIR.set(irq); + if for_hypervisor { + // let addr = 0x08010000 + 0x1000; + // unsafe { + // let gicc_dir = addr as *mut u32; + // *gicc_dir = irq; + // } + gicc.DIR.set(irq); + } + let irq = 0; + current_cpu().current_irq = irq; +} + +pub fn gicc_get_current_irq() -> (usize, usize) { + let iar = GICC.IAR.get(); + let irq = iar as usize; + current_cpu().current_irq = irq; + let id = bit_extract(iar as usize, 0, 10); + let src = bit_extract(iar as usize, 10, 3); + (id, src) +} + +pub fn gic_lrs() -> usize { + *GIC_LRS_NUM.lock() +} + +pub fn set_gic_lrs(lrs: usize) { + let mut gic_lrs = GIC_LRS_NUM.lock(); + *gic_lrs = lrs; +} diff --git a/src/arch/aarch64/interface.rs b/src/arch/aarch64/interface.rs new file mode 100644 index 0000000000000000000000000000000000000000..c2fbd074fe62905a970185e6641021b55cc47245 --- /dev/null +++ b/src/arch/aarch64/interface.rs @@ -0,0 +1,18 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub const PAGE_SIZE: usize = 4096; +pub const PAGE_SHIFT: usize = 12; +pub const ENTRY_PER_PAGE: usize = PAGE_SIZE / 8; + +pub type ContextFrame = super::context_frame::Aarch64ContextFrame; + +pub const WORD_SIZE: usize = 8; +pub const PTE_PER_PAGE: usize = PAGE_SIZE / WORD_SIZE; diff --git a/src/arch/aarch64/interrupt.rs b/src/arch/aarch64/interrupt.rs new file mode 100644 index 0000000000000000000000000000000000000000..596aefdb4c69f823b29838a5c57404c600213c77 --- /dev/null +++ b/src/arch/aarch64/interrupt.rs @@ -0,0 +1,80 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::{gic_cpu_reset, gicc_clear_current_irq}; +use crate::board::platform_cpuid_to_cpuif; +use crate::kernel::{current_cpu, Vcpu, Vm}; + +use super::GIC_SGIS_NUM; +use super::GICD; + +pub const INTERRUPT_IRQ_HYPERVISOR_TIMER: usize = 26; +pub const INTERRUPT_IRQ_IPI: usize = 1; + +pub fn interrupt_arch_init() { + use crate::arch::{gic_cpu_init, gic_glb_init, gic_maintenance_handler}; + use crate::kernel::{interrupt_reserve_int, InterruptHandler}; + + crate::lib::barrier(); + + if current_cpu().id == 0 { + gic_glb_init(); + } + + gic_cpu_init(); + + use crate::board::PLAT_DESC; + + let int_id = PLAT_DESC.arch_desc.gic_desc.maintenance_int_id; + interrupt_reserve_int(int_id, InterruptHandler::GicMaintenanceHandler(gic_maintenance_handler)); + interrupt_arch_enable(int_id, true); +} + +pub fn interrupt_arch_enable(int_id: usize, en: bool) { + let cpu_id = current_cpu().id; + if en { + GICD.set_prio(int_id, 0x7f); + GICD.set_trgt(int_id, 1 << platform_cpuid_to_cpuif(cpu_id)); + + GICD.set_enable(int_id, en); + } else { + GICD.set_enable(int_id, en); + } +} + +pub fn interrupt_arch_ipi_send(cpu_id: usize, ipi_id: usize) { + if ipi_id < GIC_SGIS_NUM { + GICD.send_sgi(platform_cpuid_to_cpuif(cpu_id), ipi_id); + } +} + +pub fn interrupt_arch_vm_register(vm: Vm, id: usize) { + super::vgic_set_hw_int(vm.clone(), id); +} + +pub fn interrupt_arch_vm_inject(vm: Vm, vcpu: Vcpu, int_id: usize) { + let vgic = vm.vgic(); + // println!("int {}, cur vcpu vm {}, trgt vcpu vm {}", int_id, active_vm_id(), vcpu.vm_id()); + // restore_vcpu_gic(current_cpu().active_vcpu.clone(), vcpu.clone()); + if let Some(cur_vcpu) = current_cpu().active_vcpu.clone() { + if cur_vcpu.vm_id() == vcpu.vm_id() { + vgic.inject(vcpu.clone(), int_id); + return; + } + } + + vcpu.push_int(int_id); + // save_vcpu_gic(current_cpu().active_vcpu.clone(), vcpu.clone()); +} + +pub fn interrupt_arch_clear() { + gic_cpu_reset(); + gicc_clear_current_irq(true); +} diff --git a/src/arch/aarch64/memcpy.S b/src/arch/aarch64/memcpy.S new file mode 100644 index 0000000000000000000000000000000000000000..9fea4ae6cfcd27351a336467f7be10df838bd270 --- /dev/null +++ b/src/arch/aarch64/memcpy.S @@ -0,0 +1,160 @@ +/* + * memcpy - copy memory area + * + * Copyright (c) 2012-2020, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +/* Assumptions: + * + * ARMv8-a, AArch64, unaligned accesses. + * + */ + +/* This implementation of memcpy uses unaligned accesses and branchless + sequences to keep the code small, simple and improve performance. + + Copies are split into 3 main cases: small copies of up to 32 bytes, medium + copies of up to 128 bytes, and large copies. The overhead of the overlap + check is negligible since it is only required for large copies. + + Large copies use a software pipelined loop processing 64 bytes per iteration. + The destination pointer is 16-byte aligned to minimize unaligned accesses. + The loop tail is handled by always copying 64 bytes from the end. +*/ + +.text +.global memcpy +// .type memcpy,%function +memcpy: + add x4, x1, x2 + add x5, x0, x2 + cmp x2, 128 + b.hi .Lcopy_long + cmp x2, 32 + b.hi .Lcopy32_128 + + /* Small copies: 0..32 bytes. */ + cmp x2, 16 + b.lo .Lcopy16 + ldp x6, x7, [x1] + ldp x12, x13, [x4, -16] + stp x6, x7, [x0] + stp x12, x13, [x5, -16] + ret + + /* Copy 8-15 bytes. */ +.Lcopy16: + tbz x2, 3, .Lcopy8 + ldr x6, [x1] + ldr x7, [x4, -8] + str x6, [x0] + str x7, [x5, -8] + ret + + .p2align 3 + /* Copy 4-7 bytes. */ +.Lcopy8: + tbz x2, 2, .Lcopy4 + ldr w6, [x1] + ldr w8, [x4, -4] + str w6, [x0] + str w8, [x5, -4] + ret + + /* Copy 0..3 bytes using a branchless sequence. */ +.Lcopy4: + cbz x2, .Lcopy0 + lsr x14, x2, 1 + ldrb w6, [x1] + ldrb w10, [x4, -1] + ldrb w8, [x1, x14] + strb w6, [x0] + strb w8, [x0, x14] + strb w10, [x5, -1] +.Lcopy0: + ret + + .p2align 4 + /* Medium copies: 33..128 bytes. */ +.Lcopy32_128: + ldp x6, x7, [x1] + ldp x8, x9, [x1, 16] + ldp x10, x11, [x4, -32] + ldp x12, x13, [x4, -16] + cmp x2, 64 + b.hi .Lcopy128 + stp x6, x7, [x0] + stp x8, x9, [x0, 16] + stp x10, x11, [x5, -32] + stp x12, x13, [x5, -16] + ret + + .p2align 4 + /* Copy 65..128 bytes. */ +.Lcopy128: + ldp x14, x15, [x1, 32] + ldp x16, x17, [x1, 48] + cmp x2, 96 + b.ls .Lcopy96 + ldp x2, x3, [x4, -64] + ldp x1, x4, [x4, -48] + stp x2, x3, [x5, -64] + stp x1, x4, [x5, -48] +.Lcopy96: + stp x6, x7, [x0] + stp x8, x9, [x0, 16] + stp x14, x15, [x0, 32] + stp x16, x17, [x0, 48] + stp x10, x11, [x5, -32] + stp x12, x13, [x5, -16] + ret + + .p2align 4 + /* Copy more than 128 bytes. */ +.Lcopy_long: + + /* Copy 16 bytes and then align x3 to 16-byte alignment. */ + + ldp x12, x13, [x1] + and x14, x0, 15 + bic x3, x0, 15 + sub x1, x1, x14 + add x2, x2, x14 /* x2 is now 16 too large. */ + ldp x6, x7, [x1, 16] + stp x12, x13, [x0] + ldp x8, x9, [x1, 32] + ldp x10, x11, [x1, 48] + ldp x12, x13, [x1, 64]! + subs x2, x2, 128 + 16 /* Test and readjust x2. */ + b.ls .Lcopy64_from_end + +.Lloop64: + stp x6, x7, [x3, 16] + ldp x6, x7, [x1, 16] + stp x8, x9, [x3, 32] + ldp x8, x9, [x1, 32] + stp x10, x11, [x3, 48] + ldp x10, x11, [x1, 48] + stp x12, x13, [x3, 64]! + ldp x12, x13, [x1, 64]! + subs x2, x2, 64 + b.hi .Lloop64 + + /* Write the last iteration and copy 64 bytes from the end. */ +.Lcopy64_from_end: + ldp x14, x15, [x4, -64] + stp x6, x7, [x3, 16] + ldp x6, x7, [x4, -48] + stp x8, x9, [x3, 32] + ldp x8, x9, [x4, -32] + stp x10, x11, [x3, 48] + ldp x10, x11, [x4, -16] + stp x12, x13, [x3, 64] + stp x14, x15, [x5, -64] + stp x6, x7, [x5, -48] + stp x8, x9, [x5, -32] + stp x10, x11, [x5, -16] + ret + +.size memcpy,.-memcpy diff --git a/src/arch/aarch64/memset.S b/src/arch/aarch64/memset.S new file mode 100644 index 0000000000000000000000000000000000000000..0bf58ce1110fe0fe5110fea030359513738f0c82 --- /dev/null +++ b/src/arch/aarch64/memset.S @@ -0,0 +1,212 @@ +/* Copyright (c) 2012-2013, Linaro Limited + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the Linaro nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS 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. */ +/* Assumptions: + * + * ARMv8-a, AArch64 + * Unaligned accesses + * + */ + + +/* By default we assume that the DC instruction can be used to zero + data blocks more efficiently. In some circumstances this might be + unsafe, for example in an asymmetric multiprocessor environment with + different DC clear lengths (neither the upper nor lower lengths are + safe to use). The feature can be disabled by defining DONT_USE_DC. + If code may be run in a virtualized environment, then define + MAYBE_VIRT. This will cause the code to cache the system register + values rather than re-reading them each call. */ + + .macro def_fn f p2align=0 + .text + .p2align \p2align + .global \f + .type \f, %function +\f: + .endm +def_fn memset p2align=6 + mov x8, x0 /* Preserve return value. */ + ands w7, w1, #255 + + orr w7, w7, w7, lsl #8 + orr w7, w7, w7, lsl #16 + orr x7, x7, x7, lsl #32 +.Ltail_maybe_long: + cmp x2, #64 + b.ge .Lnot_short +.Ltail_maybe_tiny: + cmp x2, #15 + b.le .Ltail15tiny +.Ltail63: + ands x3, x2, #0x30 + b.eq .Ltail15 + add x8, x8, x3 + cmp w3, #0x20 + b.eq 1f + b.lt 2f + stp x7, x7, [x8, #-48] +1: + stp x7, x7, [x8, #-32] +2: + stp x7, x7, [x8, #-16] +.Ltail15: + and x2, x2, #15 + add x8, x8, x2 + stp x7, x7, [x8, #-16] /* Repeat some/all of last store. */ + ret +.Ltail15tiny: + /* Set up to 15 bytes. Does not assume earlier memory + being set. */ + tbz x2, #3, 1f + str x7, [x8], #8 +1: + tbz x2, #2, 1f + str w7, [x8], #4 +1: + tbz x2, #1, 1f + strh w7, [x8], #2 +1: + tbz x2, #0, 1f + strb w7, [x8] +1: + ret + /* Critical loop. Start at a new cache line boundary. Assuming + * 64 bytes per line, this ensures the entire loop is in one line. */ + .p2align 6 +.Lnot_short: + neg x4, x8 + ands x4, x4, #15 + b.eq 2f + /* Bring x8 to 128-bit (16-byte) alignment. We know that there's + * more than that to set, so we simply store 16 bytes and advance by + * the amount required to reach alignment. */ + sub x2, x2, x4 + stp x7, x7, [x8] + add x8, x8, x4 + /* There may be less than 63 bytes to go now. */ + cmp x2, #63 + b.le .Ltail63 +2: + sub x8, x8, #16 /* Pre-bias. */ + sub x2, x2, #64 +1: + stp x7, x7, [x8, #16] + stp x7, x7, [x8, #32] + stp x7, x7, [x8, #48] + stp x7, x7, [x8, #64]! + subs x2, x2, #64 + b.ge 1b + tst x2, #0x3f + add x8, x8, #16 + b.ne .Ltail63 + ret +#ifndef DONT_USE_DC + /* For zeroing memory, check to see if we can use the ZVA feature to + * zero entire 'cache' lines. */ +.Lzero_mem: + mov x7, #0 + cmp x2, #63 + b.le .Ltail_maybe_tiny + neg x4, x8 + ands x4, x4, #15 + b.eq 1f + sub x2, x2, x4 + stp x7, x7, [x8] + add x8, x8, x4 + cmp x2, #63 + b.le .Ltail63 +1: + /* For zeroing small amounts of memory, it's not worth setting up + * the line-clear code. */ + cmp x2, #128 + b.lt .Lnot_short +#ifdef MAYBE_VIRT + /* For efficiency when virtualized, we cache the ZVA capability. */ + adrp x4, .Lcache_clear + ldr w5, [x4, #:lo12:.Lcache_clear] + tbnz w5, #31, .Lnot_short + cbnz w5, .Lzero_by_line + mrs x3, dczid_el0 + tbz x3, #4, 1f + /* ZVA not available. Remember this for next time. */ + mov w5, #~0 + str w5, [x4, #:lo12:.Lcache_clear] + b .Lnot_short +1: + mov w9, #4 + and w5, w3, #15 /* Safety: other bits reserved. */ + lsl w5, w9, w5 + str w5, [x4, #:lo12:.Lcache_clear] +#else + mrs x3, dczid_el0 + tbnz x3, #4, .Lnot_short + mov w9, #4 + and w5, w3, #15 /* Safety: other bits reserved. */ + lsl w5, w9, w5 +#endif +.Lzero_by_line: + /* Compute how far we need to go to become suitably aligned. We're + * already at quad-word alignment. */ + cmp x2, x5 + b.lt .Lnot_short /* Not enough to reach alignment. */ + sub x6, x5, #1 + neg x4, x8 + ands x4, x4, x6 + b.eq 1f /* Already aligned. */ + /* Not aligned, check that there's enough to copy after alignment. */ + sub x3, x2, x4 + cmp x3, #64 + ccmp x3, x5, #8, ge /* NZCV=0b1000 */ + b.lt .Lnot_short + /* We know that there's at least 64 bytes to zero and that it's safe + * to overrun by 64 bytes. */ + mov x2, x3 +2: + stp x7, x7, [x8] + stp x7, x7, [x8, #16] + stp x7, x7, [x8, #32] + subs x4, x4, #64 + stp x7, x7, [x8, #48] + add x8, x8, #64 + b.ge 2b + /* We've overrun a bit, so adjust x8 downwards. */ + add x8, x8, x4 +1: + sub x2, x2, x5 +3: + dc zva, x8 + add x8, x8, x5 + subs x2, x2, x5 + b.ge 3b + ands x2, x2, x6 + b.ne .Ltail_maybe_long + ret + .size memset, .-memset +#ifdef MAYBE_VIRT + .bss + .p2align 2 +.Lcache_clear: + .space 4 +#endif +#endif /* DONT_USE_DC */ \ No newline at end of file diff --git a/src/arch/aarch64/mmu.rs b/src/arch/aarch64/mmu.rs new file mode 100644 index 0000000000000000000000000000000000000000..048c792330d0a5383a34e7bdf247b90dfd238c48 --- /dev/null +++ b/src/arch/aarch64/mmu.rs @@ -0,0 +1,242 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::arch::global_asm; +use tock_registers::*; +use tock_registers::interfaces::*; + +use crate::arch::pt_lvl2_idx; +use crate::board::PLAT_DESC; +use crate::lib::memset_safe; +#[cfg(feature = "pi4")] +use crate::arch::LVL2_SHIFT; + +use super::interface::*; + +#[cfg(feature = "tx2")] +#[cfg(not(feature = "update"))] +global_asm!(include_str!("start.S")); + +#[cfg(feature = "update")] +#[cfg(feature = "tx2")] +global_asm!(include_str!("start_update.S")); + +#[cfg(feature = "pi4")] +#[cfg(not(feature = "update"))] +global_asm!(include_str!("start_pi4.S")); + +#[cfg(feature = "qemu")] +global_asm!(include_str!("start_qemu.S")); + +// const PHYSICAL_ADDRESS_LIMIT_GB: usize = BOARD_PHYSICAL_ADDRESS_LIMIT >> 30; +// const PAGE_SIZE: usize = 4096; +// const PAGE_SHIFT: usize = 12; +// const ENTRY_PER_PAGE: usize = PAGE_SIZE / 8; + +register_bitfields! {u64, + pub TableDescriptor [ + NEXT_LEVEL_TABLE_PPN OFFSET(12) NUMBITS(36) [], // [47:12] + TYPE OFFSET(1) NUMBITS(1) [ + Block = 0, + Table = 1 + ], + VALID OFFSET(0) NUMBITS(1) [ + False = 0, + True = 1 + ] + ] +} + +register_bitfields! {u64, + pub PageDescriptorS1 [ + UXN OFFSET(54) NUMBITS(1) [ + False = 0, + True = 1 + ], + PXN OFFSET(53) NUMBITS(1) [ + False = 0, + True = 1 + ], + OUTPUT_PPN OFFSET(12) NUMBITS(36) [], // [47:12] + AF OFFSET(10) NUMBITS(1) [ + False = 0, + True = 1 + ], + SH OFFSET(8) NUMBITS(2) [ + OuterShareable = 0b10, + InnerShareable = 0b11 + ], + AP OFFSET(6) NUMBITS(2) [ + RW_ELx = 0b00, + RW_ELx_EL0 = 0b01, + RO_ELx = 0b10, + RO_ELx_EL0 = 0b11 + ], + AttrIndx OFFSET(2) NUMBITS(3) [ + Attr0 = 0b000, + Attr1 = 0b001, + Attr2 = 0b010 + ], + TYPE OFFSET(1) NUMBITS(1) [ + Block = 0, + Table = 1 + ], + VALID OFFSET(0) NUMBITS(1) [ + False = 0, + True = 1 + ] + ] +} + +#[derive(Copy, Clone)] +#[repr(transparent)] +struct BlockDescriptor(u64); + +impl BlockDescriptor { + fn new(output_addr: usize, device: bool) -> BlockDescriptor { + BlockDescriptor( + (PageDescriptorS1::OUTPUT_PPN.val((output_addr >> PAGE_SHIFT) as u64) + + PageDescriptorS1::AF::True + + PageDescriptorS1::AP::RW_ELx + + PageDescriptorS1::TYPE::Block + + PageDescriptorS1::VALID::True + + if device { + PageDescriptorS1::AttrIndx::Attr0 + PageDescriptorS1::SH::OuterShareable + } else { + PageDescriptorS1::AttrIndx::Attr1 + PageDescriptorS1::SH::InnerShareable + }) + .value, + ) + } + + fn table(output_addr: usize) -> BlockDescriptor { + BlockDescriptor( + (PageDescriptorS1::OUTPUT_PPN.val((output_addr >> PAGE_SHIFT) as u64) + + PageDescriptorS1::VALID::True + + PageDescriptorS1::TYPE::Table) + .value, + ) + } + const fn invalid() -> BlockDescriptor { + BlockDescriptor(0) + } +} + +#[repr(C)] +#[repr(align(4096))] +pub struct PageTables { + lvl1: [BlockDescriptor; ENTRY_PER_PAGE], +} + +const LVL1_SHIFT: usize = 30; +const PLATFORM_PHYSICAL_LIMIT_GB: usize = 16; + +#[no_mangle] +// #[link_section = ".text.boot"] +pub extern "C" fn pt_populate(lvl1_pt: &mut PageTables, lvl2_pt: &mut PageTables) { + let lvl1_base = lvl1_pt as *const _ as usize; + let lvl2_base = lvl2_pt as *const _ as usize; + memset_safe(lvl1_base as *mut u8, 0, PAGE_SIZE); + memset_safe(lvl2_base as *mut u8, 0, PAGE_SIZE); + + #[cfg(feature = "tx2")] + { + for i in 0..PLATFORM_PHYSICAL_LIMIT_GB { + let output_addr = i << LVL1_SHIFT; + lvl1_pt.lvl1[i] = if output_addr >= PLAT_DESC.mem_desc.base { + BlockDescriptor::new(output_addr, false) + } else { + BlockDescriptor::invalid() + } + } + // for i in PLATFORM_PHYSICAL_LIMIT_GB..ENTRY_PER_PAGE { + // pt.lvl1[i] = BlockDescriptor::invalid(); + // } + + // map the devices to HIGH 32GB, whose offset is 2^35 = 0x8_0000_0000 + lvl1_pt.lvl1[32] = BlockDescriptor::table(lvl2_base); + // 0x200000 ~ 2MB + // UART0 ~ 0x3000000 - 0x3200000 (0x3100000) + // UART1 ~ 0xc200000 - 0xc400000 (0xc280000) + // EMMC ~ 0x3400000 - 0x3600000 (0x3460000) + // GIC ~ 0x3800000 - 0x3a00000 (0x3881000) + // SMMU ~ 0x12000000 - 0x13000000 + lvl2_pt.lvl1[pt_lvl2_idx(0x3000000)] = BlockDescriptor::new(0x3000000, true); + lvl2_pt.lvl1[pt_lvl2_idx(0xc200000)] = BlockDescriptor::new(0xc200000, true); + // lvl2_pt.lvl1[pt_lvl2_idx(0x3400000)] = BlockDescriptor::new(0x3400000, true); + lvl2_pt.lvl1[pt_lvl2_idx(0x3800000)] = BlockDescriptor::new(0x3800000, true); + for i in 0..(0x100_0000 / 0x200000) { + let addr = 0x12000000 + i * 0x200000; + lvl2_pt.lvl1[pt_lvl2_idx(addr)] = BlockDescriptor::new(addr, true); + } + } + #[cfg(feature = "pi4")] + { + use crate::arch::LVL2_SHIFT; + // crate::driver::putc('o' as u8); + // crate::driver::putc('r' as u8); + // crate::driver::putc('e' as u8); + // println!("pt"); + // 0x0_0000_0000 ~ 0x0_c000_0000 --> normal memory (3GB) + lvl1_pt.lvl1[0] = BlockDescriptor::new(0, false); + lvl1_pt.lvl1[1] = BlockDescriptor::new(0x40000000, false); + lvl1_pt.lvl1[2] = BlockDescriptor::new(0x80000000, false); + lvl1_pt.lvl1[3] = BlockDescriptor::table(lvl2_base); + // 0x0_c000_0000 ~ 0x0_fc00_0000 --> normal memory (960MB) + for i in 0..480 { + lvl2_pt.lvl1[i] = BlockDescriptor::new(0x0c0000000 + (i << LVL2_SHIFT), false); + } + // 0x0_fc00_0000 ~ 0x1_0000_0000 --> device memory (64MB) + for i in 480..512 { + lvl2_pt.lvl1[i] = BlockDescriptor::new(0x0c0000000 + (i << LVL2_SHIFT), true); + } + // 0x1_0000_0000 ~ 0x2_0000_0000 --> normal memory (4GB) + lvl1_pt.lvl1[4] = BlockDescriptor::new(0x100000000, false); + lvl1_pt.lvl1[5] = BlockDescriptor::new(0x140000000, false); + lvl1_pt.lvl1[6] = BlockDescriptor::new(0x180000000, false); + lvl1_pt.lvl1[7] = BlockDescriptor::new(0x1c0000000, false); + for i in 8..512 { + lvl1_pt.lvl1[i] = BlockDescriptor::invalid(); + } + // 0x8_0000_0000 + 0x0_c000_0000 + lvl1_pt.lvl1[32 + 3] = BlockDescriptor::table(lvl2_base); + } + #[cfg(feature = "qemu")] + { + todo!() + } +} + +#[no_mangle] +// #[link_section = ".text.boot"] +pub extern "C" fn mmu_init(pt: &PageTables) { + use cortex_a::registers::*; + MAIR_EL2.write( + MAIR_EL2::Attr0_Device::nonGathering_nonReordering_noEarlyWriteAck + + MAIR_EL2::Attr1_Normal_Outer::WriteBack_NonTransient_ReadWriteAlloc + + MAIR_EL2::Attr1_Normal_Inner::WriteBack_NonTransient_ReadWriteAlloc + + MAIR_EL2::Attr2_Normal_Outer::NonCacheable + + MAIR_EL2::Attr2_Normal_Inner::NonCacheable, + ); + TTBR0_EL2.set(&pt.lvl1 as *const _ as u64); + + TCR_EL2.write( + TCR_EL2::PS::Bits_48 + + TCR_EL2::SH0::Inner + + TCR_EL2::TG0::KiB_4 + + TCR_EL2::ORGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable + + TCR_EL2::IRGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable + + TCR_EL2::T0SZ.val(64 - 39), + ); + + // barrier::isb(barrier::SY); + // SCTLR_EL2.modify(SCTLR_EL2::M::Enable + SCTLR_EL2::C::Cacheable + SCTLR_EL2::I::Cacheable); + // barrier::isb(barrier::SY); +} diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..5d6d6b6f5b04321f140a91c77060d06fba35e255 --- /dev/null +++ b/src/arch/aarch64/mod.rs @@ -0,0 +1,47 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::context_frame::*; +pub use self::cpu::*; +pub use self::exception::*; +pub use self::gic::*; +pub use self::interface::*; +pub use self::interrupt::*; +pub use self::mmu::*; +pub use self::page_table::*; +pub use self::psci::*; +pub use self::regs::*; +pub use self::smc::*; +pub use self::smmu::*; +pub use self::sync::*; +pub use self::timer::*; +pub use self::tlb::*; +pub use self::vcpu::*; +pub use self::vgic::*; + +#[macro_use] +mod regs; + +mod context_frame; +mod cpu; +mod exception; +mod gic; +mod interface; +mod interrupt; +mod mmu; +mod page_table; +mod psci; +mod smc; +mod smmu; +mod sync; +mod timer; +mod tlb; +mod vcpu; +mod vgic; diff --git a/src/arch/aarch64/page_table.rs b/src/arch/aarch64/page_table.rs new file mode 100644 index 0000000000000000000000000000000000000000..8df37668facb67cef5458510f3a0c9510ece0569 --- /dev/null +++ b/src/arch/aarch64/page_table.rs @@ -0,0 +1,441 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; + +// use rlibc::{memcpy, memset}; +use spin::Mutex; + +use crate::arch::ArchPageTableEntryTrait; +use crate::arch::WORD_SIZE; +use crate::kernel::Cpu; +use crate::lib::{memcpy_safe, memset_safe}; +use crate::lib::round_up; +use crate::mm::PageFrame; + +use super::{PAGE_SIZE, PTE_PER_PAGE}; + +// page_table const +pub const LVL1_SHIFT: usize = 30; +pub const LVL2_SHIFT: usize = 21; +pub const LVL3_SHIFT: usize = 12; + +pub const PTE_TABLE: usize = 0b11; +pub const PTE_PAGE: usize = 0b11; +pub const PTE_BLOCK: usize = 0b01; + +pub const PTE_S1_FIELD_AP_RW_EL0_NONE: usize = 0b00 << 6; +pub const PTE_S1_FIELD_AP_RW_EL0_RW: usize = 0b01 << 6; +pub const PTE_S1_FIELD_AP_R0_EL0_NONE: usize = 0b10 << 6; +pub const PTE_S1_FIELD_AP_R0_EL0_RW: usize = 0b11 << 6; + +pub const PTE_S1_FIELD_SH_NON_SHAREABLE: usize = 0b00 << 8; +pub const PTE_S1_FIELD_SH_RESERVED: usize = 0b01 << 8; +pub const PTE_S1_FIELD_SH_OUTER_SHAREABLE: usize = 0b10 << 8; +pub const PTE_S1_FIELD_SH_INNER_SHAREABLE: usize = 0b11 << 8; + +pub const PTE_S1_FIELD_AF: usize = 1 << 10; + +pub const PTE_S2_FIELD_MEM_ATTR_DEVICE_NGNRNE: usize = 0; + +pub const PTE_S2_FIELD_MEM_ATTR_NORMAL_OUTER_WRITE_BACK_CACHEABLE: usize = 0b11 << 4; + +pub const PTE_S2_FIELD_MEM_ATTR_NORMAL_INNER_WRITE_BACK_CACHEABLE: usize = 0b11 << 2; + +pub const PTE_S2_FIELD_AP_NONE: usize = 0b00 << 6; +pub const PTE_S2_FIELD_AP_RO: usize = 0b01 << 6; +pub const PTE_S2_FIELD_AP_WO: usize = 0b10 << 6; +pub const PTE_S2_FIELD_AP_RW: usize = 0b11 << 6; + +pub const PTE_S2_FIELD_SH_NON_SHAREABLE: usize = 0b00 << 8; +pub const PTE_S2_FIELD_SH_RESERVED: usize = 0b01 << 8; +pub const PTE_S2_FIELD_SH_OUTER_SHAREABLE: usize = 0b10 << 8; +pub const PTE_S2_FIELD_SH_INNER_SHAREABLE: usize = 0b11 << 8; + +pub const PTE_S2_FIELD_AF: usize = 1 << 10; + +pub const PTE_S1_NORMAL: usize = + pte_s1_field_attr_indx(1) | PTE_S1_FIELD_AP_RW_EL0_NONE | PTE_S1_FIELD_SH_OUTER_SHAREABLE | PTE_S1_FIELD_AF; + +pub const PTE_S2_DEVICE: usize = + PTE_S2_FIELD_MEM_ATTR_DEVICE_NGNRNE | PTE_S2_FIELD_AP_RW | PTE_S2_FIELD_SH_OUTER_SHAREABLE | PTE_S2_FIELD_AF; + +pub const PTE_S2_NORMAL: usize = PTE_S2_FIELD_MEM_ATTR_NORMAL_INNER_WRITE_BACK_CACHEABLE + | PTE_S2_FIELD_MEM_ATTR_NORMAL_OUTER_WRITE_BACK_CACHEABLE + | PTE_S2_FIELD_AP_RW + | PTE_S2_FIELD_SH_OUTER_SHAREABLE + | PTE_S2_FIELD_AF; + +pub const PTE_S2_RO: usize = PTE_S2_FIELD_MEM_ATTR_NORMAL_INNER_WRITE_BACK_CACHEABLE + | PTE_S2_FIELD_MEM_ATTR_NORMAL_OUTER_WRITE_BACK_CACHEABLE + | PTE_S2_FIELD_AP_RO + | PTE_S2_FIELD_SH_OUTER_SHAREABLE + | PTE_S2_FIELD_AF; + +pub const CPU_BANKED_ADDRESS: usize = 0x400000000; + +pub const fn pte_s1_field_attr_indx(idx: usize) -> usize { + idx << 2 +} + +// page_table function +pub fn pt_lvl1_idx(va: usize) -> usize { + (va >> LVL1_SHIFT) & (PTE_PER_PAGE - 1) +} + +pub fn pt_lvl2_idx(va: usize) -> usize { + (va >> LVL2_SHIFT) & (PTE_PER_PAGE - 1) +} + +pub fn pt_lvl3_idx(va: usize) -> usize { + (va >> LVL3_SHIFT) & (PTE_PER_PAGE - 1) +} + +pub fn pt_map_banked_cpu(cpu: &mut Cpu) -> usize { + extern "C" { + fn lvl1_page_table(); + } + let addr: usize = lvl1_page_table as usize; + + memcpy_safe(&(cpu.cpu_pt.lvl1) as *const _ as *mut u8, addr as *mut u8, PAGE_SIZE); + memset_safe(&(cpu.cpu_pt.lvl2) as *const _ as *mut u8, 0, PAGE_SIZE); + memset_safe(&(cpu.cpu_pt.lvl3) as *const _ as *mut u8, 0, PAGE_SIZE); + + let cpu_addr = cpu as *const _ as usize; + let lvl2_addr = &(cpu.cpu_pt.lvl2) as *const _ as usize; + let lvl3_addr = &(cpu.cpu_pt.lvl3) as *const _ as usize; + cpu.cpu_pt.lvl1[pt_lvl1_idx(CPU_BANKED_ADDRESS)] = lvl2_addr | PTE_S1_NORMAL | PTE_TABLE; + cpu.cpu_pt.lvl2[pt_lvl2_idx(CPU_BANKED_ADDRESS)] = lvl3_addr | PTE_S1_NORMAL | PTE_TABLE; + + use core::mem::size_of; + let page_num = round_up(size_of::(), PAGE_SIZE) / PAGE_SIZE; + + // println!("cpu page num is {}", page_num); + for i in 0..page_num { + cpu.cpu_pt.lvl3[pt_lvl3_idx(CPU_BANKED_ADDRESS) + i] = (cpu_addr + i * PAGE_SIZE) | PTE_S1_NORMAL | PTE_PAGE; + } + + // println!("cpu addr {:x}", cpu_addr); + // println!("lvl2 addr {:x}", lvl2_addr); + // println!("lvl3 addr {:x}", lvl3_addr); + + &(cpu.cpu_pt.lvl1) as *const _ as usize +} + +#[repr(transparent)] +#[derive(Copy, Clone, Debug)] +pub struct Aarch64PageTableEntry(usize); + +impl ArchPageTableEntryTrait for Aarch64PageTableEntry { + fn from_pte(value: usize) -> Self { + Aarch64PageTableEntry(value) + } + + fn from_pa(pa: usize) -> Self { + Aarch64PageTableEntry(pa) + } + + fn to_pte(&self) -> usize { + self.0 + } + + fn to_pa(&self) -> usize { + self.0 & 0x0000_FFFF_FFFF_F000 + } + + fn valid(&self) -> bool { + self.0 & 0b11 != 0 + } + + fn entry(&self, index: usize) -> Aarch64PageTableEntry { + let addr = self.to_pa() + index * WORD_SIZE; + unsafe { Aarch64PageTableEntry((addr as *const usize).read_volatile()) } + } + + fn set_entry(&self, index: usize, value: Aarch64PageTableEntry) { + let addr = self.to_pa() + index * WORD_SIZE; + unsafe { (addr as *mut usize).write_volatile(value.0) } + } + + fn make_table(frame_pa: usize) -> Self { + Aarch64PageTableEntry::from_pa(frame_pa | PTE_TABLE) + } +} + +#[derive(Clone)] +pub struct PageTable { + pub directory: Arc, + pub pages: Arc>>, +} + +impl PageTable { + pub fn new(directory: PageFrame) -> PageTable { + PageTable { + directory: Arc::new(directory), + pages: Arc::new(Mutex::new(Vec::new())), + } + } + + pub fn base_pa(&self) -> usize { + self.directory.pa() + } + + pub fn access_permission(&self, start_ipa: usize, len: usize, ap: usize) -> (usize, usize) { + let directory = Aarch64PageTableEntry::from_pa(self.directory.pa()); + let mut ipa = start_ipa; + let mut size = 0; + let mut pa = 0; + while ipa < (start_ipa + len) { + let l1e = directory.entry(pt_lvl1_idx(ipa)); + if !l1e.valid() { + ipa += 512 * 512 * 4096; // 1GB: 9 + 9 + 12 bits + continue; + } + let l2e = l1e.entry(pt_lvl2_idx(ipa)); + if !l2e.valid() { + ipa += 512 * 4096; // 2MB: 9 + 12 bits + continue; + } else if l2e.to_pte() & 0b11 == PTE_BLOCK { + let pte = l2e.to_pte() & !(0b11 << 6) | ap; + println!("access_permission set 512 page ipa {:x}", ipa); + l1e.set_entry(pt_lvl2_idx(ipa), Aarch64PageTableEntry::from_pa(pte)); + ipa += 512 * 4096; // 2MB: 9 + 12 bits + pa = l2e.to_pa(); + size += 512 * 4096; + continue; + } + let l3e = l2e.entry(pt_lvl3_idx(ipa)); + if l3e.valid() { + // if ipa < 0x8400_0000 { + let pte = l3e.to_pte() & !(0b11 << 6) | ap; + l2e.set_entry(pt_lvl3_idx(ipa), Aarch64PageTableEntry::from_pa(pte)); + pa = l3e.to_pa(); + size += 4096; + // } else if ipa < 0x8000_0000 { + // panic!("illegal ipa {:x}", start_ipa); + // } else { + // // println!( + // // "access_permission ipa {:x} l2e pte {:x} l3e pte {:x}", + // // ipa, + // // l2e.to_pte(), + // // l3e.to_pte() + // // ); + // pa = l3e.to_pa(); + // size += 4096; + // } + } + ipa += 4096; // 4KB: 12 bits + } + (pa, size) + } + + pub fn map_2mb(&self, ipa: usize, pa: usize, pte: usize) { + let directory = Aarch64PageTableEntry::from_pa(self.directory.pa()); + let mut l1e = directory.entry(pt_lvl1_idx(ipa)); + if !l1e.valid() { + let result = crate::kernel::mem_page_alloc(); + if let Ok(frame) = result { + l1e = Aarch64PageTableEntry::make_table(frame.pa()); + let mut pages = self.pages.lock(); + pages.push(frame); + directory.set_entry(pt_lvl1_idx(ipa), l1e); + } else { + println!("map lv1 page failed"); + return; + } + } + + let l2e = l1e.entry(pt_lvl2_idx(ipa)); + if l2e.valid() { + println!("map_2mb lvl 2 already mapped with 0x{:x}", l2e.to_pte()); + } else { + l1e.set_entry(pt_lvl2_idx(ipa), Aarch64PageTableEntry::from_pa(pa | pte | PTE_BLOCK)); + } + } + + pub fn unmap_2mb(&self, ipa: usize) { + let directory = Aarch64PageTableEntry::from_pa(self.directory.pa()); + let l1e = directory.entry(pt_lvl1_idx(ipa)); + if l1e.valid() { + let l2e = l1e.entry(pt_lvl2_idx(ipa)); + if l2e.valid() { + l1e.set_entry(pt_lvl2_idx(ipa), Aarch64PageTableEntry(0)); + if empty_page(l1e.to_pa()) { + let l1e_pa = l1e.to_pa(); + directory.set_entry(pt_lvl1_idx(ipa), Aarch64PageTableEntry(0)); + let mut pages = self.pages.lock(); + pages.retain(|pf| pf.pa() != l1e_pa); + } + } + } + } + + pub fn map(&self, ipa: usize, pa: usize, pte: usize) { + // if ipa >= 0x4_0000_0000 { + // println!("map ipa 0x{:x} to pa 0x{:x}", ipa, pa); + // } + let directory = Aarch64PageTableEntry::from_pa(self.directory.pa()); + let mut l1e = directory.entry(pt_lvl1_idx(ipa)); + // if ipa >= 0x4_0000_0000 { + // println!("l1e {:x}", l1e.0); + // } + if !l1e.valid() { + let result = crate::kernel::mem_page_alloc(); + if let Ok(frame) = result { + l1e = Aarch64PageTableEntry::make_table(frame.pa()); + let mut pages = self.pages.lock(); + pages.push(frame); + directory.set_entry(pt_lvl1_idx(ipa), l1e); + } else { + println!("map lv1 page failed"); + return; + } + } + + let mut l2e = l1e.entry(pt_lvl2_idx(ipa)); + if !l2e.valid() { + let result = crate::kernel::mem_page_alloc(); + if let Ok(frame) = result { + l2e = Aarch64PageTableEntry::make_table(frame.pa()); + let mut pages = self.pages.lock(); + pages.push(frame); + l1e.set_entry(pt_lvl2_idx(ipa), l2e); + } else { + println!("map lv2 page failed {:#?}", result.err()); + return; + } + } else if l2e.to_pte() & 0b11 == PTE_BLOCK { + println!("map lvl 2 already mapped with 2mb 0x{:x}", l2e.to_pte()); + } + // if ipa >= 0x4_0000_0000 { + // println!("l2e {:x}", l2e.0); + // } + let l3e = l2e.entry(pt_lvl3_idx(ipa)); + if l3e.valid() { + println!("map lvl 3 already mapped with 0x{:x}", l3e.to_pte()); + } else { + l2e.set_entry(pt_lvl3_idx(ipa), Aarch64PageTableEntry::from_pa(pa | PTE_TABLE | pte)); + } + // if ipa >= 0x4_0000_0000 { + // println!("l3e {:x}", l3e.0); + // } + } + + pub fn unmap(&self, ipa: usize) { + let directory = Aarch64PageTableEntry::from_pa(self.directory.pa()); + let l1e = directory.entry(pt_lvl1_idx(ipa)); + if l1e.valid() { + let l2e = l1e.entry(pt_lvl2_idx(ipa)); + if l2e.valid() { + let l3e = l2e.entry(pt_lvl3_idx(ipa)); + if l3e.valid() { + l2e.set_entry(pt_lvl3_idx(ipa), Aarch64PageTableEntry::from_pa(0)); + // check l2e + if empty_page(l2e.to_pa()) { + let l2e_pa = l2e.to_pa(); + l1e.set_entry(pt_lvl2_idx(ipa), Aarch64PageTableEntry(0)); + let mut pages = self.pages.lock(); + pages.retain(|pf| pf.pa != l2e_pa); + // check l1e + if empty_page(l1e.to_pa()) { + let l1e_pa = l1e.to_pa(); + directory.set_entry(pt_lvl1_idx(ipa), Aarch64PageTableEntry(0)); + pages.retain(|pf| pf.pa != l1e_pa); + } + } + } + } + } + } + + pub fn map_range_2mb(&self, ipa: usize, len: usize, pa: usize, pte: usize) { + let size_2mb = 1 << LVL2_SHIFT; + let page_num = round_up(len, size_2mb) / size_2mb; + + for i in 0..page_num { + self.map_2mb(ipa + i * size_2mb, pa + i * size_2mb, pte); + } + } + + pub fn unmap_range_2mb(&self, ipa: usize, len: usize) { + let size_2mb = 1 << LVL2_SHIFT; + let page_num = round_up(len, size_2mb) / size_2mb; + + for i in 0..page_num { + self.unmap_2mb(ipa + i * size_2mb); + } + } + + pub fn map_range(&self, ipa: usize, len: usize, pa: usize, pte: usize) { + let page_num = round_up(len, PAGE_SIZE) / PAGE_SIZE; + // if ipa == 0x8010000 { + // println!( + // "map_range: ipa {:x}, len {:x}, pa {:x}, pte 0b{:b}, page_num {:x}", + // ipa, len, pa, pte, page_num, + // ); + // } + for i in 0..page_num { + self.map(ipa + i * PAGE_SIZE, pa + i * PAGE_SIZE, pte); + } + } + + pub fn unmap_range(&self, ipa: usize, len: usize) { + let page_num = round_up(len, PAGE_SIZE) / PAGE_SIZE; + for i in 0..page_num { + self.unmap(ipa + i * PAGE_SIZE); + } + } + + pub fn show_pt(&self, ipa: usize) { + // println!("show_pt"); + let directory = Aarch64PageTableEntry::from_pa(self.directory.pa()); + println!("1 {:x}", directory.to_pte()); + let l1e = directory.entry(pt_lvl1_idx(ipa)); + println!("2 {:x}", l1e.to_pte()); + let l2e = l1e.entry(pt_lvl2_idx(ipa)); + println!("3 {:x}", l2e.to_pte()); + if !l2e.valid() { + println!("invalid ipa {:x} to l2 pte {:x}", ipa, l2e.to_pte()); + } else if l2e.to_pte() & 0b11 == PTE_BLOCK { + println!("l2 ipa {:x} to pa {:x}", ipa, l2e.to_pte()); + } else { + let l3e = l2e.entry(pt_lvl3_idx(ipa)); + println!("l3 ipa {:x} to pa {:x}", ipa, l3e.to_pte()); + } + } + + pub fn pt_map_range(&self, ipa: usize, len: usize, pa: usize, pte: usize, map_block: bool) { + let size_2mb = 1 << LVL2_SHIFT; + if ipa % size_2mb == 0 && len % size_2mb == 0 && pa % size_2mb == 0 && map_block { + self.map_range_2mb(ipa, len, pa, pte); + } else { + self.map_range(ipa, len, pa, pte); + } + } + + pub fn pt_unmap_range(&self, ipa: usize, len: usize, map_block: bool) { + let size_2mb = 1 << LVL2_SHIFT; + if ipa % size_2mb == 0 && len % size_2mb == 0 && map_block { + self.unmap_range_2mb(ipa, len); + } else { + self.unmap_range(ipa, len); + } + } +} + +pub fn empty_page(addr: usize) -> bool { + for i in 0..(PAGE_SIZE / 8) { + if unsafe { ((addr + i * 8) as *const usize).read_volatile() != 0 } { + return false; + } + } + true +} diff --git a/src/arch/aarch64/psci.rs b/src/arch/aarch64/psci.rs new file mode 100644 index 0000000000000000000000000000000000000000..378bb9c12432551d927611cc299e2cf1f21e9b14 --- /dev/null +++ b/src/arch/aarch64/psci.rs @@ -0,0 +1,246 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::{gic_cpu_init, gicc_clear_current_irq, vcpu_arch_init}; +use crate::kernel::{cpu_idle, current_cpu, ipi_intra_broadcast_msg, Scheduler, timer_enable, Vcpu, VcpuState, Vm}; +use crate::kernel::{active_vm, ipi_send_msg, IpiInnerMsg, IpiPowerMessage, IpiType, PowerEvent}; +use crate::kernel::CpuState; +use crate::kernel::IpiMessage; +use crate::vmm::vmm_reboot; + +use super::smc::smc_call; + +pub const PSCI_VERSION: usize = 0x84000000; +pub const PSCI_MIG_INFO_TYPE: usize = 0x84000006; +pub const PSCI_FEATURES: usize = 0x8400000A; +// pub const PSCI_CPU_SUSPEND_AARCH64: usize = 0xc4000001; +// pub const PSCI_CPU_OFF: usize = 0xc4000002; +pub const PSCI_CPU_ON_AARCH64: usize = 0xc4000003; +pub const PSCI_AFFINITY_INFO_AARCH64: usize = 0xc4000004; +pub const PSCI_SYSTEM_OFF: usize = 0x84000008; +pub const PSCI_SYSTEM_RESET: usize = 0x84000009; + +pub const PSCI_E_SUCCESS: usize = 0; +pub const PSCI_E_NOT_SUPPORTED: usize = usize::MAX; + +#[cfg(feature = "tx2")] +const TEGRA_SIP_GET_ACTMON_CLK_COUNTERS: usize = 0xC2FFFE02; + +pub const PSCI_TOS_NOT_PRESENT_MP: usize = 2; + +pub fn power_arch_init() { + use crate::kernel::ipi_register; + if !ipi_register(IpiType::IpiTPower, psci_ipi_handler) { + panic!("power_arch_init: failed to register ipi IpiTPower"); + } +} + +pub fn power_arch_vm_shutdown_secondary_cores(vm: Vm) { + let m = IpiPowerMessage { + src: vm.id(), + event: PowerEvent::PsciIpiCpuReset, + entry: 0, + context: 0, + }; + + if !ipi_intra_broadcast_msg(vm, IpiType::IpiTPower, IpiInnerMsg::Power(m)) { + warn!("power_arch_vm_shutdown_secondary_cores: fail to ipi_intra_broadcast_msg"); + } +} + +pub fn power_arch_cpu_on(mpidr: usize, entry: usize, ctx: usize) -> usize { + // println!("power_arch_cpu_on, {:x}, {:x}, {:x}", PSCI_CPU_ON_AARCH64, mpidr, entry); + let r = smc_call(PSCI_CPU_ON_AARCH64, mpidr, entry, ctx).0; + // println!("smc return val is {}", r); + r +} + +pub fn power_arch_cpu_shutdown() { + gic_cpu_init(); + gicc_clear_current_irq(true); + timer_enable(false); + cpu_idle(); +} + +pub fn power_arch_sys_reset() { + smc_call(PSCI_SYSTEM_RESET, 0, 0, 0); +} + +pub fn power_arch_sys_shutdown() { + smc_call(PSCI_SYSTEM_OFF, 0, 0, 0); +} + +fn psci_guest_sys_reset() { + vmm_reboot(); +} + +#[inline(never)] +pub fn smc_guest_handler(fid: usize, x1: usize, x2: usize, x3: usize) -> bool { + debug!( + "smc_guest_handler: fid 0x{:x}, x1 0x{:x}, x2 0x{:x}, x3 0x{:x}", + fid, x1, x2, x3 + ); + let r; + match fid { + PSCI_VERSION => { + r = smc_call(PSCI_VERSION, 0, 0, 0).0; + } + PSCI_MIG_INFO_TYPE => { + r = PSCI_TOS_NOT_PRESENT_MP; + } + PSCI_CPU_ON_AARCH64 => { + r = psci_guest_cpu_on(x1, x2, x3); + } + PSCI_AFFINITY_INFO_AARCH64 => { + r = 0; + } + PSCI_SYSTEM_RESET => { + psci_guest_sys_reset(); + r = 0; + } + #[cfg(feature = "tx2")] + TEGRA_SIP_GET_ACTMON_CLK_COUNTERS => { + let result = smc_call(fid, x1, x2, x3); + r = result.0; + // println!("x1 0x{:x}, x2 0x{:x}, x3 0x{:x}", x1, x2, x3); + // println!( + // "result.0 0x{:x}, result.1 0x{:x}, result.2 0x{:x}", + // result.0, result.1, result.2 + // ); + current_cpu().set_gpr(1, result.1); + current_cpu().set_gpr(2, result.2); + } + PSCI_FEATURES => match x1 { + PSCI_VERSION | PSCI_CPU_ON_AARCH64 | PSCI_FEATURES => { + r = PSCI_E_SUCCESS; + } + _ => { + r = PSCI_E_NOT_SUPPORTED; + } + }, + _ => { + // unimplemented!(); + return false; + } + } + + let idx = 0; + let val = r; + current_cpu().set_gpr(idx, val); + + true +} + +fn psci_vcpu_on(vcpu: Vcpu, entry: usize, ctx: usize) { + // println!("psci vcpu on, entry {:x}, ctx {:x}", entry, ctx); + if vcpu.phys_id() != current_cpu().id { + panic!( + "cannot psci on vcpu on cpu {} by cpu {}", + vcpu.phys_id(), + current_cpu().id + ); + } + current_cpu().cpu_state = CpuState::CpuRun; + // let vcpu = current_cpu().active_vcpu.clone().unwrap(); + vcpu.reset_context(); + vcpu.set_gpr(0, ctx); + vcpu.set_elr(entry); + // Just wake up the vcpu and + // invoke current_cpu().sched.schedule() + // let the scheduler enable or disable timer + current_cpu().scheduler().wakeup(vcpu); + current_cpu().scheduler().do_schedule(); +} + +// Todo: need to support more vcpu in one Core +pub fn psci_ipi_handler(msg: &IpiMessage) { + match msg.ipi_message { + IpiInnerMsg::Power(power_msg) => { + let trgt_vcpu = match current_cpu().vcpu_array.pop_vcpu_through_vmid(power_msg.src) { + None => { + warn!( + "Core {} failed to find target vcpu, source vmid {}", + current_cpu().id, + power_msg.src + ); + return; + } + Some(vcpu) => vcpu, + }; + match power_msg.event { + PowerEvent::PsciIpiCpuOn => { + if trgt_vcpu.state() as usize != VcpuState::VcpuInv as usize { + warn!( + "psci_ipi_handler: target VCPU {} in VM {} is already running", + trgt_vcpu.id(), + trgt_vcpu.vm().unwrap().id() + ); + return; + } + info!( + "Core {} (vm {}, vcpu {}) is woke up", + current_cpu().id, + trgt_vcpu.vm().unwrap().id(), + trgt_vcpu.id() + ); + psci_vcpu_on(trgt_vcpu, power_msg.entry, power_msg.context); + } + PowerEvent::PsciIpiCpuOff => { + // TODO: 为什么ipi cpu off是当前vcpu shutdown,而vcpu shutdown 最后是把平台的物理核心shutdown + // 没有用到。不用管 + // current_cpu().active_vcpu.clone().unwrap().shutdown(); + unimplemented!("PowerEvent::PsciIpiCpuOff") + } + PowerEvent::PsciIpiCpuReset => { + vcpu_arch_init(active_vm().unwrap(), current_cpu().active_vcpu.clone().unwrap()); + } + } + } + _ => { + panic!( + "psci_ipi_handler: cpu{} receive illegal psci ipi type", + current_cpu().id + ); + } + } +} + +pub fn psci_guest_cpu_on(mpidr: usize, entry: usize, ctx: usize) -> usize { + let vcpu_id = mpidr & 0xff; + let vm = active_vm().unwrap(); + let physical_linear_id = vm.vcpuid_to_pcpuid(vcpu_id); + + if vcpu_id >= vm.cpu_num() || physical_linear_id.is_err() { + warn!("psci_guest_cpu_on: target vcpu {} not exist", vcpu_id); + return usize::MAX - 1; + } + #[cfg(feature = "tx2")] + { + let cluster = (mpidr >> 8) & 0xff; + if vm.id() == 0 && cluster != 1 { + warn!("psci_guest_cpu_on: L4T only support cluster #1"); + return usize::MAX - 1; + } + } + + let m = IpiPowerMessage { + src: vm.id(), + event: PowerEvent::PsciIpiCpuOn, + entry, + context: ctx, + }; + + if !ipi_send_msg(physical_linear_id.unwrap(), IpiType::IpiTPower, IpiInnerMsg::Power(m)) { + warn!("psci_guest_cpu_on: fail to send msg"); + return usize::MAX - 1; + } + + 0 +} diff --git a/src/arch/aarch64/regs.rs b/src/arch/aarch64/regs.rs new file mode 100644 index 0000000000000000000000000000000000000000..4d1eb03b6835a392c7fa0265227ae30c16f24c63 --- /dev/null +++ b/src/arch/aarch64/regs.rs @@ -0,0 +1,39 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +// Move to ARM register from system coprocessor register. +// MRS Xd, sysreg "Xd = sysreg" +macro_rules! mrs { + ($val: expr, $reg: expr, $asm_width:tt) => { + unsafe { + core::arch::asm!(concat!("mrs {0:", $asm_width, "}, ", stringify!($reg)), out(reg) $val, options(nomem, nostack)); + } + }; + ($val: expr, $reg: expr) => { + unsafe { + core::arch::asm!(concat!("mrs {0}, ", stringify!($reg)), out(reg) $val, options(nomem, nostack)); + } + }; +} + +// Move to system coprocessor register from ARM register. +// MSR sysreg, Xn "sysreg = Xn" +macro_rules! msr { + ($reg: expr, $val: expr, $asm_width:tt) => { + unsafe { + core::arch::asm!(concat!("msr ", stringify!($reg), ", {0:", $asm_width, "}"), in(reg) $val, options(nomem, nostack)); + } + }; + ($reg: expr, $val: expr) => { + unsafe { + core::arch::asm!(concat!("msr ", stringify!($reg), ", {0}"), in(reg) $val, options(nomem, nostack)); + } + }; +} diff --git a/src/arch/aarch64/smc.rs b/src/arch/aarch64/smc.rs new file mode 100644 index 0000000000000000000000000000000000000000..e508029a3300ce6c1eb00183b03a88b2875eaaf8 --- /dev/null +++ b/src/arch/aarch64/smc.rs @@ -0,0 +1,34 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::arch::asm; + +#[inline(never)] +pub fn smc_call(x0: usize, x1: usize, x2: usize, x3: usize) -> (usize, usize, usize, usize) { + #[cfg(target_arch = "aarch64")] + unsafe { + let r0; + let r1; + let r2; + let r3; + asm!( + "smc #0", + inout("x0") x0 => r0, + inout("x1") x1 => r1, + inout("x2") x2 => r2, + inout("x3") x3 => r3, + options(nomem, nostack) + ); + (r0, r1, r2, r3) + } + + #[cfg(not(target_arch = "aarch64"))] + unimplemented!(); +} diff --git a/src/arch/aarch64/smmu.rs b/src/arch/aarch64/smmu.rs new file mode 100644 index 0000000000000000000000000000000000000000..fe1088cd3dfbcf09caa2bfb98073836b0661f7b4 --- /dev/null +++ b/src/arch/aarch64/smmu.rs @@ -0,0 +1,703 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; +use core::mem::size_of; +use core::ptr; + +use spin::Mutex; +use tock_registers::*; +use tock_registers::interfaces::*; +use tock_registers::registers::*; + +use crate::board::PLAT_DESC; +use crate::device::EmuContext; +use crate::kernel::VM_NUM_MAX; +use crate::kernel::Vm; +use crate::kernel::{active_vm, active_vm_id, current_cpu}; +use crate::lib::{bit_extract, FlexBitmap}; + +pub struct SmmuDesc { + pub base: usize, + pub interrupt_id: usize, + pub global_mask: u16, +} + +const SMMUV2_CBAR_TYPE_S1_S2: usize = 0x3 << 16; + +const SMMUV2_IDR0_S1TS_BIT: usize = 1 << 30; +const SMMUV2_IDR0_S2TS_BIT: usize = 1 << 29; +const SMMUV2_IDR0_NTS_BIT: usize = 1 << 28; +const SMMUV2_IDR0_SMS_BIT: usize = 1 << 27; +const SMMUV2_IDR0_CTTW_BIT: usize = 1 << 14; +const SMMUV2_IDR0_BTM_BIT: usize = 1 << 13; + +const SMMUV2_IDR1_PAGESIZE_BIT: usize = 1 << 31; +const SMMUV2_IDR1_NUMCB_OFF: usize = 0; +const SMMUV2_IDR1_NUMCB_LEN: usize = 8; +const SMMUV2_IDR1_NUMS2CB_OFF: usize = 16; +const SMMUV2_IDR1_NUMS2CB_LEN: usize = 8; +const SMMUV2_IDR1_NUMPAGEDXB_OFF: usize = 28; +const SMMUV2_IDR1_NUMPAGEDXB_LEN: usize = 3; + +const SMMUV2_IDR2_PTFSV8_4KB_BIT: usize = 1 << 12; + +const SMMUV2_CR0_CLIENTPD: usize = 1; +const SMMUV2_CR0_GFRE: usize = 1 << 1; +const SMMUV2_CR0_GFIE: usize = 1 << 2; +const SMMUV2_CR0_GCFGFRE: usize = 1 << 4; +const SMMUV2_CR0_GCFGFIE: usize = 1 << 5; +const SMMUV2_CR0_USFCFG: usize = 1 << 10; +const SMMUV2_CR0_SMCFCFG: usize = 1 << 21; + +const SMMU_RS1_CBAR: usize = 0; +const SMMU_RS1_RES0: usize = 0x200; + +const SMMUV2_CB_TTBA_END: usize = 48; + +const SMMUV2_TCR_PS_OFF: usize = 16; +const SMMUV2_TCR_TG0_4K: usize = 0; +const SMMUV2_TCR_IRGN0_WB_RA_WA: usize = 1 << 8; +const SMMUV2_TCR_ORGN0_WB_RA_WA: usize = 1 << 10; +const SMMUV2_TCR_SH0_IS: usize = 0x3 << 12; +const SMMUV2_TCR_SL0_1: usize = 0x1 << 6; + +const SMMUV2_SCTLR_CFIE: usize = 1 << 6; +const SMMUV2_SCTLR_CFRE: usize = 1 << 5; +const SMMUV2_SCTLR_M: usize = 1; + +const SMMU_SMR_ID_OFF: usize = 0; +const SMMU_SMR_ID_LEN: usize = 15; +const SMMU_SMR_MASK_OFF: usize = 16; +const SMMU_SMR_MASK_LEN: usize = 15; + +const SMMUV2_SMR_VALID: usize = 0x1 << 31; + +const S2CR_CBNDX_OFF: usize = 0; +const S2CR_CBNDX_LEN: usize = 8; + +const S2CR_IMPL_OFF: usize = 30; +const S2CR_IMPL_LEN: usize = 2; + +const S2CR_DFLT: usize = 0; + +macro_rules! bit_mask { + ($off: expr, $len: expr) => { + ((1 << ($off + $len)) - 1) & !((1 << $off) - 1) + }; +} + +register_structs! { + #[allow(non_snake_case)] + pub SmmuGlobalRegisterSpace0 { + (0x0000 => CR0: ReadWrite), + (0x0004 => SCR1: ReadWrite), + (0x0008 => CR2: ReadWrite), + (0x000c => reserved_0), + (0x0010 => ACR: ReadWrite), + (0x0014 => reserved_1), + (0x0020 => IDR0: ReadOnly), + (0x0024 => IDR1: ReadOnly), + (0x0028 => IDR2: ReadOnly), + (0x002c => IDR3: ReadOnly), + (0x0030 => IDR4: ReadOnly), + (0x0034 => IDR5: ReadOnly), + (0x0038 => IDR6: ReadOnly), + (0x003c => IDR7: ReadOnly), + (0x0040 => GFAR: ReadWrite), + (0x0048 => GFSR: ReadWrite), + (0x004c => GFSRRESTORE: WriteOnly), + (0x0050 => GFSYNR0: ReadWrite), + (0x0054 => GFSYNR1: ReadWrite), + (0x0058 => GFSYNR2: ReadWrite), + (0x005c => reserved_2), + (0x0060 => STLBIALL: WriteOnly), + (0x0064 => TLBIVMID: WriteOnly), + (0x0068 => TLBIALLNSNH: WriteOnly), + (0x006c => TLBIALLH: WriteOnly), + (0x0070 => TLBGSYNC: WriteOnly), + (0x0074 => TLBGSTATUS: ReadOnly), + (0x0078 => TLBIVAH: WriteOnly), + (0x007c => reserved_3), + (0x00a0 => STLBIVALM: WriteOnly), + (0x00a8 => STLBIVAM: WriteOnly), + (0x00b0 => TLBIVALH64: WriteOnly), + (0x00b8 => TLBIVMIDS1: WriteOnly), + (0x00bc => TLBIALLM: WriteOnly), + (0x00c0 => TLBIVAH64: WriteOnly), + (0x00c8 => reserved_4), + (0x0100 => GATS1UR: WriteOnly), + (0x0108 => GATS1UW: WriteOnly), + (0x0110 => GATS1PR: WriteOnly), + (0x0118 => GATS1PW: WriteOnly), + (0x0120 => GATS12UR: WriteOnly), + (0x0128 => GATS12UW: WriteOnly), + (0x0130 => GATS12PR: WriteOnly), + (0x0138 => GATS12PW: WriteOnly), + (0x0140 => reserved_5), + (0x0180 => GPAR: ReadWrite), + (0x0188 => GATSR: ReadOnly), + (0x018c => reserved_6), + (0x0400 => NSCR0: ReadWrite), + (0x0404 => reserved_7), + (0x0408 => NSCR2: ReadWrite), + (0x040c => reserved_8), + (0x0410 => NSACR2: ReadWrite), + (0x0414 => reserved_9), + (0x0440 => NSGFAR: ReadWrite), + (0x0448 => NSGFSR: ReadWrite), + (0x044c => NSGFSRRESTORE: WriteOnly), + (0x0450 => NSGFSYNR0: ReadWrite), + (0x0454 => NSGFSYNR1: ReadWrite), + (0x0458 => NSGFSYNR2: ReadWrite), + (0x045c => reserved_10), + (0x0470 => NSTLBGSYNC: WriteOnly), + (0x0474 => NSTLBGSTATUS: ReadOnly), + (0x0478 => reserved_11), + (0x0500 => NSGATS1UR: WriteOnly), + (0x0508 => NSGATS1UW: WriteOnly), + (0x0510 => NSGATS1PR: WriteOnly), // NOT SURE + (0x0518 => NSGATS1PW: WriteOnly), + (0x0520 => NSGATS12UR: WriteOnly), + (0x0528 => NSGATS12UW: WriteOnly), + (0x0530 => NSGATS12PR: WriteOnly), + (0x0538 => NSGATS12PW: WriteOnly), + (0x0540 => reserved_12), + (0x0580 => NSGPAR: ReadWrite), + (0x0588 => NSGATSR: ReadOnly), + (0x058c => reserved_13), + (0x0800 => SMR: [ReadWrite; 128]), + (0x0a00 => reserved_14), + (0x0c00 => S2CR: [ReadWrite; 128]), + (0x0e00 => reserved_15), + (0x1000 => @END), + } +} + +#[derive(Clone, Copy)] +pub struct SmmuGlbRS0 { + base_addr: usize, +} + +impl core::ops::Deref for SmmuGlbRS0 { + type Target = SmmuGlobalRegisterSpace0; + fn deref(&self) -> &Self::Target { + unsafe { &*self.ptr() } + } +} + +impl SmmuGlbRS0 { + const fn new(base_addr: usize) -> SmmuGlbRS0 { + SmmuGlbRS0 { base_addr } + } + + pub fn ptr(&self) -> *const SmmuGlobalRegisterSpace0 { + self.base_addr as *const SmmuGlobalRegisterSpace0 + } +} + +register_structs! { + #[allow(non_snake_case)] + pub SmmuGlobalRegisterSpace1 { + (0x0000 => CBAR: [ReadWrite; 128]), + (0x0200 => reserved_0), + (0x0400 => CBFRSYNRA: [ReadWrite; 128]), + (0x0600 => reserved_1), + (0x0800 => CBA2R: [ReadWrite; 128]), + (0x0a00 => reserved_2), + (0x1000 => @END), + } +} + +#[derive(Clone, Copy)] +pub struct SmmuGlbRS1 { + base_addr: usize, +} + +impl core::ops::Deref for SmmuGlbRS1 { + type Target = SmmuGlobalRegisterSpace1; + fn deref(&self) -> &Self::Target { + unsafe { &*self.ptr() } + } +} + +impl SmmuGlbRS1 { + const fn new(base_addr: usize) -> SmmuGlbRS1 { + SmmuGlbRS1 { base_addr } + } + + pub fn ptr(&self) -> *const SmmuGlobalRegisterSpace1 { + self.base_addr as *const SmmuGlobalRegisterSpace1 + } +} + +register_structs! { + #[allow(non_snake_case)] + pub SmmuStage2TranslationContextBankAddressSpace { + (0x0000 => SCTLR: ReadWrite), + (0x0004 => ACTLR: ReadWrite), + (0x0008 => RESUME: WriteOnly), + (0x000c => reserved_0), + (0x0020 => TTBR0: ReadWrite), + (0x0028 => reserved_1), + (0x0030 => TCR: ReadWrite), + (0x0034 => reserved_2), + (0x0058 => FSR: ReadWrite), + (0x005c => FSRRESTORE: WriteOnly), + (0x0060 => FAR: ReadWrite), + (0x0068 => FSYNR0: ReadWrite), + (0x006c => FSYNR1: ReadWrite), + (0x0070 => IPAFAR: ReadWrite), + (0x0078 => reserved_3), + (0x0630 => TLBIIPAS2: WriteOnly), + (0x0638 => TLBIIPAS2L: WriteOnly), + (0x0640 => reserved_4), + (0x07F0 => TLBSYNC: WriteOnly), + (0x07F4 => TLBSTATUS: ReadOnly), + (0x07F8 => reserved_5), + (0x0e00 => PMEVCNTRm: ReadWrite), // what about 0xe04~0xe38 + (0x0e3c => reserved_6), + (0x0e80 => PMEVTYPERm: ReadWrite), // what about 0xe84~0xeB8 + (0x0ebc => reserved_7), + (0x0f00 => PMCFGR: ReadOnly), + (0x0f04 => PMCR: ReadWrite), + (0x0f08 => reserved_8), + (0x0f20 => PMCEID0: ReadOnly), + (0x0f24 => PMCEID1: ReadOnly), + (0x0f28 => reserved_9), + (0x0f40 => PMCNTENSET: ReadWrite), + (0x0f44 => PMCNTENCLR: ReadWrite), + (0x0f48 => PMINTENSET: ReadWrite), + (0x0f4c => PMINTENCLR: ReadWrite), + (0x0f50 => PMOVSCLR: ReadWrite), + (0x0f54 => reserved_10), + (0x0f58 => PMOVSSET: ReadWrite), + (0x0f5c => reserved_11), + (0x0fb8 => PMAUTHSTATUS: ReadOnly), + (0x0fbc => reserved_12), + (0x1000 => @END), + } +} + +#[derive(Clone, Copy)] +pub struct SmmuContextBank { + base_addr: usize, +} + +impl core::ops::Deref for SmmuContextBank { + type Target = SmmuStage2TranslationContextBankAddressSpace; + fn deref(&self) -> &Self::Target { + unsafe { &*self.ptr() } + } +} + +impl SmmuContextBank { + pub const fn new(base_addr: usize) -> SmmuContextBank { + SmmuContextBank { base_addr } + } + + pub fn ptr(&self) -> *const SmmuStage2TranslationContextBankAddressSpace { + self.base_addr as *const SmmuStage2TranslationContextBankAddressSpace + } +} + +pub struct SmmuV2 { + pub glb_rs0: Option, + pub glb_rs1: Option, + pub context_s2_idx: usize, + pub context_bank: Vec, + pub context_alloc_bitmap: Option, + + pub smr_num: usize, + pub smr_alloc_bitmap: Option, + pub group_alloc_bitmap: Option, +} + +impl SmmuV2 { + pub const fn new() -> SmmuV2 { + SmmuV2 { + glb_rs0: None, + glb_rs1: None, + context_s2_idx: 0, + context_bank: vec![], + context_alloc_bitmap: None, + smr_num: 0, + smr_alloc_bitmap: None, + group_alloc_bitmap: None, + } + } + + pub fn init(&mut self) { + let smmu_base_addr = PLAT_DESC.arch_desc.smmu_desc.base + 0x8_0000_0000; + + self.glb_rs0 = Some(SmmuGlbRS0::new(smmu_base_addr)); + let rs0 = self.glb_rs0.as_ref().unwrap(); + /* IDR1 */ + let idr1 = rs0.IDR1.get() as usize; + let page_size = if (idr1 & SMMUV2_IDR1_PAGESIZE_BIT) == 0 { + 0x1000 + } else { + 0x10000 + }; + + self.glb_rs1 = Some(SmmuGlbRS1::new(smmu_base_addr + page_size)); + let num_pages = 1 << (1 + bit_extract(idr1, SMMUV2_IDR1_NUMPAGEDXB_OFF, SMMUV2_IDR1_NUMPAGEDXB_LEN)); + let context_bank_num = bit_extract(idr1, SMMUV2_IDR1_NUMCB_OFF, SMMUV2_IDR1_NUMCB_LEN); + let context_base = smmu_base_addr + num_pages * page_size; + for i in 0..context_bank_num { + self.context_bank + .push(SmmuContextBank::new(context_base + page_size * i)); + } + let stage2_context_bank_num = bit_extract(idr1, SMMUV2_IDR1_NUMS2CB_OFF, SMMUV2_IDR1_NUMS2CB_LEN); + // TODO: not a good way to seperate context bank into 2 parts, + // one for VMs, one for hypervisor + self.context_s2_idx = context_bank_num - VM_NUM_MAX; + self.context_alloc_bitmap = Some(FlexBitmap::new(context_bank_num)); + + self.check_features(); + + // NUMSMRG: Number of Stream Mapping Register Groups + // Indicates the number of Stream mapping register groups in the Stream match table, in the range 0-128. + let smr_num = rs0.IDR0.get() as usize & 0xff; + self.smr_num = smr_num; + self.smr_alloc_bitmap = Some(FlexBitmap::new(smr_num)); + self.group_alloc_bitmap = Some(FlexBitmap::new(smr_num)); + + /* Clear random reset state. */ + rs0.GFSR.set(rs0.GFSR.get()); + rs0.NSGFSR.set(rs0.NSGFSR.get()); + + println!( + concat!( + "SMMU info:\n", + " page size {:#x}, num pages {}, context base {:#x}\n", + " stream matching with {} register groups\n", + " {} context banks ({} stage-2 only)" + ), + page_size, num_pages, context_base, smr_num, context_bank_num, stage2_context_bank_num, + ); + + for i in 0..smr_num { + rs0.SMR[i].set(0); + } + for i in 0..context_bank_num { + self.context_bank[i].SCTLR.set(0); + self.context_bank[i].FSR.set(u32::MAX); + } + + /* Enable IOMMU. */ + let mut cr0 = rs0.CR0.get() as usize; + cr0 &= (0x3 << 30) | (0x1 << 11); + // fault and interrupt configration + cr0 |= SMMUV2_CR0_USFCFG | SMMUV2_CR0_SMCFCFG; + cr0 |= SMMUV2_CR0_GFRE | SMMUV2_CR0_GFIE | SMMUV2_CR0_GCFGFRE | SMMUV2_CR0_GCFGFIE; + cr0 &= !SMMUV2_CR0_CLIENTPD; + rs0.CR0.set(cr0 as u32); + } + + pub fn check_features(&self) { + let glb_rs0 = self.glb_rs0.as_ref().unwrap(); + let version = bit_extract(glb_rs0.IDR7.get() as usize, 4, 4); + if version != 2 { + panic!("smmu unspoorted version: {}", version); + } + + if glb_rs0.IDR0.get() as usize & SMMUV2_IDR0_S2TS_BIT == 0 { + panic!("smmuv2 does not support 2nd stage translation"); + } else { + if glb_rs0.IDR0.get() as usize & SMMUV2_IDR0_NTS_BIT == 0 { + panic!("smmuv2 does not support Nested Translation (Stage 1 followed by stage 2 translation)"); + } + } + + if glb_rs0.IDR0.get() as usize & SMMUV2_IDR0_SMS_BIT == 0 { + panic!("smmuv2 does not support stream match"); + } + + /** + * TODO: the most common smmuv2 implementation (mmu-500) does not provide + * ptw coherency. So we must add some mechanism software-managed + * coherency mechanism for the vms using the smmu according to the + * result of this feature test. + */ + if glb_rs0.IDR0.get() as usize & SMMUV2_IDR0_CTTW_BIT == 0 { + warn!("smmuv2 does not support coherent page table walks"); + } + + if glb_rs0.IDR0.get() as usize & SMMUV2_IDR0_BTM_BIT == 0 { + panic!("smmuv2 does not support tlb maintenance broadcast"); + } + + if glb_rs0.IDR2.get() as usize & SMMUV2_IDR2_PTFSV8_4KB_BIT == 0 { + panic!("smmuv2 does not support 4kb page granule"); + } + + let pasize = bit_extract(glb_rs0.IDR2.get() as usize, 4, 4); + let ipasize = bit_extract(glb_rs0.IDR2.get() as usize, 0, 4); + + let mut parange = cortex_a::registers::ID_AA64MMFR0_EL1.get() as usize; + parange = parange & bit_extract(parange, 0, 4); + if (pasize as isize) < (parange as isize) { + panic!("smmuv2 does not support the full available pa range") + } + if (ipasize as isize) < (parange as isize) { + panic!("smmuv2 does not support the full available ipa range") + } + } + + #[inline] + fn smr_is_group(&self, smr: usize) -> bool { + self.group_alloc_bitmap.as_ref().unwrap().get(smr) == 1 + } + + #[inline] + fn smr_get_context(&self, smr: usize) -> usize { + bit_extract( + self.glb_rs0.as_ref().unwrap().S2CR[smr].get() as usize, + S2CR_CBNDX_OFF, + S2CR_CBNDX_LEN, + ) + } + + #[inline] + fn smr_get_id(&self, smr: usize) -> u16 { + bit_extract( + self.glb_rs0.as_ref().unwrap().SMR[smr].get() as usize, + SMMU_SMR_ID_OFF, + SMMU_SMR_ID_LEN, + ) as u16 + } + + #[inline] + fn smr_get_mask(&self, smr: usize) -> u16 { + bit_extract( + self.glb_rs0.as_ref().unwrap().SMR[smr].get() as usize, + SMMU_SMR_MASK_OFF, + SMMU_SMR_MASK_LEN, + ) as u16 + } + + pub fn alloc_smr(&self) -> Option { + let alloc_bitmap = self.smr_alloc_bitmap.as_ref().unwrap(); + for i in 0..alloc_bitmap.vec_len() { + if alloc_bitmap.get(i) == 0 { + return Some(i); + } + } + None + } + + pub fn compatible_smr_exists(&mut self, mask: u16, id: u16, context_id: usize, group: bool) -> bool { + for smr in 0..self.smr_num { + let bit = self.smr_alloc_bitmap.as_ref().unwrap().get(smr); + if bit == 0 { + continue; + } else { + let smr_mask = self.smr_get_mask(smr); + let mask_r = smr_mask & mask; + let diff_id = (self.smr_get_id(smr) ^ id) & !(mask | smr_mask); + if diff_id != 0 { + if group + || (self.smr_is_group(smr) && (mask_r == mask || mask_r == smr_mask)) + || (context_id == self.smr_get_context(smr)) + { + if mask > smr_mask { + self.smr_alloc_bitmap.as_mut().unwrap().set(smr, false); + } else { + return true; + } + } else { + panic!("SMMU smr conflict"); + } + } + } + } + false + } + + pub fn write_smr(&mut self, smr: usize, mask: u16, id: u16, group: bool) { + if self.smr_alloc_bitmap.as_ref().unwrap().get(smr) != 0 { + panic!("smmu: trying to write unallocated smr {}", smr); + } else { + let mut val: usize = (mask as usize) << SMMU_SMR_MASK_OFF; + val |= (id & bit_mask!(SMMU_SMR_ID_OFF, SMMU_SMR_ID_LEN)) as usize; + val |= SMMUV2_SMR_VALID; + self.glb_rs0.as_ref().unwrap().SMR[smr].set(val as u32); + if group { + self.group_alloc_bitmap.as_mut().unwrap().set(smr, true); + } + } + } + + // Stream-to-Context + pub fn write_s2c(&mut self, smr: usize, context_id: usize) { + if self.smr_alloc_bitmap.as_ref().unwrap().get(smr) != 0 { + panic!("smmu: trying to write unallocated s2c {}", smr); + } else { + let mut s2cr: usize = self.glb_rs0.as_ref().unwrap().S2CR[smr].get() as usize; + s2cr &= bit_mask!(S2CR_IMPL_OFF, S2CR_IMPL_LEN); + s2cr |= S2CR_DFLT; + s2cr |= context_id & bit_mask!(S2CR_CBNDX_OFF, S2CR_CBNDX_LEN); + + self.glb_rs0.as_ref().unwrap().S2CR[smr].set(s2cr as u32); + } + } + + pub fn alloc_ctxbnk(&mut self) -> Option { + let bitmap = match &mut self.context_alloc_bitmap { + None => panic!("smmu_alloc_ctxbnk: smmu v2 context_alloc_bitmap not init"), + Some(bitmap) => bitmap, + }; + for i in self.context_s2_idx..self.context_bank.len() { + if bitmap.get(i) == 0 { + bitmap.set(i, true); + return Some(i); + } + } + warn!("smmu_alloc_ctxbnk: cannot alloc ctxbnk"); + None + } + + pub fn write_ctxbnk(&mut self, context_id: usize, root_pt: usize, vm_id: usize) { + if self.context_alloc_bitmap.is_none() || self.context_alloc_bitmap.as_ref().unwrap().get(context_id) == 0 { + panic!("smmu ctx {} not allocated", context_id); + } + let rs1 = self.glb_rs1.as_ref().unwrap(); + // Set type as stage 2 only. + rs1.CBAR[context_id].set((vm_id as u32) & 0xFF); + rs1.CBA2R[context_id].set(1); // CBA2R_RW64_64BIT + + let ps = 1; // PASize, 36-bit + let t0sz = 28; + let tcr = ((ps & 0x7) << SMMUV2_TCR_PS_OFF) + | (t0sz & 0x1F) + | SMMUV2_TCR_TG0_4K + | SMMUV2_TCR_ORGN0_WB_RA_WA + | SMMUV2_TCR_IRGN0_WB_RA_WA + | SMMUV2_TCR_SH0_IS + | SMMUV2_TCR_SL0_1; + self.context_bank[context_id].TCR.set(tcr as u32); + self.context_bank[context_id] + .TTBR0 + .set((root_pt & bit_mask!(12, SMMUV2_CB_TTBA_END - 12)) as u64); + info!( + "write smmu cb[{}] TTBR0 {:#x}, vm[{}] root_pt {:#x}", + context_id, + self.context_bank[context_id].TTBR0.get(), + vm_id, + root_pt + ); + let mut sctlr = self.context_bank[context_id].SCTLR.get() as usize; + sctlr = (sctlr) & (0xF << 28 | 0x1 << 20 | 0xF << 9 | 0x1 << 11); + sctlr |= SMMUV2_SCTLR_CFRE | SMMUV2_SCTLR_CFIE | SMMUV2_SCTLR_M; + self.context_bank[context_id].SCTLR.set(sctlr as u32); + } +} + +pub static SMMU_V2: Mutex = Mutex::new(SmmuV2::new()); + +pub fn smmu_init() { + let mut smmu = SMMU_V2.lock(); + smmu.init(); +} + +pub fn smmu_vm_init(vm: Vm) -> bool { + let mut smmu_v2 = SMMU_V2.lock(); + match smmu_v2.alloc_ctxbnk() { + Some(context_id) => { + smmu_v2.write_ctxbnk(context_id, vm.pt_dir(), vm.id()); + vm.set_iommu_ctx_id(context_id); + true + } + None => panic!("iommu: smmuv2 could not allocate ctx for vm[{}]", vm.id()), + } +} + +pub fn smmu_add_device(context_id: usize, stream_id: usize) -> bool { + let mut smmu_v2 = SMMU_V2.lock(); + let prep_id = (stream_id & bit_mask!(SMMU_SMR_ID_OFF, SMMU_SMR_ID_LEN)) as u16; + + if !smmu_v2.compatible_smr_exists(0, prep_id, context_id, false) { + match smmu_v2.alloc_smr() { + Some(smr) => { + smmu_v2.write_smr(smr, 0, prep_id, false); + smmu_v2.write_s2c(smr, context_id); + } + _ => { + warn!("smmu_add_device: smmuv2 no more free sme available."); + return false; + } + } + } + true +} + +fn emu_smmu_revise_cbar(emu_ctx: &EmuContext) { + let smmu_v2 = SMMU_V2.lock(); + + let cbar_addr = smmu_v2.glb_rs1.as_ref().unwrap().CBAR.as_ptr() as usize; + let context_id = (emu_ctx.address - (cbar_addr - 0x8_0000_0000)) / size_of::(); + let vm_context_id = active_vm().unwrap().iommu_ctx_id(); + debug!( + "emu_smmu_revise_cbar: vm {} access context id {}, vm context is {}", + active_vm_id(), + context_id, + vm_context_id + ); + + let mut cbar = SMMUV2_CBAR_TYPE_S1_S2; + // stage 2 context bank index + // The SMMUv2 manual suggests that we should use identical VMID for both stages' CBAR + cbar |= (vm_context_id & 0xFF) << 8; + cbar |= active_vm_id() & 0xFF; + smmu_v2.glb_rs1.as_ref().unwrap().CBAR[context_id].set(cbar as u32); +} + +pub fn emu_smmu_handler(_emu_dev_id: usize, emu_ctx: &EmuContext) -> bool { + let address = emu_ctx.address; + let smmu_v2 = SMMU_V2.lock(); + + let mut permit_write = true; + let cbar = &smmu_v2.glb_rs1.as_ref().unwrap().CBAR; + if cbar.as_ptr_range().contains(&((address + 0x8_0000_0000) as *const _)) && emu_ctx.write { + drop(smmu_v2); + emu_smmu_revise_cbar(emu_ctx); + return true; + } else if address + 0x8_0000_0000 >= smmu_v2.context_bank[smmu_v2.context_s2_idx].base_addr { + // Forbid writing hypervisor's context banks. + permit_write = false; + } + + if !emu_ctx.write { + let val = if emu_ctx.width > 4 { + unsafe { ptr::read_volatile((address + 0x8_0000_0000) as *const usize) } + } else { + unsafe { ptr::read_volatile((address + 0x8_0000_0000) as *const u32) as usize } + }; + current_cpu().set_gpr(emu_ctx.reg, val); + } else { + let val = current_cpu().get_gpr(emu_ctx.reg); + if permit_write { + if emu_ctx.width > 4 { + unsafe { ptr::write_volatile((address + 0x8_0000_0000) as *mut usize, val) }; + } else { + unsafe { ptr::write_volatile((address + 0x8_0000_0000) as *mut u32, val as u32) }; + }; + } else { + info!( + "emu_smmu_handler: vm {} is not allowed to access context[{}]", + active_vm_id(), + (address - (smmu_v2.context_bank[0].base_addr as usize - 0x8_0000_0000)) / 0x10000, + ); + } + } + + true +} diff --git a/src/arch/aarch64/start.S b/src/arch/aarch64/start.S new file mode 100644 index 0000000000000000000000000000000000000000..3bbd8338d032d736d39cd0066e61a596ee4543c5 --- /dev/null +++ b/src/arch/aarch64/start.S @@ -0,0 +1,195 @@ +.section .text.boot + +.global _start +_start: + mov x20, x0 +// #ifdef PLATFORM_TX2 + mrs x0, mpidr_el1 + and x1, x0, #0x100 + cbz x1, 1f + and x0, x0, #3 + b 2f +1: wfe + b 1b + +// #endif +// #ifdef PLATFORM_QEMU +// mrs x0, mpidr_el1 +// and x0, x0, #7 +// #endif + +2: /* + * only cluster 1 cpu 0,1,2,3 reach here + * x0 holds core_id (indexed from zero) + */ + + // disable cache and MMU + mrs x1, sctlr_el2 + bic x1, x1, #0xf + msr sctlr_el2, x1 + + mov x19, x0 // save core_id + + // cache_invalidate(0): clear dl1$ + mov x0, #0 + bl cache_invalidate + + // if (core_id == 0) cache_invalidate(2): clear l2$ + cbnz x19, 3f + mov x0, #2 + bl cache_invalidate + +3: + mov x0, x19 // restore core_id + ic iallu // clear icache + + // setup stack sp per core + adrp x1, boot_stack + mov x2, (4096 * 2) + mul x3, x0, x2 + add x1, x1, x2 + add x1, x1, x3 + + mov sp, x1 + + cbnz x0, 5f + + adrp x0, lvl1_page_table + adrp x1, lvl2_page_table + bl pt_populate + + ldr x0, =_bss_begin + ldr x1, =_bss_end + sub x2, x1, x0 + mov x1, xzr + bl memset + +5: + // Trap nothing from EL1 to El2 + mov x3, xzr + msr cptr_el2, x3 + + adrp x0, lvl1_page_table + bl mmu_init + + mov x0, x19 + bl cpu_map_self + msr ttbr0_el2, x0 + + ldr x0, =(0x80080019) + msr hcr_el2, x0 + + mov x1, 1 + msr spsel, x1 + ldr x1, =CPU + add x1, x1, #(0x4000 + (4096 * 128)) + sub x1, x1, #0x110 + mov sp, x1 + + ldr x1, =vectors + msr vbar_el2, x1 + + + mov x0, x19 + ldr x3, =init + + + ldr x2, =(0x30c51835) + msr sctlr_el2, x2 + + tlbi alle2 + dsb nsh + isb + + mov x1, x20 + br x3 + +/* + * snipet from "Application Note Bare-metal Boot Code for ARMv8-A + * Processors - Version 1.0" + * + * x0 - cache level to be invalidated (0 - dl1$, 1 - il1$, 2 - l2$) + */ +cache_invalidate: + msr csselr_el1, x0 + mrs x4, ccsidr_el1 // read cache size id. + and x1, x4, #0x7 + add x1, x1, #0x4 // x1 = cache line size. + ldr x3, =0x7fff + and x2, x3, x4, lsr #13 // x2 = cache set number – 1. + ldr x3, =0x3ff + and x3, x3, x4, lsr #3 // x3 = cache associativity number – 1. + clz w4, w3 // x4 = way position in the cisw instruction. + mov x5, #0 // x5 = way counter way_loop. +way_loop: + mov x6, #0 // x6 = set counter set_loop. +set_loop: + lsl x7, x5, x4 + orr x7, x0, x7 // set way. + lsl x8, x6, x1 + orr x7, x7, x8 // set set. + dc cisw, x7 // clean and invalidate cache line. + add x6, x6, #1 // increment set counter. + cmp x6, x2 // last set reached yet? + ble set_loop // if not, iterate set_loop, + add x5, x5, #1 // else, next way. + cmp x5, x3 // last way reached yet? + ble way_loop // if not, iterate way_loop + ret + +.global update_request +update_request: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + adr x2, . // read pc to x2 + mov x3, #0x8a000000 + cmp x2, x3 + bgt 1f + bl live_update +1: + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +live_update: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + adr x2, . // read pc to x0 + sub x2, x2, #16 // sub str instruction + mov x3, #0x7000000 // 0x83000000 + 0x7000000 + add x2, x2, x3 + blr x2 + + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +.align 12 +.section .data.boot +boot_stack: + .space 4096 * 16 +boot_stack_top: + +.align 12 +.global lvl1_page_table +lvl1_page_table: + .space 4096 + +.align 12 +.global lvl2_page_table +lvl2_page_table: + .space 4096 + +.align 3 +_barrier: + .quad 0 diff --git a/src/arch/aarch64/start_pi4.S b/src/arch/aarch64/start_pi4.S new file mode 100644 index 0000000000000000000000000000000000000000..e2002639368afb7690ee5247a6a53804bd84400b --- /dev/null +++ b/src/arch/aarch64/start_pi4.S @@ -0,0 +1,183 @@ +.section .text.boot + +.global _start +_start: + mov x20, x0 // save fdt pointer to x20 + mrs x0, mpidr_el1 + and x0, x0, #7 + +2: /* + * only cluster 1 cpu 0,1,2,3 reach here + * x0 holds core_id (indexed from zero) + */ + + // disable cache and MMU + mrs x1, sctlr_el2 + bic x1, x1, #0xf + msr sctlr_el2, x1 + + mov x19, x0 // save core_id + + // cache_invalidate(0): clear dl1$ + mov x0, #0 + bl cache_invalidate + + // if (core_id == 0) cache_invalidate(2): clear l2$ + cbnz x19, 3f + mov x0, #2 + bl cache_invalidate + +3: + mov x0, x19 // restore core_id + ic iallu // clear icache + + // setup stack sp per core + adrp x1, boot_stack + mov x2, (4096 * 2) + mul x3, x0, x2 + add x1, x1, x3 + add x1, x1, x2 + + adrp x1, boot_stack_top + mov sp, x1 + + cbnz x0, 5f + + ldr x0, =_bss_begin + ldr x1, =_bss_end + sub x2, x1, x0 + mov x1, xzr + bl memset + + adrp x0, lvl1_page_table + adrp x1, lvl2_page_table + ldr x2, =_bss_begin + ldr x3, =_bss_end + bl pt_populate +5: + // Trap nothing from EL1 to El2 + mov x3, xzr + msr cptr_el2, x3 + + adrp x0, lvl1_page_table + bl mmu_init + + mov x0, x19 + bl cpu_map_self + msr ttbr0_el2, x0 + + ldr x0, =(0x80080019) + msr hcr_el2, x0 + + mov x1, 1 + msr spsel, x1 + ldr x1, =CPU + add x1, x1, #(0x4000 + (4096 * 128)) + sub x1, x1, #0x110 + mov sp, x1 + + ldr x1, =vectors + msr vbar_el2, x1 + + mov x0, x19 + ldr x3, =init + + ldr x2, =(0x30c51835) + msr sctlr_el2, x2 + + tlbi alle2 + dsb nsh + isb + + mov x1, x20 + br x3 + +/* + * snipet from "Application Note Bare-metal Boot Code for ARMv8-A + * Processors - Version 1.0" + * + * x0 - cache level to be invalidated (0 - dl1$, 1 - il1$, 2 - l2$) + */ +cache_invalidate: + msr csselr_el1, x0 + mrs x4, ccsidr_el1 // read cache size id. + and x1, x4, #0x7 + add x1, x1, #0x4 // x1 = cache line size. + ldr x3, =0x7fff + and x2, x3, x4, lsr #13 // x2 = cache set number – 1. + ldr x3, =0x3ff + and x3, x3, x4, lsr #3 // x3 = cache associativity number – 1. + clz w4, w3 // x4 = way position in the cisw instruction. + mov x5, #0 // x5 = way counter way_loop. +way_loop: + mov x6, #0 // x6 = set counter set_loop. +set_loop: + lsl x7, x5, x4 + orr x7, x0, x7 // set way. + lsl x8, x6, x1 + orr x7, x7, x8 // set set. + dc cisw, x7 // clean and invalidate cache line. + add x6, x6, #1 // increment set counter. + cmp x6, x2 // last set reached yet? + ble set_loop // if not, iterate set_loop, + add x5, x5, #1 // else, next way. + cmp x5, x3 // last way reached yet? + ble way_loop // if not, iterate way_loop + ret + +.global update_request +update_request: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + adr x2, . // read pc to x2 + mov x3, #0x8a000000 + cmp x2, x3 + bgt 1f + bl live_update +1: + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +live_update: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + adr x2, . // read pc to x0 + sub x2, x2, #16 // sub str instruction + mov x3, #0x5000000 + add x2, x2, x3 + blr x2 + + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +.align 12 +.section .data.boot +boot_stack: + .space 4096 * 8 +boot_stack_top: + +.align 12 +.global lvl1_page_table +lvl1_page_table: + .space 4096 + +.align 12 +.global lvl2_page_table +lvl2_page_table: + .space 4096 + +.align 3 +_barrier: + .quad 0 diff --git a/src/arch/aarch64/start_qemu.S b/src/arch/aarch64/start_qemu.S new file mode 100644 index 0000000000000000000000000000000000000000..a55c1d30910de34f78e96f3c3fea39cc4243714b --- /dev/null +++ b/src/arch/aarch64/start_qemu.S @@ -0,0 +1,192 @@ +.section .text.boot + +.global _start +_start: + mov x20, x0 +// #ifdef PLATFORM_TX2 + mrs x0, mpidr_el1 + and x1, x0, #0x100 + cbz x1, 1f + and x0, x0, #3 + b 2f +1: wfe + b 1b + +// #endif +// #ifdef PLATFORM_QEMU + mrs x0, mpidr_el1 + and x0, x0, #7 +// #endif + +2: /* + * only cluster 1 cpu 0,1,2,3 reach here + * x0 holds core_id (indexed from zero) + */ + + // disable cache and MMU + mrs x1, sctlr_el2 + bic x1, x1, #0xf + msr sctlr_el2, x1 + + mov x19, x0 // save core_id + + // cache_invalidate(0): clear dl1$ + mov x0, #0 + bl cache_invalidate + + // if (core_id == 0) cache_invalidate(2): clear l2$ + cbnz x19, 3f + mov x0, #2 + bl cache_invalidate + +3: + mov x0, x19 // restore core_id + ic iallu // clear icache + + // setup stack sp per core + adrp x1, boot_stack + mov x2, (4096 * 2) + mul x3, x0, x2 + add x1, x1, x2 + add x1, x1, x3 + + mov sp, x1 + + cbnz x0, 5f + + adrp x0, lvl1_page_table + adrp x1, lvl2_page_table + bl pt_populate + + ldr x0, =_bss_begin + ldr x1, =_bss_end + sub x2, x1, x0 + mov x1, xzr + bl memset + +5: + // Trap nothing from EL1 to El2 + mov x3, xzr + msr cptr_el2, x3 + + adrp x0, lvl1_page_table + bl mmu_init + + mov x0, x19 + bl cpu_map_self + msr ttbr0_el2, x0 + + ldr x0, =(0x80080019) + msr hcr_el2, x0 + + mov x1, 1 + msr spsel, x1 + ldr x1, =CPU + add x1, x1, #(0x4000 + (4096 * 128)) + sub x1, x1, #0x110 + mov sp, x1 + + ldr x1, =vectors + msr vbar_el2, x1 + + + mov x0, x19 + ldr x3, =init + + + ldr x2, =(0x30c51835) + msr sctlr_el2, x2 + + tlbi alle2 + dsb nsh + isb + + mov x1, x20 + br x3 + +/* + * snipet from "Application Note Bare-metal Boot Code for ARMv8-A + * Processors - Version 1.0" + * + * x0 - cache level to be invalidated (0 - dl1$, 1 - il1$, 2 - l2$) + */ +cache_invalidate: + msr csselr_el1, x0 + mrs x4, ccsidr_el1 // read cache size id. + and x1, x4, #0x7 + add x1, x1, #0x4 // x1 = cache line size. + ldr x3, =0x7fff + and x2, x3, x4, lsr #13 // x2 = cache set number – 1. + ldr x3, =0x3ff + and x3, x3, x4, lsr #3 // x3 = cache associativity number – 1. + clz w4, w3 // x4 = way position in the cisw instruction. + mov x5, #0 // x5 = way counter way_loop. +way_loop: + mov x6, #0 // x6 = set counter set_loop. +set_loop: + lsl x7, x5, x4 + orr x7, x0, x7 // set way. + lsl x8, x6, x1 + orr x7, x7, x8 // set set. + dc cisw, x7 // clean and invalidate cache line. + add x6, x6, #1 // increment set counter. + cmp x6, x2 // last set reached yet? + ble set_loop // if not, iterate set_loop, + add x5, x5, #1 // else, next way. + cmp x5, x3 // last way reached yet? + ble way_loop // if not, iterate way_loop + ret + +// TODO: need to support multi update +.global update_request +update_request: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + adr x2, . // read pc to x2 + mov x3, #0x8a000000 + cmp x2, x3 + blt 1f + bl live_update +1: + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +live_update: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + bl rust_shyper_update + + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +.align 12 +.section .data.boot +boot_stack: + .space 4096 * 16 +boot_stack_top: + +.align 12 +.global lvl1_page_table +lvl1_page_table: + .space 4096 + +.align 12 +.global lvl2_page_table +lvl2_page_table: + .space 4096 + +.align 3 +_barrier: + .quad 0 diff --git a/src/arch/aarch64/start_update.S b/src/arch/aarch64/start_update.S new file mode 100644 index 0000000000000000000000000000000000000000..77b3b7da8e8decf6d5ca7d1177f272c6419c462e --- /dev/null +++ b/src/arch/aarch64/start_update.S @@ -0,0 +1,192 @@ +.section .text.boot + +.global _start +_start: + mov x20, x0 +// #ifdef PLATFORM_TX2 + mrs x0, mpidr_el1 + and x1, x0, #0x100 + cbz x1, 1f + and x0, x0, #3 + b 2f +1: wfe + b 1b + +// #endif +// #ifdef PLATFORM_QEMU +// mrs x0, mpidr_el1 +// and x0, x0, #7 +// #endif + +2: /* + * only cluster 1 cpu 0,1,2,3 reach here + * x0 holds core_id (indexed from zero) + */ + + // disable cache and MMU + mrs x1, sctlr_el2 + bic x1, x1, #0xf + msr sctlr_el2, x1 + + mov x19, x0 // save core_id + + // cache_invalidate(0): clear dl1$ + mov x0, #0 + bl cache_invalidate + + // if (core_id == 0) cache_invalidate(2): clear l2$ + cbnz x19, 3f + mov x0, #2 + bl cache_invalidate + +3: + mov x0, x19 // restore core_id + ic iallu // clear icache + + // setup stack sp per core + adrp x1, boot_stack + mov x2, (4096 * 2) + mul x3, x0, x2 + add x1, x1, x2 + add x1, x1, x3 + + mov sp, x1 + + cbnz x0, 5f + + adrp x0, lvl1_page_table + adrp x1, lvl2_page_table + bl pt_populate + + ldr x0, =_bss_begin + ldr x1, =_bss_end + sub x2, x1, x0 + mov x1, xzr + bl memset + +5: + // Trap nothing from EL1 to El2 + mov x3, xzr + msr cptr_el2, x3 + + adrp x0, lvl1_page_table + bl mmu_init + + mov x0, x19 + bl cpu_map_self + msr ttbr0_el2, x0 + + ldr x0, =(0x80080019) + msr hcr_el2, x0 + + mov x1, 1 + msr spsel, x1 + ldr x1, =CPU + add x1, x1, #(0x4000 + (4096 * 128)) + sub x1, x1, #0x110 + mov sp, x1 + + ldr x1, =vectors + msr vbar_el2, x1 + + + mov x0, x19 + ldr x3, =init + + + ldr x2, =(0x30c51835) + msr sctlr_el2, x2 + + tlbi alle2 + dsb nsh + isb + + mov x1, x20 + br x3 + +/* + * snipet from "Application Note Bare-metal Boot Code for ARMv8-A + * Processors - Version 1.0" + * + * x0 - cache level to be invalidated (0 - dl1$, 1 - il1$, 2 - l2$) + */ +cache_invalidate: + msr csselr_el1, x0 + mrs x4, ccsidr_el1 // read cache size id. + and x1, x4, #0x7 + add x1, x1, #0x4 // x1 = cache line size. + ldr x3, =0x7fff + and x2, x3, x4, lsr #13 // x2 = cache set number – 1. + ldr x3, =0x3ff + and x3, x3, x4, lsr #3 // x3 = cache associativity number – 1. + clz w4, w3 // x4 = way position in the cisw instruction. + mov x5, #0 // x5 = way counter way_loop. +way_loop: + mov x6, #0 // x6 = set counter set_loop. +set_loop: + lsl x7, x5, x4 + orr x7, x0, x7 // set way. + lsl x8, x6, x1 + orr x7, x7, x8 // set set. + dc cisw, x7 // clean and invalidate cache line. + add x6, x6, #1 // increment set counter. + cmp x6, x2 // last set reached yet? + ble set_loop // if not, iterate set_loop, + add x5, x5, #1 // else, next way. + cmp x5, x3 // last way reached yet? + ble way_loop // if not, iterate way_loop + ret + +// TODO: need to support multi update +.global update_request +update_request: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + adr x2, . // read pc to x2 + mov x3, #0x8a000000 + cmp x2, x3 + blt 1f + bl live_update +1: + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +live_update: + sub sp, sp, #40 + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + str x30, [sp, #32] + + bl rust_shyper_update + + ldr x30, [sp, #32] + ldp x2, x3, [sp, #16] + ldp x0, x1, [sp, #0] + add sp, sp, #40 + ret + +.align 12 +.section .data.boot +boot_stack: + .space 4096 * 16 +boot_stack_top: + +.align 12 +.global lvl1_page_table +lvl1_page_table: + .space 4096 + +.align 12 +.global lvl2_page_table +lvl2_page_table: + .space 4096 + +.align 3 +_barrier: + .quad 0 diff --git a/src/arch/aarch64/sync.rs b/src/arch/aarch64/sync.rs new file mode 100644 index 0000000000000000000000000000000000000000..29cd3a59febb7016f77f48d9e9a4da15fbb9b15d --- /dev/null +++ b/src/arch/aarch64/sync.rs @@ -0,0 +1,141 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::{ + exception_data_abort_access_is_sign_ext, exception_data_abort_access_is_write, exception_data_abort_access_reg, + exception_data_abort_access_reg_width, exception_data_abort_access_width, exception_data_abort_handleable, + exception_data_abort_is_permission_fault, exception_data_abort_is_translate_fault, exception_iss, +}; +use crate::arch::{exception_esr, exception_fault_addr}; +use crate::arch::exception_next_instruction_step; +use crate::arch::smc_guest_handler; +use crate::device::{emu_handler, EmuContext}; +use crate::kernel::{active_vm, current_cpu, hvc_guest_handler, migrate_data_abort_handler}; + +pub const HVC_RETURN_REG: usize = 0; + +pub fn data_abort_handler() { + // let time0 = time_current_us(); + let emu_ctx = EmuContext { + address: exception_fault_addr(), + width: exception_data_abort_access_width(), + write: exception_data_abort_access_is_write(), + sign_ext: exception_data_abort_access_is_sign_ext(), + reg: exception_data_abort_access_reg(), + reg_width: exception_data_abort_access_reg_width(), + }; + let elr = current_cpu().get_elr(); + + if !exception_data_abort_handleable() { + panic!( + "Core {} data abort not handleable 0x{:x}, esr 0x{:x}", + current_cpu().id, + exception_fault_addr(), + exception_esr() + ); + } + + if !exception_data_abort_is_translate_fault() { + if exception_data_abort_is_permission_fault() { + // println!( + // "write {}, width {}, reg width {}, addr {:x}, iss {:x}, reg idx {}, reg val 0x{:x}, esr 0x{:x}", + // exception_data_abort_access_is_write(), + // emu_ctx.width, + // emu_ctx.reg_width, + // emu_ctx.address, + // exception_iss(), + // emu_ctx.reg, + // current_cpu().get_gpr(emu_ctx.reg), + // exception_esr() + // ); + migrate_data_abort_handler(&emu_ctx); + // no need to rewrite elr + + // let time1 = time_current_us(); + // println!("migrate_data_abort_handler: {}us", time1 - time0); + return; + } else { + panic!( + "Core {} data abort is not translate fault 0x{:x}", + current_cpu().id, + exception_fault_addr(), + ); + } + } + if !emu_handler(&emu_ctx) { + active_vm().unwrap().show_pagetable(emu_ctx.address); + println!( + "write {}, width {}, reg width {}, addr {:x}, iss {:x}, reg idx {}, reg val 0x{:x}, esr 0x{:x}", + exception_data_abort_access_is_write(), + emu_ctx.width, + emu_ctx.reg_width, + emu_ctx.address, + exception_iss(), + emu_ctx.reg, + current_cpu().get_gpr(emu_ctx.reg), + exception_esr() + ); + panic!( + "data_abort_handler: Failed to handler emul device request, ipa 0x{:x} elr 0x{:x}", + emu_ctx.address, elr + ); + } + let val = elr + exception_next_instruction_step(); + current_cpu().set_elr(val); +} + +pub fn smc_handler() { + let fid = current_cpu().get_gpr(0); + let x1 = current_cpu().get_gpr(1); + let x2 = current_cpu().get_gpr(2); + let x3 = current_cpu().get_gpr(3); + + if !smc_guest_handler(fid, x1, x2, x3) { + warn!("smc_handler: unknown fid 0x{:x}", fid); + current_cpu().set_gpr(0, 0); + } + + let elr = current_cpu().get_elr(); + let val = elr + exception_next_instruction_step(); + current_cpu().set_elr(val); +} + +pub fn hvc_handler() { + // let time_start = timer_arch_get_counter(); + let x0 = current_cpu().get_gpr(0); + let x1 = current_cpu().get_gpr(1); + let x2 = current_cpu().get_gpr(2); + let x3 = current_cpu().get_gpr(3); + let x4 = current_cpu().get_gpr(4); + let x5 = current_cpu().get_gpr(5); + let x6 = current_cpu().get_gpr(6); + let mode = current_cpu().get_gpr(7); + + let hvc_type = (mode >> 8) & 0xff; + let event = mode & 0xff; + + match hvc_guest_handler(hvc_type, event, x0, x1, x2, x3, x4, x5, x6) { + Ok(val) => { + current_cpu().set_gpr(HVC_RETURN_REG, val); + } + Err(_) => { + warn!("Failed to handle hvc request fid 0x{:x} event 0x{:x}", hvc_type, event); + current_cpu().set_gpr(HVC_RETURN_REG, usize::MAX); + } + } + // let time_end = timer_arch_get_counter(); + // println!( + // "hvc fid 0x{:x} event 0x{:x} counter {}, freq {:x}", + // hvc_type, + // event, + // time_end - time_start, + // timer_arch_get_frequency() + // ); +} diff --git a/src/arch/aarch64/timer.rs b/src/arch/aarch64/timer.rs new file mode 100644 index 0000000000000000000000000000000000000000..77897301d412de8ebe9d167ca4336051548ce947 --- /dev/null +++ b/src/arch/aarch64/timer.rs @@ -0,0 +1,54 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use spin::Mutex; +use tock_registers::interfaces::*; + +const CTL_IMASK: usize = 1 << 1; + +pub static TIMER_FREQ: Mutex = Mutex::new(0); +pub static TIMER_SLICE: Mutex = Mutex::new(0); // ms + +pub fn timer_arch_set(num: usize) { + let slice_lock = TIMER_SLICE.lock(); + let val = *slice_lock * num; + drop(slice_lock); + msr!(CNTHP_TVAL_EL2, val); +} + +pub fn timer_arch_enable_irq() { + let val = 1; + msr!(CNTHP_CTL_EL2, val, "x"); +} + +pub fn timer_arch_disable_irq() { + let val = 2; + msr!(CNTHP_CTL_EL2, val, "x"); +} + +pub fn timer_arch_get_counter() -> usize { + cortex_a::registers::CNTPCT_EL0.get() as usize +} + +pub fn timer_arch_get_frequency() -> usize { + cortex_a::registers::CNTFRQ_EL0.get() as usize +} + +pub fn timer_arch_init() { + let mut freq_lock = TIMER_FREQ.lock(); + let mut slice_lock = TIMER_SLICE.lock(); + *freq_lock = timer_arch_get_frequency(); + *slice_lock = (*freq_lock) / 1000; // ms + + let ctl = 0x3 & (1 | !CTL_IMASK); + let tval = *slice_lock * 10; + msr!(CNTHP_CTL_EL2, ctl); + msr!(CNTHP_TVAL_EL2, tval); +} diff --git a/src/arch/aarch64/tlb.rs b/src/arch/aarch64/tlb.rs new file mode 100644 index 0000000000000000000000000000000000000000..da90ba0baa7f973f66ed6e134f1c7e7be81ad893 --- /dev/null +++ b/src/arch/aarch64/tlb.rs @@ -0,0 +1,17 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::arch::asm; + +pub fn tlb_invalidate_guest_all() { + unsafe { + asm!("dsb ish", "tlbi vmalls12e1is", "dsb ish", "isb"); + } +} diff --git a/src/arch/aarch64/vcpu.rs b/src/arch/aarch64/vcpu.rs new file mode 100644 index 0000000000000000000000000000000000000000..c359d1c0b79ce88800eb463fb8a5b7fe3846159c --- /dev/null +++ b/src/arch/aarch64/vcpu.rs @@ -0,0 +1,40 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use cortex_a::registers::*; + +use crate::arch::traits::ContextFrameTrait; +use crate::kernel::{Vcpu, Vm}; +use crate::kernel::VmType; + +pub fn vcpu_arch_init(vm: Vm, vcpu: Vcpu) { + let config = vm.config(); + let mut vcpu_inner = vcpu.inner.lock(); + match config.os_type { + VmType::VmTOs => { + vcpu_inner + .vcpu_ctx + .set_argument(config.device_tree_load_ipa()); + } + _ => { + let arg = &config.memory_region()[0]; + vcpu_inner.vcpu_ctx.set_argument(arg.ipa_start + arg.length); + } + } + + vcpu_inner + .vcpu_ctx + .set_exception_pc(config.kernel_entry_point()); + vcpu_inner.vcpu_ctx.spsr = (SPSR_EL1::M::EL1h + + SPSR_EL1::I::Masked + + SPSR_EL1::F::Masked + + SPSR_EL1::A::Masked + + SPSR_EL1::D::Masked).value; +} diff --git a/src/arch/aarch64/vgic.rs b/src/arch/aarch64/vgic.rs new file mode 100644 index 0000000000000000000000000000000000000000..f99b86856627593d8c539dc82427111b28a7fd95 --- /dev/null +++ b/src/arch/aarch64/vgic.rs @@ -0,0 +1,2556 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::collections::{BTreeMap, VecDeque}; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::{arch::GICH, kernel::IpiInitcMessage}; +use crate::board::{PLATFORM_CPU_NUM_MAX, platform_cpuid_to_cpuif}; +use crate::board::PLATFORM_GICD_BASE; +use crate::device::EmuContext; +use crate::device::EmuDevs; +use crate::kernel::{ + active_vcpu_id, current_cpu, restore_vcpu_gic, save_vcpu_gic, VgicCpuPrivData, VgicIntData, VgicMigData, +}; +use crate::kernel::{active_vm, active_vm_id, active_vm_ncpu}; +use crate::kernel::{ipi_intra_broadcast_msg, ipi_send_msg, IpiInnerMsg, IpiMessage, IpiType}; +use crate::kernel::{InitcEvent, Vcpu, Vm, vm}; +use crate::lib::{bit_extract, bit_get, bit_set, bitmap_find_nth, ptr_read_write}; + +use super::gic::*; + +#[derive(Clone)] +struct VgicInt { + inner: Arc>, + pub lock: Arc>, +} + +impl VgicInt { + fn update(&self) -> Self { + let new_this = Self::new(self.id() as usize); + match self.owner() { + Some(vcpu) => { + let vm = vcpu.vm().unwrap(); + new_this.set_owner(vm.vcpu(vcpu.id()).unwrap()); + } + None => {} + }; + let mut inner = new_this.inner.lock(); + inner.id = self.id(); + inner.hw = self.hw(); + inner.in_lr = self.in_lr(); + inner.lr = self.lr(); + inner.enabled = self.enabled(); + inner.state = self.state(); + inner.prio = self.prio(); + inner.targets = self.targets(); + inner.cfg = self.cfg(); + inner.in_pend = self.in_pend(); + inner.in_act = self.in_act(); + drop(inner); + new_this + } + + fn new(id: usize) -> VgicInt { + VgicInt { + inner: Arc::new(Mutex::new(VgicIntInner::new(id))), + lock: Arc::new(Mutex::new(())), + } + } + + pub fn restore_migrate_data( + &self, + int_data: &VgicIntData, + vcpu_list: &Vec, + vcpuid_map: &BTreeMap, + ) { + let mut inner = self.inner.lock(); + inner.owner = match int_data.owner { + None => None, + Some(id) => Some(vcpu_list[id].clone()), + }; + inner.id = int_data.id; + inner.hw = int_data.hw; + inner.in_lr = int_data.in_lr; + inner.enabled = int_data.enabled; + inner.state = int_data.state; + inner.prio = int_data.prio; + inner.targets = { + let mut pcpu_targets = 0; + // println!( + // "restore vgic int {} migrate target data {:x}", + // int_data.id, int_data.targets + // ); + for vcpuid in 0..PLATFORM_CPU_NUM_MAX { + if (1 << vcpuid) & int_data.targets != 0 { + pcpu_targets |= (1 << vcpuid_map[&vcpuid]) as u8; + } + } + pcpu_targets + }; + inner.cfg = int_data.cfg; + inner.in_pend = int_data.in_pend; + inner.in_act = int_data.in_act; + + // TODO: rude + // if inner.enabled { + // let int_id = inner.id as usize; + // GICD.set_enable(int_id, true); + // GICD.set_prio(int_id, inner.prio); + // GICD.set_trgt(int_id, 1 << platform_cpuid_to_cpuif(current_cpu().id)); + // GICD.set_icfgr(int_id, inner.cfg); + // println!( + // "cpuid {} cpuif {:x}", + // current_cpu().id, + // platform_cpuid_to_cpuif(current_cpu().id) + // ); + + // if int_id > 16 { + // println!( + // "restore_migrate_data after: int {} ISENABLER {:x}, ISACTIVER {:x}, IPRIORITY {:x}, ITARGETSR {:x}, ICFGR {:x}", + // int_id, + // GICD.is_enabler(int_id / 32), + // GICD.is_activer(int_id / 32), + // GICD.ipriorityr(int_id / 4), + // GICD.itargetsr(int_id / 4), + // GICD.icfgr(int_id / 2) + // ); + // } + // } + } + + pub fn save_migrate_data(&self, int_data: &mut VgicIntData, cpuid_map: &BTreeMap) { + let inner = self.inner.lock(); + int_data.owner = match &inner.owner { + None => None, + Some(vcpu) => Some(vcpu.id()), + }; + int_data.id = inner.id; + int_data.hw = inner.hw; + int_data.in_lr = inner.in_lr; + int_data.lr = inner.lr; + int_data.enabled = inner.enabled; + int_data.state = inner.state; + int_data.prio = inner.prio; + int_data.targets = { + let mut vcpu_targets = 0; + for pcpuid in 0..PLATFORM_CPU_NUM_MAX { + if (1 << pcpuid) & inner.targets != 0 { + vcpu_targets |= (1 << cpuid_map[&pcpuid]) as u8; + } + } + vcpu_targets + }; + int_data.cfg = inner.cfg; + int_data.in_pend = inner.in_pend; + int_data.in_act = inner.in_act; + // if inner.enabled { + // println!( + // "int {} is enable, state {:#?}, prio {:x}, targets {:x}, in pend {}, int act {}, int cfg {}", + // inner.id, inner.state, inner.prio, inner.targets, inner.in_pend, inner.in_act, inner.cfg + // ); + + // let int_id = inner.id as usize; + // if int_id > 16 { + // println!( + // "int {} ISENABLER {:x}, ISACTIVER {:x}, IPRIORITY {:x}, ITARGETSR {:x}, ICFGR {:x}", + // int_id, + // GICD.is_enabler(int_id / 32), + // GICD.is_activer(int_id / 32), + // GICD.ipriorityr(int_id / 4), + // GICD.itargetsr(int_id / 4), + // GICD.icfgr(int_id / 2) + // ); + // } + // } + } + + // back up for hyper fresh + pub fn fresh_back_up(&self) -> VgicInt { + let inner = self.inner.lock(); + let owner = { + match &inner.owner { + None => None, + Some(vcpu) => { + let vm_id = vcpu.vm_id(); + let vm = vm(vm_id).unwrap(); + vm.vcpu(vcpu.id()) + } + } + }; + VgicInt { + inner: Arc::new(Mutex::new(VgicIntInner { + owner, + id: inner.id, + hw: inner.hw, + in_lr: inner.in_lr, + lr: inner.lr, + enabled: inner.enabled, + state: inner.state, + prio: inner.prio, + targets: inner.targets, + cfg: inner.cfg, + in_pend: inner.in_pend, + in_act: inner.in_act, + })), + lock: Arc::new(Mutex::new(())), + } + } + + fn priv_new(id: usize, owner: Vcpu, targets: usize, enabled: bool) -> VgicInt { + VgicInt { + inner: Arc::new(Mutex::new(VgicIntInner::priv_new(id, owner, targets, enabled))), + lock: Arc::new(Mutex::new(())), + } + } + + fn set_in_pend_state(&self, is_pend: bool) { + let mut vgic_int = self.inner.lock(); + vgic_int.in_pend = is_pend; + } + + fn set_in_act_state(&self, is_act: bool) { + let mut vgic_int = self.inner.lock(); + vgic_int.in_act = is_act; + } + + pub fn in_pend(&self) -> bool { + let vgic_int = self.inner.lock(); + vgic_int.in_pend + } + + pub fn in_act(&self) -> bool { + let vgic_int = self.inner.lock(); + vgic_int.in_act + } + + fn set_enabled(&self, enabled: bool) { + let mut vgic_int = self.inner.lock(); + vgic_int.enabled = enabled; + } + + fn set_lr(&self, lr: u16) { + let mut vgic_int = self.inner.lock(); + vgic_int.lr = lr; + } + + fn set_targets(&self, targets: u8) { + let mut vgic_int = self.inner.lock(); + // if vgic_int.targets == 1 && vgic_int.id == 48 { + // panic!("set targets to {}", targets); + // } + vgic_int.targets = targets; + } + + fn set_prio(&self, prio: u8) { + let mut vgic_int = self.inner.lock(); + vgic_int.prio = prio; + } + + fn set_in_lr(&self, in_lr: bool) { + let mut vgic_int = self.inner.lock(); + vgic_int.in_lr = in_lr; + } + + fn set_state(&self, state: IrqState) { + let mut vgic_int = self.inner.lock(); + vgic_int.state = state; + } + + fn set_owner(&self, owner: Vcpu) { + let mut vgic_int = self.inner.lock(); + vgic_int.owner = Some(owner.clone()); + } + + fn clear_owner(&self) { + let mut vgic_int = self.inner.lock(); + // println!("clear owner get lock"); + vgic_int.owner = None; + } + + fn set_hw(&self, hw: bool) { + let mut vgic_int = self.inner.lock(); + vgic_int.hw = hw; + } + + fn set_cfg(&self, cfg: u8) { + let mut vgic_int = self.inner.lock(); + vgic_int.cfg = cfg; + } + + fn lr(&self) -> u16 { + let vgic_int = self.inner.lock(); + vgic_int.lr + } + + fn in_lr(&self) -> bool { + let vgic_int = self.inner.lock(); + vgic_int.in_lr + } + + fn id(&self) -> u16 { + let vgic_int = self.inner.lock(); + vgic_int.id + } + + fn enabled(&self) -> bool { + let vgic_int = self.inner.lock(); + vgic_int.enabled + } + + fn prio(&self) -> u8 { + let vgic_int = self.inner.lock(); + vgic_int.prio + } + + fn targets(&self) -> u8 { + let vgic_int = self.inner.lock(); + vgic_int.targets + } + + fn hw(&self) -> bool { + let vgic_int = self.inner.lock(); + vgic_int.hw + } + + pub fn state(&self) -> IrqState { + let vgic_int = self.inner.lock(); + vgic_int.state + } + + fn cfg(&self) -> u8 { + let vgic_int = self.inner.lock(); + vgic_int.cfg + } + + fn owner(&self) -> Option { + let vgic_int = self.inner.lock(); + match &vgic_int.owner { + Some(vcpu) => { + return Some(vcpu.clone()); + } + None => { + // println!("vgic_int {} owner vcpu is none", vgic_int.id); + return None; + } + } + } + + fn owner_phys_id(&self) -> Option { + let vgic_int = self.inner.lock(); + match &vgic_int.owner { + Some(owner) => { + return Some(owner.phys_id()); + } + None => { + return None; + } + } + } + + fn owner_id(&self) -> Option { + let vgic_int = self.inner.lock(); + match &vgic_int.owner { + Some(owner) => { + return Some(owner.id()); + } + None => { + println!("owner_id is None"); + return None; + } + } + } + + fn owner_vm_id(&self) -> Option { + let vgic_int = self.inner.lock(); + match &vgic_int.owner { + Some(owner) => { + return Some(owner.vm_id()); + } + None => { + return None; + } + } + } + + fn owner_vm(&self) -> Vm { + let vgic_int = self.inner.lock(); + vgic_int.owner_vm() + } +} + +struct VgicIntInner { + owner: Option, + id: u16, + hw: bool, + in_lr: bool, + lr: u16, + enabled: bool, + state: IrqState, + prio: u8, + targets: u8, + cfg: u8, + + in_pend: bool, + in_act: bool, +} + +impl VgicIntInner { + fn new(id: usize) -> VgicIntInner { + VgicIntInner { + owner: None, + id: (id + GIC_PRIVINT_NUM) as u16, + hw: false, + in_lr: false, + lr: 0, + enabled: false, + state: IrqState::IrqSInactive, + prio: 0xff, + targets: 0, + cfg: 0, + in_pend: false, + in_act: false, + } + } + + fn priv_new(id: usize, owner: Vcpu, targets: usize, enabled: bool) -> VgicIntInner { + VgicIntInner { + owner: Some(owner), + id: id as u16, + hw: false, + in_lr: false, + lr: 0, + enabled, + state: IrqState::IrqSInactive, + prio: 0xff, + targets: targets as u8, + cfg: 0, + in_pend: false, + in_act: false, + } + } + + fn owner_vm(&self) -> Vm { + let owner = self.owner.as_ref().unwrap(); + owner.vm().unwrap() + } +} + +struct Vgicd { + ctlr: u32, + typer: u32, + iidr: u32, + interrupts: Vec, +} + +impl Vgicd { + fn default() -> Vgicd { + Vgicd { + ctlr: 0, + typer: 0, + iidr: 0, + interrupts: Vec::new(), + } + } +} + +#[derive(Clone, Copy)] +pub struct Sgis { + pub pend: u8, + pub act: u8, +} + +impl Sgis { + fn default() -> Sgis { + Sgis { pend: 0, act: 0 } + } +} + +struct VgicCpuPriv { + // gich: GicHypervisorInterfaceBlock, + curr_lrs: [u16; GIC_LIST_REGS_NUM], + sgis: [Sgis; GIC_SGIS_NUM], + interrupts: Vec, + + pend_list: VecDeque, + act_list: VecDeque, +} + +impl VgicCpuPriv { + fn default() -> VgicCpuPriv { + VgicCpuPriv { + curr_lrs: [0; GIC_LIST_REGS_NUM], + sgis: [Sgis::default(); GIC_SGIS_NUM], + interrupts: Vec::new(), + pend_list: VecDeque::new(), + act_list: VecDeque::new(), + } + } + + // use for migration + pub fn restore_migrate_data( + &mut self, + cpu_priv_data: &VgicCpuPrivData, + vcpu_list: &Vec, + vcpuid_map: &BTreeMap, + ) { + self.sgis = cpu_priv_data.sgis; + self.curr_lrs = cpu_priv_data.curr_lrs; + for (idx, int) in self.interrupts.iter_mut().enumerate() { + int.restore_migrate_data(&cpu_priv_data.interrupts[idx], vcpu_list, vcpuid_map); + } + assert_eq!(self.interrupts.len(), cpu_priv_data.interrupts.len()); + } + + // use for migration + pub fn save_migrate_data(&self, cpu_priv_data: &mut VgicCpuPrivData, cpuid_map: &BTreeMap) { + cpu_priv_data.sgis = self.sgis; + cpu_priv_data.curr_lrs = self.curr_lrs; + for (idx, int) in self.interrupts.iter().enumerate() { + int.save_migrate_data(&mut cpu_priv_data.interrupts[idx], cpuid_map); + } + cpu_priv_data.act_num = self.act_list.len(); + for (idx, int) in self.act_list.iter().enumerate() { + cpu_priv_data.act_list[idx] = int.id() as usize; + } + cpu_priv_data.act_num = self.pend_list.len(); + for (idx, int) in self.pend_list.iter().enumerate() { + cpu_priv_data.pend_list[idx] = int.id() as usize; + } + } +} + +pub struct Vgic { + vgicd: Mutex, + cpu_priv: Mutex>, +} + +impl Vgic { + pub fn default() -> Vgic { + Vgic { + vgicd: Mutex::new(Vgicd::default()), + cpu_priv: Mutex::new(Vec::new()), + } + } + + pub fn restore_vgic_data( + &self, + vgic_data: &VgicMigData, + vcpu_list: &Vec, + vcpuid_map: &BTreeMap, + ) { + let mut vgicd = self.vgicd.lock(); + vgicd.ctlr = vgic_data.vgicd.ctlr; + vgicd.typer = vgic_data.vgicd.typer; + vgicd.iidr = vgic_data.vgicd.iidr; + for (idx, int) in vgicd.interrupts.iter().enumerate() { + int.restore_migrate_data(&vgic_data.vgicd.interrupts[idx], vcpu_list, vcpuid_map); + } + let mut cpu_priv_list = self.cpu_priv.lock(); + for idx in 0..vgic_data.cpu_priv_num { + cpu_priv_list[idx].restore_migrate_data(&vgic_data.cpu_priv[idx], vcpu_list, vcpuid_map); + assert_eq!(cpu_priv_list[idx].act_list.len(), 0); + assert_eq!(cpu_priv_list[idx].pend_list.len(), 0); + // act list + for act_idx in 0..vgic_data.cpu_priv[idx].act_num { + let id = vgic_data.cpu_priv[idx].act_list[act_idx]; + let interrupt = if id >= GIC_SPI_MAX { + cpu_priv_list[idx].interrupts[id - GIC_SPI_MAX].clone() + } else { + vgicd.interrupts[id].clone() + }; + cpu_priv_list[idx].act_list.push_back(interrupt); + } + // pend list + for pend_idx in 0..vgic_data.cpu_priv[idx].pend_num { + let id = vgic_data.cpu_priv[idx].pend_list[pend_idx]; + let interrupt = if id >= GIC_SPI_MAX { + cpu_priv_list[idx].interrupts[id - GIC_SPI_MAX].clone() + } else { + vgicd.interrupts[id].clone() + }; + cpu_priv_list[idx].pend_list.push_back(interrupt); + } + } + } + + pub fn save_vgic_data(&self, vgic_data: &mut VgicMigData, cpuid_map: &BTreeMap) { + let vgicd = self.vgicd.lock(); + vgic_data.vgicd.iidr = vgicd.iidr; + vgic_data.vgicd.typer = vgicd.typer; + vgic_data.vgicd.ctlr = vgicd.ctlr; + for (idx, int) in vgicd.interrupts.iter().enumerate() { + int.save_migrate_data(&mut vgic_data.vgicd.interrupts[idx], cpuid_map); + } + + let cpu_priv_list = self.cpu_priv.lock(); + vgic_data.cpu_priv_num = cpu_priv_list.len(); + for (idx, cpu_priv) in cpu_priv_list.iter().enumerate() { + cpu_priv.save_migrate_data(&mut vgic_data.cpu_priv[idx], cpuid_map); + } + } + + // reset vcpu in save vgic, use for hypervisor fresh + pub fn save_vgic(&self, src_vgic: Arc) { + // let time0 = time_current_us(); + let src_vgicd = src_vgic.vgicd.lock(); + let mut cur_vgicd = self.vgicd.lock(); + cur_vgicd.ctlr = src_vgicd.ctlr; + cur_vgicd.iidr = src_vgicd.iidr; + cur_vgicd.typer = src_vgicd.typer; + for interrupt in src_vgicd.interrupts.iter() { + cur_vgicd.interrupts.push(interrupt.update()); + } + // cur_vgicd.interrupts.append(&mut src_vgicd.interrupts); + println!( + "src vgicd interrupts len {}, cur interrupts len {}", + src_vgicd.interrupts.len(), + cur_vgicd.interrupts.len() + ); + // let time1 = time_current_us(); + // let mut num = 0; + + // cur_vgicd.interrupts.push(interrupt.fresh_back_up()); + // let time2 = time_current_us(); + + let mut src_cpu_priv = src_vgic.cpu_priv.lock(); + let mut cur_cpu_priv = self.cpu_priv.lock(); + // let mut num1 = 0; + for cpu_priv in src_cpu_priv.iter_mut() { + let vgic_cpu_priv = VgicCpuPriv { + curr_lrs: cpu_priv.curr_lrs, + sgis: cpu_priv.sgis, + interrupts: { + let mut interrupts = vec![]; + // interrupts.append(&mut cpu_priv.interrupts); + for interrupt in cpu_priv.interrupts.iter_mut() { + interrupts.push(interrupt.clone()); + } + for interrupt in cpu_priv.interrupts.iter_mut() { + match interrupt.owner() { + None => {} + Some(vcpu) => { + let vm_id = vcpu.vm_id(); + let vm = vm(vm_id).unwrap(); + let int_id = interrupt.id() as usize; + let phys_id = vcpu.phys_id(); + interrupts.push(VgicInt::priv_new( + int_id, + vm.vcpu(vcpu.id()).unwrap(), + 1 << phys_id, + int_id < GIC_SGIS_NUM, + )); + // num1 += 1; + } + } + // interrupts.push(interrupt.fresh_back_up()); + } + println!( + "src vgicd cpu_priv interrupts len {}, cur interrupts cpu_priv len {}", + cpu_priv.interrupts.len(), + interrupts.len() + ); + interrupts + }, + pend_list: { + let mut pend_list = VecDeque::new(); + for pend_int in cpu_priv.pend_list.iter() { + pend_list.push_back(pend_int.fresh_back_up()); + } + pend_list + }, + act_list: { + let mut act_list = VecDeque::new(); + for act_int in cpu_priv.act_list.iter() { + act_list.push_back(act_int.fresh_back_up()); + } + act_list + }, + }; + cur_cpu_priv.push(vgic_cpu_priv); + } + // let time3 = time_current_us(); + // println!( + // "save vgic: vgicd len {} append {} us, EN_SET size {}, set owner {} {} us, cpu_priv {} change owner {} {} us", + // cur_vgicd.interrupts.len(), + // time1 - time0, + // INTERRUPT_EN_SET.lock().len(), + // num, + // time2 - time1, + // cur_cpu_priv.len(), + // num1, + // time3 - time2 + // ); + } + + fn remove_int_list(&self, vcpu: Vcpu, interrupt: VgicInt, is_pend: bool) { + let mut cpu_priv = self.cpu_priv.lock(); + let vcpu_id = vcpu.id(); + let int_id = interrupt.id(); + if is_pend { + if !interrupt.in_pend() { + // println!("why int {} in pend is false but in pend list", int_id); + return; + } + for i in 0..cpu_priv[vcpu_id].pend_list.len() { + if cpu_priv[vcpu_id].pend_list[i].id() == int_id { + // if int_id == 297 { + // println!("remove int {} in pend list[{}]", int_id, i); + // } + cpu_priv[vcpu_id].pend_list.remove(i); + break; + } + } + interrupt.set_in_pend_state(false); + } else { + if !interrupt.in_act() { + return; + } + for i in 0..cpu_priv[vcpu_id].act_list.len() { + if cpu_priv[vcpu_id].act_list[i].id() == int_id { + cpu_priv[vcpu_id].act_list.remove(i); + break; + } + } + interrupt.set_in_act_state(false); + }; + } + + fn add_int_list(&self, vcpu: Vcpu, interrupt: VgicInt, is_pend: bool) { + let mut cpu_priv = self.cpu_priv.lock(); + let vcpu_id = vcpu.id(); + if is_pend { + interrupt.set_in_pend_state(true); + cpu_priv[vcpu_id].pend_list.push_back(interrupt); + } else { + interrupt.set_in_act_state(true); + cpu_priv[vcpu_id].act_list.push_back(interrupt); + } + } + + fn update_int_list(&self, vcpu: Vcpu, interrupt: VgicInt) { + let state = interrupt.state().to_num(); + + if state & 1 != 0 && !interrupt.in_pend() { + self.add_int_list(vcpu.clone(), interrupt.clone(), true); + } else if state & 1 == 0 { + self.remove_int_list(vcpu.clone(), interrupt.clone(), true); + } + + if state & 2 != 0 && !interrupt.in_act() { + self.add_int_list(vcpu.clone(), interrupt.clone(), false); + } else if state & 2 == 0 { + self.remove_int_list(vcpu.clone(), interrupt.clone(), false); + } + + if interrupt.id() < GIC_SGIS_NUM as u16 { + if self.cpu_priv_sgis_pend(vcpu.id(), interrupt.id() as usize) != 0 && !interrupt.in_pend() { + self.add_int_list(vcpu, interrupt, true); + } + } + } + + fn int_list_head(&self, vcpu: Vcpu, is_pend: bool) -> Option { + let cpu_priv = self.cpu_priv.lock(); + let vcpu_id = vcpu.id(); + if is_pend { + if cpu_priv[vcpu_id].pend_list.is_empty() { + None + } else { + Some(cpu_priv[vcpu_id].pend_list[0].clone()) + } + } else { + if cpu_priv[vcpu_id].act_list.is_empty() { + None + } else { + Some(cpu_priv[vcpu_id].act_list[0].clone()) + } + } + } + + fn set_vgicd_ctlr(&self, ctlr: u32) { + let mut vgicd = self.vgicd.lock(); + vgicd.ctlr = ctlr; + } + + pub fn vgicd_ctlr(&self) -> u32 { + let vgicd = self.vgicd.lock(); + vgicd.ctlr + } + + pub fn vgicd_typer(&self) -> u32 { + let vgicd = self.vgicd.lock(); + vgicd.typer + } + + pub fn vgicd_iidr(&self) -> u32 { + let vgicd = self.vgicd.lock(); + vgicd.iidr + } + + fn cpu_priv_interrupt(&self, cpu_id: usize, idx: usize) -> VgicInt { + let cpu_priv = self.cpu_priv.lock(); + cpu_priv[cpu_id].interrupts[idx].clone() + } + + fn cpu_priv_curr_lrs(&self, cpu_id: usize, idx: usize) -> u16 { + let cpu_priv = self.cpu_priv.lock(); + cpu_priv[cpu_id].curr_lrs[idx] + } + + fn cpu_priv_sgis_pend(&self, cpu_id: usize, idx: usize) -> u8 { + let cpu_priv = self.cpu_priv.lock(); + cpu_priv[cpu_id].sgis[idx].pend + } + + fn cpu_priv_sgis_act(&self, cpu_id: usize, idx: usize) -> u8 { + let cpu_priv = self.cpu_priv.lock(); + cpu_priv[cpu_id].sgis[idx].act + } + + fn set_cpu_priv_curr_lrs(&self, cpu_id: usize, idx: usize, val: u16) { + let mut cpu_priv = self.cpu_priv.lock(); + cpu_priv[cpu_id].curr_lrs[idx] = val; + } + + fn set_cpu_priv_sgis_pend(&self, cpu_id: usize, idx: usize, pend: u8) { + let mut cpu_priv = self.cpu_priv.lock(); + cpu_priv[cpu_id].sgis[idx].pend = pend; + } + + fn set_cpu_priv_sgis_act(&self, cpu_id: usize, idx: usize, act: u8) { + let mut cpu_priv = self.cpu_priv.lock(); + cpu_priv[cpu_id].sgis[idx].act = act; + } + + fn vgicd_interrupt(&self, idx: usize) -> VgicInt { + let vgicd = self.vgicd.lock(); + vgicd.interrupts[idx].clone() + } + + fn get_int(&self, vcpu: Vcpu, int_id: usize) -> Option { + if int_id < GIC_PRIVINT_NUM { + let vcpu_id = vcpu.id(); + return Some(self.cpu_priv_interrupt(vcpu_id, int_id)); + } else if int_id >= GIC_PRIVINT_NUM && int_id < GIC_INTS_MAX { + return Some(self.vgicd_interrupt(int_id - GIC_PRIVINT_NUM)); + } + return None; + } + + fn remove_lr(&self, vcpu: Vcpu, interrupt: VgicInt) -> bool { + if !vgic_owns(vcpu.clone(), interrupt.clone()) { + return false; + } + let int_lr = interrupt.lr(); + let int_id = interrupt.id() as usize; + let vcpu_id = vcpu.id(); + + if !interrupt.in_lr() { + return false; + } + + let mut lr_val = 0; + if let Some(lr) = gich_get_lr(interrupt.clone()) { + GICH.set_lr(int_lr as usize, 0); + lr_val = lr; + } + + interrupt.set_in_lr(false); + + let lr_state = (lr_val >> 28) & 0b11; + if lr_state != 0 { + interrupt.set_state(IrqState::num_to_state(lr_state as usize)); + if int_id < GIC_SGIS_NUM { + if interrupt.state().to_num() & 2 != 0 { + self.set_cpu_priv_sgis_act(vcpu_id, int_id, ((lr_val >> 10) & 0b111) as u8); + } else if interrupt.state().to_num() & 1 != 0 { + let pend = self.cpu_priv_sgis_pend(vcpu_id, int_id); + self.set_cpu_priv_sgis_pend(vcpu_id, int_id, pend | (1 << ((lr_val >> 10) & 0b111) as u8)); + } + } + + self.update_int_list(vcpu.clone(), interrupt.clone()); + + if (interrupt.state().to_num() & 1 != 0) && interrupt.enabled() { + // println!("remove_lr: interrupt_state {}", interrupt.state().to_num()); + let hcr = GICH.hcr(); + GICH.set_hcr(hcr | (1 << 3)); + } + return true; + } + false + } + + fn add_lr(&self, vcpu: Vcpu, interrupt: VgicInt) -> bool { + if !interrupt.enabled() || interrupt.in_lr() { + return false; + } + + let gic_lrs = gic_lrs(); + let mut lr_ind = None; + + for i in 0..gic_lrs { + if (GICH.elrsr(i / 32) & (1 << (i % 32))) != 0 { + lr_ind = Some(i); + break; + } + } + + if lr_ind.is_none() { + let mut pend_found = 0; + let mut act_found = 0; + let mut min_prio_act = 0; + let mut min_prio_pend = 0; + let mut act_ind = None; + let mut pend_ind = None; + + for i in 0..gic_lrs { + let lr = GICH.lr(i); + let lr_prio = (lr >> 23) & 0b11111; + let lr_state = (lr >> 28) & 0b11; + + if lr_state & 2 != 0 { + if lr_prio > min_prio_act { + min_prio_act = lr_prio; + act_ind = Some(i); + } + act_found += 1; + } else if lr_state & 1 != 0 { + if lr_prio > min_prio_pend { + min_prio_pend = lr_prio; + pend_ind = Some(i); + } + pend_found += 1; + } + } + + if pend_found > 1 { + lr_ind = pend_ind; + } else if act_found > 1 { + lr_ind = act_ind; + } + + if let Some(idx) = lr_ind { + let spilled_int = self + .get_int(vcpu.clone(), GICH.lr(idx) as usize & 0b1111111111) + .unwrap(); + let spilled_int_lock; + if spilled_int.id() != interrupt.id() { + spilled_int_lock = spilled_int.lock.lock(); + } + self.remove_lr(vcpu.clone(), spilled_int.clone()); + vgic_int_yield_owner(vcpu.clone(), spilled_int.clone()); + // if spilled_int.id() != interrupt.id() { + // drop(spilled_int_lock); + // } + } + } + + match lr_ind { + Some(idx) => { + self.write_lr(vcpu.clone(), interrupt.clone(), idx); + return true; + } + None => { + // turn on maintenance interrupts + if vgic_get_state(interrupt.clone()) & 1 != 0 { + let hcr = GICH.hcr(); + GICH.set_hcr(hcr | (1 << 3)); + } + } + } + + false + } + + fn write_lr(&self, vcpu: Vcpu, interrupt: VgicInt, lr_ind: usize) { + let vcpu_id = vcpu.id(); + let int_id = interrupt.id() as usize; + let int_prio = interrupt.prio(); + + let prev_int_id = self.cpu_priv_curr_lrs(vcpu_id, lr_ind) as usize; + if prev_int_id != int_id { + let prev_interrupt_option = self.get_int(vcpu.clone(), prev_int_id); + if let Some(prev_interrupt) = prev_interrupt_option { + let prev_interrupt_lock = prev_interrupt.lock.lock(); + // println!( + // "write_lr: Core {} get int {} lock", + // current_cpu().id, + // prev_interrupt.id() + // ); + if vgic_owns(vcpu.clone(), prev_interrupt.clone()) { + if prev_interrupt.in_lr() && prev_interrupt.lr() == lr_ind as u16 { + prev_interrupt.set_in_lr(false); + let prev_id = prev_interrupt.id() as usize; + if !gic_is_priv(prev_id) { + vgic_int_yield_owner(vcpu.clone(), prev_interrupt.clone()); + } + } + } + drop(prev_interrupt_lock); + } + } + + let state = vgic_get_state(interrupt.clone()); + let mut lr = (int_id & 0b1111111111) | (((int_prio as usize >> 3) & 0b11111) << 23); + + if vgic_int_is_hw(interrupt.clone()) { + lr |= 1 << 31; + lr |= (0b1111111111 & int_id) << 10; + if state == 3 { + lr |= (2 & 0b11) << 28; + } else { + lr |= (state & 0b11) << 28; + } + if GICD.state(int_id) != 2 { + GICD.set_state(int_id, 2); + } + } else if int_id < GIC_SGIS_NUM { + if (state & 2) != 0 { + lr |= ((self.cpu_priv_sgis_act(vcpu_id, int_id) as usize) << 10) & (0b111 << 10); + // lr |= ((cpu_priv[vcpu_id].sgis[int_id].act as usize) << 10) & (0b111 << 10); + lr |= (2 & 0b11) << 28; + } else { + let mut idx = GIC_TARGETS_MAX - 1; + while idx as isize >= 0 { + if (self.cpu_priv_sgis_pend(vcpu_id, int_id) & (1 << idx)) != 0 { + lr |= (idx & 0b111) << 10; + let pend = self.cpu_priv_sgis_pend(vcpu_id, int_id); + self.set_cpu_priv_sgis_pend(vcpu_id, int_id, pend & !(1 << idx)); + + lr |= (1 & 0b11) << 28; + break; + } + idx -= 1; + } + } + + if self.cpu_priv_sgis_pend(vcpu_id, int_id) != 0 { + lr |= 1 << 19; + } + } else { + if !gic_is_priv(int_id) && !vgic_int_is_hw(interrupt.clone()) { + lr |= 1 << 19; + } + + lr |= (state & 0b11) << 28; + } + + interrupt.set_state(IrqState::IrqSInactive); + interrupt.set_in_lr(true); + interrupt.set_lr(lr_ind as u16); + self.set_cpu_priv_curr_lrs(vcpu_id, lr_ind, int_id as u16); + + // if current_cpu().id == 1 { + // println!("Core1 write lr[{}] 0x{:x}", lr_ind, lr); + // } + GICH.set_lr(lr_ind, lr as u32); + + self.update_int_list(vcpu.clone(), interrupt.clone()); + } + + fn route(&self, vcpu: Vcpu, interrupt: VgicInt) { + let cpu_id = current_cpu().id; + if let IrqState::IrqSInactive = interrupt.state() { + return; + } + + if !interrupt.enabled() { + return; + } + + let int_targets = interrupt.targets(); + if (int_targets & (1 << cpu_id)) != 0 { + // println!("vm{} route addr lr for int {}", vcpu.vm_id(), interrupt.id()); + self.add_lr(vcpu.clone(), interrupt.clone()); + } + + if !interrupt.in_lr() && (int_targets & !(1 << cpu_id)) != 0 { + let vcpu_vm_id = vcpu.vm_id(); + + let ipi_msg = IpiInitcMessage { + event: InitcEvent::VgicdRoute, + vm_id: vcpu_vm_id, + int_id: interrupt.id(), + val: 0, + }; + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + ipi_intra_broadcast_msg(active_vm().unwrap(), IpiType::IpiTIntc, IpiInnerMsg::Initc(ipi_msg)); + } + } + + fn set_enable(&self, vcpu: Vcpu, int_id: usize, en: bool) { + if int_id < GIC_SGIS_NUM { + return; + } + match self.get_int(vcpu.clone(), int_id) { + Some(interrupt) => { + let interrupt_lock = interrupt.lock.lock(); + if vgic_int_get_owner(vcpu.clone(), interrupt.clone()) { + if interrupt.enabled() ^ en { + interrupt.set_enabled(en); + if !interrupt.enabled() { + self.remove_lr(vcpu.clone(), interrupt.clone()); + } else { + self.route(vcpu.clone(), interrupt.clone()); + } + if interrupt.hw() { + GICD.set_enable(interrupt.id() as usize, en); + } + } + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + } else { + let int_phys_id = interrupt.owner_phys_id().unwrap(); + let vcpu_vm_id = vcpu.vm_id(); + let ipi_msg = IpiInitcMessage { + event: InitcEvent::VgicdSetEn, + vm_id: vcpu_vm_id, + int_id: interrupt.id(), + val: en as u8, + }; + if !ipi_send_msg(int_phys_id, IpiType::IpiTIntc, IpiInnerMsg::Initc(ipi_msg)) { + println!( + "vgicd_set_enable: Failed to send ipi message, target {} type {}", + int_phys_id, 0 + ); + } + } + drop(interrupt_lock); + } + None => { + println!("vgicd_set_enable: interrupt {} is illegal", int_id); + return; + } + } + } + + fn get_enable(&self, vcpu: Vcpu, int_id: usize) -> bool { + self.get_int(vcpu.clone(), int_id).unwrap().enabled() + } + + fn set_pend(&self, vcpu: Vcpu, int_id: usize, pend: bool) { + // TODO: sgi_get_pend ? + if bit_extract(int_id, 0, 10) < GIC_SGIS_NUM { + self.sgi_set_pend(vcpu.clone(), int_id, pend); + return; + } + + let interrupt_option = self.get_int(vcpu.clone(), bit_extract(int_id, 0, 10)); + + if let Some(interrupt) = interrupt_option { + let interrupt_lock = interrupt.lock.lock(); + if vgic_int_get_owner(vcpu.clone(), interrupt.clone()) { + self.remove_lr(vcpu.clone(), interrupt.clone()); + + let state = interrupt.state().to_num(); + if pend && ((state & 1) == 0) { + interrupt.set_state(IrqState::num_to_state(state | 1)); + } else if !pend && (state & 1) != 0 { + interrupt.set_state(IrqState::num_to_state(state & !1)); + } + self.update_int_list(vcpu.clone(), interrupt.clone()); + + let state = interrupt.state().to_num(); + if interrupt.hw() { + let vgic_int_id = interrupt.id() as usize; + GICD.set_state(vgic_int_id, if state == 1 { 2 } else { state }) + } + self.route(vcpu.clone(), interrupt.clone()); + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + drop(interrupt_lock); + } else { + let vm_id = vcpu.vm_id(); + + let m = IpiInitcMessage { + event: InitcEvent::VgicdSetPend, + vm_id, + int_id: interrupt.id(), + val: pend as u8, + }; + match interrupt.owner() { + Some(owner) => { + let phys_id = owner.phys_id(); + + drop(interrupt_lock); + if !ipi_send_msg(phys_id, IpiType::IpiTIntc, IpiInnerMsg::Initc(m)) { + println!( + "vgicd_set_pend: Failed to send ipi message, target {} type {}", + phys_id, 0 + ); + } + } + None => { + panic!( + "set_pend: Core {} int {} has no owner", + current_cpu().id, + interrupt.id() + ); + } + } + } + } + } + + fn set_active(&self, vcpu: Vcpu, int_id: usize, act: bool) { + let interrupt_option = self.get_int(vcpu.clone(), bit_extract(int_id, 0, 10)); + if let Some(interrupt) = interrupt_option { + let interrupt_lock = interrupt.lock.lock(); + if vgic_int_get_owner(vcpu.clone(), interrupt.clone()) { + self.remove_lr(vcpu.clone(), interrupt.clone()); + let state = interrupt.state().to_num(); + if act && ((state & 2) == 0) { + interrupt.set_state(IrqState::num_to_state(state | 2)); + } else if !act && (state & 2) != 0 { + interrupt.set_state(IrqState::num_to_state(state & !2)); + } + self.update_int_list(vcpu.clone(), interrupt.clone()); + + let state = interrupt.state().to_num(); + if interrupt.hw() { + let vgic_int_id = interrupt.id() as usize; + GICD.set_state(vgic_int_id, if state == 1 { 2 } else { state }) + } + self.route(vcpu.clone(), interrupt.clone()); + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + } else { + let vm_id = vcpu.vm_id(); + + let m = IpiInitcMessage { + event: InitcEvent::VgicdSetPend, + vm_id, + int_id: interrupt.id(), + val: act as u8, + }; + let phys_id = interrupt.owner_phys_id().unwrap(); + if !ipi_send_msg(phys_id, IpiType::IpiTIntc, IpiInnerMsg::Initc(m)) { + println!( + "vgicd_set_active: Failed to send ipi message, target {} type {}", + phys_id, 0 + ); + } + } + drop(interrupt_lock); + } + } + + fn set_icfgr(&self, vcpu: Vcpu, int_id: usize, cfg: u8) { + let interrupt_option = self.get_int(vcpu.clone(), int_id); + if let Some(interrupt) = interrupt_option { + let interrupt_lock = interrupt.lock.lock(); + if vgic_int_get_owner(vcpu.clone(), interrupt.clone()) { + interrupt.set_cfg(cfg); + if interrupt.hw() { + GICD.set_icfgr(interrupt.id() as usize, cfg); + } + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + } else { + let m = IpiInitcMessage { + event: InitcEvent::VgicdSetCfg, + vm_id: vcpu.vm_id(), + int_id: interrupt.id(), + val: cfg, + }; + if !ipi_send_msg( + interrupt.owner_phys_id().unwrap(), + IpiType::IpiTIntc, + IpiInnerMsg::Initc(m), + ) { + println!( + "set_icfgr: Failed to send ipi message, target {} type {}", + interrupt.owner_phys_id().unwrap(), + 0 + ); + } + } + drop(interrupt_lock); + } else { + unimplemented!(); + } + } + + fn get_icfgr(&self, vcpu: Vcpu, int_id: usize) -> u8 { + let interrupt_option = self.get_int(vcpu.clone(), int_id); + if let Some(interrupt) = interrupt_option { + return interrupt.cfg(); + } else { + unimplemented!(); + } + } + + fn sgi_set_pend(&self, vcpu: Vcpu, int_id: usize, pend: bool) { + // let begin = time_current_us(); + if bit_extract(int_id, 0, 10) > GIC_SGIS_NUM { + return; + } + + let interrupt_option = self.get_int(vcpu.clone(), bit_extract(int_id, 0, 10)); + let source = bit_extract(int_id, 10, 5); + + if let Some(interrupt) = interrupt_option { + let interrupt_lock = interrupt.lock.lock(); + self.remove_lr(vcpu.clone(), interrupt.clone()); + let vcpu_id = vcpu.id(); + + let vgic_int_id = interrupt.id() as usize; + let pendstate = self.cpu_priv_sgis_pend(vcpu_id, vgic_int_id); + // let pendstate = cpu_priv[vcpu_id].sgis[vgic_int_id].pend; + let new_pendstate = if pend { + pendstate | (1 << source) as u8 + } else { + pendstate & !(1 << source) as u8 + }; + if (pendstate ^ new_pendstate) != 0 { + // cpu_priv[vcpu_id].sgis[vgic_int_id].pend = new_pendstate; + self.set_cpu_priv_sgis_pend(vcpu_id, vgic_int_id, new_pendstate); + let state = interrupt.state().to_num(); + if new_pendstate != 0 { + interrupt.set_state(IrqState::num_to_state(state | 1)); + } else { + interrupt.set_state(IrqState::num_to_state(state & !1)); + } + + self.update_int_list(vcpu.clone(), interrupt.clone()); + + // println!("state {}", interrupt.state().to_num()); + match interrupt.state() { + IrqState::IrqSInactive => { + println!("inactive"); + } + _ => { + self.add_lr(vcpu.clone(), interrupt.clone()); + } + } + } + drop(interrupt_lock); + } else { + println!("sgi_set_pend: interrupt {} is None", bit_extract(int_id, 0, 10)); + } + // let end = time_current_us(); + // println!("sgi_set_pend[{}]", end - begin); + } + + fn set_prio(&self, vcpu: Vcpu, int_id: usize, mut prio: u8) { + let interrupt_option = self.get_int(vcpu.clone(), int_id); + prio &= 0xf0; // gic-400 only allows 4 priority bits in non-secure state + + if let Some(interrupt) = interrupt_option { + let interrupt_lock = interrupt.lock.lock(); + if vgic_int_get_owner(vcpu.clone(), interrupt.clone()) { + if interrupt.prio() != prio { + self.remove_lr(vcpu.clone(), interrupt.clone()); + let prev_prio = interrupt.prio(); + interrupt.set_prio(prio); + if prio <= prev_prio { + self.route(vcpu.clone(), interrupt.clone()); + } + if interrupt.hw() { + GICD.set_prio(interrupt.id() as usize, prio); + } + } + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + } else { + let vm_id = vcpu.vm_id(); + + let m = IpiInitcMessage { + event: InitcEvent::VgicdSetPrio, + vm_id, + int_id: interrupt.id(), + val: prio, + }; + if !ipi_send_msg( + interrupt.owner_phys_id().unwrap(), + IpiType::IpiTIntc, + IpiInnerMsg::Initc(m), + ) { + println!( + "set_prio: Failed to send ipi message, target {} type {}", + interrupt.owner_phys_id().unwrap(), + 0 + ); + } + } + drop(interrupt_lock); + } + } + + fn get_prio(&self, vcpu: Vcpu, int_id: usize) -> u8 { + let interrupt_option = self.get_int(vcpu.clone(), int_id); + return interrupt_option.unwrap().prio(); + } + + fn set_trgt(&self, vcpu: Vcpu, int_id: usize, trgt: u8) { + let interrupt_option = self.get_int(vcpu.clone(), int_id); + if let Some(interrupt) = interrupt_option { + let interrupt_lock = interrupt.lock.lock(); + if vgic_int_get_owner(vcpu.clone(), interrupt.clone()) { + if interrupt.targets() != trgt { + interrupt.set_targets(trgt); + let mut ptrgt = 0; + for cpuid in 0..8 { + if bit_get(trgt as usize, cpuid) != 0 { + ptrgt = bit_set(ptrgt, platform_cpuid_to_cpuif(cpuid)) + } + } + if interrupt.hw() { + GICD.set_trgt(interrupt.id() as usize, ptrgt as u8); + } + if vgic_get_state(interrupt.clone()) != 0 { + self.route(vcpu.clone(), interrupt.clone()); + } + } + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + } else { + let vm_id = vcpu.vm_id(); + let m = IpiInitcMessage { + event: InitcEvent::VgicdSetTrgt, + vm_id, + int_id: interrupt.id(), + val: trgt, + }; + if !ipi_send_msg( + interrupt.owner_phys_id().unwrap(), + IpiType::IpiTIntc, + IpiInnerMsg::Initc(m), + ) { + println!( + "set_trgt: Failed to send ipi message, target {} type {}", + interrupt.owner_phys_id().unwrap(), + 0 + ); + } + } + drop(interrupt_lock); + } + } + + fn get_trgt(&self, vcpu: Vcpu, int_id: usize) -> u8 { + let interrupt_option = self.get_int(vcpu.clone(), int_id); + return interrupt_option.unwrap().targets(); + } + + pub fn inject(&self, vcpu: Vcpu, int_id: usize) { + // println!("Core {} inject int {} to vm{}", current_cpu().id, int_id, vcpu.vm_id()); + let interrupt_option = self.get_int(vcpu.clone(), bit_extract(int_id, 0, 10)); + if let Some(interrupt) = interrupt_option { + if interrupt.hw() { + let interrupt_lock = interrupt.lock.lock(); + interrupt.set_owner(vcpu.clone()); + interrupt.set_state(IrqState::IrqSPend); + self.update_int_list(vcpu.clone(), interrupt.clone()); + interrupt.set_in_lr(false); + self.route(vcpu.clone(), interrupt.clone()); + drop(interrupt_lock); + } else { + self.set_pend(vcpu.clone(), int_id, true); + } + } + } + + fn emu_ctrl_access(&self, emu_ctx: &EmuContext) { + if emu_ctx.write { + let prev_ctlr = self.vgicd_ctlr(); + let idx = emu_ctx.reg; + self.set_vgicd_ctlr(current_cpu().get_gpr(idx) as u32 & 0x1); + if prev_ctlr ^ self.vgicd_ctlr() != 0 { + let enable = self.vgicd_ctlr() != 0; + let hcr = GICH.hcr(); + if enable { + GICH.set_hcr(hcr | 1); + } else { + GICH.set_hcr(hcr & !1); + } + + let m = IpiInitcMessage { + event: InitcEvent::VgicdGichEn, + vm_id: active_vm_id(), + int_id: 0, + val: enable as u8, + }; + ipi_intra_broadcast_msg(active_vm().unwrap(), IpiType::IpiTIntc, IpiInnerMsg::Initc(m)); + } + } else { + let idx = emu_ctx.reg; + let val = self.vgicd_ctlr() as usize; + current_cpu().set_gpr(idx, val); + } + } + + fn emu_typer_access(&self, emu_ctx: &EmuContext) { + if !emu_ctx.write { + let idx = emu_ctx.reg; + let val = self.vgicd_typer() as usize; + current_cpu().set_gpr(idx, val); + } else { + println!("emu_typer_access: can't write to RO reg"); + } + } + + fn emu_iidr_access(&self, emu_ctx: &EmuContext) { + if !emu_ctx.write { + let idx = emu_ctx.reg; + let val = self.vgicd_iidr() as usize; + current_cpu().set_gpr(idx, val); + } else { + println!("emu_iidr_access: can't write to RO reg"); + } + } + + fn emu_isenabler_access(&self, emu_ctx: &EmuContext) { + // println!("DEBUG: in emu_isenabler_access"); + let reg_idx = (emu_ctx.address & 0b1111111) / 4; + let idx = emu_ctx.reg; + let mut val = if emu_ctx.write { current_cpu().get_gpr(idx) } else { 0 }; + let first_int = reg_idx * 32; + let vm_id = active_vm_id(); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_isenabler_access: current vcpu.vm is none"); + } + }; + let mut vm_has_interrupt_flag = false; + + for i in 0..32 { + if vm.has_interrupt(first_int + i) || vm.emu_has_interrupt(first_int + i) { + vm_has_interrupt_flag = true; + break; + } + } + if first_int >= 16 && !vm_has_interrupt_flag { + println!( + "emu_isenabler_access: vm[{}] does not have interrupt {}", + vm_id, first_int + ); + return; + } + + if emu_ctx.write { + for i in 0..32 { + if bit_get(val, i) != 0 { + self.set_enable(current_cpu().active_vcpu.clone().unwrap(), first_int + i, true); + } + } + } else { + for i in 0..32 { + if self.get_enable(current_cpu().active_vcpu.clone().unwrap(), first_int + i) { + val |= 1 << i; + } + } + let idx = emu_ctx.reg; + current_cpu().set_gpr(idx, val); + } + } + + fn emu_pendr_access(&self, emu_ctx: &EmuContext, set: bool) { + println!("emu_pendr_access"); + let reg_idx = (emu_ctx.address & 0b1111111) / 4; + let idx = emu_ctx.reg; + let mut val = if emu_ctx.write { current_cpu().get_gpr(idx) } else { 0 }; + let first_int = reg_idx * 32; + let vm_id = active_vm_id(); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_pendr_access: current vcpu.vm is none"); + } + }; + let mut vm_has_interrupt_flag = false; + + for i in 0..emu_ctx.width { + if vm.has_interrupt(first_int + i) || vm.emu_has_interrupt(first_int + i) { + vm_has_interrupt_flag = true; + break; + } + } + if first_int >= 16 && !vm_has_interrupt_flag { + println!("emu_pendr_access: vm[{}] does not have interrupt {}", vm_id, first_int); + return; + } + + if emu_ctx.write { + for i in 0..32 { + if bit_get(val, i) != 0 { + self.set_pend(current_cpu().active_vcpu.clone().unwrap(), first_int + i, set); + } + } + } else { + for i in 0..32 { + match self.get_int(current_cpu().active_vcpu.clone().unwrap(), first_int + i) { + Some(interrupt) => { + if vgic_get_state(interrupt.clone()) & 1 != 0 { + val |= 1 << i; + } + } + None => { + unimplemented!(); + } + } + } + let idx = emu_ctx.reg; + current_cpu().set_gpr(idx, val); + } + } + + fn emu_ispendr_access(&self, emu_ctx: &EmuContext) { + self.emu_pendr_access(emu_ctx, true); + } + + fn emu_activer_access(&self, emu_ctx: &EmuContext, set: bool) { + // println!("DEBUG: in emu_activer_access"); + let reg_idx = (emu_ctx.address & 0b1111111) / 4; + let idx = emu_ctx.reg; + let mut val = if emu_ctx.write { current_cpu().get_gpr(idx) } else { 0 }; + let first_int = reg_idx * 32; + let vm_id = active_vm_id(); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_activer_access: current vcpu.vm is none"); + } + }; + let mut vm_has_interrupt_flag = false; + + for i in 0..32 { + if vm.has_interrupt(first_int + i) || vm.emu_has_interrupt(first_int + i) { + vm_has_interrupt_flag = true; + break; + } + } + if first_int >= 16 && !vm_has_interrupt_flag { + warn!( + "emu_activer_access: vm[{}] does not have interrupt {}", + vm_id, first_int + ); + return; + } + + if emu_ctx.write { + for i in 0..32 { + if bit_get(val, i) != 0 { + self.set_active(current_cpu().active_vcpu.clone().unwrap(), first_int + i, set); + } + } + } else { + for i in 0..32 { + match self.get_int(current_cpu().active_vcpu.clone().unwrap(), first_int + i) { + Some(interrupt) => { + if vgic_get_state(interrupt.clone()) & 2 != 0 { + val |= 1 << i; + } + } + None => { + unimplemented!(); + } + } + } + let idx = emu_ctx.reg; + current_cpu().set_gpr(idx, val); + } + } + + fn emu_isactiver_access(&self, emu_ctx: &EmuContext) { + self.emu_activer_access(emu_ctx, true); + } + + fn emu_icenabler_access(&self, emu_ctx: &EmuContext) { + let reg_idx = (emu_ctx.address & 0b1111111) / 4; + let idx = emu_ctx.reg; + let mut val = if emu_ctx.write { current_cpu().get_gpr(idx) } else { 0 }; + let first_int = reg_idx * 32; + let vm_id = active_vm_id(); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_activer_access: current vcpu.vm is none"); + } + }; + let mut vm_has_interrupt_flag = false; + + if emu_ctx.write { + for i in 0..32 { + if vm.has_interrupt(first_int + i) || vm.emu_has_interrupt(first_int + i) { + vm_has_interrupt_flag = true; + break; + } + } + if first_int >= 16 && !vm_has_interrupt_flag { + warn!( + "emu_icenabler_access: vm[{}] does not have interrupt {}", + vm_id, first_int + ); + return; + } + } + + if emu_ctx.write { + for i in 0..32 { + if bit_get(val, i) != 0 { + self.set_enable(current_cpu().active_vcpu.clone().unwrap(), first_int + i, false); + } + } + } else { + for i in 0..32 { + if self.get_enable(current_cpu().active_vcpu.clone().unwrap(), first_int + i) { + val |= 1 << i; + } + } + let idx = emu_ctx.reg; + current_cpu().set_gpr(idx, val); + } + } + + fn emu_icpendr_access(&self, emu_ctx: &EmuContext) { + self.emu_pendr_access(emu_ctx, false); + } + + fn emu_icativer_access(&self, emu_ctx: &EmuContext) { + self.emu_activer_access(emu_ctx, false); + } + + fn emu_icfgr_access(&self, emu_ctx: &EmuContext) { + let first_int = (32 / GIC_CONFIG_BITS) * bit_extract(emu_ctx.address, 0, 9) / 4; + let vm_id = active_vm_id(); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_icfgr_access: current vcpu.vm is none"); + } + }; + let mut vm_has_interrupt_flag = false; + + if emu_ctx.write { + for i in 0..emu_ctx.width * 8 { + if vm.has_interrupt(first_int + i) || vm.emu_has_interrupt(first_int + i) { + vm_has_interrupt_flag = true; + break; + } + } + if first_int >= 16 && !vm_has_interrupt_flag { + warn!("emu_icfgr_access: vm[{}] does not have interrupt {}", vm_id, first_int); + return; + } + } + + if emu_ctx.write { + let idx = emu_ctx.reg; + let cfg = current_cpu().get_gpr(idx); + let mut irq = first_int; + let mut bit = 0; + while bit < emu_ctx.width * 8 { + self.set_icfgr( + current_cpu().active_vcpu.clone().unwrap(), + irq, + bit_extract(cfg as usize, bit, 2) as u8, + ); + bit += 2; + irq += 1; + } + } else { + let mut cfg = 0; + let mut irq = first_int; + let mut bit = 0; + while bit < emu_ctx.width * 8 { + cfg |= (self.get_icfgr(current_cpu().active_vcpu.clone().unwrap(), irq) as usize) << bit; + bit += 2; + irq += 1; + } + let idx = emu_ctx.reg; + let val = cfg; + current_cpu().set_gpr(idx, val); + } + } + + fn emu_sgiregs_access(&self, emu_ctx: &EmuContext) { + let idx = emu_ctx.reg; + let val = if emu_ctx.write { current_cpu().get_gpr(idx) } else { 0 }; + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_sgiregs_access: current vcpu.vm is none"); + } + }; + + if bit_extract(emu_ctx.address, 0, 12) == bit_extract(PLATFORM_GICD_BASE + 0x0f00, 0, 12) { + if emu_ctx.write { + let sgir_trglstflt = bit_extract(val, 24, 2); + let mut trgtlist = 0; + // println!("addr {:x}, sgir trglst flt {}, vtrgt {}", emu_ctx.address, sgir_trglstflt, bit_extract(val, 16, 8)); + match sgir_trglstflt { + 0 => { + trgtlist = vgic_target_translate(vm.clone(), bit_extract(val, 16, 8) as u32, true) as usize; + } + 1 => { + trgtlist = active_vm_ncpu() & !(1 << current_cpu().id); + } + 2 => { + trgtlist = 1 << current_cpu().id; + } + 3 => { + return; + } + _ => {} + } + + for i in 0..8 { + if trgtlist & (1 << i) != 0 { + let m = IpiInitcMessage { + event: InitcEvent::VgicdSetPend, + vm_id: active_vm_id(), + int_id: (bit_extract(val, 0, 8) | (active_vcpu_id() << 10)) as u16, + val: true as u8, + }; + if !ipi_send_msg(i, IpiType::IpiTIntc, IpiInnerMsg::Initc(m)) { + println!( + "emu_sgiregs_access: Failed to send ipi message, target {} type {}", + i, 0 + ); + } + } + } + } + } else { + // TODO: CPENDSGIR and SPENDSGIR access + unimplemented!(); + } + } + + fn emu_ipriorityr_access(&self, emu_ctx: &EmuContext) { + let idx = emu_ctx.reg; + let mut val = if emu_ctx.write { current_cpu().get_gpr(idx) } else { 0 }; + let first_int = (8 / GIC_PRIO_BITS) * bit_extract(emu_ctx.address, 0, 9); + let vm_id = active_vm_id(); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_ipriorityr_access: current vcpu.vm is none"); + } + }; + let mut vm_has_interrupt_flag = false; + + if emu_ctx.write { + for i in 0..emu_ctx.width { + if vm.has_interrupt(first_int + i) || vm.emu_has_interrupt(first_int + i) { + vm_has_interrupt_flag = true; + break; + } + } + if first_int >= 16 && !vm_has_interrupt_flag { + warn!( + "emu_ipriorityr_access: vm[{}] does not have interrupt {}", + vm_id, first_int + ); + return; + } + } + + if emu_ctx.write { + for i in 0..emu_ctx.width { + self.set_prio( + current_cpu().active_vcpu.clone().unwrap(), + first_int + i, + bit_extract(val, GIC_PRIO_BITS * i, GIC_PRIO_BITS) as u8, + ); + } + } else { + for i in 0..emu_ctx.width { + val |= (self.get_prio(current_cpu().active_vcpu.clone().unwrap(), first_int + i) as usize) + << (GIC_PRIO_BITS * i); + } + let idx = emu_ctx.reg; + current_cpu().set_gpr(idx, val); + } + } + + fn emu_itargetr_access(&self, emu_ctx: &EmuContext) { + let idx = emu_ctx.reg; + let mut val = if emu_ctx.write { current_cpu().get_gpr(idx) } else { 0 }; + let first_int = (8 / GIC_TARGET_BITS) * bit_extract(emu_ctx.address, 0, 9); + + if emu_ctx.write { + // println!("write"); + val = vgic_target_translate(active_vm().unwrap(), val as u32, true) as usize; + for i in 0..emu_ctx.width { + self.set_trgt( + current_cpu().active_vcpu.clone().unwrap(), + first_int + i, + bit_extract(val, GIC_TARGET_BITS * i, GIC_TARGET_BITS) as u8, + ); + } + } else { + // println!("read, first_int {}, width {}", first_int, emu_ctx.width); + for i in 0..emu_ctx.width { + // println!("{}", self.get_trgt(active_vcpu().unwrap(), first_int + i)); + val |= (self.get_trgt(current_cpu().active_vcpu.clone().unwrap(), first_int + i) as usize) + << (GIC_TARGET_BITS * i); + } + // println!("after read val {}", val); + val = vgic_target_translate(active_vm().unwrap(), val as u32, false) as usize; + let idx = emu_ctx.reg; + current_cpu().set_gpr(idx, val); + } + } + + fn handle_trapped_eoir(&self, vcpu: Vcpu) { + // if current_cpu().id == 2 { + // for i in 0..4 { + // println!("gich.LR[{}] 0x{:x}", i, GICH.lr(i)); + // } + // println!("elrsr[0] {:x}", GICH.elrsr(0)); + // println!("eisr[0] {:x}", GICH.eisr(0)); + // println!("hcr 0x{:x}", GICH.hcr()); + // } + let gic_lrs = gic_lrs(); + let mut lr_idx_opt = bitmap_find_nth( + GICH.eisr(0) as usize | ((GICH.eisr(1) as usize) << 32), + 0, + gic_lrs, + 1, + true, + ); + + while lr_idx_opt.is_some() { + let lr_idx = lr_idx_opt.unwrap(); + let lr_val = GICH.lr(lr_idx) as usize; + GICH.set_lr(lr_idx, 0); + + match self.get_int(vcpu.clone(), bit_extract(lr_val, 0, 10)) { + Some(interrupt) => { + let interrupt_lock = interrupt.lock.lock(); + // if current_cpu().id == 2 { + // println!("handle_trapped_eoir interrupt {}", interrupt.id()); + // } + // if current_cpu().id == 1 && interrupt.id() == 49 { + // println!("handle_trapped_eoir interrupt 49"); + // } + interrupt.set_in_lr(false); + if (interrupt.id() as usize) < GIC_SGIS_NUM { + self.add_lr(vcpu.clone(), interrupt.clone()); + } else { + vgic_int_yield_owner(vcpu.clone(), interrupt.clone()); + } + drop(interrupt_lock); + // println!("handle_trapped_eoir: Core {} finish", current_cpu().id); + } + None => { + unimplemented!(); + } + } + lr_idx_opt = bitmap_find_nth( + GICH.eisr(0) as usize | ((GICH.eisr(1) as usize) << 32), + 0, + gic_lrs, + 1, + true, + ); + } + } + + fn refill_lrs(&self, vcpu: Vcpu) { + // if current_cpu().id == 1 { + // println!("refill lrs"); + // } + let gic_lrs = gic_lrs(); + let mut has_pending = false; + + for i in 0..gic_lrs { + let lr = GICH.lr(i) as usize; + if bit_extract(lr, 28, 2) & 1 != 0 { + has_pending = true; + } + } + + let mut lr_idx_opt = bitmap_find_nth( + GICH.elrsr(0) as usize | ((GICH.elrsr(1) as usize) << 32), + 0, + gic_lrs, + 1, + true, + ); + + while lr_idx_opt.is_some() { + let mut interrupt_opt: Option = None; + let mut prev_pend = false; + let act_head = self.int_list_head(vcpu.clone(), false); + let pend_head = self.int_list_head(vcpu.clone(), true); + if has_pending { + match act_head { + Some(act_int) => { + if !act_int.in_lr() { + interrupt_opt = Some(act_int.clone()); + } + } + None => {} + } + } + if interrupt_opt.is_none() { + if let Some(pend_int) = pend_head { + if !pend_int.in_lr() { + interrupt_opt = Some(pend_int.clone()); + prev_pend = true; + } + } + } + + match interrupt_opt { + Some(interrupt) => { + // println!("refill int {}", interrupt.id()); + vgic_int_get_owner(vcpu.clone(), interrupt.clone()); + self.write_lr(vcpu.clone(), interrupt.clone(), lr_idx_opt.unwrap()); + has_pending = has_pending || prev_pend; + } + None => { + // println!("no int to refill"); + let hcr = GICH.hcr(); + GICH.set_hcr(hcr & !(1 << 3)); + break; + } + } + + lr_idx_opt = bitmap_find_nth( + GICH.elrsr(0) as usize | ((GICH.elrsr(1) as usize) << 32), + 0, + gic_lrs, + 1, + true, + ); + } + // println!("end refill lrs"); + } + + fn eoir_highest_spilled_active(&self, vcpu: Vcpu) { + let interrupt = self.int_list_head(vcpu.clone(), false); + match interrupt { + Some(int) => { + int.lock.lock(); + vgic_int_get_owner(vcpu.clone(), int.clone()); + + let state = int.state().to_num(); + int.set_state(IrqState::num_to_state(state & !2)); + self.update_int_list(vcpu.clone(), int.clone()); + + if vgic_int_is_hw(int.clone()) { + GICD.set_act(int.id() as usize, false); + } else { + if int.state().to_num() & 1 != 0 { + self.add_lr(vcpu.clone(), int.clone()); + } + } + } + None => {} + } + } +} + +fn vgic_target_translate(vm: Vm, trgt: u32, v2p: bool) -> u32 { + let from = trgt.to_le_bytes(); + + let mut result = 0; + for (idx, val) in from + .map(|x| { + if v2p { + vm.vcpu_to_pcpu_mask(x as usize, 8) as u32 + } else { + vm.pcpu_to_vcpu_mask(x as usize, 8) as u32 + } + }) + .iter() + .enumerate() + { + result |= (*val as u32) << (8 * idx); + if idx >= 4 { + panic!("illegal idx, from len {}", from.len()); + } + } + result +} + +fn vgic_owns(vcpu: Vcpu, interrupt: VgicInt) -> bool { + if gic_is_priv(interrupt.id() as usize) { + return true; + } + // if interrupt.owner().is_none() { + // return false; + // } + + let vcpu_id = vcpu.id(); + let pcpu_id = vcpu.phys_id(); + match interrupt.owner() { + Some(owner) => { + let owner_vcpu_id = owner.id(); + let owner_pcpu_id = owner.phys_id(); + // println!( + // "return {}, arc same {}", + // owner_vcpu_id == vcpu_id && owner_pcpu_id == pcpu_id, + // result + // ); + return owner_vcpu_id == vcpu_id && owner_pcpu_id == pcpu_id; + } + None => return false, + } + + // let tmp = interrupt.owner().unwrap(); + // let owner_vcpu_id = interrupt.owner_id(); + // let owner_pcpu_id = interrupt.owner_phys_id(); + // let owner_vm_id = interrupt.owner_vm_id(); + // println!("3: owner_vm_id {}", owner_vm_id); + + // let vcpu_vm_id = vcpu.vm_id(); + + // println!("return vgic_owns: vcpu_vm_id {}", vcpu_vm_id); + // return (owner_vcpu_id == vcpu_id && owner_vm_id == vcpu_vm_id); +} + +fn vgic_get_state(interrupt: VgicInt) -> usize { + let mut state = interrupt.state().to_num(); + + if interrupt.in_lr() && interrupt.owner_phys_id().unwrap() == current_cpu().id { + let lr_option = gich_get_lr(interrupt.clone()); + if let Some(lr_val) = lr_option { + state = lr_val as usize; + } + } + + if interrupt.id() as usize >= GIC_SGIS_NUM { + return state; + } + if interrupt.owner().is_none() { + return state; + } + + let vm = interrupt.owner_vm(); + let vgic = vm.vgic(); + let vcpu_id = interrupt.owner_id().unwrap(); + + if vgic.cpu_priv_sgis_pend(vcpu_id, interrupt.id() as usize) != 0 { + state |= 1; + } + + state +} + +fn vgic_int_yield_owner(vcpu: Vcpu, interrupt: VgicInt) { + if !vgic_owns(vcpu.clone(), interrupt.clone()) { + return; + } + if gic_is_priv(interrupt.id() as usize) || interrupt.in_lr() { + return; + } + + if vgic_get_state(interrupt.clone()) & 2 == 0 { + interrupt.clear_owner(); + } +} + +fn vgic_int_is_hw(interrupt: VgicInt) -> bool { + interrupt.id() as usize >= GIC_SGIS_NUM && interrupt.hw() +} + +fn gich_get_lr(interrupt: VgicInt) -> Option { + let cpu_id = current_cpu().id; + let phys_id = interrupt.owner_phys_id().unwrap(); + + if !interrupt.in_lr() || phys_id != cpu_id { + return None; + } + + let lr_val = GICH.lr(interrupt.lr() as usize); + if (lr_val & 0b1111111111 == interrupt.id() as u32) && (lr_val >> 28 & 0b11 != 0) { + return Some(lr_val as u32); + } + return None; +} + +fn vgic_int_get_owner(vcpu: Vcpu, interrupt: VgicInt) -> bool { + // if interrupt.owner().is_none() { + // interrupt.set_owner(vcpu.clone()); + // return true; + // } + let vcpu_id = vcpu.id(); + let vcpu_vm_id = vcpu.vm_id(); + + match interrupt.owner() { + Some(owner) => { + let owner_vcpu_id = owner.id(); + let owner_vm_id = owner.vm_id(); + + owner_vm_id == vcpu_vm_id && owner_vcpu_id == vcpu_id + } + None => { + interrupt.set_owner(vcpu.clone()); + true + } + } + + // let owner_vcpu_id = interrupt.owner_id().unwrap(); + // let owner_vm_id = interrupt.owner_vm_id().unwrap(); + + // return false; +} + +pub fn gic_maintenance_handler(_arg: usize) { + let misr = GICH.misr(); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("gic_maintenance_handler: current vcpu.vm is None"); + } + }; + // if current_cpu().id == 2 { + // println!("gic_maintenance_handler, misr {:x}", misr); + // } + let vgic = vm.vgic(); + + if misr & 1 != 0 { + vgic.handle_trapped_eoir(current_cpu().active_vcpu.clone().unwrap()); + } + + if misr & (1 << 3) != 0 { + vgic.refill_lrs(current_cpu().active_vcpu.clone().unwrap()); + } + + if misr & (1 << 2) != 0 { + // println!("in gic_maintenance_handler eoir_highest_spilled_active"); + let mut hcr = GICH.hcr(); + while hcr & (0b11111 << 27) != 0 { + vgic.eoir_highest_spilled_active(current_cpu().active_vcpu.clone().unwrap()); + hcr -= 1 << 27; + GICH.set_hcr(hcr); + hcr = GICH.hcr(); + } + // println!("end gic_maintenance_handler eoir_highest_spilled_active"); + } +} + +const VGICD_REG_OFFSET_PREFIX_CTLR: usize = 0x0; +// same as TYPER & IIDR +const VGICD_REG_OFFSET_PREFIX_ISENABLER: usize = 0x2; +const VGICD_REG_OFFSET_PREFIX_ICENABLER: usize = 0x3; +const VGICD_REG_OFFSET_PREFIX_ISPENDR: usize = 0x4; +const VGICD_REG_OFFSET_PREFIX_ICPENDR: usize = 0x5; +const VGICD_REG_OFFSET_PREFIX_ISACTIVER: usize = 0x6; +const VGICD_REG_OFFSET_PREFIX_ICACTIVER: usize = 0x7; +const VGICD_REG_OFFSET_PREFIX_ICFGR: usize = 0x18; +const VGICD_REG_OFFSET_PREFIX_SGIR: usize = 0x1e; + +pub fn emu_intc_handler(_emu_dev_id: usize, emu_ctx: &EmuContext) -> bool { + let offset = emu_ctx.address & 0xfff; + if emu_ctx.width > 4 { + return false; + } + + let vm = match crate::kernel::active_vm() { + None => { + panic!("emu_intc_handler: vm is None"); + } + Some(x) => x, + }; + let vgic = vm.vgic(); + let vgicd_offset_prefix = (offset & 0xf80) >> 7; + // if current_cpu().id == 2 { + // println!( + // "emu_intc_handler: vgicd_offset_prefix 0x{:x}, offset 0x{:x}", + // vgicd_offset_prefix, offset + // ); + // } + if !vgicd_emu_access_is_vaild(emu_ctx) { + return false; + } + + match vgicd_offset_prefix { + VGICD_REG_OFFSET_PREFIX_ISENABLER => { + vgic.emu_isenabler_access(emu_ctx); + } + VGICD_REG_OFFSET_PREFIX_ISPENDR => { + vgic.emu_ispendr_access(emu_ctx); + } + VGICD_REG_OFFSET_PREFIX_ISACTIVER => { + vgic.emu_isactiver_access(emu_ctx); + } + VGICD_REG_OFFSET_PREFIX_ICENABLER => { + vgic.emu_icenabler_access(emu_ctx); + } + VGICD_REG_OFFSET_PREFIX_ICPENDR => { + vgic.emu_icpendr_access(emu_ctx); + } + VGICD_REG_OFFSET_PREFIX_ICACTIVER => { + vgic.emu_icativer_access(emu_ctx); + } + VGICD_REG_OFFSET_PREFIX_ICFGR => { + vgic.emu_icfgr_access(emu_ctx); + } + VGICD_REG_OFFSET_PREFIX_SGIR => { + vgic.emu_sgiregs_access(emu_ctx); + } + _ => { + match offset { + // VGICD_REG_OFFSET(CTLR) + 0 => { + vgic.emu_ctrl_access(emu_ctx); + } + // VGICD_REG_OFFSET(TYPER) + 0x004 => { + vgic.emu_typer_access(emu_ctx); + } + // VGICD_REG_OFFSET(IIDR) + 0x008 => { + vgic.emu_iidr_access(emu_ctx); + } + _ => { + if !emu_ctx.write { + let idx = emu_ctx.reg; + let val = 0; + current_cpu().set_gpr(idx, val); + } + } + } + if offset >= 0x400 && offset < 0x800 { + vgic.emu_ipriorityr_access(emu_ctx); + } else if offset >= 0x800 && offset < 0xc00 { + vgic.emu_itargetr_access(emu_ctx); + } + } + } + // println!("finish emu_intc_handler"); + true +} + +pub fn vgicd_emu_access_is_vaild(emu_ctx: &EmuContext) -> bool { + let offset = emu_ctx.address & 0xfff; + let offset_prefix = (offset & 0xf80) >> 7; + match offset_prefix { + VGICD_REG_OFFSET_PREFIX_CTLR + | VGICD_REG_OFFSET_PREFIX_ISENABLER + | VGICD_REG_OFFSET_PREFIX_ISPENDR + | VGICD_REG_OFFSET_PREFIX_ISACTIVER + | VGICD_REG_OFFSET_PREFIX_ICENABLER + | VGICD_REG_OFFSET_PREFIX_ICPENDR + | VGICD_REG_OFFSET_PREFIX_ICACTIVER + | VGICD_REG_OFFSET_PREFIX_ICFGR => { + if emu_ctx.width != 4 || emu_ctx.address & 0x3 != 0 { + return false; + } + } + VGICD_REG_OFFSET_PREFIX_SGIR => { + if (emu_ctx.width == 4 && emu_ctx.address & 0x3 != 0) || (emu_ctx.width == 2 && emu_ctx.address & 0x1 != 0) + { + return false; + } + } + _ => { + // TODO: hard code to rebuild (gicd IPRIORITYR and ITARGETSR) + if offset >= 0x400 && offset < 0xc00 { + if (emu_ctx.width == 4 && emu_ctx.address & 0x3 != 0) + || (emu_ctx.width == 2 && emu_ctx.address & 0x1 != 0) + { + return false; + } + } + } + } + true +} + +pub fn partial_passthrough_intc_handler(_emu_dev_id: usize, emu_ctx: &EmuContext) -> bool { + if !vgicd_emu_access_is_vaild(emu_ctx) { + return false; + } + let offset = emu_ctx.address & 0xfff; + // println!( + // "partial_passthrough_intc_handler: {} offset_prefix 0x{:x}, offset 0x{:x}", + // if emu_ctx.write { "write" } else { "read" }, offset_prefix, offset + // ); + if emu_ctx.write { + // todo: add offset match + let val = current_cpu().get_gpr(emu_ctx.reg); + ptr_read_write(PLATFORM_GICD_BASE + 0x8_0000_0000 + offset, emu_ctx.width, val, false); + } else { + let res = ptr_read_write(PLATFORM_GICD_BASE + 0x8_0000_0000 + offset, emu_ctx.width, 0, true); + current_cpu().set_gpr(emu_ctx.reg, res); + } + + true +} + +pub fn vgic_ipi_handler(msg: &IpiMessage) { + let vm_id; + let int_id; + let val; + match &msg.ipi_message { + IpiInnerMsg::Initc(intc) => { + vm_id = intc.vm_id; + int_id = intc.int_id; + val = intc.val; + } + _ => { + println!("vgic_ipi_handler: illegal ipi"); + return; + } + } + let trgt_vcpu = match current_cpu().vcpu_array.pop_vcpu_through_vmid(vm_id) { + None => { + println!("Core {} received vgic msg from unknown VM {}", current_cpu().id, vm_id); + return; + } + Some(vcpu) => vcpu, + }; + restore_vcpu_gic(current_cpu().active_vcpu.clone(), trgt_vcpu.clone()); + + let vm = match trgt_vcpu.vm() { + None => { + panic!("vgic_ipi_handler: vm is None"); + } + Some(x) => x, + }; + let vgic = vm.vgic(); + + if vm_id as usize != vm.id() { + println!("VM {} received vgic msg from another vm {}", vm.id(), vm_id); + return; + } + if let IpiInnerMsg::Initc(intc) = &msg.ipi_message { + // println!( + // "vgic_ipi_handler: core {} receive vgic_ipi, event {:?}, vm_id {}, int_id {}, val 0x{:x}", + // current_cpu().id, + // intc.event, + // vm_id, + // int_id, + // val + // ); + match intc.event { + InitcEvent::VgicdGichEn => { + let hcr = GICH.hcr(); + if val != 0 { + GICH.set_hcr(hcr | 0b1); + } else { + GICH.set_hcr(hcr & !0b1); + } + } + InitcEvent::VgicdSetEn => { + vgic.set_enable(trgt_vcpu.clone(), int_id as usize, val != 0); + } + InitcEvent::VgicdSetPend => { + vgic.set_pend(trgt_vcpu.clone(), int_id as usize, val != 0); + } + InitcEvent::VgicdSetPrio => { + vgic.set_prio(trgt_vcpu.clone(), int_id as usize, val); + } + InitcEvent::VgicdSetTrgt => { + vgic.set_trgt(trgt_vcpu.clone(), int_id as usize, val); + } + InitcEvent::VgicdRoute => { + let interrupt_option = vgic.get_int(trgt_vcpu.clone(), bit_extract(int_id as usize, 0, 10)); + if let Some(interrupt) = interrupt_option { + let interrupt_lock = interrupt.lock.lock(); + if vgic_int_get_owner(trgt_vcpu.clone(), interrupt.clone()) { + if (interrupt.targets() & (1 << current_cpu().id)) != 0 { + vgic.add_lr(trgt_vcpu.clone(), interrupt.clone()); + } + vgic_int_yield_owner(trgt_vcpu.clone(), interrupt.clone()); + } + drop(interrupt_lock); + } + } + _ => { + println!("vgic_ipi_handler: core {} received unknown event", current_cpu().id) + } + } + } + save_vcpu_gic(current_cpu().active_vcpu.clone(), trgt_vcpu.clone()); +} + +pub fn emu_intc_init(vm: Vm, emu_dev_id: usize) { + let vgic_cpu_num = vm.config().cpu_num(); + vm.init_intc_mode(true); + + let vgic = Arc::new(Vgic::default()); + + let mut vgicd = vgic.vgicd.lock(); + vgicd.typer = (GICD.typer() & GICD_TYPER_CPUNUM_MSK as u32) + | (((vm.cpu_num() - 1) << GICD_TYPER_CPUNUM_OFF) & GICD_TYPER_CPUNUM_MSK) as u32; + vgicd.iidr = GICD.iidr(); + + for i in 0..GIC_SPI_MAX { + vgicd.interrupts.push(VgicInt::new(i)); + } + drop(vgicd); + + for i in 0..vgic_cpu_num { + let mut cpu_priv = VgicCpuPriv::default(); + for int_idx in 0..GIC_PRIVINT_NUM { + let vcpu = vm.vcpu(i).unwrap(); + let phys_id = vcpu.phys_id(); + + cpu_priv.interrupts.push(VgicInt::priv_new( + int_idx, + vcpu.clone(), + 1 << phys_id, + int_idx < GIC_SGIS_NUM, + )); + } + + let mut vgic_cpu_priv = vgic.cpu_priv.lock(); + vgic_cpu_priv.push(cpu_priv); + } + + vm.set_emu_devs(emu_dev_id, EmuDevs::Vgic(vgic.clone())); +} + +pub fn partial_passthrough_intc_init(vm: Vm) { + vm.init_intc_mode(false); +} + +pub fn vgic_set_hw_int(vm: Vm, int_id: usize) { + if int_id < GIC_SGIS_NUM { + return; + } + + if !vm.has_vgic() { + return; + } + let vgic = vm.vgic(); + + if int_id < GIC_PRIVINT_NUM { + for i in 0..vm.cpu_num() { + let interrupt_option = vgic.get_int(vm.vcpu(i).unwrap(), int_id); + match interrupt_option { + Some(interrupt) => { + let interrupt_lock = interrupt.lock.lock(); + // println!( + // "vgic_set_hw_int: Core {} get int {} lock", + // cpu_id(), + // interrupt.id() + // ); + interrupt.set_hw(true); + drop(interrupt_lock); + } + None => {} + } + } + } else { + let interrupt_option = vgic.get_int(vm.vcpu(0).unwrap(), int_id); + match interrupt_option { + Some(interrupt) => { + let interrupt_lock = interrupt.lock.lock(); + // println!( + // "vgic_set_hw_int: Core {} get int {} lock", + // cpu_id(), + // interrupt.id() + // ); + interrupt.set_hw(true); + drop(interrupt_lock); + } + None => {} + } + } +} diff --git a/src/arch/mod.rs b/src/arch/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..3e5d53c9b683a9ae12dd0ce9ba840a6662253f3d --- /dev/null +++ b/src/arch/mod.rs @@ -0,0 +1,15 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::aarch64::*; +pub use self::traits::*; + +mod aarch64; +mod traits; diff --git a/src/arch/traits.rs b/src/arch/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..a5c1bb60f5306e9126e5265206c3e5a781e4b734 --- /dev/null +++ b/src/arch/traits.rs @@ -0,0 +1,32 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub trait ContextFrameTrait { + fn new(pc: usize, sp: usize, arg: usize) -> Self; + + fn exception_pc(&self) -> usize; + fn set_exception_pc(&mut self, pc: usize); + fn stack_pointer(&self) -> usize; + fn set_stack_pointer(&mut self, sp: usize); + fn set_argument(&mut self, arg: usize); + fn set_gpr(&mut self, index: usize, val: usize); + fn gpr(&self, index: usize) -> usize; +} + +pub trait ArchPageTableEntryTrait { + fn from_pte(value: usize) -> Self; + fn from_pa(pa: usize) -> Self; + fn to_pte(&self) -> usize; + fn to_pa(&self) -> usize; + fn valid(&self) -> bool; + fn entry(&self, index: usize) -> Self; + fn set_entry(&self, index: usize, value: Self); + fn make_table(frame_pa: usize) -> Self; +} diff --git a/src/board/mod.rs b/src/board/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a9b7704860937749a2c1c36dd80112cff077ae2b --- /dev/null +++ b/src/board/mod.rs @@ -0,0 +1,25 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +#[cfg(feature = "pi4")] +pub use self::pi4::*; +pub use self::platform_common::*; +#[cfg(feature = "qemu")] +pub use self::qemu::*; +#[cfg(feature = "tx2")] +pub use self::tx2::*; + +#[cfg(feature = "pi4")] +mod pi4; +mod platform_common; +#[cfg(feature = "qemu")] +mod qemu; +#[cfg(feature = "tx2")] +mod tx2; diff --git a/src/board/pi4/mod.rs b/src/board/pi4/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e79869a290f3854ae3a3e70668f5375678dfecb4 --- /dev/null +++ b/src/board/pi4/mod.rs @@ -0,0 +1,13 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::platform::*; + +mod platform; diff --git a/src/board/pi4/platform.rs b/src/board/pi4/platform.rs new file mode 100644 index 0000000000000000000000000000000000000000..833d30f79f699a3da480f596c5dee376389dd433 --- /dev/null +++ b/src/board/pi4/platform.rs @@ -0,0 +1,192 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::GicDesc; +use crate::arch::SmmuDesc; +use crate::board::{ArchDesc, PlatCpuConfig, PlatformConfig, PlatMemoryConfig, PlatMemRegion, SchedRule}; +use crate::board::SchedRule::RoundRobin; +use crate::device::ARM_CORTEX_A57; +#[allow(unused_imports)] +use crate::device::ARM_NVIDIA_DENVER; + +pub const KERNEL_ENTRY: usize = 0xF0080000; + +// pub const TIMER_FREQUENCY: usize = 62500000; + +pub const UART_0_ADDR: usize = 0xFE201000; +pub const UART_1_ADDR: usize = 0xFE201400; + +pub const UART_0_INT: usize = 32 + 0x79; +pub const UART_1_INT: usize = 32 + 0x79; + +pub const PLATFORM_GICD_BASE: usize = 0xFF841000; +pub const PLATFORM_GICC_BASE: usize = 0xFF842000; +pub const PLATFORM_GICH_BASE: usize = 0xFF844000; +pub const PLATFORM_GICV_BASE: usize = 0xFF846000; + +// pub const DISK_PARTITION_1_ADDR_SIZE: usize = 0x400; +// pub const DISK_PARTITION_1_ADDR: usize = 0xa000000; +// pub const DISK_PARTITION_2_ADDR: usize = 0xa000400; +// pub const DISK_PARTITION_3_ADDR: usize = 0xa000800; +// pub const DISK_PARTITION_4_ADDR: usize = 0xa000c00; + +pub const SHARE_MEM_BASE: usize = 0x7_0000_0000; + +// start sector number (LBA) +pub const DISK_PARTITION_0_START: usize = 2048; +pub const DISK_PARTITION_1_START: usize = 526336; +pub const DISK_PARTITION_2_START: usize = 17303552; +pub const DISK_PARTITION_3_START: usize = 34082816; +pub const DISK_PARTITION_4_START: usize = 50862080; + +// size in sector (512-byte) +// pub const DISK_PARTITION_TOTAL_SIZE: usize = 31457280; +pub const DISK_PARTITION_0_SIZE: usize = 524288; +pub const DISK_PARTITION_1_SIZE: usize = 16777216; +pub const DISK_PARTITION_2_SIZE: usize = 16777216; +pub const DISK_PARTITION_3_SIZE: usize = 16777216; +pub const DISK_PARTITION_4_SIZE: usize = 11471872; + +// pub const DISK_PARTITION_1_INT: usize = 32 + 0x10; +// pub const DISK_PARTITION_2_INT: usize = 32 + 0x11; +// pub const DISK_PARTITION_3_INT: usize = 32 + 0x12; +// pub const DISK_PARTITION_4_INT: usize = 32 + 0x13; + +//end tx2 platform const + +// extern "C" { +// fn tegra_emmc_init(); +// fn tegra_emmc_blk_read(sector: usize, count: usize, buf: *mut u8); +// fn tegra_emmc_blk_write(sector: usize, count: usize, buf: *const u8); +// } + +pub static PLAT_DESC: PlatformConfig = PlatformConfig { + cpu_desc: PlatCpuConfig { + num: 4, + mpidr_list: [0x80000000, 0x80000001, 0x80000002, 0x80000003, 0, 0, 0, 0], + name: [ARM_CORTEX_A57; 8], + sched_list: [ + RoundRobin, + RoundRobin, + RoundRobin, + RoundRobin, + SchedRule::None, + SchedRule::None, + SchedRule::None, + SchedRule::None, + ], + }, + mem_desc: PlatMemoryConfig { + region_num: 4, + regions: [ + PlatMemRegion { + base: 0xf0000000, + size: 0xc000000, + }, + PlatMemRegion { + base: 0x200000, + size: 0x3e000000 - 0x200000, + }, + PlatMemRegion { + base: 0x40000000, + size: 0xf0000000 - 0x40000000, + }, + PlatMemRegion { + base: 0x100000000, + size: 0x100000000, + }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + ], + base: 0xf0000000, + }, + uart_base: UART_0_ADDR, + arch_desc: ArchDesc { + gic_desc: GicDesc { + gicd_addr: PLATFORM_GICD_BASE, + gicc_addr: PLATFORM_GICC_BASE, + gich_addr: PLATFORM_GICH_BASE, + gicv_addr: PLATFORM_GICV_BASE, + maintenance_int_id: 25, + }, + smmu_desc: SmmuDesc { + base: 0, + interrupt_id: 0, + global_mask: 0, + }, + }, +}; + +fn platform_cpu_on(arch_core_id: usize, entry: usize, ctx: usize) { + use crate::arch::power_arch_cpu_on; + power_arch_cpu_on(arch_core_id, entry, ctx); +} + +pub fn platform_cpu_shutdown() { + crate::arch::power_arch_cpu_shutdown(); +} + +pub fn platform_power_on_secondary_cores() { + for i in 1..PLAT_DESC.cpu_desc.num { + platform_cpu_on(PLAT_DESC.cpu_desc.mpidr_list[i], KERNEL_ENTRY, 0); + } +} + +pub fn platform_sys_reboot() { + println!("Hypervisor reset..."); + // mem_heap_reset(); + crate::arch::power_arch_sys_reset(); + loop {} +} + +pub fn platform_sys_shutdown() { + println!("Hypervisor shutdown..."); + // mem_heap_reset(); + crate::arch::power_arch_sys_shutdown(); + loop {} +} + +// TODO +// pub fn platform_blk_init() { +// unsafe { +// tegra_emmc_init(); +// } +// println!("Platform block driver init ok"); +// } +// +// pub fn platform_blk_read(sector: usize, count: usize, buf: usize) { +// unsafe { +// tegra_emmc_blk_read(sector, count, buf as *mut u8); +// } +// } +// +// pub fn platform_blk_write(sector: usize, count: usize, buf: usize) { +// unsafe { +// tegra_emmc_blk_write(sector, count, buf as *const u8); +// } +// } + +pub fn platform_cpuid_to_cpuif(cpuid: usize) -> usize { + cpuid +} + +pub fn platform_cpuif_to_cpuid(cpuif: usize) -> usize { + cpuif +} diff --git a/src/board/platform_common.rs b/src/board/platform_common.rs new file mode 100644 index 0000000000000000000000000000000000000000..b1fe79deaeb64a6c1a0c9d86b877b2d5f4e8b6c7 --- /dev/null +++ b/src/board/platform_common.rs @@ -0,0 +1,57 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::GicDesc; +use crate::arch::SmmuDesc; + +pub const PLATFORM_CPU_NUM_MAX: usize = 8; +pub const TOTAL_MEM_REGION_MAX: usize = 16; +pub const PLATFORM_VCPU_NUM_MAX: usize = 8; + +#[repr(C)] +pub enum SchedRule { + RoundRobin, + None, +} + +#[repr(C)] +pub struct PlatMemRegion { + pub base: usize, + pub size: usize, +} + +#[repr(C)] +pub struct PlatMemoryConfig { + pub region_num: usize, + pub base: usize, + pub regions: [PlatMemRegion; TOTAL_MEM_REGION_MAX], +} + +#[repr(C)] +pub struct PlatCpuConfig { + pub num: usize, + pub name: [u8; PLATFORM_CPU_NUM_MAX], + pub mpidr_list: [usize; PLATFORM_CPU_NUM_MAX], + pub sched_list: [SchedRule; PLATFORM_CPU_NUM_MAX], +} + +#[repr(C)] +pub struct ArchDesc { + pub gic_desc: GicDesc, + pub smmu_desc: SmmuDesc, +} + +#[repr(C)] +pub struct PlatformConfig { + pub cpu_desc: PlatCpuConfig, + pub mem_desc: PlatMemoryConfig, + pub uart_base: usize, + pub arch_desc: ArchDesc, +} diff --git a/src/board/qemu/mod.rs b/src/board/qemu/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e79869a290f3854ae3a3e70668f5375678dfecb4 --- /dev/null +++ b/src/board/qemu/mod.rs @@ -0,0 +1,13 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::platform::*; + +mod platform; diff --git a/src/board/qemu/platform.rs b/src/board/qemu/platform.rs new file mode 100644 index 0000000000000000000000000000000000000000..fcb648af764f12c4cff89f258cead6316b294861 --- /dev/null +++ b/src/board/qemu/platform.rs @@ -0,0 +1,150 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +// TODO: move these core name to device +use crate::arch::GicDesc; +use crate::arch::SmmuDesc; +use crate::board::{ArchDesc, PlatCpuConfig, PlatformConfig, PlatMemoryConfig, PlatMemRegion}; +use crate::board::SchedRule::{self, RoundRobin}; +use crate::device::ARM_CORTEX_A57; +use crate::driver::{read, write}; + +pub const KERNEL_ENTRY: usize = 0x43000000; + +pub const TIMER_FREQUENCY: usize = 62500000; + +pub const UART_0_ADDR: usize = 0x9000000; +pub const UART_1_ADDR: usize = 0x9100000; +pub const UART_2_ADDR: usize = 0x9110000; + +pub const UART_1_INT: usize = 42; +pub const UART_2_INT: usize = 43; + +// Hardcode +pub const SHARE_MEM_BASE: usize = 0x7_0000_0000; + +pub const PLATFORM_GICD_BASE: usize = 0x08000000; +pub const PLATFORM_GICC_BASE: usize = 0x08010000; +pub const PLATFORM_GICH_BASE: usize = 0x08030000; +pub const PLATFORM_GICV_BASE: usize = 0x08040000; + +pub const DISK_PARTITION_0_START: usize = 0; +pub const DISK_PARTITION_1_START: usize = 2097152; +pub const DISK_PARTITION_2_START: usize = 10289152; + +pub const DISK_PARTITION_TOTAL_SIZE: usize = 18481152; +pub const DISK_PARTITION_0_SIZE: usize = 524288; +pub const DISK_PARTITION_1_SIZE: usize = 8192000; +pub const DISK_PARTITION_2_SIZE: usize = 8192000; + +// holy shit, need to recode later +pub static PLAT_DESC: PlatformConfig = PlatformConfig { + cpu_desc: PlatCpuConfig { + num: 4, + mpidr_list: [0, 1, 2, 3, 4, 5, 6, 7], + name: [ARM_CORTEX_A57; 8], + sched_list: [ + RoundRobin, + RoundRobin, + RoundRobin, + RoundRobin, + SchedRule::None, + SchedRule::None, + SchedRule::None, + SchedRule::None, + ], + }, + mem_desc: PlatMemoryConfig { + region_num: 2, + regions: [ + PlatMemRegion { + base: 0x40000000, + size: 0x10000000, + }, + PlatMemRegion { + base: 0x50000000, + size: 0x1f0000000, + }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + ], + base: 0x40000000, + }, + uart_base: UART_0_ADDR, + arch_desc: ArchDesc { + gic_desc: GicDesc { + gicd_addr: PLATFORM_GICD_BASE, + gicc_addr: PLATFORM_GICC_BASE, + gich_addr: PLATFORM_GICH_BASE, + gicv_addr: PLATFORM_GICV_BASE, + maintenance_int_id: 25, + }, + smmu_desc: SmmuDesc { + base: 0, + interrupt_id: 0, + global_mask: 0, + }, + }, +}; + +fn platform_cpu_on(arch_core_id: usize, entry: usize, ctx: usize) { + use crate::arch::power_arch_cpu_on; + power_arch_cpu_on(arch_core_id, entry, ctx); +} + +pub fn platform_cpu_shutdown() { + crate::arch::power_arch_cpu_shutdown(); +} + +pub fn platform_power_on_secondary_cores() { + for i in 1..PLAT_DESC.cpu_desc.num { + platform_cpu_on(PLAT_DESC.cpu_desc.mpidr_list[i], KERNEL_ENTRY, 0); + } +} + +pub fn platform_sys_reboot() { + println!("Hypervisor reset..."); + // mem_heap_reset(); + crate::arch::power_arch_sys_reset(); + loop {} +} + +pub fn platform_blk_init() { + println!("Platform block driver init ok"); + crate::driver::virtio_blk_init(); +} + +pub fn platform_blk_read(sector: usize, count: usize, buf: usize) { + read(sector, count, buf); +} + +pub fn platform_blk_write(sector: usize, count: usize, buf: usize) { + write(sector, count, buf); +} + +pub fn platform_cpuid_to_cpuif(cpuid: usize) -> usize { + cpuid +} + +pub fn platform_cpuif_to_cpuid(cpuif: usize) -> usize { + cpuif +} diff --git a/src/board/tx2/mod.rs b/src/board/tx2/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e79869a290f3854ae3a3e70668f5375678dfecb4 --- /dev/null +++ b/src/board/tx2/mod.rs @@ -0,0 +1,13 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::platform::*; + +mod platform; diff --git a/src/board/tx2/platform.rs b/src/board/tx2/platform.rs new file mode 100644 index 0000000000000000000000000000000000000000..01a311e925bff2451145eaf6f8dc3e1a5f5e84c3 --- /dev/null +++ b/src/board/tx2/platform.rs @@ -0,0 +1,185 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::GicDesc; +use crate::arch::SmmuDesc; +use crate::board::{ArchDesc, PlatCpuConfig, PlatformConfig, PlatMemoryConfig, PlatMemRegion, SchedRule}; +use crate::board::SchedRule::RoundRobin; +use crate::device::ARM_CORTEX_A57; +#[allow(unused_imports)] +use crate::device::ARM_NVIDIA_DENVER; + +pub const KERNEL_ENTRY: usize = 0x83000000; + +// pub const TIMER_FREQUENCY: usize = 62500000; + +pub const UART_0_ADDR: usize = 0x3100000; +pub const UART_1_ADDR: usize = 0xc280000; + +pub const UART_0_INT: usize = 32 + 0x70; +pub const UART_1_INT: usize = 32 + 0x72; + +pub const PLATFORM_GICD_BASE: usize = 0x3881000; +pub const PLATFORM_GICC_BASE: usize = 0x3882000; +pub const PLATFORM_GICH_BASE: usize = 0x3884000; +pub const PLATFORM_GICV_BASE: usize = 0x3886000; + +// pub const DISK_PARTITION_1_ADDR_SIZE: usize = 0x400; +// pub const DISK_PARTITION_1_ADDR: usize = 0xa000000; +// pub const DISK_PARTITION_2_ADDR: usize = 0xa000400; +// pub const DISK_PARTITION_3_ADDR: usize = 0xa000800; +// pub const DISK_PARTITION_4_ADDR: usize = 0xa000c00; + +// start sector number (LBA) +pub const DISK_PARTITION_0_START: usize = 43643256; +pub const DISK_PARTITION_1_START: usize = 4104; +pub const DISK_PARTITION_2_START: usize = 45740408; + +// size in sector (512-byte) +// pub const DISK_PARTITION_TOTAL_SIZE: usize = 31457280; +pub const DISK_PARTITION_0_SIZE: usize = 2097152; +pub const DISK_PARTITION_1_SIZE: usize = 41943040; +pub const DISK_PARTITION_2_SIZE: usize = 8388608; + +// pub const DISK_PARTITION_1_INT: usize = 32 + 0x10; +// pub const DISK_PARTITION_2_INT: usize = 32 + 0x11; +// pub const DISK_PARTITION_3_INT: usize = 32 + 0x12; +// pub const DISK_PARTITION_4_INT: usize = 32 + 0x13; + +pub const SHARE_MEM_BASE: usize = 0xd_0000_0000; + +//end tx2 platform const + +// extern "C" { +// fn tegra_emmc_init(); +// fn tegra_emmc_blk_read(sector: usize, count: usize, buf: *mut u8); +// fn tegra_emmc_blk_write(sector: usize, count: usize, buf: *const u8); +// } + +pub static PLAT_DESC: PlatformConfig = PlatformConfig { + cpu_desc: PlatCpuConfig { + num: 4, + mpidr_list: [0x80000100, 0x80000101, 0x80000102, 0x80000103, 0, 0, 0, 0], + name: [ARM_CORTEX_A57; 8], + sched_list: [ + RoundRobin, + RoundRobin, + RoundRobin, + RoundRobin, + SchedRule::None, + SchedRule::None, + SchedRule::None, + SchedRule::None, + ], + }, + mem_desc: PlatMemoryConfig { + region_num: 3, + regions: [ + PlatMemRegion { + base: 0x80000000, + size: 0x10000000, + }, + PlatMemRegion { + base: 0x90000000, + size: 0x60000000, + }, + PlatMemRegion { + base: 0xf0200000, + size: 0x185600000, + }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + PlatMemRegion { base: 0, size: 0 }, + ], + base: 0x80000000, + }, + uart_base: UART_0_ADDR, + arch_desc: ArchDesc { + gic_desc: GicDesc { + gicd_addr: PLATFORM_GICD_BASE, + gicc_addr: PLATFORM_GICC_BASE, + gich_addr: PLATFORM_GICH_BASE, + gicv_addr: PLATFORM_GICV_BASE, + maintenance_int_id: 25, + }, + smmu_desc: SmmuDesc { + base: 0x12000000, + interrupt_id: 187, + global_mask: 0x7f80, + }, + }, +}; + +fn platform_cpu_on(arch_core_id: usize, entry: usize, ctx: usize) { + use crate::arch::power_arch_cpu_on; + power_arch_cpu_on(arch_core_id, entry, ctx); +} + +pub fn platform_cpu_shutdown() { + crate::arch::power_arch_cpu_shutdown(); +} + +pub fn platform_power_on_secondary_cores() { + for i in 1..PLAT_DESC.cpu_desc.num { + platform_cpu_on(PLAT_DESC.cpu_desc.mpidr_list[i], KERNEL_ENTRY, 0); + } +} + +pub fn platform_sys_reboot() { + println!("Hypervisor reset..."); + // mem_heap_reset(); + crate::arch::power_arch_sys_reset(); + loop {} +} + +pub fn platform_sys_shutdown() { + println!("Hypervisor shutdown..."); + // mem_heap_reset(); + crate::arch::power_arch_sys_shutdown(); + loop {} +} + +// TODO +// pub fn platform_blk_init() { +// unsafe { +// tegra_emmc_init(); +// } +// println!("Platform block driver init ok"); +// } +// +// pub fn platform_blk_read(sector: usize, count: usize, buf: usize) { +// unsafe { +// tegra_emmc_blk_read(sector, count, buf as *mut u8); +// } +// } +// +// pub fn platform_blk_write(sector: usize, count: usize, buf: usize) { +// unsafe { +// tegra_emmc_blk_write(sector, count, buf as *const u8); +// } +// } + +pub fn platform_cpuid_to_cpuif(cpuid: usize) -> usize { + cpuid + PLAT_DESC.cpu_desc.num +} + +pub fn platform_cpuif_to_cpuid(cpuif: usize) -> usize { + cpuif - PLAT_DESC.cpu_desc.num +} diff --git a/src/config/config.rs b/src/config/config.rs new file mode 100644 index 0000000000000000000000000000000000000000..68ec0d7ea3bd83204b1c2665c59ea9d05c19e4e5 --- /dev/null +++ b/src/config/config.rs @@ -0,0 +1,1067 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::string::{String, ToString}; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use spin::Mutex; + +// use crate::board::*; +use crate::device::{EmuDeviceType, mediated_blk_free, mediated_blk_request}; +use crate::kernel::{active_vm, vm, Vm, vm_ipa2pa, VM_NUM_MAX, VmType}; +use crate::lib::{BitAlloc, BitAlloc16, memcpy_safe}; +use crate::vmm::vmm_init_gvm; + +pub const NAME_MAX_LEN: usize = 32; +const CFG_MAX_NUM: usize = 0x10; +const IRQ_MAX_NUM: usize = 0x40; +const PASSTHROUGH_DEV_MAX_NUM: usize = 128; +const EMULATED_DEV_MAX_NUM: usize = 16; + +#[derive(Clone, Copy, PartialEq)] +pub enum DtbDevType { + DevSerial = 0, + DevGicd = 1, + DevGicc = 2, +} + +impl DtbDevType { + pub fn from_usize(value: usize) -> DtbDevType { + match value { + 0 => DtbDevType::DevSerial, + 1 => DtbDevType::DevGicd, + 2 => DtbDevType::DevGicc, + _ => panic!("Unknown DtbDevType value: {}", value), + } + } +} + +#[derive(Clone)] +pub struct VmEmulatedDeviceConfig { + pub name: Option, + pub base_ipa: usize, + pub length: usize, + pub irq_id: usize, + pub cfg_list: Vec, + pub emu_type: EmuDeviceType, + pub mediated: bool, +} + +pub struct VmEmulatedDeviceConfigList { + pub emu_dev_list: Vec, +} + +impl VmEmulatedDeviceConfigList { + pub const fn default() -> VmEmulatedDeviceConfigList { + VmEmulatedDeviceConfigList { + emu_dev_list: Vec::new(), + } + } +} + +#[derive(Default, Clone, Copy, Debug, Eq)] +pub struct PassthroughRegion { + pub ipa: usize, + pub pa: usize, + pub length: usize, + pub dev_property: bool, +} + +impl PartialEq for PassthroughRegion { + fn eq(&self, other: &Self) -> bool { + self.ipa == other.ipa && self.pa == other.pa && self.length == other.length + } +} + +#[derive(Default, Clone)] +pub struct VmPassthroughDeviceConfig { + pub regions: Vec, + pub irqs: Vec, + pub streams_ids: Vec, +} + +impl VmPassthroughDeviceConfig { + pub const fn default() -> VmPassthroughDeviceConfig { + VmPassthroughDeviceConfig { + regions: Vec::new(), + irqs: Vec::new(), + streams_ids: Vec::new(), + } + } +} + +#[derive(Clone, Copy, Debug, Eq)] +pub struct VmRegion { + pub ipa_start: usize, + pub length: usize, +} + +impl VmRegion { + pub const fn default() -> VmRegion { + VmRegion { + ipa_start: 0, + length: 0, + } + } +} + +impl PartialEq for VmRegion { + fn eq(&self, other: &Self) -> bool { + self.ipa_start == other.ipa_start && self.length == other.length + } +} + +#[derive(Clone)] +pub struct VmMemoryConfig { + pub region: Vec, +} + +impl VmMemoryConfig { + pub const fn default() -> VmMemoryConfig { + VmMemoryConfig { region: vec![] } + } +} + +#[derive(Clone, Copy)] +pub struct VmImageConfig { + pub kernel_img_name: Option<&'static str>, + pub kernel_load_ipa: usize, + pub kernel_load_pa: usize, + pub kernel_entry_point: usize, + // pub device_tree_filename: Option<&'static str>, + pub device_tree_load_ipa: usize, + // pub ramdisk_filename: Option<&'static str>, + pub ramdisk_load_ipa: usize, + pub mediated_block_index: Option, +} + +impl VmImageConfig { + pub const fn default() -> VmImageConfig { + VmImageConfig { + kernel_img_name: None, + kernel_load_ipa: 0, + kernel_load_pa: 0, + kernel_entry_point: 0, + // device_tree_filename: None, + device_tree_load_ipa: 0, + // ramdisk_filename: None, + ramdisk_load_ipa: 0, + mediated_block_index: None, + } + } + pub fn new(kernel_load_ipa: usize, device_tree_load_ipa: usize, ramdisk_load_ipa: usize) -> VmImageConfig { + VmImageConfig { + kernel_img_name: None, + kernel_load_ipa, + kernel_load_pa: 0, + kernel_entry_point: kernel_load_ipa, + // device_tree_filename: None, + device_tree_load_ipa, + // ramdisk_filename: None, + ramdisk_load_ipa, + mediated_block_index: None, + } + } +} + +#[derive(Clone, Copy)] +pub struct VmCpuConfig { + pub num: usize, + pub allocate_bitmap: u32, + pub master: i32, +} + +impl VmCpuConfig { + pub const fn default() -> VmCpuConfig { + VmCpuConfig { + num: 0, + allocate_bitmap: 0, + master: 0, + } + } +} + +#[derive(Clone, Copy)] +pub struct AddrRegions { + pub ipa: usize, + pub length: usize, +} + +#[derive(Clone)] +pub struct VmDtbDevConfig { + pub name: String, + pub dev_type: DtbDevType, + pub irqs: Vec, + pub addr_region: AddrRegions, +} + +#[derive(Clone)] +pub struct VMDtbDevConfigList { + pub dtb_device_list: Vec, +} + +impl VMDtbDevConfigList { + pub const fn default() -> VMDtbDevConfigList { + VMDtbDevConfigList { + dtb_device_list: Vec::new(), + } + } +} + +#[derive(Clone)] +pub struct VmConfigEntry { + // VM id, generate inside hypervisor. + pub id: usize, + // Following configs are not intended to be modified during configuration. + pub name: Option, + pub os_type: VmType, + pub cmdline: String, + // Following config can be modified during configuration. + pub image: Arc>, + pub memory: Arc>, + pub cpu: Arc>, + pub vm_emu_dev_confg: Arc>, + pub vm_pt_dev_confg: Arc>, + pub vm_dtb_devs: Arc>, +} + +impl VmConfigEntry { + pub fn default() -> VmConfigEntry { + VmConfigEntry { + id: 0, + name: Some(String::from("unknown")), + os_type: VmType::VmTBma, + + cmdline: String::from("root=/dev/vda rw audit=0"), + + image: Arc::new(Mutex::new(VmImageConfig::default())), + memory: Arc::new(Mutex::new(VmMemoryConfig::default())), + cpu: Arc::new(Mutex::new(VmCpuConfig::default())), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList::default())), + vm_pt_dev_confg: Arc::new(Mutex::new(VmPassthroughDeviceConfig::default())), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList::default())), + } + } + + pub fn new( + name: String, + cmdline: String, + vm_type: usize, + kernel_load_ipa: usize, + device_tree_load_ipa: usize, + ramdisk_load_ipa: usize, + ) -> VmConfigEntry { + VmConfigEntry { + id: 0, + name: Some(name), + os_type: VmType::from_usize(vm_type), + cmdline, + image: Arc::new(Mutex::new(VmImageConfig::new( + kernel_load_ipa, + device_tree_load_ipa, + ramdisk_load_ipa, + ))), + memory: Arc::new(Mutex::new(VmMemoryConfig::default())), + cpu: Arc::new(Mutex::new(VmCpuConfig::default())), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList::default())), + vm_pt_dev_confg: Arc::new(Mutex::new(VmPassthroughDeviceConfig::default())), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList::default())), + } + } + + pub fn id(&self) -> usize { + self.id + } + + pub fn set_id(&mut self, id: usize) { + self.id = id; + } + + pub fn vm_name(&self) -> String { + match &self.name { + Some(name) => name.to_string(), + None => String::from("unknown"), + } + } + + pub fn mediated_block_index(&self) -> Option { + let img_cfg = self.image.lock(); + img_cfg.mediated_block_index + } + + pub fn set_mediated_block_index(&mut self, med_blk_id: usize) { + let mut img_cfg = self.image.lock(); + // println!("set_mediated_block_index {}",med_blk_id); + img_cfg.mediated_block_index = Some(med_blk_id); + // println!("set_mediated_block_index {} self.med_blk_idx {:?}",med_blk_id, img_cfg.mediated_block_index); + } + + pub fn kernel_img_name(&self) -> Option<&'static str> { + let img_cfg = self.image.lock(); + img_cfg.kernel_img_name + } + + pub fn kernel_load_ipa(&self) -> usize { + let img_cfg = self.image.lock(); + img_cfg.kernel_load_ipa + } + + pub fn set_kernel_load_pa(&mut self, kernel_load_pa: usize) { + let mut img_cfg = self.image.lock(); + img_cfg.kernel_load_pa = kernel_load_pa + } + + pub fn kernel_load_pa(&self) -> usize { + let img_cfg = self.image.lock(); + img_cfg.kernel_load_pa + } + + pub fn kernel_entry_point(&self) -> usize { + let img_cfg = self.image.lock(); + img_cfg.kernel_entry_point + } + + pub fn device_tree_load_ipa(&self) -> usize { + let img_cfg = self.image.lock(); + img_cfg.device_tree_load_ipa + } + + pub fn ramdisk_load_ipa(&self) -> usize { + let img_cfg = self.image.lock(); + img_cfg.ramdisk_load_ipa + } + + pub fn memory_region(&self) -> Vec { + let mem_cfg = self.memory.lock(); + mem_cfg.region.clone() + } + + pub fn add_memory_cfg(&self, ipa_start: usize, length: usize) { + let mut mem_cfg = self.memory.lock(); + mem_cfg.region.push(VmRegion { ipa_start, length }); + } + + pub fn cpu_num(&self) -> usize { + let cpu_cfg = self.cpu.lock(); + cpu_cfg.num + } + + pub fn cpu_allocated_bitmap(&self) -> u32 { + let cpu_cfg = self.cpu.lock(); + cpu_cfg.allocate_bitmap + } + + pub fn cpu_master(&self) -> usize { + let cpu_cfg = self.cpu.lock(); + cpu_cfg.master as usize + } + + pub fn set_cpu_cfg(&self, num: usize, allocate_bitmap: usize, master: usize) { + let mut cpu_cfg = self.cpu.lock(); + cpu_cfg.num = usize::min(num, allocate_bitmap.count_ones() as usize); + cpu_cfg.allocate_bitmap = allocate_bitmap as u32; + cpu_cfg.master = master as i32; + } + + pub fn emulated_device_list(&self) -> Vec { + let emu_dev_cfg = self.vm_emu_dev_confg.lock(); + emu_dev_cfg.emu_dev_list.clone() + } + + pub fn add_emulated_device_cfg(&self, cfg: VmEmulatedDeviceConfig) { + let mut emu_dev_cfgs = self.vm_emu_dev_confg.lock(); + emu_dev_cfgs.emu_dev_list.push(cfg); + } + + pub fn passthrough_device_regions(&self) -> Vec { + let pt_dev_cfg = self.vm_pt_dev_confg.lock(); + pt_dev_cfg.regions.clone() + } + + pub fn passthrough_device_irqs(&self) -> Vec { + let pt_dev_cfg = self.vm_pt_dev_confg.lock(); + pt_dev_cfg.irqs.clone() + } + + pub fn passthrough_device_stread_ids(&self) -> Vec { + let pt_dev_cfg = self.vm_pt_dev_confg.lock(); + pt_dev_cfg.streams_ids.clone() + } + + pub fn add_passthrough_device_region(&self, base_ipa: usize, base_pa: usize, length: usize) { + let mut pt_dev_cfg = self.vm_pt_dev_confg.lock(); + let pt_region_cfg = PassthroughRegion { + ipa: base_ipa, + pa: base_pa, + length, + dev_property: true, + }; + pt_dev_cfg.regions.push(pt_region_cfg) + } + + pub fn add_passthrough_device_irqs(&self, irqs: &mut Vec) { + let mut pt_dev_cfg = self.vm_pt_dev_confg.lock(); + pt_dev_cfg.irqs.append(irqs); + } + + pub fn add_passthrough_device_streams_ids(&self, streams_ids: &mut Vec) { + let mut pt_dev_cfg = self.vm_pt_dev_confg.lock(); + pt_dev_cfg.streams_ids.append(streams_ids); + } + + pub fn dtb_device_list(&self) -> Vec { + let dtb_dev_cfg = self.vm_dtb_devs.lock(); + dtb_dev_cfg.dtb_device_list.clone() + } + + pub fn add_dtb_device(&self, cfg: VmDtbDevConfig) { + let mut dtb_dev_cfg = self.vm_dtb_devs.lock(); + dtb_dev_cfg.dtb_device_list.push(cfg); + } + + pub fn gicc_addr(&self) -> usize { + let dtb_devs = self.vm_dtb_devs.lock(); + for dev in &dtb_devs.dtb_device_list { + match dev.dev_type { + DtbDevType::DevGicc => { + return dev.addr_region.ipa; + } + _ => {} + } + } + 0 + } + + pub fn gicd_addr(&self) -> usize { + let dtb_devs = self.vm_dtb_devs.lock(); + for dev in &dtb_devs.dtb_device_list { + match dev.dev_type { + DtbDevType::DevGicd => { + return dev.addr_region.ipa; + } + _ => {} + } + } + 0 + } +} + +#[derive(Clone)] +pub struct VmConfigTable { + pub name: Option<&'static str>, + pub vm_bitmap: BitAlloc16, + pub vm_num: usize, + pub entries: Vec, +} + +impl VmConfigTable { + pub const fn default() -> VmConfigTable { + VmConfigTable { + name: None, + vm_bitmap: BitAlloc16::default(), + vm_num: 0, + entries: Vec::new(), + } + } + + pub fn generate_vm_id(&mut self) -> Result { + for i in 0..VM_NUM_MAX { + if self.vm_bitmap.get(i) == 0 { + self.vm_bitmap.set(i); + return Ok(i); + } + } + Err(()) + } + + pub fn remove_vm_id(&mut self, vm_id: usize) { + if vm_id >= VM_NUM_MAX || self.vm_bitmap.get(vm_id) == 0 { + println!("illegal vm id {}", vm_id); + } + self.vm_bitmap.clear(vm_id); + } +} + +// lazy_static! { +pub static DEF_VM_CONFIG_TABLE: Mutex = Mutex::new(VmConfigTable::default()); +// } + +pub fn vm_cfg_set_config_name(name: &'static str) { + let mut vm_config = DEF_VM_CONFIG_TABLE.lock(); + vm_config.name = Some(name); +} + +pub fn vm_num() -> usize { + let vm_config = DEF_VM_CONFIG_TABLE.lock(); + vm_config.entries.len() +} + +pub fn vm_type(vmid: usize) -> VmType { + let vm_config = DEF_VM_CONFIG_TABLE.lock(); + for vm_cfg_entry in vm_config.entries.iter() { + if vm_cfg_entry.id == vmid { + return vm_cfg_entry.os_type; + } + } + println!("failed to find VM[{}] in vm cfg entry list", vmid); + return VmType::VmTOs; +} + +pub fn vm_id_list() -> Vec { + let vm_config = DEF_VM_CONFIG_TABLE.lock(); + let mut id_list: Vec = Vec::new(); + for vm_cfg_entry in vm_config.entries.iter() { + id_list.push(vm_cfg_entry.id) + } + id_list +} + +pub fn vm_cfg_entry(vmid: usize) -> Option { + let vm_config = DEF_VM_CONFIG_TABLE.lock(); + for vm_cfg_entry in vm_config.entries.iter() { + if vm_cfg_entry.id == vmid { + return Some(vm_cfg_entry.clone()); + } + } + println!("failed to find VM[{}] in vm cfg entry list", vmid); + return None; +} + +/* Add VM config entry to DEF_VM_CONFIG_TABLE */ +pub fn vm_cfg_add_vm_entry(mut vm_cfg_entry: VmConfigEntry) -> Result { + let mut vm_config = DEF_VM_CONFIG_TABLE.lock(); + match vm_config.generate_vm_id() { + Ok(vm_id) => { + if vm_id == 0 && (vm_config.entries.len() > 0 || vm_config.vm_num > 0) { + panic!("error in mvm config init, the def vm config table is not empty"); + } + vm_cfg_entry.set_id(vm_id); + vm_config.vm_num += 1; + vm_config.entries.push(vm_cfg_entry.clone()); + println!( + "\nSuccessfully add {}[{}] name {:?}, currently vm_num {}", + if vm_id == 0 { "MVM" } else { "GVM" }, + vm_cfg_entry.id(), + vm_cfg_entry.clone().name.unwrap(), + vm_config.vm_num + ); + + Ok(vm_id) + } + Err(_) => { + println!("vm_cfg_add_vm_entry, vm num reached max value"); + Err(()) + } + } +} + +pub fn vm_cfg_remove_vm_entry(vm_id: usize) { + let mut vm_config = DEF_VM_CONFIG_TABLE.lock(); + for (idx, vm_cfg_entry) in vm_config.entries.iter().enumerate() { + if vm_cfg_entry.id == vm_id { + vm_config.vm_num -= 1; + vm_config.remove_vm_id(vm_id); + match vm_config.entries[idx].mediated_block_index() { + None => {} + Some(block_idx) => { + mediated_blk_free(block_idx); + } + } + vm_config.entries.remove(idx); + // println!("remove VM[{}] config from vm-config-table", vm_id); + return; + } + } + println!("VM[{}] config not found in vm-config-table", vm_id); +} + +/* Generate a new VM Config Entry, set basic value */ +pub fn vm_cfg_add_vm(config_ipa: usize) -> Result { + let config_pa = vm_ipa2pa(active_vm().unwrap(), config_ipa); + let ( + vm_name_ipa, + vm_name_length, + vm_type, + cmdline_ipa, + cmdline_length, + kernel_load_ipa, + device_tree_load_ipa, + ramdisk_load_ipa, + ) = unsafe { *(config_pa as *const _) }; + println!("\n\nStart to prepare configuration for new VM"); + + // Copy VM name from user ipa. + let vm_name_pa = vm_ipa2pa(active_vm().unwrap(), vm_name_ipa); + if vm_name_pa == 0 { + println!("illegal vm_name_ipa {:x}", vm_name_ipa); + return Err(()); + } + let vm_name_u8 = vec![0 as u8; vm_name_length]; + if vm_name_length > 0 { + memcpy_safe( + &vm_name_u8[0] as *const _ as *const u8, + vm_name_pa as *mut u8, + vm_name_length, + ); + } + + let vm_name_str = match String::from_utf8(vm_name_u8.clone()) { + Ok(_str) => _str, + Err(error) => { + println!("error: {:?} in parsing the vm_name {:?}", error, vm_name_u8); + String::from("unknown") + } + }; + + // Copy VM cmdline from user ipa. + let cmdline_pa = vm_ipa2pa(active_vm().unwrap(), cmdline_ipa); + if cmdline_pa == 0 { + println!("illegal cmdline_ipa {:x}", cmdline_ipa); + return Err(()); + } + let cmdline_u8 = vec![0 as u8; cmdline_length]; + if cmdline_length > 0 { + memcpy_safe( + &cmdline_u8[0] as *const _ as *const u8, + cmdline_pa as *mut u8, + cmdline_length, + ); + } + let cmdline_str = match String::from_utf8(cmdline_u8.clone()) { + Ok(_str) => _str, + Err(error) => { + println!("error: {:?} in parsing the cmdline {:?}", error, cmdline_u8); + String::from("unknown") + } + }; + + // Generate a new VM config entry. + let new_vm_cfg = VmConfigEntry::new( + vm_name_str, + cmdline_str, + vm_type, + kernel_load_ipa, + device_tree_load_ipa, + ramdisk_load_ipa, + ); + + println!(" VM name is [{:?}]", new_vm_cfg.name.clone().unwrap()); + println!(" cmdline is [{:?}]", new_vm_cfg.cmdline.clone()); + println!(" ramdisk is [0x{:x}]", new_vm_cfg.ramdisk_load_ipa()); + vm_cfg_add_vm_entry(new_vm_cfg) +} + +/* Delete a VM config entry */ +pub fn vm_cfg_del_vm(vmid: usize) -> Result { + println!("VM[{}] delete config entry", vmid); + vm_cfg_remove_vm_entry(vmid); + Ok(0) +} + +/* Add VM memory region according to VM id */ +pub fn vm_cfg_add_mem_region(vmid: usize, ipa_start: usize, length: usize) -> Result { + let vm_cfg = match vm_cfg_entry(vmid) { + Some(vm_cfg) => vm_cfg, + None => return Err(()), + }; + vm_cfg.add_memory_cfg(ipa_start, length); + println!( + "\nVM[{}] vm_cfg_add_mem_region: add region start_ipa {:x} length {:x}", + vmid, ipa_start, length + ); + Ok(0) +} + +/* Set VM cpu config according to VM id */ +pub fn vm_cfg_set_cpu(vmid: usize, num: usize, allocate_bitmap: usize, master: usize) -> Result { + let vm_cfg = match vm_cfg_entry(vmid) { + Some(vm_cfg) => vm_cfg, + None => return Err(()), + }; + + vm_cfg.set_cpu_cfg(num, allocate_bitmap, master); + + println!( + "\nVM[{}] vm_cfg_set_cpu: num {} allocate_bitmap {} master {}", + vmid, + vm_cfg.cpu_num(), + vm_cfg.cpu_allocated_bitmap(), + vm_cfg.cpu_master() + ); + + Ok(0) +} + +/* Add emulated device config for VM */ +pub fn vm_cfg_add_emu_dev( + vmid: usize, + name_ipa: usize, + base_ipa: usize, + length: usize, + irq_id: usize, + cfg_list_ipa: usize, + emu_type: usize, +) -> Result { + let mut vm_cfg = match vm_cfg_entry(vmid) { + Some(vm_cfg) => vm_cfg, + None => return Err(()), + }; + let emu_cfg_list = vm_cfg.emulated_device_list(); + + // Copy emu device name from user ipa. + let name_pa = vm_ipa2pa(active_vm().unwrap(), name_ipa); + if name_pa == 0 { + println!("illegal emulated device name_ipa {:x}", name_ipa); + return Err(()); + } + let name_u8 = vec![0 as u8; NAME_MAX_LEN]; + memcpy_safe(&name_u8[0] as *const _ as *const u8, name_pa as *mut u8, NAME_MAX_LEN); + let name_str = match String::from_utf8(name_u8.clone()) { + Ok(str) => str, + Err(error) => { + println!("error: {:?} in parsing the emulated device name {:?}", error, name_u8); + String::from("unknown") + } + }; + // Copy emu device cfg list from user ipa. + let cfg_list_pa = vm_ipa2pa(active_vm().unwrap(), cfg_list_ipa); + if cfg_list_pa == 0 { + println!("illegal emulated device cfg_list_ipa {:x}", cfg_list_ipa); + return Err(()); + } + let cfg_list = vec![0 as usize; CFG_MAX_NUM]; + memcpy_safe( + &cfg_list[0] as *const _ as *const u8, + cfg_list_pa as *mut u8, + CFG_MAX_NUM * 8, // sizeof(usize) / sizeof(u8) + ); + + println!( + concat!( + "\nVM[{}] vm_cfg_add_emu_dev: ori emu dev num {}\n", + " name {:?}\n", + " cfg_list {:?}\n", + " base ipa {:x} length {:x} irq_id {} emu_type {}" + ), + vmid, + emu_cfg_list.len(), + name_str.clone().trim_end_matches(char::from(0)), + cfg_list, + base_ipa, + length, + irq_id, + emu_type + ); + + let emu_dev_type = EmuDeviceType::from_usize(emu_type); + let emu_dev_cfg = VmEmulatedDeviceConfig { + name: Some(name_str.trim_end_matches(char::from(0)).to_string()), + base_ipa, + length, + irq_id, + cfg_list, + emu_type: match emu_dev_type { + EmuDeviceType::EmuDeviceTVirtioBlkMediated => EmuDeviceType::EmuDeviceTVirtioBlk, + _ => emu_dev_type.clone(), + }, + mediated: match EmuDeviceType::from_usize(emu_type) { + EmuDeviceType::EmuDeviceTVirtioBlkMediated => true, + _ => false, + }, + }; + vm_cfg.add_emulated_device_cfg(emu_dev_cfg); + + // Set GVM Mediated Blk Index Here. + if emu_dev_type == EmuDeviceType::EmuDeviceTVirtioBlkMediated { + let med_blk_index = match mediated_blk_request() { + Ok(idx) => idx, + Err(_) => { + println!("no more medaited blk for vm {}", vmid); + return Err(()); + } + }; + vm_cfg.set_mediated_block_index(med_blk_index); + } + + Ok(0) +} + +/* Add passthrough device config region for VM */ +pub fn vm_cfg_add_passthrough_device_region( + vmid: usize, + base_ipa: usize, + base_pa: usize, + length: usize, +) -> Result { + // Get VM config entry. + let vm_cfg = match vm_cfg_entry(vmid) { + Some(vm_cfg) => vm_cfg, + None => return Err(()), + }; + // Get passthrough device config list. + let pt_dev_regions = vm_cfg.passthrough_device_regions(); + + println!( + concat!( + "\nVM[{}] vm_cfg_add_pt_dev: ori pt dev regions num {}\n", + " base_ipa {:x} base_pa {:x} length {:x}" + ), + vmid, + pt_dev_regions.len(), + base_ipa, + base_pa, + length + ); + + vm_cfg.add_passthrough_device_region(base_ipa, base_pa, length); + Ok(0) +} + +/* Add passthrough device config irqs for VM */ +pub fn vm_cfg_add_passthrough_device_irqs(vmid: usize, irqs_base_ipa: usize, irqs_length: usize) -> Result { + println!( + "\nVM[{}] vm_cfg_add_pt_dev irqs:\n base_ipa {:x} length {:x}", + vmid, irqs_base_ipa, irqs_length + ); + + // Copy passthrough device irqs from user ipa. + let irqs_base_pa = vm_ipa2pa(active_vm().unwrap(), irqs_base_ipa); + if irqs_base_pa == 0 { + println!("illegal irqs_base_ipa {:x}", irqs_base_ipa); + return Err(()); + } + let mut irqs = vec![0 as usize, irqs_length]; + if irqs_length > 0 { + memcpy_safe( + &irqs[0] as *const _ as *const u8, + irqs_base_pa as *mut u8, + irqs_length * 8, // sizeof(usize) / sizeof(u8) + ); + } + println!(" irqs {:?}", irqs); + + let vm_cfg = match vm_cfg_entry(vmid) { + Some(vm_cfg) => vm_cfg, + None => return Err(()), + }; + vm_cfg.add_passthrough_device_irqs(&mut irqs); + Ok(0) +} + +/* Add passthrough device config streams ids for VM */ +pub fn vm_cfg_add_passthrough_device_streams_ids( + vmid: usize, + streams_ids_base_ipa: usize, + streams_ids_length: usize, +) -> Result { + println!( + "\nVM[{}] vm_cfg_add_pt_dev streams ids:\n streams_ids_base_ipa {:x} streams_ids_length {:x}", + vmid, streams_ids_base_ipa, streams_ids_length + ); + + // Copy passthrough device streams ids from user ipa. + let streams_ids_base_pa = vm_ipa2pa(active_vm().unwrap(), streams_ids_base_ipa); + if streams_ids_base_pa == 0 { + println!("illegal streams_ids_base_ipa {:x}", streams_ids_base_ipa); + return Err(()); + } + let mut streams_ids = vec![0 as usize, streams_ids_length]; + if streams_ids_length > 0 { + memcpy_safe( + &streams_ids[0] as *const _ as *const u8, + streams_ids_base_pa as *mut u8, + streams_ids_length * 8, // sizeof(usize) / sizeof(u8) + ); + } + println!(" get streams_ids {:?}", streams_ids); + + let vm_cfg = match vm_cfg_entry(vmid) { + Some(vm_cfg) => vm_cfg, + None => return Err(()), + }; + vm_cfg.add_passthrough_device_streams_ids(&mut streams_ids); + Ok(0) +} + +/* Add device tree device config for VM */ +pub fn vm_cfg_add_dtb_dev( + vmid: usize, + name_ipa: usize, + dev_type: usize, + irq_list_ipa: usize, + irq_list_length: usize, + addr_region_ipa: usize, + addr_region_length: usize, +) -> Result { + println!( + "\nVM[{}] vm_cfg_add_dtb_dev:\n dev_type {} irq_list_length {} addr_region_ipa {:x} addr_region_length {:x}", + vmid, dev_type, irq_list_length, addr_region_ipa, addr_region_length + ); + + // Copy DTB device name from user ipa. + let name_pa = vm_ipa2pa(active_vm().unwrap(), name_ipa); + if name_pa == 0 { + println!("illegal dtb_dev name ipa {:x}", name_ipa); + return Err(()); + } + let dtb_dev_name_u8 = vec![0 as u8; NAME_MAX_LEN]; + memcpy_safe( + &dtb_dev_name_u8[0] as *const _ as *const u8, + name_pa as *mut u8, + NAME_MAX_LEN, + ); + let dtb_dev_name_str = match String::from_utf8(dtb_dev_name_u8.clone()) { + Ok(str) => str, + Err(error) => { + println!( + "error: {:?} in parsing the DTB device name {:?}", + error, dtb_dev_name_u8 + ); + String::from("unknown") + } + }; + println!( + " get dtb dev name {:?}", + dtb_dev_name_str.trim_end_matches(char::from(0)) + ); + + // Copy DTB device irq list from user ipa. + let irq_list_pa = vm_ipa2pa(active_vm().unwrap(), irq_list_ipa); + if irq_list_pa == 0 { + println!("illegal dtb_dev irq list ipa {:x}", irq_list_ipa); + return Err(()); + } + let mut dtb_irq_list: Vec = Vec::new(); + + if irq_list_length > 0 { + let tmp_dtb_irq_list = vec![0 as usize, irq_list_length]; + memcpy_safe( + &tmp_dtb_irq_list[0] as *const _ as *const u8, + irq_list_pa as *mut u8, + irq_list_length * 8, // sizeof(usize) / sizeof(u8) + ); + for i in 0..irq_list_length { + dtb_irq_list.push(tmp_dtb_irq_list[i]); + } + } + println!(" get dtb dev dtb_irq_list {:?}", dtb_irq_list); + + // Get VM config entry. + let vm_cfg = match vm_cfg_entry(vmid) { + Some(vm_cfg) => vm_cfg, + None => return Err(()), + }; + // Get DTB device config list. + let vm_dtb_dev = VmDtbDevConfig { + name: dtb_dev_name_str.trim_end_matches(char::from(0)).to_string(), + dev_type: DtbDevType::from_usize(dev_type), + irqs: dtb_irq_list, + addr_region: AddrRegions { + ipa: addr_region_ipa, + length: addr_region_length, + }, + }; + + vm_cfg.add_dtb_device(vm_dtb_dev); + + Ok(0) +} + +/** + * Final Step for GVM configuration. + * Set up GVM configuration; + * Set VM kernel image load region; + */ +fn vm_cfg_finish_configuration(vmid: usize, img_size: usize) -> Vm { + // Set up GVM configuration. + vmm_init_gvm(vmid); + + // Get VM structure. + let vm = match vm(vmid) { + None => { + panic!("vm_cfg_upload_kernel_image:failed to init VM[{}]", vmid); + } + Some(vm) => vm, + }; + + let mut config = vm.config(); + let load_ipa = config.kernel_load_ipa(); + + // Find actual physical memory region according to kernel image ipa. + for (idx, region) in config.memory_region().iter().enumerate() { + if load_ipa < region.ipa_start || load_ipa + img_size > region.ipa_start + region.length { + continue; + } + let offset = load_ipa - region.ipa_start; + println!( + "VM [{}] {} kernel image region: ipa=<0x{:x}>, pa=<0x{:x}>, img_size=<{}KB>", + vm.id(), + config.vm_name(), + load_ipa, + vm.pa_start(idx) + offset, + img_size / 1024 + ); + config.set_kernel_load_pa(vm.pa_start(idx) + offset); + } + vm +} + +/** + * Load kernel image file from MVM user space. + * It's the last step in GVM configuration. + */ +pub fn vm_cfg_upload_kernel_image( + vmid: usize, + img_size: usize, + cache_ipa: usize, + load_offset: usize, + load_size: usize, +) -> Result { + // Before upload kernel image, set GVM. + let vm = match vm(vmid) { + None => { + println!( + "\nSuccessfully add configuration file for VM [{}]\nStart to init...", + vmid + ); + // This code should only run once. + vm_cfg_finish_configuration(vmid, img_size) + } + Some(vm) => vm, + }; + let config = vm.config(); + + println!( + "VM[{}] Upload kernel image. cache_ipa:{:x} load_offset:{:x} load_size:{:x}", + vmid, cache_ipa, load_offset, load_size + ); + // Get cache pa. + let cache_pa = vm_ipa2pa(active_vm().unwrap(), cache_ipa); + if cache_pa == 0 { + println!("illegal cache ipa {:x}", cache_ipa); + return Err(()); + } + let src = unsafe { core::slice::from_raw_parts_mut((cache_pa) as *mut u8, load_size) }; + + // Get kernel image load pa. + let load_pa = config.kernel_load_pa(); + if load_pa == 0 { + println!( + "vm_cfg_upload_kernel_image: failed to get kernel image load pa of VM[{}]", + vmid + ); + return Err(()); + } + // Copy from user space. + let dst = unsafe { core::slice::from_raw_parts_mut((load_pa + load_offset) as *mut u8, load_size) }; + dst.copy_from_slice(src); + Ok(0) +} diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..90b4c4d21c07f1df14aa32522024d3fd9d318f8e --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,29 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::config::*; +#[cfg(feature = "static-config")] +pub use self::vm_def::*; +#[cfg(feature = "pi4")] +pub use self::pi4_def::*; +#[cfg(feature = "qemu")] +pub use self::qemu_def::*; +#[cfg(feature = "tx2")] +pub use self::tx2_def::*; + +mod config; +#[cfg(feature = "static-config")] +mod vm_def; +#[cfg(feature = "pi4")] +mod pi4_def; +#[cfg(feature = "qemu")] +mod qemu_def; +#[cfg(feature = "tx2")] +mod tx2_def; diff --git a/src/config/pi4_def.rs b/src/config/pi4_def.rs new file mode 100644 index 0000000000000000000000000000000000000000..63e15e19685bea9cb8eba7bc5aafbe43fa563901 --- /dev/null +++ b/src/config/pi4_def.rs @@ -0,0 +1,200 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::board::*; +use crate::config::vm_cfg_add_vm_entry; +use crate::device::EmuDeviceType; +use crate::kernel::{HVC_IRQ, INTERRUPT_IRQ_GUEST_TIMER, VmType}; + +use super::{ + PassthroughRegion, vm_cfg_set_config_name, VmConfigEntry, VmCpuConfig, VMDtbDevConfigList, VmEmulatedDeviceConfig, + VmEmulatedDeviceConfigList, VmImageConfig, VmMemoryConfig, VmPassthroughDeviceConfig, VmRegion, +}; + +#[rustfmt::skip] +pub fn mvm_config_init() { + println!("mvm_config_init() init config for VM0, which is manager VM"); + + vm_cfg_set_config_name("pi4-default"); + + // vm0 emu + let mut emu_dev_config: Vec = Vec::new(); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("interrupt-controller@fff841000")), + base_ipa: 0xFFF841000, + length: 0x1000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTGicd, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_net@fa000800")), + base_ipa: 0xfa000800, + length: 0x400, + irq_id: 32 + 0x17, + cfg_list: vec![0x74, 0x56, 0xaa, 0x0f, 0x47, 0xd0], + emu_type: EmuDeviceType::EmuDeviceTVirtioNet, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_console@fa000c00")), + base_ipa: 0xfa000c00, + length: 0x1000, + irq_id: 32 + 0x20, + cfg_list: vec![1, 0xa002000], + emu_type: EmuDeviceType::EmuDeviceTVirtioConsole, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_console@fa002000")), + base_ipa: 0xfa002000, + length: 0x1000, + irq_id: 32 + 0x18, + cfg_list: vec![2, 0xa002000], + emu_type: EmuDeviceType::EmuDeviceTVirtioConsole, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("vm_service")), + base_ipa: 0, + length: 0, + irq_id: 32 + 0x10, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTShyper, + mediated: false, + }); + + // vm0 passthrough + let mut pt_dev_config: VmPassthroughDeviceConfig = VmPassthroughDeviceConfig::default(); + pt_dev_config.regions = vec![ + // all + PassthroughRegion { ipa: 0xFC000000, pa: 0xFC000000, length: 0x04000000, dev_property: true }, + // pcie@7d500000 + PassthroughRegion { ipa: 0x600000000, pa: 0x600000000, length: 0x4000000, dev_property: true }, + // fb + PassthroughRegion { ipa: 0x3e000000, pa: 0x3e000000, length: 0x40000000 - 0x3e000000, dev_property: false }, + // gicv + PassthroughRegion { ipa: PLATFORM_GICC_BASE + 0xF_0000_0000, pa: PLATFORM_GICV_BASE, length: 0x2000, dev_property: true }, + ]; + // 146 is UART_INT + pt_dev_config.irqs = vec![ + 27, // timer + 32 + 0x21, // mailbox@7e00b880 + 32 + 0x28, // usb@7e980000 + 32 + 0x40, // timer@7e003000 + 32 + 0x41, // timer@7e003000 + 32 + 0x42, // timer@7e003000 + 32 + 0x43, // timer@7e003000 + 32 + 0x4b, // txp@7e004000 + 32 + 0x7d, // rng@7e104000 + 32 + 0x71, // gpio@7e200000 + 32 + 0x72, // gpio@7e200000 + 32 + 0x79, // serial@7e201000 + 32 + 0x78, // mmc@7e202000 + 32 + 0x76, // spi@7e204000 + 32 + 0x64, // dsi@7e209000 + 32 + 0x5d, // spi@7e215080 + 32 + 0x61, // hvs@7e400000 + 32 + 0x6c, // dsi@7e700000 + 32 + 0x7b, // vec@7e806000 + 32 + 0x49, // usb@7e980000 + 32 + 0x50, // dma@7e007000 + 32 + 0x51, // dma@7e007000 + 32 + 0x52, // dma@7e007000 + 32 + 0x53, // dma@7e007000 + 32 + 0x54, // dma@7e007000 + 32 + 0x55, // dma@7e007000 + 32 + 0x56, // dma@7e007000 + 32 + 0x57, // dma@7e007000 + 32 + 0x58, // dma@7e007000 + // spi@7e204800 + // spi@7e204s00 + // spi@7e204v00 + 32 + 0x75, // i2c@7e205600 + // i2c@7e205800 + // i2c@7e205a00 + // i2c@7e205c00 + 32 + 0x6d, // pixelvalve@7e206000 + 32 + 0x6e, // pixelvalve@7e207000 + 32 + 0x65, // pixelvalve@7e20a000 + 32 + 0x6a, // pixelvalve@7e20a000 + 32 + 0x60, // hdmi@7ef00700 + 32 + 0x22, // mailbox@7e00b840 + 32 + 0x70, // smi@7e600000 + 32 + 0x66, // csi@7e800000 + 32 + 0x67, // csi@7e801000 + // 32 + 0x10, // arm-pmu + // 32 + 0x11, // arm-pmu + // 32 + 0x12, // arm-pmu + // 32 + 0x13, // arm-pmu + 32 + 0x94, // pcie@7d500000 + 32 + 0x9d, // ethernet@7d580000 + 32 + 0x9e, // ethernet@7d580000 + 32 + 0x59, // dma@7e007b00 + 32 + 0x5a, // dma@7e007b00 + 32 + 0x5b, // dma@7e007b00 + 32 + 0x5c, // dma@7e007b00 + 32 + 0xb0, // xhci@7e9c0000 + 32 + 0x62, // rpivid-local-intc@7eb10000 + ]; + pt_dev_config.streams_ids = vec![]; + + // vm0 vm_region + let mut vm_region: Vec = Vec::new(); + vm_region.push(VmRegion { + ipa_start: 0x200000, + length: 0x3e000000 - 0x200000, + }); + // vm_region.push(VmRegion { + // ipa_start: 0xf0200000, + // length: 0xc0000000, + // }); + + // vm0 config + + let mvm_config_entry = VmConfigEntry { + id: 0, + // name: Some("privileged"), + name: Some(String::from("Raspi4")), + os_type: VmType::VmTOs, + cmdline: + // String::from("earlycon=uart8250,mmio32,0x3100000 console=ttyS0,115200n8 root=/dev/nvme0n1p2 rw audit=0 rootwait default_hugepagesz=32M hugepagesz=32M hugepages=4\0"), + String::from("coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1 console=ttyAMA0,115200n8 root=/dev/sda1 rootfstype=ext4 rw audit=0 rootwait default_hugepagesz=32M hugepagesz=32M hugepages=4\0"), + + image: Arc::new(Mutex::new(VmImageConfig { + kernel_img_name: Some("Raspi4"), + kernel_load_ipa: 0x280000, + kernel_load_pa: 0, + kernel_entry_point: 0x280000, + device_tree_load_ipa: 0x10000000, + ramdisk_load_ipa: 0, + mediated_block_index: None, + })), + memory: Arc::new(Mutex::new(VmMemoryConfig { + region: vm_region, + })), + cpu: Arc::new(Mutex::new(VmCpuConfig { + num: 1, + allocate_bitmap: 0b0001, + master: 0, + })), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList { emu_dev_list: emu_dev_config })), + vm_pt_dev_confg: Arc::new(Mutex::new(pt_dev_config)), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList::default())), + }; + vm_cfg_add_vm_entry(mvm_config_entry); +} diff --git a/src/config/qemu_def.rs b/src/config/qemu_def.rs new file mode 100644 index 0000000000000000000000000000000000000000..4780e0c5dfb6826b367b0dc8d0bc632ae0a96ef9 --- /dev/null +++ b/src/config/qemu_def.rs @@ -0,0 +1,290 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::board::*; +use crate::device::EmuDeviceType; +use crate::kernel::{HVC_IRQ, VmType}; + +use super::{ + DEF_VM_CONFIG_TABLE, VmConfigEntry, VmConfigTable, VmCpuConfig, VmEmulatedDeviceConfig, VmImageConfig, + VmMemoryConfig, VmPassthroughDeviceConfig, VmRegion, vm_cfg_set_config_name, PassthroughRegion, + vm_cfg_add_vm_entry, VmEmulatedDeviceConfigList, VMDtbDevConfigList, +}; + +#[rustfmt::skip] +pub fn mvm_config_init() { + vm_cfg_set_config_name("qemu-default"); + + // vm0 emu + let mut emu_dev_config: Vec = Vec::new(); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("vgicd")), + base_ipa: 0x8000000, + length: 0x1000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTGicd, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio-blk0")), + base_ipa: 0xa000000, + length: 0x1000, + irq_id: 32 + 0x10, + cfg_list: vec![DISK_PARTITION_1_START, DISK_PARTITION_1_SIZE], + emu_type: EmuDeviceType::EmuDeviceTVirtioBlk, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio-nic0")), + base_ipa: 0xa001000, + length: 0x1000, + irq_id: 32 + 0x11, + cfg_list: vec![0x74, 0x56, 0xaa, 0x0f, 0x47, 0xd0], + emu_type: EmuDeviceType::EmuDeviceTVirtioNet, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("shyper")), + base_ipa: 0, + length: 0, + irq_id: HVC_IRQ, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTShyper, + mediated: false, + }); + + // vm0 passthrough + let mut pt_dev_config: VmPassthroughDeviceConfig = VmPassthroughDeviceConfig::default(); + pt_dev_config.regions = vec![ + PassthroughRegion { ipa: 0x9000000, pa: UART_1_ADDR, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: PLATFORM_GICC_BASE, pa: PLATFORM_GICV_BASE, length: 0x2000, dev_property: true }, + PassthroughRegion { ipa: 0x0a003000, pa: 0x0a003000, length: 0x1000, dev_property: true }, + ]; + pt_dev_config.irqs = vec![UART_1_INT, 27, 32 + 0x2e]; + pt_dev_config.streams_ids = vec![]; // TODO + // pt_dev_config.push(VmPassthroughDeviceConfig { + // name: Some(String::from("serial0")), + // base_pa: UART_1_ADDR, + // base_ipa: 0x9000000, + // length: 0x1000, + // // dma: false, + // irq_list: vec![UART_1_INT, 27], + // }); + // pt_dev_config.push(VmPassthroughDeviceConfig { + // name: Some(String::from("gicc")), + // base_pa: PLATFORM_GICV_BASE, + // base_ipa: 0x8010000, + // length: 0x2000, + // // dma: false, + // irq_list: Vec::new(), + // }); + // pt_dev_config.push(VmPassthroughDeviceConfig { + // name: Some(String::from("nic")), + // base_pa: 0x0a003000, + // base_ipa: 0x0a003000, + // length: 0x1000, + // irq_list: vec![32 + 0x2e], + // }); + + // vm0 vm_region + let mut vm_region: Vec = Vec::new(); + vm_region.push(VmRegion { + ipa_start: 0x50000000, + length: 0x80000000, + }); + + // vm0 config + let mvm_config_entry =VmConfigEntry { + id: 0, + name: Some(String::from("supervisor")), + os_type: VmType::VmTOs, + cmdline: String::from(""), // TODO + image: Arc::new(Mutex::new(VmImageConfig { + kernel_img_name: Some("Image"), + kernel_load_ipa: 0x58080000, + kernel_load_pa: 0, + kernel_entry_point: 0x58080000, + // device_tree_filename: Some("qemu1.bin"), + device_tree_load_ipa: 0x52000000, + // ramdisk_filename: Some("initrd.gz"), + ramdisk_load_ipa: 0x53000000, + mediated_block_index: None, + })), + cpu: Arc::new(Mutex::new(VmCpuConfig { + num: 4, + allocate_bitmap: 0b0001, + master: -1, + })), + memory: Arc::new(Mutex::new(VmMemoryConfig { + region: vm_region, + })), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList { emu_dev_list: emu_dev_config })), + vm_pt_dev_confg: Arc::new(Mutex::new(pt_dev_config)), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList::default())), + }; + let _ = vm_cfg_add_vm_entry(mvm_config_entry); +} + +// pub fn config_init() { +// let mut vm_config = DEF_VM_CONFIG_TABLE.lock(); +// // vm1 emu +// let mut emu_dev_config: Vec = Vec::new(); +// emu_dev_config.push(VmEmulatedDeviceConfig { +// name: Some(String::from("vgicd")), +// base_ipa: 0x8000000, +// length: 0x1000, +// irq_id: 0, +// cfg_list: Vec::new(), +// emu_type: EmuDeviceType::EmuDeviceTGicd, +// mediated: false, +// }); +// emu_dev_config.push(VmEmulatedDeviceConfig { +// name: Some(String::from("virtio-blk1")), +// base_ipa: 0xa000000, +// length: 0x1000, +// irq_id: 32 + 0x10, +// cfg_list: vec![DISK_PARTITION_2_START, DISK_PARTITION_2_SIZE], +// emu_type: EmuDeviceType::EmuDeviceTVirtioBlk, +// mediated: false, +// }); + +// // vm1 passthrough +// let mut pt_dev_config: Vec = Vec::new(); +// // pt_dev_config.push(VmPassthroughDeviceConfig { +// // name: Some(String::from("serial1")), +// // base_pa: UART_2_ADDR, +// // base_ipa: 0x9000000, +// // length: 0x1000, +// // // dma: false, +// // irq_list: vec![UART_2_INT, 27], +// // }); +// // pt_dev_config.push(VmPassthroughDeviceConfig { +// // name: Some(String::from("gicc")), +// // base_pa: PLATFORM_GICV_BASE, +// // base_ipa: 0x8010000, +// // length: 0x2000, +// // // dma: false, +// // irq_list: Vec::new(), +// // }); +// // vm1 vm_region +// let mut vm_region: Vec = Vec::new(); +// vm_region.push(VmRegion { +// ipa_start: 0x80000000, +// length: 0x80000000, +// }); + +// // vm1 config +// vm_config.entries.push(Arc::new(VmConfigEntry { +// id: 1, +// name: Some(String::from("guest-os-0")), +// os_type: VmType::VmTOs, +// memory: VmMemoryConfig { +// num: 1, +// region: Some(vm_region), +// }, +// image: VmImageConfig { +// kernel_name: Some("Image"), +// kernel_load_ipa: 0x88080000, +// kernel_entry_point: 0x88080000, +// device_tree_filename: Some("qemu2.bin"), +// device_tree_load_ipa: 0x82000000, +// ramdisk_filename: Some("initrd.gz"), +// ramdisk_load_ipa: 0x83000000, +// }, +// cpu: VmCpuConfig { +// num: 1, +// allocate_bitmap: 0b0010, +// master: -1, +// }, +// vm_emu_dev_confg: Some(emu_dev_config), +// vm_pt_dev_confg: Some(pt_dev_config), +// })); + +// // vm2 BMA emu +// let mut emu_dev_config: Vec = Vec::new(); +// emu_dev_config.push(VmEmulatedDeviceConfig { +// name: Some(String::from("vgicd")), +// base_ipa: 0x8000000, +// length: 0x1000, +// irq_id: 0, +// cfg_list: Vec::new(), +// emu_type: EmuDeviceType::EmuDeviceTGicd, +// mediated: false, +// }); +// emu_dev_config.push(VmEmulatedDeviceConfig { +// name: Some(String::from("virtio-blk0")), +// base_ipa: 0xa000000, +// length: 0x1000, +// irq_id: 32 + 0x10, +// cfg_list: vec![DISK_PARTITION_1_START, DISK_PARTITION_1_SIZE], +// emu_type: EmuDeviceType::EmuDeviceTVirtioBlk, +// mediated: false, +// }); + +// // vm2 BMA passthrough +// let mut pt_dev_config: Vec = Vec::new(); +// pt_dev_config.push(VmPassthroughDeviceConfig { +// name: Some(String::from("serial1")), +// base_pa: UART_2_ADDR, +// base_ipa: 0x9000000, +// length: 0x1000, +// // dma: false, +// irq_list: vec![27], +// }); +// pt_dev_config.push(VmPassthroughDeviceConfig { +// name: Some(String::from("gicc")), +// base_pa: PLATFORM_GICV_BASE, +// base_ipa: 0x8010000, +// length: 0x2000, +// // dma: false, +// irq_list: Vec::new(), +// }); + +// // vm2 BMA vm_region +// let mut vm_region: Vec = Vec::new(); +// vm_region.push(VmRegion { +// ipa_start: 0x40000000, +// length: 0x1000000, +// }); + +// // vm2 BMA config +// vm_config.entries.push(Arc::new(VmConfigEntry { +// id: 2, +// name: Some(String::from("guest-bma-0")), +// os_type: VmType::VmTBma, +// memory: VmMemoryConfig { +// num: 1, +// region: Some(vm_region), +// }, +// image: VmImageConfig { +// kernel_name: Some("sbma1.bin"), +// kernel_load_ipa: 0x40080000, +// kernel_entry_point: 0x40080000, +// device_tree_filename: None, +// device_tree_load_ipa: 0, +// ramdisk_filename: None, +// ramdisk_load_ipa: 0, +// }, +// cpu: VmCpuConfig { +// num: 1, +// allocate_bitmap: 0b0100, +// master: -1, +// }, +// vm_emu_dev_confg: Some(emu_dev_config), +// vm_pt_dev_confg: Some(pt_dev_config), +// })); +// } diff --git a/src/config/tx2_def.rs b/src/config/tx2_def.rs new file mode 100644 index 0000000000000000000000000000000000000000..3a0ae832c938253e9c8421d5626d796fb9855cff --- /dev/null +++ b/src/config/tx2_def.rs @@ -0,0 +1,261 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::board::*; +// self.mem_map_cache = None; +use crate::config::vm_cfg_add_vm_entry; +use crate::device::EmuDeviceType; +use crate::kernel::{HVC_IRQ, INTERRUPT_IRQ_GUEST_TIMER, VmType}; + +use super::{ + PassthroughRegion, vm_cfg_set_config_name, VmConfigEntry, VmCpuConfig, VMDtbDevConfigList, VmEmulatedDeviceConfig, + VmEmulatedDeviceConfigList, VmImageConfig, VmMemoryConfig, VmPassthroughDeviceConfig, VmRegion, +}; + +#[rustfmt::skip] +pub fn mvm_config_init() { + println!("mvm_config_init() init config for VM0, which is manager VM"); + + vm_cfg_set_config_name("tx2-default"); + + // vm0 emu + let mut emu_dev_config: Vec = Vec::new(); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("interrupt-controller@3881000")), + base_ipa: PLATFORM_GICD_BASE, + length: 0x1000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTGicd, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_net@a001000")), + base_ipa: 0xa001000, + length: 0x1000, + irq_id: 32 + 0x100, + cfg_list: vec![0x74, 0x56, 0xaa, 0x0f, 0x47, 0xd0], + emu_type: EmuDeviceType::EmuDeviceTVirtioNet, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_console@a002000")), + base_ipa: 0xa002000, + length: 0x1000, + irq_id: 32 + 0x101, + cfg_list: vec![1, 0xa002000], + emu_type: EmuDeviceType::EmuDeviceTVirtioConsole, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_console@a003000")), + base_ipa: 0xa003000, + length: 0x1000, + irq_id: 32 + 0x102, + cfg_list: vec![2, 0xa002000], + emu_type: EmuDeviceType::EmuDeviceTVirtioConsole, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("iommu")), + base_ipa: 0x12000000, + length: 0x1000000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTIOMMU, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("vm_service")), + base_ipa: 0, + length: 0, + irq_id: HVC_IRQ, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTShyper, + mediated: false, + }); + + // vm0 passthrough + let mut pt_dev_config: VmPassthroughDeviceConfig = VmPassthroughDeviceConfig::default(); + pt_dev_config.regions = vec![ + PassthroughRegion { ipa: 0x100000, pa: 0x100000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x02100000, pa: 0x02100000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02110000, pa: 0x02110000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02120000, pa: 0x02120000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02130000, pa: 0x02130000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02140000, pa: 0x02140000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02150000, pa: 0x02150000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02160000, pa: 0x02160000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02170000, pa: 0x02170000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02180000, pa: 0x02180000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02190000, pa: 0x02190000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02200000, pa: 0x02200000, length: 0x20000, dev_property: true }, + PassthroughRegion { ipa: 0x02390000, pa: 0x02390000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x023a0000, pa: 0x023a0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x023b0000, pa: 0x023b0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x023c0000, pa: 0x023c0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x023d0000, pa: 0x023d0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x02430000, pa: 0x02430000, length: 0x15000, dev_property: true }, + PassthroughRegion { ipa: 0x02490000, pa: 0x02490000, length: 0x50000, dev_property: true }, + PassthroughRegion { ipa: 0x02600000, pa: 0x02600000, length: 0x210000, dev_property: true }, + PassthroughRegion { ipa: 0x02900000, pa: 0x02900000, length: 0x200000, dev_property: true }, + PassthroughRegion { ipa: 0x02c00000, pa: 0x02c00000, length: 0xb0000, dev_property: true }, + PassthroughRegion { ipa: 0x03010000, pa: 0x03010000, length: 0xe0000, dev_property: true }, + // sata + PassthroughRegion { ipa: 0x03100000, pa: 0x03100000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03110000, pa: 0x03110000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03130000, pa: 0x03130000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03160000, pa: 0x03160000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03180000, pa: 0x03180000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03190000, pa: 0x03190000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x031b0000, pa: 0x031b0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x031c0000, pa: 0x031c0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x031e0000, pa: 0x031e0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03210000, pa: 0x03210000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x03240000, pa: 0x03240000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x03280000, pa: 0x03280000, length: 0x30000, dev_property: true }, + PassthroughRegion { ipa: 0x03400000, pa: 0x03400000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03440000, pa: 0x03440000, length: 0x1000, dev_property: true }, + // emmc blk + // PassthroughRegion { ipa: 0x03460000, pa: 0x03460000, length: 0x140000 }, + PassthroughRegion { ipa: 0x03460000, pa: 0x03460000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03500000, pa: 0x03500000, length: 0x9000, dev_property: true }, + PassthroughRegion { ipa: 0x03510000, pa: 0x03510000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x03520000, pa: 0x03520000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03530000, pa: 0x03530000, length: 0x8000, dev_property: true }, + PassthroughRegion { ipa: 0x03538000, pa: 0x03538000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03540000, pa: 0x03540000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03550000, pa: 0x03550000, length: 0x9000, dev_property: true }, + PassthroughRegion { ipa: 0x03820000, pa: 0x03820000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03830000, pa: 0x03830000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x03960000, pa: 0x03960000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03990000, pa: 0x03990000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x039c0000, pa: 0x039c0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x03a90000, pa: 0x03a90000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x03ad0000, pa: 0x03ad0000, length: 0x20000, dev_property: true }, + // PassthroughRegion { ipa: 0x03b41000, pa: 0x03b41000, length: 0x1000 }, + PassthroughRegion { ipa: 0x03c00000, pa: 0x03c00000, length: 0xa0000, dev_property: true }, + PassthroughRegion { ipa: PLATFORM_GICC_BASE, pa: PLATFORM_GICV_BASE, length: 0x2000, dev_property: true }, + PassthroughRegion { ipa: 0x8010000, pa: 0x8010000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x08030000, pa: 0x08030000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x08050000, pa: 0x08050000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x08060000, pa: 0x08060000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x08070000, pa: 0x08070000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x08820000, pa: 0x08820000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x08a1c000, pa: 0x08a1c000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x09010000, pa: 0x09010000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x09840000, pa: 0x09840000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x09940000, pa: 0x09940000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x09a40000, pa: 0x09a40000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x09b40000, pa: 0x09b40000, length: 0x1000, dev_property: true }, + // PassthroughRegion { ipa: 0x0b000000, pa: 0x0b000000, length: 0x1000 }, + // PassthroughRegion { ipa: 0x0b040000, pa: 0x0b040000, length: 0x20000}, + PassthroughRegion { ipa: 0x0b150000, pa: 0x0b150000, length: 0x90000, dev_property: true }, + PassthroughRegion { ipa: 0x0b1f0000, pa: 0x0b1f0000, length: 0x50000, dev_property: true }, + PassthroughRegion { ipa: 0x0c150000, pa: 0x0c150000, length: 0x90000, dev_property: true }, + PassthroughRegion { ipa: 0x0c240000, pa: 0x0c240000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c250000, pa: 0x0c250000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c260000, pa: 0x0c260000, length: 0x10000, dev_property: true }, + // serial + PassthroughRegion { ipa: 0x0c280000, pa: 0x0c280000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c2a0000, pa: 0x0c2a0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c2f0000, pa: 0x0c2f0000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c2f1000, pa: 0x0c2f1000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c300000, pa: 0x0c300000, length: 0x4000, dev_property: true }, + PassthroughRegion { ipa: 0x0c340000, pa: 0x0c340000, length: 0x10000, dev_property: true }, + PassthroughRegion { ipa: 0x0c360000, pa: 0x0c360000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c370000, pa: 0x0c370000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0c390000, pa: 0x0c390000, length: 0x3000, dev_property: true }, + PassthroughRegion { ipa: 0x0d230000, pa: 0x0d230000, length: 0x1000, dev_property: true }, + PassthroughRegion { ipa: 0x0e000000, pa: 0x0e000000, length: 0x80000, dev_property: true }, + PassthroughRegion { ipa: 0x10000000, pa: 0x10000000, length: 0x1000000, dev_property: true }, + // smmu + // PassthroughRegion { ipa: 0x12000000, pa: 0x12000000, length: 0x1000000 , dev_property: true}, + PassthroughRegion { ipa: 0x13e00000, pa: 0x13e00000, length: 0x20000, dev_property: true }, + PassthroughRegion { ipa: 0x13ec0000, pa: 0x13ec0000, length: 0x40000, dev_property: true }, + // PassthroughRegion { ipa: 0x15040000, pa: 0x15040000, length: 0x40000 }, + PassthroughRegion { ipa: 0x150c0000, pa: 0x150c0000, length: 0x80000, dev_property: true }, + // PassthroughRegion { ipa: 0x15210000, pa: 0x15210000, length: 0x10000 }, + PassthroughRegion { ipa: 0x15340000, pa: 0x15340000, length: 0x80000, dev_property: true }, + PassthroughRegion { ipa: 0x15480000, pa: 0x15480000, length: 0xc0000, dev_property: true }, + // PassthroughRegion { ipa: 0x15580000, pa: 0x15580000, length: 0x40000 }, + PassthroughRegion { ipa: 0x15600000, pa: 0x15600000, length: 0x40000, dev_property: true }, + PassthroughRegion { ipa: 0x15700000, pa: 0x15700000, length: 0x100000, dev_property: true }, + PassthroughRegion { ipa: 0x15810000, pa: 0x15810000, length: 0x40000, dev_property: true }, + PassthroughRegion { ipa: 0x17000000, pa: 0x17000000, length: 0x2000000, dev_property: true }, + PassthroughRegion { ipa: 0x30000000, pa: 0x30000000, length: 0x10000000, dev_property: true }, + PassthroughRegion { ipa: 0x40000000, pa: 0x40000000, length: 0x40000000, dev_property: true }, + ]; + // 146 is UART_INT + pt_dev_config.irqs = vec![ + INTERRUPT_IRQ_GUEST_TIMER, 32, 33, 34, 35, 36, 37, 38, 39, 40, 48, 49, 56, 57, 58, 59, 60, 62, 63, 64, 65, 67, 68, + 69, 70, 71, 72, 74, 76, 79, 82, 85, 88, 91, 92, 94, 95, 96, 97, 102, 103, 104, 105, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, UART_0_INT, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 165, 166, 167, 168, 173, 174, 175, 176, 177, 178, 179, + 185, 186, 187, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 208, + 212, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 229, 230, 233, 234, 235, 237, 238, + 242, 255, 256, 295, 297, 315, 322, 328, 329, 330, 331, 352, 353, 366, + ]; + pt_dev_config.streams_ids = vec![ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 25, 26, 27, 28, + 29, 30, 31, 32, 42, 45, 50, 51, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, + ]; + + // vm0 vm_region + let mut vm_region: Vec = Vec::new(); + vm_region.push(VmRegion { + ipa_start: 0xa0000000, + length: 0x60000000, + }); + // vm_region.push(VmRegion { + // ipa_start: 0xf0200000, + // length: 0xc0000000, + // }); + + // vm0 config + let mvm_config_entry = VmConfigEntry { + id: 0, + name: Some(String::from("privileged")), + os_type: VmType::VmTOs, + cmdline: + // String::from("earlycon=uart8250,mmio32,0x3100000 console=ttyS0,115200n8 root=/dev/nvme0n1p2 rw audit=0 rootwait default_hugepagesz=32M hugepagesz=32M hugepages=4\0"), + String::from("earlycon=uart8250,mmio32,0x3100000 console=ttyS0,115200n8 root=/dev/sda1 rw audit=0 rootwait default_hugepagesz=32M hugepagesz=32M hugepages=5\0"), + + image: Arc::new(Mutex::new(VmImageConfig { + kernel_img_name: Some("L4T"), + kernel_load_ipa: 0xa0080000, + kernel_load_pa: 0, + kernel_entry_point: 0xa0080000, + device_tree_load_ipa: 0xa0000000, + ramdisk_load_ipa: 0, + mediated_block_index: None, + })), + memory: Arc::new(Mutex::new(VmMemoryConfig { + region: vm_region, + })), + cpu: Arc::new(Mutex::new(VmCpuConfig { + num: 1, + allocate_bitmap: 0b0001, + master: 0, + })), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList { emu_dev_list: emu_dev_config })), + vm_pt_dev_confg: Arc::new(Mutex::new(pt_dev_config)), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList::default())), + }; + let _ = vm_cfg_add_vm_entry(mvm_config_entry); +} diff --git a/src/config/vm_def.rs b/src/config/vm_def.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f869573b3503f794a076581a4a52570081bd96d --- /dev/null +++ b/src/config/vm_def.rs @@ -0,0 +1,461 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::board::*; +use crate::config::vm_cfg_add_vm_entry; +use crate::device::EmuDeviceType; +use crate::kernel::{INTERRUPT_IRQ_GUEST_TIMER, VmType}; + +use super::{ + PassthroughRegion, VmConfigEntry, VmCpuConfig, VMDtbDevConfigList, VmEmulatedDeviceConfig, + VmEmulatedDeviceConfigList, VmImageConfig, VmMemoryConfig, VmPassthroughDeviceConfig, VmRegion, VmDtbDevConfig, + AddrRegions, DtbDevType, +}; + +pub fn init_tmp_config_for_bma1() { + println!("init_tmp_config_for_bma1"); + // #################### bare metal app emu (vm1) ###################### + let mut emu_dev_config: Vec = Vec::new(); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("intc@8000000")), + base_ipa: 0x8000000, + length: 0x1000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTGicd, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_blk@a000000")), + base_ipa: 0xa000000, + length: 0x1000, + irq_id: 32 + 0x10, + cfg_list: vec![0, 209715200], // 100G + emu_type: EmuDeviceType::EmuDeviceTVirtioBlk, + mediated: true, + }); + + // bma passthrough + let mut pt_dev_config: VmPassthroughDeviceConfig = VmPassthroughDeviceConfig::default(); + pt_dev_config.regions = vec![ + PassthroughRegion { + ipa: 0x9000000, + pa: UART_1_ADDR, + length: 0x1000, + dev_property: true, + }, + PassthroughRegion { + ipa: 0x8010000, + pa: PLATFORM_GICV_BASE, + length: 0x2000, + dev_property: true, + }, + ]; + pt_dev_config.irqs = vec![UART_1_INT]; + + // bma vm_region + let mut vm_region: Vec = Vec::new(); + vm_region.push(VmRegion { + ipa_start: 0x40000000, + length: 0x40000000, + }); + + // bma config + let bma_config = VmConfigEntry { + id: 0, + name: Some(String::from("guest-bma-0")), + os_type: VmType::VmTBma, + memory: Arc::new(Mutex::new(VmMemoryConfig { region: vm_region })), + image: Arc::new(Mutex::new(VmImageConfig { + kernel_img_name: None, + kernel_load_ipa: 0x40080000, + kernel_load_pa: 0, + kernel_entry_point: 0x40080000, + device_tree_load_ipa: 0, + ramdisk_load_ipa: 0, + mediated_block_index: None, + })), + cpu: Arc::new(Mutex::new(VmCpuConfig { + num: 1, + allocate_bitmap: 0b0010, + master: 1, + })), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList { + emu_dev_list: emu_dev_config, + })), + vm_pt_dev_confg: Arc::new(Mutex::new(pt_dev_config)), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList { + dtb_device_list: vec![], + })), + cmdline: String::from(""), + }; + let _ = vm_cfg_add_vm_entry(bma_config); +} + +pub fn init_tmp_config_for_bma2() { + println!("init_tmp_config_for_bma2"); + // #################### bare metal app emu (vm1) ###################### + let mut emu_dev_config: Vec = Vec::new(); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("intc@8000000")), + base_ipa: 0x8000000, + length: 0x1000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTGicd, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_blk@a000000")), + base_ipa: 0xa000000, + length: 0x1000, + irq_id: 32 + 0x10, + cfg_list: vec![0, 209715200], // 100G + emu_type: EmuDeviceType::EmuDeviceTVirtioBlk, + mediated: true, + }); + + // bma passthrough + let mut pt_dev_config: VmPassthroughDeviceConfig = VmPassthroughDeviceConfig::default(); + pt_dev_config.regions = vec![ + PassthroughRegion { + ipa: 0x9000000, + pa: UART_1_ADDR, + length: 0x1000, + dev_property: true, + }, + PassthroughRegion { + ipa: 0x8010000, + pa: PLATFORM_GICV_BASE, + length: 0x2000, + dev_property: true, + }, + ]; + // pt_dev_config.irqs = vec![UART_1_INT]; + + // bma vm_region + let mut vm_region: Vec = Vec::new(); + vm_region.push(VmRegion { + ipa_start: 0x40000000, + length: 0x40000000, + }); + + // bma config + let bma_config = VmConfigEntry { + id: 0, + name: Some(String::from("guest-bma-1")), + os_type: VmType::VmTBma, + memory: Arc::new(Mutex::new(VmMemoryConfig { region: vm_region })), + image: Arc::new(Mutex::new(VmImageConfig { + kernel_img_name: None, + kernel_load_ipa: 0x40080000, + kernel_load_pa: 0, + kernel_entry_point: 0x40080000, + device_tree_load_ipa: 0, + ramdisk_load_ipa: 0, + mediated_block_index: None, + })), + cpu: Arc::new(Mutex::new(VmCpuConfig { + num: 1, + allocate_bitmap: 0b0100, + master: 2, + })), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList { + emu_dev_list: emu_dev_config, + })), + vm_pt_dev_confg: Arc::new(Mutex::new(pt_dev_config)), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList { + dtb_device_list: vec![], + })), + cmdline: String::from(""), + }; + let _ = vm_cfg_add_vm_entry(bma_config); +} + +pub fn init_tmp_config_for_vm1() { + println!("init_tmp_config_for_vm1"); + + // #################### vm1 emu ###################### + let mut emu_dev_config: Vec = Vec::new(); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("intc@8000000")), + base_ipa: 0x8000000, + length: 0x1000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTGicd, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_blk@a000000")), + base_ipa: 0xa000000, + length: 0x1000, + irq_id: 32 + 0x10, + // cfg_list: vec![DISK_PARTITION_2_START, DISK_PARTITION_2_SIZE], + // cfg_list: vec![0, 8388608], + // cfg_list: vec![0, 67108864i], // 32G + cfg_list: vec![0, 209715200], // 100G + emu_type: EmuDeviceType::EmuDeviceTVirtioBlk, + mediated: true, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_net@a001000")), + base_ipa: 0xa001000, + length: 0x1000, + irq_id: 32 + 0x11, + cfg_list: vec![0x74, 0x56, 0xaa, 0x0f, 0x47, 0xd1], + emu_type: EmuDeviceType::EmuDeviceTVirtioNet, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_console@a002000")), + base_ipa: 0xa002000, + length: 0x1000, + irq_id: 32 + 0x12, + cfg_list: vec![0, 0xa002000], + emu_type: EmuDeviceType::EmuDeviceTVirtioConsole, + mediated: false, + }); + // emu_dev_config.push(VmEmulatedDeviceConfig { + // name: Some(String::from("vm_service")), + // base_ipa: 0, + // length: 0, + // irq_id: HVC_IRQ, + // cfg_list: Vec::new(), + // emu_type: EmuDeviceType::EmuDeviceTShyper, + // mediated: false, + // }); + + // vm1 passthrough + let mut pt_dev_config: VmPassthroughDeviceConfig = VmPassthroughDeviceConfig::default(); + pt_dev_config.regions = vec![ + // PassthroughRegion { + // ipa: UART_1_ADDR, + // pa: UART_1_ADDR, + // length: 0x1000, + // dev_property: true + // }, + PassthroughRegion { + ipa: 0x8010000, + pa: PLATFORM_GICV_BASE, + length: 0x2000, + dev_property: true, + }, + ]; + // pt_dev_config.irqs = vec![UART_1_INT, INTERRUPT_IRQ_GUEST_TIMER]; + pt_dev_config.irqs = vec![INTERRUPT_IRQ_GUEST_TIMER]; + + // vm1 vm_region + let mut vm_region: Vec = Vec::new(); + vm_region.push(VmRegion { + ipa_start: 0x80000000, + length: 0x40000000, + }); + + let mut vm_dtb_devs: Vec = vec![]; + vm_dtb_devs.push(VmDtbDevConfig { + name: String::from("gicd"), + dev_type: DtbDevType::DevGicd, + irqs: vec![], + addr_region: AddrRegions { + ipa: 0x8000000, + length: 0x1000, + }, + }); + vm_dtb_devs.push(VmDtbDevConfig { + name: String::from("gicc"), + dev_type: DtbDevType::DevGicc, + irqs: vec![], + addr_region: AddrRegions { + ipa: 0x8010000, + length: 0x2000, + }, + }); + // vm_dtb_devs.push(VmDtbDevConfig { + // name: String::from("serial"), + // dev_type: DtbDevType::DevSerial, + // irqs: vec![UART_1_INT], + // addr_region: AddrRegions { + // ipa: UART_1_ADDR, + // length: 0x1000, + // }, + // }); + + // vm1 config + let vm1_config = VmConfigEntry { + id: 1, + name: Some(String::from("guest-os-0")), + os_type: VmType::VmTOs, + // cmdline: "root=/dev/vda rw audit=0", + cmdline: String::from("earlycon console=hvc0,115200n8 root=/dev/vda rw audit=0"), + + image: Arc::new(Mutex::new(VmImageConfig { + kernel_img_name: Some("Image_vanilla"), + kernel_load_ipa: 0x80080000, + kernel_load_pa: 0, + kernel_entry_point: 0x80080000, + device_tree_load_ipa: 0x80000000, + ramdisk_load_ipa: 0, //0x83000000, + mediated_block_index: Some(0), + })), + memory: Arc::new(Mutex::new(VmMemoryConfig { region: vm_region })), + cpu: Arc::new(Mutex::new(VmCpuConfig { + num: 1, + allocate_bitmap: 0b0010, + master: 1, + })), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList { + emu_dev_list: emu_dev_config, + })), + vm_pt_dev_confg: Arc::new(Mutex::new(pt_dev_config)), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList { + dtb_device_list: vm_dtb_devs, + })), + }; + println!("generate tmp_config for vm1"); + let _ = vm_cfg_add_vm_entry(vm1_config); +} + +pub fn init_tmp_config_for_vm2() { + println!("init_tmp_config_for_vm2"); + + // #################### vm2 emu ###################### + let mut emu_dev_config: Vec = Vec::new(); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("intc@8000000")), + base_ipa: 0x8000000, + length: 0x1000, + irq_id: 0, + cfg_list: Vec::new(), + emu_type: EmuDeviceType::EmuDeviceTGicd, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_blk@a000000")), + base_ipa: 0xa000000, + length: 0x1000, + irq_id: 32 + 0x10, + cfg_list: vec![0, 209715200], // 100G + emu_type: EmuDeviceType::EmuDeviceTVirtioBlk, + mediated: true, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_net@a001000")), + base_ipa: 0xa001000, + length: 0x1000, + irq_id: 32 + 0x11, + cfg_list: vec![0x74, 0x56, 0xaa, 0x0f, 0x47, 0xd2], + emu_type: EmuDeviceType::EmuDeviceTVirtioNet, + mediated: false, + }); + emu_dev_config.push(VmEmulatedDeviceConfig { + name: Some(String::from("virtio_console@a003000")), + base_ipa: 0xa003000, + length: 0x1000, + irq_id: 32 + 0x12, + cfg_list: vec![0, 0xa003000], + emu_type: EmuDeviceType::EmuDeviceTVirtioConsole, + mediated: false, + }); + + // vm2 passthrough + let mut pt_dev_config: VmPassthroughDeviceConfig = VmPassthroughDeviceConfig::default(); + pt_dev_config.regions = vec![ + // PassthroughRegion { + // ipa: UART_1_ADDR, + // pa: UART_1_ADDR, + // length: 0x1000, + // dev_property: true, + // }, + PassthroughRegion { + ipa: 0x8010000, + pa: PLATFORM_GICV_BASE, + length: 0x2000, + dev_property: true, + }, + ]; + // pt_dev_config.irqs = vec![UART_1_INT, INTERRUPT_IRQ_GUEST_TIMER]; + pt_dev_config.irqs = vec![INTERRUPT_IRQ_GUEST_TIMER]; + + // vm2 vm_region + let mut vm_region: Vec = Vec::new(); + vm_region.push(VmRegion { + ipa_start: 0x80000000, + length: 0x40000000, + }); + + let mut vm_dtb_devs: Vec = vec![]; + vm_dtb_devs.push(VmDtbDevConfig { + name: String::from("gicd"), + dev_type: DtbDevType::DevGicd, + irqs: vec![], + addr_region: AddrRegions { + ipa: 0x8000000, + length: 0x1000, + }, + }); + vm_dtb_devs.push(VmDtbDevConfig { + name: String::from("gicc"), + dev_type: DtbDevType::DevGicc, + irqs: vec![], + addr_region: AddrRegions { + ipa: 0x8010000, + length: 0x2000, + }, + }); + // vm_dtb_devs.push(VmDtbDevConfig { + // name: String::from("serial"), + // dev_type: DtbDevType::DevSerial, + // irqs: vec![UART_1_INT], + // addr_region: AddrRegions { + // ipa: UART_1_ADDR, + // length: 0x1000, + // }, + // }); + + // vm2 config + let vm2_config = VmConfigEntry { + id: 2, + name: Some(String::from("guest-os-1")), + os_type: VmType::VmTOs, + // cmdline: "root=/dev/vda rw audit=0", + cmdline: String::from("earlycon console=ttyS0,115200n8 root=/dev/vda rw audit=0"), + + image: Arc::new(Mutex::new(VmImageConfig { + kernel_img_name: Some("Image_vanilla"), + kernel_load_ipa: 0x80080000, + kernel_load_pa: 0, + kernel_entry_point: 0x80080000, + device_tree_load_ipa: 0x80000000, + ramdisk_load_ipa: 0, //0x83000000, + mediated_block_index: Some(1), + })), + memory: Arc::new(Mutex::new(VmMemoryConfig { region: vm_region })), + cpu: Arc::new(Mutex::new(VmCpuConfig { + num: 1, + allocate_bitmap: 0b0100, + master: 2, + })), + vm_emu_dev_confg: Arc::new(Mutex::new(VmEmulatedDeviceConfigList { + emu_dev_list: emu_dev_config, + })), + vm_pt_dev_confg: Arc::new(Mutex::new(pt_dev_config)), + vm_dtb_devs: Arc::new(Mutex::new(VMDtbDevConfigList { + dtb_device_list: vm_dtb_devs, + })), + }; + let _ = vm_cfg_add_vm_entry(vm2_config); +} diff --git a/src/device/device.rs b/src/device/device.rs new file mode 100644 index 0000000000000000000000000000000000000000..ccc3b2976b76d8e588545338c7e16b816a971276 --- /dev/null +++ b/src/device/device.rs @@ -0,0 +1,194 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; + +use spin::Mutex; + +pub const ARM_CORTEX_A57: u8 = 0; +pub const ARM_NVIDIA_DENVER: u8 = 1; + +#[derive(Clone)] +pub struct BlkStat { + inner: Arc>, +} + +impl BlkStat { + pub fn default() -> BlkStat { + BlkStat { + inner: Arc::new(Mutex::new(BlkStatInner::default())), + } + } + + pub fn back_up(&self) -> BlkStat { + let current_inner = self.inner.lock(); + let inner = *current_inner; + BlkStat { + inner: Arc::new(Mutex::new(inner)), + } + } + + pub fn read_req(&self) -> usize { + let inner = self.inner.lock(); + inner.read_req + } + + pub fn read_byte(&self) -> usize { + let inner = self.inner.lock(); + inner.read_byte + } + + pub fn write_req(&self) -> usize { + let inner = self.inner.lock(); + inner.write_req + } + + pub fn write_byte(&self) -> usize { + let inner = self.inner.lock(); + inner.write_byte + } + + pub fn set_read_req(&self, read_req: usize) { + let mut inner = self.inner.lock(); + inner.read_req = read_req; + } + + pub fn set_read_byte(&self, read_byte: usize) { + let mut inner = self.inner.lock(); + inner.read_byte = read_byte; + } + + pub fn set_write_req(&self, write_req: usize) { + let mut inner = self.inner.lock(); + inner.write_req = write_req; + } + + pub fn set_write_byte(&self, write_byte: usize) { + let mut inner = self.inner.lock(); + inner.write_byte = write_byte; + } +} + +#[derive(Copy, Clone)] +struct BlkStatInner { + read_req: usize, + write_req: usize, + read_byte: usize, + write_byte: usize, +} + +impl BlkStatInner { + fn default() -> BlkStatInner { + BlkStatInner { + read_req: 0, + write_req: 0, + read_byte: 0, + write_byte: 0, + } + } +} + +#[derive(Clone)] +pub struct NicStat { + inner: Arc>, +} + +impl NicStat { + pub fn default() -> NicStat { + NicStat { + inner: Arc::new(Mutex::new(NicStatInner::default())), + } + } + + pub fn back_up(&self) -> NicStat { + let current_inner = self.inner.lock(); + let inner = *current_inner; + NicStat { + inner: Arc::new(Mutex::new(inner)), + } + } + + pub fn migrate_save(&self, src_stat: NicStat) { + let mut dst_inner = self.inner.lock(); + let src_inner = src_stat.inner.lock(); + *dst_inner = *src_inner; + } + + pub fn send_req(&self) -> usize { + let inner = self.inner.lock(); + inner.send_req + } + + pub fn send_byte(&self) -> usize { + let inner = self.inner.lock(); + inner.send_byte + } + + pub fn discard(&self) -> usize { + let inner = self.inner.lock(); + inner.discard + } + + pub fn receive_req(&self) -> usize { + let inner = self.inner.lock(); + inner.receive_req + } + + pub fn receive_byte(&self) -> usize { + let inner = self.inner.lock(); + inner.receive_byte + } + + pub fn set_send_req(&self, req: usize) { + let mut inner = self.inner.lock(); + inner.send_req = req; + } + + pub fn set_send_byte(&self, byte: usize) { + let mut inner = self.inner.lock(); + inner.send_byte = byte; + } + + pub fn set_discard(&self, discard: usize) { + let mut inner = self.inner.lock(); + inner.discard = discard; + } + + pub fn set_receive_req(&self, receive_req: usize) { + let mut inner = self.inner.lock(); + inner.receive_req = receive_req; + } + + pub fn set_receive_byte(&self, receive_byte: usize) { + let mut inner = self.inner.lock(); + inner.receive_byte = receive_byte; + } +} + +#[derive(Copy, Clone)] +struct NicStatInner { + send_req: usize, + receive_req: usize, + send_byte: usize, + receive_byte: usize, + discard: usize, +} + +impl NicStatInner { + fn default() -> NicStatInner { + NicStatInner { + send_req: 0, + receive_req: 0, + send_byte: 0, + receive_byte: 0, + discard: 0, + } + } +} diff --git a/src/device/device_tree.rs b/src/device/device_tree.rs new file mode 100644 index 0000000000000000000000000000000000000000..576775876b1d6925de2704f254059035300ebef8 --- /dev/null +++ b/src/device/device_tree.rs @@ -0,0 +1,291 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; + +use vm_fdt::{Error, FdtWriter, FdtWriterResult}; + +#[cfg(feature = "pi4")] +use crate::arch::PAGE_SIZE; +use crate::config::{DtbDevType, VmDtbDevConfig}; +use crate::config::VmConfigEntry; +use crate::device::EmuDeviceType; +use crate::SYSTEM_FDT; +use crate::vmm::CPIO_RAMDISK; + +const PI4_DTB_ADDR: usize = 0xf0000000; + +pub fn init_vm0_dtb(dtb: *mut fdt::myctypes::c_void) { + #[cfg(feature = "tx2")] + unsafe { + use fdt::*; + println!("fdt orignal size {}", fdt_size(dtb)); + fdt_pack(dtb); + fdt_enlarge(dtb); + let r = fdt_del_mem_rsv(dtb, 0); + assert_eq!(r, 0); + // fdt_add_mem_rsv(fdt, 0x80000000, 0x10000000); + fdt_clear_initrd(dtb); + let r = fdt_remove_node(dtb, "/cpus/cpu-map/cluster0/core0\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_remove_node(dtb, "/cpus/cpu-map/cluster0/core1\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/cpus/cpu@0\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/cpus/cpu@1\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/sdhci@3460000\0".as_ptr()); + assert_eq!(r, 0); + // fdt_disable_node(dtb, "iommu@12000000\0".as_ptr()); + // assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/sdhci@3440000\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/serial@c280000\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/serial@3110000\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/serial@3130000\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/combined-uart\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/trusty\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/host1x/nvdisplay@15210000\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/reserved-memory/ramoops_carveout\0".as_ptr()); + assert_eq!(r, 0); + let r = fdt_disable_node(dtb, "/watchdog@30c0000\0".as_ptr()); + assert_eq!(r, 0); + // disable denver pmu + let r = fdt_disable_node(dtb, "/denver-pmu\0".as_ptr()); + assert_eq!(r, 0); + // modify arm pmu + // Hardcode: here, irq and affi are associated with clurster 1, cpu 0 + let irq: [u32; 1] = [0x128]; + let affi: [u32; 1] = [0x4]; + let r = fdt_setup_pmu( + dtb, + "arm,armv8-pmuv3\0".as_ptr(), + irq.as_ptr(), + irq.len() as u32, + affi.as_ptr(), + affi.len() as u32, + ); + assert_eq!(r, 0); + let len = fdt_size(dtb); + println!("fdt after patched size {}", len); + let slice = core::slice::from_raw_parts(dtb as *const u8, len as usize); + + SYSTEM_FDT.call_once(|| slice.to_vec()); + } + #[cfg(feature = "pi4")] + unsafe { + use fdt::*; + use crate::lib::round_up; + use crate::arch::PAGE_SIZE; + let pi_fdt = PI4_DTB_ADDR as *mut fdt::myctypes::c_void; + let len = round_up(fdt_size(pi_fdt) as usize, PAGE_SIZE) + PAGE_SIZE; + println!("fdt orignal size {}", len); + let slice = core::slice::from_raw_parts(pi_fdt as *const u8, len as usize); + SYSTEM_FDT.call_once(|| slice.to_vec()); + } +} + +// create vm1 fdt demo +pub fn create_fdt(config: VmConfigEntry) -> Result, Error> { + let mut fdt = FdtWriter::new()?; + + let root_node = fdt.begin_node("root")?; + fdt.property_string("compatible", "linux,dummy-virt")?; + fdt.property_u32("#address-cells", 0x2)?; + fdt.property_u32("#size-cells", 0x2)?; + fdt.property_u32("interrupt-parent", 0x8001)?; + + let psci = fdt.begin_node("psci")?; + fdt.property_string("compatible", "arm,psci-1.0")?; + fdt.property_string("method", "smc")?; + fdt.property_array_u32("interrupts", &[0x1, 0x7, 0x4])?; + fdt.end_node(psci)?; + + create_memory_node(&mut fdt, config.clone())?; + create_timer_node(&mut fdt, 0x8)?; + // todo: fix create_chosen_node size + create_chosen_node(&mut fdt, &config.cmdline, config.ramdisk_load_ipa(), CPIO_RAMDISK.len())?; + create_cpu_node(&mut fdt, config.clone())?; + if config.dtb_device_list().len() > 0 { + create_serial_node(&mut fdt, &config.dtb_device_list())?; + } + // match &config.vm_dtb_devs { + // Some(vm_dtb_devs) => { + // create_serial_node(&mut fdt, vm_dtb_devs)?; + // } + // None => {} + // } + create_gic_node(&mut fdt, config.gicc_addr(), config.gicd_addr())?; + + for emu_cfg in config.emulated_device_list() { + match emu_cfg.emu_type { + EmuDeviceType::EmuDeviceTVirtioBlk + | EmuDeviceType::EmuDeviceTVirtioNet + | EmuDeviceType::EmuDeviceTVirtioConsole => { + println!( + "virtio fdt node init {} {:x}", + emu_cfg.name.as_ref().unwrap(), + emu_cfg.base_ipa + ); + create_virtio_node(&mut fdt, &emu_cfg.name.unwrap(), emu_cfg.irq_id, emu_cfg.base_ipa)?; + } + EmuDeviceType::EmuDeviceTShyper => { + println!("shyper fdt node init {:x}", emu_cfg.base_ipa); + create_shyper_node( + &mut fdt, + &emu_cfg.name.unwrap(), + emu_cfg.irq_id, + emu_cfg.base_ipa, + emu_cfg.length, + )?; + } + _ => {} + } + } + + fdt.end_node(root_node)?; + fdt.finish() +} + +// hard code for tx2 vm1 +fn create_memory_node(fdt: &mut FdtWriter, config: VmConfigEntry) -> FdtWriterResult<()> { + if config.memory_region().len() == 0 { + panic!("create_memory_node memory region num 0"); + } + let memory_name = format!("memory@{:x}", config.memory_region()[0].ipa_start); + let memory = fdt.begin_node(&memory_name)?; + fdt.property_string("device_type", "memory")?; + let mut addr = vec![]; + for region in config.memory_region() { + addr.push(region.ipa_start as u64); + addr.push(region.length as u64); + } + fdt.property_array_u64("reg", addr.as_slice())?; + fdt.end_node(memory)?; + Ok(()) +} + +fn create_timer_node(fdt: &mut FdtWriter, trigger_lvl: u32) -> FdtWriterResult<()> { + let timer = fdt.begin_node("timer")?; + fdt.property_string("compatible", "arm,armv8-timer")?; + fdt.property_array_u32( + "interrupts", + &[ + 0x1, + 0xd, + trigger_lvl, + 0x1, + 0xe, + trigger_lvl, + 0x1, + 0xb, + trigger_lvl, + 0x1, + 0xa, + trigger_lvl, + ], + )?; + fdt.end_node(timer)?; + Ok(()) +} + +fn create_cpu_node(fdt: &mut FdtWriter, config: VmConfigEntry) -> FdtWriterResult<()> { + let cpus = fdt.begin_node("cpus")?; + fdt.property_u32("#size-cells", 0)?; + fdt.property_u32("#address-cells", 0x2)?; + + let cpu_num = config.cpu_allocated_bitmap().count_ones(); + for cpu_id in 0..cpu_num { + let cpu_name = format!("cpu@{:x}", cpu_id); + let cpu_node = fdt.begin_node(&cpu_name)?; + fdt.property_string("compatible", "arm,cortex-a57")?; + fdt.property_string("device_type", "cpu")?; + fdt.property_string("enable-method", "psci")?; + fdt.property_array_u32("reg", &[0, cpu_id as u32])?; + fdt.end_node(cpu_node)?; + } + + fdt.end_node(cpus)?; + + Ok(()) +} + +fn create_serial_node(fdt: &mut FdtWriter, devs_config: &Vec) -> FdtWriterResult<()> { + for dev in devs_config { + match dev.dev_type { + DtbDevType::DevSerial => { + let serial_name = format!("serial@{:x}", dev.addr_region.ipa); + let serial = fdt.begin_node(&serial_name)?; + fdt.property_string("compatible", "ns16550")?; + fdt.property_array_u64("reg", &[dev.addr_region.ipa as u64, 0x1000])?; + fdt.property_u32("reg-shift", 0x2)?; + fdt.property_array_u32("interrupts", &[0x0, (dev.irqs[0] - 32) as u32, 0x4])?; + fdt.property_u32("clock-frequency", 408000000)?; + // fdt.property_string("status", "disabled")?; + fdt.end_node(serial)?; + } + _ => {} + } + } + + Ok(()) +} + +fn create_chosen_node(fdt: &mut FdtWriter, cmdline: &str, ipa: usize, size: usize) -> FdtWriterResult<()> { + let chosen = fdt.begin_node("chosen")?; + fdt.property_string("bootargs", cmdline)?; + fdt.property_u32("linux,initrd-start", ipa as u32)?; + fdt.property_u32("linux,initrd-end", (ipa + size) as u32)?; + fdt.end_node(chosen)?; + Ok(()) +} + +fn create_gic_node(fdt: &mut FdtWriter, gicc_addr: usize, gicd_addr: usize) -> FdtWriterResult<()> { + let gic_name = format!("interrupt-controller@{:x}", gicd_addr); + let gic = fdt.begin_node(&gic_name)?; + + fdt.property_u32("phandle", 0x8001)?; + fdt.property_array_u64("reg", &[gicd_addr as u64, 0x1000, gicc_addr as u64, 0x2000])?; + fdt.property_string("compatible", "arm,gic-400")?; + fdt.property_u32("#interrupt-cells", 0x03)?; + fdt.property_null("interrupt-controller")?; + fdt.end_node(gic)?; + + Ok(()) +} + +fn create_virtio_node(fdt: &mut FdtWriter, name: &str, irq: usize, address: usize) -> FdtWriterResult<()> { + let virtio = fdt.begin_node(name)?; + fdt.property_null("dma-coherent")?; + fdt.property_string("compatible", "virtio,mmio")?; + fdt.property_array_u32("interrupts", &[0, irq as u32 - 32, 0x1])?; + fdt.property_array_u64("reg", &[address as u64, 0x400])?; + fdt.end_node(virtio)?; + + Ok(()) +} + +fn create_shyper_node(fdt: &mut FdtWriter, name: &str, irq: usize, address: usize, len: usize) -> FdtWriterResult<()> { + let shyper = fdt.begin_node(name)?; + fdt.property_string("compatible", "shyper")?; + fdt.property_array_u32("interrupts", &[0, irq as u32 - 32, 0x1])?; + if address != 0 && len != 0 { + fdt.property_array_u64("reg", &[address as u64, len as u64])?; + } + fdt.end_node(shyper)?; + + Ok(()) +} diff --git a/src/device/emu.rs b/src/device/emu.rs new file mode 100644 index 0000000000000000000000000000000000000000..45b60a09c03ab74c59c6346405cd8522db6d900f --- /dev/null +++ b/src/device/emu.rs @@ -0,0 +1,228 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::fmt::{Display, Formatter}; + +use spin::Mutex; + +use crate::arch::Vgic; +use crate::device::{ + virtio_blk_notify_handler, virtio_console_notify_handler, virtio_mediated_blk_notify_handler, + virtio_net_notify_handler, VirtioMmio, +}; +use crate::kernel::current_cpu; +use crate::lib::in_range; + +pub const EMU_DEV_NUM_MAX: usize = 32; +pub static EMU_DEVS_LIST: Mutex> = Mutex::new(Vec::new()); + +#[derive(Clone)] +pub enum EmuDevs { + Vgic(Arc), + VirtioBlk(VirtioMmio), + VirtioNet(VirtioMmio), + VirtioConsole(VirtioMmio), + None, +} + +impl EmuDevs { + pub fn migrate_emu_devs(&mut self, src_dev: EmuDevs) { + match self { + EmuDevs::Vgic(vgic) => { + if let EmuDevs::Vgic(src_vgic) = src_dev { + vgic.save_vgic(src_vgic.clone()); + } else { + println!("EmuDevs::migrate_save: illegal src dev type for vgic"); + } + } + EmuDevs::VirtioBlk(mmio) => { + if let EmuDevs::VirtioBlk(src_mmio) = src_dev { + mmio.save_mmio( + src_mmio.clone(), + if src_mmio.dev().mediated() { + Some(virtio_mediated_blk_notify_handler) + } else { + Some(virtio_blk_notify_handler) + }, + ); + } else { + println!("EmuDevs::migrate_save: illegal src dev type for virtio blk"); + } + } + EmuDevs::VirtioNet(mmio) => { + if let EmuDevs::VirtioNet(src_mmio) = src_dev { + mmio.save_mmio(src_mmio, Some(virtio_net_notify_handler)); + } else { + println!("EmuDevs::migrate_save: illegal src dev type for virtio net"); + } + } + EmuDevs::VirtioConsole(mmio) => { + if let EmuDevs::VirtioConsole(src_mmio) = src_dev { + mmio.save_mmio(src_mmio, Some(virtio_console_notify_handler)); + } else { + println!("EmuDevs::migrate_save: illegal src dev type for virtio console"); + } + } + EmuDevs::None => {} + } + } +} + +pub struct EmuContext { + pub address: usize, + pub width: usize, + pub write: bool, + pub sign_ext: bool, + pub reg: usize, + pub reg_width: usize, +} + +pub struct EmuDevEntry { + pub emu_type: EmuDeviceType, + pub vm_id: usize, + pub id: usize, + pub ipa: usize, + pub size: usize, + pub handler: EmuDevHandler, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum EmuDeviceType { + EmuDeviceTConsole = 0, + EmuDeviceTGicd = 1, + EmuDeviceTGPPT = 2, + EmuDeviceTVirtioBlk = 3, + EmuDeviceTVirtioNet = 4, + EmuDeviceTVirtioConsole = 5, + EmuDeviceTShyper = 6, + EmuDeviceTVirtioBlkMediated = 7, + EmuDeviceTIOMMU = 8, +} + +impl Display for EmuDeviceType { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + EmuDeviceType::EmuDeviceTConsole => write!(f, "console"), + EmuDeviceType::EmuDeviceTGicd => write!(f, "interrupt controller"), + EmuDeviceType::EmuDeviceTGPPT => write!(f, "partial passthrough interrupt controller"), + EmuDeviceType::EmuDeviceTVirtioBlk => write!(f, "virtio block"), + EmuDeviceType::EmuDeviceTVirtioNet => write!(f, "virtio net"), + EmuDeviceType::EmuDeviceTVirtioConsole => write!(f, "virtio console"), + EmuDeviceType::EmuDeviceTShyper => write!(f, "device shyper"), + EmuDeviceType::EmuDeviceTVirtioBlkMediated => write!(f, "medaited virtio block"), + EmuDeviceType::EmuDeviceTIOMMU => write!(f, "IOMMU"), + } + } +} + +impl EmuDeviceType { + pub fn removable(&self) -> bool { + match *self { + EmuDeviceType::EmuDeviceTGicd + | EmuDeviceType::EmuDeviceTGPPT + | EmuDeviceType::EmuDeviceTVirtioBlk + | EmuDeviceType::EmuDeviceTVirtioNet + | EmuDeviceType::EmuDeviceTVirtioConsole => true, + _ => false, + } + } +} + +impl EmuDeviceType { + pub fn from_usize(value: usize) -> EmuDeviceType { + match value { + 0 => EmuDeviceType::EmuDeviceTConsole, + 1 => EmuDeviceType::EmuDeviceTGicd, + 2 => EmuDeviceType::EmuDeviceTGPPT, + 3 => EmuDeviceType::EmuDeviceTVirtioBlk, + 4 => EmuDeviceType::EmuDeviceTVirtioNet, + 5 => EmuDeviceType::EmuDeviceTVirtioConsole, + 6 => EmuDeviceType::EmuDeviceTShyper, + 7 => EmuDeviceType::EmuDeviceTVirtioBlkMediated, + 8 => EmuDeviceType::EmuDeviceTIOMMU, + _ => panic!("Unknown EmuDeviceType value: {}", value), + } + } +} + +pub type EmuDevHandler = fn(usize, &EmuContext) -> bool; + +// TO CHECK +pub fn emu_handler(emu_ctx: &EmuContext) -> bool { + let ipa = emu_ctx.address; + let emu_devs_list = EMU_DEVS_LIST.lock(); + + for emu_dev in &*emu_devs_list { + let active_vcpu = current_cpu().active_vcpu.clone().unwrap(); + if active_vcpu.vm_id() == emu_dev.vm_id && in_range(ipa, emu_dev.ipa, emu_dev.size - 1) { + // if current_cpu().id == 2 { + // println!("emu dev {:#?} handler", emu_dev.emu_type); + // } + let handler = emu_dev.handler; + let id = emu_dev.id; + drop(emu_devs_list); + return handler(id, emu_ctx); + } + } + println!( + "emu_handler: no emul handler for Core {} data abort ipa 0x{:x}", + current_cpu().id, + ipa + ); + return false; +} + +pub fn emu_register_dev( + emu_type: EmuDeviceType, + vm_id: usize, + dev_id: usize, + address: usize, + size: usize, + handler: EmuDevHandler, +) { + let mut emu_devs_list = EMU_DEVS_LIST.lock(); + if emu_devs_list.len() >= EMU_DEV_NUM_MAX { + panic!("emu_register_dev: can't register more devs"); + } + + for emu_dev in &*emu_devs_list { + if vm_id != emu_dev.vm_id { + continue; + } + if in_range(address, emu_dev.ipa, emu_dev.size - 1) || in_range(emu_dev.ipa, address, size - 1) { + panic!("emu_register_dev: duplicated emul address region: prev address 0x{:x} size 0x{:x}, next address 0x{:x} size 0x{:x}", emu_dev.ipa, emu_dev.size, address, size); + } + } + + emu_devs_list.push(EmuDevEntry { + emu_type, + vm_id, + id: dev_id, + ipa: address, + size, + handler, + }); +} + +pub fn emu_remove_dev(vm_id: usize, dev_id: usize, address: usize, size: usize) { + let mut emu_devs_list = EMU_DEVS_LIST.lock(); + for (idx, emu_dev) in emu_devs_list.iter().enumerate() { + if vm_id == emu_dev.vm_id && emu_dev.ipa == address && emu_dev.id == dev_id && emu_dev.size == size { + emu_devs_list.remove(idx); + return; + } + } + panic!( + "emu_remove_dev: emu dev not exist address 0x{:x} size 0x{:x}", + address, size + ); +} diff --git a/src/device/mod.rs b/src/device/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..6d4def7ab4bd34aba39cddcf4b6e13adbb83a241 --- /dev/null +++ b/src/device/mod.rs @@ -0,0 +1,19 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::device::*; +pub use self::device_tree::*; +pub use self::emu::*; +pub use self::virtio::*; + +mod device; +mod device_tree; +mod emu; +mod virtio; diff --git a/src/device/virtio/blk.rs b/src/device/virtio/blk.rs new file mode 100644 index 0000000000000000000000000000000000000000..8f35dea2ff23d42055c9ceab5a21aaaae384a31a --- /dev/null +++ b/src/device/virtio/blk.rs @@ -0,0 +1,674 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; +use spin::Mutex; + +use crate::arch::PAGE_SIZE; +use crate::device::{mediated_blk_list_get, VirtioMmio, Virtq}; +use crate::kernel::{ + active_vm_id, add_async_task, async_blk_id_req, async_blk_io_req, async_ipi_req, AsyncTask, AsyncTaskData, + AsyncTaskState, IoAsyncMsg, IoIdAsyncMsg, IpiMediatedMsg, push_used_info, Vm, vm_ipa2pa, +}; +use crate::lib::{memcpy_safe, trace}; + +pub const VIRTQUEUE_BLK_MAX_SIZE: usize = 256; +pub const VIRTQUEUE_NET_MAX_SIZE: usize = 256; + +/* VIRTIO_BLK_FEATURES*/ +pub const VIRTIO_BLK_F_SIZE_MAX: usize = 1 << 1; +pub const VIRTIO_BLK_F_SEG_MAX: usize = 1 << 2; + +/* BLOCK PARAMETERS*/ +pub const SECTOR_BSIZE: usize = 512; +pub const BLOCKIF_SIZE_MAX: usize = 128 * PAGE_SIZE; +pub const BLOCKIF_IOV_MAX: usize = 512; + +/* BLOCK REQUEST TYPE*/ +pub const VIRTIO_BLK_T_IN: usize = 0; +pub const VIRTIO_BLK_T_OUT: usize = 1; +pub const VIRTIO_BLK_T_FLUSH: usize = 4; +pub const VIRTIO_BLK_T_GET_ID: usize = 8; + +/* BLOCK REQUEST STATUS*/ +pub const VIRTIO_BLK_S_OK: usize = 0; +// pub const VIRTIO_BLK_S_IOERR: usize = 1; +pub const VIRTIO_BLK_S_UNSUPP: usize = 2; + +#[repr(C)] +#[derive(Copy, Clone)] +struct BlkGeometry { + cylinders: u16, + heads: u8, + sectors: u8, +} + +impl BlkGeometry { + fn default() -> BlkGeometry { + BlkGeometry { + cylinders: 0, + heads: 0, + sectors: 0, + } + } +} + +#[repr(C)] +#[derive(Copy, Clone)] +struct BlkTopology { + // # of logical blocks per physical block (log2) + physical_block_exp: u8, + // offset of first aligned logical block + alignment_offset: u8, + // suggested minimum I/O size in blocks + min_io_size: u16, + // optimal (suggested maximum) I/O size in blocks + opt_io_size: u32, +} + +impl BlkTopology { + fn default() -> BlkTopology { + BlkTopology { + physical_block_exp: 0, + alignment_offset: 0, + min_io_size: 0, + opt_io_size: 0, + } + } +} + +#[derive(Clone)] +pub struct BlkDesc { + inner: Arc>, +} + +impl BlkDesc { + pub fn default() -> BlkDesc { + BlkDesc { + inner: Arc::new(Mutex::new(BlkDescInner::default())), + } + } + pub fn back_up(&self) -> BlkDesc { + let current_inner = self.inner.lock(); + let inner = *current_inner; + BlkDesc { + inner: Arc::new(Mutex::new(inner)), + } + } + + pub fn cfg_init(&self, bsize: usize) { + let mut inner = self.inner.lock(); + inner.cfg_init(bsize); + } + + pub fn start_addr(&self) -> usize { + let inner = self.inner.lock(); + &inner.capacity as *const _ as usize + } + + pub fn offset_data(&self, offset: usize) -> u32 { + let start_addr = self.start_addr(); + if trace() && start_addr + offset < 0x1000 { + panic!("illegal addr {:x}", start_addr + offset); + } + let value = unsafe { *((start_addr + offset) as *const u32) }; + return value; + } +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct BlkDescInner { + capacity: usize, + size_max: u32, + seg_max: u32, + geometry: BlkGeometry, + blk_size: usize, + topology: BlkTopology, + writeback: u8, + unused0: [u8; 3], + max_discard_sectors: u32, + max_discard_seg: u32, + discard_sector_alignment: u32, + max_write_zeroes_sectors: u32, + max_write_zeroes_seg: u32, + write_zeroes_may_unmap: u8, + unused1: [u8; 3], +} + +impl BlkDescInner { + pub fn default() -> BlkDescInner { + BlkDescInner { + capacity: 0, + size_max: 0, + seg_max: 0, + geometry: BlkGeometry::default(), + blk_size: 0, + topology: BlkTopology::default(), + writeback: 0, + unused0: [0; 3], + max_discard_sectors: 0, + max_discard_seg: 0, + discard_sector_alignment: 0, + max_write_zeroes_sectors: 0, + max_write_zeroes_seg: 0, + write_zeroes_may_unmap: 0, + unused1: [0; 3], + } + } + + pub fn cfg_init(&mut self, bsize: usize) { + self.capacity = bsize; + self.size_max = BLOCKIF_SIZE_MAX as u32; + self.seg_max = BLOCKIF_IOV_MAX as u32; + } +} + +#[repr(C)] +#[derive(Clone)] +pub struct BlkIov { + pub data_bg: usize, + pub len: u32, +} + +#[repr(C)] +pub struct BlkReqRegion { + pub start: usize, + pub size: usize, +} + +#[derive(Clone)] +pub struct VirtioBlkReq { + inner: Arc>, + req_list: Arc>>, +} + +impl VirtioBlkReq { + pub fn default() -> VirtioBlkReq { + VirtioBlkReq { + inner: Arc::new(Mutex::new(VirtioBlkReqInner::default())), + req_list: Arc::new(Mutex::new(Vec::new())), + } + } + + pub fn back_up(&self) -> VirtioBlkReq { + let current_inner = self.inner.lock(); + let current_req_list = self.req_list.lock(); + let inner = VirtioBlkReqInner { + region: BlkReqRegion { + start: current_inner.region.start, + size: current_inner.region.size, + }, + mediated: current_inner.mediated, + process_list: { + let mut list = vec![]; + for process in current_inner.process_list.iter() { + list.push(*process) + } + list + }, + }; + let mut req_list = vec![]; + for req in current_req_list.iter() { + req_list.push(VirtioBlkReqNode { + req_type: req.req_type, + reserved: req.reserved, + sector: req.sector, + desc_chain_head_idx: req.desc_chain_head_idx, + iov: { + let mut iov = vec![]; + for io in req.iov.iter() { + iov.push(BlkIov { + data_bg: io.data_bg, + len: io.len, + }); + } + iov + }, + iov_sum_up: req.iov_sum_up, + iov_total: req.iov_total, + }); + } + VirtioBlkReq { + inner: Arc::new(Mutex::new(inner)), + req_list: Arc::new(Mutex::new(req_list)), + } + } + + pub fn add_req_node(&self, node: VirtioBlkReqNode, _vm: Vm) { + let mut list = self.req_list.lock(); + // let mediated_blk = mediated_blk_list_get(vm.med_blk_id()); + // push_used_info(node.desc_chain_head_idx, node.iov_total as u32, vm.id()); + list.push(node); + + // match list.last_mut() { + // None => { + // list.push(node); + // } + // Some(prev) => { + // if prev.req_type == node.req_type + // && (prev.sector + prev.iov_sum_up / SECTOR_BSIZE) == node.sector + // && (prev.iov_sum_up + node.iov_sum_up) / SECTOR_BSIZE < mediated_blk.dma_block_max() + // { + // prev.iov_sum_up += node.iov_sum_up; + // prev.iov.append(&mut node.iov); + // } else { + // list.push(node); + // } + // } + // } + } + + pub fn req_num(&self) -> usize { + let list = self.req_list.lock(); + list.len() + } + + pub fn req_node(&self, idx: usize) -> VirtioBlkReqNode { + let list = self.req_list.lock(); + list[idx].clone() + } + + pub fn clear_node(&self) { + let mut list = self.req_list.lock(); + list.clear(); + } + + pub fn set_start(&self, start: usize) { + let mut inner = self.inner.lock(); + inner.set_start(start); + } + + pub fn set_size(&self, size: usize) { + let mut inner = self.inner.lock(); + inner.set_size(size); + } + + pub fn set_mediated(&self, mediated: bool) { + let mut inner = self.inner.lock(); + inner.mediated = mediated; + } + + pub fn mediated(&self) -> bool { + let inner = self.inner.lock(); + inner.mediated + } + + pub fn region_start(&self) -> usize { + let inner = self.inner.lock(); + inner.region.start + } + + pub fn region_size(&self) -> usize { + let inner = self.inner.lock(); + inner.region.size + } +} + +#[repr(C)] +#[derive(Clone)] +pub struct VirtioBlkReqNode { + req_type: u32, + reserved: u32, + sector: usize, + desc_chain_head_idx: u32, + iov: Vec, + // sum up byte for req + iov_sum_up: usize, + // total byte for current req + iov_total: usize, +} + +impl VirtioBlkReqNode { + pub fn default() -> VirtioBlkReqNode { + VirtioBlkReqNode { + req_type: 0, + reserved: 0, + sector: 0, + desc_chain_head_idx: 0, + iov: vec![], + iov_sum_up: 0, + iov_total: 0, + } + } +} + +#[repr(C)] +struct VirtioBlkReqInner { + region: BlkReqRegion, + mediated: bool, + process_list: Vec, +} + +impl VirtioBlkReqInner { + pub fn default() -> VirtioBlkReqInner { + VirtioBlkReqInner { + region: BlkReqRegion { start: 0, size: 0 }, + mediated: false, + process_list: Vec::new(), + } + } + + pub fn set_start(&mut self, start: usize) { + self.region.start = start; + } + + pub fn set_size(&mut self, size: usize) { + self.region.size = size; + } +} + +pub fn generate_blk_req(req: VirtioBlkReq, vq: Virtq, dev: VirtioMmio, cache: usize, vm: Vm) { + let region_start = req.region_start(); + let region_size = req.region_size(); + let mut cache_ptr = cache; + for idx in 0..req.req_num() { + let req_node = req.req_node(idx); + let sector = req_node.sector; + if sector + req_node.iov_sum_up / SECTOR_BSIZE > region_start + region_size { + println!( + "blk_req_handler: {} out of vm range", + if req_node.req_type == VIRTIO_BLK_T_IN as u32 { + "read" + } else { + "write" + } + ); + continue; + } + match req_node.req_type as usize { + VIRTIO_BLK_T_IN => { + if req.mediated() { + // mediated blk read + let task = AsyncTask::new( + AsyncTaskData::AsyncIoTask(IoAsyncMsg { + src_vmid: vm.id(), + vq: vq.clone(), + dev: dev.clone(), + io_type: VIRTIO_BLK_T_IN, + blk_id: vm.med_blk_id(), + sector: sector + region_start, + count: req_node.iov_sum_up / SECTOR_BSIZE, + cache, + iov_list: Arc::new(req_node.iov.clone()), + }), + vm.id(), + async_blk_io_req, + ); + add_async_task(task, false); + } else { + todo!(); + } + for iov in req_node.iov.iter() { + let data_bg = iov.data_bg; + let len = iov.len as usize; + + if len < SECTOR_BSIZE { + println!("blk_req_handler: read len < SECTOR_BSIZE"); + continue; + } + if !req.mediated() { + if trace() && (data_bg < 0x1000 || cache_ptr < 0x1000) { + panic!("illegal des addr {:x}, src addr {:x}", data_bg, cache_ptr); + } + memcpy_safe(data_bg as *mut u8, cache_ptr as *mut u8, len); + } + cache_ptr += len; + } + } + VIRTIO_BLK_T_OUT => { + for iov in req_node.iov.iter() { + let data_bg = iov.data_bg; + let len = iov.len as usize; + if len < SECTOR_BSIZE { + println!("blk_req_handler: read len < SECTOR_BSIZE"); + continue; + } + if !req.mediated() { + if trace() && (data_bg < 0x1000 || cache_ptr < 0x1000) { + panic!("illegal des addr {:x}, src addr {:x}", cache_ptr, data_bg); + } + memcpy_safe(cache_ptr as *mut u8, data_bg as *mut u8, len); + } + cache_ptr += len; + } + if req.mediated() { + // mediated blk write + let task = AsyncTask::new( + AsyncTaskData::AsyncIoTask(IoAsyncMsg { + src_vmid: vm.id(), + vq: vq.clone(), + dev: dev.clone(), + io_type: VIRTIO_BLK_T_OUT, + blk_id: vm.med_blk_id(), + sector: sector + region_start, + count: req_node.iov_sum_up / SECTOR_BSIZE, + cache, + iov_list: Arc::new(req_node.iov.clone()), + }), + vm.id(), + async_blk_io_req, + ); + add_async_task(task, false); + } else { + todo!(); + } + } + VIRTIO_BLK_T_FLUSH => { + todo!(); + } + VIRTIO_BLK_T_GET_ID => { + let data_bg = req_node.iov[0].data_bg; + let name = "virtio-blk".as_ptr(); + if trace() && (data_bg < 0x1000) { + panic!("illegal des addr {:x}", cache_ptr); + } + memcpy_safe(data_bg as *mut u8, name, 20); + let task = AsyncTask::new( + AsyncTaskData::AsyncNoneTask(IoIdAsyncMsg { + vq: vq.clone(), + dev: dev.clone(), + }), + vm.id(), + async_blk_id_req, + ); + task.set_state(AsyncTaskState::Finish); + add_async_task(task, false); + } + _ => { + println!("Wrong block request type {} ", req_node.req_type); + continue; + } + } + + // update used ring + if !req.mediated() { + todo!("reset num to vq size"); + if !vq.update_used_ring(req_node.iov_total as u32, req_node.desc_chain_head_idx as u32) { + println!("blk_req_handler: fail to update used ring"); + } + } else { + push_used_info(req_node.desc_chain_head_idx, req_node.iov_total as u32, vm.id()); + } + } + + req.clear_node(); +} + +pub fn virtio_mediated_blk_notify_handler(vq: Virtq, blk: VirtioMmio, vm: Vm) -> bool { + // add_task_count(); + let task = AsyncTask::new( + AsyncTaskData::AsyncIpiTask(IpiMediatedMsg { + src_id: vm.id(), + vq: vq.clone(), + blk: blk.clone(), + }), + vm.id(), + async_ipi_req, + ); + add_async_task(task, true); + true +} + +pub fn virtio_blk_notify_handler(vq: Virtq, blk: VirtioMmio, vm: Vm) -> bool { + if vm.id() == 0 && active_vm_id() == 0 { + panic!("src vm should not be 0"); + } + + let avail_idx = vq.avail_idx(); + + // let begin = time_current_us(); + if vq.ready() == 0 { + println!("blk virt_queue is not ready!"); + return false; + } + + // let mediated = blk.mediated(); + let dev = blk.dev(); + let req = match dev.req() { + super::DevReq::BlkReq(blk_req) => blk_req, + _ => { + panic!("virtio_blk_notify_handler: illegal req"); + } + }; + + // let vq_size = vq.num(); + let mut next_desc_idx_opt = vq.pop_avail_desc_idx(avail_idx); + let mut process_count: i32 = 0; + // let mut desc_chain_head_idx; + + // let time0 = time_current_us(); + + while next_desc_idx_opt.is_some() { + let mut next_desc_idx = next_desc_idx_opt.unwrap() as usize; + vq.disable_notify(); + if vq.check_avail_idx(avail_idx) { + vq.enable_notify(); + } + + let mut head = true; + // desc_chain_head_idx = next_desc_idx; + + // vq.show_desc_info(4, vm.clone()); + + let mut req_node = VirtioBlkReqNode::default(); + req_node.desc_chain_head_idx = next_desc_idx as u32; + // println!( + // "avail idx {} desc_chain_head {} avail flag {}", + // vq.last_avail_idx() - 1, + // req_node.desc_chain_head_idx, + // vq.avail_flags() + // ); + + loop { + if vq.desc_has_next(next_desc_idx) { + if head { + if vq.desc_is_writable(next_desc_idx) { + println!( + "Failed to get virt blk queue desc header, idx = {}, flag = {:x}", + next_desc_idx, + vq.desc_flags(next_desc_idx) + ); + blk.notify(vm.clone()); + // vq.notify(dev.int_id(), vm.clone()); + return false; + } + head = false; + let vreq_addr = vm_ipa2pa(vm.clone(), vq.desc_addr(next_desc_idx)); + if vreq_addr == 0 { + println!("virtio_blk_notify_handler: failed to get vreq"); + return false; + } + let vreq = unsafe { &mut *(vreq_addr as *mut VirtioBlkReqNode) }; + req_node.req_type = vreq.req_type; + req_node.sector = vreq.sector; + } else { + /*data handler*/ + if (vq.desc_flags(next_desc_idx) & 0x2) as u32 >> 1 == req_node.req_type { + println!( + "Failed to get virt blk queue desc data, idx = {}, req.type = {}, desc.flags = {}", + next_desc_idx, + req_node.req_type, + vq.desc_flags(next_desc_idx) + ); + blk.notify(vm.clone()); + // vq.notify(dev.int_id(), vm.clone()); + return false; + } + let data_bg = vm_ipa2pa(vm.clone(), vq.desc_addr(next_desc_idx)); + if data_bg == 0 { + println!("virtio_blk_notify_handler: failed to get iov data begin"); + return false; + } + + let iov = BlkIov { + data_bg, + len: vq.desc_len(next_desc_idx), + }; + req_node.iov_sum_up += iov.len as usize; + req_node.iov.push(iov); + } + } else { + /*state handler*/ + if !vq.desc_is_writable(next_desc_idx) { + println!("Failed to get virt blk queue desc status, idx = {}", next_desc_idx); + blk.notify(vm.clone()); + // vq.notify(dev.int_id(), vm.clone()); + return false; + } + let vstatus_addr = vm_ipa2pa(vm.clone(), vq.desc_addr(next_desc_idx)); + if vstatus_addr == 0 { + println!("virtio_blk_notify_handler: vm[{}] failed to vstatus", vm.id()); + return false; + } + let vstatus = unsafe { &mut *(vstatus_addr as *mut u8) }; + if req_node.req_type > 1 && req_node.req_type != VIRTIO_BLK_T_GET_ID as u32 { + *vstatus = VIRTIO_BLK_S_UNSUPP as u8; + } else { + *vstatus = VIRTIO_BLK_S_OK as u8; + } + break; + } + next_desc_idx = vq.desc_next(next_desc_idx) as usize; + } + req_node.iov_total = req_node.iov_sum_up; + req.add_req_node(req_node, vm.clone()); + + process_count += 1; + next_desc_idx_opt = vq.pop_avail_desc_idx(avail_idx); + } + + if !req.mediated() { + generate_blk_req(req.clone(), vq.clone(), blk.clone(), dev.cache(), vm.clone()); + } else { + let mediated_blk = mediated_blk_list_get(vm.med_blk_id()); + let cache = mediated_blk.cache_pa(); + generate_blk_req(req.clone(), vq.clone(), blk.clone(), cache, vm.clone()); + }; + + // let time1 = time_current_us(); + + if vq.avail_flags() == 0 && process_count > 0 && !req.mediated() { + println!("virtio blk notify"); + blk.notify(vm.clone()); + // vq.notify(dev.int_id(), vm.clone()); + } + + // if req.mediated() { + // finish_task(true); + // finish_async_task(true); + // async_task_exe(); + // } + + // let end = time_current_us(); + // println!("init time {}us, while handle desc ring time {}us, finish task {}us", time0 - begin, time1 - time0, end - time1); + return true; +} diff --git a/src/device/virtio/console.rs b/src/device/virtio/console.rs new file mode 100644 index 0000000000000000000000000000000000000000..7b834b409ae9d04695ab2ccffb62077fb6b0650c --- /dev/null +++ b/src/device/virtio/console.rs @@ -0,0 +1,343 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; + +use spin::Mutex; + +use crate::arch::PAGE_SIZE; +use crate::device::{VirtioMmio, Virtq}; +use crate::device::DevDesc; +use crate::device::EmuDevs; +use crate::device::VirtioIov; +use crate::kernel::{active_vm, ConsoleDescData, vm_if_set_mem_map_bit, vm_ipa2pa}; +use crate::kernel::vm; +use crate::kernel::Vm; +use crate::lib::{round_down, trace}; + +pub const VIRTQUEUE_CONSOLE_MAX_SIZE: usize = 64; + +const VIRTIO_F_VERSION_1: usize = 1 << 32; + +const VIRTQUEUE_SERIAL_MAX_SIZE: usize = 64; + +const VIRTIO_CONSOLE_F_SIZE: usize = 1 << 0; +const VIRTIO_CONSOLE_F_MULTIPORT: usize = 1 << 1; +const VIRTIO_CONSOLE_F_EMERG_WRITE: usize = 1 << 2; + +const VIRTIO_CONSOLE_DEVICE_READY: usize = 0; +const VIRTIO_CONSOLE_DEVICE_ADD: usize = 1; +const VIRTIO_CONSOLE_DEVICE_REMOVE: usize = 2; +const VIRTIO_CONSOLE_PORT_READY: usize = 3; +const VIRTIO_CONSOLE_CONSOLE_PORT: usize = 4; +const VIRTIO_CONSOLE_RESIZE: usize = 5; +const VIRTIO_CONSOLE_PORT_OPEN: usize = 6; +const VIRTIO_CONSOLE_PORT_NAME: usize = 7; + +#[derive(Clone)] +pub struct ConsoleDesc { + inner: Arc>, +} + +impl ConsoleDesc { + pub fn default() -> ConsoleDesc { + ConsoleDesc { + inner: Arc::new(Mutex::new(ConsoleDescInner::default())), + } + } + + pub fn back_up(&self) -> ConsoleDesc { + let current_inner = self.inner.lock(); + let inner = ConsoleDescInner { + oppo_end_vmid: current_inner.oppo_end_vmid, + oppo_end_ipa: current_inner.oppo_end_ipa, + cols: current_inner.cols, + rows: current_inner.rows, + max_nr_ports: current_inner.max_nr_ports, + emerg_wr: current_inner.emerg_wr, + }; + ConsoleDesc { + inner: Arc::new(Mutex::new(inner)), + } + } + + pub fn cfg_init(&self, oppo_end_vmid: u16, oppo_end_ipa: u64) { + let mut inner = self.inner.lock(); + inner.oppo_end_vmid = oppo_end_vmid; + inner.oppo_end_ipa = oppo_end_ipa; + inner.cols = 80; + inner.rows = 25; + } + + pub fn start_addr(&self) -> usize { + let inner = self.inner.lock(); + &inner.cols as *const _ as usize + } + + pub fn offset_data(&self, offset: usize) -> u32 { + let start_addr = self.start_addr(); + if trace() && start_addr + offset < 0x1000 { + println!("value addr is {}", start_addr + offset); + } + let value = unsafe { *((start_addr + offset) as *const u32) }; + return value; + } + + pub fn target_console(&self) -> (u16, u64) { + let inner = self.inner.lock(); + (inner.oppo_end_vmid, inner.oppo_end_ipa) + } + + // use for migration restore + pub fn restore_console_data(&self, desc_data: &ConsoleDescData) { + let mut inner = self.inner.lock(); + // inner.oppo_end_vmid = desc_data.oppo_end_vmid; + // inner.oppo_end_ipa = desc_data.oppo_end_ipa; + inner.cols = desc_data.cols; + inner.rows = desc_data.rows; + inner.max_nr_ports = desc_data.max_nr_ports; + inner.emerg_wr = desc_data.emerg_wr; + } + + // use for migration save + pub fn save_console_data(&self, desc_data: &mut ConsoleDescData) { + let inner = self.inner.lock(); + desc_data.oppo_end_vmid = inner.oppo_end_vmid; + desc_data.oppo_end_ipa = inner.oppo_end_ipa; + desc_data.cols = inner.cols; + desc_data.rows = inner.rows; + desc_data.max_nr_ports = inner.max_nr_ports; + desc_data.emerg_wr = inner.emerg_wr; + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct ConsoleDescInner { + oppo_end_vmid: u16, + oppo_end_ipa: u64, + // vm access + cols: u16, + rows: u16, + max_nr_ports: u32, + emerg_wr: u32, +} + +impl ConsoleDescInner { + pub fn default() -> ConsoleDescInner { + ConsoleDescInner { + oppo_end_vmid: 0, + oppo_end_ipa: 0, + cols: 0, + rows: 0, + max_nr_ports: 0, + emerg_wr: 0, + } + } +} + +pub fn console_features() -> usize { + VIRTIO_F_VERSION_1 | VIRTIO_CONSOLE_F_SIZE +} + +pub fn virtio_console_notify_handler(vq: Virtq, console: VirtioMmio, vm: Vm) -> bool { + if vq.vq_indx() % 4 != 1 { + // println!("console rx queue notified!"); + return true; + } + + if vq.ready() == 0 { + println!("virtio_console_notify_handler: console virt_queue is not ready!"); + return false; + } + + let tx_iov = VirtioIov::default(); + let dev = console.dev(); + + let (trgt_vmid, trgt_console_ipa) = match dev.desc() { + DevDesc::ConsoleDesc(desc) => desc.target_console(), + _ => { + println!("virtio_console_notify_handler: console desc should not be None"); + return false; + } + }; + + // let buf = dev.cache(); + let mut next_desc_idx_opt = vq.pop_avail_desc_idx(vq.avail_idx()); + + while next_desc_idx_opt.is_some() { + let mut idx = next_desc_idx_opt.unwrap() as usize; + let mut len = 0; + tx_iov.clear(); + + loop { + let addr = vm_ipa2pa(active_vm().unwrap(), vq.desc_addr(idx)); + if addr == 0 { + println!("virtio_console_notify_handler: failed to desc addr"); + return false; + } + tx_iov.push_data(addr, vq.desc_len(idx) as usize); + + len += vq.desc_len(idx) as usize; + if vq.desc_flags(idx) == 0 { + break; + } + idx = vq.desc_next(idx) as usize; + } + + if !virtio_console_recv(trgt_vmid, trgt_console_ipa, tx_iov.clone(), len) { + println!("virtio_console_notify_handler: failed send"); + // return false; + } + if vm.id() != 0 { + let used_addr = vm_ipa2pa(vm.clone(), vq.used_addr()); + // println!( + // "virtio_console_notify_handler: used addr {:x}, size {}", + // used_addr, + // size_of::() + // ); + vm_if_set_mem_map_bit(vm.clone(), used_addr); + vm_if_set_mem_map_bit(vm.clone(), used_addr + PAGE_SIZE); + } + if !vq.update_used_ring(len as u32, next_desc_idx_opt.unwrap() as u32) { + return false; + } + + next_desc_idx_opt = vq.pop_avail_desc_idx(vq.avail_idx()); + } + + if !vq.avail_is_avail() { + println!("invalid descriptor table index"); + return false; + } + + console.notify(vm.clone()); + // vq.notify(dev.int_id(), vm.clone()); + + true +} + +fn virtio_console_recv(trgt_vmid: u16, trgt_console_ipa: u64, tx_iov: VirtioIov, len: usize) -> bool { + let trgt_vm = match vm(trgt_vmid as usize) { + None => { + println!("target vm [{}] is not ready or not exist", trgt_vmid); + return true; + } + Some(vm) => vm, + }; + + let console = match trgt_vm.emu_console_dev(trgt_console_ipa as usize) { + EmuDevs::VirtioConsole(x) => x, + _ => { + println!( + "virtio_console_recv: trgt_vm[{}] failed to get virtio console dev", + trgt_vmid + ); + return true; + } + }; + + if !console.dev().activated() { + println!( + "virtio_console_recv: trgt_vm[{}] virtio console dev is not ready", + trgt_vmid + ); + return false; + } + + let rx_vq = match console.vq(0) { + Ok(x) => x, + Err(_) => { + println!( + "virtio_console_recv: trgt_vm[{}] failed to get virtio console rx virt queue", + trgt_vmid + ); + return false; + } + }; + + let desc_header_idx_opt = rx_vq.pop_avail_desc_idx(rx_vq.avail_idx()); + if !rx_vq.avail_is_avail() { + println!("virtio_console_recv: receive invalid avail desc idx"); + return false; + } else if desc_header_idx_opt.is_none() { + // println!("virtio_console_recv: desc_header_idx_opt.is_none()"); + return true; + } + + let desc_idx_header = desc_header_idx_opt.unwrap(); + let mut desc_idx = desc_header_idx_opt.unwrap() as usize; + let rx_iov = VirtioIov::default(); + let mut rx_len = 0; + loop { + let dst = vm_ipa2pa(trgt_vm.clone(), rx_vq.desc_addr(desc_idx)); + if dst == 0 { + println!( + "virtio_console_recv: failed to get dst, desc_idx {}, avail idx {}", + desc_idx, + rx_vq.avail_idx() + ); + return false; + } + let desc_len = rx_vq.desc_len(desc_idx) as usize; + // dirty pages + if trgt_vmid != 0 { + let mut addr = round_down(dst, PAGE_SIZE); + while addr <= round_down(dst + desc_len, PAGE_SIZE) { + vm_if_set_mem_map_bit(trgt_vm.clone(), addr); + addr += PAGE_SIZE; + } + } + rx_iov.push_data(dst, desc_len); + rx_len += desc_len; + if rx_len >= len { + break; + } + if rx_vq.desc_flags(desc_idx) & 0x1 == 0 { + break; + } + desc_idx = rx_vq.desc_next(desc_idx) as usize; + } + + if rx_len < len { + rx_vq.put_back_avail_desc_idx(); + println!("virtio_console_recv: rx_len smaller than tx_len"); + return false; + } + + if tx_iov.write_through_iov(rx_iov.clone(), len) > 0 { + println!( + "virtio_console_recv: write through iov failed, rx_iov_num {} tx_iov_num {} rx_len {} tx_len {}", + rx_iov.num(), + tx_iov.num(), + rx_len, + len + ); + return false; + } + + if trgt_vmid != 0 { + let used_addr = vm_ipa2pa(trgt_vm.clone(), rx_vq.used_addr()); + vm_if_set_mem_map_bit(trgt_vm.clone(), used_addr); + vm_if_set_mem_map_bit(trgt_vm.clone(), used_addr + PAGE_SIZE); + } + if !rx_vq.update_used_ring(len as u32, desc_idx_header as u32) { + println!( + "virtio_console_recv: update used ring failed len {} rx_vq num {}", + len, + rx_vq.num() + ); + return false; + } + + console.notify(trgt_vm.clone()); + // rx_vq.notify(console.dev().int_id(), trgt_vm.clone()); + true +} diff --git a/src/device/virtio/dev.rs b/src/device/virtio/dev.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1139e18a3f26ea0a08be3f49e14f24272002bf9 --- /dev/null +++ b/src/device/virtio/dev.rs @@ -0,0 +1,374 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; + +use spin::Mutex; + +use crate::config::VmEmulatedDeviceConfig; +// use crate::device::add_mediated_dev; +use crate::device::{net_features, NetDesc}; +use crate::device::{console_features, ConsoleDesc}; +use crate::device::{BlkDesc, BLOCKIF_IOV_MAX, VirtioBlkReq}; +use crate::device::{VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_F_VERSION_1}; +use crate::device::{BlkStat, NicStat}; +use crate::device::DevReq::BlkReq; +use crate::kernel::{ConsoleDescData, DevDescData, mem_pages_alloc, NetDescData, VirtDevData}; +use crate::mm::PageFrame; + +#[derive(Copy, Clone, Debug)] +pub enum VirtioDeviceType { + None = 0, + Net = 1, + Block = 2, + Console = 3, +} + +#[derive(Clone)] +pub enum DevStat { + BlkStat(BlkStat), + NicStat(NicStat), + None, +} + +impl DevStat { + pub fn copy_from(&mut self, stat: DevStat) { + match stat { + DevStat::BlkStat(src_stat) => { + *self = DevStat::BlkStat(src_stat.back_up()); + } + DevStat::NicStat(src_stat) => { + *self = DevStat::NicStat(src_stat.back_up()); + } + DevStat::None => { + *self = DevStat::None; + } + } + } +} + +#[derive(Clone)] +pub enum DevDesc { + BlkDesc(BlkDesc), + NetDesc(NetDesc), + ConsoleDesc(ConsoleDesc), + None, +} + +impl DevDesc { + pub fn copy_from(&mut self, desc: DevDesc) { + match desc { + DevDesc::BlkDesc(src_desc) => { + *self = DevDesc::BlkDesc(src_desc); + } + DevDesc::NetDesc(src_desc) => { + *self = DevDesc::NetDesc(src_desc.back_up()); + } + DevDesc::ConsoleDesc(src_desc) => { + *self = DevDesc::ConsoleDesc(src_desc.back_up()); + } + DevDesc::None => *self = DevDesc::None, + } + } +} + +#[derive(Clone)] +pub enum DevReq { + BlkReq(VirtioBlkReq), + None, +} + +impl DevReq { + pub fn copy_from(&mut self, src_req: DevReq) { + match src_req { + DevReq::BlkReq(req) => { + *self = BlkReq(req.back_up()); + } + DevReq::None => { + *self = DevReq::None; + } + } + } +} + +#[derive(Clone)] +pub struct VirtDev { + inner: Arc>, +} + +impl VirtDev { + pub fn default() -> VirtDev { + VirtDev { + inner: Arc::new(Mutex::new(VirtDevInner::default())), + } + } + + pub fn init(&self, dev_type: VirtioDeviceType, config: &VmEmulatedDeviceConfig, mediated: bool) { + let mut inner = self.inner.lock(); + inner.init(dev_type, config, mediated); + } + + pub fn features(&self) -> usize { + let inner = self.inner.lock(); + inner.features + } + + pub fn generation(&self) -> usize { + let inner = self.inner.lock(); + inner.generation + } + + pub fn desc(&self) -> DevDesc { + let inner = self.inner.lock(); + inner.desc.clone() + } + + pub fn req(&self) -> DevReq { + let inner = self.inner.lock(); + inner.req.clone() + } + + pub fn int_id(&self) -> usize { + let inner = self.inner.lock(); + inner.int_id + } + + pub fn cache(&self) -> usize { + let inner = self.inner.lock(); + return inner.cache.as_ref().unwrap().pa(); + } + + pub fn stat(&self) -> DevStat { + let inner = self.inner.lock(); + inner.stat.clone() + } + + pub fn activated(&self) -> bool { + let inner = self.inner.lock(); + inner.activated + } + + pub fn set_activated(&self, activated: bool) { + let mut inner = self.inner.lock(); + inner.activated = activated; + } + + pub fn mediated(&self) -> bool { + let inner = self.inner.lock(); + inner.mediated() + } + + pub fn is_net(&self) -> bool { + let inner = self.inner.lock(); + match &inner.desc { + DevDesc::NetDesc(_) => { true } + _ => { false } + } + } + + // use for migration save + pub fn restore_virt_dev_data(&self, dev_data: &VirtDevData) { + let mut inner = self.inner.lock(); + // println!( + // "activated {}, type {:#?}, features 0x{:x}, generation {}, int id {}", + // dev_data.activated, dev_data.dev_type, dev_data.features, dev_data.generation, dev_data.int_id + // ); + inner.activated = dev_data.activated; + inner.dev_type = dev_data.dev_type; + inner.features = dev_data.features; + inner.generation = dev_data.generation; + inner.int_id = dev_data.int_id; + match &inner.desc { + DevDesc::BlkDesc(_) => { + todo!("restore_virt_dev_data: Migrate vm use nfs"); + } + DevDesc::NetDesc(net_desc) => { + if let DevDescData::NetDesc(desc_data) = &dev_data.desc { + net_desc.restore_net_data(desc_data); + } + } + DevDesc::ConsoleDesc(console_desvc) => { + if let DevDescData::ConsoleDesc(desc_data) = &dev_data.desc { + console_desvc.restore_console_data(desc_data); + } + } + DevDesc::None => {} + } + } + + // use for migration save + pub fn save_virt_dev_data(&self, dev_data: &mut VirtDevData) { + let mut inner = self.inner.lock(); + dev_data.activated = inner.activated; + dev_data.dev_type = inner.dev_type; + dev_data.features = inner.features; + dev_data.generation = inner.generation; + dev_data.int_id = inner.int_id; + match &inner.desc { + DevDesc::BlkDesc(_) => { + todo!("save_virt_dev_data: Migrate vm use nfs"); + } + DevDesc::NetDesc(net_desc) => { + dev_data.desc = DevDescData::NetDesc(NetDescData { mac: [0; 6], status: 0 }); + if let DevDescData::NetDesc(desc_data) = &mut dev_data.desc { + net_desc.save_net_data(desc_data); + } + } + DevDesc::ConsoleDesc(console_desvc) => { + dev_data.desc = DevDescData::ConsoleDesc(ConsoleDescData { + oppo_end_vmid: 0, + oppo_end_ipa: 0, + cols: 0, + rows: 0, + max_nr_ports: 0, + emerg_wr: 0, + }); + if let DevDescData::ConsoleDesc(desc_data) = &mut dev_data.desc { + console_desvc.save_console_data(desc_data); + } + } + DevDesc::None => {} + } + // set activated to false + inner.activated = false; + } + + // use for live update + pub fn save_virt_dev(&self, src_dev: VirtDev) { + let mut inner = self.inner.lock(); + let src_dev_inner = src_dev.inner.lock(); + inner.activated = src_dev_inner.activated; + inner.dev_type = src_dev_inner.dev_type; + inner.features = src_dev_inner.features; + inner.generation = src_dev_inner.generation; + inner.int_id = src_dev_inner.int_id; + inner.desc.copy_from(src_dev_inner.desc.clone()); + inner.req.copy_from(src_dev_inner.req.clone()); + // inner.cache is set by fn dev_init, no need to copy here + inner.cache = match &src_dev_inner.cache { + None => None, + Some(page) => Some(PageFrame::new(page.pa, page.page_num)), + }; + inner.stat.copy_from(src_dev_inner.stat.clone()); + } +} + +pub struct VirtDevInner { + activated: bool, + dev_type: VirtioDeviceType, + features: usize, + generation: usize, + int_id: usize, + desc: DevDesc, + req: DevReq, + cache: Option, + stat: DevStat, +} + +impl VirtDevInner { + pub fn default() -> VirtDevInner { + VirtDevInner { + activated: false, + dev_type: VirtioDeviceType::None, + features: 0, + generation: 0, + int_id: 0, + desc: DevDesc::None, + req: DevReq::None, + cache: None, + stat: DevStat::None, + } + } + + pub fn mediated(&self) -> bool { + match &self.req { + DevReq::BlkReq(req) => req.mediated(), + DevReq::None => false, + } + } + + // virtio_dev_init + pub fn init(&mut self, dev_type: VirtioDeviceType, config: &VmEmulatedDeviceConfig, mediated: bool) { + self.dev_type = dev_type; + self.int_id = config.irq_id; + + match self.dev_type { + VirtioDeviceType::Block => { + let blk_desc = BlkDesc::default(); + blk_desc.cfg_init(config.cfg_list[1]); + self.desc = DevDesc::BlkDesc(blk_desc); + + // TODO: blk_features_init & cache init + self.features |= VIRTIO_BLK_F_SIZE_MAX | VIRTIO_BLK_F_SEG_MAX | VIRTIO_F_VERSION_1; + + let blk_req = VirtioBlkReq::default(); + blk_req.set_start(config.cfg_list[0]); + blk_req.set_mediated(mediated); + blk_req.set_size(config.cfg_list[1]); + self.req = DevReq::BlkReq(blk_req); + + match mem_pages_alloc(BLOCKIF_IOV_MAX) { + Ok(page_frame) => { + // println!("PageFrame pa {:x}", page_frame.pa()); + self.cache = Some(page_frame); + // if mediated { + // // todo: change to iov ring + // let cache_size = BLOCKIF_IOV_MAX * PAGE_SIZE; + // add_mediated_dev(0, page_frame.pa(), cache_size); + // } + } + Err(_) => { + println!("VirtDevInner::init(): mem_pages_alloc failed"); + } + } + + self.stat = DevStat::BlkStat(BlkStat::default()); + } + VirtioDeviceType::Net => { + let net_desc = NetDesc::default(); + net_desc.cfg_init(&config.cfg_list); + self.desc = DevDesc::NetDesc(net_desc); + + self.features |= net_features(); + + match mem_pages_alloc(1) { + Ok(page_frame) => { + // println!("PageFrame pa {:x}", page_frame.pa()); + self.cache = Some(page_frame); + } + Err(_) => { + println!("VirtDevInner::init(): mem_pages_alloc failed"); + } + } + + self.stat = DevStat::NicStat(NicStat::default()); + } + VirtioDeviceType::Console => { + let console_desc = ConsoleDesc::default(); + console_desc.cfg_init(config.cfg_list[0] as u16, config.cfg_list[1] as u64); + self.desc = DevDesc::ConsoleDesc(console_desc); + self.features |= console_features(); + + match mem_pages_alloc(1) { + Ok(page_frame) => { + // println!("PageFrame pa {:x}", page_frame.pa()); + self.cache = Some(page_frame); + } + Err(_) => { + println!("VirtDevInner::init(): mem_pages_alloc failed"); + } + } + } + _ => { + panic!("ERROR: Wrong virtio device type"); + } + } + } +} diff --git a/src/device/virtio/iov.rs b/src/device/virtio/iov.rs new file mode 100644 index 0000000000000000000000000000000000000000..ff94115a75b9877e0223283f6bddbf2208da8ae0 --- /dev/null +++ b/src/device/virtio/iov.rs @@ -0,0 +1,196 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::slice::from_raw_parts; + +use spin::Mutex; + +use crate::lib::{memcpy_safe, trace}; + +#[derive(Clone)] +pub struct VirtioIov { + inner: Arc>, +} + +impl VirtioIov { + pub fn default() -> VirtioIov { + VirtioIov { + inner: Arc::new(Mutex::new(VirtioIovInner::default())), + } + } + + pub fn clear(&self) { + let mut inner = self.inner.lock(); + inner.vector.clear(); + } + + pub fn push_data(&self, buf: usize, len: usize) { + let mut inner = self.inner.lock(); + inner.vector.push(VirtioIovData { buf, len }); + } + + pub fn get_buf(&self, idx: usize) -> usize { + let inner = self.inner.lock(); + inner.vector[idx].buf + } + + pub fn to_buf(&self, addr: usize, len: usize) { + let mut size = len; + let inner = self.inner.lock(); + for iov_data in &inner.vector { + let offset = len - size; + let dst = addr + offset; + if iov_data.len >= size { + memcpy_safe(dst as *const u8, iov_data.buf as *const u8, size); + break; + } else { + memcpy_safe(dst as *const u8, iov_data.buf as *const u8, iov_data.len); + size -= iov_data.len; + } + } + } + + pub fn from_buf(&self, addr: usize, len: usize) { + let mut size = len; + let inner = self.inner.lock(); + for iov_data in &inner.vector { + let offset = len - size; + let src = addr + offset; + if iov_data.len >= size { + memcpy_safe(iov_data.buf as *const u8, src as *const u8, size); + break; + } else { + memcpy_safe(iov_data.buf as *const u8, src as *const u8, iov_data.len); + size -= iov_data.len; + } + } + } + + pub fn num(&self) -> usize { + let inner = self.inner.lock(); + inner.vector.len() + } + + pub fn get_len(&self, idx: usize) -> usize { + let inner = self.inner.lock(); + inner.vector[idx].len + } + + pub fn get_ptr(&self, size: usize) -> &'static [u8] { + let inner = self.inner.lock(); + // let mut iov_idx = 0; + let mut idx = size; + + for iov_data in &inner.vector { + if iov_data.len > idx { + if trace() && iov_data.buf + idx < 0x1000 { + panic!("illegal addr {:x}", iov_data.buf + idx); + } + return unsafe { from_raw_parts((iov_data.buf + idx) as *const u8, 14) }; + } else { + idx -= iov_data.len; + } + } + + println!("iov get_ptr failed"); + println!("get_ptr iov {:#?}", inner.vector); + println!("size {}, idx {}", size, idx); + return &[0]; + } + + pub fn write_through_iov(&self, dst: VirtioIov, remain: usize) -> usize { + let inner = self.inner.lock(); + + let mut dst_iov_idx = 0; + let mut src_iov_idx = 0; + let mut dst_ptr = dst.get_buf(0); + let mut src_ptr = inner.vector[0].buf; + let mut dst_vlen_remain = dst.get_len(0); + let mut src_vlen_remain = inner.vector[0].len; + let mut remain = remain; + // println!( + // "dst_vlen_remain {}, src_vlen_remain {}, remain {}", + // dst_vlen_remain, src_vlen_remain, remain + // ); + + while remain > 0 { + if dst_iov_idx == dst.num() || src_iov_idx == inner.vector.len() { + break; + } + + let written; + if dst_vlen_remain > src_vlen_remain { + written = src_vlen_remain; + if trace() && (dst_ptr < 0x1000 || src_ptr < 0x1000) { + panic!("illegal des addr {:x}, src addr {:x}", dst_ptr, src_ptr); + } + memcpy_safe(dst_ptr as *const u8, src_ptr as *const u8, written); + src_iov_idx += 1; + if src_iov_idx < inner.vector.len() { + src_ptr = inner.vector[src_iov_idx].buf; + src_vlen_remain = inner.vector[src_iov_idx].len; + dst_ptr += written; + dst_vlen_remain -= written; + } + // if dst_vlen_remain == 0 { + // dst_iov_idx += 1; + // dst_ptr = dst.get_buf(dst_iov_idx); + // dst_vlen_remain = dst.get_len(dst_iov_idx); + // } + } else { + written = dst_vlen_remain; + if trace() && (dst_ptr < 0x1000 || src_ptr < 0x1000) { + panic!("illegal des addr {:x}, src addr {:x}", dst_ptr, src_ptr); + } + memcpy_safe(dst_ptr as *const u8, src_ptr as *const u8, written); + dst_iov_idx += 1; + if dst_iov_idx < dst.num() { + dst_ptr = dst.get_buf(dst_iov_idx); + dst_vlen_remain = dst.get_len(dst_iov_idx); + src_ptr += written; + src_vlen_remain -= written; + } + if inner.vector[src_iov_idx].len == 0 { + src_iov_idx += 1; + if src_iov_idx < inner.vector.len() { + src_ptr = inner.vector[src_iov_idx].buf; + src_vlen_remain = inner.vector[src_iov_idx].len; + } + } + } + // if remain < written { + // println!("remain {} less than writter {}", remain, written); + // return 1; + // } + remain -= written; + } + + remain + } +} + +#[derive(Debug)] +struct VirtioIovData { + buf: usize, + len: usize, +} + +#[derive(Debug)] +struct VirtioIovInner { + vector: Vec, +} + +impl VirtioIovInner { + pub fn default() -> VirtioIovInner { + VirtioIovInner { vector: Vec::new() } + } +} diff --git a/src/device/virtio/mediated.rs b/src/device/virtio/mediated.rs new file mode 100644 index 0000000000000000000000000000000000000000..0f8be6eaf0992af56b025f134369243ac0a7a19f --- /dev/null +++ b/src/device/virtio/mediated.rs @@ -0,0 +1,271 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::device::{virtio_blk_notify_handler, VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT}; +use crate::kernel::{ + active_vm, async_task_exe, AsyncTaskState, finish_async_task, hvc_send_msg_to_vm, HvcDefaultMsg, HvcGuestMsg, + IpiInnerMsg, set_front_io_task_state, vm, vm_ipa2pa, VM_LIST, +}; +use crate::kernel::{ipi_register, IpiMessage, IpiType}; +use crate::lib::trace; + +pub static MEDIATED_BLK_LIST: Mutex> = Mutex::new(Vec::new()); + +pub fn mediated_blk_list_push(mut blk: MediatedBlk) { + let mut list = MEDIATED_BLK_LIST.lock(); + for vm in VM_LIST.lock().iter() { + if let Some(id) = vm.config().mediated_block_index() { + if id == list.len() { + info!("Assign blk[{}] to VM {}", list.len(), vm.id()); + blk.avail = false; + #[cfg(feature = "static-config")] + { + // NOTE: here, VM0 must monopolize Core 0 + use crate::vmm::vmm_boot_vm; + vmm_boot_vm(vm.id()); + } + break; + } + } + } + list.push(blk); +} + +// TODO: not concern abort the num of sectors +pub fn mediated_blk_request() -> Result { + let mut list = MEDIATED_BLK_LIST.lock(); + for (idx, blk) in list.iter_mut().enumerate() { + if blk.avail { + blk.avail = false; + return Ok(idx); + } + } + Err(()) +} + +pub fn mediated_blk_free(idx: usize) { + let mut list = MEDIATED_BLK_LIST.lock(); + list[idx].avail = true; +} + +pub fn mediated_blk_list_get(idx: usize) -> MediatedBlk { + let list = MEDIATED_BLK_LIST.lock(); + list[idx].clone() +} + +pub fn mediated_blk_list_get_from_pa(pa: usize) -> Option { + let list = MEDIATED_BLK_LIST.lock(); + for blk in &*list { + if blk.base_addr == pa { + return Some(blk.clone()); + } + } + None +} + +#[derive(Clone)] +pub struct MediatedBlk { + pub base_addr: usize, + pub avail: bool, // mediated blk will not be removed after append +} + +impl MediatedBlk { + pub fn content(&self) -> &mut MediatedBlkContent { + if trace() && self.base_addr < 0x1000 { + panic!("illeagal addr {:x}", self.base_addr); + } + unsafe { &mut *(self.base_addr as *mut MediatedBlkContent) } + } + + pub fn dma_block_max(&self) -> usize { + self.content().cfg.dma_block_max + } + + pub fn nreq(&self) -> usize { + self.content().nreq + } + + pub fn cache_ipa(&self) -> usize { + self.content().cfg.cache_ipa + } + + pub fn cache_pa(&self) -> usize { + self.content().cfg.cache_pa + } + + pub fn set_nreq(&self, nreq: usize) { + self.content().nreq = nreq; + } + + pub fn set_type(&self, req_type: usize) { + self.content().req.req_type = req_type as u32; + } + + pub fn set_sector(&self, sector: usize) { + self.content().req.sector = sector; + } + + pub fn set_count(&self, count: usize) { + self.content().req.count = count; + } + + pub fn set_cache_pa(&self, cache_pa: usize) { + self.content().cfg.cache_pa = cache_pa; + } +} + +#[repr(C)] +pub struct MediatedBlkContent { + nreq: usize, + cfg: MediatedBlkCfg, + req: MediatedBlkReq, +} + +#[repr(C)] +pub struct MediatedBlkCfg { + name: [u8; 32], + block_dev_path: [u8; 32], + block_num: usize, + dma_block_max: usize, + cache_size: usize, + idx: u16, + // TODO: enable page cache + pcache: bool, + cache_va: usize, + cache_ipa: usize, + cache_pa: usize, +} + +#[repr(C)] +pub struct MediatedBlkReq { + req_type: u32, + sector: usize, + count: usize, +} + +pub fn mediated_dev_init() { + if !ipi_register(IpiType::IpiTMediatedDev, mediated_ipi_handler) { + panic!("mediated_dev_init: failed to register ipi IpiTMediatedDev"); + } +} + +// only run in vm0 +pub fn mediated_dev_append(_class_id: usize, mmio_ipa: usize) -> Result { + let vm = active_vm().unwrap(); + let blk_pa = vm_ipa2pa(vm.clone(), mmio_ipa); + let mediated_blk = MediatedBlk { + base_addr: blk_pa, + avail: true, + }; + mediated_blk.set_nreq(0); + + let cache_pa = vm_ipa2pa(vm.clone(), mediated_blk.cache_ipa()); + info!( + "mediated_dev_append: dev_ipa_reg 0x{:x}, cache ipa 0x{:x}, cache_pa 0x{:x}, dma_block_max 0x{:x}", + mmio_ipa, + mediated_blk.cache_ipa(), + cache_pa, + mediated_blk.dma_block_max() + ); + mediated_blk.set_cache_pa(cache_pa); + mediated_blk_list_push(mediated_blk); + Ok(0) +} + +// service VM finish blk request, and inform the requested VM +pub fn mediated_blk_notify_handler(dev_ipa_reg: usize) -> Result { + let dev_pa_reg = vm_ipa2pa(active_vm().unwrap(), dev_ipa_reg); + + // check weather src vm is still alive + let mediated_blk = match mediated_blk_list_get_from_pa(dev_pa_reg) { + Some(blk) => blk, + None => { + println!("illegal mediated blk pa {:x} ipa {:x}", dev_pa_reg, dev_ipa_reg); + return Err(()); + } + }; + if mediated_blk.avail == false { + // finish current IO task + set_front_io_task_state(AsyncTaskState::Finish); + } else { + println!("Mediated blk not belong to any VM"); + } + // invoke the excuter to handle finished IO task + async_task_exe(); + Ok(0) +} + +fn check_sum(addr: usize, len: usize) -> usize { + let slice = unsafe { core::slice::from_raw_parts(addr as *const usize, len / 8) }; + let mut sum = 0; + for num in slice { + sum ^= num; + } + sum +} + +// call by normal VMs ipi request (generated by mediated virtio blk) +pub fn mediated_ipi_handler(msg: &IpiMessage) { + // println!("core {} mediated_ipi_handler", current_cpu().id); + match &msg.ipi_message { + IpiInnerMsg::MediatedMsg(mediated_msg) => { + let src_id = mediated_msg.src_id; + let vm = vm(src_id).unwrap(); + // generate IO request in `virtio_blk_notify_handler` + virtio_blk_notify_handler(mediated_msg.vq.clone(), mediated_msg.blk.clone(), vm); + // mark the ipi task as finish (pop it from the ipi queue) + finish_async_task(true); + // invoke the executor to do IO request + async_task_exe(); + } + _ => {} + } +} + +pub fn mediated_blk_read(blk_idx: usize, sector: usize, count: usize) { + let mediated_blk = mediated_blk_list_get(blk_idx); + let nreq = mediated_blk.nreq(); + mediated_blk.set_nreq(nreq + 1); + mediated_blk.set_type(VIRTIO_BLK_T_IN); + mediated_blk.set_sector(sector); + mediated_blk.set_count(count); + + let med_msg = HvcDefaultMsg { + fid: 3, // HVC_MEDIATED + event: 50, // HVC_MEDIATED_DEV_NOTIFY + }; + + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::Default(med_msg)) { + println!("mediated_blk_read: failed to notify VM 0"); + } +} + +pub fn mediated_blk_write(blk_idx: usize, sector: usize, count: usize) { + let mediated_blk = mediated_blk_list_get(blk_idx); + let nreq = mediated_blk.nreq(); + mediated_blk.set_nreq(nreq + 1); + mediated_blk.set_type(VIRTIO_BLK_T_OUT); + mediated_blk.set_sector(sector); + mediated_blk.set_count(count); + + let med_msg = HvcDefaultMsg { + fid: 3, // HVC_MEDIATED + event: 50, // HVC_MEDIATED_DRV_NOTIFY + }; + + // println!("mediated_blk_write send msg to vm0"); + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::Default(med_msg)) { + println!("mediated_blk_write: failed to notify VM 0"); + } +} diff --git a/src/device/virtio/mmio.rs b/src/device/virtio/mmio.rs new file mode 100644 index 0000000000000000000000000000000000000000..cd29716d19855b068ef568c1c269336e9fa7ddc1 --- /dev/null +++ b/src/device/virtio/mmio.rs @@ -0,0 +1,828 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; +use spin::Mutex; + +use crate::config::VmEmulatedDeviceConfig; +use crate::device::{ + EmuContext, virtio_blk_notify_handler, virtio_console_notify_handler, virtio_mediated_blk_notify_handler, + virtio_net_handle_ctrl, virtio_net_notify_handler, +}; +use crate::device::{EmuDevs, VirtioDeviceType}; +use crate::device::{VirtioQueue, Virtq}; +use crate::device::{VIRTQUEUE_BLK_MAX_SIZE, VIRTQUEUE_CONSOLE_MAX_SIZE, VIRTQUEUE_NET_MAX_SIZE}; +use crate::device::VirtDev; +use crate::device::VIRTQ_READY; +use crate::kernel::{current_cpu, ipi_send_msg, IpiInnerMsg, IpiIntInjectMsg, IpiType, VirtioMmioData, vm_ipa2pa, VmPa}; +use crate::kernel::{active_vm, active_vm_id}; +use crate::kernel::Vm; + +pub const VIRTIO_F_VERSION_1: usize = 1 << 32; +pub const VIRTIO_MMIO_MAGIC_VALUE: usize = 0x000; +pub const VIRTIO_MMIO_VERSION: usize = 0x004; +pub const VIRTIO_MMIO_DEVICE_ID: usize = 0x008; +pub const VIRTIO_MMIO_VENDOR_ID: usize = 0x00c; +pub const VIRTIO_MMIO_HOST_FEATURES: usize = 0x010; +pub const VIRTIO_MMIO_HOST_FEATURES_SEL: usize = 0x014; +pub const VIRTIO_MMIO_GUEST_FEATURES: usize = 0x020; +pub const VIRTIO_MMIO_GUEST_FEATURES_SEL: usize = 0x024; +pub const VIRTIO_MMIO_QUEUE_SEL: usize = 0x030; +pub const VIRTIO_MMIO_QUEUE_NUM_MAX: usize = 0x034; +pub const VIRTIO_MMIO_QUEUE_NUM: usize = 0x038; +pub const VIRTIO_MMIO_QUEUE_READY: usize = 0x044; +pub const VIRTIO_MMIO_QUEUE_NOTIFY: usize = 0x050; +pub const VIRTIO_MMIO_INTERRUPT_STATUS: usize = 0x060; +pub const VIRTIO_MMIO_INTERRUPT_ACK: usize = 0x064; +pub const VIRTIO_MMIO_STATUS: usize = 0x070; +pub const VIRTIO_MMIO_QUEUE_DESC_LOW: usize = 0x080; +pub const VIRTIO_MMIO_QUEUE_DESC_HIGH: usize = 0x084; +pub const VIRTIO_MMIO_QUEUE_AVAIL_LOW: usize = 0x090; +pub const VIRTIO_MMIO_QUEUE_AVAIL_HIGH: usize = 0x094; +pub const VIRTIO_MMIO_QUEUE_USED_LOW: usize = 0x0a0; +pub const VIRTIO_MMIO_QUEUE_USED_HIGH: usize = 0x0a4; +pub const VIRTIO_MMIO_CONFIG_GENERATION: usize = 0x0fc; +pub const VIRTIO_MMIO_CONFIG: usize = 0x100; +pub const VIRTIO_MMIO_REGS_END: usize = 0x200; + +pub const VIRTIO_MMIO_INT_VRING: u32 = 1 << 0; +pub const VIRTIO_MMIO_INT_CONFIG: u32 = 1 << 1; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct VirtMmioRegs { + magic: u32, + version: u32, + device_id: u32, + vendor_id: u32, + dev_feature: u32, + dev_feature_sel: u32, + drv_feature: u32, + drv_feature_sel: u32, + q_sel: u32, + q_num_max: u32, + irt_stat: u32, + irt_ack: u32, + dev_stat: u32, +} + +impl VirtMmioRegs { + pub fn default() -> VirtMmioRegs { + VirtMmioRegs { + magic: 0, + version: 0, + device_id: 0, + vendor_id: 0, + dev_feature: 0, + dev_feature_sel: 0, + drv_feature: 0, + drv_feature_sel: 0, + q_sel: 0, + q_num_max: 0, + irt_stat: 0, + irt_ack: 0, + dev_stat: 0, + } + } + + pub fn init(&mut self, id: VirtioDeviceType) { + self.magic = 0x74726976; + self.version = 0x2; + self.vendor_id = 0x8888; + self.device_id = id as u32; + self.dev_feature = 0; + self.drv_feature = 0; + self.q_sel = 0; + } + + pub fn save_regs(&mut self, src: &VirtMmioRegs) { + self.magic = src.magic; + self.version = src.version; + self.device_id = src.device_id; + self.vendor_id = src.vendor_id; + self.dev_feature = src.dev_feature; + self.dev_feature_sel = src.dev_feature_sel; + self.drv_feature = src.drv_feature; + self.drv_feature_sel = src.drv_feature_sel; + self.q_sel = src.q_sel; + self.q_num_max = src.q_num_max; + self.irt_stat = src.irt_stat; + self.irt_ack = src.irt_ack; + self.dev_stat = src.dev_stat; + } +} + +#[derive(Clone)] +pub struct VirtioMmio { + inner: Arc>, +} + +impl VirtioQueue for VirtioMmio { + fn virtio_queue_init(&self, dev_type: VirtioDeviceType) { + match dev_type { + VirtioDeviceType::Block => { + self.set_q_num_max(VIRTQUEUE_BLK_MAX_SIZE as u32); + let mut inner = self.inner.lock(); + let queue = Virtq::default(); + queue.reset(0); + if inner.dev.mediated() { + queue.set_notify_handler(virtio_mediated_blk_notify_handler); + } else { + queue.set_notify_handler(virtio_blk_notify_handler); + } + inner.vq.push(queue); + } + VirtioDeviceType::Net => { + self.set_q_num_max(VIRTQUEUE_NET_MAX_SIZE as u32); + let mut inner = self.inner.lock(); + // Not support feature VIRTIO_NET_F_CTRL_VQ (no control queue) + for i in 0..2 { + let queue = Virtq::default(); + queue.reset(i); + queue.set_notify_handler(virtio_net_notify_handler); + inner.vq.push(queue); + } + inner.vq.push(Virtq::default()); + inner.vq[2].reset(2); + inner.vq[2].set_notify_handler(virtio_net_handle_ctrl); + } + VirtioDeviceType::Console => { + self.set_q_num_max(VIRTQUEUE_CONSOLE_MAX_SIZE as u32); + let mut inner = self.inner.lock(); + for i in 0..4 { + let queue = Virtq::default(); + queue.reset(i); + queue.set_notify_handler(virtio_console_notify_handler); + inner.vq.push(queue); + } + } + VirtioDeviceType::None => { + panic!("virtio_queue_init: unknown emulated device type"); + } + } + } + + fn virtio_queue_reset(&self, index: usize) { + let inner = self.inner.lock(); + inner.vq[index].reset(index); + } +} + +impl VirtioMmio { + pub fn new(id: usize) -> VirtioMmio { + VirtioMmio { + inner: Arc::new(Mutex::new(VirtioMmioInner::new(id))), + } + } + + pub fn notify_config(&self, vm: Vm) { + let mut inner = self.inner.lock(); + inner.regs.irt_stat |= VIRTIO_MMIO_INT_CONFIG; + let int_id = inner.dev.int_id(); + let trgt_id = vm.vcpu(0).unwrap().phys_id(); + drop(inner); + use crate::kernel::interrupt_vm_inject; + if trgt_id == current_cpu().id { + interrupt_vm_inject(vm.clone(), vm.vcpu(0).unwrap(), int_id, 0); + } else { + let m = IpiIntInjectMsg { vm_id: vm.id(), int_id }; + if !ipi_send_msg(trgt_id, IpiType::IpiTIntInject, IpiInnerMsg::IntInjectMsg(m)) { + println!("notify_config: failed to send ipi to Core {}", trgt_id); + } + } + } + + pub fn notify(&self, vm: Vm) { + let mut inner = self.inner.lock(); + inner.regs.irt_stat |= VIRTIO_MMIO_INT_VRING; + let int_id = inner.dev.int_id(); + let trgt_id = vm.vcpu(0).unwrap().phys_id(); + drop(inner); + use crate::kernel::interrupt_vm_inject; + if trgt_id == current_cpu().id { + interrupt_vm_inject(vm.clone(), vm.vcpu(0).unwrap(), int_id, 0); + } else { + let m = IpiIntInjectMsg { vm_id: vm.id(), int_id }; + if !ipi_send_msg(trgt_id, IpiType::IpiTIntInject, IpiInnerMsg::IntInjectMsg(m)) { + println!("notify_config: failed to send ipi to Core {}", trgt_id); + } + } + } + + pub fn mmio_reg_init(&self, dev_type: VirtioDeviceType) { + let mut inner = self.inner.lock(); + inner.reg_init(dev_type); + } + + pub fn dev_init(&self, dev_type: VirtioDeviceType, config: &VmEmulatedDeviceConfig, mediated: bool) { + let inner = self.inner.lock(); + inner.dev.init(dev_type, config, mediated) + } + + // virtio_dev_reset + pub fn dev_reset(&self) { + let mut inner = self.inner.lock(); + inner.regs.dev_stat = 0; + inner.regs.irt_stat = 0; + let idx = inner.regs.q_sel as usize; + inner.vq[idx].set_ready(0); + for (idx, virtq) in inner.vq.iter().enumerate() { + virtq.reset(idx); + } + inner.dev.set_activated(false); + } + + pub fn set_irt_stat(&self, irt_stat: u32) { + let mut inner = self.inner.lock(); + inner.regs.irt_stat = irt_stat; + } + + pub fn set_irt_ack(&self, irt_ack: u32) { + let mut inner = self.inner.lock(); + inner.regs.irt_ack = irt_ack; + } + + pub fn set_q_sel(&self, q_sel: u32) { + let mut inner = self.inner.lock(); + inner.regs.q_sel = q_sel; + } + + pub fn set_dev_stat(&self, dev_stat: u32) { + let mut inner = self.inner.lock(); + inner.regs.dev_stat = dev_stat; + } + + pub fn set_q_num_max(&self, q_num_max: u32) { + let mut inner = self.inner.lock(); + inner.regs.q_num_max = q_num_max; + } + + pub fn set_dev_feature(&self, dev_feature: u32) { + let mut inner = self.inner.lock(); + inner.regs.dev_feature = dev_feature; + } + + pub fn set_dev_feature_sel(&self, dev_feature_sel: u32) { + let mut inner = self.inner.lock(); + inner.regs.dev_feature_sel = dev_feature_sel; + } + + pub fn set_drv_feature(&self, drv_feature: u32) { + let mut inner = self.inner.lock(); + inner.regs.drv_feature = drv_feature; + } + + pub fn set_drv_feature_sel(&self, drv_feature_sel: u32) { + let mut inner = self.inner.lock(); + inner.regs.drv_feature = drv_feature_sel; + } + + pub fn or_driver_feature(&self, driver_features: usize) { + let mut inner = self.inner.lock(); + inner.driver_features |= driver_features; + } + + pub fn dev(&self) -> VirtDev { + let inner = self.inner.lock(); + inner.dev.clone() + } + + pub fn q_sel(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.q_sel + } + + pub fn magic(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.magic + } + + pub fn version(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.version + } + + pub fn device_id(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.device_id + } + + pub fn vendor_id(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.vendor_id + } + + pub fn dev_stat(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.dev_stat + } + + pub fn dev_feature_sel(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.dev_feature_sel + } + + pub fn drv_feature_sel(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.drv_feature_sel + } + + pub fn q_num_max(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.q_num_max + } + + pub fn irt_stat(&self) -> u32 { + let inner = self.inner.lock(); + inner.regs.irt_stat + } + + pub fn vq(&self, idx: usize) -> Result { + let inner = self.inner.lock(); + if idx >= inner.vq.len() { + return Err(()); + } + return Ok(inner.vq[idx].clone()); + } + + pub fn id(&self) -> usize { + let inner = self.inner.lock(); + inner.id + } + + pub fn notify_handler(&self, idx: usize) -> bool { + let inner = self.inner.lock(); + if idx >= inner.vq.len() { + return false; + } + let vq = inner.vq[idx].clone(); + drop(inner); + return vq.call_notify_handler(self.clone()); + } + + // use for migration restore + pub fn restore_mmio_data(&self, mmio_data: &VirtioMmioData, pa_region: &Vec) { + let mut inner = self.inner.lock(); + // inner.id = mmio_data.id; + inner.driver_features = mmio_data.driver_features; + inner.driver_status = mmio_data.driver_status; + inner.regs = mmio_data.regs; + inner.dev.restore_virt_dev_data(&mmio_data.dev); + for (idx, vq) in inner.vq.iter().enumerate() { + vq.restore_vq_data(&mmio_data.vq[idx], pa_region); + } + } + + // use for migration save + pub fn save_mmio_data(&self, mmio_data: &mut VirtioMmioData, pa_region: &Vec) { + let inner = self.inner.lock(); + mmio_data.id = inner.id; + mmio_data.driver_features = inner.driver_features; + mmio_data.driver_status = inner.driver_status; + mmio_data.regs = inner.regs; + inner.dev.save_virt_dev_data(&mut mmio_data.dev); + for (idx, vq) in inner.vq.iter().enumerate() { + vq.save_vq_data(&mut mmio_data.vq[idx], pa_region); + } + + // if let DevDescData::ConsoleDesc(desc_data) = &mmio_data.dev.desc { + // let oppo_vm_id = desc_data.oppo_end_vmid; + // let oppo_vm_ipa = desc_data.oppo_end_ipa; + // if oppo_vm_id != 0 { + // return; + // } + // let vm = vm(oppo_vm_id as usize).unwrap(); + // if let EmuDevs::VirtioConsole(console_mmio) = vm.emu_console_dev(oppo_vm_ipa as usize) { + // console_mmio.dev().save_virt_dev_data(&mut mmio_data.oppo_dev); + // } + // } + } + + // use for live update + pub fn save_mmio(&self, virtio_mmio: VirtioMmio, notify_handler: Option bool>) { + // println!("save mmio notify_handler addr {:x}", unsafe { *(&(notify_handler.unwrap()) as *const _ as *const usize) }); + let mut dst_dev = self.inner.lock(); + let src_dev = virtio_mmio.inner.lock(); + let is_net = src_dev.dev.is_net(); + dst_dev.id = src_dev.id; + dst_dev.driver_features = src_dev.driver_features; + dst_dev.driver_status = src_dev.driver_status; + dst_dev.regs.save_regs(&src_dev.regs); + dst_dev.dev.save_virt_dev(src_dev.dev.clone()); + for (idx, vq) in src_dev.vq.iter().enumerate() { + let new_vq = Virtq::default(); + if is_net && idx == src_dev.vq.len() - 1 && idx % 2 == 0 { + // control queue + new_vq.save_vq(vq.clone(), Some(virtio_net_handle_ctrl)); + } else { + new_vq.save_vq(vq.clone(), notify_handler); + } + dst_dev.vq.push(new_vq); + } + } +} + +struct VirtioMmioInner { + id: usize, + driver_features: usize, + driver_status: usize, + regs: VirtMmioRegs, + dev: VirtDev, + + vq: Vec, +} + +impl VirtioMmioInner { + fn new(id: usize) -> VirtioMmioInner { + VirtioMmioInner { + id, + driver_features: 0, + driver_status: 0, + regs: VirtMmioRegs::default(), + dev: VirtDev::default(), + vq: Vec::new(), + } + } + + fn reg_init(&mut self, dev_type: VirtioDeviceType) { + self.regs.init(dev_type); + } +} + +fn virtio_mmio_prologue_access(mmio: VirtioMmio, emu_ctx: &EmuContext, offset: usize, write: bool) { + if !write { + let value; + match offset { + VIRTIO_MMIO_MAGIC_VALUE => { + value = mmio.magic(); + } + VIRTIO_MMIO_VERSION => { + value = mmio.version(); + } + VIRTIO_MMIO_DEVICE_ID => { + value = mmio.device_id(); + } + VIRTIO_MMIO_VENDOR_ID => { + value = mmio.vendor_id(); + } + VIRTIO_MMIO_HOST_FEATURES => { + if mmio.dev_feature_sel() != 0 { + value = (mmio.dev().features() >> 32) as u32; + } else { + value = mmio.dev().features() as u32; + } + mmio.set_dev_feature(value); + } + VIRTIO_MMIO_STATUS => { + value = mmio.dev_stat(); + } + _ => { + println!("virtio_be_init_handler wrong reg_read, address=0x{:x}", emu_ctx.address); + return; + } + } + let idx = emu_ctx.reg; + let val = value as usize; + current_cpu().set_gpr(idx, val); + } else { + let idx = emu_ctx.reg; + let value = current_cpu().get_gpr(idx) as u32; + match offset { + VIRTIO_MMIO_HOST_FEATURES_SEL => { + mmio.set_dev_feature_sel(value); + } + VIRTIO_MMIO_GUEST_FEATURES => { + mmio.set_drv_feature(value); + if mmio.drv_feature_sel() != 0 { + mmio.or_driver_feature((value as usize) << 32); + } else { + mmio.or_driver_feature(value as usize); + } + } + VIRTIO_MMIO_GUEST_FEATURES_SEL => { + mmio.set_drv_feature_sel(value); + } + VIRTIO_MMIO_STATUS => { + mmio.set_dev_stat(value); + if mmio.dev_stat() == 0 { + mmio.dev_reset(); + info!("VM {} virtio device {} is reset", active_vm_id(), mmio.id()); + } else if mmio.dev_stat() == 0xf { + mmio.dev().set_activated(true); + info!("VM {} virtio device {} init ok", active_vm_id(), mmio.id()); + } + } + _ => { + println!("virtio_mmio_prologue_access: wrong reg write 0x{:x}", emu_ctx.address); + return; + } + } + } +} + +fn virtio_mmio_queue_access(mmio: VirtioMmio, emu_ctx: &EmuContext, offset: usize, write: bool) { + if !write { + let value; + match offset { + VIRTIO_MMIO_QUEUE_NUM_MAX => value = mmio.q_num_max(), + VIRTIO_MMIO_QUEUE_READY => { + let idx = mmio.q_sel() as usize; + match mmio.vq(idx) { + Ok(virtq) => { + value = virtq.ready() as u32; + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in read VIRTIO_MMIO_QUEUE_READY", + idx + ); + // return; + } + } + } + _ => { + println!( + "virtio_mmio_queue_access: wrong reg_read, address {:x}", + emu_ctx.address + ); + return; + } + } + let idx = emu_ctx.reg; + let val = value as usize; + current_cpu().set_gpr(idx, val); + } else { + let idx = emu_ctx.reg; + let value = current_cpu().get_gpr(idx); + let q_sel = mmio.q_sel() as usize; + match offset { + VIRTIO_MMIO_QUEUE_SEL => mmio.set_q_sel(value as u32), + VIRTIO_MMIO_QUEUE_NUM => { + match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.set_num(value); + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_NUM", + q_sel + ); + // return; + } + } + } + VIRTIO_MMIO_QUEUE_READY => match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.set_ready(value); + if value == VIRTQ_READY { + info!( + "VM {} virtio device {} queue {} ready", + active_vm_id(), + mmio.id(), + q_sel + ); + } else { + warn!( + "VM {} virtio device {} queue {} init failed", + active_vm_id(), + mmio.id(), + q_sel + ); + } + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_READY", + q_sel + ); + } + }, + VIRTIO_MMIO_QUEUE_DESC_LOW => match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.or_desc_table_addr(value & u32::MAX as usize); + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_DESC_LOW", + q_sel + ); + } + }, + VIRTIO_MMIO_QUEUE_DESC_HIGH => match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.or_desc_table_addr(value << 32); + let desc_table_addr = vm_ipa2pa(active_vm().unwrap(), virtq.desc_table_addr()); + if desc_table_addr == 0 { + println!("virtio_mmio_queue_access: invalid desc_table_addr"); + return; + } + virtq.set_desc_table(desc_table_addr); + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_DESC_HIGH", + q_sel + ); + } + }, + VIRTIO_MMIO_QUEUE_AVAIL_LOW => match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.or_avail_addr(value & u32::MAX as usize); + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_AVAIL_LOW", + q_sel + ); + } + }, + VIRTIO_MMIO_QUEUE_AVAIL_HIGH => match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.or_avail_addr(value << 32); + let avail_addr = vm_ipa2pa(active_vm().unwrap(), virtq.avail_addr()); + if avail_addr == 0 { + println!("virtio_mmio_queue_access: invalid avail_addr"); + return; + } + virtq.set_avail(avail_addr); + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_AVAIL_HIGH", + q_sel + ); + } + }, + VIRTIO_MMIO_QUEUE_USED_LOW => match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.or_used_addr(value & u32::MAX as usize); + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_USED_LOW", + q_sel + ); + } + }, + VIRTIO_MMIO_QUEUE_USED_HIGH => match mmio.vq(q_sel) { + Ok(virtq) => { + virtq.or_used_addr(value << 32); + let used_addr = vm_ipa2pa(active_vm().unwrap(), virtq.used_addr()); + if used_addr == 0 { + println!("virtio_mmio_queue_access: invalid used_addr"); + return; + } + virtq.set_used(used_addr); + } + Err(_) => { + panic!( + "virtio_mmio_queue_access: wrong q_sel {:x} in write VIRTIO_MMIO_QUEUE_USED_HIGH", + q_sel + ); + } + }, + _ => { + println!("virtio_mmio_queue_access: wrong reg write 0x{:x}", emu_ctx.address); + } + } + } +} + +fn virtio_mmio_cfg_access(mmio: VirtioMmio, emu_ctx: &EmuContext, offset: usize, write: bool) { + if !write { + let value; + match offset { + VIRTIO_MMIO_CONFIG_GENERATION => { + value = mmio.dev().generation() as u32; + } + VIRTIO_MMIO_CONFIG..=0x1ff => match mmio.dev().desc() { + super::DevDesc::BlkDesc(blk_desc) => { + value = blk_desc.offset_data(offset - VIRTIO_MMIO_CONFIG); + } + super::DevDesc::NetDesc(net_desc) => { + value = net_desc.offset_data(offset - VIRTIO_MMIO_CONFIG); + } + _ => { + panic!("unknow desc type"); + } + }, + _ => { + println!("virtio_mmio_cfg_access: wrong reg write 0x{:x}", emu_ctx.address); + return; + } + } + let idx = emu_ctx.reg; + let val = value as usize; + current_cpu().set_gpr(idx, val); + } else { + println!("virtio_mmio_cfg_access: wrong reg write 0x{:x}", emu_ctx.address); + } +} + +pub fn emu_virtio_mmio_init(vm: Vm, emu_dev_id: usize, mediated: bool) -> bool { + let virt_dev_type: VirtioDeviceType; + let vm_cfg = vm.config(); + let mmio = VirtioMmio::new(emu_dev_id); + match vm_cfg.emulated_device_list()[emu_dev_id].emu_type { + crate::device::EmuDeviceType::EmuDeviceTVirtioBlk => { + virt_dev_type = VirtioDeviceType::Block; + vm.set_emu_devs(emu_dev_id, EmuDevs::VirtioBlk(mmio.clone())); + } + crate::device::EmuDeviceType::EmuDeviceTVirtioNet => { + virt_dev_type = VirtioDeviceType::Net; + vm.set_emu_devs(emu_dev_id, EmuDevs::VirtioNet(mmio.clone())); + } + crate::device::EmuDeviceType::EmuDeviceTVirtioConsole => { + virt_dev_type = VirtioDeviceType::Console; + vm.set_emu_devs(emu_dev_id, EmuDevs::VirtioConsole(mmio.clone())); + } + _ => { + println!("emu_virtio_mmio_init: unknown emulated device type"); + return false; + } + } + + mmio.mmio_reg_init(virt_dev_type); + mmio.dev_init(virt_dev_type, &vm_cfg.emulated_device_list()[emu_dev_id], mediated); + // no need to set vm_if_list + mmio.virtio_queue_init(virt_dev_type); + + true +} + +pub fn emu_virtio_mmio_handler(emu_dev_id: usize, emu_ctx: &EmuContext) -> bool { + // println!("emu_virtio_mmio_handler active_vcpu addr {:x}", unsafe { *(¤t_cpu().active_vcpu as *const _ as *const usize) }); + let vm = match active_vm() { + Some(vm) => vm, + None => { + panic!("emu_virtio_mmio_handler: current vcpu.vm is none"); + } + }; + + let mmio = match vm.emu_dev(emu_dev_id) { + EmuDevs::VirtioBlk(blk) => blk, + EmuDevs::VirtioNet(net) => net, + EmuDevs::VirtioConsole(console) => console, + _ => { + panic!("emu_virtio_mmio_handler: illegal mmio dev type") + } + }; + + let addr = emu_ctx.address; + let offset = addr - vm.config().emulated_device_list()[emu_dev_id].base_ipa; + let write = emu_ctx.write; + + // if vm.vm_id() == 1 && emu_dev_id == 2 { + // println!("### emu_virtio_mmio_handler offset {:x} ###", offset); + // } + if offset == VIRTIO_MMIO_QUEUE_NOTIFY && write { + mmio.set_irt_stat(VIRTIO_MMIO_INT_VRING as u32); + // let q_sel = mmio.q_sel(); + // if q_sel as usize != current_cpu().get_gpr(emu_ctx.reg) { + // println!("{} {}", q_sel as usize, current_cpu().get_gpr(emu_ctx.reg)); + // } + // println!("in VIRTIO_MMIO_QUEUE_NOTIFY"); + + if !mmio.notify_handler(current_cpu().get_gpr(emu_ctx.reg)) { + println!("Failed to handle virtio mmio request!"); + } + } else if offset == VIRTIO_MMIO_INTERRUPT_STATUS && !write { + // println!("in VIRTIO_MMIO_INTERRUPT_STATUS"); + let idx = emu_ctx.reg; + let val = mmio.irt_stat() as usize; + current_cpu().set_gpr(idx, val); + } else if offset == VIRTIO_MMIO_INTERRUPT_ACK && write { + let idx = emu_ctx.reg; + let val = mmio.irt_stat(); + mmio.set_irt_stat(val & !(current_cpu().get_gpr(idx) as u32)); + mmio.set_irt_ack(current_cpu().get_gpr(idx) as u32); + } else if (VIRTIO_MMIO_MAGIC_VALUE <= offset && offset <= VIRTIO_MMIO_GUEST_FEATURES_SEL) + || offset == VIRTIO_MMIO_STATUS + { + // println!("in virtio_mmio_prologue_access"); + virtio_mmio_prologue_access(mmio.clone(), emu_ctx, offset, write); + } else if VIRTIO_MMIO_QUEUE_SEL <= offset && offset <= VIRTIO_MMIO_QUEUE_USED_HIGH { + // println!("in virtio_mmio_queue_access"); + virtio_mmio_queue_access(mmio.clone(), emu_ctx, offset, write); + } else if VIRTIO_MMIO_CONFIG_GENERATION <= offset && offset <= VIRTIO_MMIO_REGS_END { + // println!("in virtio_mmio_cfg_access"); + virtio_mmio_cfg_access(mmio.clone(), emu_ctx, offset, write); + } else { + println!( + "emu_virtio_mmio_handler: regs wrong {}, address 0x{:x}, offset 0x{:x}", + if write { "write" } else { "read" }, + addr, + offset + ); + return false; + } + return true; +} diff --git a/src/device/virtio/mod.rs b/src/device/virtio/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..3d1d6c1591d584da8d9ee42304a134591b94590b --- /dev/null +++ b/src/device/virtio/mod.rs @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::blk::*; +pub use self::dev::*; +pub use self::iov::*; +pub use self::mediated::*; +pub use self::mmio::*; +pub use self::net::*; +pub use self::console::*; +pub use self::queue::*; + +mod blk; +mod console; +mod dev; +mod iov; +mod mediated; +mod mmio; +mod net; +mod queue; diff --git a/src/device/virtio/net.rs b/src/device/virtio/net.rs new file mode 100644 index 0000000000000000000000000000000000000000..862406c92da5305e2bb42197733b83ad8518f9be --- /dev/null +++ b/src/device/virtio/net.rs @@ -0,0 +1,655 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::mem::size_of; +use spin::Mutex; + +use crate::arch::PAGE_SIZE; +use crate::config::{vm_num, vm_type}; +use crate::device::{DevDesc, VirtioMmio, Virtq, VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE}; +use crate::device::EmuDevs; +use crate::device::VirtioIov; +use crate::kernel::{ + active_vm, active_vm_id, current_cpu, NetDescData, vm_if_cmp_mac, vm_if_get_cpu_id, vm_if_set_mem_map_bit, + vm_ipa2pa, VM_LIST, VM_STATE_FLAG, +}; +use crate::kernel::{ipi_send_msg, IpiEthernetMsg, IpiInnerMsg, IpiType}; +use crate::kernel::IpiMessage; +use crate::kernel::vm; +use crate::kernel::Vm; +use crate::lib::{round_down, trace}; + +const VIRTIO_NET_OK: u8 = 0; +const VIRTIO_NET_ERR: u8 = 1; + +const VIRTIO_F_VERSION_1: usize = 1 << 32; +const VIRTIO_NET_F_CSUM: usize = 1 << 0; +const VIRTIO_NET_F_GUEST_CSUM: usize = 1 << 1; +const VIRTIO_NET_F_MAC: usize = 1 << 5; +const VIRTIO_NET_F_GSO_DEPREC: usize = 1 << 6; +// deprecated: host handles GSO +const VIRTIO_NET_F_GUEST_TSO4: usize = 1 << 7; +// guest can rcv TSOv4 * +const VIRTIO_NET_F_GUEST_TSO6: usize = 1 << 8; +// guest can rcv TSOv6 +const VIRTIO_NET_F_GUEST_ECN: usize = 1 << 9; +// guest can rcv TSO with ECN +const VIRTIO_NET_F_GUEST_UFO: usize = 1 << 10; +// guest can rcv UFO * +const VIRTIO_NET_F_HOST_TSO4: usize = 1 << 11; +// host can rcv TSOv4 * +const VIRTIO_NET_F_HOST_TSO6: usize = 1 << 12; +// host can rcv TSOv6 +const VIRTIO_NET_F_HOST_ECN: usize = 1 << 13; +// host can rcv TSO with ECN +const VIRTIO_NET_F_HOST_UFO: usize = 1 << 14; +// host can rcv UFO * +const VIRTIO_NET_F_MRG_RXBUF: usize = 1 << 15; +// host can merge RX buffers * +const VIRTIO_NET_F_STATUS: usize = 1 << 16; +// config status field available * +const VIRTIO_NET_F_CTRL_VQ: usize = 1 << 17; +// control channel available +const VIRTIO_NET_F_CTRL_RX: usize = 1 << 18; +// control channel RX mode support +const VIRTIO_NET_F_CTRL_VLAN: usize = 1 << 19; +// control channel VLAN filtering +const VIRTIO_NET_F_GUEST_ANNOUNCE: usize = 1 << 21; // guest can send gratuitous pkts + +const VIRTIO_NET_HDR_F_DATA_VALID: usize = 2; + +const VIRTIO_NET_HDR_GSO_NONE: usize = 0; + +#[repr(C)] +struct VirtioNetHdr { + pub flags: u8, + pub gso_type: u8, + pub hdr_len: u16, + pub gso_size: u16, + pub csum_start: u16, + pub csum_offset: u16, + pub num_buffers: u16, +} + +#[derive(Clone)] +pub struct NetDesc { + inner: Arc>, +} + +impl NetDesc { + pub fn default() -> NetDesc { + NetDesc { + inner: Arc::new(Mutex::new(NetDescInner::default())), + } + } + + // use for live update + pub fn back_up(&self) -> NetDesc { + let current_inner = self.inner.lock(); + let inner = NetDescInner { + mac: current_inner.mac, + status: current_inner.status, + }; + NetDesc { + inner: Arc::new(Mutex::new(inner)), + } + } + + pub fn set_status(&self, status: u16) { + let mut inner = self.inner.lock(); + inner.status = status; + } + + pub fn status(&self) -> u16 { + let inner = self.inner.lock(); + inner.status + } + + pub fn cfg_init(&self, mac: &Vec) { + let mut inner = self.inner.lock(); + inner.mac[0] = mac[0] as u8; + inner.mac[1] = mac[1] as u8; + inner.mac[2] = mac[2] as u8; + inner.mac[3] = mac[3] as u8; + inner.mac[4] = mac[4] as u8; + inner.mac[5] = mac[5] as u8; + } + + pub fn offset_data(&self, offset: usize) -> u32 { + let inner = self.inner.lock(); + let start_addr = &inner.mac[0] as *const _ as usize; + if trace() && start_addr + offset < 0x1000 { + println!("value addr is {}", start_addr + offset); + } + let value = unsafe { *((start_addr + offset) as *const u32) }; + return value; + } + + // use for migration + pub fn restore_net_data(&self, desc_data: &NetDescData) { + let mut inner = self.inner.lock(); + inner.mac = desc_data.mac; + inner.status = desc_data.status; + } + + // use for migration + pub fn save_net_data(&self, desc_data: &mut NetDescData) { + let inner = self.inner.lock(); + desc_data.mac = inner.mac; + desc_data.status = inner.status; + } +} + +pub const VIRTIO_NET_S_LINK_UP: u16 = 1; +pub const VIRTIO_NET_S_ANNOUNCE: u16 = 2; + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct NetDescInner { + mac: [u8; 6], + status: u16, +} + +impl NetDescInner { + pub fn default() -> NetDescInner { + NetDescInner { + mac: [0; 6], + status: VIRTIO_NET_S_LINK_UP, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy, Default)] +struct VirtioNetCtrlHdr { + class: u8, + command: u8, +} + +pub fn net_features() -> usize { + VIRTIO_F_VERSION_1 + | VIRTIO_NET_F_GUEST_CSUM + | VIRTIO_NET_F_MAC + | VIRTIO_NET_F_CSUM + | VIRTIO_NET_F_GUEST_TSO4 + | VIRTIO_NET_F_GUEST_TSO6 + | VIRTIO_NET_F_GUEST_UFO + | VIRTIO_NET_F_HOST_TSO4 + | VIRTIO_NET_F_HOST_TSO6 + | VIRTIO_NET_F_HOST_UFO + | VIRTIO_NET_F_HOST_ECN + | VIRTIO_NET_F_CTRL_VQ + | VIRTIO_NET_F_GUEST_ANNOUNCE + | VIRTIO_NET_F_STATUS +} + +const VIRTIO_NET_CTRL_ANNOUNCE: u8 = 3; +const VIRTIO_NET_CTRL_ANNOUNCE_ACK: u8 = 0; + +pub fn virtio_net_handle_ctrl(vq: Virtq, nic: VirtioMmio, vm: Vm) -> bool { + if vq.ready() == 0 { + println!("virtio net control queue is not ready!"); + return false; + } + + let out_iov = VirtioIov::default(); + let in_iov = VirtioIov::default(); + let mut next_desc_idx_opt = vq.pop_avail_desc_idx(vq.avail_idx()); + while next_desc_idx_opt.is_some() { + let mut idx = next_desc_idx_opt.unwrap() as usize; + let mut len = 0; + out_iov.clear(); + in_iov.clear(); + + loop { + let addr = vm_ipa2pa(active_vm().unwrap(), vq.desc_addr(idx)); + if addr == 0 { + println!("virtio_net_handle_ctrl: failed to desc addr"); + return false; + } + if vq.desc_flags(idx) & VIRTQ_DESC_F_WRITE != 0 { + in_iov.push_data(addr, vq.desc_len(idx) as usize); + } else { + out_iov.push_data(addr, vq.desc_len(idx) as usize); + } + len += vq.desc_len(idx) as usize; + if vq.desc_flags(idx) != VIRTQ_DESC_F_NEXT { + break; + } + idx = vq.desc_next(idx) as usize; + } + let ctrl = VirtioNetCtrlHdr::default(); + out_iov.to_buf(&ctrl as *const _ as usize, size_of::()); + match ctrl.class { + VIRTIO_NET_CTRL_ANNOUNCE => { + let status: u8 = if ctrl.command == VIRTIO_NET_CTRL_ANNOUNCE_ACK { + match nic.dev().desc() { + DevDesc::NetDesc(desc) => { + desc.set_status(VIRTIO_NET_S_LINK_UP); + VIRTIO_NET_OK + } + _ => { + panic!("illegal dev type for nic"); + } + } + } else { + VIRTIO_NET_ERR + }; + in_iov.from_buf(&status as *const _ as usize, size_of::()); + } + _ => { + println!("Control queue header class can't match {}", ctrl.class); + } + } + + // update ctrl queue used ring + if vm.id() != 0 { + let used_addr = vm_ipa2pa(vm.clone(), vq.used_addr()); + if *VM_STATE_FLAG.lock() == 1 { + println!("vm1 virtio net ctrl write memory in 0x{:x}", used_addr); + } + vm_if_set_mem_map_bit(vm.clone(), used_addr); + + for idx in 0..in_iov.num() { + vm_if_set_mem_map_bit(vm.clone(), in_iov.get_buf(idx)); + } + } + if !vq.update_used_ring(len as u32, next_desc_idx_opt.unwrap() as u32) { + return false; + } + next_desc_idx_opt = vq.pop_avail_desc_idx(vq.avail_idx()); + } + nic.notify(vm.clone()); + true +} + +pub fn virtio_net_notify_handler(vq: Virtq, nic: VirtioMmio, vm: Vm) -> bool { + if vq.ready() == 0 { + println!("net virt_queue is not ready!"); + return false; + } + + if vq.vq_indx() != 1 { + // println!("net rx queue notified!"); + return true; + } + + let tx_iov = VirtioIov::default(); + let mut vms_to_notify = 0; + + let mut next_desc_idx_opt = vq.pop_avail_desc_idx(vq.avail_idx()); + + while next_desc_idx_opt.is_some() { + let mut idx = next_desc_idx_opt.unwrap() as usize; + let mut len = 0; + tx_iov.clear(); + + loop { + let addr = vm_ipa2pa(active_vm().unwrap(), vq.desc_addr(idx)); + if addr == 0 { + println!("virtio_net_notify_handler: failed to desc addr"); + return false; + } + tx_iov.push_data(addr, vq.desc_len(idx) as usize); + + len += vq.desc_len(idx) as usize; + if vq.desc_flags(idx) == 0 { + break; + } + idx = vq.desc_next(idx) as usize; + } + + let trgt_vmid_map = ethernet_transmit(tx_iov.clone(), len).1; + if trgt_vmid_map != 0 { + vms_to_notify |= trgt_vmid_map; + } + + if vm.id() != 0 { + let used_addr = vm_ipa2pa(vm.clone(), vq.used_addr()); + if *VM_STATE_FLAG.lock() == 1 { + println!("vm1 virtio net write memory in 0x{:x}", used_addr); + } + vm_if_set_mem_map_bit(vm.clone(), used_addr); + vm_if_set_mem_map_bit(vm.clone(), used_addr + PAGE_SIZE); + } + if !vq.update_used_ring( + (len - size_of::()) as u32, + next_desc_idx_opt.unwrap() as u32, + ) { + return false; + } + + next_desc_idx_opt = vq.pop_avail_desc_idx(vq.avail_idx()); + } + + if !vq.avail_is_avail() { + println!("invalid descriptor table index"); + return false; + } + + nic.notify(vm.clone()); + // vq.notify(dev.int_id(), vm.clone()); + let mut trgt_vmid = 0; + while vms_to_notify > 0 { + if vms_to_notify & 1 != 0 { + let vm = match crate::kernel::vm(trgt_vmid) { + None => { + println!( + "virtio_net_notify_handler: target vm [{}] is not ready or not exist", + trgt_vmid + ); + return true; + } + Some(_vm) => _vm, + }; + let vcpu = vm.vcpu(0).unwrap(); + if vcpu.phys_id() == current_cpu().id { + let nic = match vm.emu_net_dev(0) { + EmuDevs::VirtioNet(x) => x, + _ => { + println!("virtio_net_notify_handler: failed to get virtio net dev"); + return false; + } + }; + let rx_vq = match nic.vq(0) { + Ok(x) => x, + Err(_) => { + println!( + "virtio_net_notify_handler: vm[{}] failed to get virtio net rx virt queue", + vm.id() + ); + return false; + } + }; + if rx_vq.ready() != 0 && rx_vq.avail_flags() == 0 { + nic.notify(vm.clone()); + // rx_vq.notify(nic.dev().int_id(), vm.clone()); + } + } else { + let msg = IpiEthernetMsg { + src_vmid: active_vm_id(), + trgt_vmid, + }; + let cpu_trgt = vm_if_get_cpu_id(trgt_vmid); + if !ipi_send_msg(cpu_trgt, IpiType::IpiTEthernetMsg, IpiInnerMsg::EnternetMsg(msg)) { + println!( + "virtio_net_notify_handler: failed to send ipi message, target {}", + cpu_trgt + ); + } + } + } + + trgt_vmid += 1; + vms_to_notify = vms_to_notify >> 1; + } + true +} + +pub fn ethernet_ipi_rev_handler(msg: &IpiMessage) { + match msg.ipi_message { + IpiInnerMsg::EnternetMsg(ethernet_msg) => { + let trgt_vmid = ethernet_msg.trgt_vmid; + let vm = match vm(trgt_vmid) { + None => { + println!( + "ethernet_ipi_rev_handler: target vm [{}] is not ready or not exist", + trgt_vmid + ); + return; + } + Some(_vm) => _vm, + }; + let nic = match vm.emu_net_dev(0) { + EmuDevs::VirtioNet(x) => x, + _ => { + // println!( + // "ethernet_ipi_rev_handler: vm[{}] failed to get virtio net dev", + // vm.id() + // ); + return; + } + }; + let rx_vq = match nic.vq(0) { + Ok(x) => x, + Err(_) => { + println!( + "ethernet_ipi_rev_handler: vm[{}] failed to get virtio net rx virt queue", + vm.id() + ); + return; + } + }; + + if rx_vq.ready() != 0 && rx_vq.avail_flags() == 0 { + nic.notify(vm); + // rx_vq.notify(nic.dev().int_id(), vm); + } + } + _ => { + panic!("illegal ipi message type in ethernet_ipi_rev_handler"); + } + } +} + +fn ethernet_transmit(tx_iov: VirtioIov, len: usize) -> (bool, usize) { + // [ destination MAC - 6 ][ source MAC - 6 ][ EtherType - 2 ][ Payload ] + if len < size_of::() || len - size_of::() < 6 + 6 + 2 { + println!( + "Too short for an ethernet frame, len {}, size of head {}", + len, + size_of::() + ); + return (false, 0); + } + + let frame: &[u8] = tx_iov.get_ptr(size_of::()); + // need to check mac + // vm_if_list_cmp_mac(active_vm_id(), frame + 6); + + if frame[0] == 0xff + && frame[1] == 0xff + && frame[2] == 0xff + && frame[3] == 0xff + && frame[4] == 0xff + && frame[5] == 0xff + { + if !ethernet_is_arp(frame) { + return (false, 0); + } + return ethernet_broadcast(tx_iov.clone(), len); + } + + if frame[0] == 0x33 && frame[1] == 0x33 { + if !(frame[12] == 0x86 && frame[13] == 0xdd) { + // Only IPV6 multicast packet is allowed to be broadcast + return (false, 0); + } + return ethernet_broadcast(tx_iov.clone(), len); + } + + match ethernet_mac_to_vm_id(frame) { + Ok(vm_id) => { + return (ethernet_send_to(vm_id, tx_iov.clone(), len), 1 << vm_id); + } + Err(_) => { + return (false, 0); + } + } +} + +fn ethernet_broadcast(tx_iov: VirtioIov, len: usize) -> (bool, usize) { + let vm_num = vm_num(); + let cur_vm_id = active_vm_id(); + let mut trgt_vmid_map = 0; + for vm_id in 0..vm_num { + if vm_id == cur_vm_id { + continue; + } + if vm_type(vm_id) as usize != 0 { + continue; + } + if !ethernet_send_to(vm_id, tx_iov.clone(), len) { + continue; + } + trgt_vmid_map |= 1 << vm_id; + } + (trgt_vmid_map != 0, trgt_vmid_map) +} + +fn ethernet_send_to(vmid: usize, tx_iov: VirtioIov, len: usize) -> bool { + // println!("ethernet send to vm{}", vmid); + let vm = match vm(vmid) { + None => { + // println!("ethernet_send_to: target vm [{}] is not ready or not exist", vmid); + return true; + } + Some(vm) => vm, + }; + let nic = match vm.emu_net_dev(0) { + EmuDevs::VirtioNet(x) => x, + _ => { + // println!("ethernet_send_to: vm[{}] failed to get virtio net dev", vmid); + return true; + } + }; + + if !nic.dev().activated() { + // println!("ethernet_send_to: vm[{}] nic dev is not activate", vmid); + return false; + } + + let rx_vq = match nic.vq(0) { + Ok(x) => x, + Err(_) => { + println!( + "ethernet_send_to: vm[{}] failed to get virtio net rx virt queue", + vm.id() + ); + return false; + } + }; + + let desc_header_idx_opt = rx_vq.pop_avail_desc_idx(rx_vq.avail_idx()); + if !rx_vq.avail_is_avail() { + println!("ethernet_send_to: receive invalid avail desc idx"); + return false; + } else if desc_header_idx_opt.is_none() { + // println!("ethernet_send_to: desc_header_idx_opt is none"); + return false; + } + + let desc_idx_header = desc_header_idx_opt.unwrap(); + let mut desc_idx = desc_header_idx_opt.unwrap() as usize; + let rx_iov = VirtioIov::default(); + let mut rx_len = 0; + + loop { + let dst = vm_ipa2pa(vm.clone(), rx_vq.desc_addr(desc_idx)); + if dst == 0 { + println!( + "rx_vq desc base table addr 0x{:x}, idx {}, avail table addr 0x{:x}, avail last idx {}", + rx_vq.desc_table_addr(), + desc_idx, + rx_vq.avail_addr(), + rx_vq.avail_idx() + ); + println!("ethernet_send_to: failed to get dst {}", vmid); + return false; + } + let desc_len = rx_vq.desc_len(desc_idx) as usize; + + if vmid != 0 { + let mut addr = round_down(dst, PAGE_SIZE); + if *VM_STATE_FLAG.lock() == 1 { + println!("A: vm0 virtio net write vm1 memory in 0x{:x}", addr); + } + while addr <= round_down(dst + desc_len, PAGE_SIZE) { + vm_if_set_mem_map_bit(vm.clone(), addr); + addr += PAGE_SIZE; + } + } + rx_iov.push_data(dst, desc_len); + rx_len += desc_len; + if rx_len >= len { + break; + } + if rx_vq.desc_flags(desc_idx) & 0x1 == 0 { + break; + } + desc_idx = rx_vq.desc_next(desc_idx) as usize; + } + + if rx_len < len { + rx_vq.put_back_avail_desc_idx(); + println!("ethernet_send_to: rx_len smaller than tx_len"); + return false; + } + if trace() && tx_iov.get_buf(0) < 0x1000 { + panic!("illegal header addr {}", tx_iov.get_buf(0)); + } + let header = unsafe { &mut *(tx_iov.get_buf(0) as *mut VirtioNetHdr) }; + header.num_buffers = 1; + + if tx_iov.write_through_iov(rx_iov.clone(), len) > 0 { + println!( + "ethernet_send_to: write through iov failed, rx_iov_num {} tx_iov_num {} rx_len {} tx_len {}", + rx_iov.num(), + tx_iov.num(), + rx_len, + len + ); + return false; + } + + if vmid != 0 { + let used_addr = vm_ipa2pa(vm.clone(), rx_vq.used_addr()); + if *VM_STATE_FLAG.lock() == 1 { + println!("B: vm0 virtio net write vm1 memory in 0x{:x}", used_addr); + } + vm_if_set_mem_map_bit(vm.clone(), used_addr); + vm_if_set_mem_map_bit(vm.clone(), used_addr + PAGE_SIZE); + } + if !rx_vq.update_used_ring(len as u32, desc_idx_header as u32) { + return false; + } + + return true; +} + +fn ethernet_is_arp(frame: &[u8]) -> bool { + return frame[12] == 0x8 && frame[13] == 0x6; +} + +fn ethernet_mac_to_vm_id(frame: &[u8]) -> Result { + for vm in VM_LIST.lock().iter() { + let vm_id = vm.id(); + if vm_if_cmp_mac(vm_id, frame) { + return Ok(vm_id); + } + } + return Err(()); +} + +pub fn virtio_net_announce(vm: Vm) { + match vm.emu_net_dev(0) { + EmuDevs::VirtioNet(nic) => match nic.dev().desc() { + DevDesc::NetDesc(desc) => { + let status = desc.status(); + desc.set_status(status | VIRTIO_NET_S_ANNOUNCE); + nic.notify_config(vm); + } + _ => {} + }, + _ => {} + } +} diff --git a/src/device/virtio/queue.rs b/src/device/virtio/queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..7741f2180c73ed9a8b654ca67c28e0d4b42fb5d4 --- /dev/null +++ b/src/device/virtio/queue.rs @@ -0,0 +1,548 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::slice; + +use spin::Mutex; + +use crate::device::VirtioDeviceType; +use crate::device::VirtioMmio; +use crate::kernel::{active_vm, ipa2pa, VirtqData, Vm, vm_ipa2pa, VmPa}; +use crate::lib::trace; + +pub const VIRTQ_READY: usize = 1; +pub const VIRTQ_DESC_F_NEXT: u16 = 1; +pub const VIRTQ_DESC_F_WRITE: u16 = 2; + +pub const VRING_USED_F_NO_NOTIFY: usize = 1; + +pub const DESC_QUEUE_SIZE: usize = 512; + +#[repr(C, align(16))] +#[derive(Copy, Clone)] +struct VringDesc { + /*Address (guest-physical)*/ + pub addr: usize, + /* Length */ + len: u32, + /* The flags as indicated above */ + flags: u16, + /* We chain unused descriptors via this, too */ + next: u16, +} + +#[repr(C)] +#[derive(Copy, Clone)] +struct VringAvail { + flags: u16, + idx: u16, + ring: [u16; 512], +} + +#[repr(C)] +#[derive(Copy, Clone)] +struct VringUsedElem { + pub id: u32, + pub len: u32, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct VringUsed { + flags: u16, + idx: u16, + ring: [VringUsedElem; 512], +} + +pub trait VirtioQueue { + fn virtio_queue_init(&self, dev_type: VirtioDeviceType); + fn virtio_queue_reset(&self, index: usize); +} + +#[derive(Clone)] +pub struct Virtq { + inner: Arc>>, +} + +impl Virtq { + pub fn default() -> Virtq { + Virtq { + inner: Arc::new(Mutex::new(VirtqInner::default())), + } + } + + pub fn reset(&self, index: usize) { + let mut inner = self.inner.lock(); + inner.reset(index); + } + + pub fn pop_avail_desc_idx(&self, avail_idx: u16) -> Option { + let mut inner = self.inner.lock(); + match &inner.avail { + Some(avail) => { + if avail_idx == inner.last_avail_idx { + return None; + } + let idx = inner.last_avail_idx as usize % inner.num; + let avail_desc_idx = avail.ring[idx]; + inner.last_avail_idx = inner.last_avail_idx.wrapping_add(1); + return Some(avail_desc_idx); + } + None => { + println!("pop_avail_desc_idx: failed to avail table"); + return None; + } + } + } + + pub fn put_back_avail_desc_idx(&self) { + let mut inner = self.inner.lock(); + match &inner.avail { + Some(_) => { + inner.last_avail_idx -= 1; + } + None => { + println!("put_back_avail_desc_idx: failed to avail table"); + } + } + } + + pub fn avail_is_avail(&self) -> bool { + let inner = self.inner.lock(); + inner.avail.is_some() + } + + pub fn disable_notify(&self) { + let mut inner = self.inner.lock(); + if inner.used_flags & VRING_USED_F_NO_NOTIFY as u16 != 0 { + return; + } + inner.used_flags |= VRING_USED_F_NO_NOTIFY as u16; + } + + pub fn enable_notify(&self) { + let mut inner = self.inner.lock(); + if inner.used_flags & VRING_USED_F_NO_NOTIFY as u16 == 0 { + return; + } + inner.used_flags &= !VRING_USED_F_NO_NOTIFY as u16; + } + + pub fn check_avail_idx(&self, avail_idx: u16) -> bool { + let inner = self.inner.lock(); + return inner.last_avail_idx == avail_idx; + } + + pub fn desc_is_writable(&self, idx: usize) -> bool { + let inner = self.inner.lock(); + let desc_table = inner.desc_table.as_ref().unwrap(); + desc_table[idx].flags & VIRTQ_DESC_F_WRITE as u16 != 0 + } + + pub fn desc_has_next(&self, idx: usize) -> bool { + let inner = self.inner.lock(); + let desc_table = inner.desc_table.as_ref().unwrap(); + desc_table[idx].flags & VIRTQ_DESC_F_NEXT != 0 + } + + pub fn update_used_ring(&self, len: u32, desc_chain_head_idx: u32) -> bool { + let mut inner = self.inner.lock(); + let num = inner.num; + let flag = inner.used_flags; + match &mut inner.used { + Some(used) => { + used.flags = flag; + used.ring[used.idx as usize % num].id = desc_chain_head_idx; + used.ring[used.idx as usize % num].len = len; + used.idx = used.idx.wrapping_add(1); + return true; + } + None => { + println!("update_used_ring: failed to used table"); + return false; + } + } + } + + pub fn set_notify_handler(&self, handler: fn(Virtq, VirtioMmio, Vm) -> bool) { + let mut inner = self.inner.lock(); + inner.notify_handler = Some(handler); + } + + pub fn call_notify_handler(&self, mmio: VirtioMmio) -> bool { + let inner = self.inner.lock(); + match inner.notify_handler { + Some(handler) => { + drop(inner); + // println!("call_notify_handler"); + // println!("handler addr {:x}", unsafe { *(&handler as *const _ as *const usize) }); + return handler(self.clone(), mmio, active_vm().unwrap()); + } + None => { + println!("call_notify_handler: virtq notify handler is None"); + return false; + } + } + } + + pub fn show_desc_info(&self, size: usize, vm: Vm) { + let inner = self.inner.lock(); + let desc = inner.desc_table.as_ref().unwrap(); + println!("[*desc_ring*]"); + for i in 0..size { + let desc_addr = vm_ipa2pa(vm.clone(), desc[i].addr); + println!( + "index {} desc_addr_ipa 0x{:x} desc_addr_pa 0x{:x} len 0x{:x} flags {} next {}", + i, desc[i].addr, desc_addr, desc[i].len, desc[i].flags, desc[i].next + ); + } + } + + pub fn show_avail_info(&self, size: usize) { + let inner = self.inner.lock(); + let avail = inner.avail.as_ref().unwrap(); + println!("[*avail_ring*]"); + for i in 0..size { + println!("index {} ring_idx {}", i, avail.ring[i]); + } + } + + pub fn show_used_info(&self, size: usize) { + let inner = self.inner.lock(); + let used = inner.used.as_ref().unwrap(); + println!("[*used_ring*]"); + for i in 0..size { + println!( + "index {} ring_id {} ring_len {:x}", + i, used.ring[i].id, used.ring[i].len + ); + } + } + + pub fn show_addr_info(&self) { + let inner = self.inner.lock(); + println!( + "avail_addr {:x}, desc_addr {:x}, used_addr {:x}", + inner.avail_addr, inner.desc_table_addr, inner.used_addr + ); + } + + pub fn set_last_used_idx(&self, last_used_idx: u16) { + let mut inner = self.inner.lock(); + inner.last_used_idx = last_used_idx; + } + + pub fn set_num(&self, num: usize) { + let mut inner = self.inner.lock(); + inner.num = num; + } + + pub fn set_ready(&self, ready: usize) { + let mut inner = self.inner.lock(); + inner.ready = ready; + } + + pub fn or_desc_table_addr(&self, addr: usize) { + let mut inner = self.inner.lock(); + inner.desc_table_addr |= addr; + } + + pub fn or_avail_addr(&self, addr: usize) { + let mut inner = self.inner.lock(); + inner.avail_addr |= addr; + } + + pub fn or_used_addr(&self, addr: usize) { + let mut inner = self.inner.lock(); + inner.used_addr |= addr; + } + + pub fn set_desc_table(&self, addr: usize) { + let mut inner = self.inner.lock(); + if trace() && addr < 0x1000 { + panic!("illegal desc ring addr {:x}", addr); + } + inner.desc_table = Some(unsafe { slice::from_raw_parts_mut(addr as *mut VringDesc, 16 * DESC_QUEUE_SIZE) }); + } + + pub fn set_avail(&self, addr: usize) { + if trace() && addr < 0x1000 { + panic!("illegal avail ring addr {:x}", addr); + } + let mut inner = self.inner.lock(); + inner.avail = Some(unsafe { &mut *(addr as *mut VringAvail) }); + } + + pub fn set_used(&self, addr: usize) { + if trace() && addr < 0x1000 { + panic!("illegal used ring addr {:x}", addr); + } + let mut inner = self.inner.lock(); + inner.used = Some(unsafe { &mut *(addr as *mut VringUsed) }); + } + + pub fn last_used_idx(&self) -> u16 { + let inner = self.inner.lock(); + inner.last_used_idx + } + + pub fn desc_table_addr(&self) -> usize { + let inner = self.inner.lock(); + inner.desc_table_addr + } + + pub fn avail_addr(&self) -> usize { + let inner = self.inner.lock(); + inner.avail_addr + } + + pub fn used_addr(&self) -> usize { + let inner = self.inner.lock(); + inner.used_addr + } + + pub fn desc_table(&self) -> usize { + let inner = self.inner.lock(); + match &inner.desc_table { + None => 0, + Some(desc_table) => &(desc_table[0]) as *const _ as usize, + } + } + + pub fn avail(&self) -> usize { + let inner = self.inner.lock(); + match &inner.avail { + None => 0, + Some(avail) => (*avail) as *const _ as usize, + } + } + + pub fn used(&self) -> usize { + let inner = self.inner.lock(); + match &inner.used { + None => 0, + Some(used) => (*used) as *const _ as usize, + } + } + + pub fn ready(&self) -> usize { + let inner = self.inner.lock(); + inner.ready + } + + pub fn vq_indx(&self) -> usize { + let inner = self.inner.lock(); + inner.vq_index + } + + pub fn num(&self) -> usize { + let inner = self.inner.lock(); + inner.num + } + + pub fn desc_addr(&self, idx: usize) -> usize { + let inner = self.inner.lock(); + let desc_table = inner.desc_table.as_ref().unwrap(); + desc_table[idx].addr + } + + pub fn desc_flags(&self, idx: usize) -> u16 { + let inner = self.inner.lock(); + let desc_table = inner.desc_table.as_ref().unwrap(); + desc_table[idx].flags + } + + pub fn desc_next(&self, idx: usize) -> u16 { + let inner = self.inner.lock(); + let desc_table = inner.desc_table.as_ref().unwrap(); + desc_table[idx].next + } + + pub fn desc_len(&self, idx: usize) -> u32 { + let inner = self.inner.lock(); + let desc_table = inner.desc_table.as_ref().unwrap(); + desc_table[idx].len + } + + pub fn avail_flags(&self) -> u16 { + let inner = self.inner.lock(); + let avail = inner.avail.as_ref().unwrap(); + avail.flags + } + + pub fn avail_idx(&self) -> u16 { + let inner = self.inner.lock(); + let avail = inner.avail.as_ref().unwrap(); + avail.idx + } + + pub fn last_avail_idx(&self) -> u16 { + let inner = self.inner.lock(); + inner.last_avail_idx + } + + pub fn used_idx(&self) -> u16 { + let inner = self.inner.lock(); + let used = inner.used.as_ref().unwrap(); + used.idx + } + + // use for migration + pub fn restore_vq_data(&self, data: &VirtqData, pa_region: &Vec) { + let mut inner = self.inner.lock(); + inner.ready = data.ready; + inner.vq_index = data.vq_index; + inner.num = data.num; + inner.last_avail_idx = data.last_avail_idx; + inner.last_used_idx = data.last_used_idx; + inner.used_flags = data.used_flags; + inner.desc_table_addr = data.desc_table_ipa; + inner.avail_addr = data.avail_ipa; + inner.used_addr = data.used_ipa; + let desc_table_addr = ipa2pa(pa_region, data.desc_table_ipa); + let avail_addr = ipa2pa(pa_region, data.avail_ipa); + let used_addr = ipa2pa(pa_region, data.used_ipa); + // println!("restore_vq_data: ready {}, vq idx {}, last_avail_idx {}, last_used_idx {}, desc_table_ipa {:x}, avail_ipa {:x}, used_ipa {:x}, desc_table_pa {:x}, avail_pa {:x}, used_pa {:x}", + // data.ready, data.vq_index, data.last_avail_idx, data.last_used_idx, data.desc_table_ipa, data.avail_ipa, data.used_ipa, desc_table_addr, avail_addr, used_addr); + if desc_table_addr != 0 { + inner.desc_table = + Some(unsafe { slice::from_raw_parts_mut(desc_table_addr as *mut VringDesc, 16 * DESC_QUEUE_SIZE) }); + } + if avail_addr != 0 { + inner.avail = Some(unsafe { &mut *(avail_addr as *mut VringAvail) }); + // println!("restore_vq_data: avail idx {}", inner.avail.as_ref().unwrap().idx); + } + if used_addr != 0 { + inner.used = Some(unsafe { &mut *(used_addr as *mut VringUsed) }); + // println!("restore_vq_data: used idx {}", inner.used.as_ref().unwrap().idx); + } + } + + // use for migration + pub fn save_vq_data(&self, data: &mut VirtqData, _pa_region: &Vec) { + let inner = self.inner.lock(); + data.ready = inner.ready; + data.vq_index = inner.vq_index; + data.num = inner.num; + data.last_avail_idx = inner.last_avail_idx; + data.last_used_idx = inner.last_used_idx; + data.used_flags = inner.used_flags; + data.desc_table_ipa = inner.desc_table_addr; + data.avail_ipa = inner.avail_addr; + data.used_ipa = inner.used_addr; + + // println!("save_vq_data: ready {}, vq idx {}, last_avail_idx {}, last_used_idx {}, desc_table_ipa {:x}, avail_ipa {:x}, used_ipa {:x}", + // data.ready, data.vq_index, data.last_avail_idx, data.last_used_idx, data.desc_table_ipa, data.avail_ipa, data.used_ipa); + // if inner.avail.is_some() { + // println!("save_vq_data: avail idx {}", inner.avail.as_ref().unwrap().idx); + // } + // if inner.used.is_some() { + // println!("save_vq_data: used idx {}", inner.used.as_ref().unwrap().idx); + // } + } + + // use for live update + pub fn save_vq(&self, vq: Virtq, notify_handler: Option bool>) { + let mut dst_inner = self.inner.lock(); + let src_inner = vq.inner.lock(); + dst_inner.ready = src_inner.ready; + dst_inner.vq_index = src_inner.vq_index; + dst_inner.num = src_inner.num; + + dst_inner.desc_table = match &src_inner.desc_table { + None => None, + Some(desc_table) => { + let desc_addr = &desc_table[0] as *const _ as usize; + Some(unsafe { slice::from_raw_parts_mut(desc_addr as *mut VringDesc, 16 * DESC_QUEUE_SIZE) }) + } + }; + dst_inner.avail = match &src_inner.avail { + None => None, + Some(avail) => { + let avail_addr = *avail as *const _ as usize; + Some(unsafe { &mut *(avail_addr as *mut VringAvail) }) + } + }; + dst_inner.used = match &src_inner.used { + None => None, + Some(used) => { + let used_addr = *used as *const _ as usize; + Some(unsafe { &mut *(used_addr as *mut VringUsed) }) + } + }; + + dst_inner.last_avail_idx = src_inner.last_avail_idx; + dst_inner.last_used_idx = src_inner.last_used_idx; + dst_inner.used_flags = src_inner.used_flags; + dst_inner.desc_table_addr = src_inner.desc_table_addr; + dst_inner.avail_addr = src_inner.avail_addr; + dst_inner.used_addr = src_inner.used_addr; + dst_inner.notify_handler = notify_handler; + } +} + +pub struct VirtqInner<'a> { + ready: usize, + vq_index: usize, + num: usize, + desc_table: Option<&'a mut [VringDesc]>, + avail: Option<&'a mut VringAvail>, + used: Option<&'a mut VringUsed>, + last_avail_idx: u16, + last_used_idx: u16, + used_flags: u16, + + desc_table_addr: usize, + avail_addr: usize, + used_addr: usize, + + notify_handler: Option bool>, +} + +impl VirtqInner<'_> { + pub fn default() -> Self { + VirtqInner { + ready: 0, + vq_index: 0, + num: 0, + desc_table: None, + avail: None, + used: None, + last_avail_idx: 0, + last_used_idx: 0, + used_flags: 0, + + desc_table_addr: 0, + avail_addr: 0, + used_addr: 0, + + notify_handler: None, + } + } + + // virtio_queue_reset + pub fn reset(&mut self, index: usize) { + self.ready = 0; + self.vq_index = index; + self.num = 0; + self.last_avail_idx = 0; + self.last_used_idx = 0; + self.used_flags = 0; + self.desc_table_addr = 0; + self.avail_addr = 0; + self.used_addr = 0; + + self.desc_table = None; + self.avail = None; + self.used = None; + } +} diff --git a/src/driver/aarch64/mod.rs b/src/driver/aarch64/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..4cff2612b1e4c15915a5663d43a62297f31e86d2 --- /dev/null +++ b/src/driver/aarch64/mod.rs @@ -0,0 +1,13 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::uart::*; + +mod uart; diff --git a/src/driver/aarch64/uart.rs b/src/driver/aarch64/uart.rs new file mode 100644 index 0000000000000000000000000000000000000000..787d05f17ac5110f7c6767364092a29fedf9fc9f --- /dev/null +++ b/src/driver/aarch64/uart.rs @@ -0,0 +1,40 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::ptr; + +pub fn putc(byte: u8) { + use crate::board::UART_1_ADDR; + #[cfg(feature = "qemu")] + unsafe { + ptr::write_volatile(UART_1_ADDR as *mut u8, byte); + } + // ns16550 + #[cfg(feature = "tx2")] + unsafe { + if byte == '\n' as u8 { + putc('\r' as u8); + } + while ptr::read_volatile((UART_1_ADDR + 0x8_0000_0000 + 20) as *const u8) & 0x20 == 0 {} + ptr::write_volatile((UART_1_ADDR + 0x8_0000_0000) as *mut u8, byte); + // while ptr::read_volatile((UART_1_ADDR + 20) as *const u8) & 0x20 == 0 {} + // ptr::write_volatile(UART_1_ADDR as *mut u8, byte); + } + // pl011 + #[cfg(feature = "pi4")] + unsafe { + use crate::board::UART_0_ADDR; + if byte == '\n' as u8 { + putc('\r' as u8); + } + while (ptr::read_volatile((UART_0_ADDR as usize + 24) as *const u32) & (1 << 5)) != 0 {} + ptr::write_volatile(UART_0_ADDR as *mut u32, byte as u32); + } +} diff --git a/src/driver/gpio/gpio.rs b/src/driver/gpio/gpio.rs new file mode 100644 index 0000000000000000000000000000000000000000..662a6dd5eb134ebb2d66bab9eaa28faa6cced5b8 --- /dev/null +++ b/src/driver/gpio/gpio.rs @@ -0,0 +1,43 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +const MMIO_BASE: usize = 0xFE000000; +const GPFSEL0: usize = MMIO_BASE + 0x200000; + +fn alt2bits(alt: u8) -> u8 { + match alt { + 0 => 0b100, + 1 => 0b101, + 2 => 0b110, + 3 => 0b111, + 4 => 0b011, + 5 => 0b010, + _ => 0, + } +} + +#[no_mangle] +#[inline(never)] +pub fn gpio_select_function(gpio: u8, alt: u8) { + let mut gpfsel; + let field_offset; + match gpio { + 0..=9 => { + gpfsel = unsafe { *(GPFSEL0 as *const u32) }; + field_offset = (gpio as u32) % 10 * 3; + gpfsel &= !(1 << field_offset); + gpfsel &= !(1 << (field_offset + 1)); + gpfsel &= !(1 << (field_offset + 2)); + gpfsel |= (alt2bits(alt) as u32) << field_offset; + unsafe { (GPFSEL0 as *mut u32).write_volatile(gpfsel) }; + } + _ => {} + } +} diff --git a/src/driver/gpio/mod.rs b/src/driver/gpio/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e958428d546f801c6fc174514a042ff53eb11dac --- /dev/null +++ b/src/driver/gpio/mod.rs @@ -0,0 +1,13 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::gpio::*; + +mod gpio; diff --git a/src/driver/mod.rs b/src/driver/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e4c59a0d5a5d1505a328ae17c3237d78a278bc52 --- /dev/null +++ b/src/driver/mod.rs @@ -0,0 +1,19 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::aarch64::*; +pub use self::gpio::*; +#[cfg(feature = "qemu")] +pub use self::virtio::*; + +mod aarch64; +mod gpio; +#[cfg(feature = "qemu")] +mod virtio; diff --git a/src/driver/virtio/blk.rs b/src/driver/virtio/blk.rs new file mode 100644 index 0000000000000000000000000000000000000000..1ec4ad970c5a8a8ec3c9290d3e7c7fd70a58000b --- /dev/null +++ b/src/driver/virtio/blk.rs @@ -0,0 +1,24 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +// Feature bits +pub const VIRTIO_BLK_F_SIZE_MAX: usize = 1; +pub const VIRTIO_BLK_F_SEG_MAX: usize = 2; +pub const VIRTIO_BLK_F_GEOMETRY: usize = 4; +pub const VIRTIO_BLK_F_RO: usize = 5; +pub const VIRTIO_BLK_F_BLK_SIZE: usize = 6; +pub const VIRTIO_BLK_F_TOPOLOGY: usize = 10; +pub const VIRTIO_BLK_F_MQ: usize = 12; + +// Legacy feature bits +pub const VIRTIO_BLK_F_BARRIER: usize = 0; +pub const VIRTIO_BLK_F_SCSI: usize = 7; +pub const VIRTIO_BLK_F_FLUSH: usize = 9; +pub const VIRTIO_BLK_F_CONFIG_WCE: usize = 11; diff --git a/src/driver/virtio/mmio.rs b/src/driver/virtio/mmio.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab894fcea0ecd3a74c6fb9fa0b574af7fa0c0e69 --- /dev/null +++ b/src/driver/virtio/mmio.rs @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub const VIRTIO_MMIO_MAGIC_VALUE: usize = 0x000; +pub const VIRTIO_MMIO_VERSION: usize = 0x004; +pub const VIRTIO_MMIO_DEVICE_ID: usize = 0x008; +pub const VIRTIO_MMIO_VENDOR_ID: usize = 0x00c; +pub const VIRTIO_MMIO_DEVICE_FEATURES: usize = 0x010; + +pub const VIRTIO_MMIO_DRIVER_FEATURES: usize = 0x020; + +pub const VIRTIO_MMIO_GUEST_PAGE_SIZE: usize = 0x028; + +pub const VIRTIO_MMIO_QUEUE_SEL: usize = 0x030; +pub const VIRTIO_MMIO_QUEUE_NUM_MAX: usize = 0x034; +pub const VIRTIO_MMIO_QUEUE_NUM: usize = 0x038; + +pub const VIRTIO_MMIO_QUEUE_PIN: usize = 0x040; + +pub const VIRTIO_MMIO_STATUS: usize = 0x070; diff --git a/src/driver/virtio/mod.rs b/src/driver/virtio/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..d3ce3f34a9145eed10d5db1cfcabbd5fb97f0c19 --- /dev/null +++ b/src/driver/virtio/mod.rs @@ -0,0 +1,21 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::blk::*; +pub use self::mmio::*; +pub use self::ring::*; +pub use self::virtio::*; +pub use self::virtio_blk::*; + +mod blk; +mod mmio; +mod ring; +mod virtio; +mod virtio_blk; diff --git a/src/driver/virtio/ring.rs b/src/driver/virtio/ring.rs new file mode 100644 index 0000000000000000000000000000000000000000..b1030064a57aa7d3481e129ccf1662abe53042a5 --- /dev/null +++ b/src/driver/virtio/ring.rs @@ -0,0 +1,12 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub const VIRTIO_RING_F_INDIRECT_DESC: usize = 28; +pub const VIRTIO_RING_F_EVENT_IDX: usize = 29; diff --git a/src/driver/virtio/virtio.rs b/src/driver/virtio/virtio.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5601b5945a193f5ed5efd35b6dff319f55b1fef --- /dev/null +++ b/src/driver/virtio/virtio.rs @@ -0,0 +1,18 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub const VIRTIO_CONFIG_S_ACKNOWLEDGE: usize = 1; +pub const VIRTIO_CONFIG_S_DRIVER: usize = 2; +pub const VIRTIO_CONFIG_S_DRIVER_OK: usize = 4; +pub const VIRTIO_CONFIG_S_FEATURES_OK: usize = 8; +pub const VIRTIO_CONFIG_S_NEEDS_RESET: usize = 0x40; +pub const VIRTIO_CONFIG_S_FAILED: usize = 0x80; + +pub const VIRTIO_F_ANY_LAYOUT: usize = 27; diff --git a/src/driver/virtio/virtio_blk.rs b/src/driver/virtio/virtio_blk.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad906a62e26212d0c7ecf8838148baac2e774bb6 --- /dev/null +++ b/src/driver/virtio/virtio_blk.rs @@ -0,0 +1,330 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::boxed::Box; +use core::arch::asm; +use core::mem::size_of; + +// use register::mmio::*; +// use register::*; +use spin::Mutex; +use tock_registers::*; +use tock_registers::interfaces::*; +use tock_registers::registers::*; + +use Operation::*; + +use crate::lib::trace; + +// use crate::device::*; +use super::virtio::*; + +const VIRTIO_MMIO_BASE: usize = 0x0a000000; +const QUEUE_SIZE: usize = 8; +const VIRTIO_F_VERSION_1: u32 = 32; + +#[repr(C)] +#[repr(align(4096))] +#[derive(Debug)] +struct VirtioRing { + desc: [VirtioRingDesc; QUEUE_SIZE], + driver: VirtioRingDriver, + device: VirtioRingDevice, +} + +static VIRTIO_RING: Mutex = Mutex::new(VirtioRing { + desc: [VirtioRingDesc { + addr: 0, + len: 0, + flags: 0, + next: 0, + }; QUEUE_SIZE], + driver: VirtioRingDriver { + flags: 0, + idx: 0, + ring: [0; QUEUE_SIZE], + }, + device: VirtioRingDevice { + flags: 0, + idx: 0, + ring: [VirtioRingDeviceElement { id: 0, len: 0 }; QUEUE_SIZE], + }, +}); + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +struct VirtioRingDesc { + addr: u64, + len: u32, + flags: u16, + next: u16, +} + +#[repr(C)] +#[derive(Debug)] +struct VirtioRingDriver { + flags: u16, + idx: u16, + ring: [u16; QUEUE_SIZE], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +struct VirtioRingDeviceElement { + id: u32, + len: u32, +} + +#[repr(C)] +#[repr(align(4096))] +#[derive(Debug)] +struct VirtioRingDevice { + flags: u16, + idx: u16, + ring: [VirtioRingDeviceElement; QUEUE_SIZE], +} + +register_structs! { + #[allow(non_snake_case)] + VirtioMmioBlock { + (0x000 => MagicValue: ReadOnly), + (0x004 => Version: ReadOnly), + (0x008 => DeviceID: ReadOnly), + (0x00c => VendorID: ReadOnly), + (0x010 => DeviceFeatures: ReadOnly), + (0x014 => DeviceFeaturesSel: WriteOnly), + (0x018 => _reserved_0), + (0x020 => DriverFeatures: WriteOnly), + (0x024 => DriverFeaturesSel: WriteOnly), + (0x028 => _reserved_1), + (0x030 => QueueSel: WriteOnly), + (0x034 => QueueNumMax: ReadOnly), + (0x038 => QueueNum: WriteOnly), + (0x03c => _reserved_2), + (0x044 => QueueReady: ReadWrite), + (0x048 => _reserved_3), + (0x050 => QueueNotify: WriteOnly), + (0x054 => _reserved_4), + (0x060 => InterruptStatus: ReadOnly), + (0x064 => InterruptACK: WriteOnly), + (0x068 => _reserved_5), + (0x070 => Status: ReadWrite), + (0x074 => _reserved_6), + (0x080 => QueueDescLow: WriteOnly), + (0x084 => QueueDescHigh: WriteOnly), + (0x088 => _reserved_7), + (0x090 => QueueDriverLow: WriteOnly), + (0x094 => QueueDriverHigh: WriteOnly), + (0x098 => _reserved_8), + (0x0a0 => QueueDeviceLow: WriteOnly), + (0x0a4 => QueueDeviceHigh: WriteOnly), + (0x0a8 => _reserved_9), + (0x0fc => ConfigGeneration: ReadOnly), + (0x0fd => _reserved_10), + (0x100 => _reserved_config), + (0x200 => @END), + } +} + +struct VirtioMmio { + base_addr: usize, +} + +impl core::ops::Deref for VirtioMmio { + type Target = VirtioMmioBlock; + fn deref(&self) -> &Self::Target { + if trace() && self.base_addr < 0x1000 { + panic!("illegal addr {:x}", self.base_addr); + } + unsafe { &*self.ptr() } + } +} + +impl VirtioMmio { + const fn new(base_addr: usize) -> Self { + VirtioMmio { base_addr } + } + fn ptr(&self) -> *const VirtioMmioBlock { + self.base_addr as *const _ + } +} + +trait BaseAddr { + fn base_addr_u64(&self) -> u64; + fn base_addr_usize(&self) -> usize; +} + +impl BaseAddr for T { + fn base_addr_u64(&self) -> u64 { + self as *const T as u64 + } + fn base_addr_usize(&self) -> usize { + self as *const T as usize + } +} + +static VIRTIO_MMIO: VirtioMmio = VirtioMmio::new(VIRTIO_MMIO_BASE); + +fn virtio_mmio_setup_vq(index: usize) { + let mmio = &VIRTIO_MMIO; + mmio.QueueSel.set(index as u32); + + let num = mmio.QueueNumMax.get(); + if num == 0 { + panic!("queue num max is zero"); + } else if num < QUEUE_SIZE as u32 { + panic!("queue size not supported"); + } + mmio.QueueNum.set(QUEUE_SIZE as u32); + + let ring = VIRTIO_RING.lock(); + + mmio.QueueDescLow.set(ring.desc.base_addr_usize() as u32); + mmio.QueueDescHigh.set((ring.desc.base_addr_usize() >> 32) as u32); + mmio.QueueDriverLow.set(ring.driver.base_addr_usize() as u32); + mmio.QueueDriverHigh.set((ring.driver.base_addr_usize() >> 32) as u32); + mmio.QueueDeviceLow.set(ring.device.base_addr_usize() as u32); + mmio.QueueDeviceHigh.set((ring.device.base_addr_usize() >> 32) as u32); + + mmio.QueueReady.set(1); +} + +pub fn virtio_blk_init() { + let mmio = &VIRTIO_MMIO; + if mmio.MagicValue.get() != 0x74726976 + || mmio.Version.get() != 2 + || mmio.DeviceID.get() != 2 + || mmio.VendorID.get() != 0x554d4551 + { + // println!("mmio.MagicValue {:x}", mmio.MagicValue.get()); + // println!("mmio.Version {:x}", mmio.Version.get()); + // println!("mmio.DeviceID {:x}", mmio.DeviceID.get()); + // println!("mmio.VendorID {:x}", mmio.VendorID.get()); + panic!("could not find virtio blk") + } + + let mut status = VIRTIO_CONFIG_S_ACKNOWLEDGE as u32; + mmio.Status.set(status); + status |= VIRTIO_CONFIG_S_DRIVER as u32; + mmio.Status.set(status); + + let feature: u64 = 1 << VIRTIO_F_VERSION_1; + + mmio.DriverFeaturesSel.set(0); + mmio.DriverFeatures.set(feature as u32); + mmio.DriverFeaturesSel.set(1); + mmio.DriverFeatures.set((feature >> 32) as u32); + + status |= VIRTIO_CONFIG_S_FEATURES_OK as u32; + mmio.Status.set(status); + + status |= VIRTIO_CONFIG_S_DRIVER_OK as u32; + mmio.Status.set(status); + + virtio_mmio_setup_vq(0); +} + +pub enum Operation { + Read, + Write, +} + +#[repr(C)] +pub struct VirtioBlkOutHdr { + t: u32, + priority: u32, + sector: u64, +} + +const VRING_DESC_F_NEXT: u16 = 1; +const VRING_DESC_F_WRITE: u16 = 2; +const VRING_DESC_F_INDIRECT: u16 = 4; + +pub fn read(sector: usize, count: usize, buf: usize) { + io(sector, count, buf, Read); +} + +pub fn write(sector: usize, count: usize, buf: usize) /* -> Box*/ +{ + io(sector, count, buf, Write); +} + +fn io(sector: usize, count: usize, buf: usize, op: Operation) { + let hdr = Box::new(VirtioBlkOutHdr { + t: match op { + Operation::Read => 0, + Operation::Write => 1, + }, + priority: 0, + sector: sector as u64, + // status: 255, + }); + + let status = Box::new(255u8); + let mut ring = VIRTIO_RING.lock(); + + let desc = ring.desc.get_mut(0).unwrap(); + desc.addr = hdr.as_ref() as *const VirtioBlkOutHdr as u64; + desc.len = size_of::() as u32; + desc.flags = VRING_DESC_F_NEXT; + desc.next = 1; + + let desc = ring.desc.get_mut(1).unwrap(); + desc.addr = buf as u64; + desc.len = (512 * count) as u32; + desc.flags = match op { + Operation::Read => VRING_DESC_F_WRITE, + Operation::Write => 0, + }; + desc.flags |= VRING_DESC_F_NEXT; + desc.next = 2; + + let desc = ring.desc.get_mut(2).unwrap(); + desc.addr = status.as_ref() as *const u8 as u64; + desc.len = 1; + desc.flags = VRING_DESC_F_WRITE; + desc.next = 0; + + // avail[0] is flags + // avail[1] tells the device how far to look in avail[2...]. + // avail[2...] are desc[] indices the device should process. + // we only tell device the first index in our chain of descriptors. + let avail = &mut ring.driver; + avail.ring[(avail.idx as usize) % QUEUE_SIZE] = 0; + // barrier + unsafe { + asm!("dsb sy"); + } + avail.idx = avail.idx.wrapping_add(1); + + let mmio = &VIRTIO_MMIO; + + mmio.QueueNotify.set(0); // queue num + + loop { + // barrier + unsafe { + asm!("dsb sy"); + } + if *status == 0 { + return; + } else if *status == 1 { + panic!("VIRTIO_BLK_S_IOERR"); + } else if *status == 2 { + panic!("VIRTIO_BLK_S_UNSUPP"); + } else if *status == 255 { + continue; + } + // if mmio.InterruptStatus.get() == 1 { + // mmio.InterruptACK.set(1); + // break; + // } + } +} diff --git a/src/kernel/async_task.rs b/src/kernel/async_task.rs new file mode 100644 index 0000000000000000000000000000000000000000..02c47ac269b899c02f57fb2d7410c02fc2bdb314 --- /dev/null +++ b/src/kernel/async_task.rs @@ -0,0 +1,531 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +// use alloc::boxed::Box; +use alloc::collections::{BTreeMap, LinkedList}; +use alloc::sync::Arc; +use alloc::vec::Vec; +use spin::mutex::Mutex; + +use crate::device::{ + BlkIov, mediated_blk_read, mediated_blk_write, virtio_blk_notify_handler, VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT, + VirtioMmio, Virtq, +}; +use crate::kernel::{active_vm_id, ipi_send_msg, IpiInnerMsg, IpiMediatedMsg, IpiType, vm}; +use crate::lib::{memcpy_safe, sleep, trace}; + +// use core::future::Future; +// use core::pin::Pin; +// use core::task::Context; + +// use woke::{waker_ref, Woke}; + +pub static TASK_IPI_COUNT: Mutex = Mutex::new(0); +pub static TASK_COUNT: Mutex = Mutex::new(0); + +pub fn add_task_ipi_count() { + let mut count = TASK_IPI_COUNT.lock(); + *count += 1; +} + +pub fn add_task_count() { + let mut count = TASK_COUNT.lock(); + if *count % 100 == 0 { + println!("task count {}, ipi count {}", *count, get_task_ipi_count()); + } + *count += 1; +} + +pub fn get_task_ipi_count() -> usize { + let count = TASK_IPI_COUNT.lock(); + *count +} + +pub fn get_task_count() -> usize { + let count = TASK_COUNT.lock(); + *count +} + +#[derive(Clone, Copy, Debug)] +pub enum AsyncTaskState { + Pending, + Running, + Finish, +} + +pub struct UsedInfo { + pub desc_chain_head_idx: u32, + pub used_len: u32, +} + +#[derive(Clone)] +pub struct IoAsyncMsg { + pub src_vmid: usize, + pub vq: Virtq, + pub dev: VirtioMmio, + pub io_type: usize, + pub blk_id: usize, + pub sector: usize, + pub count: usize, + pub cache: usize, + pub iov_list: Arc>, +} + +#[derive(Clone)] +pub struct IoIdAsyncMsg { + pub vq: Virtq, + pub dev: VirtioMmio, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum AsyncExeStatus { + Pending, + Scheduling, +} + +pub static ASYNC_EXE_STATUS: Mutex = Mutex::new(AsyncExeStatus::Pending); +pub static ASYNC_IPI_TASK_LIST: Mutex> = Mutex::new(LinkedList::new()); +pub static ASYNC_IO_TASK_LIST: Mutex> = Mutex::new(FairQueue::new()); +pub static ASYNC_USED_INFO_LIST: Mutex>> = Mutex::new(BTreeMap::new()); + +pub trait TaskOwner { + fn owner(&self) -> usize; +} + +// pub struct FairQueue { +// map: BTreeMap>>>, +// // reverse_map: BTreeMap>>, usize>, +// queue: LinkedList>>>, +// } + +pub struct FairQueue { + len: usize, + map: BTreeMap>, + queue: LinkedList, +} + +impl FairQueue { + pub const fn new() -> Self { + Self { + len: 0, + map: BTreeMap::new(), + queue: LinkedList::new(), + } + } + + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + pub fn len(&self) -> usize { + self.len + } + + pub fn push_back(&mut self, task: T) { + let key = task.owner(); + match self.map.get_mut(&key) { + Some(sub_queue) => sub_queue.push_back(task), + None => { + let mut sub_queue = LinkedList::new(); + sub_queue.push_back(task); + self.map.insert(key, sub_queue); + self.queue.push_back(key); + } + } + self.len += 1; + } + + pub fn pop_front(&mut self) -> Option { + match self.queue.pop_front() { + Some(owner) => match self.map.get_mut(&owner) { + Some(sub_queue) => { + let res = sub_queue.pop_front(); + if !sub_queue.is_empty() { + self.queue.push_back(owner); + } else { + self.map.remove(&owner); + } + self.len -= 1; + res + } + None => panic!(""), + }, + None => panic!("front: queue empty"), + } + } + + pub fn front(&self) -> Option<&T> { + match self.queue.front() { + Some(owner) => match self.map.get(owner) { + Some(sub_queue) => sub_queue.front(), + None => panic!(""), + }, + None => panic!("front: queue empty"), + } + } + + pub fn remove(&mut self, owner: usize) { + match self.map.remove(&owner) { + Some(sub_queue) => { + self.len -= sub_queue.len(); + self.queue = self.queue.drain_filter(|x| *x == owner).collect(); + } + None => {} + } + } +} + +impl Iterator for FairQueue { + type Item = T; + fn next(&mut self) -> Option<::Item> { + todo!() + } +} + +#[derive(Clone)] +pub enum AsyncTaskData { + AsyncIpiTask(IpiMediatedMsg), + AsyncIoTask(IoAsyncMsg), + AsyncNoneTask(IoIdAsyncMsg), +} + +fn async_exe_status() -> AsyncExeStatus { + *ASYNC_EXE_STATUS.lock() +} + +fn set_async_exe_status(status: AsyncExeStatus) { + *ASYNC_EXE_STATUS.lock() = status; +} + +#[derive(Clone)] +pub struct AsyncTask { + pub task_data: AsyncTaskData, + pub src_vmid: usize, + pub state: Arc>, + // pub task: Arc + 'static + Send + Sync>>>>, + pub task: fn(), +} + +impl TaskOwner for AsyncTask { + fn owner(&self) -> usize { + self.src_vmid + } +} + +// impl Woke for AsyncTask { +// fn wake(self: Arc) { +// todo!() +// } + +// fn wake_by_ref(_arc_self: &Arc) { +// todo!() +// } +// } + +impl AsyncTask { + pub fn new(task_data: AsyncTaskData, src_vmid: usize, future: fn()) -> AsyncTask { + AsyncTask { + task_data, + src_vmid, + state: Arc::new(Mutex::new(AsyncTaskState::Pending)), + task: future, + } + } + + pub fn handle(&mut self) -> bool { + let mut state = self.state.lock(); + match *state { + AsyncTaskState::Pending => { + *state = AsyncTaskState::Running; + } + AsyncTaskState::Running => { + return false; + } + AsyncTaskState::Finish => { + return true; + } + } + drop(state); + // let wake: Arc = unsafe { Arc::from_raw(self as *mut _) }; + // let waker = waker_ref(&wake); + // let mut context = Context::from_waker(&*waker); + // self.task.lock().as_mut().poll(&mut context); + (self.task)(); + return false; + } + + pub fn set_state(&self, state: AsyncTaskState) { + let mut cur_state = self.state.lock(); + *cur_state = state; + } +} + +// async req function +pub fn async_ipi_req() { + let ipi_list = ASYNC_IPI_TASK_LIST.lock(); + if ipi_list.is_empty() { + panic!("ipi_list should not be empty"); + } + let task = ipi_list.front().unwrap().clone(); + drop(ipi_list); + match task.task_data { + AsyncTaskData::AsyncIpiTask(msg) => { + if active_vm_id() == 0 { + virtio_blk_notify_handler(msg.vq.clone(), msg.blk.clone(), vm(msg.src_id).unwrap()); + } else { + // add_task_ipi_count(); + // send IPI to target cpu, and the target will invoke `mediated_ipi_handler` + ipi_send_msg(0, IpiType::IpiTMediatedDev, IpiInnerMsg::MediatedMsg(msg.clone())); + } + } + _ => {} + } +} + +pub fn async_blk_id_req() {} + +// inject an interrupt to service VM +pub fn async_blk_io_req() { + let io_list = ASYNC_IO_TASK_LIST.lock(); + if io_list.is_empty() { + panic!("io_list should not be empty"); + } + let task = io_list.front().unwrap().clone(); + drop(io_list); + match task.task_data { + AsyncTaskData::AsyncIoTask(msg) => match msg.io_type { + VIRTIO_BLK_T_IN => { + mediated_blk_read(msg.blk_id, msg.sector, msg.count); + } + VIRTIO_BLK_T_OUT => { + let mut cache_ptr = msg.cache; + for idx in 0..msg.iov_list.len() { + let data_bg = msg.iov_list[idx].data_bg; + let len = msg.iov_list[idx].len as usize; + + if cache_ptr < 0x1000 || data_bg < 0x1000 { + panic!("illegal des addr {:x}, src addr {:x}", cache_ptr, data_bg); + } + memcpy_safe(cache_ptr as *mut u8, data_bg as *mut u8, len); + cache_ptr += len; + } + mediated_blk_write(msg.blk_id, msg.sector, msg.count); + } + _ => { + panic!("illegal mediated blk req type {}", msg.io_type); + } + }, + _ => {} + } +} +// end async req function + +pub fn set_front_io_task_state(state: AsyncTaskState) { + let io_list = ASYNC_IO_TASK_LIST.lock(); + match io_list.front() { + None => { + panic!("front io task is none"); + } + Some(task) => { + task.set_state(state); + } + } +} + +pub fn add_async_task(task: AsyncTask, ipi: bool) { + // println!("add {} task", if ipi { "ipi" } else { "blk io" }); + let mut ipi_list = ASYNC_IPI_TASK_LIST.lock(); + let mut io_list = ASYNC_IO_TASK_LIST.lock(); + + if ipi { + ipi_list.push_back(task); + } else { + io_list.push_back(task); + } + let need_execute = ipi_list.len() == 1 + && io_list.is_empty() + && active_vm_id() != 0 + && async_exe_status() == AsyncExeStatus::Pending; + // println!("add_async_task: ipi len {} io len {}", ipi_list.len(), io_list.len()); + drop(ipi_list); + drop(io_list); + loop { + if active_vm_id() == 0 || ASYNC_IPI_TASK_LIST.lock().len() < 1024 { + break; + } else { + sleep(100); + } + } + + // if this is a normal VM and this is the first IO request + // (which generate a ipi async task in `virtio_mediated_blk_notify_handler`) + // invoke the executor to handle it + if need_execute { + async_task_exe(); + } +} + +// async task executor +pub fn async_task_exe() { + if active_vm_id() == 0 { + match async_exe_status() { + AsyncExeStatus::Pending => { + set_async_exe_status(AsyncExeStatus::Scheduling); + } + AsyncExeStatus::Scheduling => { + return; + } + } + } + loop { + let ipi_list = ASYNC_IPI_TASK_LIST.lock(); + let io_list = ASYNC_IO_TASK_LIST.lock(); + + // if !ipi_list.is_empty() { + // let state = ipi_list[0].state.lock(); + // if let AsyncTaskState::Finish = *state { + // drop(state); + // ipi_list.remove(0); + // } + // } + + let mut task; + let ipi; + if io_list.is_empty() { + if !ipi_list.is_empty() { + // other VM start an IO which need to be handled by service VM + task = ipi_list.front().unwrap().clone(); + ipi = true; + } else { + set_async_exe_status(AsyncExeStatus::Pending); + return; + } + } else { + // if io_list is not empty, prioritize IO requests + ipi = false; + task = io_list.front().unwrap().clone(); + } + drop(ipi_list); + drop(io_list); + if task.handle() || (ipi && active_vm_id() == 0) { + // task finish + finish_async_task(ipi); + } else { + // wait for notify + set_async_exe_status(AsyncExeStatus::Pending); + return; + } + // not a service VM, end loop + if active_vm_id() != 0 { + return; + } + } +} + +pub fn finish_async_task(ipi: bool) { + let mut ipi_list = ASYNC_IPI_TASK_LIST.lock(); + let mut io_list = ASYNC_IO_TASK_LIST.lock(); + let task = match if ipi { ipi_list.pop_front() } else { io_list.pop_front() } { + None => { + panic!("there is no {} task", if ipi { "ipi" } else { "io" }) + } + Some(t) => t, + }; + // println!("finish_async_task: ipi len {} io len {}", ipi_list.len(), io_list.len()); + drop(io_list); + drop(ipi_list); + match task.task_data { + AsyncTaskData::AsyncIoTask(args) => { + match args.io_type { + VIRTIO_BLK_T_IN => { + // let mut sum = 0; + let mut cache_ptr = args.cache; + for idx in 0..args.iov_list.len() { + let data_bg = args.iov_list[idx].data_bg; + let len = args.iov_list[idx].len as usize; + if trace() && (data_bg < 0x1000 || cache_ptr < 0x1000) { + panic!("illegal des addr {:x}, src addr {:x}", data_bg, cache_ptr); + } + memcpy_safe(data_bg as *mut u8, cache_ptr as *mut u8, len); + // sum |= check_sum(data_bg, len); + cache_ptr += len; + } + // println!("read check_sum is {:x}", sum); + } + _ => {} + } + + update_used_info(args.vq.clone(), task.src_vmid); + let src_vm = vm(task.src_vmid).unwrap(); + args.dev.notify(src_vm.clone()); + } + AsyncTaskData::AsyncIpiTask(_) => {} + AsyncTaskData::AsyncNoneTask(args) => { + update_used_info(args.vq.clone(), task.src_vmid); + let src_vm = vm(task.src_vmid).unwrap(); + args.dev.notify(src_vm.clone()); + } + } +} + +pub fn push_used_info(desc_chain_head_idx: u32, used_len: u32, src_vmid: usize) { + let mut used_info_list = ASYNC_USED_INFO_LIST.lock(); + match used_info_list.get_mut(&src_vmid) { + Some(info_list) => { + info_list.push_back(UsedInfo { + desc_chain_head_idx, + used_len, + }); + } + None => { + println!("async_push_used_info: src_vmid {} not existed", src_vmid); + } + } +} + +fn update_used_info(vq: Virtq, src_vmid: usize) { + let mut used_info_list = ASYNC_USED_INFO_LIST.lock(); + match used_info_list.get_mut(&src_vmid) { + Some(info_list) => { + // for info in info_list.iter() { + // vq.update_used_ring(info.used_len, info.desc_chain_head_idx, vq_size); + let info = info_list.pop_front().unwrap(); + vq.update_used_ring(info.used_len, info.desc_chain_head_idx); + // } + // info_list.clear(); + } + None => { + println!("async_push_used_info: src_vmid {} not existed", src_vmid); + } + } +} + +pub fn add_async_used_info(vm_id: usize) { + let mut used_info_list = ASYNC_USED_INFO_LIST.lock(); + used_info_list.insert(vm_id, LinkedList::new()); +} + +pub fn remove_async_used_info(vm_id: usize) { + let mut used_info_list = ASYNC_USED_INFO_LIST.lock(); + used_info_list.remove(&vm_id); + // println!("VM[{}] remove async used info", vm_id); +} + +pub fn remove_vm_async_task(vm_id: usize) { + let mut io_list = ASYNC_IO_TASK_LIST.lock(); + let mut ipi_list = ASYNC_IPI_TASK_LIST.lock(); + // io_list.retain(|x| x.src_vmid != vm_id); + // ipi_list.retain(|x| x.src_vmid != vm_id); + // *io_list = io_list.drain_filter(|x| x.src_vmid == vm_id).collect::>(); + io_list.remove(vm_id); + *ipi_list = ipi_list + .drain_filter(|x| x.src_vmid == vm_id) + .collect::>(); +} diff --git a/src/kernel/cpu.rs b/src/kernel/cpu.rs new file mode 100644 index 0000000000000000000000000000000000000000..f4a6ac4bc4f4b638f362c6f62da0d1c869efed44 --- /dev/null +++ b/src/kernel/cpu.rs @@ -0,0 +1,356 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::arch::{PAGE_SIZE, pt_map_banked_cpu, PTE_PER_PAGE}; +use crate::arch::ContextFrame; +use crate::arch::ContextFrameTrait; +// use core::ops::{Deref, DerefMut}; +use crate::arch::cpu_interrupt_unmask; +use crate::board::PLATFORM_CPU_NUM_MAX; +use crate::kernel::{SchedType, Vcpu, VcpuArray, VcpuState, Vm, Scheduler}; +use crate::kernel::IpiMessage; +use crate::lib::trace; + +pub const CPU_MASTER: usize = 0; +pub const CPU_STACK_SIZE: usize = PAGE_SIZE * 128; +pub const CONTEXT_GPR_NUM: usize = 31; + +#[repr(C)] +#[repr(align(4096))] +#[derive(Copy, Clone, Debug, Eq)] +pub struct CpuPt { + pub lvl1: [usize; PTE_PER_PAGE], + pub lvl2: [usize; PTE_PER_PAGE], + pub lvl3: [usize; PTE_PER_PAGE], +} + +impl PartialEq for CpuPt { + fn eq(&self, other: &Self) -> bool { + self.lvl1 == other.lvl1 && self.lvl2 == other.lvl2 && self.lvl3 == other.lvl3 + } +} + +#[derive(Copy, Clone, Debug, Eq)] +pub enum CpuState { + CpuInv = 0, + CpuIdle = 1, + CpuRun = 2, +} + +impl PartialEq for CpuState { + fn eq(&self, other: &Self) -> bool { + *self as usize == *other as usize + } +} + +pub struct CpuIf { + pub msg_queue: Vec, +} + +impl CpuIf { + pub fn default() -> CpuIf { + CpuIf { msg_queue: Vec::new() } + } + + pub fn push(&mut self, ipi_msg: IpiMessage) { + self.msg_queue.push(ipi_msg); + } + + pub fn pop(&mut self) -> Option { + self.msg_queue.pop() + } +} + +pub static CPU_IF_LIST: Mutex> = Mutex::new(Vec::new()); + +fn cpu_if_init() { + let mut cpu_if_list = CPU_IF_LIST.lock(); + for _ in 0..PLATFORM_CPU_NUM_MAX { + cpu_if_list.push(CpuIf::default()); + } +} + +#[repr(C)] +#[repr(align(4096))] +// #[derive(Clone)] +pub struct Cpu { + pub id: usize, + pub cpu_state: CpuState, + pub active_vcpu: Option, + pub ctx: Option, + + pub sched: SchedType, + pub vcpu_array: VcpuArray, + pub current_irq: usize, + pub cpu_pt: CpuPt, + pub stack: [u8; CPU_STACK_SIZE], +} + +impl Cpu { + const fn default() -> Cpu { + Cpu { + id: 0, + cpu_state: CpuState::CpuInv, + active_vcpu: None, + ctx: None, + sched: SchedType::None, + vcpu_array: VcpuArray::new(), + current_irq: 0, + cpu_pt: CpuPt { + lvl1: [0; PTE_PER_PAGE], + lvl2: [0; PTE_PER_PAGE], + lvl3: [0; PTE_PER_PAGE], + }, + stack: [0; CPU_STACK_SIZE], + } + } + + pub fn set_ctx(&mut self, ctx: *mut ContextFrame) { + self.ctx = Some(ctx as usize); + } + + pub fn clear_ctx(&mut self) { + self.ctx = None; + } + + pub fn set_gpr(&self, idx: usize, val: usize) { + if idx >= CONTEXT_GPR_NUM { + return; + } + match self.ctx { + Some(ctx_addr) => { + if trace() && ctx_addr < 0x1000 { + panic!("illegal ctx addr {:x}", ctx_addr); + } + let ctx = ctx_addr as *mut ContextFrame; + unsafe { + (*ctx).set_gpr(idx, val); + } + } + None => {} + } + } + + pub fn get_gpr(&self, idx: usize) -> usize { + if idx >= CONTEXT_GPR_NUM { + return 0; + } + match self.ctx { + Some(ctx_addr) => { + if trace() && ctx_addr < 0x1000 { + panic!("illegal ctx addr {:x}", ctx_addr); + } + let ctx = ctx_addr as *mut ContextFrame; + unsafe { (*ctx).gpr(idx) } + } + None => 0, + } + } + + pub fn get_elr(&self) -> usize { + match self.ctx { + Some(ctx_addr) => { + if trace() && ctx_addr < 0x1000 { + panic!("illegal ctx addr {:x}", ctx_addr); + } + let ctx = ctx_addr as *mut ContextFrame; + unsafe { (*ctx).exception_pc() } + } + None => 0, + } + } + + pub fn get_spsr(&self) -> usize { + match self.ctx { + Some(ctx_addr) => { + if trace() && ctx_addr < 0x1000 { + panic!("illegal ctx addr {:x}", ctx_addr); + } + let ctx = ctx_addr as *mut ContextFrame; + unsafe { (*ctx).spsr as usize } + } + None => 0, + } + } + + pub fn set_elr(&self, val: usize) { + match self.ctx { + Some(ctx_addr) => { + if trace() && ctx_addr < 0x1000 { + panic!("illegal ctx addr {:x}", ctx_addr); + } + let ctx = ctx_addr as *mut ContextFrame; + unsafe { (*ctx).set_exception_pc(val) } + } + None => {} + } + } + + pub fn set_active_vcpu(&mut self, active_vcpu: Option) { + self.active_vcpu = active_vcpu.clone(); + match active_vcpu { + None => {} + Some(vcpu) => { + vcpu.set_state(VcpuState::VcpuAct); + } + } + } + + pub fn schedule_to(&mut self, next_vcpu: Vcpu) { + if let Some(prev_vcpu) = &self.active_vcpu { + if prev_vcpu.vm_id() != next_vcpu.vm_id() { + // println!( + // "next vm{} vcpu {}, prev vm{} vcpu {}", + // next_vcpu.vm_id(), + // next_vcpu.id(), + // prev_vcpu.vm_id(), + // prev_vcpu.id() + // ); + prev_vcpu.set_state(VcpuState::VcpuPend); + prev_vcpu.context_vm_store(); + } + } + // NOTE: Must set active first and then restore context!!! + // because context restore while inject pending interrupt for VM + // and will judge if current active vcpu + self.set_active_vcpu(Some(next_vcpu.clone())); + next_vcpu.context_vm_restore(); + // restore vm's Stage2 MMU context + let vttbr = (next_vcpu.vm_id() << 48) | next_vcpu.vm_pt_dir(); + // println!("vttbr {:#x}", vttbr); + // TODO: replace the arch related expr + unsafe { + core::arch::asm!("msr VTTBR_EL2, {0}", "isb", in(reg) vttbr); + } + } + + pub fn scheduler(&mut self) -> &mut impl Scheduler { + match &mut self.sched { + SchedType::None => panic!("scheduler is None"), + SchedType::SchedRR(rr) => rr, + } + } + + pub fn assigned(&self) -> bool { + self.vcpu_array.vcpu_num() != 0 + } +} + +#[no_mangle] +#[link_section = ".cpu_private"] +pub static mut CPU: Cpu = Cpu { + id: 0, + cpu_state: CpuState::CpuInv, + active_vcpu: None, + ctx: None, + vcpu_array: VcpuArray::new(), + sched: SchedType::None, + current_irq: 0, + cpu_pt: CpuPt { + lvl1: [0; PTE_PER_PAGE], + lvl2: [0; PTE_PER_PAGE], + lvl3: [0; PTE_PER_PAGE], + }, + stack: [0; CPU_STACK_SIZE], +}; + +pub fn current_cpu() -> &'static mut Cpu { + unsafe { &mut CPU } +} + +pub fn active_vcpu_id() -> usize { + let active_vcpu = current_cpu().active_vcpu.clone().unwrap(); + active_vcpu.id() +} + +pub fn active_vm_id() -> usize { + let vm = active_vm().unwrap(); + vm.id() +} + +pub fn active_vm() -> Option { + match current_cpu().active_vcpu.clone() { + None => { + return None; + } + Some(active_vcpu) => { + return active_vcpu.vm(); + } + } +} + +pub fn active_vm_ncpu() -> usize { + match active_vm() { + Some(vm) => vm.ncpu(), + None => 0, + } +} + +pub fn cpu_init() { + let cpu_id = current_cpu().id; + if cpu_id == 0 { + use crate::arch::power_arch_init; + use crate::board::platform_power_on_secondary_cores; + platform_power_on_secondary_cores(); + power_arch_init(); + cpu_if_init(); + } + + let state = CpuState::CpuIdle; + current_cpu().cpu_state = state; + let sp = current_cpu().stack.as_ptr() as usize + CPU_STACK_SIZE; + let size = core::mem::size_of::(); + current_cpu().set_ctx((sp - size) as *mut _); + println!("Core {} init ok", cpu_id); + + crate::lib::barrier(); + // println!("after barrier cpu init"); + use crate::board::PLAT_DESC; + if cpu_id == 0 { + println!("Bring up {} cores", PLAT_DESC.cpu_desc.num); + println!("Cpu init ok"); + } +} + +pub fn cpu_idle() -> ! { + let state = CpuState::CpuIdle; + current_cpu().cpu_state = state; + cpu_interrupt_unmask(); + loop { + // TODO: replace it with an Arch function `arch_idle` + cortex_a::asm::wfi(); + } +} + +pub static mut CPU_LIST: [Cpu; PLATFORM_CPU_NUM_MAX] = [ + Cpu::default(), + Cpu::default(), + Cpu::default(), + Cpu::default(), + Cpu::default(), + Cpu::default(), + Cpu::default(), + Cpu::default(), +]; + +#[no_mangle] +// #[link_section = ".text.boot"] +pub extern "C" fn cpu_map_self(cpu_id: usize) -> usize { + let mut cpu = unsafe { &mut CPU_LIST[cpu_id] }; + (*cpu).id = cpu_id; + + let lvl1_addr = pt_map_banked_cpu(cpu); + + lvl1_addr +} diff --git a/src/kernel/hvc.rs b/src/kernel/hvc.rs new file mode 100644 index 0000000000000000000000000000000000000000..32dd1c16c2aaabc88eea91826cd0e5e52d26ff11 --- /dev/null +++ b/src/kernel/hvc.rs @@ -0,0 +1,683 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::collections::BTreeMap; +use core::mem::size_of; + +use spin::Mutex; + +use crate::arch::{PAGE_SIZE, PTE_S2_NORMAL}; +use crate::arch::gicc_clear_current_irq; +use crate::config::*; +use crate::device::{mediated_blk_notify_handler, mediated_dev_append}; +use crate::kernel::{ + active_vm, active_vm_id, current_cpu, DIRTY_MEM_THRESHOLD, interrupt_vm_inject, ipi_register, ipi_send_msg, + IpiHvcMsg, IpiInnerMsg, IpiMessage, IpiType, ivc_update_mq, map_migrate_vm_mem, mem_heap_region_reserve, + migrate_finish_ipi_handler, migrate_ready, Scheduler, send_migrate_memcpy_msg, unmap_migrate_vm_mem, + UPDATE_IMG_BASE_ADDR, update_request, vcpu_idle, VgicMigData, VirtioMmioData, vm, vm_if_copy_mem_map, + vm_if_dirty_mem_map, vm_if_get_cpu_id, vm_if_ivc_arg, vm_if_ivc_arg_ptr, vm_if_mem_map_dirty_sum, + vm_if_mem_map_page_num, vm_if_set_ivc_arg_ptr, VM_NUM_MAX, VMData, +}; +use crate::lib::{func_barrier, memcpy_safe, round_up, set_barrier_num, trace}; +use crate::lib::unilib::*; +use crate::vmm::{get_vm_id, vmm_boot_vm, vmm_list_vm, vmm_migrate_boot, vmm_reboot_vm, vmm_remove_vm}; + +pub static VM_STATE_FLAG: Mutex = Mutex::new(0); + +pub static SHARE_MEM_LIST: Mutex> = Mutex::new(BTreeMap::new()); +// If succeed, return 0. +const HVC_FINISH: usize = 0; +// If failed, return -1. +const HVC_ERR: usize = usize::MAX; + +// share mem type +pub const MIGRATE_BITMAP: usize = 0; +pub const VM_CONTEXT_SEND: usize = 1; +pub const VM_CONTEXT_RECEIVE: usize = 2; +pub const MIGRATE_SEND: usize = 3; +pub const MIGRATE_RECEIVE: usize = 4; +pub const LIVE_UPDATE_IMG: usize = 5; + +// hvc_fid +pub const HVC_SYS: usize = 0; +pub const HVC_VMM: usize = 1; +pub const HVC_IVC: usize = 2; +pub const HVC_MEDIATED: usize = 3; +pub const HVC_CONFIG: usize = 0x11; +pub const HVC_UNILIB: usize = 0x12; + +// hvc_sys_event +pub const HVC_SYS_REBOOT: usize = 0; +pub const HVC_SYS_SHUTDOWN: usize = 1; +pub const HVC_SYS_UPDATE: usize = 3; +pub const HVC_SYS_TEST: usize = 4; + +// hvc_vmm_event +pub const HVC_VMM_LIST_VM: usize = 0; +pub const HVC_VMM_GET_VM_STATE: usize = 1; +pub const HVC_VMM_BOOT_VM: usize = 2; +pub const HVC_VMM_SHUTDOWN_VM: usize = 3; +pub const HVC_VMM_REBOOT_VM: usize = 4; +pub const HVC_VMM_GET_VM_DEF_CFG: usize = 5; +pub const HVC_VMM_GET_VM_CFG: usize = 6; +pub const HVC_VMM_SET_VM_CFG: usize = 7; +pub const HVC_VMM_GET_VM_ID: usize = 8; +pub const HVC_VMM_TRACE_VMEXIT: usize = 9; +// for src vm: send msg to MVM to ask for migrating +pub const HVC_VMM_MIGRATE_START: usize = 10; +pub const HVC_VMM_MIGRATE_READY: usize = 11; +// for sender: copy dirty memory to receiver +pub const HVC_VMM_MIGRATE_MEMCPY: usize = 12; +pub const HVC_VMM_MIGRATE_FINISH: usize = 13; +// for receiver: init new vm but not boot +pub const HVC_VMM_MIGRATE_INIT_VM: usize = 14; +pub const HVC_VMM_MIGRATE_VM_BOOT: usize = 15; +pub const HVC_VMM_VM_REMOVE: usize = 16; + +// hvc_ivc_event +pub const HVC_IVC_UPDATE_MQ: usize = 0; +pub const HVC_IVC_SEND_MSG: usize = 1; +pub const HVC_IVC_BROADCAST_MSG: usize = 2; +pub const HVC_IVC_INIT_KEEP_ALIVE: usize = 3; +pub const HVC_IVC_KEEP_ALIVE: usize = 4; +pub const HVC_IVC_ACK: usize = 5; +pub const HVC_IVC_GET_TIME: usize = 6; +pub const HVC_IVC_SHARE_MEM: usize = 7; +pub const HVC_IVC_SEND_SHAREMEM: usize = 0x10; +//共享内存通信 +pub const HVC_IVC_GET_SHARED_MEM_IPA: usize = 0x11; +//用于VM获取共享内存IPA +pub const HVC_IVC_SEND_SHAREMEM_TEST_SPEED: usize = 0x12; //共享内存通信速度测试 + +// hvc_mediated_event +pub const HVC_MEDIATED_DEV_APPEND: usize = 0x30; +pub const HVC_MEDIATED_DEV_NOTIFY: usize = 0x31; +pub const HVC_MEDIATED_DRV_NOTIFY: usize = 0x32; + +pub const HVC_UNILIB_FS_INIT: usize = 0; +pub const HVC_UNILIB_FS_OPEN: usize = 1; +pub const HVC_UNILIB_FS_CLOSE: usize = 2; +pub const HVC_UNILIB_FS_READ: usize = 3; +pub const HVC_UNILIB_FS_WRITE: usize = 4; +pub const HVC_UNILIB_FS_LSEEK: usize = 5; +pub const HVC_UNILIB_FS_STAT: usize = 6; +pub const HVC_UNILIB_FS_APPEND: usize = 7; +pub const HVC_UNILIB_FS_FINISHED: usize = 8; + +// hvc_config_event +pub const HVC_CONFIG_ADD_VM: usize = 0; +pub const HVC_CONFIG_DELETE_VM: usize = 1; +pub const HVC_CONFIG_CPU: usize = 2; +pub const HVC_CONFIG_MEMORY_REGION: usize = 3; +pub const HVC_CONFIG_EMULATED_DEVICE: usize = 4; +pub const HVC_CONFIG_PASSTHROUGH_DEVICE_REGION: usize = 5; +pub const HVC_CONFIG_PASSTHROUGH_DEVICE_IRQS: usize = 6; +pub const HVC_CONFIG_PASSTHROUGH_DEVICE_STREAMS_IDS: usize = 7; +pub const HVC_CONFIG_DTB_DEVICE: usize = 8; +pub const HVC_CONFIG_UPLOAD_KERNEL_IMAGE: usize = 9; + +#[cfg(feature = "tx2")] +pub const HVC_IRQ: usize = 32 + 0x20; +#[cfg(feature = "pi4")] +pub const HVC_IRQ: usize = 32 + 0x10; +#[cfg(feature = "qemu")] +pub const HVC_IRQ: usize = 32 + 0x20; + +#[repr(C)] +pub enum HvcGuestMsg { + Default(HvcDefaultMsg), + Manage(HvcManageMsg), + Migrate(HvcMigrateMsg), + UniLib(HvcUniLibMsg), +} + +#[repr(C)] +pub struct HvcDefaultMsg { + pub fid: usize, + pub event: usize, +} + +#[repr(C)] +pub struct HvcManageMsg { + pub fid: usize, + pub event: usize, + pub vm_id: usize, +} + +pub const MIGRATE_START: usize = 0; +pub const MIGRATE_COPY: usize = 1; +pub const MIGRATE_FINISH: usize = 2; + +#[repr(C)] +pub struct HvcMigrateMsg { + pub fid: usize, + pub event: usize, + pub vm_id: usize, + pub oper: usize, + pub page_num: usize, // bitmap page num +} + +#[repr(C)] +pub struct HvcUniLibMsg { + pub fid: usize, + pub event: usize, + pub vm_id: usize, + pub arg_1: usize, + pub arg_2: usize, + pub arg_3: usize, +} + +pub fn add_share_mem(mem_type: usize, base: usize) { + let mut list = SHARE_MEM_LIST.lock(); + list.insert(mem_type, base); +} + +pub fn get_share_mem(mem_type: usize) -> usize { + let list = SHARE_MEM_LIST.lock(); + match list.get(&mem_type) { + None => { + panic!("there is not {} type share memory", mem_type); + } + Some(tup) => *tup, + } +} + +pub fn hvc_guest_handler( + hvc_type: usize, + event: usize, + x0: usize, + x1: usize, + x2: usize, + x3: usize, + x4: usize, + x5: usize, + x6: usize, +) -> Result { + match hvc_type { + HVC_SYS => hvc_sys_handler(event, x0), + HVC_VMM => hvc_vmm_handler(event, x0, x1), + HVC_IVC => hvc_ivc_handler(event, x0, x1), + HVC_MEDIATED => hvc_mediated_handler(event, x0, x1), + HVC_CONFIG => hvc_config_handler(event, x0, x1, x2, x3, x4, x5, x6), + HVC_UNILIB => hvc_unilib_handler(event, x0, x1, x2), + _ => { + println!("hvc_guest_handler: unknown hvc type {} event {}", hvc_type, event); + Err(()) + } + } +} + +fn hvc_config_handler( + event: usize, + x0: usize, + x1: usize, + x2: usize, + x3: usize, + x4: usize, + x5: usize, + x6: usize, +) -> Result { + match event { + HVC_CONFIG_ADD_VM => vm_cfg_add_vm(x0), + HVC_CONFIG_DELETE_VM => vm_cfg_del_vm(x0), + HVC_CONFIG_CPU => vm_cfg_set_cpu(x0, x1, x2, x3), + HVC_CONFIG_MEMORY_REGION => vm_cfg_add_mem_region(x0, x1, x2), + HVC_CONFIG_EMULATED_DEVICE => vm_cfg_add_emu_dev(x0, x1, x2, x3, x4, x5, x6), + HVC_CONFIG_PASSTHROUGH_DEVICE_REGION => vm_cfg_add_passthrough_device_region(x0, x1, x2, x3), + HVC_CONFIG_PASSTHROUGH_DEVICE_IRQS => vm_cfg_add_passthrough_device_irqs(x0, x1, x2), + HVC_CONFIG_PASSTHROUGH_DEVICE_STREAMS_IDS => vm_cfg_add_passthrough_device_streams_ids(x0, x1, x2), + HVC_CONFIG_DTB_DEVICE => vm_cfg_add_dtb_dev(x0, x1, x2, x3, x4, x5, x6), + HVC_CONFIG_UPLOAD_KERNEL_IMAGE => vm_cfg_upload_kernel_image(x0, x1, x2, x3, x4), + _ => { + println!("hvc_config_handler unknown event {}", event); + Err(()) + } + } +} + +fn hvc_sys_handler(event: usize, x0: usize) -> Result { + match event { + HVC_SYS_UPDATE => { + mem_heap_region_reserve(UPDATE_IMG_BASE_ADDR, x0); + update_request(); + Ok(0) + } + HVC_SYS_TEST => { + let vm = active_vm().unwrap(); + crate::device::virtio_net_announce(vm); + Ok(0) + } + _ => Err(()), + } +} + +fn hvc_vmm_handler(event: usize, x0: usize, _x1: usize) -> Result { + match event { + HVC_VMM_LIST_VM => vmm_list_vm(x0), + HVC_VMM_GET_VM_STATE => { + todo!(); + } + HVC_VMM_BOOT_VM => { + vmm_boot_vm(x0); + Ok(HVC_FINISH) + } + HVC_VMM_SHUTDOWN_VM => { + todo!(); + } + HVC_VMM_REBOOT_VM => { + vmm_reboot_vm(x0); + Ok(HVC_FINISH) + } + HVC_VMM_GET_VM_ID => { + get_vm_id(x0); + Ok(HVC_FINISH) + } + HVC_VMM_MIGRATE_START => { + // demo: migration for bma1 + if x0 == 0 { + println!("migration for mvm is not supported"); + return Err(()); + } + + hvc_send_msg_to_vm( + 0, + &HvcGuestMsg::Migrate(HvcMigrateMsg { + fid: HVC_VMM, + event: HVC_VMM_MIGRATE_START, + vm_id: x0, + oper: MIGRATE_START, + page_num: 0, + }), + ); + Ok(HVC_FINISH) + } + HVC_VMM_MIGRATE_READY => { + // init gvm dirty memory bitmap + // let cpu_trgt = vm_if_get_cpu_id(x0); + // println!( + // "core {} HVC_VMM_MIGRATE_READY, cpu trgt {}, vmid {}", + // current_cpu().id, + // cpu_trgt, + // x0 + // ); + migrate_ready(x0); + mvm_migrate_memory(x0); + vm_if_dirty_mem_map(x0); + + // send_hvc_ipi(0, x0, HVC_VMM, HVC_VMM_MIGRATE_READY, cpu_trgt); + Ok(HVC_FINISH) + } + HVC_VMM_MIGRATE_MEMCPY => { + let dirty_mem_num = vm_if_mem_map_dirty_sum(x0); + // let cpu_trgt = vm_if_get_cpu_id(x0); + if dirty_mem_num < DIRTY_MEM_THRESHOLD { + // Idle live vm, copy dirty mem and vm register struct + let trgt_vm = vm(x0).unwrap(); + set_barrier_num(trgt_vm.cpu_num()); + for vcpu_id in 0..trgt_vm.cpu_num() { + let pcpu_id = trgt_vm.vcpuid_to_pcpuid(vcpu_id).unwrap(); + send_hvc_ipi(0, x0, HVC_VMM, HVC_VMM_MIGRATE_FINISH, pcpu_id); + } + } else { + mvm_migrate_memory(x0); + // send_hvc_ipi(0, x0, HVC_VMM, HVC_VMM_MIGRATE_MEMCPY, cpu_trgt); + } + Ok(HVC_FINISH) + } + HVC_VMM_MIGRATE_INIT_VM => { + info!("migrate init vm {}", x0); + // vmm_init_gvm(x0); + let vm = vm(x0).unwrap(); + map_migrate_vm_mem(vm.clone(), get_share_mem(MIGRATE_RECEIVE)); + vm.context_vm_migrate_init(); + Ok(HVC_FINISH) + } + HVC_VMM_MIGRATE_VM_BOOT => { + let mvm = vm(0).unwrap(); + let vm = vm(x0).unwrap(); + + let size = size_of::(); + mvm.pt_unmap_range(get_share_mem(VM_CONTEXT_RECEIVE), round_up(size, PAGE_SIZE), true); + unmap_migrate_vm_mem(vm.clone(), get_share_mem(MIGRATE_RECEIVE)); + + vm.context_vm_migrate_restore(); + for vcpu_id in 0..vm.cpu_num() { + let cpu_trgt = vm.vcpuid_to_pcpuid(vcpu_id).unwrap(); + // send ipi to target vcpu, copy data and boot vm (in ipi copy gic data) + send_hvc_ipi(0, x0, HVC_VMM, HVC_VMM_MIGRATE_VM_BOOT, cpu_trgt); + } + Ok(HVC_FINISH) + } + HVC_VMM_MIGRATE_FINISH => { + let mvm = vm(0).unwrap(); + let trgt_vm = vm(x0).unwrap(); + let size = size_of::(); + mvm.pt_unmap_range(get_share_mem(VM_CONTEXT_SEND), round_up(size, PAGE_SIZE), true); + mvm.pt_unmap_range( + get_share_mem(MIGRATE_BITMAP), + PAGE_SIZE * vm_if_mem_map_page_num(x0), + true, + ); + unmap_migrate_vm_mem(trgt_vm, get_share_mem(MIGRATE_SEND)); + vmm_remove_vm(x0); + *VM_STATE_FLAG.lock() = 0; + Ok(HVC_FINISH) + } + HVC_VMM_VM_REMOVE => { + vmm_remove_vm(x0); + *VM_STATE_FLAG.lock() = 0; + Ok(HVC_FINISH) + } + _ => { + println!("hvc_vmm unknown event {}", event); + Err(()) + } + } +} + +fn hvc_ivc_handler(event: usize, x0: usize, x1: usize) -> Result { + match event { + HVC_IVC_UPDATE_MQ => { + if ivc_update_mq(x0, x1) { + Ok(HVC_FINISH) + } else { + Err(()) + } + } + HVC_IVC_SHARE_MEM => { + let vm = active_vm().unwrap(); + let base = vm.share_mem_base(); + if x0 == LIVE_UPDATE_IMG { + // hard code for pa 0x8a000000, x1 should be 0x8000000 + vm.pt_map_range(base, x1, 0x8a000000, PTE_S2_NORMAL, true); + } + vm.add_share_mem_base(x1); + add_share_mem(x0, base); + info!( + "VM{} add share mem type 0x{:x} base 0x{:x} len 0x{:x}", + active_vm_id(), + x0, + base, + x1 + ); + Ok(base) + } + _ => { + println!("hvc_ivc_handler: unknown event {}", event); + Err(()) + } + } +} + +fn hvc_mediated_handler(event: usize, x0: usize, x1: usize) -> Result { + match event { + HVC_MEDIATED_DEV_APPEND => mediated_dev_append(x0, x1), + HVC_MEDIATED_DEV_NOTIFY => mediated_blk_notify_handler(x0), + _ => { + println!("unknown mediated event {}", event); + return Err(()); + } + } +} + +fn hvc_unilib_handler(event: usize, x0: usize, x1: usize, x2: usize) -> Result { + match event { + HVC_UNILIB_FS_INIT => unilib_fs_init(), + HVC_UNILIB_FS_OPEN => unilib_fs_open(x0, x1, x2), + HVC_UNILIB_FS_CLOSE => unilib_fs_close(x0), + HVC_UNILIB_FS_READ => unilib_fs_read(x0, x1, x2), + HVC_UNILIB_FS_WRITE => unilib_fs_write(x0, x1, x2), + HVC_UNILIB_FS_LSEEK => unilib_fs_lseek(x0, x1, x2), + HVC_UNILIB_FS_STAT => unilib_fs_stat(), + HVC_UNILIB_FS_APPEND => unilib_fs_append(x0), + HVC_UNILIB_FS_FINISHED => unilib_fs_finished(x0), + _ => { + println!("unknown mediated event {}", event); + return Err(()); + } + } +} + +pub fn hvc_send_msg_to_vm(vm_id: usize, guest_msg: &HvcGuestMsg) -> bool { + let mut target_addr = 0; + let mut arg_ptr_addr = vm_if_ivc_arg_ptr(vm_id); + let arg_addr = vm_if_ivc_arg(vm_id); + + if arg_ptr_addr != 0 { + arg_ptr_addr += PAGE_SIZE / VM_NUM_MAX; + if arg_ptr_addr - arg_addr >= PAGE_SIZE { + vm_if_set_ivc_arg_ptr(vm_id, arg_addr); + target_addr = arg_addr; + } else { + vm_if_set_ivc_arg_ptr(vm_id, arg_ptr_addr); + target_addr = arg_ptr_addr; + } + } + + if target_addr == 0 { + println!("hvc_send_msg_to_vm: target VM{} interface is not prepared", vm_id); + return false; + } + + if trace() && (target_addr < 0x1000 || (guest_msg as *const _ as usize) < 0x1000) { + panic!( + "illegal des addr {:x}, src addr {:x}", + target_addr, guest_msg as *const _ as usize + ); + } + let (fid, event) = match guest_msg { + HvcGuestMsg::Default(msg) => { + memcpy_safe( + target_addr as *const u8, + msg as *const _ as *const u8, + size_of::(), + ); + (msg.fid, msg.event) + } + HvcGuestMsg::Migrate(msg) => { + memcpy_safe( + target_addr as *const u8, + msg as *const _ as *const u8, + size_of::(), + ); + (msg.fid, msg.event) + } + HvcGuestMsg::Manage(msg) => { + memcpy_safe( + target_addr as *const u8, + msg as *const _ as *const u8, + size_of::(), + ); + (msg.fid, msg.event) + } + HvcGuestMsg::UniLib(msg) => { + memcpy_safe( + target_addr as *const u8, + msg as *const _ as *const u8, + size_of::(), + ); + (msg.fid, msg.event) + } + }; + + let cpu_trgt = vm_if_get_cpu_id(vm_id); + if cpu_trgt != current_cpu().id { + // println!("cpu {} send hvc msg to cpu {}", current_cpu().id, cpu_trgt); + let ipi_msg = IpiHvcMsg { + src_vmid: 0, + trgt_vmid: vm_id, + fid, + event, + }; + if !ipi_send_msg(cpu_trgt, IpiType::IpiTHvc, IpiInnerMsg::HvcMsg(ipi_msg)) { + println!( + "hvc_send_msg_to_vm: Failed to send ipi message, target {} type {:#?}", + cpu_trgt, + IpiType::IpiTHvc + ); + } + } else { + hvc_guest_notify(vm_id); + } + + true +} + +// notify current cpu's vcpu +pub fn hvc_guest_notify(vm_id: usize) { + let vm = vm(vm_id).unwrap(); + match current_cpu().vcpu_array.pop_vcpu_through_vmid(vm_id) { + None => { + println!( + "hvc_guest_notify: Core {} failed to find vcpu of VM {}", + current_cpu().id, + vm_id + ); + } + Some(vcpu) => { + interrupt_vm_inject(vm.clone(), vcpu.clone(), HVC_IRQ, 0); + } + }; +} + +pub fn hvc_ipi_handler(msg: &IpiMessage) { + match &msg.ipi_message { + IpiInnerMsg::HvcMsg(msg) => { + if current_cpu().vcpu_array.pop_vcpu_through_vmid(msg.trgt_vmid).is_none() { + println!( + "hvc_ipi_handler: Core {} failed to find vcpu of VM {}", + current_cpu().id, + msg.trgt_vmid + ); + return; + } + + match msg.fid { + HVC_MEDIATED => { + hvc_guest_notify(msg.trgt_vmid); + } + HVC_VMM => match msg.event { + HVC_VMM_MIGRATE_START => { + // in mvm + hvc_guest_notify(msg.trgt_vmid); + } + HVC_VMM_MIGRATE_FINISH => { + // 被迁移VM收到该ipi标志vcpu_idle,VM0收到该ipi标志最后一次内存拷贝 + if current_cpu().id == 0 { + migrate_finish_ipi_handler(msg.src_vmid); + return; + } + let trgt_vcpu = match current_cpu().vcpu_array.pop_vcpu_through_vmid(msg.trgt_vmid) { + None => { + println!( + "Core {} failed to find target vcpu, vmid {}", + current_cpu().id, + msg.trgt_vmid + ); + return; + } + Some(vcpu) => vcpu, + }; + let vm = trgt_vcpu.vm().unwrap(); + // println!("Core[{}] clear irq {}", current_cpu().id, current_cpu().current_irq); + gicc_clear_current_irq(true); + // 当满足下序条件时需要拷贝cpu.ctx + // 否则意味着当前核心有多个虚拟机共享,且被迁移虚拟机所在的核心尚未被调度到,寄存器数值无需更新 + if vm.id() == msg.trgt_vmid { + trgt_vcpu.context_vm_store(); + } + // save gic register for each vcpu + trgt_vcpu.context_gic_irqs_store(); + func_barrier(); + *VM_STATE_FLAG.lock() = 1; + if trgt_vcpu.id() == 0 { + vm.context_vm_migrate_save(); + // println!("send finish ipi to core0"); + send_hvc_ipi(msg.trgt_vmid, 0, HVC_VMM, HVC_VMM_MIGRATE_FINISH, 0); + } + // println!( + // "VMData size is {:x}, VgicMigData size is {:x}, VirtioMmioData size is {:x}", + // size_of::(), + // size_of::(), + // size_of::(), + // ); + vcpu_idle(trgt_vcpu); + } + HVC_VMM_MIGRATE_VM_BOOT => { + // let vm = vm(msg.trgt_vmid).unwrap(); + // vm.set_migration_state(true); + + gicc_clear_current_irq(true); + match current_cpu().vcpu_array.pop_vcpu_through_vmid(msg.trgt_vmid) { + None => { + panic!("Core[{}] does not have VM[{}] vcpu", current_cpu().id, msg.trgt_vmid); + } + Some(vcpu) => { + current_cpu().scheduler().yield_to(vcpu.clone()); + // restore gic register for each vcpu + vcpu.context_gic_irqs_restore(); + } + } + vmm_migrate_boot(); + } + _ => {} + }, + HVC_CONFIG => match msg.event { + HVC_CONFIG_UPLOAD_KERNEL_IMAGE => { + hvc_guest_notify(msg.trgt_vmid); + } + _ => { + todo!(); + } + }, + HVC_UNILIB => { + hvc_guest_notify(msg.trgt_vmid); + } + _ => { + todo!(); + } + } + } + _ => { + println!("vgic_ipi_handler: illegal ipi"); + return; + } + } +} + +fn mvm_migrate_memory(trgt_vmid: usize) { + let vm = vm(trgt_vmid); + vm.as_ref().unwrap().pt_read_only(); + // tlb_invalidate_guest_all(); + vm_if_copy_mem_map(trgt_vmid); + send_migrate_memcpy_msg(trgt_vmid); +} + +pub fn hvc_init() { + if !ipi_register(IpiType::IpiTHvc, hvc_ipi_handler) { + panic!("hvc_init: failed to register hvc ipi {}", IpiType::IpiTHvc as usize) + } +} + +pub fn send_hvc_ipi(src_vmid: usize, trgt_vmid: usize, fid: usize, event: usize, trgt_cpuid: usize) { + let ipi_msg = IpiHvcMsg { + src_vmid, + trgt_vmid, + fid, + event, + }; + if !ipi_send_msg(trgt_cpuid, IpiType::IpiTHvc, IpiInnerMsg::HvcMsg(ipi_msg)) { + println!( + "send_hvc_ipi: Failed to send ipi message, target {} type {:#?}", + 0, + IpiType::IpiTHvc + ); + } +} diff --git a/src/kernel/interrupt.rs b/src/kernel/interrupt.rs new file mode 100644 index 0000000000000000000000000000000000000000..aec758f1260178e366af972a2a509c72ad3c951b --- /dev/null +++ b/src/kernel/interrupt.rs @@ -0,0 +1,250 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::collections::BTreeMap; + +use spin::Mutex; + +use crate::arch::{interrupt_arch_ipi_send, interrupt_arch_vm_inject}; +use crate::arch::{GIC_PRIVINT_NUM, interrupt_arch_vm_register}; +use crate::kernel::{current_cpu, hyper_fresh_ipi_handler, ipi_irq_handler, IpiInnerMsg, IpiMessage, Vcpu, VcpuState}; +use crate::kernel::{ipi_register, IpiType, Vm}; +use crate::lib::{BitAlloc, BitAlloc256, BitAlloc4K, BitMap}; +use crate::vmm::vmm_ipi_handler; + +pub const INTERRUPT_NUM_MAX: usize = 1024; +pub const INTERRUPT_IRQ_HYPERVISOR_TIMER: usize = 26; +pub const INTERRUPT_IRQ_GUEST_TIMER: usize = 27; +pub const INTERRUPT_IRQ_IPI: usize = 1; + +pub static INTERRUPT_HYPER_BITMAP: Mutex> = Mutex::new(BitAlloc4K::default()); +pub static INTERRUPT_GLB_BITMAP: Mutex> = Mutex::new(BitAlloc4K::default()); +// pub static INTERRUPT_HANDLERS: Mutex<[InterruptHandler; INTERRUPT_NUM_MAX]> = +// Mutex::new([InterruptHandler::None; INTERRUPT_NUM_MAX]); +pub static INTERRUPT_HANDLERS: Mutex> = Mutex::new(BTreeMap::new()); + +#[derive(Copy, Clone)] +pub enum InterruptHandler { + IpiIrqHandler(fn()), + GicMaintenanceHandler(fn(usize)), + TimeIrqHandler(fn(usize)), + None, +} + +impl InterruptHandler { + pub fn call(&self, arg0: usize, _arg1: usize) { + match self { + InterruptHandler::IpiIrqHandler(irq_handler) => irq_handler(), + InterruptHandler::GicMaintenanceHandler(gic_handler) => gic_handler(arg0), + InterruptHandler::TimeIrqHandler(time_handler) => time_handler(arg0), + InterruptHandler::None => panic!("Call An Empty Interrupt Hanlder!"), + } + } +} + +pub fn interrupt_cpu_ipi_send(target_cpu: usize, ipi_id: usize) { + interrupt_arch_ipi_send(target_cpu, ipi_id); +} + +pub fn interrupt_reserve_int(int_id: usize, handler: InterruptHandler) { + if int_id < INTERRUPT_NUM_MAX { + let mut irq_handler_lock = INTERRUPT_HANDLERS.lock(); + let mut hyper_bitmap_lock = INTERRUPT_HYPER_BITMAP.lock(); + let mut glb_bitmap_lock = INTERRUPT_GLB_BITMAP.lock(); + // irq_handler_lock[int_id] = handler; + irq_handler_lock.insert(int_id, handler); + hyper_bitmap_lock.set(int_id); + glb_bitmap_lock.set(int_id) + } +} + +fn interrupt_is_reserved(int_id: usize) -> bool { + let hyper_bitmap_lock = INTERRUPT_HYPER_BITMAP.lock(); + hyper_bitmap_lock.get(int_id) != 0 +} + +pub fn interrupt_cpu_enable(int_id: usize, en: bool) { + use crate::arch::interrupt_arch_enable; + interrupt_arch_enable(int_id, en); +} + +pub fn interrupt_init() { + use crate::arch::interrupt_arch_init; + interrupt_arch_init(); + + let cpu_id = current_cpu().id; + if cpu_id == 0 { + interrupt_reserve_int(INTERRUPT_IRQ_IPI, InterruptHandler::IpiIrqHandler(ipi_irq_handler)); + + if !ipi_register(IpiType::IpiTIntInject, interrupt_inject_ipi_handler) { + panic!( + "interrupt_init: failed to register int inject ipi {:#?}", + IpiType::IpiTIntInject + ) + } + use crate::arch::vgic_ipi_handler; + if !ipi_register(IpiType::IpiTIntc, vgic_ipi_handler) { + panic!("interrupt_init: failed to register intc ipi {:#?}", IpiType::IpiTIntc) + } + use crate::device::ethernet_ipi_rev_handler; + if !ipi_register(IpiType::IpiTEthernetMsg, ethernet_ipi_rev_handler) { + panic!( + "interrupt_init: failed to register eth ipi {:#?}", + IpiType::IpiTEthernetMsg, + ); + } + if !ipi_register(IpiType::IpiTVMM, vmm_ipi_handler) { + panic!("interrupt_init: failed to register ipi vmm"); + } + if !ipi_register(IpiType::IpiTHyperFresh, hyper_fresh_ipi_handler) { + panic!("interrupt_init: failed to register ipi hyper fresh"); + } + + println!("Interrupt init ok"); + } + interrupt_cpu_enable(INTERRUPT_IRQ_IPI, true); +} + +pub fn interrupt_vm_register(vm: Vm, id: usize) -> bool { + // println!("VM {} register interrupt {}", vm.id(), id); + let mut glb_bitmap_lock = INTERRUPT_GLB_BITMAP.lock(); + if glb_bitmap_lock.get(id) != 0 && id >= GIC_PRIVINT_NUM { + println!("interrupt_vm_register: VM {} interrupts conflict, id = {}", vm.id(), id); + return false; + } + + interrupt_arch_vm_register(vm.clone(), id); + vm.set_int_bit_map(id); + glb_bitmap_lock.set(id); + true +} + +pub fn interrupt_vm_remove(_vm: Vm, id: usize) { + let mut glb_bitmap_lock = INTERRUPT_GLB_BITMAP.lock(); + // vgic and vm will be removed with struct vm + glb_bitmap_lock.clear(id); + // todo: for interrupt 16~31, need to check by vm config + if id >= GIC_PRIVINT_NUM { + interrupt_cpu_enable(id, false); + } +} + +pub fn interrupt_vm_inject(vm: Vm, vcpu: Vcpu, int_id: usize, _source: usize) { + // if vm.id() == 1 { + // println!("inject int {} to vm1", int_id); + // } + // if current_cpu().id == 2 { + // println!("inject int {} to core 2", int_id); + // } + // if current_cpu().id == 1 && int_id == 49 { + // println!("inject int {} to core 1", int_id); + // } + if vcpu.phys_id() != current_cpu().id { + println!( + "interrupt_vm_inject: Core {} failed to find target (VCPU {} VM {})", + current_cpu().id, + vcpu.id(), + vm.id() + ); + return; + } + interrupt_arch_vm_inject(vm, vcpu, int_id); +} + +pub fn interrupt_handler(int_id: usize, src: usize) -> bool { + if interrupt_is_reserved(int_id) { + let irq_handler_list = INTERRUPT_HANDLERS.lock(); + let irq_handler = irq_handler_list.get(&int_id).unwrap().clone(); + drop(irq_handler_list); + match irq_handler { + InterruptHandler::IpiIrqHandler(ipi_handler) => { + ipi_handler(); + } + InterruptHandler::GicMaintenanceHandler(maintenace_handler) => { + maintenace_handler(int_id); + } + InterruptHandler::TimeIrqHandler(timer_irq_handler) => { + timer_irq_handler(int_id); + } + InterruptHandler::None => { + unimplemented!(); + } + } + // drop(irq_handler); + return true; + } + + if int_id >= 16 && int_id < 32 { + if let Some(vcpu) = ¤t_cpu().active_vcpu { + if let Some(active_vm) = vcpu.vm() { + if active_vm.has_interrupt(int_id) { + interrupt_vm_inject(active_vm.clone(), vcpu.clone(), int_id, src); + // if current_cpu().id == 1 { + // println!("GICH_MISR {:x}", GICH.misr()); + // println!("GICH_HCR {:x}", GICH.hcr()); + // for i in 0..4 { + // println!("GICH_LR[{}] {:x}", i, GICH.lr(i)); + // } + // println!("interrupt_handler, inject {} to core1", int_id); + // } + return false; + } else { + return true; + } + } + } + } + + for vcpu in current_cpu().vcpu_array.iter() { + if let Some(vcpu) = vcpu { + match vcpu.vm() { + Some(vm) => { + if vm.has_interrupt(int_id) { + if vcpu.state() as usize == VcpuState::VcpuInv as usize { + return true; + } + + interrupt_vm_inject(vm.clone(), vcpu.clone(), int_id, src); + return false; + } + } + None => {} + } + } + } + + println!( + "interrupt_handler: core {} receive unsupported int {}", + current_cpu().id, + int_id + ); + true +} + +pub fn interrupt_inject_ipi_handler(msg: &IpiMessage) { + match &msg.ipi_message { + IpiInnerMsg::IntInjectMsg(int_msg) => { + let vm_id = int_msg.vm_id; + let int_id = int_msg.int_id; + match current_cpu().vcpu_array.pop_vcpu_through_vmid(vm_id) { + None => { + panic!("inject int {} to illegal cpu {}", int_id, current_cpu().id); + } + Some(vcpu) => { + interrupt_vm_inject(vcpu.vm().unwrap(), vcpu.clone(), int_id, 0); + } + } + } + _ => { + println!("interrupt_inject_ipi_handler: illegal ipi type"); + return; + } + } +} diff --git a/src/kernel/iommu.rs b/src/kernel/iommu.rs new file mode 100644 index 0000000000000000000000000000000000000000..0df3aac62425f642e39d2cd1fd7bedd7028c07a0 --- /dev/null +++ b/src/kernel/iommu.rs @@ -0,0 +1,39 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::{smmu_add_device, smmu_vm_init}; +use crate::kernel::Vm; + +pub fn iommu_init() { + if cfg!(feature = "tx2") { + crate::arch::smmu_init(); + println!("IOMMU init ok"); + } else { + println!("Platform not support IOMMU"); + } +} + +pub fn iommmu_vm_init(vm: Vm) -> bool { + if cfg!(feature = "tx2") { + return smmu_vm_init(vm.clone()); + } else { + println!("Platform not support IOMMU"); + return false; + } +} + +pub fn iommu_add_device(vm: Vm, stream_id: usize) -> bool { + if cfg!(feature = "tx2") { + return smmu_add_device(vm.iommu_ctx_id(), stream_id); + } else { + println!("Platform not support IOMMU"); + return false; + } +} diff --git a/src/kernel/ipi.rs b/src/kernel/ipi.rs new file mode 100644 index 0000000000000000000000000000000000000000..7dec7e35edbbda3f1c6a9c26a617296fecbbf32e --- /dev/null +++ b/src/kernel/ipi.rs @@ -0,0 +1,237 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::arch::INTERRUPT_IRQ_IPI; +use crate::board::PLAT_DESC; +use crate::device::{VirtioMmio, Virtq}; +use crate::kernel::{CPU_IF_LIST, current_cpu, interrupt_cpu_ipi_send}; +use crate::vmm::VmmEvent; + +use super::Vm; + +#[derive(Copy, Clone, Debug)] +pub enum InitcEvent { + VgicdGichEn, + VgicdSetEn, + VgicdSetAct, + VgicdSetPend, + VgicdSetPrio, + VgicdSetTrgt, + VgicdSetCfg, + VgicdRoute, + None, +} + +#[derive(Copy, Clone)] +pub enum PowerEvent { + PsciIpiCpuOn, + PsciIpiCpuOff, + PsciIpiCpuReset, +} + +#[derive(Copy, Clone)] +pub struct IpiInitcMessage { + pub event: InitcEvent, + pub vm_id: usize, + pub int_id: u16, + pub val: u8, +} + +/* +* src: src vm id +*/ +#[derive(Copy, Clone)] +pub struct IpiPowerMessage { + pub src: usize, + pub event: PowerEvent, + pub entry: usize, + pub context: usize, +} + +// #[derive(Copy, Clone)] +// pub struct IpiEthernetAckMsg { +// pub len: usize, +// pub succeed: bool, +// } + +#[derive(Copy, Clone)] +pub struct IpiEthernetMsg { + pub src_vmid: usize, + pub trgt_vmid: usize, +} + +#[derive(Copy, Clone)] +pub struct IpiVmmMsg { + pub vmid: usize, + pub event: VmmEvent, +} + +// only support for mediated blk +#[derive(Clone)] +pub struct IpiMediatedMsg { + pub src_id: usize, + pub vq: Virtq, + pub blk: VirtioMmio, + // pub avail_idx: u16, +} + +#[derive(Clone, Copy)] +pub struct IpiMediatedNotifyMsg { + pub vm_id: usize, +} + +#[derive(Clone, Copy)] +pub struct IpiHvcMsg { + pub src_vmid: usize, + pub trgt_vmid: usize, + pub fid: usize, + pub event: usize, +} + +#[derive(Clone, Copy)] +pub struct IpiIntInjectMsg { + pub vm_id: usize, + pub int_id: usize, +} + +#[derive(Copy, Clone, Debug)] +pub enum IpiType { + IpiTIntc = 0, + IpiTPower = 1, + IpiTEthernetMsg = 2, + IpiTHyperFresh = 3, + IpiTHvc = 4, + IpiTVMM = 5, + IpiTMediatedDev = 6, + IpiTIntInject = 8, +} + +#[derive(Clone)] +pub enum IpiInnerMsg { + Initc(IpiInitcMessage), + Power(IpiPowerMessage), + EnternetMsg(IpiEthernetMsg), + VmmMsg(IpiVmmMsg), + MediatedMsg(IpiMediatedMsg), + MediatedNotifyMsg(IpiMediatedNotifyMsg), + HvcMsg(IpiHvcMsg), + IntInjectMsg(IpiIntInjectMsg), + HyperFreshMsg(), + None, +} + +pub struct IpiMessage { + pub ipi_type: IpiType, + pub ipi_message: IpiInnerMsg, +} + +const IPI_HANDLER_MAX: usize = 16; + +pub type IpiHandlerFunc = fn(&IpiMessage); + +pub struct IpiHandler { + pub handler: IpiHandlerFunc, + pub ipi_type: IpiType, +} + +impl IpiHandler { + fn new(handler: IpiHandlerFunc, ipi_type: IpiType) -> IpiHandler { + IpiHandler { handler, ipi_type } + } +} + +pub static IPI_HANDLER_LIST: Mutex> = Mutex::new(Vec::new()); + +pub fn ipi_irq_handler() { + // println!("ipi handler"); + let cpu_id = current_cpu().id; + let mut cpu_if_list = CPU_IF_LIST.lock(); + let mut msg: Option = cpu_if_list[cpu_id].pop(); + drop(cpu_if_list); + + while !msg.is_none() { + let ipi_msg = msg.unwrap(); + let ipi_type = ipi_msg.ipi_type as usize; + + let ipi_handler_list = IPI_HANDLER_LIST.lock(); + let len = ipi_handler_list.len(); + let handler = ipi_handler_list[ipi_type].handler.clone(); + drop(ipi_handler_list); + + if len <= ipi_type { + println!("illegal ipi type {}", ipi_type) + } else { + // println!("ipi type is {:#?}", ipi_msg.ipi_type); + handler(&ipi_msg); + } + let mut cpu_if_list = CPU_IF_LIST.lock(); + msg = cpu_if_list[cpu_id].pop(); + } +} + +pub fn ipi_register(ipi_type: IpiType, handler: IpiHandlerFunc) -> bool { + // check handler max + let mut ipi_handler_list = IPI_HANDLER_LIST.lock(); + for i in 0..ipi_handler_list.len() { + if ipi_type as usize == ipi_handler_list[i].ipi_type as usize { + println!("ipi_register: try to cover exist ipi handler"); + return false; + } + } + + while (ipi_type as usize) >= ipi_handler_list.len() { + ipi_handler_list.push(IpiHandler::new(handler, ipi_type)); + } + ipi_handler_list[ipi_type as usize] = IpiHandler::new(handler, ipi_type); + // ipi_handler_list.push(IpiHandler::new(handler, ipi_type)); + true +} + +fn ipi_send(target_id: usize, msg: IpiMessage) -> bool { + if target_id >= PLAT_DESC.cpu_desc.num { + println!("ipi_send: core {} not exist", target_id); + return false; + } + + let mut cpu_if_list = CPU_IF_LIST.lock(); + cpu_if_list[target_id].msg_queue.push(msg); + interrupt_cpu_ipi_send(target_id, INTERRUPT_IRQ_IPI); + + true +} + +pub fn ipi_send_msg(target_id: usize, ipi_type: IpiType, ipi_message: IpiInnerMsg) -> bool { + let msg = IpiMessage { ipi_type, ipi_message }; + ipi_send(target_id, msg) +} + +pub fn ipi_intra_broadcast_msg(vm: Vm, ipi_type: IpiType, msg: IpiInnerMsg) -> bool { + let mut i = 0; + let mut n = 0; + while n < (vm.cpu_num() - 1) { + if ((1 << i) & vm.ncpu()) != 0 && i != current_cpu().id { + n += 1; + if !ipi_send_msg(i, ipi_type, msg.clone()) { + println!( + "ipi_intra_broadcast_msg: Failed to send ipi request, cpu {} type {}", + i, ipi_type as usize + ); + return false; + } + } + + i += 1; + } + true +} diff --git a/src/kernel/ivc.rs b/src/kernel/ivc.rs new file mode 100644 index 0000000000000000000000000000000000000000..88582154304428cde00683068c3b1b5effc8fde1 --- /dev/null +++ b/src/kernel/ivc.rs @@ -0,0 +1,71 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use spin::Mutex; + +use crate::arch::PAGE_SIZE; +use crate::arch::PTE_S2_NORMAL; +use crate::kernel::{ + active_vm, current_cpu, mem_pages_alloc, Vm, vm_if_set_ivc_arg, vm_if_set_ivc_arg_ptr, vm_ipa2pa, VM_NUM_MAX, +}; +use crate::mm::PageFrame; + +// todo: need to rewrite for more vm +pub static SHARED_MEM: Mutex> = Mutex::new(None); +pub const SHARED_MEM_SIZE_MAX: usize = 0x200000; + +pub fn ivc_update_mq(receive_ipa: usize, cfg_ipa: usize) -> bool { + let vm = active_vm().unwrap(); + let vm_id = vm.id(); + let receive_pa = vm_ipa2pa(vm.clone(), receive_ipa); + let cfg_pa = vm_ipa2pa(vm.clone(), cfg_ipa); + + if receive_pa == 0 { + println!("ivc_update_mq: invalid receive_pa"); + return false; + } + + vm_if_set_ivc_arg(vm_id, cfg_pa); + vm_if_set_ivc_arg_ptr(vm_id, cfg_pa - PAGE_SIZE / VM_NUM_MAX); + + let idx = 0; + let val = vm_id; + current_cpu().set_gpr(idx, val); + // println!("VM {} update message", vm_id); + true +} + +pub fn mem_shared_mem_init() { + let mut shared_mem = SHARED_MEM.lock(); + if shared_mem.is_none() { + if let Ok(page_frame) = mem_pages_alloc(SHARED_MEM_SIZE_MAX / PAGE_SIZE) { + *shared_mem = Some(page_frame); + } + } +} + +pub fn shyper_init(vm: Vm, base_ipa: usize, len: usize) -> bool { + if base_ipa == 0 || len == 0 { + info!("vm{} shyper base ipa {:x}, len {:x}", vm.id(), base_ipa, len); + return true; + } + let shared_mem = SHARED_MEM.lock(); + + match &*shared_mem { + Some(page_frame) => { + vm.pt_map_range(base_ipa, len, page_frame.pa(), PTE_S2_NORMAL, true); + true + } + None => { + println!("shyper_init: shared mem should not be None"); + false + } + } +} diff --git a/src/kernel/live_update.rs b/src/kernel/live_update.rs new file mode 100644 index 0000000000000000000000000000000000000000..cf2f512c534518dbc2421f973d6226f312e6aeb2 --- /dev/null +++ b/src/kernel/live_update.rs @@ -0,0 +1,1110 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +// use alloc::boxed::Box; +use alloc::collections::{BTreeMap, BTreeSet, LinkedList}; +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use spin::{Mutex, RwLock}; + +use crate::arch::{ + emu_intc_handler, emu_smmu_handler, GIC_LRS_NUM, gic_maintenance_handler, gicc_clear_current_irq, INTERRUPT_EN_SET, + PageTable, partial_passthrough_intc_handler, psci_ipi_handler, SMMU_V2, SmmuV2, TIMER_FREQ, TIMER_SLICE, Vgic, + vgic_ipi_handler, +}; +use crate::board::PLAT_DESC; +use crate::config::{ + DEF_VM_CONFIG_TABLE, vm_cfg_entry, VmConfigEntry, VmConfigTable, VmDtbDevConfig, VMDtbDevConfigList, + VmEmulatedDeviceConfig, VmEmulatedDeviceConfigList, VmMemoryConfig, VmPassthroughDeviceConfig, +}; +use crate::device::{ + BlkIov, EMU_DEVS_LIST, emu_virtio_mmio_handler, EmuDevEntry, EmuDeviceType, EmuDevs, ethernet_ipi_rev_handler, + MEDIATED_BLK_LIST, mediated_ipi_handler, MediatedBlk, virtio_blk_notify_handler, virtio_console_notify_handler, + virtio_mediated_blk_notify_handler, virtio_net_notify_handler, VirtioMmio, +}; +use crate::kernel::{ + async_blk_io_req, ASYNC_EXE_STATUS, ASYNC_IO_TASK_LIST, async_ipi_req, ASYNC_IPI_TASK_LIST, ASYNC_USED_INFO_LIST, + AsyncExeStatus, AsyncTask, AsyncTaskData, CPU, Cpu, cpu_idle, CPU_IF_LIST, CpuIf, CpuState, current_cpu, FairQueue, + HEAP_REGION, HeapRegion, hvc_ipi_handler, INTERRUPT_GLB_BITMAP, INTERRUPT_HANDLERS, INTERRUPT_HYPER_BITMAP, + interrupt_inject_ipi_handler, InterruptHandler, IoAsyncMsg, IPI_HANDLER_LIST, ipi_irq_handler, ipi_register, + ipi_send_msg, IpiHandler, IpiInnerMsg, IpiMediatedMsg, IpiMessage, IpiType, mem_heap_region_init, SchedType, + SchedulerUpdate, SHARE_MEM_LIST, timer_irq_handler, UsedInfo, Vcpu, VCPU_LIST, VcpuInner, vm, Vm, VM_IF_LIST, + vm_ipa2pa, VM_LIST, VM_NUM_MAX, VM_REGION, VmInterface, VmRegion, logger_init, +}; +use crate::lib::{barrier, BitAlloc256, BitMap, FlexBitmap, time_current_us}; +use crate::mm::{heap_init, PageFrame}; +use crate::vmm::vmm_ipi_handler; + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum FreshStatus { + Start, + FreshVM, + FreshVCPU, + Finish, + None, +} + +#[cfg(feature = "update")] +static FRESH_STATUS: RwLock = RwLock::new(FreshStatus::Start); +#[cfg(not(feature = "update"))] +static FRESH_STATUS: RwLock = RwLock::new(FreshStatus::None); + +pub static FRESH_LOGIC_LOCK: Mutex<()> = Mutex::new(()); +pub static FRESH_IRQ_LOGIC_LOCK: Mutex<()> = Mutex::new(()); +// static FRESH_STATUS: FreshStatus = FreshStatus::None; + +fn set_fresh_status(status: FreshStatus) { + *FRESH_STATUS.write() = status; +} + +pub fn fresh_status() -> FreshStatus { + *FRESH_STATUS.read() +} + +#[cfg(not(feature = "update"))] +pub const UPDATE_IMG_BASE_ADDR: usize = 0x8a000000; +#[cfg(feature = "update")] +pub const UPDATE_IMG_BASE_ADDR: usize = 0x83000000; + +#[repr(C)] +pub struct HypervisorAddr { + cpu_id: usize, + vm_list: usize, + vm_config_table: usize, + vcpu_list: usize, + cpu: usize, + emu_dev_list: usize, + interrupt_hyper_bitmap: usize, + interrupt_glb_bitmap: usize, + interrupt_en_set: usize, + interrupt_handlers: usize, + vm_region: usize, + heap_region: usize, + vm_if_list: usize, + gic_lrs_num: usize, + // address for ipi + cpu_if_list: usize, + ipi_handler_list: usize, + // arch time + time_freq: usize, + time_slice: usize, + // mediated blk + mediated_blk_list: usize, + // async task + async_exe_status: usize, + async_ipi_task_list: usize, + async_io_task_list: usize, + async_used_info_list: usize, + // shared mem + shared_mem_list: usize, + // smmu_v2 + smmu_v2: usize, +} + +pub fn hyper_fresh_ipi_handler(_msg: &IpiMessage) { + update_request(); +} + +pub fn update_request() { + // println!("Src Hypervisor Core[{}] send update request", current_cpu().id); + extern "C" { + pub fn update_request(address_list: &HypervisorAddr, alloc: bool); + } + // VM_STATE_FLAG UNILIB_FS_LIST SYSTEM_FDT + let vm_config_table = &DEF_VM_CONFIG_TABLE as *const _ as usize; + let emu_dev_list = &EMU_DEVS_LIST as *const _ as usize; + let interrupt_hyper_bitmap = &INTERRUPT_HYPER_BITMAP as *const _ as usize; + let interrupt_glb_bitmap = &INTERRUPT_GLB_BITMAP as *const _ as usize; + let interrupt_en_set = &INTERRUPT_EN_SET as *const _ as usize; + let interrupt_handlers = &INTERRUPT_HANDLERS as *const _ as usize; + let vm_region = &VM_REGION as *const _ as usize; + let heap_region = &HEAP_REGION as *const _ as usize; + let vm_list = &VM_LIST as *const _ as usize; + let vm_if_list = &VM_IF_LIST as *const _ as usize; + let vcpu_list = &VCPU_LIST as *const _ as usize; + let cpu = unsafe { &CPU as *const _ as usize }; + let cpu_if_list = &CPU_IF_LIST as *const _ as usize; + let gic_lrs_num = &GIC_LRS_NUM as *const _ as usize; + let ipi_handler_list = &IPI_HANDLER_LIST as *const _ as usize; + let time_freq = &TIMER_FREQ as *const _ as usize; + let time_slice = &TIMER_SLICE as *const _ as usize; + let mediated_blk_list = &MEDIATED_BLK_LIST as *const _ as usize; + let async_exe_status = &ASYNC_EXE_STATUS as *const _ as usize; + let async_ipi_task_list = &ASYNC_IPI_TASK_LIST as *const _ as usize; + let async_io_task_list = &ASYNC_IO_TASK_LIST as *const _ as usize; + let async_used_info_list = &ASYNC_USED_INFO_LIST as *const _ as usize; + let shared_mem_list = &SHARE_MEM_LIST as *const _ as usize; + let smmu_v2 = &SMMU_V2 as *const _ as usize; + + let addr_list = HypervisorAddr { + cpu_id: current_cpu().id, + vm_config_table, + emu_dev_list, + interrupt_hyper_bitmap, + interrupt_glb_bitmap, + interrupt_en_set, + interrupt_handlers, + vm_region, + heap_region, + vm_list, + vm_if_list, + vcpu_list, + cpu, + cpu_if_list, + gic_lrs_num, + ipi_handler_list, + time_freq, + time_slice, + mediated_blk_list, + async_exe_status, + async_ipi_task_list, + async_io_task_list, + async_used_info_list, + shared_mem_list, + smmu_v2, + }; + if current_cpu().id == 0 { + unsafe { + update_request(&addr_list, true); + } + for cpu_id in 0..PLAT_DESC.cpu_desc.num { + if cpu_id != current_cpu().id { + ipi_send_msg(cpu_id, IpiType::IpiTHyperFresh, IpiInnerMsg::HyperFreshMsg()); + } + } + } + unsafe { + update_request(&addr_list, false); + } +} + +#[no_mangle] +pub extern "C" fn rust_shyper_update(address_list: &HypervisorAddr, alloc: bool) { + // TODO: vm0_dtb? + // let mut time0 = 0; + // let mut time1 = 0; + if alloc { + // cpu id is 0 + heap_init(); + mem_heap_region_init(); + // alloc and pre_copy + unsafe { + // DEF_VM_CONFIG_TABLE + let vm_config_table = &*(address_list.vm_config_table as *const Mutex); + vm_config_table_update(vm_config_table); + + // VM_LIST + let vm_list = &*(address_list.vm_list as *const Mutex>); + vm_list_alloc(vm_list); + + // VCPU_LIST + let vcpu_list = &*(address_list.vcpu_list as *const Mutex>); + vcpu_list_alloc(vcpu_list); + + // CPU_IF + let cpu_if = &*(address_list.cpu_if_list as *const Mutex>); + cpu_if_alloc(cpu_if); + + // IPI_HANDLER_LIST + let ipi_handler_list = &*(address_list.ipi_handler_list as *const Mutex>); + ipi_handler_list_update(ipi_handler_list); + + // TIMER_FREQ & TIMER_SLICE + let time_freq = &*(address_list.time_freq as *const Mutex); + let time_slice = &*(address_list.time_slice as *const Mutex); + arch_time_update(time_freq, time_slice); + + // INTERRUPT_HYPER_BITMAP, INTERRUPT_GLB_BITMAP, INTERRUPT_HANDLERS + let interrupt_hyper_bitmap = &*(address_list.interrupt_hyper_bitmap as *const Mutex>); + let interrupt_glb_bitmap = &*(address_list.interrupt_glb_bitmap as *const Mutex>); + let interrutp_en_set = &*(address_list.interrupt_en_set as *const Mutex>); + let interrupt_handlers = + &*(address_list.interrupt_handlers as *const Mutex>); + interrupt_update( + interrupt_hyper_bitmap, + interrupt_glb_bitmap, + interrutp_en_set, + interrupt_handlers, + ); + + // EMU_DEVS_LIST + let emu_dev_list = &*(address_list.emu_dev_list as *const Mutex>); + emu_dev_list_update(emu_dev_list); + + // GIC_LRS_NUM + let gic_lrs_num = &*(address_list.gic_lrs_num as *const Mutex); + gic_lrs_num_update(gic_lrs_num); + } + println!("Finish Alloc VM / VCPU / CPU_IF"); + return; + } + + if address_list.cpu_id == 0 { + let lock0 = FRESH_LOGIC_LOCK.lock(); + let lock1 = FRESH_IRQ_LOGIC_LOCK.lock(); + // set_fresh_status(FreshStatus::Start); + unsafe { + // VM_LIST + let time0 = time_current_us(); + let vm_list = &*(address_list.vm_list as *const Mutex>); + vm_list_update(vm_list); + set_fresh_status(FreshStatus::FreshVM); + let time1 = time_current_us(); + + // VCPU_LIST (add vgic) + let vcpu_list = &*(address_list.vcpu_list as *const Mutex>); + vcpu_update(vcpu_list, vm_list); + let time2 = time_current_us(); + drop(lock1); + set_fresh_status(FreshStatus::FreshVCPU); + let time3 = time_current_us(); + + // CPU: Must update after vcpu and vm + let cpu = &*(address_list.cpu as *const Cpu); + current_cpu_update(cpu); + + // VM_REGION + let vm_region = &*(address_list.vm_region as *const Mutex); + vm_region_update(vm_region); + + // HEAP_REGION + let heap_region = &*(address_list.heap_region as *const Mutex); + heap_region_update(heap_region); + + // VM_IF_LIST + let vm_if_list = &*(address_list.vm_if_list as *const [Mutex; VM_NUM_MAX]); + vm_if_list_update(vm_if_list); + + // MEDIATED_BLK_LIST + let mediated_blk_list = &*(address_list.mediated_blk_list as *const Mutex>); + mediated_blk_list_update(mediated_blk_list); + + // SHARED_MEM_LIST + let shared_mem_list = &*(address_list.shared_mem_list as *const Mutex>); + shared_mem_list_update(shared_mem_list); + + // cpu_if_list + let cpu_if = &*(address_list.cpu_if_list as *const Mutex>); + cpu_if_update(cpu_if); + + // ASYNC_EXE_STATUS、ASYNC_IPI_TASK_LIST、ASYNC_IO_TASK_LIST、ASYNC_USED_INFO_LIST + let async_exe_status = &*(address_list.async_exe_status as *const Mutex); + let async_ipi_task_list = &*(address_list.async_ipi_task_list as *const Mutex>); + let async_io_task_list = &*(address_list.async_io_task_list as *const Mutex>); + let async_used_info_list = + &*(address_list.async_used_info_list as *const Mutex>>); + async_task_update( + async_exe_status, + async_ipi_task_list, + async_io_task_list, + async_used_info_list, + ); + + // SMMU_V2 + let smmu_v2 = &*(address_list.smmu_v2 as *const Mutex); + smmu_update(smmu_v2); + // LOGGER + let _ = logger_init(); + set_fresh_status(FreshStatus::Finish); + drop(lock0); + println!( + "handle VM {} us, handle VCPU {} us, free lock {} us", + time1 - time0, + time2 - time1, + time3 - time2 + ); + println!("Finish Update VM and VCPU_LIST"); + println!("Update CPU[{}]", cpu.id); + println!("Update {} region for VM_REGION", VM_REGION.lock().region.len()); + println!("Update HEAP_REGION"); + println!("Update VM_IF_LIST"); + println!("Update {} Mediated BLK", MEDIATED_BLK_LIST.lock().len()); + println!("Update {} SHARE_MEM_LIST", SHARE_MEM_LIST.lock().len()); + println!("Update CPU_IF_LIST"); + } + } else { + let cpu = unsafe { &*(address_list.cpu as *const Cpu) }; + // let time0 = time_current_us(); + // CPU: Must update after vcpu and vm alloc + current_cpu_update(cpu); + // let time1 = time_current_us(); + // println!("Update CPU[{}], time {}us", cpu.id, time1 - time0); + } + // barrier(); + // if current_cpu().id != 0 { + // println!("Core[{}] handle time {}", current_cpu().id, time1 - time0,); + // } + fresh_hyper(); +} + +pub fn fresh_hyper() { + extern "C" { + pub fn fresh_cpu(); + pub fn fresh_hyper(ctx: usize); + } + if current_cpu().id == 0 { + let ctx = current_cpu().ctx.unwrap(); + println!("CPU[{}] ctx {:x}", current_cpu().id, ctx); + current_cpu().clear_ctx(); + unsafe { fresh_hyper(ctx) }; + } else { + match current_cpu().cpu_state { + CpuState::CpuInv => { + panic!("Core[{}] state {:#?}", current_cpu().id, CpuState::CpuInv); + } + CpuState::CpuIdle => { + println!("Core[{}] state {:#?}", current_cpu().id, CpuState::CpuIdle); + unsafe { fresh_cpu() }; + // println!( + // "Core[{}] current cpu irq {}", + // current_cpu().id, + // current_cpu().current_irq + // ); + gicc_clear_current_irq(true); + cpu_idle(); + } + CpuState::CpuRun => { + println!("Core[{}] state {:#?}", current_cpu().id, CpuState::CpuRun); + // println!( + // "Core[{}] current cpu irq {}", + // current_cpu().id, + // current_cpu().current_irq + // ); + gicc_clear_current_irq(true); + let ctx = current_cpu().ctx.unwrap(); + current_cpu().clear_ctx(); + unsafe { fresh_hyper(ctx) }; + } + } + } +} + +pub fn shared_mem_list_update(src_shared_mem_list: &Mutex>) { + let mut shared_mem_list = SHARE_MEM_LIST.lock(); + for (key, val) in src_shared_mem_list.lock().iter() { + shared_mem_list.insert(*key, *val); + } +} + +pub fn async_task_update( + src_async_exe_status: &Mutex, + src_async_ipi_task_list: &Mutex>, + src_async_io_task_list: &Mutex>, + src_async_used_info_list: &Mutex>>, +) { + let mut async_exe_status = ASYNC_EXE_STATUS.lock(); + let mut async_ipi_task_list = ASYNC_IPI_TASK_LIST.lock(); + let mut async_io_task_list = ASYNC_IO_TASK_LIST.lock(); + let mut async_used_info_list = ASYNC_USED_INFO_LIST.lock(); + assert_eq!(async_ipi_task_list.len(), 0); + assert_eq!(async_io_task_list.len(), 0); + assert_eq!(async_used_info_list.len(), 0); + *async_exe_status = *src_async_exe_status.lock(); + for ipi_task in src_async_ipi_task_list.lock().iter() { + let vm_id = ipi_task.src_vmid; + let vm = vm(vm_id).unwrap(); + let task_data = match &ipi_task.task_data { + AsyncTaskData::AsyncIpiTask(mediated_msg) => { + assert_eq!(mediated_msg.src_id, vm_id); + let mmio_id = mediated_msg.blk.id(); + let vq_idx = mediated_msg.vq.vq_indx(); + match vm.emu_dev(mmio_id) { + EmuDevs::VirtioBlk(blk) => { + let new_vq = blk.vq(vq_idx).clone().unwrap(); + AsyncTaskData::AsyncIpiTask(IpiMediatedMsg { + src_id: vm_id, + vq: new_vq.clone(), + blk: blk.clone(), + }) + } + _ => panic!("illegal mmio dev type in async_task_update"), + } + } + AsyncTaskData::AsyncIoTask(_) => panic!("Find an IO Task in IPI task list"), + AsyncTaskData::AsyncNoneTask(_) => panic!("Find an IO None Task in IPI task list"), + }; + async_ipi_task_list.push_back(AsyncTask { + task_data, + src_vmid: vm_id, + state: Arc::new(Mutex::new(*ipi_task.state.lock())), + // task: Arc::new(Mutex::new(Box::pin(async_ipi_req()))), + task: async_ipi_req, + }) + } + // for io_task in src_async_io_task_list.lock().iter() { + while !src_async_io_task_list.lock().is_empty() { + let io_task = src_async_io_task_list.lock().pop_front().unwrap(); + let vm_id = io_task.src_vmid; + let vm = vm(vm_id).unwrap(); + let task_data = match &io_task.task_data { + AsyncTaskData::AsyncIpiTask(_) => panic!("Find an IPI Task in IO task list"), + AsyncTaskData::AsyncIoTask(io_msg) => { + assert_eq!(vm_id, io_msg.src_vmid); + let vq_idx = io_msg.vq.vq_indx(); + match vm.emu_blk_dev() { + EmuDevs::VirtioBlk(blk) => { + let new_vq = blk.vq(vq_idx).clone().unwrap(); + AsyncTaskData::AsyncIoTask(IoAsyncMsg { + src_vmid: vm_id, + vq: new_vq.clone(), + dev: blk.clone(), + io_type: io_msg.io_type, + blk_id: io_msg.blk_id, + sector: io_msg.sector, + count: io_msg.count, + cache: io_msg.cache, + iov_list: Arc::new({ + let mut list = vec![]; + for iov in io_msg.iov_list.iter() { + list.push(BlkIov { + data_bg: iov.data_bg, + len: iov.len, + }); + } + list + }), + }) + } + _ => panic!("illegal mmio dev type in async_task_update"), + } + } + _ => { + todo!() + } + }; + async_io_task_list.push_back(AsyncTask { + task_data, + src_vmid: vm_id, + state: Arc::new(Mutex::new(*io_task.state.lock())), + // task: Arc::new(Mutex::new(Box::pin(async_blk_io_req()))), + task: async_blk_io_req, + }); + } + for (key, used_info) in src_async_used_info_list.lock().iter() { + let mut new_used_info = LinkedList::new(); + for info in used_info.iter() { + new_used_info.push_back(UsedInfo { + desc_chain_head_idx: info.desc_chain_head_idx, + used_len: info.used_len, + }); + } + async_used_info_list.insert(*key, new_used_info); + } + // println!("Update {} ipi task for ASYNC_IPI_TASK_LIST", async_ipi_task_list.len()); + // println!("Update {} io task for ASYNC_IO_TASK_LIST", async_io_task_list.len()); + // println!( + // "Update {} used info for ASYNC_USED_INFO_LIST", + // async_used_info_list.len() + // ); +} + +pub fn mediated_blk_list_update(src_mediated_blk_list: &Mutex>) { + let mut mediated_blk_list = MEDIATED_BLK_LIST.lock(); + assert_eq!(mediated_blk_list.len(), 0); + mediated_blk_list.clear(); + for blk in src_mediated_blk_list.lock().iter() { + mediated_blk_list.push(MediatedBlk { + base_addr: blk.base_addr, + avail: blk.avail, + }); + } +} + +pub fn arch_time_update(src_time_freq: &Mutex, src_time_slice: &Mutex) { + *TIMER_FREQ.lock() = *src_time_freq.lock(); + *TIMER_SLICE.lock() = *src_time_slice.lock(); +} + +pub fn cpu_if_alloc(src_cpu_if: &Mutex>) { + let mut cpu_if_list = CPU_IF_LIST.lock(); + for _ in 0..src_cpu_if.lock().len() { + cpu_if_list.push(CpuIf::default()); + } +} + +pub fn cpu_if_update(src_cpu_if: &Mutex>) { + let mut cpu_if_list = CPU_IF_LIST.lock(); + assert_eq!(cpu_if_list.len(), src_cpu_if.lock().len()); + for (idx, cpu_if) in src_cpu_if.lock().iter().enumerate() { + for (msg_idx, msg) in cpu_if.msg_queue.iter().enumerate() { + // Copy ipi msg + let new_ipi_msg = match msg.ipi_message.clone() { + IpiInnerMsg::Initc(initc) => IpiInnerMsg::Initc(initc), + IpiInnerMsg::Power(power) => IpiInnerMsg::Power(power), + IpiInnerMsg::EnternetMsg(eth_msg) => IpiInnerMsg::EnternetMsg(eth_msg), + IpiInnerMsg::VmmMsg(vmm_msg) => IpiInnerMsg::VmmMsg(vmm_msg), + IpiInnerMsg::MediatedMsg(mediated_msg) => { + let mmio_id = mediated_msg.blk.id(); + let vm_id = mediated_msg.src_id; + let vq_idx = mediated_msg.vq.vq_indx(); + + let vm = vm(vm_id).unwrap(); + match vm.emu_dev(mmio_id) { + EmuDevs::VirtioBlk(blk) => { + let new_vq = blk.vq(vq_idx).clone().unwrap(); + IpiInnerMsg::MediatedMsg(IpiMediatedMsg { + src_id: vm_id, + vq: new_vq.clone(), + blk: blk.clone(), + }) + } + _ => { + panic!("illegal mmio dev type in cpu_if_update"); + } + } + } + IpiInnerMsg::MediatedNotifyMsg(notify_msg) => IpiInnerMsg::MediatedNotifyMsg(notify_msg), + IpiInnerMsg::HvcMsg(hvc_msg) => IpiInnerMsg::HvcMsg(hvc_msg), + IpiInnerMsg::IntInjectMsg(inject_msg) => IpiInnerMsg::IntInjectMsg(inject_msg), + IpiInnerMsg::HyperFreshMsg() => IpiInnerMsg::HyperFreshMsg(), + IpiInnerMsg::None => IpiInnerMsg::None, + }; + cpu_if_list[idx].msg_queue.insert( + msg_idx, + IpiMessage { + ipi_type: msg.ipi_type, + ipi_message: new_ipi_msg, + }, + ); + } + // println!( + // "Update {} ipi msg for CpuIf[{}], after update len is {}", + // cpu_if.msg_queue.len(), + // idx, + // cpu_if_list[idx].msg_queue.len() + // ); + } +} + +pub fn ipi_handler_list_update(src_ipi_handler_list: &Mutex>) { + for ipi_handler in src_ipi_handler_list.lock().iter() { + let handler = match ipi_handler.ipi_type { + IpiType::IpiTIntc => vgic_ipi_handler, + IpiType::IpiTPower => psci_ipi_handler, + IpiType::IpiTEthernetMsg => ethernet_ipi_rev_handler, + IpiType::IpiTHvc => hvc_ipi_handler, + IpiType::IpiTVMM => vmm_ipi_handler, + IpiType::IpiTMediatedDev => mediated_ipi_handler, + IpiType::IpiTIntInject => interrupt_inject_ipi_handler, + IpiType::IpiTHyperFresh => hyper_fresh_ipi_handler, + }; + ipi_register(ipi_handler.ipi_type, handler); + } + println!("Update IPI_HANDLER_LIST"); +} + +pub fn vm_if_list_update(src_vm_if_list: &[Mutex; VM_NUM_MAX]) { + for (idx, vm_if_lock) in src_vm_if_list.iter().enumerate() { + let vm_if = vm_if_lock.lock(); + let mut cur_vm_if = VM_IF_LIST[idx].lock(); + cur_vm_if.master_cpu_id = vm_if.master_cpu_id; + cur_vm_if.state = vm_if.state; + cur_vm_if.vm_type = vm_if.vm_type; + cur_vm_if.mac = vm_if.mac; + cur_vm_if.ivc_arg = vm_if.ivc_arg; + cur_vm_if.ivc_arg_ptr = vm_if.ivc_arg_ptr; + cur_vm_if.mem_map = match &vm_if.mem_map { + None => None, + Some(mem_map) => Some(FlexBitmap { + len: mem_map.len, + map: { + let mut map = vec![]; + for v in mem_map.map.iter() { + map.push(*v); + } + map + }, + }), + }; + cur_vm_if.mem_map_cache = match &vm_if.mem_map_cache { + None => None, + Some(cache) => Some(Arc::new(PageFrame::new(cache.pa, cache.page_num))), + }; + } +} + +pub fn current_cpu_update(src_cpu: &Cpu) { + let cpu = current_cpu(); + // only need to alloc a new VcpuPool from heap, other props all map at 0x400000000 + // current_cpu().sched = src_cpu.sched; + match &src_cpu.sched { + SchedType::SchedRR(rr) => { + cpu.sched = SchedType::SchedRR(rr.update()); + } + SchedType::None => { + cpu.sched = SchedType::None; + } + } + + assert_eq!(cpu.id, src_cpu.id); + assert_eq!(cpu.ctx, src_cpu.ctx); + assert_eq!(cpu.cpu_state, src_cpu.cpu_state); + assert_eq!(cpu.current_irq, src_cpu.current_irq); + assert_eq!(cpu.cpu_pt, src_cpu.cpu_pt); + assert_eq!(cpu.stack, src_cpu.stack); + println!("Update CPU[{}]", cpu.id); +} + +pub fn gic_lrs_num_update(src_gic_lrs_num: &Mutex) { + let gic_lrs_num = *src_gic_lrs_num.lock(); + *GIC_LRS_NUM.lock() = gic_lrs_num; + println!("Update GIC_LRS_NUM"); +} + +// alloc vm_list +pub fn vm_list_alloc(src_vm_list: &Mutex>) { + let mut vm_list = VM_LIST.lock(); + for vm in src_vm_list.lock().iter() { + let new_vm = Vm::new(vm.id()); + vm_list.push(new_vm.clone()); + let mut dst_inner = new_vm.inner.lock(); + let src_inner = vm.inner.lock(); + let pt = match &src_inner.pt { + None => None, + Some(page_table) => { + let new_page_table = PageTable { + directory: Arc::new(PageFrame::new(page_table.directory.pa, page_table.directory.page_num)), + pages: Arc::new(Mutex::new(vec![])), + }; + for page in page_table.pages.lock().iter() { + new_page_table.pages.lock().push(PageFrame::new(page.pa, page.page_num)); + } + Some(new_page_table) + } + }; + dst_inner.ready = src_inner.ready; + dst_inner.config = vm_cfg_entry(src_inner.id); + dst_inner.pt = pt; + dst_inner.mem_region_num = src_inner.mem_region_num; + dst_inner.pa_region = { + let mut pa_region = vec![]; + for region in src_inner.pa_region.iter() { + pa_region.push(*region); + } + pa_region + }; + dst_inner.entry_point = src_inner.entry_point; + dst_inner.has_master = src_inner.has_master; + dst_inner.cpu_num = src_inner.cpu_num; + dst_inner.ncpu = src_inner.ncpu; + dst_inner.intc_dev_id = src_inner.intc_dev_id; + dst_inner.int_bitmap = src_inner.int_bitmap; + dst_inner.share_mem_base = src_inner.share_mem_base; + dst_inner.migrate_save_pf = { + let mut pf = vec![]; + for page in src_inner.migrate_save_pf.iter() { + pf.push(PageFrame::new(page.pa, page.page_num)); + } + pf + }; + dst_inner.migrate_restore_pf = { + let mut pf = vec![]; + for page in src_inner.migrate_restore_pf.iter() { + pf.push(PageFrame::new(page.pa, page.page_num)); + } + pf + }; + dst_inner.med_blk_id = src_inner.med_blk_id; + } + assert_eq!(vm_list.len(), src_vm_list.lock().len()); + println!("Alloc {} VM in VM_LIST", vm_list.len()); +} + +// Set vm.vcpu_list in vcpu_update +pub fn vm_list_update(src_vm_list: &Mutex>) { + // let mut vm_list = VM_LIST.lock(); + assert_eq!(VM_LIST.lock().len(), src_vm_list.lock().len()); + // vm_list.clear(); + // drop(vm_list); + for (idx, vm) in src_vm_list.lock().iter().enumerate() { + let emu_devs = { + let mut emu_devs = vec![]; + // drop(old_inner); + let old_emu_devs = vm.inner.lock().emu_devs.clone(); + for dev in old_emu_devs.iter() { + // TODO: wip + let new_dev = match dev { + EmuDevs::Vgic(_) => { + // set vgic after vcpu update + EmuDevs::None + } + EmuDevs::VirtioBlk(blk) => { + let mmio = VirtioMmio::new(0); + assert_eq!( + (blk.vq(0).unwrap().desc_table()), + vm_ipa2pa(vm.clone(), blk.vq(0).unwrap().desc_table_addr()) + ); + assert_eq!( + (blk.vq(0).unwrap().used()), + vm_ipa2pa(vm.clone(), blk.vq(0).unwrap().used_addr()) + ); + assert_eq!( + (blk.vq(0).unwrap().avail()), + vm_ipa2pa(vm.clone(), blk.vq(0).unwrap().avail_addr()) + ); + mmio.save_mmio( + blk.clone(), + if blk.dev().mediated() { + Some(virtio_mediated_blk_notify_handler) + } else { + Some(virtio_blk_notify_handler) + }, + ); + EmuDevs::VirtioBlk(mmio) + } + EmuDevs::VirtioNet(net) => { + let mmio = VirtioMmio::new(0); + assert_eq!( + (net.vq(0).unwrap().desc_table()), + vm_ipa2pa(vm.clone(), net.vq(0).unwrap().desc_table_addr()) + ); + assert_eq!( + (net.vq(0).unwrap().used()), + vm_ipa2pa(vm.clone(), net.vq(0).unwrap().used_addr()) + ); + assert_eq!( + (net.vq(0).unwrap().avail()), + vm_ipa2pa(vm.clone(), net.vq(0).unwrap().avail_addr()) + ); + println!( + "VirtioNet save handler {:x}", + unsafe { *(&virtio_net_notify_handler as *const _ as *const usize) } + ); + mmio.save_mmio(net.clone(), Some(virtio_net_notify_handler)); + EmuDevs::VirtioNet(mmio) + } + EmuDevs::VirtioConsole(console) => { + let mmio = VirtioMmio::new(0); + assert_eq!( + (console.vq(0).unwrap().desc_table()), + vm_ipa2pa(vm.clone(), console.vq(0).unwrap().desc_table_addr()) + ); + assert_eq!( + (console.vq(0).unwrap().used()), + vm_ipa2pa(vm.clone(), console.vq(0).unwrap().used_addr()) + ); + assert_eq!( + (console.vq(0).unwrap().avail()), + vm_ipa2pa(vm.clone(), console.vq(0).unwrap().avail_addr()) + ); + println!( + "VirtioConsole save handler {:x}", + unsafe { *(&virtio_console_notify_handler as *const _ as *const usize) } + ); + mmio.save_mmio(console.clone(), Some(virtio_console_notify_handler)); + EmuDevs::VirtioConsole(mmio) + } + EmuDevs::None => EmuDevs::None, + }; + emu_devs.push(new_dev); + } + emu_devs + }; + let dst_vm = VM_LIST.lock()[idx].clone(); + let mut dst_inner = dst_vm.inner.lock(); + let src_inner = vm.inner.lock(); + assert_eq!(dst_inner.id, src_inner.id); + dst_inner.emu_devs = emu_devs; + } + // println!("Update VM_LIST"); +} + +pub fn heap_region_update(src_heap_region: &Mutex) { + let mut heap_region = HEAP_REGION.lock(); + let src_region = src_heap_region.lock(); + heap_region.map = src_region.map; + heap_region.region = src_region.region; + assert_eq!(heap_region.region, src_region.region); +} + +pub fn vm_region_update(src_vm_region: &Mutex) { + let mut vm_region = VM_REGION.lock(); + assert_eq!(vm_region.region.len(), 0); + vm_region.region.clear(); + for mem_region in src_vm_region.lock().region.iter() { + vm_region.region.push(*mem_region); + } + assert_eq!(vm_region.region, src_vm_region.lock().region); +} + +pub fn interrupt_update( + src_hyper_bitmap: &Mutex>, + src_glb_bitmap: &Mutex>, + src_en_set: &Mutex>, + src_handlers: &Mutex>, +) { + let mut hyper_bitmap = INTERRUPT_HYPER_BITMAP.lock(); + *hyper_bitmap = *src_hyper_bitmap.lock(); + let mut glb_bitmap = INTERRUPT_GLB_BITMAP.lock(); + *glb_bitmap = *src_glb_bitmap.lock(); + let mut handlers = INTERRUPT_HANDLERS.lock(); + for (int_id, handler) in src_handlers.lock().iter() { + match handler { + InterruptHandler::IpiIrqHandler(_) => { + handlers.insert(*int_id, InterruptHandler::IpiIrqHandler(ipi_irq_handler)); + } + InterruptHandler::GicMaintenanceHandler(_) => { + handlers.insert( + *int_id, + InterruptHandler::GicMaintenanceHandler(gic_maintenance_handler), + ); + } + InterruptHandler::TimeIrqHandler(_) => { + handlers.insert(*int_id, InterruptHandler::TimeIrqHandler(timer_irq_handler)); + } + InterruptHandler::None => { + handlers.insert(*int_id, InterruptHandler::None); + } + } + } + let mut en_set = INTERRUPT_EN_SET.lock(); + (*en_set).extend(&*src_en_set.lock()); + println!("Update INTERRUPT_GLB_BITMAP / INTERRUPT_HYPER_BITMAP / INTERRUPT_EN_SET / INTERRUPT_HANDLERS"); +} + +pub fn emu_dev_list_update(src_emu_dev_list: &Mutex>) { + let mut emu_dev_list = EMU_DEVS_LIST.lock(); + assert_eq!(emu_dev_list.len(), 0); + emu_dev_list.clear(); + for emu_dev_entry in src_emu_dev_list.lock().iter() { + let emu_handler = match emu_dev_entry.emu_type { + EmuDeviceType::EmuDeviceTGicd => emu_intc_handler, + EmuDeviceType::EmuDeviceTGPPT => partial_passthrough_intc_handler, + EmuDeviceType::EmuDeviceTVirtioBlk => emu_virtio_mmio_handler, + EmuDeviceType::EmuDeviceTVirtioNet => emu_virtio_mmio_handler, + EmuDeviceType::EmuDeviceTVirtioConsole => emu_virtio_mmio_handler, + EmuDeviceType::EmuDeviceTIOMMU => emu_smmu_handler, + _ => { + panic!("not support emu dev entry type {}", emu_dev_entry.emu_type); + } + }; + emu_dev_list.push(EmuDevEntry { + emu_type: emu_dev_entry.emu_type, + vm_id: emu_dev_entry.vm_id, + id: emu_dev_entry.id, + ipa: emu_dev_entry.ipa, + size: emu_dev_entry.size, + handler: emu_handler, + }); + } + println!("Update {} emu dev for EMU_DEVS_LIST", emu_dev_list.len()); +} + +pub fn vm_config_table_update(src_vm_config_table: &Mutex) { + let mut vm_config_table = DEF_VM_CONFIG_TABLE.lock(); + let src_config_table = src_vm_config_table.lock(); + vm_config_table.name = src_config_table.name; + vm_config_table.vm_bitmap = src_config_table.vm_bitmap; + vm_config_table.vm_num = src_config_table.vm_num; + assert_eq!(vm_config_table.entries.len(), 0); + vm_config_table.entries.clear(); + for entry in src_config_table.entries.iter() { + let image = *entry.image.lock(); + let memory = VmMemoryConfig { + region: { + let mut region = vec![]; + for mem in entry.memory.lock().region.iter() { + region.push(*mem); + } + assert_eq!(region, entry.memory.lock().region); + region + }, + }; + let cpu = *entry.cpu.lock(); + // emu dev config + let mut vm_emu_dev_confg = VmEmulatedDeviceConfigList { emu_dev_list: vec![] }; + let src_emu_dev_confg_list = entry.vm_emu_dev_confg.lock(); + for emu_config in &src_emu_dev_confg_list.emu_dev_list { + vm_emu_dev_confg.emu_dev_list.push(VmEmulatedDeviceConfig { + name: Some(String::from(emu_config.name.as_ref().unwrap())), + base_ipa: emu_config.base_ipa, + length: emu_config.length, + irq_id: emu_config.irq_id, + cfg_list: { + let mut cfg_list = vec![]; + for cfg in emu_config.cfg_list.iter() { + cfg_list.push(*cfg); + } + assert_eq!(cfg_list, emu_config.cfg_list); + cfg_list + }, + emu_type: emu_config.emu_type, + mediated: emu_config.mediated, + }) + } + // passthrough dev config + let src_pt = entry.vm_pt_dev_confg.lock(); + let mut vm_pt_dev_confg = VmPassthroughDeviceConfig { + regions: vec![], + irqs: vec![], + streams_ids: vec![], + }; + for region in src_pt.regions.iter() { + vm_pt_dev_confg.regions.push(*region); + } + for irq in src_pt.irqs.iter() { + vm_pt_dev_confg.irqs.push(*irq); + } + for streams_id in src_pt.streams_ids.iter() { + vm_pt_dev_confg.streams_ids.push(*streams_id); + } + assert_eq!(vm_pt_dev_confg.regions, src_pt.regions); + assert_eq!(vm_pt_dev_confg.irqs, src_pt.irqs); + assert_eq!(vm_pt_dev_confg.streams_ids, src_pt.streams_ids); + + // dtb config + let mut vm_dtb_devs = VMDtbDevConfigList { + dtb_device_list: vec![], + }; + let src_dtb_confg_list = entry.vm_dtb_devs.lock(); + for dtb_config in src_dtb_confg_list.dtb_device_list.iter() { + vm_dtb_devs.dtb_device_list.push(VmDtbDevConfig { + name: String::from(&dtb_config.name), + dev_type: dtb_config.dev_type, + irqs: { + let mut irqs = vec![]; + for irq in dtb_config.irqs.iter() { + irqs.push(*irq); + } + assert_eq!(irqs, dtb_config.irqs); + irqs + }, + addr_region: dtb_config.addr_region, + }); + } + + vm_config_table.entries.push(VmConfigEntry { + id: entry.id, + name: Some(String::from(entry.name.as_ref().unwrap())), + os_type: entry.os_type, + cmdline: String::from(&entry.cmdline), + image: Arc::new(Mutex::new(image)), + memory: Arc::new(Mutex::new(memory)), + cpu: Arc::new(Mutex::new(cpu)), + vm_emu_dev_confg: Arc::new(Mutex::new(vm_emu_dev_confg)), + vm_pt_dev_confg: Arc::new(Mutex::new(vm_pt_dev_confg)), + vm_dtb_devs: Arc::new(Mutex::new(vm_dtb_devs)), + }); + } + assert_eq!(vm_config_table.entries.len(), src_config_table.entries.len()); + assert_eq!(vm_config_table.vm_num, src_config_table.vm_num); + assert_eq!(vm_config_table.vm_bitmap, src_config_table.vm_bitmap); + assert_eq!(vm_config_table.name, src_config_table.name); + println!("Update {} VM to DEF_VM_CONFIG_TABLE", vm_config_table.vm_num); +} + +pub fn vcpu_list_alloc(src_vcpu_list: &Mutex>) { + let mut vcpu_list = VCPU_LIST.lock(); + for vcpu in src_vcpu_list.lock().iter() { + let src_inner = vcpu.inner.lock(); + let src_vm_option = src_inner.vm.clone(); + let vm = match src_vm_option { + None => None, + Some(src_vm) => { + let vm_id = src_vm.id(); + vm(vm_id) + } + }; + let mut vcpu_inner = VcpuInner::default(); + vcpu_inner.vm = vm.clone(); + vcpu_inner.id = src_inner.id; + vcpu_inner.phys_id = src_inner.phys_id; + let vcpu = Vcpu { + inner: Arc::new(Mutex::new(vcpu_inner)), + }; + vm.unwrap().push_vcpu(vcpu.clone()); + vcpu_list.push(vcpu); + } + assert_eq!(vcpu_list.len(), src_vcpu_list.lock().len()); + println!("Alloc {} VCPU to VCPU_LIST", vcpu_list.len()); +} + +pub fn vcpu_update(src_vcpu_list: &Mutex>, src_vm_list: &Mutex>) { + let vcpu_list = VCPU_LIST.lock(); + // assert_eq!(vcpu_list.len(), src_vcpu_list.lock().len()); + for (idx, vcpu) in src_vcpu_list.lock().iter().enumerate() { + let src_inner = vcpu.inner.lock(); + let mut dst_inner = vcpu_list[idx].inner.lock(); + + // assert_eq!(dst_inner.id, src_inner.id); + // assert_eq!(dst_inner.phys_id, src_inner.phys_id); + dst_inner.state = src_inner.state; + dst_inner.int_list = { + let mut int_list = vec![]; + for int in src_inner.int_list.iter() { + int_list.push(*int); + } + int_list + }; + dst_inner.vcpu_ctx = src_inner.vcpu_ctx; + dst_inner.vm_ctx = src_inner.vm_ctx; + // assert_eq!(dst_inner.int_list, src_inner.int_list); + } + + // Add vgic emu dev for vm + for src_vm in src_vm_list.lock().iter() { + let src_vgic = src_vm.vgic(); + let new_vgic = Vgic::default(); + new_vgic.save_vgic(src_vgic.clone()); + + let vm = vm(src_vm.id()).unwrap(); + if let EmuDevs::None = vm.emu_dev(vm.intc_dev_id()) { + vm.set_emu_devs(vm.intc_dev_id(), EmuDevs::Vgic(Arc::new(new_vgic))); + } else { + panic!("illegal vgic emu dev idx in vm.emu_devs"); + } + } + // println!("Update {} Vcpu to VCPU_LIST", vcpu_list.len()); +} + +fn smmu_update(src_smmu_v2: &Mutex) { + let mut smmu_v2 = SMMU_V2.lock(); + let src_smmu = src_smmu_v2.lock(); + smmu_v2.glb_rs0 = src_smmu.glb_rs0; + smmu_v2.glb_rs1 = src_smmu.glb_rs1; + smmu_v2.context_s2_idx = src_smmu.context_s2_idx; + for ctx_bank in src_smmu.context_bank.iter() { + smmu_v2.context_bank.push(*ctx_bank); + } + smmu_v2.context_alloc_bitmap = match &src_smmu.context_alloc_bitmap { + Some(ctx_bitmap) => { + let mut bitmap = FlexBitmap::new(ctx_bitmap.len); + for v in ctx_bitmap.map.iter() { + bitmap.map.push(*v); + } + Some(bitmap) + } + None => None, + }; + + smmu_v2.smr_num = src_smmu.smr_num; + smmu_v2.smr_alloc_bitmap = match &src_smmu.smr_alloc_bitmap { + Some(smr_bitmap) => { + let mut bitmap = FlexBitmap::new(smr_bitmap.len); + for v in smr_bitmap.map.iter() { + bitmap.map.push(*v); + } + Some(bitmap) + } + None => None, + }; + smmu_v2.group_alloc_bitmap = match &src_smmu.group_alloc_bitmap { + Some(group_bitmap) => { + let mut bitmap = FlexBitmap::new(group_bitmap.len); + for v in group_bitmap.map.iter() { + bitmap.map.push(*v); + } + Some(bitmap) + } + None => None, + }; +} diff --git a/src/kernel/logger.rs b/src/kernel/logger.rs new file mode 100755 index 0000000000000000000000000000000000000000..ea79728e42686881cfd9a21b56290016dc038ea1 --- /dev/null +++ b/src/kernel/logger.rs @@ -0,0 +1,46 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use log::{Level, Metadata, Record}; +use log::{LevelFilter, SetLoggerError}; + +struct SimpleLogger; + +impl log::Log for SimpleLogger { + fn enabled(&self, _metadata: &Metadata) -> bool { + true + } + + fn log(&self, record: &Record) { + if self.enabled(record.metadata()) { + // let ms = crate::lib::timer::current_ms(); + // let s = ms / 1000; + // let ms = ms % 1000; + // print!("[{:04}.{:03}]", s, ms); + + let level = match record.level() { + Level::Error => "[E]", + Level::Warn => "[W]", + Level::Info => "[I]", + Level::Debug => "[D]", + Level::Trace => "[T]", + }; + println!("{}[{}] {}", level, record.target(), record.args()); + } + } + + fn flush(&self) {} +} + +static LOGGER: SimpleLogger = SimpleLogger; + +pub fn logger_init() -> Result<(), SetLoggerError> { + log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Trace)) +} diff --git a/src/kernel/mem.rs b/src/kernel/mem.rs new file mode 100644 index 0000000000000000000000000000000000000000..4e30e12d0fa53a8b9e564d00e1ee48aafe3c5e55 --- /dev/null +++ b/src/kernel/mem.rs @@ -0,0 +1,214 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::PAGE_SIZE; +use crate::board::*; +use crate::kernel::mem_shared_mem_init; +use crate::lib::{memset_safe, round_up}; +use crate::mm::PageFrame; + +use super::mem_region::*; + +use self::AllocError::*; + +pub const VM_MEM_REGION_MAX: usize = 4; + +pub fn mem_init() { + mem_heap_region_init(); + mem_vm_region_init(); + mem_shared_mem_init(); + println!("Mem init ok"); +} + +pub fn mem_heap_region_init() { + extern "C" { + // Note: link-time label, see aarch64.lds + fn _image_end(); + } + + if PLAT_DESC.mem_desc.region_num == 0 { + println!("Platform has no memory region!"); + } + + let base = round_up(_image_end as usize, PAGE_SIZE); + let size = round_up( + PLAT_DESC.mem_desc.regions[0].size as usize - (base - PLAT_DESC.mem_desc.base as usize), + PAGE_SIZE, + ) / PAGE_SIZE; + + println!("init memory, please waiting..."); + memset_safe(base as *mut u8, 0, size as usize * PAGE_SIZE); + // core::intrinsics::volatile_set_memory(ptr, 0, size as usize * PAGE_SIZE); + + let mut heap_lock = HEAP_REGION.lock(); + (*heap_lock).region_init(base, size, size, 0); + + drop(heap_lock); + + println!( + "Memory Heap: base 0x{:x}, size {} MB / {} pages", + base, + size * PAGE_SIZE / (1024 * 1024), + size + ); + println!("Memory Heap init ok"); +} + +/// Reserve Heap Memory from base_addr to base_addr + size +/// #Example +/// ``` +/// mem_heap_region_reserve(0x8a000000, 0x8000000); +/// ``` +pub fn mem_heap_region_reserve(base_addr: usize, size: usize) { + let mut heap = HEAP_REGION.lock(); + heap.reserve_pages(base_addr, round_up(size, PAGE_SIZE) / PAGE_SIZE); + println!( + "Reserve Heap Region 0x{:x} ~ 0x{:x}", + base_addr, + base_addr + round_up(size, PAGE_SIZE) + ); +} + +fn mem_vm_region_init() { + if PLAT_DESC.mem_desc.region_num - 1 > TOTAL_MEM_REGION_MAX { + panic!("Platform memory regions overrun!"); + } else if PLAT_DESC.mem_desc.region_num == 0 { + panic!("Platform Vm Memory Regions Overrun!"); + } + + if PLAT_DESC.mem_desc.region_num <= 1 { + panic!("Platform has no VM memory region!"); + } + + let mut pages: usize = 0; + let vm_region_num = PLAT_DESC.mem_desc.region_num - 1; + + for i in 0..vm_region_num { + let mut mem_region = MemRegion::new(); + mem_region.init( + PLAT_DESC.mem_desc.regions[i + 1].base, + PLAT_DESC.mem_desc.regions[i + 1].size / PAGE_SIZE, + PLAT_DESC.mem_desc.regions[i + 1].size / PAGE_SIZE, + 0, + ); + pages += PLAT_DESC.mem_desc.regions[i + 1].size / PAGE_SIZE; + + let mut vm_region_lock = VM_REGION.lock(); + (*vm_region_lock).push(mem_region); + } + + println!( + "Memory VM regions: total {} region, size {} MB / {} pages", + vm_region_num, + pages * PAGE_SIZE / (1024 * 1024), + pages + ); + println!("Memory VM regions init ok!"); +} + +#[derive(Debug)] +pub enum AllocError { + AllocZeroPage, + OutOfFrame, +} + +fn mem_heap_reset() { + let heap = HEAP_REGION.lock(); + memset_safe(heap.region.base as *mut u8, 0, heap.region.size * PAGE_SIZE); +} + +pub fn mem_heap_alloc(page_num: usize, _aligned: bool) -> Result { + if page_num == 0 { + return Err(AllocZeroPage); + } + + let mut heap = HEAP_REGION.lock(); + if page_num > heap.region.free { + return Err(OutOfFrame); + } + + heap.alloc_pages(page_num) +} + +pub fn mem_heap_free(addr: usize, page_num: usize) -> bool { + let mut heap = HEAP_REGION.lock(); + heap.free_pages(addr, page_num) +} + +pub fn mem_page_alloc() -> Result { + PageFrame::alloc_pages(1) +} + +pub fn mem_pages_alloc(page_num: usize) -> Result { + PageFrame::alloc_pages(page_num) +} + +pub fn mem_vm_region_alloc(size: usize) -> usize { + let mut vm_region = VM_REGION.lock(); + for i in 0..vm_region.region.len() { + if vm_region.region[i].free >= size / PAGE_SIZE { + let start_addr = vm_region.region[i].base; + let region_size = vm_region.region[i].size; + if vm_region.region[i].size > size / PAGE_SIZE { + vm_region.push(MemRegion { + base: start_addr + size, + size: region_size - size / PAGE_SIZE, + free: region_size - size / PAGE_SIZE, + last: 0, // never use in vm mem region + }); + vm_region.region[i].size = size / PAGE_SIZE; + } + vm_region.region[i].free = 0; + + return start_addr; + } + } + + 0 +} + +pub fn mem_vm_region_free(start: usize, size: usize) { + let mut vm_region = VM_REGION.lock(); + let mut free_idx = None; + // free mem region + for (idx, region) in vm_region.region.iter_mut().enumerate() { + if start == region.base && region.free == 0 { + region.free += size / PAGE_SIZE; + free_idx = Some(idx); + break; + } + } + // merge mem region + while free_idx.is_some() { + let merge_idx = free_idx.unwrap(); + let base = vm_region.region[merge_idx].base; + let size = vm_region.region[merge_idx].size; + free_idx = None; + for (idx, region) in vm_region.region.iter_mut().enumerate() { + if region.free != 0 && base == region.base + region.size * PAGE_SIZE { + // merge free region into curent region + region.size += size; + region.free += size; + free_idx = Some(if idx < merge_idx { idx } else { idx - 1 }); + vm_region.region.remove(merge_idx); + break; + } else if region.free != 0 && base + size * PAGE_SIZE == region.base { + // merge curent region into free region + let size = region.size; + vm_region.region[merge_idx].size += size; + vm_region.region[merge_idx].free += size; + free_idx = Some(if merge_idx < idx { merge_idx } else { merge_idx - 1 }); + vm_region.region.remove(idx); + break; + } + } + } + println!("Free mem from pa 0x{:x} to 0x{:x}", start, start + size); +} diff --git a/src/kernel/mem_region.rs b/src/kernel/mem_region.rs new file mode 100644 index 0000000000000000000000000000000000000000..24608ab6ead33202dd8693d7635139a33d57df42 --- /dev/null +++ b/src/kernel/mem_region.rs @@ -0,0 +1,175 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; + +use spin::Mutex; + +use crate::arch::PAGE_SIZE; +use crate::lib::{BitAlloc, BitAlloc4K, BitAlloc64K, BitMap}; +use crate::lib::memset_safe; + +use super::AllocError; + +const TOTAL_MEM_REGION_MAX: usize = 16; + +#[derive(Copy, Clone, Eq, Debug)] +pub struct MemRegion { + pub base: usize, + pub size: usize, + // bit + pub free: usize, + // bit + pub last: usize, // bit +} + +impl PartialEq for MemRegion { + fn eq(&self, other: &Self) -> bool { + self.base == other.base && self.size == other.size && self.free == other.free && self.last == other.last + } +} + +impl MemRegion { + pub const fn new() -> MemRegion { + MemRegion { + base: 0, + size: 0, + free: 0, + last: 0, + } + } + + pub fn init(&mut self, base: usize, size: usize, free: usize, last: usize) { + self.base = base; + self.size = size; + self.free = free; + self.last = last; + } +} + +pub struct HeapRegion { + pub map: BitMap, + pub region: MemRegion, +} + +impl HeapRegion { + pub fn region_init(&mut self, base: usize, size: usize, free: usize, last: usize) { + self.region.init(base, size, free, last); + } + + // base addr need to align to PAGE_SIZE + pub fn reserve_pages(&mut self, base: usize, size: usize) { + let offset = (base - self.region.base) / PAGE_SIZE; + for i in 0..size { + if self.map.get(offset + i) != 0 { + panic!("Heap Page 0x{:x} has been alloc", base + i * PAGE_SIZE); + } + self.map.set(offset + i); + } + } + + fn first_fit(&self, size: usize) -> Option { + if size <= 1 && self.map.get(self.region.last) == 0 { + Some(self.region.last) + } else { + let mut bit = None; + let mut count = 0; + for i in 0..self.region.size { + if self.map.get(i) == 0 { + count += 1; + if count >= size { + bit = Some(i + 1 - count); + break; + } + } else { + count = 0; + } + } + bit + } + } + + pub fn alloc_pages(&mut self, size: usize) -> Result { + let res = self.first_fit(size); + if res.is_none() { + println!( + "alloc_pages: allocate {} pages failed (heap_base 0x{:x} remain {} total {})", + size, self.region.base, self.region.free, self.region.size + ); + return Err(AllocError::OutOfFrame); + } + let bit = res.unwrap(); + + for i in bit..bit + size { + self.map.set(i); + } + self.region.free -= size; + if bit + size < self.region.size { + self.region.last = bit + size; + } else { + self.region.last = 0; + } + + let addr = self.region.base + bit * PAGE_SIZE; + memset_safe(addr as *mut u8, 0, size * PAGE_SIZE); + return Ok(addr); + } + + pub fn free_pages(&mut self, base: usize, size: usize) -> bool { + use crate::lib::range_in_range; + if !range_in_range(base, size * PAGE_SIZE, self.region.base, self.region.size * PAGE_SIZE) { + panic!( + "free_page: out of range (addr 0x{:x} page num {} heap base 0x{:x} heap size 0x{:x})", + base, + size, + self.region.base, + self.region.size * PAGE_SIZE + ); + // return false; + } + + let page_idx = (base - self.region.base) / PAGE_SIZE; + for idx in page_idx..page_idx + size { + self.map.clear(idx); + } + self.region.free += size; + self.region.last = page_idx; + return true; + } +} + +pub struct VmRegion { + pub region: Vec, +} + +impl VmRegion { + pub fn push(&mut self, region: MemRegion) { + self.region.push(region); + } +} + +pub static HEAP_REGION: Mutex = Mutex::new(HeapRegion { + map: BitAlloc64K::default(), + region: MemRegion::new(), +}); + +pub static VM_REGION: Mutex = Mutex::new(VmRegion { + region: Vec::::new(), +}); + +pub fn bits_to_pages(bits: usize) -> usize { + use crate::lib::round_up; + round_up(bits, PAGE_SIZE) +} + +pub fn pa_in_heap_region(pa: usize) -> bool { + let heap_region = HEAP_REGION.lock(); + pa > heap_region.region.base && pa < (heap_region.region.base * PAGE_SIZE + heap_region.region.size) +} diff --git a/src/kernel/migrate.rs b/src/kernel/migrate.rs new file mode 100644 index 0000000000000000000000000000000000000000..e4478ce7f4c7bbd04fd0e1d7d56a999bd50daebb --- /dev/null +++ b/src/kernel/migrate.rs @@ -0,0 +1,360 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::{ + Aarch64ContextFrame, GIC_LIST_REGS_NUM, GIC_PRIVINT_NUM, GIC_SGIS_NUM, GIC_SPI_MAX, GicContext, IrqState, + PAGE_SIZE, PTE_S2_FIELD_AP_RW, PTE_S2_NORMAL, PTE_S2_RO, Sgis, VmContext, +}; +use crate::arch::tlb_invalidate_guest_all; +use crate::board::PLATFORM_VCPU_NUM_MAX; +use crate::device::{EMU_DEV_NUM_MAX, EmuContext, VirtioDeviceType, VirtMmioRegs}; +use crate::kernel::{ + active_vm, get_share_mem, hvc_send_msg_to_vm, HVC_VMM, HVC_VMM_MIGRATE_START, HvcGuestMsg, HvcMigrateMsg, + mem_pages_alloc, MIGRATE_BITMAP, MIGRATE_COPY, MIGRATE_FINISH, MIGRATE_SEND, vm, Vm, vm_if_copy_mem_map, + vm_if_mem_map_cache, vm_if_mem_map_page_num, vm_if_set_mem_map, vm_if_set_mem_map_cache, +}; + +pub struct VMData { + pub vm_ctx: [VmContext; PLATFORM_VCPU_NUM_MAX], + pub vcpu_ctx: [Aarch64ContextFrame; PLATFORM_VCPU_NUM_MAX], + pub gic_ctx: [GicContext; PLATFORM_VCPU_NUM_MAX], + pub vgic_ctx: VgicMigData, + pub emu_devs: [EmuDevData; EMU_DEV_NUM_MAX], +} + +pub enum EmuDevData { + VirtioBlk(VirtioMmioData), + VirtioNet(VirtioMmioData), + VirtioConsole(VirtioMmioData), + None, +} + +// virtio vgic migration data +pub struct VgicMigData { + pub vgicd: VgicdData, + pub cpu_priv_num: usize, + pub cpu_priv: [VgicCpuPrivData; 4], +} + +impl VgicMigData { + pub fn default() -> VgicMigData { + VgicMigData { + vgicd: VgicdData::default(), + cpu_priv_num: 0, + cpu_priv: [VgicCpuPrivData::default(); 4], // TODO: 4 is hardcode for vm cpu num max + } + } +} + +pub struct VgicdData { + pub ctlr: u32, + pub typer: u32, + pub iidr: u32, + pub interrupts: [VgicIntData; GIC_SPI_MAX], +} + +impl VgicdData { + pub fn default() -> VgicdData { + VgicdData { + ctlr: 0, + typer: 0, + iidr: 0, + interrupts: [VgicIntData::default(); GIC_SPI_MAX], + } + } +} + +#[derive(Copy, Clone)] +pub struct VgicCpuPrivData { + pub curr_lrs: [u16; GIC_LIST_REGS_NUM], + pub sgis: [Sgis; GIC_SGIS_NUM], + pub interrupts: [VgicIntData; GIC_PRIVINT_NUM], + pub pend_num: usize, + pub pend_list: [usize; 16], + // TODO: 16 is hard code + pub act_num: usize, + pub act_list: [usize; 16], +} + +impl VgicCpuPrivData { + pub fn default() -> VgicCpuPrivData { + VgicCpuPrivData { + curr_lrs: [0; GIC_LIST_REGS_NUM], + sgis: [Sgis { pend: 0, act: 0 }; GIC_SGIS_NUM], + interrupts: [VgicIntData::default(); GIC_PRIVINT_NUM], + pend_num: 0, + pend_list: [0; 16], + act_num: 0, + act_list: [0; 16], + } + } +} + +#[derive(Copy, Clone)] +pub struct VgicIntData { + pub owner: Option, + // vcpu_id + pub id: u16, + pub hw: bool, + pub in_lr: bool, + pub lr: u16, + pub enabled: bool, + pub state: IrqState, + pub prio: u8, + pub targets: u8, + pub cfg: u8, + + pub in_pend: bool, + pub in_act: bool, +} + +impl VgicIntData { + pub fn default() -> VgicIntData { + VgicIntData { + owner: None, + id: 0, + hw: false, + in_lr: false, + lr: 0, + enabled: false, + state: IrqState::IrqSInactive, + prio: 0, + targets: 0, + cfg: 0, + in_pend: false, + in_act: false, + } + } +} + +// virtio mmio migration data +pub struct VirtioMmioData { + pub id: usize, + pub driver_features: usize, + pub driver_status: usize, + pub regs: VirtMmioRegs, + pub dev: VirtDevData, + pub oppo_dev: VirtDevData, + pub vq: [VirtqData; 4], // TODO: 4 is hard code for vq max len +} + +impl VirtioMmioData { + pub fn default() -> VirtioMmioData { + VirtioMmioData { + id: 0, + driver_features: 0, + driver_status: 0, + regs: VirtMmioRegs::default(), + dev: VirtDevData::default(), + oppo_dev: VirtDevData::default(), + vq: [VirtqData::default(); 4], + } + } +} + +#[derive(Copy, Clone)] +pub struct VirtqData { + pub ready: usize, + pub vq_index: usize, + pub num: usize, + + pub last_avail_idx: u16, + pub last_used_idx: u16, + pub used_flags: u16, + + pub desc_table_ipa: usize, + pub avail_ipa: usize, + pub used_ipa: usize, +} + +impl VirtqData { + pub fn default() -> VirtqData { + VirtqData { + ready: 0, + vq_index: 0, + num: 0, + last_avail_idx: 0, + last_used_idx: 0, + used_flags: 0, + desc_table_ipa: 0, + avail_ipa: 0, + used_ipa: 0, + } + } +} + +pub struct VirtDevData { + pub activated: bool, + pub dev_type: VirtioDeviceType, + pub features: usize, + pub generation: usize, + pub int_id: usize, + pub desc: DevDescData, + // req: reserve; we used nfs, no need to mig blk req data + // cache: reserve + // stat: reserve +} + +impl VirtDevData { + pub fn default() -> VirtDevData { + VirtDevData { + activated: false, + dev_type: VirtioDeviceType::None, + features: 0, + generation: 0, + int_id: 0, + desc: DevDescData::None, + } + } +} + +pub enum DevDescData { + // reserve blk desc + BlkDesc(BlkDescData), + NetDesc(NetDescData), + ConsoleDesc(ConsoleDescData), + None, +} + +pub struct BlkDescData {} + +pub struct NetDescData { + pub mac: [u8; 6], + pub status: u16, +} + +pub struct ConsoleDescData { + pub oppo_end_vmid: u16, + pub oppo_end_ipa: u64, + // vm access + pub cols: u16, + pub rows: u16, + pub max_nr_ports: u32, + pub emerg_wr: u32, +} + +pub fn migrate_ready(vmid: usize) { + if vm_if_mem_map_cache(vmid).is_none() { + let trgt_vm = vm(vmid).unwrap(); + map_migrate_vm_mem(trgt_vm.clone(), get_share_mem(MIGRATE_SEND)); + match mem_pages_alloc(vm_if_mem_map_page_num(vmid)) { + Ok(pf) => { + active_vm().unwrap().pt_map_range( + get_share_mem(MIGRATE_BITMAP), + PAGE_SIZE * vm_if_mem_map_page_num(vmid), + pf.pa(), + PTE_S2_RO, + true, + ); + vm_if_set_mem_map_cache(vmid, pf); + } + Err(_) => { + panic!("migrate_ready: mem_pages_alloc failed"); + } + } + } +} + +pub fn send_migrate_memcpy_msg(vmid: usize) { + // copy trgt_vm dirty mem map to kernel module + // println!("migrate_memcpy, vm_id {}", vmid); + hvc_send_msg_to_vm( + 0, + &HvcGuestMsg::Migrate(HvcMigrateMsg { + fid: HVC_VMM, + event: HVC_VMM_MIGRATE_START, + vm_id: vmid, + oper: MIGRATE_COPY, + page_num: vm_if_mem_map_page_num(vmid), + }), + ); +} + +pub fn map_migrate_vm_mem(vm: Vm, ipa_start: usize) { + let mut len = 0; + for i in 0..vm.region_num() { + active_vm() + .unwrap() + .pt_map_range(ipa_start + len, vm.pa_length(i), vm.pa_start(i), PTE_S2_NORMAL, true); + len += vm.pa_length(i); + } +} + +pub fn unmap_migrate_vm_mem(vm: Vm, ipa_start: usize) { + let mut len = 0; + for i in 0..vm.region_num() { + // println!("unmap_migrate_vm_mem, ipa_start {:x}, len {:x}", ipa_start, vm.pa_length(i)); + active_vm() + .unwrap() + .pt_unmap_range(ipa_start + len, vm.pa_length(i), true); + len += vm.pa_length(i); + } +} + +pub fn migrate_finish_ipi_handler(vm_id: usize) { + // println!("Core 0 handle VM[{}] finish ipi", vm_id); + // let vm = vm(vm_id).unwrap(); + // copy trgt_vm dirty mem map to kernel module + // let vm = vm(vm_id).unwrap(); + // for i in 0..vm.mem_region_num() { + // unsafe { + // cache_invalidate_d(vm.pa_start(i), vm.pa_length(i)); + // } + // } + // tlb_invalidate_guest_all(); + vm_if_copy_mem_map(vm_id); + + hvc_send_msg_to_vm( + 0, + &HvcGuestMsg::Migrate(HvcMigrateMsg { + fid: HVC_VMM, + event: HVC_VMM_MIGRATE_START, + vm_id, + oper: MIGRATE_FINISH, + page_num: vm_if_mem_map_page_num(vm_id), + }), + ); +} + +pub fn migrate_data_abort_handler(emu_ctx: &EmuContext) { + if emu_ctx.write { + // ptr_read_write(emu_ctx.address, emu_ctx.width, val, false); + let vm = active_vm().unwrap(); + // vm.show_pagetable(emu_ctx.address); + let vm_id = vm.id(); + + let (pa, len) = vm.pt_set_access_permission(emu_ctx.address, PTE_S2_FIELD_AP_RW); + // println!( + // "migrate_data_abort_handler: emu_ctx addr 0x{:x}, write pa {:x}, len 0x{:x}", + // emu_ctx.address, pa, len + // ); + let mut bit = 0; + for i in 0..vm.region_num() { + let start = vm.pa_start(i); + let end = start + vm.pa_length(i); + if pa >= start && pa < end { + bit += (pa - active_vm().unwrap().pa_start(i)) / PAGE_SIZE; + vm_if_set_mem_map(vm_id, bit, len / PAGE_SIZE); + break; + } + bit += vm.pa_length(i) / PAGE_SIZE; + if i + 1 == vm.region_num() { + panic!( + "migrate_data_abort_handler: can not found addr 0x{:x} in vm{} pa region", + pa, vm_id + ); + } + } + // flush tlb for updating page table + tlb_invalidate_guest_all(); + } else { + panic!("migrate_data_abort_handler: permission should be read only"); + } +} diff --git a/src/kernel/mod.rs b/src/kernel/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a00688685db7e988b548978de3e9e43683635fa9 --- /dev/null +++ b/src/kernel/mod.rs @@ -0,0 +1,49 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::async_task::*; +pub use self::cpu::*; +pub use self::hvc::*; +pub use self::interrupt::*; +pub use self::iommu::*; +pub use self::ipi::*; +pub use self::ivc::*; +pub use self::live_update::*; +pub use self::logger::*; +pub use self::mem::*; +pub use self::mem_region::*; +pub use self::migrate::*; +pub use self::sched::*; +// pub use self::task::*; +pub use self::timer::*; +pub use self::vcpu::*; +// pub use self::vcpu_pool::*; +pub use self::vcpu_array::*; +pub use self::vm::*; + +mod async_task; +mod cpu; +mod hvc; +mod interrupt; +mod ipi; +mod ivc; +mod live_update; +mod logger; +mod mem; +mod mem_region; +mod migrate; +// mod task; +mod iommu; +mod sched; +mod timer; +mod vcpu; +// mod vcpu_pool; +mod vcpu_array; +mod vm; diff --git a/src/kernel/sched/mod.rs b/src/kernel/sched/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a233ddd25033a68cc7fdaf31c8ee8a8145aa75d7 --- /dev/null +++ b/src/kernel/sched/mod.rs @@ -0,0 +1,43 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +mod sched_rr; +// mod sched_rt; + +pub use self::sched_rr::SchedulerRR; +// pub use self::sched_rt::SchedulerRT; + +use crate::kernel::Vcpu; + +// Must Implement SchedulerTrait for inner struct(the real scheduler object) +pub enum SchedType { + SchedRR(SchedulerRR), + // SchedRT(SchedulerRT), + None, +} + +pub trait Scheduler { + fn init(&mut self); + /* pick the next vcpu object */ + fn next(&mut self) -> Option; + /* yield current vcpu */ + fn do_schedule(&mut self); + /* put vcpu into sleep, and remove it from scheduler */ + fn sleep(&mut self, vcpu: Vcpu); + /* wake up vcpu from sleep status, remember to set_active_vcpu when it is none*/ + fn wakeup(&mut self, vcpu: Vcpu); + /* yield to another cpu, only used when vcpu is new added and want to be excuted immediately */ + fn yield_to(&mut self, vcpu: Vcpu); +} + +// #[cfg(feature = "update")] +pub trait SchedulerUpdate { + fn update(&self) -> Self; +} diff --git a/src/kernel/sched/sched_rr.rs b/src/kernel/sched/sched_rr.rs new file mode 100644 index 0000000000000000000000000000000000000000..b268508ae8c0065619cc145c68dd549bdf04acf4 --- /dev/null +++ b/src/kernel/sched/sched_rr.rs @@ -0,0 +1,151 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; +use crate::kernel::{Vcpu, Scheduler, SchedulerUpdate, current_cpu, VcpuState, timer_enable, vm}; + +pub struct SchedulerRR { + queue: Vec, + active_idx: usize, + base_slice: usize, +} + +impl SchedulerRR { + pub fn new(slice: usize) -> Self { + Self { + queue: Vec::new(), + active_idx: 0, + base_slice: slice, + } + } +} + +impl Default for SchedulerRR { + fn default() -> Self { + Self { + queue: Default::default(), + active_idx: Default::default(), + base_slice: Default::default(), + } + } +} + +impl Scheduler for SchedulerRR { + fn init(&mut self) {} + + fn next(&mut self) -> Option { + let queue = &self.queue; + let len = queue.len(); + for i in 1..=len { + let idx = (self.active_idx + i) % len; + match queue.get(idx) { + Some(vcpu) => match vcpu.state() { + VcpuState::VcpuInv => {} + _ => { + self.active_idx = idx; + return Some(vcpu.clone()); + } + }, + None => panic!("len != 0 but front is None"), + } + } + None + } + + fn do_schedule(&mut self) { + let next_vcpu = self.next().unwrap(); + current_cpu().schedule_to(next_vcpu); + } + + fn sleep(&mut self, vcpu: Vcpu) { + // println!( + // "SchedulerRR: Core {} sleep VM[{}] vcpu {}", + // current_cpu().id, + // vcpu.vm_id(), + // vcpu.id() + // ); + let mut need_schedule = false; + { + let queue = &mut self.queue; + match queue.iter().position(|x| x.vm_id() == vcpu.vm_id()) { + Some(idx) => { + queue.remove(idx); + if idx < self.active_idx { + self.active_idx -= 1; + } else if idx == self.active_idx { + // cpu.active_vcpu need remove + current_cpu().set_active_vcpu(None); + if !queue.is_empty() { + need_schedule = true; + } + } + } + None => {} + } + } + if self.queue.len() <= 1 { + timer_enable(false); + } + if need_schedule { + self.do_schedule(); + } + } + + fn wakeup(&mut self, vcpu: Vcpu) { + let queue = &mut self.queue; + vcpu.set_state(VcpuState::VcpuPend); + queue.push(vcpu); + if queue.len() > 1 { + timer_enable(true); + } + if queue.len() == 1 { + self.do_schedule(); + } + } + + fn yield_to(&mut self, vcpu: Vcpu) { + let queue = &mut self.queue; + queue.push(vcpu.clone()); + self.active_idx = queue.len() - 1; + current_cpu().schedule_to(vcpu); + if queue.len() > 1 { + timer_enable(true); + } + } +} + +// #[cfg(feature = "update")] +impl SchedulerUpdate for SchedulerRR { + fn update(&self) -> Self { + let src_rr = self; + let mut new_rr = SchedulerRR::default(); + for vcpu in src_rr.queue.iter() { + let vm_id = vcpu.vm_id(); + let vcpu_id = vcpu.id(); + let vm = vm(vm_id).unwrap(); + new_rr.queue.push(vm.vcpu(vcpu_id).unwrap()); + } + new_rr.active_idx = src_rr.active_idx; + new_rr.base_slice = src_rr.base_slice; + + let active_vcpu = if src_rr.active_idx < src_rr.queue.len() { + println!("Core[{}] is some, active_idx {}, addr {:x}", current_cpu().id, src_rr.active_idx, unsafe { *(&new_rr.queue[src_rr.active_idx].clone() as *const _ as *const usize) }); + Some(new_rr.queue[src_rr.active_idx].clone()) + } else { + println!("Core[{}] is none", current_cpu().id); + None + }; + if active_vcpu.is_some() { + println!("core[{}] update active_vcpu addr {:x}", current_cpu().id, unsafe { *(&active_vcpu.clone().unwrap() as *const _ as *const usize) }); + } + current_cpu().set_active_vcpu(active_vcpu); + new_rr + } +} diff --git a/src/kernel/sched/sched_rt.rs b/src/kernel/sched/sched_rt.rs new file mode 100644 index 0000000000000000000000000000000000000000..c3e24deb90bfc800bc7085161901511b76111b44 --- /dev/null +++ b/src/kernel/sched/sched_rt.rs @@ -0,0 +1,39 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::kernel::{Vcpu, Scheduler}; + +pub struct SchedulerRT {} + +impl Scheduler for SchedulerRT { + fn init(&mut self) { + todo!() + } + + fn next(&mut self) -> Option { + todo!() + } + + fn do_schedule(&mut self) { + todo!() + } + + fn sleep(&mut self, vcpu: Vcpu) { + todo!() + } + + fn wakeup(&mut self, vcpu: Vcpu) { + todo!() + } + + fn yield_to(&mut self, vcpu: Vcpu) { + todo!() + } +} diff --git a/src/kernel/timer.rs b/src/kernel/timer.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1143b8ef4016e75846536a39fa32fc3744f12da --- /dev/null +++ b/src/kernel/timer.rs @@ -0,0 +1,72 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::INTERRUPT_IRQ_HYPERVISOR_TIMER; +// use crate::board::PLATFORM_CPU_NUM_MAX; +use crate::kernel::{current_cpu, InterruptHandler, Scheduler}; + +// #[derive(Copy, Clone)] +// struct Timer(bool); + +// impl Timer { +// const fn default() -> Timer { +// Timer(false) +// } + +// fn set(&mut self, val: bool) { +// self.0 = val; +// } +// } + +// static TIMER_LIST: Mutex<[Timer; PLATFORM_CPU_NUM_MAX]> = +// Mutex::new([Timer::default(); PLATFORM_CPU_NUM_MAX]); + +pub fn timer_init() { + crate::arch::timer_arch_init(); + timer_enable(false); + + crate::lib::barrier(); + if current_cpu().id == 0 { + crate::kernel::interrupt_reserve_int( + INTERRUPT_IRQ_HYPERVISOR_TIMER, + InterruptHandler::TimeIrqHandler(timer_irq_handler), + ); + println!("Timer frequency: {}Hz", crate::arch::timer_arch_get_frequency()); + println!("Timer init ok"); + } +} + +pub fn timer_enable(val: bool) { + // println!( + // "Core {} {} EL2 timer", + // current_cpu().id, + // if val { "enable" } else { "disable" } + // ); + super::interrupt::interrupt_cpu_enable(INTERRUPT_IRQ_HYPERVISOR_TIMER, val); +} + +fn timer_notify_after(ms: usize) { + use crate::arch::{timer_arch_enable_irq, timer_arch_set}; + if ms == 0 { + return; + } + + timer_arch_set(ms); + timer_arch_enable_irq(); +} + +pub fn timer_irq_handler(_arg: usize) { + use crate::arch::timer_arch_disable_irq; + + timer_arch_disable_irq(); + current_cpu().scheduler().do_schedule(); + + timer_notify_after(1); +} diff --git a/src/kernel/vcpu.rs b/src/kernel/vcpu.rs new file mode 100644 index 0000000000000000000000000000000000000000..76e01d90bc6876739aed2329ec1abab262807189 --- /dev/null +++ b/src/kernel/vcpu.rs @@ -0,0 +1,632 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::mem::size_of; +use spin::Mutex; + +use crate::arch::{ + ContextFrame, ContextFrameTrait, cpu_interrupt_unmask, GIC_INTS_MAX, GIC_SGI_REGS_NUM, GICC, GicContext, GICD, + GICH, VmContext, timer_arch_get_counter, +}; +use crate::board::{platform_cpuid_to_cpuif, PLATFORM_GICV_BASE, PLATFORM_VCPU_NUM_MAX}; +use crate::kernel::{current_cpu, interrupt_vm_inject, vm_if_set_state}; +use crate::kernel::{active_vcpu_id, active_vm_id}; +use crate::lib::memcpy_safe; + +use super::{CpuState, Vm, VmType}; + +#[derive(Clone, Copy, Debug)] +pub enum VcpuState { + VcpuInv = 0, + VcpuPend = 1, + VcpuAct = 2, +} + +#[derive(Clone)] +pub struct Vcpu { + pub inner: Arc>, +} + +impl Vcpu { + pub fn default() -> Vcpu { + Vcpu { + inner: Arc::new(Mutex::new(VcpuInner::default())), + } + } + + pub fn init(&self, vm: Vm, vcpu_id: usize) { + let mut inner = self.inner.lock(); + inner.vm = Some(vm.clone()); + inner.id = vcpu_id; + inner.phys_id = 0; + drop(inner); + crate::arch::vcpu_arch_init(vm.clone(), self.clone()); + self.reset_context(); + } + + pub fn shutdown(&self) { + println!( + "Core {} (vm {} vcpu {}) shutdown ok", + current_cpu().id, + active_vm_id(), + active_vcpu_id() + ); + crate::board::platform_cpu_shutdown(); + } + + pub fn migrate_vm_ctx_save(&self, cache_pa: usize) { + let inner = self.inner.lock(); + memcpy_safe( + cache_pa as *const u8, + &(inner.vm_ctx) as *const _ as *const u8, + size_of::(), + ); + } + + pub fn migrate_vcpu_ctx_save(&self, cache_pa: usize) { + let inner = self.inner.lock(); + memcpy_safe( + cache_pa as *const u8, + &(inner.vcpu_ctx) as *const _ as *const u8, + size_of::(), + ); + } + + pub fn migrate_gic_ctx_save(&self, cache_pa: usize) { + let inner = self.inner.lock(); + memcpy_safe( + cache_pa as *const u8, + &(inner.gic_ctx) as *const _ as *const u8, + size_of::(), + ); + } + + pub fn migrate_vm_ctx_restore(&self, cache_pa: usize) { + let inner = self.inner.lock(); + memcpy_safe( + &(inner.vm_ctx) as *const _ as *const u8, + cache_pa as *const u8, + size_of::(), + ); + } + + pub fn migrate_vcpu_ctx_restore(&self, cache_pa: usize) { + let inner = self.inner.lock(); + memcpy_safe( + &(inner.vcpu_ctx) as *const _ as *const u8, + cache_pa as *const u8, + size_of::(), + ); + } + + pub fn migrate_gic_ctx_restore(&self, cache_pa: usize) { + let inner = self.inner.lock(); + memcpy_safe( + &(inner.gic_ctx) as *const _ as *const u8, + cache_pa as *const u8, + size_of::(), + ); + } + + pub fn context_vm_store(&self) { + self.save_cpu_ctx(); + + let mut inner = self.inner.lock(); + inner.vm_ctx.ext_regs_store(); + inner.vm_ctx.fpsimd_save_context(); + inner.vm_ctx.gic_save_state(); + } + + pub fn context_gic_irqs_store(&self) { + let mut inner = self.inner.lock(); + let vm = inner.vm.clone().unwrap(); + inner.gic_ctx; + for irq in vm.config().passthrough_device_irqs() { + inner.gic_ctx.add_irq(irq as u64); + } + inner.gic_ctx.add_irq(25); + let gicv_ctlr = unsafe { &*((PLATFORM_GICV_BASE + 0x8_0000_0000) as *const u32) }; + inner.gic_ctx.set_gicv_ctlr(*gicv_ctlr); + let gicv_pmr = unsafe { &*((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0x4) as *const u32) }; + inner.gic_ctx.set_gicv_pmr(*gicv_pmr); + } + + pub fn context_gic_irqs_restore(&self) { + let inner = self.inner.lock(); + + for irq_state in inner.gic_ctx.irq_state.iter() { + if irq_state.id != 0 { + GICD.set_enable(irq_state.id as usize, irq_state.enable != 0); + GICD.set_prio(irq_state.id as usize, irq_state.priority); + GICD.set_trgt(irq_state.id as usize, 1 << platform_cpuid_to_cpuif(current_cpu().id)); + } + } + + let gicv_pmr = unsafe { &mut *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0x4) as *mut u32) }; + *gicv_pmr = inner.gic_ctx.gicv_pmr(); + // println!("Core[{}] save gic context", current_cpu().id); + let gicv_ctlr = unsafe { &mut *((PLATFORM_GICV_BASE + 0x8_0000_0000) as *mut u32) }; + *gicv_ctlr = inner.gic_ctx.gicv_ctlr(); + // show_vcpu_reg_context(); + } + + pub fn context_vm_restore(&self) { + // println!("context_vm_restore"); + self.restore_cpu_ctx(); + + let inner = self.inner.lock(); + // restore vm's VFP and SIMD + inner.vm_ctx.fpsimd_restore_context(); + inner.vm_ctx.gic_restore_state(); + inner.vm_ctx.ext_regs_restore(); + drop(inner); + + self.inject_int_inlist(); + } + + pub fn gic_restore_context(&self) { + let inner = self.inner.lock(); + inner.vm_ctx.gic_restore_state(); + } + + pub fn gic_save_context(&self) { + let mut inner = self.inner.lock(); + inner.vm_ctx.gic_save_state(); + } + + pub fn save_cpu_ctx(&self) { + let inner = self.inner.lock(); + match current_cpu().ctx { + None => { + println!("save_cpu_ctx: cpu{} ctx is NULL", current_cpu().id); + } + Some(ctx) => { + memcpy_safe( + &(inner.vcpu_ctx) as *const _ as *const u8, + ctx as *const u8, + size_of::(), + ); + } + } + } + + fn restore_cpu_ctx(&self) { + let inner = self.inner.lock(); + match current_cpu().ctx { + None => { + println!("restore_cpu_ctx: cpu{} ctx is NULL", current_cpu().id); + } + Some(ctx) => { + memcpy_safe( + ctx as *const u8, + &(inner.vcpu_ctx) as *const _ as *const u8, + size_of::(), + ); + } + } + } + + pub fn set_phys_id(&self, phys_id: usize) { + let mut inner = self.inner.lock(); + println!("set vcpu {} phys id {}", inner.id, phys_id); + inner.phys_id = phys_id; + } + + pub fn set_gich_ctlr(&self, ctlr: u32) { + let mut inner = self.inner.lock(); + inner.vm_ctx.gic_state.ctlr = ctlr; + } + + pub fn set_hcr(&self, hcr: u64) { + let mut inner = self.inner.lock(); + inner.vm_ctx.hcr_el2 = hcr; + } + + pub fn state(&self) -> VcpuState { + let inner = self.inner.lock(); + inner.state.clone() + } + + pub fn set_state(&self, state: VcpuState) { + let mut inner = self.inner.lock(); + inner.state = state; + } + + pub fn id(&self) -> usize { + let inner = self.inner.lock(); + inner.id + } + + pub fn vm(&self) -> Option { + let inner = self.inner.lock(); + inner.vm.clone() + } + + pub fn phys_id(&self) -> usize { + let inner = self.inner.lock(); + inner.phys_id + } + + pub fn vm_id(&self) -> usize { + self.vm().unwrap().id() + } + + pub fn vm_pt_dir(&self) -> usize { + self.vm().unwrap().pt_dir() + } + + pub fn reset_context(&self) { + let mut inner = self.inner.lock(); + inner.reset_context(); + } + + pub fn reset_vmpidr(&self) { + let mut inner = self.inner.lock(); + inner.reset_vmpidr(); + } + + pub fn reset_vtimer_offset(&self) { + let mut inner = self.inner.lock(); + inner.reset_vtimer_offset(); + } + + pub fn context_ext_regs_store(&self) { + let mut inner = self.inner.lock(); + inner.context_ext_regs_store(); + } + + pub fn vcpu_ctx_addr(&self) -> usize { + let inner = self.inner.lock(); + inner.vcpu_ctx_addr() + } + + pub fn set_elr(&self, elr: usize) { + let mut inner = self.inner.lock(); + inner.set_elr(elr); + } + + pub fn elr(&self) -> usize { + let inner = self.inner.lock(); + inner.vcpu_ctx.exception_pc() + } + + pub fn set_gpr(&self, idx: usize, val: usize) { + let mut inner = self.inner.lock(); + inner.set_gpr(idx, val); + } + + pub fn show_ctx(&self) { + let inner = self.inner.lock(); + inner.show_ctx(); + } + + pub fn push_int(&self, int: usize) { + let mut inner = self.inner.lock(); + if !inner.int_list.contains(&int) { + inner.int_list.push(int); + } + } + + fn inject_int_inlist(&self) { + match self.vm() { + None => {} + Some(vm) => { + let mut inner = self.inner.lock(); + let int_list = inner.int_list.clone(); + inner.int_list.clear(); + drop(inner); + for int in int_list { + // println!("schedule: inject int {} for vm {}", int, vm.id()); + interrupt_vm_inject(vm.clone(), self.clone(), int, 0); + } + } + } + } +} + +pub struct VcpuInner { + pub id: usize, + pub phys_id: usize, + pub state: VcpuState, + pub vm: Option, + pub int_list: Vec, + pub vcpu_ctx: ContextFrame, + pub vm_ctx: VmContext, + pub gic_ctx: GicContext, +} + +impl VcpuInner { + pub fn default() -> VcpuInner { + VcpuInner { + id: 0, + phys_id: 0, + state: VcpuState::VcpuInv, + vm: None, + int_list: vec![], + vcpu_ctx: ContextFrame::default(), + vm_ctx: VmContext::default(), + gic_ctx: GicContext::default(), + } + } + + fn vcpu_ctx_addr(&self) -> usize { + &(self.vcpu_ctx) as *const _ as usize + } + + fn vm_id(&self) -> usize { + let vm = self.vm.as_ref().unwrap(); + vm.id() + } + + fn arch_ctx_reset(&mut self) { + // let migrate = self.vm.as_ref().unwrap().migration_state(); + // if !migrate { + self.vm_ctx.cntvoff_el2 = 0; + self.vm_ctx.sctlr_el1 = 0x30C50830; + self.vm_ctx.cntkctl_el1 = 0; + self.vm_ctx.pmcr_el0 = 0; + self.vm_ctx.vtcr_el2 = 0x8001355c; + // } + let mut vmpidr = 0; + vmpidr |= 1 << 31; + + #[cfg(feature = "tx2")] + if self.vm_id() == 0 { + // A57 is cluster #1 for L4T + vmpidr |= 0x100; + } + + vmpidr |= self.id; + self.vm_ctx.vmpidr_el2 = vmpidr as u64; + } + + fn reset_vmpidr(&mut self) { + let mut vmpidr = 0; + vmpidr |= 1 << 31; + + #[cfg(feature = "tx2")] + if self.vm_id() == 0 { + // A57 is cluster #1 for L4T + vmpidr |= 0x100; + } + + vmpidr |= self.id; + self.vm_ctx.vmpidr_el2 = vmpidr as u64; + } + + fn reset_vtimer_offset(&mut self) { + let curpct = timer_arch_get_counter() as u64; + self.vm_ctx.cntvoff_el2 = curpct - self.vm_ctx.cntvct_el0; + } + + fn reset_context(&mut self) { + // let migrate = self.vm.as_ref().unwrap().migration_state(); + self.arch_ctx_reset(); + // if !migrate { + self.gic_ctx_reset(); + // } + use crate::kernel::vm_if_get_type; + match vm_if_get_type(self.vm_id()) { + VmType::VmTBma => { + println!("vm {} bma ctx restore", self.vm_id()); + self.reset_vm_ctx(); + self.context_ext_regs_store(); + } + _ => {} + } + } + + fn gic_ctx_reset(&mut self) { + use crate::arch::gich_lrs_num; + for i in 0..gich_lrs_num() { + self.vm_ctx.gic_state.lr[i] = 0; + } + self.vm_ctx.gic_state.hcr |= 1 << 2; + } + + fn context_ext_regs_store(&mut self) { + self.vm_ctx.ext_regs_store(); + } + + fn reset_vm_ctx(&mut self) { + self.vm_ctx.reset(); + } + + fn set_elr(&mut self, elr: usize) { + self.vcpu_ctx.set_exception_pc(elr); + } + + fn set_gpr(&mut self, idx: usize, val: usize) { + self.vcpu_ctx.set_gpr(idx, val); + } + + fn show_ctx(&self) { + println!( + "cntvoff_el2 {:x}, sctlr_el1 {:x}, cntkctl_el1 {:x}, pmcr_el0 {:x}, vtcr_el2 {:x} x0 {:x}", + self.vm_ctx.cntvoff_el2, + self.vm_ctx.sctlr_el1, + self.vm_ctx.cntkctl_el1, + self.vm_ctx.pmcr_el0, + self.vm_ctx.vtcr_el2, + self.vcpu_ctx.gpr(0) + ); + } +} + +pub static VCPU_LIST: Mutex> = Mutex::new(Vec::new()); + +pub fn vcpu_alloc() -> Option { + let mut vcpu_list = VCPU_LIST.lock(); + if vcpu_list.len() >= PLATFORM_VCPU_NUM_MAX { + return None; + } + + let val = Vcpu::default(); + vcpu_list.push(val.clone()); + Some(val.clone()) +} + +pub fn vcpu_remove(vcpu: Vcpu) { + let mut vcpu_list = VCPU_LIST.lock(); + for (idx, core) in vcpu_list.iter().enumerate() { + if core.id() == vcpu.id() && core.vm_id() == vcpu.vm_id() { + vcpu_list.remove(idx); + return; + } + } + panic!("illegal vm{} vcpu{}, not exist in vcpu_list", vcpu.vm_id(), vcpu.id()); +} + +pub fn vcpu_idle(_vcpu: Vcpu) -> ! { + cpu_interrupt_unmask(); + loop { + // TODO: replace it with an Arch function `arch_idle` + cortex_a::asm::wfi(); + } +} + +// WARNING: No Auto `drop` in this function +pub fn vcpu_run(announce: bool) -> ! { + { + let vcpu = current_cpu().active_vcpu.clone().unwrap(); + let vm = vcpu.vm().unwrap().clone(); + + current_cpu().cpu_state = CpuState::CpuRun; + vm_if_set_state(active_vm_id(), super::VmState::VmActive); + + vcpu.context_vm_restore(); + if announce { + crate::device::virtio_net_announce(vm.clone()); + } + // tlb_invalidate_guest_all(); + // for i in 0..vm.mem_region_num() { + // unsafe { + // cache_invalidate_d(vm.pa_start(i), vm.pa_length(i)); + // } + // } + } + extern "C" { + fn context_vm_entry(ctx: usize) -> !; + } + unsafe { + context_vm_entry(current_cpu().ctx.unwrap()); + } +} + +pub fn show_vcpu_reg_context() { + print!("#### GICD ISENABLER ####"); + for i in 0..GIC_INTS_MAX / 32 { + if i % 8 == 0 { + println!(""); + } + print!("{:x} ", GICD.is_enabler(i)); + } + println!(""); + print!("#### GICD ISACTIVER ####"); + for i in 0..GIC_INTS_MAX / 32 { + if i % 8 == 0 { + println!(""); + } + print!("{:x} ", GICD.is_activer(i)); + } + println!(""); + print!("#### GICD ISPENDER ####"); + for i in 0..GIC_INTS_MAX / 32 { + if i % 8 == 0 { + println!(""); + } + print!("{:x} ", GICD.is_pender(i)); + } + println!(""); + print!("#### GICD IGROUP ####"); + for i in 0..GIC_INTS_MAX / 32 { + if i % 8 == 0 { + println!(""); + } + print!("{:x} ", GICD.igroup(i)); + } + println!(""); + print!("#### GICD ICFGR ####"); + for i in 0..GIC_INTS_MAX * 2 / 32 { + if i % 8 == 0 { + println!(""); + } + print!("{:x} ", GICD.icfgr(i)); + } + println!(""); + print!("#### GICD CPENDSGIR ####"); + for i in 0..GIC_SGI_REGS_NUM { + if i % 8 == 0 { + println!(""); + } + print!("{:x} ", GICD.cpendsgir(i)); + } + println!(""); + println!("GICH_APR {:x}", GICH.misr()); + + println!("GICD_CTLR {:x}", GICD.ctlr()); + print!("#### GICD ITARGETSR ####"); + for i in 0..GIC_INTS_MAX * 8 / 32 { + if i % 8 == 0 { + println!(""); + } + print!("{:x} ", GICD.itargetsr(i)); + } + println!(""); + + print!("#### GICD IPRIORITYR ####"); + for i in 0..GIC_INTS_MAX * 8 / 32 { + if i % 16 == 0 { + println!(""); + } + print!("{:x} ", GICD.ipriorityr(i)); + } + println!(""); + + println!("GICC_RPR {:x}", GICC.rpr()); + println!("GICC_HPPIR {:x}", GICC.hppir()); + println!("GICC_BPR {:x}", GICC.bpr()); + println!("GICC_ABPR {:x}", GICC.abpr()); + println!("#### GICC APR ####"); + for i in 0..4 { + print!("{:x} ", GICC.apr(i)); + } + println!(""); + println!("#### GICC NSAPR ####"); + for i in 0..4 { + print!("{:x} ", GICC.nsapr(i)); + } + + println!("GICH_MISR {:x}", GICH.misr()); + println!("GICV_CTLR {:x}", unsafe { + *((PLATFORM_GICV_BASE + 0x8_0000_0000) as *const u32) + }); + println!("GICV_PMR {:x}", unsafe { + *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0x4) as *const u32) + }); + println!("GICV_BPR {:x}", unsafe { + *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0x8) as *const u32) + }); + println!("GICV_ABPR {:x}", unsafe { + *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0x1c) as *const u32) + }); + println!("GICV_STATUSR {:x}", unsafe { + *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0x2c) as *const u32) + }); + println!( + "GICV_APR[0] {:x}, GICV_APR[1] {:x}, GICV_APR[2] {:x}, GICV_APR[3] {:x}", + unsafe { *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0xd0) as *const u32) }, + unsafe { *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0xd4) as *const u32) }, + unsafe { *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0xd8) as *const u32) }, + unsafe { *((PLATFORM_GICV_BASE + 0x8_0000_0000 + 0xdc) as *const u32) }, + ); +} diff --git a/src/kernel/vcpu_array.rs b/src/kernel/vcpu_array.rs new file mode 100644 index 0000000000000000000000000000000000000000..4234f59aed364e346b2d86d36b27a1b0501bdc41 --- /dev/null +++ b/src/kernel/vcpu_array.rs @@ -0,0 +1,137 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::slice::{Iter, IterMut}; +use crate::board::{PLAT_DESC, SchedRule}; +use crate::kernel::{current_cpu, SchedType, SchedulerRR, Vcpu, VM_NUM_MAX, interrupt_cpu_enable}; + +pub struct VcpuArray { + array: [Option; VM_NUM_MAX], + len: usize, +} + +impl VcpuArray { + pub const fn new() -> Self { + Self { + array: [None, None, None, None, None, None, None, None], + len: 0, + } + } + + #[deprecated] + pub const fn capacity(&self) -> usize { + self.array.len() + } + + #[inline] + pub fn pop_vcpu_through_vmid(&self, vm_id: usize) -> Option { + self.array[vm_id].clone() + } + + #[inline] + pub fn vcpu_num(&self) -> usize { + self.len + } + + pub fn append_vcpu(&mut self, vcpu: Vcpu) { + // There is only 1 VCPU from a VM in a PCPU + let vm_id = vcpu.vm_id(); + if vm_id >= self.array.len() { + panic!("vm_id > self.array.len()"); + } + if self.array[vm_id].is_some() { + panic!("self.array[vm_id].is_some()"); + } + vcpu.set_phys_id(current_cpu().id); + info!( + "append_vcpu: append VM[{}] vcpu {} on core {}", + vm_id, + vcpu.id(), + current_cpu().id + ); + self.array[vm_id] = Some(vcpu); + self.len += 1; + } + + pub fn remove_vcpu(&mut self, vm_id: usize) -> Option { + if vm_id >= self.array.len() { + panic!("vm_id > self.array.len()"); + } + match self.array[vm_id].clone() { + Some(vcpu) => { + self.len -= 1; + self.array[vm_id] = None; + if self.len == 0 { + // hard code: remove el1 timer interrupt 27 + interrupt_cpu_enable(27, false); + } + Some(vcpu) + } + None => panic!( + "no vcpu from vm[{}] exist in Core[{}] vcpu_pool", + vm_id, + current_cpu().id + ), + } + } + + pub fn iter(&self) -> Iter<'_, Option> { + self.array.iter() + } + + pub fn iter_mut(&mut self) -> IterMut<'_, Option> { + self.array.iter_mut() + } +} + +// Todo: add config for base slice +pub fn cpu_sched_init() { + match PLAT_DESC.cpu_desc.sched_list[current_cpu().id] { + SchedRule::RoundRobin => { + info!("cpu[{}] init Round Robin Scheduler", current_cpu().id); + current_cpu().sched = SchedType::SchedRR(SchedulerRR::new(1)); + } + _ => { + todo!(); + } + } +} + +pub fn restore_vcpu_gic(cur_vcpu: Option, trgt_vcpu: Vcpu) { + // println!("restore_vcpu_gic"); + match cur_vcpu { + None => { + // println!("None cur vmid trgt {}", trgt_vcpu.vm_id()); + trgt_vcpu.gic_restore_context(); + } + Some(active_vcpu) => { + if trgt_vcpu.vm_id() != active_vcpu.vm_id() { + // println!("different vm_id cur {}, trgt {}", active_vcpu.vm_id(), trgt_vcpu.vm_id()); + active_vcpu.gic_save_context(); + trgt_vcpu.gic_restore_context(); + } + } + } +} + +pub fn save_vcpu_gic(cur_vcpu: Option, trgt_vcpu: Vcpu) { + // println!("save_vcpu_gic"); + match cur_vcpu { + None => { + trgt_vcpu.gic_save_context(); + } + Some(active_vcpu) => { + if trgt_vcpu.vm_id() != active_vcpu.vm_id() { + trgt_vcpu.gic_save_context(); + active_vcpu.gic_restore_context(); + } + } + } +} diff --git a/src/kernel/vm.rs b/src/kernel/vm.rs new file mode 100644 index 0000000000000000000000000000000000000000..30124b7cc62a48f046cb10b6946ab0ce0485b8fa --- /dev/null +++ b/src/kernel/vm.rs @@ -0,0 +1,1097 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::collections::BTreeMap; +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::mem::size_of; + +use spin::Mutex; + +use crate::arch::{PAGE_SIZE, PTE_S2_FIELD_AP_RO, PTE_S2_NORMAL, PTE_S2_RO}; +use crate::arch::{GICC_CTLR_EN_BIT, GICC_CTLR_EOIMODENS_BIT}; +use crate::arch::PageTable; +use crate::arch::Vgic; +use crate::board::SHARE_MEM_BASE; +use crate::config::VmConfigEntry; +use crate::device::EmuDevs; +use crate::kernel::{ + EmuDevData, get_share_mem, mem_pages_alloc, VirtioMmioData, VM_CONTEXT_RECEIVE, VM_CONTEXT_SEND, VMData, +}; +use crate::lib::*; +use crate::mm::PageFrame; + +use super::vcpu::Vcpu; + +pub const DIRTY_MEM_THRESHOLD: usize = 0x2000; +pub const VM_NUM_MAX: usize = 8; +pub static VM_IF_LIST: [Mutex; VM_NUM_MAX] = [ + Mutex::new(VmInterface::default()), + Mutex::new(VmInterface::default()), + Mutex::new(VmInterface::default()), + Mutex::new(VmInterface::default()), + Mutex::new(VmInterface::default()), + Mutex::new(VmInterface::default()), + Mutex::new(VmInterface::default()), + Mutex::new(VmInterface::default()), +]; + +pub fn vm_if_reset(vm_id: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.reset(); +} + +pub fn vm_if_set_state(vm_id: usize, vm_state: VmState) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.state = vm_state; +} + +pub fn vm_if_get_state(vm_id: usize) -> VmState { + let vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.state +} + +pub fn vm_if_set_type(vm_id: usize, vm_type: VmType) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.vm_type = vm_type; +} + +pub fn vm_if_get_type(vm_id: usize) -> VmType { + let vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.vm_type +} + +fn vm_if_set_cpu_id(vm_id: usize, master_cpu_id: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.master_cpu_id = master_cpu_id; + debug!( + "vm_if_list_set_cpu_id vm [{}] set master_cpu_id {}", + vm_id, master_cpu_id + ); +} + +// todo: rewrite return val to Option +pub fn vm_if_get_cpu_id(vm_id: usize) -> usize { + let vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.master_cpu_id +} + +pub fn vm_if_cmp_mac(vm_id: usize, frame: &[u8]) -> bool { + let vm_if = VM_IF_LIST[vm_id].lock(); + for i in 0..6 { + if vm_if.mac[i] != frame[i] { + return false; + } + } + true +} + +pub fn vm_if_set_ivc_arg(vm_id: usize, ivc_arg: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.ivc_arg = ivc_arg; +} + +pub fn vm_if_ivc_arg(vm_id: usize) -> usize { + let vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.ivc_arg +} + +pub fn vm_if_set_ivc_arg_ptr(vm_id: usize, ivc_arg_ptr: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.ivc_arg_ptr = ivc_arg_ptr; +} + +pub fn vm_if_ivc_arg_ptr(vm_id: usize) -> usize { + let vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.ivc_arg_ptr +} + +// new if for vm migration +pub fn vm_if_init_mem_map(vm_id: usize, len: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.mem_map = Some(FlexBitmap::new(len)); +} + +pub fn vm_if_set_mem_map_cache(vm_id: usize, pf: PageFrame) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.mem_map_cache = Some(Arc::new(pf)); +} + +pub fn vm_if_mem_map_cache(vm_id: usize) -> Option> { + let vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.mem_map_cache.clone() +} + +pub fn vm_if_dirty_mem_map(vm_id: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.mem_map.as_mut().unwrap().init_dirty(); +} + +pub fn vm_if_set_mem_map_bit(vm: Vm, pa: usize) { + let mut vm_if = VM_IF_LIST[vm.id()].lock(); + let mut bit = 0; + for i in 0..vm.region_num() { + let start = vm.pa_start(i); + let len = vm.pa_length(i); + if pa >= start && pa < start + len { + bit += (pa - start) / PAGE_SIZE; + // if vm_if.mem_map.as_mut().unwrap().get(bit) == 0 { + // println!("vm_if_set_mem_map_bit: set pa 0x{:x}", pa); + // } + vm_if.mem_map.as_mut().unwrap().set(bit, true); + return; + } else { + bit += len / PAGE_SIZE; + } + } + panic!("vm_if_set_mem_map_bit: illegal pa 0x{:x}", pa); +} + +pub fn vm_if_set_mem_map(vm_id: usize, bit: usize, len: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.mem_map.as_mut().unwrap().set_bits(bit, len, true); +} + +pub fn vm_if_clear_mem_map(vm_id: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.mem_map.as_mut().unwrap().clear(); +} + +pub fn vm_if_copy_mem_map(vm_id: usize) { + let mut vm_if = VM_IF_LIST[vm_id].lock(); + let mem_map_cache = vm_if.mem_map_cache.clone(); + let map = vm_if.mem_map.as_mut().unwrap(); + // map.set(0x15, true); + // TODO: hard code for offset 0x15000 + // println!( + // "vm_if_copy_mem_map: dirty mem page num {}, first dirty page 0x{:x}, bitmap len {:x}", + // map.sum(), + // map.first(), + // size_of::() * map.vec_len() + // ); + memcpy_safe( + mem_map_cache.as_ref().unwrap().pa() as *const u8, + map.slice() as *const _ as *const u8, + size_of::() * map.vec_len(), + ); + // clear bitmap after copy + map.clear(); +} + +pub fn vm_if_mem_map_page_num(vm_id: usize) -> usize { + let vm_if = VM_IF_LIST[vm_id].lock(); + let map = vm_if.mem_map.as_ref().unwrap(); + 8 * map.vec_len() / PAGE_SIZE +} + +pub fn vm_if_mem_map_dirty_sum(vm_id: usize) -> usize { + let vm_if = VM_IF_LIST[vm_id].lock(); + vm_if.mem_map.as_ref().unwrap().sum() +} +// End vm interface func implementation + +#[derive(Clone, Copy)] +pub enum VmState { + VmInv = 0, + VmPending = 1, + VmActive = 2, +} + +#[derive(Clone, Copy, PartialEq)] +pub enum VmType { + VmTOs = 0, + VmTBma = 1, +} + +impl VmType { + pub fn from_usize(value: usize) -> VmType { + match value { + 0 => VmType::VmTOs, + 1 => VmType::VmTBma, + _ => panic!("Unknown VmType value: {}", value), + } + } +} + +pub struct VmInterface { + pub master_cpu_id: usize, + pub state: VmState, + pub vm_type: VmType, + pub mac: [u8; 6], + pub ivc_arg: usize, + pub ivc_arg_ptr: usize, + pub mem_map: Option, + pub mem_map_cache: Option>, +} + +impl VmInterface { + const fn default() -> VmInterface { + VmInterface { + master_cpu_id: 0, + state: VmState::VmPending, + vm_type: VmType::VmTBma, + mac: [0; 6], + ivc_arg: 0, + ivc_arg_ptr: 0, + mem_map: None, + mem_map_cache: None, + } + } + + fn reset(&mut self) { + self.master_cpu_id = 0; + self.state = VmState::VmPending; + self.vm_type = VmType::VmTBma; + self.mac = [0; 6]; + self.ivc_arg = 0; + self.ivc_arg_ptr = 0; + self.mem_map = None; + self.mem_map_cache = None; + } +} + +#[derive(Clone, Copy)] +pub struct VmPa { + pub pa_start: usize, + pub pa_length: usize, + pub offset: isize, +} + +impl VmPa { + pub fn default() -> VmPa { + VmPa { + pa_start: 0, + pa_length: 0, + offset: 0, + } + } +} + +// #[repr(align(4096))] +#[derive(Clone)] +pub struct Vm { + pub inner: Arc>, +} + +impl Vm { + pub fn inner(&self) -> Arc> { + self.inner.clone() + } + + pub fn default() -> Vm { + Vm { + inner: Arc::new(Mutex::new(VmInner::default())), + } + } + + pub fn new(id: usize) -> Vm { + Vm { + inner: Arc::new(Mutex::new(VmInner::new(id))), + } + } + + pub fn init_intc_mode(&self, emu: bool) { + let vm_inner = self.inner.lock(); + for vcpu in &vm_inner.vcpu_list { + info!( + "vm {} vcpu {} set {} hcr", + vm_inner.id, + vcpu.id(), + if emu { "emu" } else { "partial passthrough" } + ); + if !emu { + vcpu.set_gich_ctlr((GICC_CTLR_EN_BIT) as u32); + vcpu.set_hcr(0x80080001); // HCR_EL2_GIC_PASSTHROUGH_VAL + } else { + vcpu.set_gich_ctlr((GICC_CTLR_EN_BIT | GICC_CTLR_EOIMODENS_BIT) as u32); + vcpu.set_hcr(0x80080019); + } + } + } + + pub fn set_iommu_ctx_id(&self, id: usize) { + let mut vm_inner = self.inner.lock(); + vm_inner.iommu_ctx_id = Some(id); + } + + pub fn iommu_ctx_id(&self) -> usize { + let vm_inner = self.inner.lock(); + match vm_inner.iommu_ctx_id { + None => { + panic!("vm {} do not have iommu context bank", vm_inner.id); + } + Some(id) => id, + } + } + + pub fn med_blk_id(&self) -> usize { + let vm_inner = self.inner.lock(); + // match self.config().mediated_block_index() { + // None => { + // panic!("vm {} do not have mediated blk", vm_inner.id); + // } + // Some(idx) => idx, + // } + match vm_inner.config.as_ref().unwrap().mediated_block_index() { + None => { + panic!("vm {} do not have mediated blk", vm_inner.id); + } + Some(idx) => idx, + } + // match vm_inner.med_blk_id { + // None => { + // panic!("vm {} do not have mediated blk", vm_inner.id); + // } + // Some(idx) => idx, + // } + } + + pub fn dtb(&self) -> Option<*mut fdt::myctypes::c_void> { + let vm_inner = self.inner.lock(); + vm_inner.dtb.map(|x| x as *mut fdt::myctypes::c_void) + } + + pub fn set_dtb(&self, val: *mut fdt::myctypes::c_void) { + let mut vm_inner = self.inner.lock(); + vm_inner.dtb = Some(val as usize); + } + + pub fn vcpu(&self, index: usize) -> Option { + let vm_inner = self.inner.lock(); + match vm_inner.vcpu_list.get(index).cloned() { + Some(vcpu) => { + assert_eq!(index, vcpu.id()); + Some(vcpu) + } + None => { + println!( + "vcpu idx {} is to large than vcpu_list len {}", + index, + vm_inner.vcpu_list.len() + ); + None + } + } + } + + pub fn push_vcpu(&self, vcpu: Vcpu) { + let mut vm_inner = self.inner.lock(); + if vcpu.id() >= vm_inner.vcpu_list.len() { + vm_inner.vcpu_list.push(vcpu); + } else { + println!("VM[{}] insert VCPU {}", vm_inner.id, vcpu.id()); + vm_inner.vcpu_list.insert(vcpu.id(), vcpu); + } + } + + // avoid circular references + pub fn clear_list(&self) { + let mut vm_inner = self.inner.lock(); + vm_inner.emu_devs.clear(); + vm_inner.vcpu_list.clear(); + } + + pub fn select_vcpu2assign(&self, cpu_id: usize) -> Option { + let cfg_master = self.config().cpu_master(); + let cfg_cpu_num = self.config().cpu_num(); + let cfg_cpu_allocate_bitmap = self.config().cpu_allocated_bitmap(); + // make sure that vcpu assign is executed sequentially, otherwise + // the PCPUs may found that vm.cpu_num() == 0 at the same time and + // if cfg_master is not setted, they will not set master vcpu for VM + let mut vm_inner = self.inner.lock(); + if (cfg_cpu_allocate_bitmap & (1 << cpu_id)) != 0 && vm_inner.cpu_num < cfg_cpu_num { + // vm.vcpu(0) must be the VM's master vcpu + let trgt_id = if cpu_id == cfg_master || (!vm_inner.has_master && vm_inner.cpu_num == cfg_cpu_num - 1) { + 0 + } else if vm_inner.has_master { + cfg_cpu_num - vm_inner.cpu_num + } else { + // if master vcpu is not assigned, retain id 0 for it + cfg_cpu_num - vm_inner.cpu_num - 1 + }; + match vm_inner.vcpu_list.get(trgt_id).cloned() { + None => None, + Some(vcpu) => { + if vcpu.id() == 0 { + vm_if_set_cpu_id(vm_inner.id, cpu_id); + vm_inner.has_master = true; + } + vm_inner.cpu_num += 1; + vm_inner.ncpu |= 1 << cpu_id; + Some(vcpu) + } + } + } else { + None + } + } + + pub fn set_entry_point(&self, entry_point: usize) { + let mut vm_inner = self.inner.lock(); + vm_inner.entry_point = entry_point; + } + + pub fn set_emu_devs(&self, idx: usize, emu: EmuDevs) { + let mut vm_inner = self.inner.lock(); + if idx < vm_inner.emu_devs.len() { + if let EmuDevs::None = vm_inner.emu_devs[idx] { + // println!("set_emu_devs: cover a None emu dev"); + vm_inner.emu_devs[idx] = emu; + return; + } else { + panic!("set_emu_devs: set an exsit emu dev"); + } + } + while idx > vm_inner.emu_devs.len() { + println!("set_emu_devs: push a None emu dev"); + vm_inner.emu_devs.push(EmuDevs::None); + } + vm_inner.emu_devs.push(emu); + } + + pub fn set_intc_dev_id(&self, intc_dev_id: usize) { + let mut vm_inner = self.inner.lock(); + vm_inner.intc_dev_id = intc_dev_id; + } + + pub fn set_int_bit_map(&self, int_id: usize) { + let mut vm_inner = self.inner.lock(); + vm_inner.int_bitmap.as_mut().unwrap().set(int_id); + } + + pub fn set_config_entry(&self, config: Option) { + let mut vm_inner = self.inner.lock(); + vm_inner.config = config; + } + + pub fn intc_dev_id(&self) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.intc_dev_id + } + + pub fn pt_map_range(&self, ipa: usize, len: usize, pa: usize, pte: usize, map_block: bool) { + let vm_inner = self.inner.lock(); + match &vm_inner.pt { + Some(pt) => pt.pt_map_range(ipa, len, pa, pte, map_block), + None => { + panic!("Vm::pt_map_range: vm{} pt is empty", vm_inner.id); + } + } + } + + pub fn pt_unmap_range(&self, ipa: usize, len: usize, map_block: bool) { + let vm_inner = self.inner.lock(); + match &vm_inner.pt { + Some(pt) => pt.pt_unmap_range(ipa, len, map_block), + None => { + panic!("Vm::pt_umnmap_range: vm{} pt is empty", vm_inner.id); + } + } + } + + // ap: access permission + pub fn pt_set_access_permission(&self, ipa: usize, ap: usize) -> (usize, usize) { + let vm_inner = self.inner.lock(); + match &vm_inner.pt { + Some(pt) => { + return pt.access_permission(ipa, PAGE_SIZE, ap); + } + None => { + panic!("pt_set_access_permission: vm{} pt is empty", vm_inner.id); + } + } + } + + pub fn pt_read_only(&self) { + let vm_inner = self.inner.lock(); + match vm_inner.pt.clone() { + Some(pt) => { + let num = vm_inner.mem_region_num; + drop(vm_inner); + for i in 0..num { + let vm_inner = self.inner.lock(); + let ipa_start = vm_inner.pa_region[i].pa_start + vm_inner.pa_region[i].offset as usize; + let len = vm_inner.pa_region[i].pa_length; + drop(vm_inner); + pt.access_permission(ipa_start, len, PTE_S2_FIELD_AP_RO); + } + } + None => { + panic!("Vm::read_only: vm{} pt is empty", vm_inner.id); + } + } + } + + pub fn set_pt(&self, pt_dir_frame: PageFrame) { + let mut vm_inner = self.inner.lock(); + vm_inner.pt = Some(PageTable::new(pt_dir_frame)) + } + + pub fn pt_dir(&self) -> usize { + let vm_inner = self.inner.lock(); + match &vm_inner.pt { + Some(pt) => return pt.base_pa(), + None => { + panic!("Vm::pt_dir: vm{} pt is empty", vm_inner.id); + } + } + } + + pub fn cpu_num(&self) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.cpu_num + } + + pub fn id(&self) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.id + } + + pub fn config(&self) -> VmConfigEntry { + let vm_inner = self.inner.lock(); + match &vm_inner.config { + None => { + panic!("VM[{}] do not have vm config entry", vm_inner.id); + } + Some(config) => config.clone(), + } + } + + pub fn add_region(&self, region: VmPa) { + let mut vm_inner = self.inner.lock(); + vm_inner.pa_region.push(region); + } + + pub fn region_num(&self) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.pa_region.len() + } + + pub fn pa_start(&self, idx: usize) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.pa_region[idx].pa_start + } + + pub fn pa_length(&self, idx: usize) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.pa_region[idx].pa_length + } + + pub fn pa_offset(&self, idx: usize) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.pa_region[idx].offset as usize + } + + pub fn set_mem_region_num(&self, mem_region_num: usize) { + let mut vm_inner = self.inner.lock(); + vm_inner.mem_region_num = mem_region_num; + } + + pub fn mem_region_num(&self) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.mem_region_num + } + + pub fn vgic(&self) -> Arc { + let vm_inner = self.inner.lock(); + match &vm_inner.emu_devs[vm_inner.intc_dev_id] { + EmuDevs::Vgic(vgic) => { + return vgic.clone(); + } + _ => { + panic!("vm{} cannot find vgic", vm_inner.id); + } + } + } + + pub fn has_vgic(&self) -> bool { + let vm_inner = self.inner.lock(); + if vm_inner.intc_dev_id >= vm_inner.emu_devs.len() { + return false; + } + match &vm_inner.emu_devs[vm_inner.intc_dev_id] { + EmuDevs::Vgic(_) => true, + _ => false, + } + } + + // TODO: should copy from or copy to addr, not copy from other vm + pub fn migrate_emu_devs(&self, src_vm: Vm) { + let mut vm_inner = self.inner.lock(); + for (idx, emu_dev) in vm_inner.emu_devs.iter_mut().enumerate() { + emu_dev.migrate_emu_devs(src_vm.emu_dev(idx)); + } + } + + pub fn emu_dev(&self, dev_id: usize) -> EmuDevs { + let vm_inner = self.inner.lock(); + vm_inner.emu_devs[dev_id].clone() + } + + pub fn emu_net_dev(&self, id: usize) -> EmuDevs { + let vm_inner = self.inner.lock(); + let mut dev_num = 0; + + for i in 0..vm_inner.emu_devs.len() { + match vm_inner.emu_devs[i] { + EmuDevs::VirtioNet(_) => { + if dev_num == id { + return vm_inner.emu_devs[i].clone(); + } + dev_num += 1; + } + _ => {} + } + } + return EmuDevs::None; + } + + pub fn emu_blk_dev(&self) -> EmuDevs { + for emu in &self.inner.lock().emu_devs { + if let EmuDevs::VirtioBlk(_) = emu { + return emu.clone(); + } + } + return EmuDevs::None; + } + + // Get console dev by ipa. + pub fn emu_console_dev(&self, ipa: usize) -> EmuDevs { + for (idx, emu_dev_cfg) in self.config().emulated_device_list().iter().enumerate() { + if emu_dev_cfg.base_ipa == ipa { + return self.inner.lock().emu_devs[idx].clone(); + } + } + // println!("emu_console_dev ipa {:x}", ipa); + // for (idx, emu_dev_cfg) in self.config().emulated_device_list().iter().enumerate() { + // println!("emu dev[{}], ipa 0x{:x}", idx, emu_dev_cfg.base_ipa); + // } + return EmuDevs::None; + } + + pub fn ncpu(&self) -> usize { + let vm_inner = self.inner.lock(); + vm_inner.ncpu + } + + pub fn has_interrupt(&self, int_id: usize) -> bool { + let mut vm_inner = self.inner.lock(); + vm_inner.int_bitmap.as_mut().unwrap().get(int_id) != 0 + } + + pub fn emu_has_interrupt(&self, int_id: usize) -> bool { + for emu_dev in self.config().emulated_device_list() { + if int_id == emu_dev.irq_id { + return true; + } + } + false + } + + pub fn vcpuid_to_pcpuid(&self, vcpuid: usize) -> Result { + // println!("vcpuid_to_pcpuid"); + let vm_inner = self.inner.lock(); + if vcpuid < vm_inner.cpu_num { + let vcpu = vm_inner.vcpu_list[vcpuid].clone(); + drop(vm_inner); + return Ok(vcpu.phys_id()); + } else { + return Err(()); + } + } + + pub fn pcpuid_to_vcpuid(&self, pcpuid: usize) -> Result { + let vm_inner = self.inner.lock(); + for vcpuid in 0..vm_inner.cpu_num { + if vm_inner.vcpu_list[vcpuid].phys_id() == pcpuid { + return Ok(vcpuid); + } + } + return Err(()); + } + + pub fn vcpu_to_pcpu_mask(&self, mask: usize, len: usize) -> usize { + let mut pmask = 0; + for i in 0..len { + let shift = self.vcpuid_to_pcpuid(i); + if mask & (1 << i) != 0 && !shift.is_err() { + pmask |= 1 << shift.unwrap(); + } + } + return pmask; + } + + pub fn pcpu_to_vcpu_mask(&self, mask: usize, len: usize) -> usize { + let mut pmask = 0; + for i in 0..len { + let shift = self.pcpuid_to_vcpuid(i); + if mask & (1 << i) != 0 && !shift.is_err() { + pmask |= 1 << shift.unwrap(); + } + } + return pmask; + } + + pub fn show_pagetable(&self, ipa: usize) { + let vm_inner = self.inner.lock(); + vm_inner.pt.as_ref().unwrap().show_pt(ipa); + } + + pub fn ready(&self) -> bool { + let vm_inner = self.inner.lock(); + vm_inner.ready + } + + pub fn set_ready(&self, _ready: bool) { + let mut vm_inner = self.inner.lock(); + vm_inner.ready = _ready; + } + + // init for migrate restore + pub fn context_vm_migrate_init(&self) { + let mvm = vm(0).unwrap(); + // for i in 0..self.ncpu() { + let size = size_of::(); + // println!("context_vm_migrate_init: VM Data size 0x{:x}", size); + match mem_pages_alloc(round_up(size, PAGE_SIZE) / PAGE_SIZE) { + Ok(pf) => { + mvm.pt_map_range( + get_share_mem(VM_CONTEXT_RECEIVE), + round_up(size, PAGE_SIZE), + pf.pa(), + PTE_S2_NORMAL, + true, + ); + let mut inner = self.inner.lock(); + inner.migrate_restore_pf.push(pf); + } + Err(_) => { + panic!("context_vm_migrate_restore_init: mem_pages_alloc for vm context failed"); + } + } + // } + } + + pub fn context_vm_migrate_save(&self) { + let mvm = vm(0).unwrap(); + let size = size_of::(); + match mem_pages_alloc(round_up(size, PAGE_SIZE) / PAGE_SIZE) { + Ok(pf) => { + let mut vm_data = unsafe { &mut *(pf.pa as *mut VMData) }; + let base = get_share_mem(VM_CONTEXT_SEND); + // println!("pt map base 0x{:x} size 0x{:x}", base, size); + mvm.pt_map_range(base, round_up(size, PAGE_SIZE), pf.pa(), PTE_S2_RO, true); + + // key: pcpuid, val: vcpuid + let mut cpuid_map: BTreeMap = BTreeMap::new(); + for vcpu_id in 0..self.cpu_num() { + let vcpu = self.vcpu(vcpu_id).unwrap(); + // vm context + vcpu.migrate_vm_ctx_save(&(vm_data.vm_ctx[vcpu_id]) as *const _ as usize); + // vcpu context + vcpu.migrate_vcpu_ctx_save(&(vm_data.vcpu_ctx[vcpu_id]) as *const _ as usize); + // cpu gic context + vcpu.migrate_gic_ctx_save(&(vm_data.gic_ctx[vcpu_id]) as *const _ as usize); + cpuid_map.insert(self.vcpuid_to_pcpuid(vcpu_id).unwrap(), vcpu_id); + } + + let mut inner = self.inner.lock(); + for (idx, emu) in inner.emu_devs.iter().enumerate() { + match emu { + EmuDevs::Vgic(vgic) => { + vgic.save_vgic_data(&mut vm_data.vgic_ctx, &cpuid_map); + } + EmuDevs::VirtioBlk(mmio) => { + vm_data.emu_devs[idx] = EmuDevData::VirtioBlk(VirtioMmioData::default()); + if let EmuDevData::VirtioBlk(mmio_data) = &mut vm_data.emu_devs[idx] { + // println!("vm[{}] save virtio blk", inner.id); + mmio.save_mmio_data(mmio_data, &inner.pa_region); + } + } + EmuDevs::VirtioNet(mmio) => { + vm_data.emu_devs[idx] = EmuDevData::VirtioNet(VirtioMmioData::default()); + if let EmuDevData::VirtioNet(mmio_data) = &mut vm_data.emu_devs[idx] { + // println!("vm[{}] save virtio net", inner.id); + mmio.save_mmio_data(mmio_data, &inner.pa_region); + } + } + EmuDevs::VirtioConsole(mmio) => { + vm_data.emu_devs[idx] = EmuDevData::VirtioConsole(VirtioMmioData::default()); + if let EmuDevData::VirtioConsole(mmio_data) = &mut vm_data.emu_devs[idx] { + // println!("vm[{}] save virtio console", inner.id); + mmio.save_mmio_data(mmio_data, &inner.pa_region); + } + } + EmuDevs::None => {} + } + } + inner.migrate_save_pf.push(pf); + } + Err(_) => {} + } + } + + pub fn context_vm_migrate_restore(&self) { + // key: vcpuid, val: pcpuid + let mut vcpuid_map: BTreeMap = BTreeMap::new(); + for vcpu_id in 0..self.cpu_num() { + vcpuid_map.insert(vcpu_id, self.vcpuid_to_pcpuid(vcpu_id).unwrap()); + } + let inner = self.inner.lock(); + let pa = inner.migrate_restore_pf[0].pa(); + let vm_data = unsafe { &mut *(pa as *mut VMData) }; + // migrate emu dev + for (idx, emu) in inner.emu_devs.iter().enumerate() { + match emu { + EmuDevs::Vgic(vgic) => { + vgic.restore_vgic_data(&vm_data.vgic_ctx, &inner.vcpu_list, &vcpuid_map); + } + EmuDevs::VirtioBlk(mmio) => { + if let EmuDevData::VirtioBlk(mmio_data) = &vm_data.emu_devs[idx] { + mmio.restore_mmio_data(mmio_data, &inner.pa_region); + } + } + EmuDevs::VirtioNet(mmio) => { + // println!("context_vm_migrate_restore: net"); + if let EmuDevData::VirtioNet(mmio_data) = &vm_data.emu_devs[idx] { + mmio.restore_mmio_data(mmio_data, &inner.pa_region); + } + } + EmuDevs::VirtioConsole(mmio) => { + // println!("context_vm_migrate_restore: console"); + if let EmuDevData::VirtioConsole(mmio_data) = &mut vm_data.emu_devs[idx] { + mmio.restore_mmio_data(mmio_data, &inner.pa_region); + } + } + EmuDevs::None => {} + } + } + drop(inner); + for vcpu_id in 0..self.cpu_num() { + let vcpu = self.vcpu(vcpu_id).unwrap(); + vcpu.migrate_vm_ctx_restore(&vm_data.vm_ctx[vcpu_id] as *const _ as usize); + vcpu.migrate_vcpu_ctx_restore(&vm_data.vcpu_ctx[vcpu_id] as *const _ as usize); + // cpu gic context + vcpu.migrate_gic_ctx_restore(&(vm_data.gic_ctx[vcpu_id]) as *const _ as usize); + } + } + + pub fn share_mem_base(&self) -> usize { + let inner = self.inner.lock(); + inner.share_mem_base + } + + pub fn add_share_mem_base(&self, len: usize) { + let mut inner = self.inner.lock(); + inner.share_mem_base += len; + } +} + +#[repr(align(4096))] +pub struct VmInner { + pub id: usize, + pub ready: bool, + pub config: Option, + pub dtb: Option, + // memory config + pub pt: Option, + pub mem_region_num: usize, + pub pa_region: Vec, // Option<[VmPa; VM_MEM_REGION_MAX]>, + + // image config + pub entry_point: usize, + + // vcpu config + pub has_master: bool, + pub vcpu_list: Vec, + pub cpu_num: usize, + pub ncpu: usize, + + // interrupt + pub intc_dev_id: usize, + pub int_bitmap: Option>, + + // migration + // pub migration_state: bool, + pub share_mem_base: usize, + pub migrate_save_pf: Vec, + pub migrate_restore_pf: Vec, + + // iommu + pub iommu_ctx_id: Option, + + // emul devs + pub emu_devs: Vec, + pub med_blk_id: Option, +} + +impl VmInner { + pub const fn default() -> VmInner { + VmInner { + id: 0, + ready: false, + config: None, + dtb: None, + pt: None, + mem_region_num: 0, + pa_region: Vec::new(), + entry_point: 0, + + has_master: false, + vcpu_list: Vec::new(), + cpu_num: 0, + ncpu: 0, + + intc_dev_id: 0, + int_bitmap: Some(BitAlloc4K::default()), + // migration_state: false, + share_mem_base: SHARE_MEM_BASE, // hard code + migrate_save_pf: vec![], + migrate_restore_pf: vec![], + + iommu_ctx_id: None, + emu_devs: Vec::new(), + med_blk_id: None, + } + } + + pub fn new(id: usize) -> VmInner { + VmInner { + id, + ready: false, + config: None, + dtb: None, + pt: None, + mem_region_num: 0, + pa_region: Vec::new(), + entry_point: 0, + + has_master: false, + vcpu_list: Vec::new(), + cpu_num: 0, + ncpu: 0, + + intc_dev_id: 0, + int_bitmap: Some(BitAlloc4K::default()), + // migration_state: false, + share_mem_base: SHARE_MEM_BASE, // hard code + migrate_save_pf: vec![], + migrate_restore_pf: vec![], + iommu_ctx_id: None, + emu_devs: Vec::new(), + med_blk_id: None, + } + } +} + +pub static VM_LIST: Mutex> = Mutex::new(Vec::new()); + +pub fn push_vm(id: usize) -> Result<(), ()> { + let mut vm_list = VM_LIST.lock(); + if vm_list.iter().any(|x| x.id() == id) { + println!("push_vm: vm {} already exists", id); + Err(()) + } else { + vm_list.push(Vm::new(id)); + Ok(()) + } +} + +pub fn remove_vm(id: usize) -> Vm { + let mut vm_list = VM_LIST.lock(); + match vm_list.iter().position(|x| x.id() == id) { + None => { + panic!("VM[{}] not exist in VM LIST", id); + } + Some(idx) => vm_list.remove(idx), + } +} + +pub fn vm(id: usize) -> Option { + let vm_list = VM_LIST.lock(); + vm_list.iter().find(|&x| x.id() == id).cloned() +} + +pub fn vm_list_size() -> usize { + let vm_list = VM_LIST.lock(); + vm_list.len() +} + +pub fn vm_ipa2pa(vm: Vm, ipa: usize) -> usize { + if ipa == 0 { + println!("vm_ipa2pa: VM {} access invalid ipa {:x}", vm.id(), ipa); + return 0; + } + + for i in 0..vm.mem_region_num() { + if in_range( + (ipa as isize - vm.pa_offset(i) as isize) as usize, + vm.pa_start(i), + vm.pa_length(i), + ) { + return (ipa as isize - vm.pa_offset(i) as isize) as usize; + } + } + + println!("vm_ipa2pa: VM {} access invalid ipa {:x}", vm.id(), ipa); + return 0; +} + +pub fn vm_pa2ipa(vm: Vm, pa: usize) -> usize { + if pa == 0 { + println!("vm_pa2ipa: VM {} access invalid pa {:x}", vm.id(), pa); + return 0; + } + + for i in 0..vm.mem_region_num() { + if in_range(pa, vm.pa_start(i), vm.pa_length(i)) { + return (pa as isize + vm.pa_offset(i) as isize) as usize; + } + } + + println!("vm_pa2ipa: VM {} access invalid pa {:x}", vm.id(), pa); + return 0; +} + +pub fn pa2ipa(pa_region: &Vec, pa: usize) -> usize { + if pa == 0 { + println!("pa2ipa: access invalid pa {:x}", pa); + return 0; + } + + for region in pa_region.iter() { + if in_range(pa, region.pa_start, region.pa_length) { + return (pa as isize + region.offset) as usize; + } + } + + println!("pa2ipa: access invalid pa {:x}", pa); + return 0; +} + +pub fn ipa2pa(pa_region: &Vec, ipa: usize) -> usize { + if ipa == 0 { + // println!("ipa2pa: access invalid ipa {:x}", ipa); + return 0; + } + + for region in pa_region.iter() { + if in_range( + (ipa as isize - region.offset) as usize, + region.pa_start, + region.pa_length, + ) { + return (ipa as isize - region.offset) as usize; + } + } + + // println!("ipa2pa: access invalid ipa {:x}", ipa); + return 0; +} diff --git a/src/lib/barrier.rs b/src/lib/barrier.rs new file mode 100644 index 0000000000000000000000000000000000000000..e76ad3cc7c7d02c1217f457914b08839f7c496c7 --- /dev/null +++ b/src/lib/barrier.rs @@ -0,0 +1,62 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::ptr; +use core::sync::atomic::AtomicUsize; +use core::sync::atomic::Ordering; + +use crate::board::PLAT_DESC; +use crate::lib::round_up; + +struct CpuSyncToken { + n: usize, + count: AtomicUsize, + ready: bool, +} + +static mut CPU_GLB_SYNC: CpuSyncToken = CpuSyncToken { + n: PLAT_DESC.cpu_desc.num, + count: AtomicUsize::new(0), + ready: true, +}; + +static mut CPU_FUNC_SYNC: CpuSyncToken = CpuSyncToken { + n: 0, + count: AtomicUsize::new(0), + ready: true, +}; + +#[inline(never)] +pub fn barrier() { + unsafe { + let ori = CPU_GLB_SYNC.count.fetch_add(1, Ordering::Relaxed); + let next_count = round_up(ori + 1, CPU_GLB_SYNC.n); + while CPU_GLB_SYNC.count.load(Ordering::Acquire) < next_count { + core::hint::spin_loop(); + } + } +} + +#[inline(never)] +pub fn func_barrier() { + unsafe { + let ori = CPU_FUNC_SYNC.count.fetch_add(1, Ordering::Relaxed); + let next_count = round_up(ori + 1, CPU_FUNC_SYNC.n); + while CPU_FUNC_SYNC.count.load(Ordering::Acquire) < next_count { + core::hint::spin_loop(); + } + } +} + +pub fn set_barrier_num(num: usize) { + unsafe { + ptr::write_volatile(&mut CPU_FUNC_SYNC.n, num); + } +} diff --git a/src/lib/bitmap.rs b/src/lib/bitmap.rs new file mode 100644 index 0000000000000000000000000000000000000000..14760344a82ce39d9bc8f96d25fde471fed45f62 --- /dev/null +++ b/src/lib/bitmap.rs @@ -0,0 +1,264 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +// const BITMAP_SIZE: usize = 0x3000; +// const BITMAP_ATOMIC_SIZE: usize = 64; + +// type BitmapAtomicType = u64; + +// type BitMap([Bitmap]) + +use alloc::vec::Vec; + +use crate::lib::bit_get; + +pub trait BitAlloc { + // The bitmap has a total of CAP bits, numbered from 0 to CAP-1 inclusively. + const CAP: usize; + + // The default value. Workaround for `const fn new() -> Self`. + #[allow(clippy::declare_interior_mutable_const)] + const DEFAULT: Self; + + // Set a bit. + fn set(&mut self, idx: usize); + + // Clear a bit + fn clear(&mut self, idx: usize); + + // Get a bit + fn get(&self, idx: usize) -> usize; + + // Whether there are free bits remaining + // fn any(&self) -> bool; +} + +// A bitmap of 4K bits +pub type BitAlloc256 = BitMap; +// A bitmap of 4K bits +pub type BitAlloc4K = BitMap; +// A bitmap of 64K bits +pub type BitAlloc64K = BitMap; +// A bitmap of 1M bits +pub type BitAlloc1M = BitMap; +// A bitmap of 16M bits +pub type BitAlloc16M = BitMap; +// A bitmap of 256M bits +pub type BitAlloc256M = BitMap; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct BitMap { + // bitset: u16, + map: [T; 16], +} + +impl BitMap { + pub const fn default() -> BitMap { + BitMap:: { map: [T::DEFAULT; 16] } + } +} + +impl BitAlloc for BitMap { + const CAP: usize = T::CAP * 16; + + const DEFAULT: Self = BitMap { + // bitset: 0, + map: [T::DEFAULT; 16], + }; + + fn set(&mut self, idx: usize) { + let i = idx / T::CAP; + self.map[i].set(idx % T::CAP); + // self.0 = self.0 | (1 << i); + } + + fn clear(&mut self, idx: usize) { + let i = idx / T::CAP; + self.map[i].clear(idx % T::CAP); + // self.0 = self.0 & (!(1 << idx) & 0xffff); + } + + fn get(&self, idx: usize) -> usize { + let i = idx / T::CAP; + self.map[i].get(idx % T::CAP) + } +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Eq)] +pub struct BitAlloc16(u16); + +impl PartialEq for BitAlloc16 { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl BitAlloc16 { + pub const fn default() -> BitAlloc16 { + BitAlloc16(0) + } +} + +impl BitAlloc for BitAlloc16 { + const CAP: usize = 16; + const DEFAULT: Self = BitAlloc16(0); + + fn set(&mut self, idx: usize) { + self.0 = self.0 | (1 << idx); + } + + fn clear(&mut self, idx: usize) { + self.0 = self.0 & (!(1 << idx) & 0xffff); + } + + fn get(&self, idx: usize) -> usize { + if self.0 & (1 << idx) != 0 { + 1 + } else { + 0 + } + } +} + +// flex bit map +#[derive(Clone)] +pub struct FlexBitmap { + pub len: usize, + pub map: Vec, +} + +impl FlexBitmap { + pub fn new(len: usize) -> FlexBitmap { + let map = vec![0; (len + 64 - 1) / 64]; + FlexBitmap { len, map } + } + + pub fn init_dirty(&mut self) { + for i in 0..self.map.len() { + self.map[i] = usize::MAX; + } + } + + pub fn clear(&mut self) { + for i in 0..self.map.len() { + self.map[i] = 0; + } + } + + pub fn get(&self, idx: usize) -> usize { + if idx > self.len { + panic!("too large idx {} for get bitmap", idx); + } + let val = self.map[idx / 64]; + bit_get(val, idx % 64) + } + + pub fn set(&mut self, bit: usize, val: bool) { + if bit > self.len { + panic!("too large idx {} for set bitmap", bit); + } + if val { + self.map[bit / 64] |= 1 << (bit % 64); + } else { + self.map[bit / 64] &= !(1 << (bit % 64)); + } + } + + pub fn set_bits(&mut self, bit: usize, len: usize, val: bool) { + if bit + len > self.len { + panic!("set_bits: too large idx {} for set bitmap", bit); + } + // 默认2MB或1KB对齐 + if len == 1 { + self.set(bit, val); + } else { + if bit % 64 != 0 || (bit + len) % 64 != 0 { + panic!("set_bits: bit start and len should align with 64"); + } + + let mut head = bit; + while head < (bit + len) { + self.map[head / 64] = if val { usize::MAX } else { 0 }; + head += 64; + } + } + } + + pub fn slice(&self) -> &[usize] { + self.map.as_slice() + } + + pub fn vec_len(&self) -> usize { + self.map.len() + } + + pub fn sum(&self) -> usize { + let mut sum = 0; + for val in &self.map { + sum += val.count_ones() as usize; + } + sum + } + + pub fn first(&self) -> usize { + let mut first = 0; + for val in &self.map { + if *val == 0 { + first += 64; + } else { + let mut tmp = *val; + while (tmp & 1) == 0 { + tmp = tmp >> 1; + first += 1; + } + return first; + } + } + println!("all is 0"); + first + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bitalloc16() { + let mut bitmap = BitAlloc16::default(); + let mut value = bitmap.get(11); + assert_eq!(value, 0); + + bitmap.set(11); + value = bitmap.get(11); + assert_eq!(value, 1); + + bitmap.clear(11); + value = bitmap.get(11); + assert_eq!(value, 0); + } + + #[test] + fn bitalloc256() { + let mut bitmap = BitAlloc256::default(); + let mut value = bitmap.get(121); + assert_eq!(value, 0); + + bitmap.set(121); + value = bitmap.get(121); + assert_eq!(value, 1); + + bitmap.clear(11); + value = bitmap.get(121); + assert_eq!(value, 0); + } +} diff --git a/src/lib/cache.rs b/src/lib/cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..616c383b739ea14a31c06492d820490fefec6d66 --- /dev/null +++ b/src/lib/cache.rs @@ -0,0 +1,18 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::arch::global_asm; + +global_asm!(include_str!("../arch/aarch64/cache.S")); + +extern "C" { + pub fn cache_invalidate_d(start: usize, len: usize); + pub fn cache_clean_invalidate_d(start: usize, len: usize); +} diff --git a/src/lib/fatfs.rs b/src/lib/fatfs.rs new file mode 100644 index 0000000000000000000000000000000000000000..01edd3a638bac3e4623cb0864325ebae5c3faf5f --- /dev/null +++ b/src/lib/fatfs.rs @@ -0,0 +1,198 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core_io as io; +use io::{Read, SeekFrom}; +use io::prelude::*; + +use crate::arch::PAGE_SIZE; +use crate::board::{DISK_PARTITION_0_START, platform_blk_read}; + +use super::{round_down, round_up}; + +struct Disk { + pointer: usize, + size: usize, +} + +impl Disk { + const fn default() -> Disk { + Disk { + pointer: 0, + size: 0, + } + } +} + +// TODO: add fatfs read +impl core_io::Read for Disk { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let sector = round_down(self.pointer, 512) / 512; + let offset = self.pointer - round_down(self.pointer, 512); + let count = round_up(offset + buf.len(), 512) / 512; + assert!(count <= 8); + if buf.len() == PAGE_SIZE { + let addr = buf.as_ptr() as usize; + platform_blk_read(sector + DISK_PARTITION_0_START, count, addr); + return Ok(buf.len()); + } + + let result = crate::kernel::mem_page_alloc(); + if let Ok(frame) = result { + // if count >= 4 { + // println!( + // "read sector {} count {} offset {} buf.len {} pointer {}", + // sector, + // count, + // offset, + // buf.len(), + // self.pointer + // ); + // } + platform_blk_read(sector + DISK_PARTITION_0_START, count, frame.pa()); + for i in 0..buf.len() { + buf[i] = frame.as_slice()[offset + i]; + // print!("{}", buf[i]); + } + self.pointer += buf.len(); + Ok(buf.len()) + } else { + println!("read failed"); + Ok(0) + } + } +} + +impl core_io::Write for Disk { + fn flush(&mut self) -> io::Result<()> { + // println!("in flush"); + Ok(()) + } + + // TODO: add fatfs write + fn write(&mut self, buf: &[u8]) -> io::Result { + println!("in write"); + println!("write dropped"); + Ok(0) + } +} + +impl core_io::Seek for Disk { + fn seek(&mut self, pos: SeekFrom) -> io::Result { + match pos { + SeekFrom::Start(u) => { + self.pointer = u as usize; + } + SeekFrom::End(i) => { + self.pointer = self.size - (i as usize); + } + SeekFrom::Current(i) => { + self.pointer += i as usize; + } + } + Ok(self.pointer as u64) + } +} + +// lazy_static! { +// static FS: Mutex>> = Mutex::new(None); +// } +// static ROOT_DIR: Mutex>> = Mutex::new(None); + +pub fn fs_init() { + // let mut disk = Disk { + // pointer: 0, + // size: 536870912, + // }; + + // // let fs = FS.lock(); + // let mut fs: io::Result> = + // fatfs::FileSystem::new(&mut disk, fatfs::FsOptions::new()); + + // let fs = fatfs::FileSystem::new(&mut disk, fatfs::FsOptions::new()).unwrap(); + // let root_dir = fs.root_dir(); + // let file = root_dir.open_file("hello.txt"); + // match file { + // Ok(mut file) => { + // let mut buf = [0u8; 5000]; + // // let len = file.seek(SeekFrom::End(0)).unwrap(); + // file.read(&mut buf); + // file.read(&mut buf[4096..]); + // let mut idx = 0; + // for i in 0..buf.len() { + // let val = buf[i as usize]; + // if val != 0 { + // idx += 1; + // } + // // let tmp = char::from_u32(val as u32); + // // print!("{}", tmp.unwrap()); + // } + // println!("idx is {}", idx); + // println!("FAT file system init ok"); + // } + // Err(_) => { + // println!("err"); + // } + // } +} + +pub fn fs_read_to_mem(filename: &str, buf: &mut [u8]) -> bool { + let mut disk = Disk { + pointer: 0, + size: 536870912, + }; + let count = round_up(buf.len(), PAGE_SIZE) / PAGE_SIZE; + + let fs = fatfs::FileSystem::new(&mut disk, fatfs::FsOptions::new()).unwrap(); + let root_dir = fs.root_dir(); + let file = root_dir.open_file(filename); + match file { + Ok(mut file) => { + for i in 0..count { + if i + 1 != count { + file.read(&mut buf[i * PAGE_SIZE..(i + 1) * PAGE_SIZE]); + } else { + file.read(&mut buf[i * PAGE_SIZE..]); + } + } + return true; + } + Err(_) => { + println!("read file {} failed!", filename); + return false; + } + } +} + +pub fn fs_file_size(filename: &str) -> usize { + let mut disk = Disk { + pointer: 0, + size: 536870912, + }; + let result = fatfs::FileSystem::new(&mut disk, fatfs::FsOptions::new()); + match result { + Ok(fs) => { + let root_dir = fs.root_dir(); + let file = root_dir.open_file(filename); + match file { + Ok(mut file) => { + return file.seek(SeekFrom::End(0)).unwrap() as usize; + } + Err(_) => { + return 0; + } + } + } + Err(err) => { + panic!("Err is {:#?}", err); + } + } + // let fs = .unwrap(); +} diff --git a/src/lib/mod.rs b/src/lib/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..1b0fbbad78505a68270b1fd58838b67fada0802c --- /dev/null +++ b/src/lib/mod.rs @@ -0,0 +1,28 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::barrier::*; +pub use self::bitmap::*; +pub use self::cache::*; +// pub use self::fatfs::*; +pub use self::print::*; +pub use self::string::*; +pub use self::time::*; +pub use self::util::*; + +mod barrier; +mod bitmap; +// mod fatfs; +mod cache; +mod print; +mod string; +mod time; +mod util; +pub mod unilib; \ No newline at end of file diff --git a/src/lib/print.rs b/src/lib/print.rs new file mode 100644 index 0000000000000000000000000000000000000000..82dc2303cb2f48dc5a44d80241337be38c8cae9d --- /dev/null +++ b/src/lib/print.rs @@ -0,0 +1,32 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::fmt::{Arguments, Write}; + +use spin::Mutex; + +pub struct Writer; + +static WRITER: Mutex = Mutex::new(Writer); + +impl Write for Writer { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + for b in s.bytes() { + crate::driver::putc(b); + } + Ok(()) + } +} + +pub fn _print(args: Arguments) { + // use core::fmt::Write; + let mut lock = WRITER.lock(); + lock.write_fmt(args).unwrap(); +} diff --git a/src/lib/string.rs b/src/lib/string.rs new file mode 100644 index 0000000000000000000000000000000000000000..f89b848bbdc9cdebc8a0f8e4b140eedc19b2cbaf --- /dev/null +++ b/src/lib/string.rs @@ -0,0 +1,32 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::arch::global_asm; + +global_asm!(include_str!("../arch/aarch64/memset.S")); +global_asm!(include_str!("../arch/aarch64/memcpy.S")); +extern "C" { + pub fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8; + pub fn memcpy(s1: *const u8, s2: *const u8, n: usize) -> *mut u8; +} + +pub fn memset_safe(s: *mut u8, c: i32, n: usize) -> *mut u8 { + if (s as usize) < 0x1000 { + panic!("illegal addr for memset s {:x}", s as usize); + } + unsafe { memset(s, c, n) } +} + +pub fn memcpy_safe(s1: *const u8, s2: *const u8, n: usize) -> *mut u8 { + if (s1 as usize) < 0x1000 || (s2 as usize) < 0x1000 { + panic!("illegal addr for memcpy s1 {:x} s2 {:x}", s1 as usize, s2 as usize); + } + unsafe { memcpy(s1, s2, n) } +} diff --git a/src/lib/time.rs b/src/lib/time.rs new file mode 100644 index 0000000000000000000000000000000000000000..a5d04de543fff8df62ed402d7d46d37130943bd3 --- /dev/null +++ b/src/lib/time.rs @@ -0,0 +1,30 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::{timer_arch_get_counter, timer_arch_get_frequency}; + +pub fn time_current_us() -> usize { + let count = timer_arch_get_counter(); + let freq = timer_arch_get_frequency(); + count * 1000000 / freq +} + +pub fn time_current_ms() -> usize { + let count = timer_arch_get_counter(); + let freq = timer_arch_get_frequency(); + count * 1000 / freq +} + +pub fn sleep(us: usize) { + let end = time_current_us() + us; + while time_current_us() < end { + core::hint::spin_loop(); + } +} diff --git a/src/lib/unilib.rs b/src/lib/unilib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f9460958a4a6c85025d0b137ce05389599ca340a --- /dev/null +++ b/src/lib/unilib.rs @@ -0,0 +1,463 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +/** + * This module is used to forward the unilib request from Unishyper to MVM. + * Note: + * Currently it's a synchronous process, which means it's unefficient. + * In the case of 1-to-1 CPU partion strategy, I don't think it's a problem. + * But for different Unishypers runs on one single CPU, stucking in EL2 may cause a big efficiency problem, + * We still need some notify mechanism to improve the CPU usage. + */ +use alloc::collections::BTreeMap; + +use spin::Mutex; + +use crate::lib::{memcpy_safe, sleep}; +use crate::kernel::{vm_ipa2pa, active_vm, HVC_UNILIB_FS_INIT, HVC_UNILIB_FS_LSEEK}; +use crate::kernel::{HvcGuestMsg, HvcUniLibMsg, hvc_send_msg_to_vm}; +use crate::kernel::HVC_UNILIB; +use crate::kernel::{HVC_UNILIB_FS_OPEN, HVC_UNILIB_FS_CLOSE, HVC_UNILIB_FS_READ, HVC_UNILIB_FS_WRITE}; + +pub static UNILIB_FS_LIST: Mutex> = Mutex::new(BTreeMap::new()); + +#[repr(C)] +pub struct UnilibFSCfg { + /// The name of this UnilibFS, it may used to identify the path of UnilibFS in MVM. + name: [u8; 32], + /// The "client" VM who owns this `UnilibFSCfg`, currently it should be our Unishyper. + vmid: usize, + /// Size of FS opration buffer, it's provided by the MVM with HUGE_TLB enabled. + cache_size: usize, + /// Virtual address of FS opration buffer, it's provided by the MVM with HUGE_TLB enabled. + buf_va: usize, + /// Intermediate physical address of FS opration buffer, it's provided by the MVM with HUGE_TLB enabled. + buf_ipa: usize, + /// Acutal physical address of FS opration buffer, it's set by the hypervisor during `unilib_fs_append` process. + buf_pa: usize, +} + +#[repr(C)] +pub struct UnilibFSOpsRes { + /// Before each operation, we need to zero the flag field. + /// When operation is completed by MVM, MVM's kernel module will set this field as the "client" OS's vm_id. + flag: usize, + /// The field `value` stores the operation result of MVM. + /// It's set by the MVM, we alse need to reset it before each operation. + value: usize, +} + +/// This struct contains basic information about the UnilibFS, which shared between MVM and hypervisor. +/// * UnilibFSCfg: stores the config information. +/// * UnilibFSOpsRes: stores the operation result of MVM. +#[repr(C)] +pub struct UnilibFSContent { + cfg: UnilibFSCfg, + res: UnilibFSOpsRes, +} + +#[derive(Clone)] +pub struct UnilibFS { + pub base_addr: usize, +} + +impl UnilibFS { + /// Get the actual content of UnilibFS config, it's just a dereference from base_addr, which is unsafe. + fn content(&self) -> &mut UnilibFSContent { + unsafe { &mut *(self.base_addr as *mut UnilibFSContent) } + } + + fn vm_id(&self) -> usize { + self.content().cfg.vmid + } + + fn get_buf(&self) -> *mut u8 { + self.content().cfg.buf_pa as *mut u8 + } + + fn buf_ipa(&self) -> usize { + self.content().cfg.buf_ipa + } + + fn set_buf_pa(&self, buf_pa: usize) { + self.content().cfg.buf_pa = buf_pa + } + + fn flag(&self) -> usize { + self.content().res.flag + } + + fn zero_flag(&self) { + self.content().res.flag = 0; + } + + fn value(&self) -> usize { + self.content().res.value + } + + fn zero_value(&self) { + self.content().res.value = 0 + } + + /// Before each fs operation is sent to MVM, this function is use to reset the `UnilibFSOpsRes` field. + fn prepare_for_request(&self) { + self.zero_flag(); + self.zero_value(); + } + + /// The main loop logic of synchronous process, it's stupid!!! + /// The fs operation from guest VM should be synchronous, + /// but current CPU need to wait for the implementation of MVM, and the IPI process is a asynchronous process. + /// So we need to wait here and periodicly check the flag of `UnilibFSOpsRes`. + fn loop_for_response(&self) -> usize { + loop { + if self.flag() != 0 { + println!("unilib operation finished, flag {}, value {}", self.flag(), self.value()); + break self.value(); + } + sleep(1); + } + } +} + +pub fn unilib_fs_remove(vm_id: usize) { + // println!("unilib_fs_remove: VM[{}] umount unilib-fs", vm_id); + let mut lock = UNILIB_FS_LIST.lock(); + lock.remove(&vm_id); +} + +/// Init the UnilibFS of guest VM, triggered by GVM through a HVC call, HVC_UNILIB | HVC_UNILIB_FS_INIT. +/// This function generates a HvcGuestMsg to tell the MVM to init a new `UnilibFS` structure for this GVM. +/// The MVM's setting up process mainly happens in shyper-cli. +/// It's also a synchronous process, after send out the hvc guest msg, this function will enter a loop, +/// wait for the MVM(VM 0) to initialize the `UnilibFS` structure and insert it into `UNILIB_FS_LIST`. +pub fn unilib_fs_init() -> Result { + let vm = active_vm().unwrap(); + let vm_id = vm.id(); + println!("unilib_fs_init: VM[{}] init unilib-fs", vm.id()); + let unilib_msg = HvcUniLibMsg { + fid: HVC_UNILIB, + event: HVC_UNILIB_FS_INIT, + vm_id: vm.id(), + arg_1: 0, + arg_2: 0, + arg_3: 0, + }; + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::UniLib(unilib_msg)) { + println!("unilib fs init: failed to notify VM 0"); + return Err(()); + } + // Enter a loop, wait for VM0 to setup the unilib fs config struct. + loop { + let lock = UNILIB_FS_LIST.lock(); + match lock.get(&vm_id) { + Some(_) => { + println!("unilib_fs_init, fs append success, return"); + drop(lock); + return Ok(0); + } + _ => {} + } + drop(lock); + sleep(5); + } +} + +/// Init the UnilibFS for guest VM, triggered by MVM through a HVC call, HVC_UNILIB | HVC_UNILIB_FS_APPEND. +/// After MVM's user daemon thread allocate the memory space for fs operation buffer, it'll tell the kernel module to setup the `UnilibFS` struct, +/// and then passed the ipa of `UnilibFS` struct to the hypervisor. +/// In this function, hypervisor calculates the actual physical address for fs operation buffer, set up the `UnilibFS` struct, +/// then insert it to `UNILIB_FS_LIST`. +/// After this function, `unilib_fs_init` should finished and return to GVM on EL1. +/// ## Arguments +/// * `mmio_ipa` - The intermediated physical address of target GVM's `UnilibFS` struct provided ny MVM. +pub fn unilib_fs_append(mmio_ipa: usize) -> Result { + let vm = active_vm().unwrap(); + let mmio_pa = vm_ipa2pa(vm.clone(), mmio_ipa); + let unilib_fs = UnilibFS { base_addr: mmio_pa }; + let buf_pa = vm_ipa2pa(vm.clone(), unilib_fs.buf_ipa()); + println!( + "unilib_fs_append: VM[{}] fs_mmio_ipa 0x{:x}, buf ipa 0x{:x}, buf_pa 0x{:x}", + unilib_fs.vm_id(), + mmio_ipa, + unilib_fs.buf_ipa(), + buf_pa + ); + unilib_fs.set_buf_pa(buf_pa); + UNILIB_FS_LIST.lock().insert(unilib_fs.vm_id(), unilib_fs); + Ok(0) +} + +/// Finished one unilib fs operation. +/// Currently this function is unused, cause we use a loop for polling. +/// We may need to design a nofity mechanism in the future. +/// ## Arguments +/// * `vm_id` - The target GVM's VM id of this unilib fs operation. +pub fn unilib_fs_finished(vm_id: usize) -> Result { + println!( + "unilib_fs_finished: VM[{}] fs io request is finished, currently unused", + vm_id + ); + Ok(0) +} + +/// **Open** API for unilib fs. +/// HVC_UNILIB | HVC_UNILIB_FS_OPEN +/// This function performs the open operation by send a HvcGuestMsg to MVM. +/// It's a synchronous process trigger by GVM. +/// If success, returns the **fd** of opened file wrapped by `Result` structure. +/// ## Arguments +/// * `path_start_ipa` - The intermediated physical address of the path that GVM wants to open through unilib-fs API. +/// * `path_length` - The string length of the path that GVM wants to open through unilib-fs API. +/// * `flags` - The flags of open API, we need to care about the transfer between C and Rust. +pub fn unilib_fs_open(path_start_ipa: usize, path_length: usize, flags: usize) -> Result { + let vm = active_vm().unwrap(); + let vm_id = vm.id(); + // println!( + // "VM[{}] unilib fs open path_ipa: {:x}, path_length {}, flags {}", + // vm_id, path_start_ipa, path_length, flags + // ); + // Get fs_cfg struct according to vm_id. + let fs_list_lock = UNILIB_FS_LIST.lock(); + let fs_cfg = match fs_list_lock.get(&vm_id) { + Some(cfg) => cfg, + None => { + println!("VM[{}] doesn't register a unilib fs, return", vm_id); + return Err(()); + } + }; + + // Copy path to unilib_fs buf, see UnilibFSCfg. + let path_pa = vm_ipa2pa(active_vm().unwrap(), path_start_ipa); + memcpy_safe(fs_cfg.get_buf(), path_pa as *mut u8, path_length); + // Add end '\0' for path buf. + unsafe { + *((fs_cfg.get_buf() as usize + path_length) as *mut u8) = 0u8; + } + + fs_cfg.prepare_for_request(); + + // Notify MVM to operate the fs operation. + let unilib_msg = HvcUniLibMsg { + fid: HVC_UNILIB, + event: HVC_UNILIB_FS_OPEN, + vm_id: vm.id(), + arg_1: path_length, + arg_2: flags, + arg_3: 0, + }; + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::UniLib(unilib_msg)) { + println!("unilib fs open: failed to notify VM 0"); + return Err(()); + } + + // Still, we need to enter a loop, wait for VM to complete operation. + Ok(fs_cfg.loop_for_response()) +} + +/// **Close** API for unilib fs. +/// HVC_UNILIB | HVC_UNILIB_FS_CLOSE +/// This function performs the close operation by send a HvcGuestMsg to MVM. +/// It's a synchronous process trigger by GVM. +/// If success, returns the return value of close opreation passed from MVM's C lib, wrapped by `Result` structure. +/// ## Arguments +/// * `fd` - The file descriptor of file to be closed. +pub fn unilib_fs_close(fd: usize) -> Result { + let vm = active_vm().unwrap(); + let vm_id = vm.id(); + // println!("VM[{}] unilib fs close fd {}", vm_id, fd); + + // Get fs_cfg struct according to vm_id. + let fs_list_lock = UNILIB_FS_LIST.lock(); + let fs_cfg = match fs_list_lock.get(&vm_id) { + Some(cfg) => cfg, + None => { + println!("VM[{}] doesn't register a unilib fs, return", vm_id); + return Err(()); + } + }; + + fs_cfg.prepare_for_request(); + + // Notify MVM to operate the fs operation. + let unilib_msg = HvcUniLibMsg { + fid: HVC_UNILIB, + event: HVC_UNILIB_FS_CLOSE, + vm_id, + arg_1: fd, + arg_2: 0, + arg_3: 0, + }; + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::UniLib(unilib_msg)) { + println!("unilib fs close: failed to notify VM 0"); + return Err(()); + } + // Still, we need to enter a loop, wait for VM to complete operation. + Ok(fs_cfg.loop_for_response()) +} + +/// **Read** API for unilib fs. +/// HVC_UNILIB | HVC_UNILIB_FS_READ +/// This function performs the read operation by send a HvcGuestMsg to MVM. +/// Read NBYTES into BUF from FD. +/// It's a synchronous process trigger by GVM. +/// If success, returns the number read, -1 for errors or 0 for EOF, wrapped by `Result` structure. +/// ## Arguments +/// * `fd` - The file descriptor of file to read. +/// * `buf_ipa` - The intermediated physical address of the buffer to be read into. +/// * `len` - Number of bytes to be read. +pub fn unilib_fs_read(fd: usize, buf_ipa: usize, len: usize) -> Result { + let vm = active_vm().unwrap(); + let vm_id = vm.id(); + // println!( + // "VM[{}] unilib fs read fd {}, buf_ipa {:x}, len {}", + // vm_id, fd, buf_ipa, len + // ); + // Get fs_cfg struct according to vm_id. + let fs_list_lock = UNILIB_FS_LIST.lock(); + let fs_cfg = match fs_list_lock.get(&vm_id) { + Some(cfg) => cfg, + None => { + println!("VM[{}] doesn't register a unilib fs, return", vm_id); + return Err(()); + } + }; + fs_cfg.prepare_for_request(); + // Notify MVM to operate the fs operation. + let unilib_msg = HvcUniLibMsg { + fid: HVC_UNILIB, + event: HVC_UNILIB_FS_READ, + vm_id: vm.id(), + arg_1: fd, + arg_2: len, + arg_3: 0, + }; + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::UniLib(unilib_msg)) { + println!("unilib fs read: failed to notify VM 0"); + return Err(()); + } + + // Still, we need to enter a loop, wait for VM to complete operation. + let res = fs_cfg.loop_for_response() as i64; + + if res < 0 { + return Ok(res as usize); + } + let buf_pa = vm_ipa2pa(vm.clone(), buf_ipa); + memcpy_safe(buf_pa as *mut u8, fs_cfg.get_buf(), fs_cfg.value()); + Ok(fs_cfg.value()) +} + +/// **Write** API for unilib fs. +/// HVC_UNILIB | HVC_UNILIB_FS_WRITE +/// This function performs the write operation by send a HvcGuestMsg to MVM. +/// Write N bytes of BUF to FD. Return the number written. +/// It's a synchronous process trigger by GVM. +/// If success, returns the number written, or -1, wrapped by `Result` structure. +/// ## Arguments +/// * `fd` - The file descriptor of file to write to. +/// * `buf_ipa` - The intermediated physical address of the buffer waiting to be written to the target file. +/// * `len` - Number of bytes to be written. +pub fn unilib_fs_write(fd: usize, buf_ipa: usize, len: usize) -> Result { + let vm = active_vm().unwrap(); + let vm_id = vm.id(); + // println!( + // "VM[{}] unilib fs write fd {}, buf_ipa {:x}, len {}", + // vm_id, fd, buf_ipa, len + // ); + + // Get fs_cfg struct according to vm_id. + let fs_list_lock = UNILIB_FS_LIST.lock(); + let fs_cfg = match fs_list_lock.get(&vm_id) { + Some(cfg) => cfg, + None => { + println!("VM[{}] doesn't register a unilib fs, return", vm_id); + return Err(()); + } + }; + let buf_pa = vm_ipa2pa(vm.clone(), buf_ipa); + memcpy_safe(fs_cfg.get_buf(), buf_pa as *mut u8, len); + + fs_cfg.prepare_for_request(); + + // Notify MVM to operate the fs operation. + let unilib_msg = HvcUniLibMsg { + fid: HVC_UNILIB, + event: HVC_UNILIB_FS_WRITE, + vm_id: vm.id(), + arg_1: fd, + arg_2: len, + arg_3: 0, + }; + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::UniLib(unilib_msg)) { + println!("unilib fs write: failed to notify VM 0"); + return Err(()); + } + + // Still, we need to enter a loop, wait for VM to complete operation. + Ok(fs_cfg.loop_for_response()) +} + +/// **Lseek** API for unilib fs. +/// HVC_UNILIB | HVC_UNILIB_FS_LSEEK +/// This function performs the lseek operation by send a HvcGuestMsg to MVM. +/// Reposition read/write file offset. +/// lseek() repositions the file offset of the open file description associated with the file descriptor fd to the argument offset according to the directive whence. +/// It's a synchronous process trigger by GVM. +/// Upon successful completion, lseek() returns the resulting offset +/// location as measured in bytes from the beginning of the file, wrapped by `Result` structure. +/// ## Arguments +/// * `fd` - The file descriptor of file. +/// * `offset` - The file offset of the open file. +/// * `whence` - Only can be these three following types currently: +/// SEEK_SET 0 : Seek from beginning of file, the file offset is set to offset bytes. +/// SEEK_CUR 1 : Seek from current position, the file offset is set to its current location plus offset bytes. +/// SEEK_END 2 : Seek from end of file, the file offset is set to the size of the file plus offset bytes. +pub fn unilib_fs_lseek(fd: usize, offset: usize, whence: usize) -> Result { + let vm = active_vm().unwrap(); + let vm_id = vm.id(); + // println!( + // "VM[{}] unilib fs lseek fd {}, offset {}, whence {}", + // vm_id, fd, offset, whence + // ); + // Get fs_cfg struct according to vm_id. + let fs_list_lock = UNILIB_FS_LIST.lock(); + let fs_cfg = match fs_list_lock.get(&vm_id) { + Some(cfg) => cfg, + None => { + println!("VM[{}] doesn't register a unilib fs, return", vm_id); + return Err(()); + } + }; + fs_cfg.prepare_for_request(); + + // Notify MVM to operate the fs operation. + let unilib_msg = HvcUniLibMsg { + fid: HVC_UNILIB, + event: HVC_UNILIB_FS_LSEEK, + vm_id: vm.id(), + arg_1: fd, + arg_2: offset, + arg_3: whence, + }; + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::UniLib(unilib_msg)) { + println!("unilib fs read: failed to notify VM 0"); + return Err(()); + } + // Still, we need to enter a loop, wait for VM to complete operation. + Ok(fs_cfg.loop_for_response()) +} + +/// **Stat** API for unilib fs. +/// HVC_UNILIB | HVC_UNILIB_FS_STAT +/// Currently unsupported. +pub fn unilib_fs_stat() -> Result { + unimplemented!("stat is unimplemented"); +} diff --git a/src/lib/util.rs b/src/lib/util.rs new file mode 100644 index 0000000000000000000000000000000000000000..f6631e6716564eccb056eb8956cf62938c334cd9 --- /dev/null +++ b/src/lib/util.rs @@ -0,0 +1,126 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::ptr; + +use spin::Mutex; + +use crate::arch::PAGE_SIZE; + +pub static TRACE: Mutex = Mutex::new(true); + +pub fn set_trace(value: bool) { + let mut trace = TRACE.lock(); + *trace = value; +} + +pub fn trace() -> bool { + let trace = TRACE.lock(); + *trace +} + +#[inline(always)] +pub fn round_up(value: usize, to: usize) -> usize { + ((value + to - 1) / to) * to +} + +#[inline(always)] +pub fn round_down(value: usize, to: usize) -> usize { + value & !(to - 1) +} + +#[inline(always)] +pub fn byte2page(byte: usize) -> usize { + round_up(byte, PAGE_SIZE) / PAGE_SIZE +} + +#[inline(always)] +pub fn range_in_range(base1: usize, size1: usize, base2: usize, size2: usize) -> bool { + (base1 >= base2) && ((base1 + size1) <= (base2 + size2)) +} + +#[inline(always)] +pub fn in_range(addr: usize, base: usize, size: usize) -> bool { + range_in_range(addr, 0, base, size) +} + +#[inline(always)] +pub fn bit_extract(bits: usize, off: usize, len: usize) -> usize { + (bits >> off) & ((1 << len) - 1) +} + +#[inline(always)] +pub fn bit_get(bits: usize, off: usize) -> usize { + (bits >> off) & 1 +} + +#[inline(always)] +pub fn bit_set(bits: usize, off: usize) -> usize { + bits | (1 << off) +} + +// change find nth +pub fn bitmap_find_nth(bitmap: usize, start: usize, size: usize, nth: usize, set: bool) -> Option { + if size + start > 64 { + println!("bitmap_find_nth: bitmap size is too large"); + return None; + } + let mut count = 0; + let bit = if set { 1 } else { 0 }; + let end = start + size; + + for i in start..end { + if bit_extract(bitmap, i, 1) == bit { + count += 1; + if count == nth { + return Some(i); + } + } + } + + None +} + +pub fn ptr_read_write(addr: usize, width: usize, val: usize, read: bool) -> usize { + if read { + if width == 1 { + unsafe { ptr::read(addr as *const u8) as usize } + } else if width == 2 { + unsafe { ptr::read(addr as *const u16) as usize } + } else if width == 4 { + unsafe { ptr::read(addr as *const u32) as usize } + } else if width == 8 { + unsafe { ptr::read(addr as *const u64) as usize } + } else { + panic!("ptr_read_write: illegal read len {}", width); + } + } else { + if width == 1 { + unsafe { + ptr::write(addr as *mut u8, val as u8); + } + } else if width == 2 { + unsafe { + ptr::write(addr as *mut u16, val as u16); + } + } else if width == 4 { + unsafe { + ptr::write(addr as *mut u32, val as u32); + } + } else if width == 8 { + unsafe { + ptr::write(addr as *mut u64, val as u64); + } + } else { + panic!("ptr_read_write: illegal write len {}", width); + } + 0 + } +} diff --git a/src/linkers/aarch64-pi4.ld b/src/linkers/aarch64-pi4.ld new file mode 100644 index 0000000000000000000000000000000000000000..26096ec23422d2754ba3bd586bb80caf33d423f8 --- /dev/null +++ b/src/linkers/aarch64-pi4.ld @@ -0,0 +1,42 @@ +ENTRY(_start) + +SECTIONS +{ + . = 0xf0080000; + + _image_start = ABSOLUTE(.); + + .boot : { + *(.text.boot) + *(.data.boot) + } + + .text : { + *(.text*) + } + + .rodata : { + *(.rodata*) + } + + + .data : { + *(.data*) + } + + . = ALIGN(4096); + _bss_begin = .; + .bss (NOLOAD) : ALIGN(4096) { + *(.bss*) + } + . = ALIGN(4096); + _bss_end = .; + + _image_end = ABSOLUTE(.); + + . = 0x400000000; + + .cpu_private (NOLOAD) : ALIGN(4096) { + *(.cpu_private) + } +} diff --git a/src/linkers/aarch64-qemu.ld b/src/linkers/aarch64-qemu.ld new file mode 100644 index 0000000000000000000000000000000000000000..87580e25088dd5c76716ff2da41f51f7596f520b --- /dev/null +++ b/src/linkers/aarch64-qemu.ld @@ -0,0 +1,41 @@ +ENTRY(_start) +SECTIONS +{ + . = 0x43000000; + + _image_start = ABSOLUTE(.); + + .boot : { + *(.text.boot) + *(.data.boot) + } + + .text : { + *(.text*) + } + + .rodata : { + *(.rodata*) + } + + + .data : { + *(.data*) + } + + . = ALIGN(4096); + _bss_begin = .; + .bss (NOLOAD) : ALIGN(4096) { + *(.bss*) + } + . = ALIGN(4096); + _bss_end = .; + + _image_end = ABSOLUTE(.); + + . = 0x400000000; + + .cpu_private (NOLOAD) : ALIGN(4096) { + *(.cpu_private) + } +} diff --git a/src/linkers/aarch64-tx2-update.ld b/src/linkers/aarch64-tx2-update.ld new file mode 100644 index 0000000000000000000000000000000000000000..002389bd3ea40322e5a43024b2660360d610626a --- /dev/null +++ b/src/linkers/aarch64-tx2-update.ld @@ -0,0 +1,41 @@ +ENTRY(_start) +SECTIONS +{ + . = 0x8a000000; + + _image_start = ABSOLUTE(.); + + .boot : { + *(.text.boot) + *(.data.boot) + } + + .text : { + *(.text*) + } + + .rodata : { + *(.rodata*) + } + + + .data : { + *(.data*) + } + + . = ALIGN(4096); + _bss_begin = .; + .bss (NOLOAD) : ALIGN(4096) { + *(.bss*) + } + . = ALIGN(4096); + _bss_end = .; + + _image_end = ABSOLUTE(.); + + . = 0x400000000; + + .cpu_private (NOLOAD) : ALIGN(4096) { + *(.cpu_private) + } +} diff --git a/src/linkers/aarch64-tx2.ld b/src/linkers/aarch64-tx2.ld new file mode 100644 index 0000000000000000000000000000000000000000..767ee53da518eb1998ebd59bd23b2cdda8360083 --- /dev/null +++ b/src/linkers/aarch64-tx2.ld @@ -0,0 +1,41 @@ +ENTRY(_start) +SECTIONS +{ + . = 0x83000000; + + _image_start = ABSOLUTE(.); + + .boot : { + *(.text.boot) + *(.data.boot) + } + + .text : { + *(.text*) + } + + .rodata : { + *(.rodata*) + } + + + .data : { + *(.data*) + } + + . = ALIGN(4096); + _bss_begin = .; + .bss (NOLOAD) : ALIGN(4096) { + *(.bss*) + } + . = ALIGN(4096); + _bss_end = .; + + _image_end = ABSOLUTE(.); + + . = 0x400000000; + + .cpu_private (NOLOAD) : ALIGN(4096) { + *(.cpu_private) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..e30749bd49d6632677419cabb294777f17aadc34 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,119 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +#![no_std] +#![no_main] +#![feature(core_intrinsics)] +#![feature(default_alloc_error_handler)] +#![feature(alloc_error_handler)] +#![feature(const_btree_new)] +#![feature(drain_filter)] +#![allow(unused_doc_comments)] +#![allow(special_module_name)] + +#[macro_use] +extern crate alloc; +extern crate fdt; +#[macro_use] +// extern crate lazy_static; +extern crate log; + +// extern crate rlibc; + +use device::{init_vm0_dtb, mediated_dev_init}; +use kernel::{cpu_init, interrupt_init, mem_init, timer_init}; +use mm::heap_init; +use vmm::{vm_init, vmm_boot_vm}; + +use crate::kernel::{cpu_sched_init, hvc_init, iommu_init}; + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::lib::_print(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! println { + () => ($crate::print!("\n")); + ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); +} + +#[allow(dead_code)] +mod arch; +#[allow(dead_code)] +mod board; +#[allow(dead_code)] +mod config; +#[allow(dead_code)] +mod device; +#[allow(dead_code)] +mod driver; +#[allow(dead_code)] +mod kernel; +#[allow(dead_code)] +mod lib; +#[allow(dead_code)] +mod mm; +#[allow(dead_code)] +mod panic; +#[allow(dead_code)] +mod vmm; + +// use lib::{BitAlloc, BitAlloc256}; + +pub static SYSTEM_FDT: spin::Once> = spin::Once::new(); + +#[no_mangle] +pub fn init(cpu_id: usize, dtb: *mut fdt::myctypes::c_void) { + // const UART0: *mut u8 = 0x0900_0000 as *mut u8; + // let out_str = b"AArch64 Bare Metal"; + // for byte in out_str { + // crate::driver::uart::putc(*byte); + // } + // tegra_emmc_blk_read(0, 0, 0 as *mut _); + if cpu_id == 0 { + #[cfg(feature = "tx2")] + println!("Welcome to TX2 Rust-Shyper Hypervisor!"); + #[cfg(feature = "qemu")] + println!("Welcome to Qemu Rust-Shyper Hypervisor!"); + #[cfg(feature = "pi4")] + println!("Welcome to PI4 Rust-Shyper Hypervisor!"); + println!("Built At {}", env!("BUILD_TIME")); + + #[cfg(feature = "pi4")] + { + crate::driver::gpio_select_function(0, 4); + crate::driver::gpio_select_function(1, 4); + } + + heap_init(); + let _ = kernel::logger_init(); + mem_init(); + init_vm0_dtb(dtb); + hvc_init(); + iommu_init(); + } + cpu_init(); + interrupt_init(); + timer_init(); + cpu_sched_init(); + if cpu_id == 0 { + mediated_dev_init(); + } + crate::lib::barrier(); + if cpu_id != 0 { + crate::kernel::cpu_idle(); + } + vm_init(); + println!("Sybilla Hypervisor init ok\n\nStart booting Monitor VM ..."); + vmm_boot_vm(0); + + loop {} +} diff --git a/src/mm/heap.rs b/src/mm/heap.rs new file mode 100644 index 0000000000000000000000000000000000000000..524242d273f4a22467ceae179c845bf11da2ad0f --- /dev/null +++ b/src/mm/heap.rs @@ -0,0 +1,38 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use buddy_system_allocator::LockedHeap; + +// rCore buddy system allocator +use crate::arch::PAGE_SIZE; + +const HEAP_SIZE: usize = 10 * 1024 * PAGE_SIZE; // 40MB + +#[repr(align(4096))] +struct HeapRegion([u8; HEAP_SIZE]); + +static mut HEAP_REGION: HeapRegion = HeapRegion([0; HEAP_SIZE]); + +#[global_allocator] +pub static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::empty(); + +pub fn heap_init() { + println!("init buddy system"); + unsafe { + HEAP_ALLOCATOR + .lock() + .init(HEAP_REGION.0.as_mut_ptr() as usize, HEAP_SIZE); + } +} + +#[alloc_error_handler] +fn alloc_error_handler(_: core::alloc::Layout) -> ! { + panic!("alloc_error_handler: heap Out Of Memory"); +} diff --git a/src/mm/mod.rs b/src/mm/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..b9e82154596d0437b2832c6913c5bf5fc24efd3f --- /dev/null +++ b/src/mm/mod.rs @@ -0,0 +1,15 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::heap::*; +pub use self::page_frame::*; + +mod heap; +mod page_frame; diff --git a/src/mm/page_frame.rs b/src/mm/page_frame.rs new file mode 100644 index 0000000000000000000000000000000000000000..d5f45e3354e8020cbaa3873db620182dee45481d --- /dev/null +++ b/src/mm/page_frame.rs @@ -0,0 +1,61 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::PAGE_SIZE; +use crate::kernel::{mem_heap_free, mem_heap_alloc, AllocError}; +use crate::lib::{memset_safe, trace}; + +#[derive(Debug)] +pub struct PageFrame { + pub pa: usize, + pub page_num: usize, +} + +impl PageFrame { + pub fn new(pa: usize, page_num: usize) -> Self { + assert_eq!(pa % PAGE_SIZE, 0); + PageFrame { pa, page_num } + } + + pub fn alloc_pages(page_num: usize) -> Result { + match mem_heap_alloc(page_num, false) { + Ok(pa) => Ok(Self::new(pa, page_num)), + Err(err) => Err(err), + } + } + + pub fn pa(&self) -> usize { + self.pa + } + + pub fn zero(&self) { + memset_safe(self.pa as *mut u8, 0, PAGE_SIZE); + } + + pub fn as_slice(&self) -> &'static [T] { + if trace() && self.pa() < 0x1000 { + panic!("illegal addr {:x}", self.pa()); + } + unsafe { core::slice::from_raw_parts(self.pa as *const T, PAGE_SIZE / core::mem::size_of::()) } + } + + pub fn as_mut_slice(&self) -> &'static mut [T] { + if trace() && self.pa() < 0x1000 { + panic!("illegal addr {:x}", self.pa()); + } + unsafe { core::slice::from_raw_parts_mut(self.pa as *mut T, PAGE_SIZE / core::mem::size_of::()) } + } +} + +impl Drop for PageFrame { + fn drop(&mut self) { + mem_heap_free(self.pa, 1); + } +} diff --git a/src/mm/page_pool.rs b/src/mm/page_pool.rs new file mode 100644 index 0000000000000000000000000000000000000000..3f3a4ae94064edc34b7f557c057b28d3464d1bf3 --- /dev/null +++ b/src/mm/page_pool.rs @@ -0,0 +1,96 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; +use core::ops::Range; +use spin::Mutex; + +use crate::arch::*; +use crate::mm::PageFrame; + +use self::Error::*; + +#[derive(Copy, Clone, Debug)] +pub enum Error { + OutOfFrame, + FreeNotAllocated, +} + +struct PagePool { + free: Vec, + allocated: Vec, +} + +pub trait PagePoolTrait { + fn init(&mut self, range: Range); + fn allocate(&mut self) -> Result; + fn free(&mut self, pa: usize) -> Result<(), Error>; +} + +impl PagePoolTrait for PagePool { + fn init(&mut self, range: Range) { + assert_eq!(range.start % PAGE_SIZE, 0); + assert_eq!(range.end % PAGE_SIZE, 0); + for pa in range.step_by(PAGE_SIZE) { + self.free.push(pa); + } + } + + fn allocate(&mut self) -> Result { + if let Some(pa) = self.free.pop() { + self.allocated.push(pa); + Ok(PageFrame::new(pa)) + } else { + Err(OutOfFrame) + } + } + + fn free(&mut self, pa: usize) -> Result<(), Error> { + if !self.allocated.contains(&pa) { + Err(FreeNotAllocated) + } else { + self.allocated.retain(|p| { *p != pa }); + self.free.push(pa); + Ok(()) + } + } +} + + +static PAGE_POOL: Mutex = Mutex::new(PagePool { + free: Vec::new(), + allocated: Vec::new(), +}); + +pub fn init() { + let range = super::config::paged_range(); + let mut pool = PAGE_POOL.lock(); + pool.init(range); +} + +pub fn alloc() -> PageFrame { + let mut pool = PAGE_POOL.lock(); + if let Ok(frame) = pool.allocate() { + frame + } else { + panic!("page_pool: alloc failed") + } +} + +pub fn try_alloc() -> Result { + let mut pool = PAGE_POOL.lock(); + let r = pool.allocate(); + r +} + +pub fn free(pa: usize) -> Result<(), Error> { + let mut pool = PAGE_POOL.lock(); + pool.free(pa) +} \ No newline at end of file diff --git a/src/panic.rs b/src/panic.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1eae9983208cc09facdf971458d5960d5251064 --- /dev/null +++ b/src/panic.rs @@ -0,0 +1,19 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use core::panic::PanicInfo; + +#[cfg_attr(target_os = "none", panic_handler)] +#[no_mangle] +fn panic(info: &PanicInfo) -> ! { + println!("[Panic]"); + println!("{}", info); + loop {} +} diff --git a/src/vmm/init.rs b/src/vmm/init.rs new file mode 100644 index 0000000000000000000000000000000000000000..586c053f02a552a70211e5988f2e32fa9faa635b --- /dev/null +++ b/src/vmm/init.rs @@ -0,0 +1,554 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; + +use crate::arch::{ + emu_intc_handler, emu_intc_init, emu_smmu_handler, partial_passthrough_intc_handler, partial_passthrough_intc_init, +}; +use crate::arch::{PTE_S2_DEVICE, PTE_S2_NORMAL}; +use crate::arch::PAGE_SIZE; +use crate::board::*; +use crate::config::vm_cfg_entry; +use crate::device::{emu_register_dev, emu_virtio_mmio_handler, emu_virtio_mmio_init}; +use crate::device::create_fdt; +use crate::device::EmuDeviceType::*; +use crate::kernel::{ + add_async_used_info, cpu_idle, current_cpu, iommmu_vm_init, shyper_init, vm_if_init_mem_map, VM_IF_LIST, VmPa, + VmType, iommu_add_device, +}; +use crate::kernel::{mem_page_alloc, mem_vm_region_alloc}; +use crate::kernel::{vm, Vm}; +use crate::kernel::{active_vcpu_id, vcpu_run}; +use crate::kernel::interrupt_vm_register; +use crate::kernel::VM_NUM_MAX; +use crate::lib::trace; + +#[cfg(feature = "ramdisk")] +pub static CPIO_RAMDISK: &'static [u8] = include_bytes!("../../image/net_rootfs.cpio"); +#[cfg(not(feature = "ramdisk"))] +pub static CPIO_RAMDISK: &'static [u8] = &[]; + +fn vmm_init_memory(vm: Vm) -> bool { + let result = mem_page_alloc(); + let vm_id = vm.id(); + let config = vm.config(); + let mut vm_mem_size: usize = 0; // size for pages + + if let Ok(pt_dir_frame) = result { + vm.set_pt(pt_dir_frame); + vm.set_mem_region_num(config.memory_region().len()); + } else { + println!("vmm_init_memory: page alloc failed"); + return false; + } + + for vm_region in config.memory_region() { + let pa = mem_vm_region_alloc(vm_region.length); + vm_mem_size += vm_region.length; + + if pa == 0 { + println!("vmm_init_memory: vm memory region is not large enough"); + return false; + } + + println!( + "VM {} memory region: ipa=<0x{:x}>, pa=<0x{:x}>, size=<0x{:x}>", + vm_id, vm_region.ipa_start, pa, vm_region.length + ); + vm.pt_map_range(vm_region.ipa_start, vm_region.length, pa, PTE_S2_NORMAL, vm_id == 0); + + vm.add_region(VmPa { + pa_start: pa, + pa_length: vm_region.length, + offset: vm_region.ipa_start as isize - pa as isize, + }); + } + vm_if_init_mem_map(vm_id, (vm_mem_size + PAGE_SIZE - 1) / PAGE_SIZE); + + true +} + +pub fn vmm_load_image(vm: Vm, bin: &[u8]) { + let size = bin.len(); + let config = vm.config(); + let load_ipa = config.kernel_load_ipa(); + for (idx, region) in config.memory_region().iter().enumerate() { + if load_ipa < region.ipa_start || load_ipa + size > region.ipa_start + region.length { + continue; + } + + let offset = load_ipa - region.ipa_start; + println!( + "VM {} loads kernel: ipa=<0x{:x}>, pa=<0x{:x}>, size=<{}K>", + vm.id(), + load_ipa, + vm.pa_start(idx) + offset, + size / 1024 + ); + if trace() && vm.pa_start(idx) + offset < 0x1000 { + panic!("illegal addr {:x}", vm.pa_start(idx) + offset); + } + let dst = unsafe { core::slice::from_raw_parts_mut((vm.pa_start(idx) + offset) as *mut u8, size) }; + dst.clone_from_slice(bin); + return; + } + panic!("vmm_load_image: Image config conflicts with memory config"); +} + +pub fn vmm_init_image(vm: Vm) -> bool { + let vm_id = vm.id(); + let config = vm.config(); + + if config.kernel_load_ipa() == 0 { + println!("vmm_init_image: kernel load ipa is null"); + return false; + } + + vm.set_entry_point(config.kernel_entry_point()); + + // Only load MVM kernel image "L4T" from binding. + // Load GVM kernel image from shyper-cli, you may check it for more information. + if config.os_type == VmType::VmTOs { + match vm.config().kernel_img_name() { + Some(name) => { + #[cfg(feature = "tx2")] + if name == "L4T" { + println!("MVM {} loading Image", vm.id()); + vmm_load_image(vm.clone(), include_bytes!("../../image/L4T")); + } else if name == "Image_vanilla" { + println!("VM {} loading default Linux Image", vm.id()); + #[cfg(feature = "static-config")] + vmm_load_image(vm.clone(), include_bytes!("../../image/Image_vanilla")); + #[cfg(not(feature = "static-config"))] + println!("*** Please enable feature `static-config`"); + } else { + warn!("Image {} is not supported", name); + } + #[cfg(feature = "pi4")] + vmm_load_image(vm.clone(), include_bytes!("../../image/Image_pi4_5.4.83_tlb")); + // vmm_load_image(vm.clone(), include_bytes!("../../image/Image_pi4_5.4.78")); + // vmm_load_image(vm.clone(), include_bytes!("../../image/Image_pi4")); + #[cfg(feature = "qemu")] + vmm_load_image(vm.clone(), include_bytes!("../../image/Image_vanilla")); + } + None => { + // nothing to do, its a dynamic configuration + } + } + } + + if config.device_tree_load_ipa() != 0 { + // Init dtb for Linux. + if vm_id == 0 { + // Init dtb for MVM. + use crate::SYSTEM_FDT; + let offset = config.device_tree_load_ipa() - config.memory_region()[0].ipa_start; + println!("MVM[{}] dtb addr 0x{:x}", vm_id, vm.pa_start(0) + offset); + vm.set_dtb((vm.pa_start(0) + offset) as *mut fdt::myctypes::c_void); + unsafe { + let src = SYSTEM_FDT.get().unwrap(); + let len = src.len(); + let dst = core::slice::from_raw_parts_mut((vm.pa_start(0) + offset) as *mut u8, len); + dst.clone_from_slice(&src); + vmm_setup_fdt(vm.clone()); + } + } else { + // Init dtb for GVM. + match create_fdt(config.clone()) { + Ok(dtb) => { + let offset = config.device_tree_load_ipa() - vm.config().memory_region()[0].ipa_start; + println!("GVM[{}] dtb addr 0x{:x}", vm.id(), vm.pa_start(0) + offset); + crate::lib::memcpy_safe((vm.pa_start(0) + offset) as *const u8, dtb.as_ptr(), dtb.len()); + } + _ => { + panic!("vmm_setup_config: create fdt for vm{} fail", vm.id()); + } + } + } + } else { + println!( + "VM {} id {} device tree load ipa is not set", + vm_id, + vm.config().vm_name() + ); + } + + // ... + // Todo: support loading ramdisk from MVM shyper-cli. + // ... + if config.ramdisk_load_ipa() != 0 { + println!("VM {} use ramdisk CPIO_RAMDISK", vm_id); + let offset = config.ramdisk_load_ipa() - config.memory_region()[0].ipa_start; + let len = CPIO_RAMDISK.len(); + let dst = unsafe { core::slice::from_raw_parts_mut((vm.pa_start(0) + offset) as *mut u8, len) }; + dst.clone_from_slice(CPIO_RAMDISK); + } + + true +} + +fn vmm_init_emulated_device(vm: Vm) -> bool { + let config = vm.config().emulated_device_list(); + + for (idx, emu_dev) in config.iter().enumerate() { + match emu_dev.emu_type { + EmuDeviceTGicd => { + vm.set_intc_dev_id(idx); + emu_register_dev( + EmuDeviceTGicd, + vm.id(), + idx, + emu_dev.base_ipa, + emu_dev.length, + emu_intc_handler, + ); + emu_intc_init(vm.clone(), idx); + } + EmuDeviceTGPPT => { + vm.set_intc_dev_id(idx); + emu_register_dev( + EmuDeviceTGPPT, + vm.id(), + idx, + emu_dev.base_ipa, + emu_dev.length, + partial_passthrough_intc_handler, + ); + partial_passthrough_intc_init(vm.clone()); + } + EmuDeviceTVirtioBlk => { + emu_register_dev( + EmuDeviceTVirtioBlk, + vm.id(), + idx, + emu_dev.base_ipa, + emu_dev.length, + emu_virtio_mmio_handler, + ); + if !emu_virtio_mmio_init(vm.clone(), idx, emu_dev.mediated) { + return false; + } + } + EmuDeviceTVirtioNet => { + emu_register_dev( + EmuDeviceTVirtioNet, + vm.id(), + idx, + emu_dev.base_ipa, + emu_dev.length, + emu_virtio_mmio_handler, + ); + if !emu_virtio_mmio_init(vm.clone(), idx, emu_dev.mediated) { + return false; + } + let mut vm_if_list = VM_IF_LIST[vm.id()].lock(); + for i in 0..6 { + vm_if_list.mac[i] = emu_dev.cfg_list[i] as u8; + } + drop(vm_if_list); + } + EmuDeviceTVirtioConsole => { + emu_register_dev( + EmuDeviceTVirtioConsole, + vm.id(), + idx, + emu_dev.base_ipa, + emu_dev.length, + emu_virtio_mmio_handler, + ); + if !emu_virtio_mmio_init(vm.clone(), idx, emu_dev.mediated) { + return false; + } + } + EmuDeviceTIOMMU => { + emu_register_dev( + EmuDeviceTIOMMU, + vm.id(), + idx, + emu_dev.base_ipa, + emu_dev.length, + emu_smmu_handler, + ); + if !iommmu_vm_init(vm.clone()) { + return false; + } + } + EmuDeviceTShyper => { + if !shyper_init(vm.clone(), emu_dev.base_ipa, emu_dev.length) { + return false; + } + } + _ => { + warn!("vmm_init_emulated_device: unknown emulated device"); + return false; + } + } + info!( + "VM {} registers emulated device: id=<{}>, name=\"{}\", ipa=<0x{:x}>", + vm.id(), + idx, + emu_dev.emu_type, + emu_dev.base_ipa + ); + } + + true +} + +fn vmm_init_passthrough_device(vm: Vm) -> bool { + for region in vm.config().passthrough_device_regions() { + if region.dev_property { + vm.pt_map_range(region.ipa, region.length, region.pa, PTE_S2_DEVICE, true); + } else { + vm.pt_map_range(region.ipa, region.length, region.pa, PTE_S2_NORMAL, true); + } + + debug!( + "VM {} registers passthrough device: ipa=<0x{:x}>, pa=<0x{:x}>, size=<0x{:x}>, {}", + vm.id(), + region.ipa, + region.pa, + region.length, + if region.dev_property { "device" } else { "normal" } + ); + } + for irq in vm.config().passthrough_device_irqs() { + if !interrupt_vm_register(vm.clone(), irq) { + return false; + } + } + true +} + +fn vmm_init_iommu_device(vm: Vm) -> bool { + for stream_id in vm.config().passthrough_device_stread_ids() { + if stream_id == 0 { + break; + } + if !iommu_add_device(vm.clone(), stream_id) { + return false; + } + } + true +} + +pub unsafe fn vmm_setup_fdt(vm: Vm) { + use fdt::*; + let config = vm.config(); + match vm.dtb() { + Some(dtb) => { + let mut mr = Vec::new(); + for r in config.memory_region() { + mr.push(region { + ipa_start: r.ipa_start as u64, + length: r.length as u64, + }); + } + #[cfg(feature = "tx2")] + fdt_set_memory(dtb, mr.len() as u64, mr.as_ptr(), "memory@90000000\0".as_ptr()); + #[cfg(feature = "pi4")] + fdt_set_memory(dtb, mr.len() as u64, mr.as_ptr(), "memory@200000\0".as_ptr()); + // FDT+TIMER + fdt_add_timer(dtb, 0x8); + // FDT+BOOTCMD + fdt_set_bootcmd(dtb, config.cmdline.as_ptr()); + #[cfg(feature = "tx2")] + fdt_set_stdout_path(dtb, "/serial@3100000\0".as_ptr()); + // #[cfg(feature = "pi4")] + // fdt_set_stdout_path(dtb, "/serial@fe340000\0".as_ptr()); + + if config.emulated_device_list().len() > 0 { + for emu_cfg in config.emulated_device_list() { + match emu_cfg.emu_type { + EmuDeviceTGicd => { + #[cfg(feature = "tx2")] + fdt_setup_gic( + dtb, + PLATFORM_GICD_BASE as u64, + PLATFORM_GICC_BASE as u64, + emu_cfg.name.unwrap().as_ptr(), + ); + #[cfg(feature = "pi4")] + let r = fdt_setup_gic( + dtb, + (PLATFORM_GICD_BASE | 0xF_0000_0000) as u64, + (PLATFORM_GICC_BASE | 0xF_0000_0000) as u64, + emu_cfg.name.unwrap().as_ptr(), + ); + } + EmuDeviceTVirtioNet | EmuDeviceTVirtioConsole => { + #[cfg(feature = "tx2")] + fdt_add_virtio( + dtb, + emu_cfg.name.unwrap().as_ptr(), + emu_cfg.irq_id as u32 - 0x20, + emu_cfg.base_ipa as u64, + ); + } + EmuDeviceTShyper => { + #[cfg(feature = "tx2")] + fdt_add_vm_service( + dtb, + emu_cfg.irq_id as u32 - 0x20, + emu_cfg.base_ipa as u64, + emu_cfg.length as u64, + ); + } + EmuDeviceTIOMMU => { + #[cfg(feature = "tx2")] + trace!("EmuDeviceTIOMMU"); + } + _ => { + todo!(); + } + } + } + } + println!("after dtb size {}", fdt_size(dtb)); + } + None => { + println!("None dtb"); + } + } +} + +/* Setup VM Configuration before boot. + * Only VM0 will call this function. + * This func should run 1 time for each vm. + * + * @param[in] vm_id: target VM id to set up config. + */ +pub fn vmm_setup_config(vm_id: usize) { + let vm = match vm(vm_id) { + Some(vm) => vm, + None => { + panic!("vmm_setup_config vm id {} doesn't exist", vm_id); + } + }; + + let config = match vm_cfg_entry(vm_id) { + Some(config) => config, + None => { + panic!("vmm_setup_config vm id {} config doesn't exist", vm_id); + } + }; + + println!( + "vmm_setup_config VM[{}] name {:?} current core {}", + vm_id, + config.name.clone().unwrap(), + current_cpu().id + ); + + if vm_id >= VM_NUM_MAX { + panic!("vmm_setup_config: out of vm"); + } + if !vmm_init_memory(vm.clone()) { + panic!("vmm_setup_config: vmm_init_memory failed"); + } + + if !vmm_init_image(vm.clone()) { + panic!("vmm_setup_config: vmm_init_image failed"); + } + + if !vmm_init_emulated_device(vm.clone()) { + panic!("vmm_setup_config: vmm_init_emulated_device failed"); + } + if !vmm_init_passthrough_device(vm.clone()) { + panic!("vmm_setup_config: vmm_init_passthrough_device failed"); + } + if !vmm_init_iommu_device(vm.clone()) { + panic!("vmm_setup_config: vmm_init_iommu_device failed"); + } + + add_async_used_info(vm_id); + info!("VM {} id {} init ok", vm.id(), vm.config().name.unwrap()); +} + +pub fn vmm_cpu_assign_vcpu(vm_id: usize) { + let cpu_id = current_cpu().id; + if current_cpu().assigned() { + debug!("vmm_cpu_assign_vcpu vm[{}] cpu {} is assigned", vm_id, cpu_id); + } + + // let cpu_config = vm(vm_id).config().cpu; + let vm = vm(vm_id).unwrap(); + let cfg_master = vm.config().cpu_master(); + let cfg_cpu_num = vm.config().cpu_num(); + let cfg_cpu_allocate_bitmap = vm.config().cpu_allocated_bitmap(); + + if cfg_cpu_num != cfg_cpu_allocate_bitmap.count_ones() as usize { + panic!( + "vmm_cpu_assign_vcpu: VM[{}] cpu_num {} not match cpu_allocated_bitmap {:#b}", + vm_id, cfg_cpu_num, cfg_cpu_allocate_bitmap + ); + } + + info!( + "vmm_cpu_assign_vcpu: vm[{}] cpu {} cfg_master {} cfg_cpu_num {} cfg_cpu_allocate_bitmap {:#b}", + vm_id, cpu_id, cfg_master, cfg_cpu_num, cfg_cpu_allocate_bitmap + ); + + // Judge if current cpu is allocated. + if (cfg_cpu_allocate_bitmap & (1 << cpu_id)) != 0 { + let vcpu = match vm.select_vcpu2assign(cpu_id) { + None => panic!("core {} vm {} cannot find proper vcpu to assign", cpu_id, vm_id), + Some(vcpu) => vcpu, + }; + if vcpu.id() == 0 { + println!("* Core {} is assigned => vm {}, vcpu {}", cpu_id, vm_id, vcpu.id()); + } else { + println!("Core {} is assigned => vm {}, vcpu {}", cpu_id, vm_id, vcpu.id()); + } + current_cpu().vcpu_array.append_vcpu(vcpu); + } + + if cfg_cpu_num == vm.cpu_num() { + vm.set_ready(true); + } +} + +pub fn vm_init() { + if current_cpu().id == 0 { + // Set up basic config. + crate::config::mvm_config_init(); + // Add VM 0 + super::vmm_init_gvm(0); + #[cfg(feature = "static-config")] + { + crate::config::init_tmp_config_for_vm1(); + crate::config::init_tmp_config_for_vm2(); + super::vmm_init_gvm(1); + super::vmm_init_gvm(2); + } + } +} + +pub fn vmm_boot() { + if current_cpu().assigned() && active_vcpu_id() == 0 { + // active_vm().unwrap().set_migration_state(false); + info!("Core {} start running", current_cpu().id); + vcpu_run(false); + } else { + // If there is no available vm(vcpu), just go idle + info!("Core {} idle", current_cpu().id); + cpu_idle(); + } +} + +pub fn vmm_migrate_boot() { + let vcpu = current_cpu().active_vcpu.clone().unwrap(); + vcpu.reset_vmpidr(); + vcpu.reset_vtimer_offset(); + + // println!("Core[{}] start running", current_cpu().id); + vcpu_run(true); +} diff --git a/src/vmm/manager.rs b/src/vmm/manager.rs new file mode 100644 index 0000000000000000000000000000000000000000..fdd9c93e73202985bc412d2cc854eed8b8b94f4f --- /dev/null +++ b/src/vmm/manager.rs @@ -0,0 +1,449 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use alloc::vec::Vec; + +use crate::arch::gicc_clear_current_irq; +use crate::arch::power_arch_vm_shutdown_secondary_cores; +use crate::board::PLATFORM_CPU_NUM_MAX; +use crate::config::{vm_id_list, vm_num}; +// use crate::config::{init_tmp_config_for_bma1, init_tmp_config_for_bma2, init_tmp_config_for_vm1, init_tmp_config_for_vm2}; +use crate::config::NAME_MAX_LEN; +use crate::config::vm_cfg_entry; +use crate::config::vm_type; +use crate::kernel::{ + active_vcpu_id, active_vm, current_cpu, push_vm, vm, Vm, vm_if_get_state, vm_if_set_ivc_arg, vm_if_set_ivc_arg_ptr, + vm_ipa2pa, VM_NUM_MAX, Scheduler, +}; +use crate::kernel::{active_vm_id, vm_if_get_cpu_id}; +use crate::kernel::{ipi_send_msg, IpiInnerMsg, IpiMessage, IpiType, IpiVmmMsg}; +use crate::kernel::{hvc_send_msg_to_vm, HvcGuestMsg, HvcManageMsg}; +use crate::kernel::HVC_CONFIG; +use crate::kernel::HVC_CONFIG_UPLOAD_KERNEL_IMAGE; +use crate::kernel::HVC_VMM; +use crate::kernel::HVC_VMM_REBOOT_VM; +use crate::lib::sleep; +use crate::lib::{bit_extract, memcpy_safe, memset_safe}; +use crate::vmm::{vmm_cpu_assign_vcpu, vmm_boot, vmm_init_image, vmm_setup_config, vmm_cpu_remove_vcpu}; + +#[derive(Copy, Clone)] +pub enum VmmEvent { + VmmBoot, + VmmReboot, + VmmShutdown, + VmmAssignCpu, + VmmRemoveCpu, +} + +pub fn vmm_shutdown_secondary_vm() { + println!("Shutting down all VMs..."); +} + +/* Generate VM structure and push it to VM. + * + * @param[in] vm_id: new added VM id. + */ +pub fn vmm_push_vm(vm_id: usize) { + info!("vmm_push_vm: add vm {} on cpu {}", vm_id, current_cpu().id); + if push_vm(vm_id).is_err() { + return; + } + let vm = vm(vm_id).unwrap(); + let vm_cfg = match vm_cfg_entry(vm_id) { + Some(vm_cfg) => vm_cfg, + None => { + println!("vmm_push_vm: failed to find config for vm {}", vm_id); + return; + } + }; + vm.set_config_entry(Some(vm_cfg)); + + use crate::kernel::vm_if_set_type; + vm_if_set_type(vm_id, vm_type(vm_id)); +} + +pub fn vmm_alloc_vcpu(vm_id: usize) { + let vm = match vm(vm_id) { + None => { + panic!( + "vmm_alloc_vcpu: on core {}, VM [{}] is not added yet", + current_cpu().id, + vm_id + ); + } + Some(vm) => vm, + }; + + for i in 0..vm.config().cpu_num() { + use crate::kernel::vcpu_alloc; + if let Some(vcpu) = vcpu_alloc() { + vcpu.init(vm.clone(), i); + vm.push_vcpu(vcpu.clone()); + } else { + println!("failed to allocte vcpu"); + return; + } + } + + println!( + "VM {} init cpu: cores=<{}>, allocat_bits=<0b{:b}>", + vm.id(), + vm.config().cpu_num(), + vm.config().cpu_allocated_bitmap() + ); +} + +/* Finish cpu assignment before set up VM config. + * Only VM0 will go through this function. + * + * @param[in] vm_id: new added VM id. + */ +pub fn vmm_set_up_cpu(vm_id: usize) { + println!("vmm_set_up_cpu: set up vm {} on cpu {}", vm_id, current_cpu().id); + let vm = match vm(vm_id) { + None => { + panic!( + "vmm_set_up_cpu: on core {}, VM [{}] is not added yet", + current_cpu().id, + vm_id + ); + } + Some(vm) => vm, + }; + + vmm_alloc_vcpu(vm_id); + + let mut cpu_allocate_bitmap = vm.config().cpu_allocated_bitmap(); + let mut target_cpu_id = 0; + let mut cpu_num = 0; + while cpu_allocate_bitmap != 0 && target_cpu_id < PLATFORM_CPU_NUM_MAX { + if cpu_allocate_bitmap & 1 != 0 { + println!("vmm_set_up_cpu: vm {} physical cpu id {}", vm_id, target_cpu_id); + cpu_num += 1; + + if target_cpu_id != current_cpu().id { + let m = IpiVmmMsg { + vmid: vm_id, + event: VmmEvent::VmmAssignCpu, + }; + if !ipi_send_msg(target_cpu_id, IpiType::IpiTVMM, IpiInnerMsg::VmmMsg(m)) { + println!("vmm_set_up_cpu: failed to send ipi to Core {}", target_cpu_id); + } + } else { + vmm_cpu_assign_vcpu(vm_id); + } + } + cpu_allocate_bitmap >>= 1; + target_cpu_id += 1; + } + println!( + "vmm_set_up_cpu: vm {} total physical cpu num {} bitmap {:#b}", + vm_id, + cpu_num, + vm.config().cpu_allocated_bitmap() + ); + + // Waiting till others set up. + println!( + "vmm_set_up_cpu: on core {}, waiting VM [{}] to be set up", + current_cpu().id, + vm_id + ); + while !vm.ready() { + sleep(10); + } + println!("vmm_set_up_cpu: VM [{}] is ready", vm_id); +} + +/* Init VM before boot. + * Only VM0 will call this function. + * + * @param[in] vm_id: target VM id to boot. + */ +pub fn vmm_init_gvm(vm_id: usize) { + // Before boot, we need to set up the VM config. + if current_cpu().id == 0 || (active_vm_id() == 0 && active_vm_id() != vm_id) { + vmm_push_vm(vm_id); + + vmm_set_up_cpu(vm_id); + + vmm_setup_config(vm_id); + } else { + error!( + "VM[{}] Core {} should not init VM [{}]", + active_vm_id(), + current_cpu().id, + vm_id + ); + } +} + +/* Boot Guest VM. + * + * @param[in] vm_id: target VM id to boot. + */ +pub fn vmm_boot_vm(vm_id: usize) { + let phys_id = vm_if_get_cpu_id(vm_id); + // println!( + // "vmm_boot_vm: current_cpu {} target vm {} get phys_id {}", + // current_cpu().id, + // vm_id, + // phys_id + // ); + if phys_id != current_cpu().id { + let m = IpiVmmMsg { + vmid: vm_id, + event: VmmEvent::VmmBoot, + }; + if !ipi_send_msg(phys_id, IpiType::IpiTVMM, IpiInnerMsg::VmmMsg(m)) { + println!("vmm_boot_vm: failed to send ipi to Core {}", phys_id); + } + } else { + match current_cpu().vcpu_array.pop_vcpu_through_vmid(vm_id) { + None => { + panic!( + "vmm_boot_vm: VM[{}] does not have vcpu on Core {}", + vm_id, + current_cpu().id + ); + } + Some(vcpu) => { + gicc_clear_current_irq(true); + // TODO: try to use `wakeup` (still bugs when booting multi-shared-core VM using wakeup) + current_cpu().scheduler().yield_to(vcpu); + vmm_boot(); + } + }; + } +} + +/** + * Reboot target vm according to arguments + * + * @param arg force ~ (31, 16) ~ [soft shutdown or hard shutdown] + * vmid ~ (15, 0) ~ [target vm id] + */ +pub fn vmm_reboot_vm(arg: usize) { + let vm_id = bit_extract(arg, 0, 16); + let force = bit_extract(arg, 16, 16) != 0; + let cur_vm = active_vm().unwrap(); + + println!("vmm_reboot VM [{}] force:{}", vm_id, force); + + if force { + if cur_vm.id() == vm_id { + vmm_reboot(); + } else { + let cpu_trgt = vm_if_get_cpu_id(vm_id); + let m = IpiVmmMsg { + vmid: vm_id, + event: VmmEvent::VmmReboot, + }; + if !ipi_send_msg(cpu_trgt, IpiType::IpiTVMM, IpiInnerMsg::VmmMsg(m)) { + println!("vmm_reboot_vm: failed to send ipi to Core {}", cpu_trgt); + } + } + return; + } + + let msg = HvcManageMsg { + fid: HVC_VMM, + event: HVC_VMM_REBOOT_VM, + vm_id, + }; + if !hvc_send_msg_to_vm(vm_id, &HvcGuestMsg::Manage(msg)) { + println!("vmm_reboot_vm: failed to notify VM 0"); + } +} + +/* Reset vm os at current core. + * + * @param[in] vm : target VM structure to be reboot. + */ +pub fn vmm_reboot() { + let vm = active_vm().unwrap(); + // If running MVM, reboot the whole system. + if vm.id() == 0 { + vmm_shutdown_secondary_vm(); + crate::board::platform_sys_reboot(); + } + + // Reset GVM. + let vcpu = current_cpu().active_vcpu.clone().unwrap(); + println!("VM [{}] reset...", vm.id()); + power_arch_vm_shutdown_secondary_cores(vm.clone()); + println!( + "Core {} (VM [{}] vcpu {}) shutdown ok", + current_cpu().id, + vm.id(), + active_vcpu_id() + ); + + // Clear memory region. + for idx in 0..vm.mem_region_num() { + println!( + "Core {} (VM [{}] vcpu {}) reset mem region start {:x} size {:x}", + current_cpu().id, + vm.id(), + active_vcpu_id(), + vm.pa_start(idx), + vm.pa_length(idx) + ); + memset_safe(vm.pa_start(idx) as *mut u8, 0, vm.pa_length(idx)); + } + + // Reset image. + if !vmm_init_image(vm.clone()) { + panic!("vmm_reboot: vmm_init_image failed"); + } + + // Reset ivc arg. + vm_if_set_ivc_arg(vm.id(), 0); + vm_if_set_ivc_arg_ptr(vm.id(), 0); + + crate::arch::interrupt_arch_clear(); + crate::arch::vcpu_arch_init(vm.clone(), vm.vcpu(0).unwrap()); + vcpu.reset_context(); + + // TODO: rewite hard code. + // vmm_load_image( + // vm.clone(), + // include_bytes!("../../image/Image_vanilla"), + // ); + vmm_load_image_from_mvm(vm.clone()); + + // vcpu_run(); +} + +pub fn vmm_load_image_from_mvm(vm: Vm) { + let vm_id = vm.id(); + let msg = HvcManageMsg { + fid: HVC_CONFIG, + event: HVC_CONFIG_UPLOAD_KERNEL_IMAGE, + vm_id, + }; + // println!("mediated_blk_write send msg to vm0"); + if !hvc_send_msg_to_vm(0, &HvcGuestMsg::Manage(msg)) { + println!("vmm_load_image_from_mvm: failed to notify VM 0"); + } +} + +/* Get current VM id. + * + * @param[in] id_ipa : vm id ipa. + */ +pub fn get_vm_id(id_ipa: usize) -> bool { + let vm = active_vm().unwrap(); + let id_pa = vm_ipa2pa(vm.clone(), id_ipa); + if id_pa == 0 { + println!("illegal id_pa {:x}", id_pa); + return false; + } + unsafe { + *(id_pa as *mut usize) = vm.id(); + } + true +} + +#[repr(C)] +struct VMInfo { + pub id: u32, + pub vm_name: [u8; NAME_MAX_LEN], + pub vm_type: u32, + pub vm_state: u32, +} + +#[repr(C)] +struct VMInfoList { + pub vm_num: usize, + pub info_list: [VMInfo; VM_NUM_MAX], +} + +/* List VM info in hypervisor. + * + * @param[in] vm_info_ipa : vm info list ipa. + */ +pub fn vmm_list_vm(vm_info_ipa: usize) -> Result { + #[cfg(feature = "update")] + println!("Rust-Shyper list vm"); + let vm_info_pa = vm_ipa2pa(active_vm().unwrap(), vm_info_ipa); + if vm_info_pa == 0 { + println!("illegal vm_info_ipa {:x}", vm_info_ipa); + return Err(()); + } + + let vm_info = unsafe { &mut *(vm_info_pa as *mut VMInfoList) }; + + // Get VM num. + vm_info.vm_num = vm_num(); + + for (idx, vmid) in vm_id_list().iter().enumerate() { + let vm_cfg = match vm_cfg_entry(*vmid) { + Some(vm_cfg) => vm_cfg, + None => { + println!("Failed to get VM config entry for VM[{}]", *vmid); + continue; + } + }; + // Get VM type. + let vm_type = vm_type(*vmid); + // Get VM State. + let vm_state = vm_if_get_state(*vmid); + + vm_info.info_list[idx].id = *vmid as u32; + vm_info.info_list[idx].vm_type = vm_type as u32; + vm_info.info_list[idx].vm_state = vm_state as u32; + + let vm_name_u8: Vec = vm_cfg.vm_name().as_bytes().to_vec(); + memcpy_safe( + vm_info.info_list[idx].vm_name.as_ptr() as *const _ as *const u8, + vm_name_u8.as_ptr(), + NAME_MAX_LEN, + ); + vm_info.info_list[idx].vm_name[vm_name_u8.len()] = 0; + } + Ok(0) +} + +pub fn vmm_ipi_handler(msg: &IpiMessage) { + match msg.ipi_message { + IpiInnerMsg::VmmMsg(vmm) => match vmm.event { + VmmEvent::VmmBoot => { + vmm_boot_vm(vmm.vmid); + } + VmmEvent::VmmReboot => { + vmm_reboot(); + } + VmmEvent::VmmAssignCpu => { + println!( + "vmm_ipi_handler: core {} receive assign vcpu request for vm[{}]", + current_cpu().id, + vmm.vmid + ); + vmm_cpu_assign_vcpu(vmm.vmid); + } + VmmEvent::VmmRemoveCpu => { + println!( + "vmm_ipi_handler: core {} remove vcpu for vm[{}]", + current_cpu().id, + vmm.vmid + ); + vmm_cpu_remove_vcpu(vmm.vmid); + } + _ => { + todo!(); + } + }, + _ => { + println!("vmm_ipi_handler: illegal ipi type"); + return; + } + } +} diff --git a/src/vmm/mod.rs b/src/vmm/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..07bc6cd912d42b4d60174682f94d62512b7e4545 --- /dev/null +++ b/src/vmm/mod.rs @@ -0,0 +1,17 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +pub use self::init::*; +pub use self::manager::*; +pub use self::remove::*; + +mod init; +mod manager; +mod remove; diff --git a/src/vmm/remove.rs b/src/vmm/remove.rs new file mode 100644 index 0000000000000000000000000000000000000000..9337f1b6909d4899f5cbb65b334b20c02f13768e --- /dev/null +++ b/src/vmm/remove.rs @@ -0,0 +1,124 @@ +// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved. +// Rust-Shyper is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. + +use crate::arch::{GIC_SGIS_NUM, gicc_clear_current_irq}; +use crate::config::vm_cfg_remove_vm_entry; +use crate::device::emu_remove_dev; +use crate::kernel::{ + current_cpu, interrupt_vm_remove, ipi_send_msg, IpiInnerMsg, IpiType, IpiVmmMsg, mem_vm_region_free, + remove_async_used_info, remove_vm, remove_vm_async_task, vcpu_remove, vm, Vm, Scheduler, cpu_idle, +}; +use crate::kernel::vm_if_reset; +use crate::vmm::VmmEvent; +use crate::lib::memset_safe; + +pub fn vmm_remove_vm(vm_id: usize) { + if vm_id == 0 { + warn!("Rust-Shyper do not support remove vm0"); + return; + } + + let vm = match vm(vm_id) { + None => { + println!("vmm_remove_vm: vm[{}] not exist", vm_id); + return; + } + Some(vm) => vm, + }; + + // vcpu + vmm_remove_vcpu(vm.clone()); + // reset vm interface + vm_if_reset(vm_id); + // free mem + for idx in 0..vm.region_num() { + memset_safe(vm.pa_start(idx) as *mut u8, 0, vm.pa_length(idx)); + mem_vm_region_free(vm.pa_start(idx), vm.pa_length(idx)); + } + // emu dev + vmm_remove_emulated_device(vm.clone()); + // passthrough dev + vmm_remove_passthrough_device(vm.clone()); + // clear async task list + remove_vm_async_task(vm_id); + // async used info + remove_async_used_info(vm_id); + // remove vm: page table / mmio / vgic will be removed with struct vm + vmm_remove_vm_list(vm_id); + // remove vm cfg + vm_cfg_remove_vm_entry(vm_id); + // remove vm unilib + crate::lib::unilib::unilib_fs_remove(vm_id); + info!("remove vm[{}] successfully", vm_id); +} + +fn vmm_remove_vm_list(vm_id: usize) { + let vm = remove_vm(vm_id); + vm.clear_list(); +} + +pub fn vmm_cpu_remove_vcpu(vmid: usize) { + let vcpu = current_cpu().vcpu_array.remove_vcpu(vmid); + if let Some(vcpu) = vcpu { + // remove vcpu from scheduler + current_cpu().scheduler().sleep(vcpu); + } + if current_cpu().vcpu_array.vcpu_num() == 0 { + gicc_clear_current_irq(true); + cpu_idle(); + } +} + +fn vmm_remove_vcpu(vm: Vm) { + for idx in 0..vm.cpu_num() { + let vcpu = vm.vcpu(idx).unwrap(); + // remove vcpu from VCPU_LIST + vcpu_remove(vcpu.clone()); + if vcpu.phys_id() == current_cpu().id { + vmm_cpu_remove_vcpu(vm.id()); + } else { + let m = IpiVmmMsg { + vmid: vm.id(), + event: VmmEvent::VmmRemoveCpu, + }; + if !ipi_send_msg(vcpu.phys_id(), IpiType::IpiTVMM, IpiInnerMsg::VmmMsg(m)) { + warn!("vmm_remove_vcpu: failed to send ipi to Core {}", vcpu.phys_id()); + } + } + } +} + +fn vmm_remove_emulated_device(vm: Vm) { + let config = vm.config().emulated_device_list(); + for (idx, emu_dev) in config.iter().enumerate() { + // mmio / vgic will be removed with struct vm + if !emu_dev.emu_type.removable() { + warn!("vmm_remove_emulated_device: cannot remove device {}", emu_dev.emu_type); + return; + } + emu_remove_dev(vm.id(), idx, emu_dev.base_ipa, emu_dev.length); + // println!( + // "VM[{}] removes emulated device: id=<{}>, name=\"{}\", ipa=<0x{:x}>", + // vm.id(), + // idx, + // emu_dev.emu_type, + // emu_dev.base_ipa + // ); + } +} + +fn vmm_remove_passthrough_device(vm: Vm) { + for irq in vm.config().passthrough_device_irqs() { + if irq > GIC_SGIS_NUM { + interrupt_vm_remove(vm.clone(), irq); + // println!("VM[{}] remove irq {}", vm.id(), irq); + } + } +} diff --git a/test/fio.sh b/test/fio.sh new file mode 100644 index 0000000000000000000000000000000000000000..b9bc711fb6ed327383594644b4ef075bd27fd487 --- /dev/null +++ b/test/fio.sh @@ -0,0 +1,3 @@ +fio -direct=1 -iodepth 1 -thread -rw=read \ + -ioengine=psync -bs=4M -size=256M -numjobs=1 -runtime=180 -group_reporting \ + -name=randrw_70read_4k diff --git a/tools/shyper b/tools/shyper new file mode 100644 index 0000000000000000000000000000000000000000..73a37e39a5d46e501c9e119eefbc2679195d10cf Binary files /dev/null and b/tools/shyper differ diff --git a/tools/shyper.ko b/tools/shyper.ko new file mode 100644 index 0000000000000000000000000000000000000000..ca501e517df61cbde77030be5f95d0274a5d81a7 Binary files /dev/null and b/tools/shyper.ko differ