diff options
author | Harunobu Kurokawa <harunobu.kurokawa.dn@renesas.com> | 2018-04-27 14:30:40 +0900 |
---|---|---|
committer | Harunobu Kurokawa <harunobu.kurokawa.dn@renesas.com> | 2018-04-27 14:30:40 +0900 |
commit | f8fb4a95d6f0ca9a92d3b9155e54ac1f3695a20d (patch) | |
tree | 7f5a50447e8a940b274c53581dc8af01e2fe0db6 /meta-rcar-gen3-adas/recipes-kernel | |
parent | 2e1a7e39e012ea4436c819f46cfcac05fb161184 (diff) | |
parent | f4fad8b9a0d29946c39bb760b76bc9c16448555a (diff) |
Merge remote-tracking branch 'cogent/v2.23.1' into sandbox/kingfisher_v2.23.1.20180427
Signed-off-by: Harunobu Kurokawa <harunobu.kurokawa.dn@renesas.com>
Conflicts:
meta-rcar-gen3-adas/conf/layer.conf
meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend
meta-rcar-gen3-adas/recipes-multimedia/pulseaudio/pulseaudio_8.0.bbappend
Change-Id: Ib0345634b8bec6a85357152138355d8f932bafc0
Diffstat (limited to 'meta-rcar-gen3-adas/recipes-kernel')
63 files changed, 31534 insertions, 3318 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0003-kernelheap-cached-support.patch b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0003-kernelheap-cached-support.patch new file mode 100644 index 0000000..171eac1 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0003-kernelheap-cached-support.patch @@ -0,0 +1,102 @@ +From d20b6893f3d22abd12ffb5421292fcee4820de33 Mon Sep 17 00:00:00 2001 +From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com> +Date: Wed, 14 Feb 2018 17:12:01 +0300 +Subject: [PATCH] mmngr: Add kernelheap cached buffers support. + +--- + .../mmngr/mmngr-module/files/mmngr/drv/mmngr_drv.c | 20 ++++++++++++++++---- + .../files/mmngr/include/mmngr_private_cmn.h | 7 +++++++ + .../files/mmngr/include/mmngr_public_cmn.h | 1 + + 4 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/mmngr_drv/mmngr/mmngr-module/files/mmngr/drv/mmngr_drv.c b/mmngr_drv/mmngr/mmngr-module/files/mmngr/drv/mmngr_drv.c +index cd797f5..c38329d 100644 +--- a/mmngr_drv/mmngr/mmngr-module/files/mmngr/drv/mmngr_drv.c ++++ b/mmngr_drv/mmngr/mmngr-module/files/mmngr/drv/mmngr_drv.c +@@ -736,7 +736,7 @@ static int close(struct inode *inode, struct file *file) + int entry = 0; + + if (p) { +- if ((p->flag == MM_KERNELHEAP) ++ if ((p->flag == MM_KERNELHEAP || p->flag == MM_KERNELHEAP_CACHED) + && (p->kernel_virt_addr != 0)) { + pr_err("MMD close kernelheap\n"); + mm_dev = mm_drvdata->mm_dev; +@@ -779,6 +779,7 @@ static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) + int ercd; + int ret; + struct MM_PARAM *p = file->private_data; ++ struct MM_CACHE_PARAM *cachep; + struct device *mm_dev; + + mm_dev = mm_drvdata->mm_dev; +@@ -830,6 +831,14 @@ static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) + goto exit; + } + break; ++ case MM_IOC_FLUSH: ++ cachep = (struct MM_CACHE_PARAM *) arg; ++ dma_sync_single_for_device(mm_dev, p->hard_addr + cachep->offset, cachep->len, DMA_FROM_DEVICE); ++ break; ++ case MM_IOC_INVAL: ++ cachep = (struct MM_CACHE_PARAM *) arg; ++ dma_sync_single_for_cpu(mm_dev, p->hard_addr + cachep->offset, cachep->len, DMA_TO_DEVICE); ++ break; + default: + pr_err("MMD CMD EFAULT\n"); + ret = -EFAULT; +@@ -954,9 +963,12 @@ static int mmap(struct file *filp, struct vm_area_struct *vma) + off += start; + vma->vm_pgoff = off >> PAGE_SHIFT; + +- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); +- +- vma->vm_flags |= (VM_IO | VM_DONTEXPAND | VM_DONTDUMP); ++ if (p->flag != MM_KERNELHEAP_CACHED) { ++ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ++ vma->vm_flags |= (VM_IO | VM_DONTEXPAND | VM_DONTDUMP); ++ } else { ++ vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP); ++ } + + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) +diff --git a/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private_cmn.h b/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private_cmn.h +index f731ab6..5f137c6 100644 +--- a/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private_cmn.h ++++ b/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private_cmn.h +@@ -72,6 +72,11 @@ struct MM_PARAM { + unsigned int flag; + }; + ++struct MM_CACHE_PARAM { ++ size_t offset; ++ size_t len; ++}; ++ + #define MM_IOC_MAGIC 'm' + #define MM_IOC_ALLOC _IOWR(MM_IOC_MAGIC, 0, struct MM_PARAM) + #define MM_IOC_FREE _IOWR(MM_IOC_MAGIC, 1, struct MM_PARAM) +@@ -80,5 +85,7 @@ struct MM_PARAM { + #define MM_IOC_ALLOC_CO _IOWR(MM_IOC_MAGIC, 4, struct MM_PARAM) + #define MM_IOC_FREE_CO _IOWR(MM_IOC_MAGIC, 5, struct MM_PARAM) + #define MM_IOC_SHARE _IOWR(MM_IOC_MAGIC, 6, struct MM_PARAM) ++#define MM_IOC_FLUSH _IOWR(MM_IOC_MAGIC, 7, struct MM_CACHE_PARAM) ++#define MM_IOC_INVAL _IOWR(MM_IOC_MAGIC, 8, struct MM_CACHE_PARAM) + + #endif /* __MMNGR_PRIVATE_CMN_H__ */ +diff --git a/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_public_cmn.h b/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_public_cmn.h +index dce81a1..a668019 100644 +--- a/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_public_cmn.h ++++ b/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_public_cmn.h +@@ -62,6 +62,7 @@ + #define __MMNGR_PUBLIC_CMN_H__ + + #define MM_KERNELHEAP 0 ++#define MM_KERNELHEAP_CACHED 5 + #define MM_CARVEOUT 1 + #define MM_CARVEOUT_SSP 3 + #define MM_CARVEOUT_LOSSY 4 +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend index 6abdc7d..bdb0251 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend @@ -2,5 +2,11 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" MMNGR_CFG_eagle = "MMNGR_V3MSK" MMNGR_CFG_v3msk = "MMNGR_V3MSK" +MMNGR_CFG_condor = "MMNGR_V3MSK" +MMNGR_CFG_v3mzf = "MMNGR_V3MSK" +MMNGR_CFG_v3hsk = "MMNGR_V3MSK" -SRC_URI_append = " file://0002-mmngr-Add-V3MSK-board.patch" +SRC_URI_append = " \ + file://0002-mmngr-Add-V3MSK-board.patch \ + file://0003-kernelheap-cached-support.patch \ +" diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/GPL-COPYING b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/GPL-COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/GPL-COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/MIT-COPYING b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/MIT-COPYING new file mode 100644 index 0000000..28e2a15 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/MIT-COPYING @@ -0,0 +1,41 @@ + +This software is Copyright (C) 2013 Renesas Electronics Corporation + +You may use, distribute and copy this software under the terms of the MIT +license displayed below. + +----------------------------------------------------------------------------- + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + Alternatively, the contents of this file may be used under the terms of + the GNU General Public License Version 2 ("GPL") in which case the provisions + of GPL are applicable instead of those above. + + If you wish to allow use of your version of this file only under the terms of + GPL, and not to allow others to use your version of this file under the terms + of the MIT license, indicate your decision by deleting the provisions above + and replace them with the notice and other provisions required by GPL as set + out in the file called "GPL-COPYING" included in this distribution. If you do + not delete the provisions above, a recipient may use your version of this file + under the terms of either the MIT license or GPL. + +----------------------------------------------------------------------------- + + EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS + PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------------------------------------------------------------------------- diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/Makefile b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/Makefile new file mode 100644 index 0000000..33c2ced --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/Makefile @@ -0,0 +1,14 @@ +obj-m := uio_isp.o + +SRC := $(shell pwd) + +all: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) + +modules_install: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install + +clean: + rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c + rm -f Module.markers Module.symvers modules.order + rm -rf .tmp_versions Modules.symvers diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/uio_isp.c b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/uio_isp.c new file mode 100644 index 0000000..5898b01 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/files/uio_isp.c @@ -0,0 +1,450 @@ +/** + * This driver module supports both the ISP itself and the ISP Wrapper + * by providing the user with two separate UIO devices in /dev, one for the + * ISP and one for the ISP Wrapper. The struct uio_isp_platform_data contains + * the uio_info for the ISP as well as the ISP Wrapper. + * The ISP has to be defined in the Device Tree using the following structure + isp0: isp@fec00000 { + compatible = "renesas,isp-r8a7797"; + reg = <0 0xfec00000 0 0x20000>, <0 0xfed00000 0 0x10000>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 817>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; + }; + * The first reg entry is the base and size of the ISP memory area. + * The second reg entry is the base and size of the ISP Wrapper memory area. + * The first interrupt entry is for the ISP. + * The second interrupt entry is for the ISP Wrapper + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/uio_driver.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/pm_runtime.h> + +#include <linux/of.h> +#include <linux/of_irq.h> + + +/* ISP internals */ +#define ISP_INTERNAL_REG_SIZE 0X20000 +#define ISP_INT_FRAME_START_MASK 0x84 +#define ISP_INT_FRAME_START_STATUS 0x88 +#define ISP_INT_FRAME_START_CLEAR 0x8c +#define ISP_INT_FRAME_END_MASK 0x98 +#define ISP_INT_FRAME_END_STATUS 0x9c +#define ISP_INT_FRAME_END_CLEAR 0xa0 +#define ISP_INT_STATS_MASK 0xb0 +#define ISP_INT_STATS_STATUS 0xb4 +#define ISP_INT_STATS_CLEAR 0xb8 + +/* ISP Wrapper internals */ +#define ISPVCR 0x00 +#define ISPINT_STATUS 0x40 +#define ISPINT_ENABLE 0x60 +#define ISPERR0_ENABLE 0x64 + +/* ISP uio driver name */ +#define DRIVER_NAME "uio_isp" +#define DRIVER_VERSION "0.1" + +/* Platform data for ISP and ISP Wrapper */ +struct uio_isp_platform_data +{ + struct platform_device *pdev; + struct uio_info *uio_info[2]; /* [0]: ISP [1]: ISP Wrapper */ + struct clk *isp_clock; + spinlock_t isp_lock; + spinlock_t wrapper_lock; + unsigned long isp_flags; + unsigned long wrapper_flags; + void __iomem *base_addr; + void __iomem *wrapper_addr; +}; + +/* ISP Wrapper function prototypes */ +static int isp_wrapper_probe(struct platform_device *pdev, struct uio_isp_platform_data * const priv); +static int isp_wrapper_open(struct uio_info *uio_info, struct inode *inode); +static int isp_wrapper_close(struct uio_info *uio_info, struct inode *inode); +static irqreturn_t isp_wrapper_irq_handler(int irq, struct uio_info *uio_info); + +/* ISP function prototypes */ +static int isp_probe(struct platform_device *pdev, struct uio_isp_platform_data * const priv); +static int isp_open(struct uio_info *uio_info, struct inode *inode); +static int isp_close(struct uio_info *uio_info, struct inode *inode); +static irqreturn_t isp_irq_handler(int irq, struct uio_info *uio_info); + +/* Common functions for ISP and ISP Wrapper */ +static int irq_control(struct uio_info *uio_info, s32 irq_on); + +static inline u32 read_reg(void * const base, const u32 offset) +{ + return ioread32((u8 *)base + offset); +} + +static inline void write_reg(void * const base, const u32 offset, const u32 val) +{ + iowrite32(val, (u8 *)base + offset); +} + +/* Function definitions */ +static int isp_wrapper_probe(struct platform_device *pdev, struct uio_isp_platform_data * const priv) +{ + struct uio_info *uio_info; + struct uio_mem *uio_mem; + struct resource *res; + char *wrapper_name; + int err; + struct device *dev = &pdev->dev; + + /* Construct the uio_info structure */ + uio_info = devm_kzalloc(dev, sizeof(*uio_info), GFP_KERNEL); + wrapper_name = devm_kmalloc(dev, strlen(pdev->name) + strlen("_wrapper") + 1, GFP_KERNEL); + if (!uio_info || !wrapper_name) + return -ENOMEM; + sprintf(wrapper_name, "%s_wrapper", pdev->name); + uio_info->version = DRIVER_VERSION; + uio_info->open = isp_wrapper_open; + uio_info->release = isp_wrapper_close; + uio_info->name = wrapper_name; + + /* Set up memory resource */ + uio_mem = &uio_info->mem[0]; + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "failed to get ISP Wrapper memory\n"); + return -EINVAL; + } + uio_mem->memtype = UIO_MEM_PHYS; + uio_mem->addr = res->start; + uio_mem->size = resource_size(res); + uio_mem->name = res->name; + if (!devm_request_mem_region(dev, res->start, resource_size(res), uio_info->name)) { + dev_err(dev, "failed to reserve ISP Wrapper memory\n"); + return -ENOMEM; + } + priv->wrapper_addr = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!priv->wrapper_addr) { + dev_err(dev, "failed to map ISP Wrapper memory\n"); + return -EIO; + } + + /* Set up interrupt */ + write_reg(priv->wrapper_addr, ISPINT_ENABLE, 0); + write_reg(priv->wrapper_addr, ISPERR0_ENABLE, 0); + uio_info->irq = irq_of_parse_and_map(pdev->dev.of_node, 1); + if (uio_info->irq == -ENXIO) { + dev_err(dev, "failed to parse ISP Wrapper interrupt\n"); + return -EINVAL; + } + uio_info->handler = isp_wrapper_irq_handler; + uio_info->irqcontrol = irq_control; + + /* Register the UIO device */ + if ((err = uio_register_device(dev, uio_info))) { + dev_err(dev, "failed to register UIO device for ISP Wrapper\n"); + return err; + } + + /* Register this uio_info with the platform data */ + uio_info->priv = priv; + priv->uio_info[1] = uio_info; + spin_lock_init(&priv->wrapper_lock); + priv->wrapper_flags = 1; /* The ISP Wrapper interrupt is active */ + + /* Print some information */ + dev_dbg(dev, "ISP Wrapper irq %ld\n", uio_info->irq); + + return 0; +} + +static int isp_wrapper_open(struct uio_info *uio_info, struct inode *inode) +{ + struct uio_isp_platform_data *priv = uio_info->priv; + + dev_dbg(&priv->pdev->dev, "isp wrapper open\n"); + + return 0; +} + +static int isp_wrapper_close(struct uio_info *uio_info, struct inode *inode) +{ + struct uio_isp_platform_data *priv = uio_info->priv; + + dev_dbg(&priv->pdev->dev, "isp wrapper close\n"); + + return 0; +} + +static irqreturn_t isp_wrapper_irq_handler(int irq, struct uio_info *uio_info) +{ + struct uio_isp_platform_data *priv = uio_info->priv; + u32 ispint_status = read_reg(priv->wrapper_addr, ISPINT_STATUS); + + /* Mask all interrupts */ + write_reg(priv->wrapper_addr, ISPINT_ENABLE, 0); + + if (!ispint_status) + return IRQ_NONE; + + return IRQ_HANDLED; +} + +static int isp_probe(struct platform_device *pdev, struct uio_isp_platform_data * const priv) +{ + struct uio_info *uio_info; + struct uio_mem *uio_mem; + struct resource *res; + int err; + struct device *dev = &pdev->dev; + + /* Construct the uio_info structure */ + uio_info = devm_kzalloc(dev, sizeof(*uio_info), GFP_KERNEL); + if (!uio_info) + return -ENOMEM; + uio_info->version = DRIVER_VERSION; + uio_info->open = isp_open; + uio_info->release = isp_close; + uio_info->name = pdev->name; + + /* Set up memory resource */ + uio_mem = &uio_info->mem[0]; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "failed to get ISP memory\n"); + return -EINVAL; + } + uio_mem->memtype = UIO_MEM_PHYS; + uio_mem->addr = res->start; + uio_mem->size = resource_size(res); + uio_mem->name = res->name; + if (!devm_request_mem_region(dev, res->start, resource_size(res), uio_info->name)) { + dev_err(dev, "failed to reserve ISP memory\n"); + return -ENOMEM; + } + priv->base_addr = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!priv->base_addr) { + dev_err(dev, "failed to map ISP memory\n"); + return -EIO; + } + + /* Set up interrupt */ + write_reg(priv->base_addr, ISP_INT_FRAME_START_MASK, 0); + write_reg(priv->base_addr, ISP_INT_FRAME_END_MASK, 0); + write_reg(priv->base_addr, ISP_INT_STATS_MASK, 0); + uio_info->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + if (uio_info->irq == -ENXIO) { + dev_err(dev, "failed to parse ISP interrupt\n"); + return -EINVAL; + } + uio_info->handler = isp_irq_handler; + uio_info->irqcontrol = irq_control; + + /* Set up clock */ + priv->isp_clock = devm_clk_get(dev, NULL); + if (IS_ERR(priv->isp_clock)) { + dev_err(dev, "failed to get ISP clock info\n"); + return -ENODEV; + } + + /* Register the UIO device */ + if ((err = uio_register_device(dev, uio_info))) { + dev_err(dev, "failed to register UIO device for ISP\n"); + return err; + } + + /* Register the uio_info with the platform data */ + uio_info->priv = priv; + priv->uio_info[0] = uio_info; + spin_lock_init(&priv->isp_lock); + priv->isp_flags = 1; /* ISP interrupt is active */ + + /* Register the UIO device with the PM framework */ + pm_runtime_enable(dev); + + /* Enable clocks */ + if ((err = clk_prepare_enable(priv->isp_clock))) { + dev_err(dev, "failed to enable clock\n"); + return -EBUSY; + } + + /* Print some information */ + dev_dbg(dev, "ISP irq %ld clock %ld Hz\n", uio_info->irq, clk_get_rate(priv->isp_clock)); + + return 0; +} + +static int isp_open(struct uio_info *uio_info, __attribute__((unused)) struct inode *inode) +{ + struct uio_isp_platform_data *priv = uio_info->priv; + + dev_dbg(&priv->pdev->dev, "isp open\n"); + /* Wait until the PM has woken up the device */ + pm_runtime_get_sync(&priv->pdev->dev); + + if (!test_and_set_bit(0, &priv->isp_flags)) + enable_irq((unsigned int)uio_info->irq); + + return 0; +} + +static int isp_close(struct uio_info *uio_info, __attribute__((unused)) struct inode *inode) +{ + struct uio_isp_platform_data *priv = uio_info->priv; + + dev_dbg(&priv->pdev->dev, "isp close\n"); + /* Tell the PM that the device has become idle */ + pm_runtime_put_sync(&priv->pdev->dev); + + if (test_and_clear_bit(0, &priv->isp_flags)) + disable_irq((unsigned int)uio_info->irq); + + return 0; +} + +static irqreturn_t isp_irq_handler(int irq, struct uio_info *uio_info) +{ + struct uio_isp_platform_data *priv = uio_info->priv; + u32 fstart_status; + u32 fend_status; + u32 stats_status; + + /* Mask all interrupts, umask by user process */ + write_reg(priv->base_addr, ISP_INT_FRAME_START_MASK, 0); + write_reg(priv->base_addr, ISP_INT_FRAME_END_MASK, 0); + write_reg(priv->base_addr, ISP_INT_STATS_MASK, 0); + + fstart_status = read_reg(priv->base_addr, ISP_INT_FRAME_START_STATUS); + fend_status = read_reg(priv->base_addr, ISP_INT_FRAME_END_STATUS); + stats_status = read_reg(priv->base_addr, ISP_INT_STATS_STATUS); + + if (!(fstart_status | fend_status | stats_status)) { + return IRQ_NONE; + } + + return IRQ_HANDLED; +} + +static int irq_control(struct uio_info *uio_info, s32 irq_on) +{ + struct uio_isp_platform_data *const priv = uio_info->priv; + unsigned long flag; + + if (uio_info == priv->uio_info[0]) { + dev_dbg(&priv->pdev->dev, "ISP irq_control\n"); + /* This is the ISP */ + spin_lock_irqsave(&priv->isp_lock, flag); + if (irq_on) { + if (!test_and_set_bit(0, &priv->isp_flags)) { + enable_irq((unsigned int)uio_info->irq); + } + } + else { + if (test_and_clear_bit(0, &priv->isp_flags)) { + disable_irq((unsigned int)uio_info->irq); + } + } + spin_unlock_irqrestore(&priv->isp_lock, flag); + } else { + dev_dbg(&priv->pdev->dev, "ISP Wrapper irq_control\n"); + /* This is the ISP Wrapper */ + spin_lock_irqsave(&priv->wrapper_lock, flag); + if (irq_on) { + if (!test_and_set_bit(0, &priv->wrapper_flags)) { + enable_irq((unsigned int)uio_info->irq); + } + } + else { + if (test_and_clear_bit(0, &priv->wrapper_flags)) { + disable_irq((unsigned int)uio_info->irq); + } + } + spin_unlock_irqrestore(&priv->wrapper_lock, flag); + } + + return 0; +} + +static int uio_isp_probe(struct platform_device *pdev) +{ + struct uio_isp_platform_data *priv; + int err; + + /* Allocate memory for the common housekeeping structure */ + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->pdev = pdev; + + if ((err = isp_wrapper_probe(pdev, priv))) + return err; + if ((err = isp_probe(pdev, priv))) + return err; + + platform_set_drvdata(pdev, priv); + + return 0; +} + +static int uio_isp_remove(struct platform_device *pdev) +{ + struct uio_isp_platform_data *priv = platform_get_drvdata(pdev); + + uio_unregister_device(priv->uio_info[0]); + uio_unregister_device(priv->uio_info[1]); + + clk_disable_unprepare(priv->isp_clock); + pm_runtime_disable(&priv->pdev->dev); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +/* Power management */ +static int uio_runtime_isp_nop(__attribute__((unused)) struct device *dev) +{ + return 0; +}; + +static const struct dev_pm_ops uio_dev_pm_isp_ops = +{ + .runtime_suspend = &uio_runtime_isp_nop, + .runtime_resume = &uio_runtime_isp_nop, +}; + +/* Compatible table */ +static const struct of_device_id rcar_isp_dt_ids[] = +{ + { .compatible = "renesas,isp-r8a7797", .data = 0 }, + { .compatible = "renesas,isp-r8a7798", .data = 0 }, + {}, +}; +MODULE_DEVICE_TABLE(of, rcar_isp_dt_ids); + +/* Platform driver structure */ +static struct platform_driver uio_isp_platform_driver = +{ + .probe = &uio_isp_probe, + .remove = &uio_isp_remove, + .driver = + { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .pm = &uio_dev_pm_isp_ops, + .of_match_table = of_match_ptr(rcar_isp_dt_ids) + } +}; +module_platform_driver(uio_isp_platform_driver); + +MODULE_AUTHOR("Renesas Electronics Corporation"); +MODULE_DESCRIPTION("Userspace I/O driver for ISP"); +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/kernel-module-uio-isp_0.1.bb b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/kernel-module-uio-isp_0.1.bb new file mode 100644 index 0000000..ed3a742 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-isp/kernel-module-uio-isp_0.1.bb @@ -0,0 +1,27 @@ +SUMMARY = "ISP UIO Driver Module" +LICENSE = "GPLv2 & MIT" +LIC_FILES_CHKSUM = " \ + file://GPL-COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \ + file://MIT-COPYING;md5=fea016ce2bdf2ec10080f69e9381d378 \ + " + +inherit module + +PR = "r0" +PV = "0.1" + +SRC_URI = " \ + file://Makefile \ + file://uio_isp.c \ + file://GPL-COPYING \ + file://MIT-COPYING \ + " + +S = "${WORKDIR}" + +KERNEL_MODULE_AUTOLOAD += "uio_isp" +KERNEL_MODULE_PROBECONF += "uio_isp" + +module_conf_uio_isp = "" +module_conf_uio_isp_r8a7795 = "options uio_isp clear_int" +module_conf_uio_isp_r8a7796 = "options uio_isp clear_int" diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch index d8806ba..411d0ee 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch @@ -3,7 +3,8 @@ From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> Date: Sun, 15 May 2016 21:53:13 +0300 Subject: [PATCH] spi: sh-msiof: fixes -speed up polling of CTR register +speed up polling of CTR register and allow scheduling instead of +busy loop Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- @@ -19,15 +20,24 @@ index d096f5a..6817304 100644 sh_msiof_write(p, CTR, data); - for (k = 100; k > 0; k--) { -+ for (k = 1000; k > 0; k--) { ++ for (k = 100000; k > 0; k--) { if ((sh_msiof_read(p, CTR) & mask) == set) break; - udelay(10); -+ udelay(1); ++ usleep_range(1, 2); } return k > 0 ? 0 : -ETIMEDOUT; +@@ -295,7 +295,7 @@ static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p) + if (!(sh_msiof_read(p, CTR) & mask)) + break; + +- udelay(10); ++ usleep_range(10, 20); + } + } + -- 1.9.1 diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch index ffe7684..42b8f23 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch @@ -7,11 +7,11 @@ This adds Renesas R8A7797 SoC support Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- - arch/arm64/Kconfig.platforms | 6 + - arch/arm64/boot/dts/renesas/r8a7797.dtsi | 1156 +++++++++++ + arch/arm64/Kconfig.platforms | 8 + + arch/arm64/boot/dts/renesas/r8a7797.dtsi | 1168 +++++++++++ drivers/clk/renesas/Kconfig | 1 + drivers/clk/renesas/Makefile | 1 + - drivers/clk/renesas/r8a7797-cpg-mssr.c | 231 +++ + drivers/clk/renesas/r8a7797-cpg-mssr.c | 232 +++ drivers/clk/renesas/rcar-gen3-cpg.c | 41 +- drivers/clk/renesas/rcar-gen3-cpg.h | 6 + drivers/clk/renesas/renesas-cpg-mssr.c | 6 + @@ -47,7 +47,7 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> drivers/thermal/rcar_gen3_thermal.c | 29 + include/dt-bindings/clock/r8a7797-cpg-mssr.h | 48 + include/dt-bindings/power/r8a7797-sysc.h | 32 + - 40 files changed, 4486 insertions(+), 29 deletions(-) + 40 files changed, 4501 insertions(+), 29 deletions(-) create mode 100644 arch/arm64/boot/dts/renesas/r8a7797.dtsi create mode 100644 drivers/clk/renesas/r8a7797-cpg-mssr.c create mode 100644 drivers/pinctrl/sh-pfc/pfc-r8a7797.c @@ -56,15 +56,17 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> create mode 100644 include/dt-bindings/power/r8a7797-sysc.h diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms -index ebe0a37..d3b6771 100644 +index ebe0a37..9cebaad 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms -@@ -166,6 +166,12 @@ config ARCH_R8A77965 +@@ -166,6 +166,14 @@ config ARCH_R8A77965 help This enables support for the Renesas R-Car M3N SoC. +config ARCH_R8A7797 + bool "Renesas R-Car V3M SoC Platform" ++ select SYS_SUPPORTS_SH_TMU ++ select SYS_SUPPORTS_SH_CMT + depends on ARCH_RENESAS + help + This enables support for the Renesas R-Car V3M SoC. @@ -74,10 +76,10 @@ index ebe0a37..d3b6771 100644 help diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi new file mode 100644 -index 0000000..0dd374f +index 0000000..faefe8a --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi -@@ -0,0 +1,1156 @@ +@@ -0,0 +1,1167 @@ +/* + * Device Tree Source for the r8a7797 SoC + * @@ -113,6 +115,7 @@ index 0000000..0dd374f + vin2 = &vin2; + vin3 = &vin3; + tsc0 = &tsc1; ++ isp0 = &isp0; + }; + + psci { @@ -577,9 +580,9 @@ index 0000000..0dd374f + }; + }; + -+ cmt0: timer@ffca0000 { ++ cmt0: timer@e60f0000 { + compatible = "renesas,cmt-48-r8a7797", "renesas,cmt-48-gen2"; -+ reg = <0 0xffca0000 0 0x1004>; ++ reg = <0 0xe60f0000 0 0x1004>; + interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 303>; @@ -1232,6 +1235,16 @@ index 0000000..0dd374f + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; + }; ++ ++ isp0: isp@fec00000 { ++ compatible = "renesas,isp-r8a7797"; ++ reg = <0 0xfec00000 0 0x20000>, ++ <0 0xfed00000 0 0x10000>; ++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 817>; ++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; ++ }; + }; +}; diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig @@ -1260,10 +1273,10 @@ index 2c224e9..c2ef11e 100644 obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o diff --git a/drivers/clk/renesas/r8a7797-cpg-mssr.c b/drivers/clk/renesas/r8a7797-cpg-mssr.c new file mode 100644 -index 0000000..6f481a4 +index 0000000..0460ed4 --- /dev/null +++ b/drivers/clk/renesas/r8a7797-cpg-mssr.c -@@ -0,0 +1,231 @@ +@@ -0,0 +1,232 @@ +/* + * r8a7797 Clock Pulse Generator / Module Standby and Software Reset + * @@ -1362,6 +1375,7 @@ index 0000000..6f481a4 + DEF_MOD("tmu3", 122, R8A7797_CLK_S2D2), + DEF_MOD("tmu2", 123, R8A7797_CLK_S2D2), + DEF_MOD("tmu1", 124, R8A7797_CLK_S2D2), ++ DEF_MOD("tmu0", 125, R8A7797_CLK_CP), + DEF_MOD("ivcp1e", 127, R8A7797_CLK_S2D1), + DEF_MOD("scif4", 203, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */ + DEF_MOD("scif3", 204, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */ @@ -1818,10 +1832,10 @@ index ecae864..d5fa06c 100644 lvdcr0 |= LVDCR0_LVRES; diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c -index 74c17d8..149c107 100644 +index 156fe5f..ea451cd 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c -@@ -807,6 +807,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap) +@@ -836,6 +836,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap) { .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 }, { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 }, { .compatible = "renesas,i2c-r8a77965", .data = (void *)I2C_RCAR_GEN3 }, @@ -5029,7 +5043,7 @@ index 29b8a4d..2ba6a76 100644 obj-$(CONFIG_RCAR_DDR_BACKUP) += s2ram_ddr_backup.o diff --git a/drivers/soc/renesas/r8a7797-sysc.c b/drivers/soc/renesas/r8a7797-sysc.c new file mode 100644 -index 0000000..b71bdedb +index 0000000..cde7d9e --- /dev/null +++ b/drivers/soc/renesas/r8a7797-sysc.c @@ -0,0 +1,39 @@ @@ -5060,12 +5074,12 @@ index 0000000..b71bdedb + PD_CPU_NOCR }, + { "cr7", 0x240, 0, R8A7797_PD_CR7, R8A7797_PD_ALWAYS_ON }, + { "a3ir", 0x180, 0, R8A7797_PD_A3IR, R8A7797_PD_ALWAYS_ON }, -+ { "a2ir0", 0x400, 0, R8A7797_PD_A2IR0, R8A7797_PD_ALWAYS_ON }, -+ { "a2ir1", 0x400, 1, R8A7797_PD_A2IR1, R8A7797_PD_A2IR0 }, -+ { "a2ir2", 0x400, 2, R8A7797_PD_A2IR2, R8A7797_PD_A2IR0 }, -+ { "a2ir3", 0x400, 3, R8A7797_PD_A2IR3, R8A7797_PD_A2IR0 }, -+ { "a2sc0", 0x400, 4, R8A7797_PD_A2SC0, R8A7797_PD_ALWAYS_ON }, -+ { "a2sc1", 0x400, 5, R8A7797_PD_A2SC1, R8A7797_PD_A2SC0 }, ++ { "a2ir0", 0x400, 0, R8A7797_PD_A2IR0, R8A7797_PD_A3IR }, ++ { "a2ir1", 0x400, 1, R8A7797_PD_A2IR1, R8A7797_PD_A3IR }, ++ { "a2ir2", 0x400, 2, R8A7797_PD_A2IR2, R8A7797_PD_A3IR }, ++ { "a2ir3", 0x400, 3, R8A7797_PD_A2IR3, R8A7797_PD_A3IR }, ++ { "a2sc0", 0x400, 4, R8A7797_PD_A2SC0, R8A7797_PD_A3IR }, ++ { "a2sc1", 0x400, 5, R8A7797_PD_A2SC1, R8A7797_PD_A3IR }, +}; + +const struct rcar_sysc_info r8a7797_sysc_info __initconst = { @@ -5168,7 +5182,7 @@ index 1b33c50..63f943d 100644 { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 }, #endif diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c -index 36e70db..a2606fe 100644 +index 2d3ac0b..1488964 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -216,7 +216,8 @@ static int msiof_rcar_is_gen3(struct device *dev) diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch index 00928d1..1623d12 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch @@ -4,139 +4,122 @@ Date: Sun, 14 May 2017 15:20:01 +0300 Subject: [PATCH] Gen3: LVDS cameras This add Gen3 LVDS cameras support: -- deserializers: MAX9286, TI964, TI954, TI960 -- cameras: ov10635, ov490+ov10640, ov495+OV2775, ar0132, ap0101+ar014x +- deserializers: MAX9286, DS90UB954/960/964 +- cameras: ov10635, ov490+ov10640, ov495+OV2775, ar0132, ar0220, + ap0101+ar014x, ov2775, imx390, ox03a Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- - drivers/media/i2c/soc_camera/Kconfig | 47 + - drivers/media/i2c/soc_camera/Makefile | 7 + - drivers/media/i2c/soc_camera/ap0101_ar014x.c | 536 ++++++++++ + drivers/media/i2c/soc_camera/Kconfig | 19 + + drivers/media/i2c/soc_camera/Makefile | 3 + + drivers/media/i2c/soc_camera/ap0101_ar014x.c | 588 ++++ drivers/media/i2c/soc_camera/ap0101_ar014x.h | 28 + - drivers/media/i2c/soc_camera/ar0132.c | 581 +++++++++++ - drivers/media/i2c/soc_camera/ar0132.h | 213 ++++ - drivers/media/i2c/soc_camera/max9286.c | 672 +++++++++++++ - drivers/media/i2c/soc_camera/max9286.h | 244 +++++ - drivers/media/i2c/soc_camera/ov10635.c | 758 ++++++++++++++ - drivers/media/i2c/soc_camera/ov10635.h | 1139 +++++++++++++++++++++ + drivers/media/i2c/soc_camera/ar0132.c | 565 ++++ + drivers/media/i2c/soc_camera/ar0132.h | 212 ++ + drivers/media/i2c/soc_camera/ar0220.c | 538 +++ + drivers/media/i2c/soc_camera/ar0220.h | 43 + + drivers/media/i2c/soc_camera/imx390.c | 533 +++ + drivers/media/i2c/soc_camera/imx390.h | 3817 ++++++++++++++++++++++ + drivers/media/i2c/soc_camera/max9286.c | 692 ++++ + drivers/media/i2c/soc_camera/max9286.h | 244 ++ + drivers/media/i2c/soc_camera/ov10635.c | 759 +++++ + drivers/media/i2c/soc_camera/ov10635.h | 1139 +++++++ drivers/media/i2c/soc_camera/ov10635_debug.h | 54 + - drivers/media/i2c/soc_camera/ov106xx.c | 117 +++ - drivers/media/i2c/soc_camera/ov490_ov10640.c | 1156 ++++++++++++++++++++++ - drivers/media/i2c/soc_camera/ov490_ov10640.h | 102 ++ - drivers/media/i2c/soc_camera/ov495_ov2775.c | 658 ++++++++++++ + drivers/media/i2c/soc_camera/ov106xx.c | 161 + + drivers/media/i2c/soc_camera/ov2775.c | 538 +++ + drivers/media/i2c/soc_camera/ov2775.h | 1841 +++++++++++ + drivers/media/i2c/soc_camera/ov490_ov10640.c | 1133 +++++++ + drivers/media/i2c/soc_camera/ov490_ov10640.h | 102 + + drivers/media/i2c/soc_camera/ov495_ov2775.c | 650 ++++ drivers/media/i2c/soc_camera/ov495_ov2775.h | 23 + - drivers/media/i2c/soc_camera/ti954_ti9x3.c | 431 ++++++++ - drivers/media/i2c/soc_camera/ti964_ti9x3.c | 400 ++++++++ - drivers/media/i2c/soc_camera/ti9x4_ti9x3.h | 153 +++ - drivers/media/platform/soc_camera/rcar_csi2.c | 297 ++++-- - drivers/media/platform/soc_camera/rcar_vin.c | 211 +++- - drivers/media/platform/soc_camera/soc_camera.c | 17 +- - drivers/media/platform/soc_camera/soc_mediabus.c | 16 + + drivers/media/i2c/soc_camera/ox03a.c | 526 +++ + drivers/media/i2c/soc_camera/ox03a.h | 1724 ++++++++++ + drivers/media/i2c/soc_camera/ti9x4.c | 518 +++ + drivers/media/i2c/soc_camera/ti9x4.h | 156 + + drivers/media/platform/soc_camera/rcar_csi2.c | 312 +- + drivers/media/platform/soc_camera/rcar_vin.c | 194 +- + drivers/media/platform/soc_camera/soc_camera.c | 47 +- + drivers/media/platform/soc_camera/soc_mediabus.c | 26 + include/media/drv-intf/soc_mediabus.h | 3 + - include/media/soc_camera.h | 1 + - 25 files changed, 7755 insertions(+), 109 deletions(-) + include/media/soc_camera.h | 5 + + 32 files changed, 17066 insertions(+), 127 deletions(-) create mode 100644 drivers/media/i2c/soc_camera/ap0101_ar014x.c create mode 100644 drivers/media/i2c/soc_camera/ap0101_ar014x.h create mode 100644 drivers/media/i2c/soc_camera/ar0132.c create mode 100644 drivers/media/i2c/soc_camera/ar0132.h + create mode 100644 drivers/media/i2c/soc_camera/ar0220.c + create mode 100644 drivers/media/i2c/soc_camera/ar0220.h + create mode 100644 drivers/media/i2c/soc_camera/imx390.c + create mode 100644 drivers/media/i2c/soc_camera/imx390.h create mode 100644 drivers/media/i2c/soc_camera/max9286.c create mode 100644 drivers/media/i2c/soc_camera/max9286.h create mode 100644 drivers/media/i2c/soc_camera/ov10635.c create mode 100644 drivers/media/i2c/soc_camera/ov10635.h create mode 100644 drivers/media/i2c/soc_camera/ov10635_debug.h create mode 100644 drivers/media/i2c/soc_camera/ov106xx.c + create mode 100644 drivers/media/i2c/soc_camera/ov2775.c + create mode 100644 drivers/media/i2c/soc_camera/ov2775.h create mode 100644 drivers/media/i2c/soc_camera/ov490_ov10640.c create mode 100644 drivers/media/i2c/soc_camera/ov490_ov10640.h create mode 100644 drivers/media/i2c/soc_camera/ov495_ov2775.c create mode 100644 drivers/media/i2c/soc_camera/ov495_ov2775.h - create mode 100644 drivers/media/i2c/soc_camera/ti954_ti9x3.c - create mode 100644 drivers/media/i2c/soc_camera/ti964_ti9x3.c - create mode 100644 drivers/media/i2c/soc_camera/ti9x4_ti9x3.h + create mode 100644 drivers/media/i2c/soc_camera/ox03a.c + create mode 100644 drivers/media/i2c/soc_camera/ox03a.h + create mode 100644 drivers/media/i2c/soc_camera/ti9x4.c + create mode 100644 drivers/media/i2c/soc_camera/ti9x4.h diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig -index 7704bcf..82da59f 100644 +index 7704bcf..2249b40 100644 --- a/drivers/media/i2c/soc_camera/Kconfig +++ b/drivers/media/i2c/soc_camera/Kconfig -@@ -6,6 +6,53 @@ config SOC_CAMERA_IMX074 +@@ -6,6 +6,25 @@ config SOC_CAMERA_IMX074 help This driver supports IMX074 cameras from Sony -+config SOC_CAMERA_MAX9286_MAX9271 -+ tristate "max9286-max9271 GMSL support" ++config SOC_CAMERA_MAX9286 ++ tristate "max9286 GMSL support" + depends on SOC_CAMERA && I2C + help -+ This is a MAXIM max9286-max9271 GMSL driver ++ This is a MAXIM max9286 GMSL driver + +config SOC_CAMERA_OV106XX + tristate "ov106xx camera support" -+ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C ++ depends on SOC_CAMERA && I2C + help + This is a runtime detected OmniVision ov10635 or ov490-ov10640 + or ov495-ov2775 sensors camera driver + -+if !SOC_CAMERA_OV106XX -+ -+config SOC_CAMERA_OV10635 -+ tristate "ov10635 camera support" -+ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C -+ help -+ This is an OmniVision ov10635 sensor camera driver -+ -+config SOC_CAMERA_OV490_OV10640 -+ tristate "ov490-ov10640 camera support" -+ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C -+ help -+ This is an OmniVision ov490-ov10640 sensor camera driver -+ -+config SOC_CAMERA_OV495_OV2775 -+ tristate "ov495-ov2775 camera support" ++config SOC_CAMERA_TI9X4 ++ tristate "ti9x4 FPDLinkIII support" + depends on SOC_CAMERA && I2C + help -+ This is an OmniVision ov495-ov2775 sensor camera driver -+ -+endif -+ -+config SOC_CAMERA_TI964_TI9X3 -+ tristate "ti964-ti9x3 FPDLinkIII support" -+ depends on SOC_CAMERA && I2C -+ help -+ This is an Texas Instruments ti964-ti9X3 FPDLinkIII driver -+ -+config SOC_CAMERA_TI954_TI9X3 -+ tristate "ti954-ti9X3 FPDLinkIII support" -+ depends on SOC_CAMERA && I2C -+ help -+ This is an Texas Instruments ti954-ti9X3 FPDLinkIII driver ++ This is an Texas Instruments ti9X4 FPDLinkIII driver + config SOC_CAMERA_MT9M001 tristate "mt9m001 support" depends on SOC_CAMERA && I2C diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile -index 6f994f9..e88f6a9 100644 +index 6f994f9..2b2583a 100644 --- a/drivers/media/i2c/soc_camera/Makefile +++ b/drivers/media/i2c/soc_camera/Makefile -@@ -1,8 +1,15 @@ +@@ -1,8 +1,11 @@ obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o -+obj-$(CONFIG_SOC_CAMERA_MAX9286_MAX9271) += max9286.o -+obj-$(CONFIG_SOC_CAMERA_TI964_TI9X3) += ti964_ti9x3.o -+obj-$(CONFIG_SOC_CAMERA_TI954_TI9X3) += ti954_ti9x3.o ++obj-$(CONFIG_SOC_CAMERA_MAX9286) += max9286.o ++obj-$(CONFIG_SOC_CAMERA_TI9X4) += ti9x4.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o -+obj-$(CONFIG_SOC_CAMERA_OV10635) += ov10635.o -+obj-$(CONFIG_SOC_CAMERA_OV490_OV10640) += ov490_ov10640.o -+obj-$(CONFIG_SOC_CAMERA_OV495_OV2775) += ov495_ov2775.o +obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c new file mode 100644 -index 0000000..4757657 +index 0000000..2c6b034 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c -@@ -0,0 +1,536 @@ +@@ -0,0 +1,588 @@ +/* + * ON Semiconductor AP0101-AR014X sensor camera driver + * @@ -168,6 +151,8 @@ index 0000000..4757657 + +#define AP0101_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8 + ++static void ap0101_otp_id_read(struct i2c_client *client); ++ +struct ap0101_priv { + struct v4l2_subdev sd; + struct v4l2_ctrl_handler hdl; @@ -184,7 +169,6 @@ index 0000000..4757657 + int port; + int gpio_resetb; + int gpio_fsin; -+ +}; + +static inline struct ap0101_priv *to_ap0101(const struct i2c_client *client) @@ -201,6 +185,7 @@ index 0000000..4757657 + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -222,6 +207,40 @@ index 0000000..4757657 + return 0; +} + ++static u16 ap0101_ar014x_read(struct i2c_client *client, u16 addr) ++{ ++ u16 reg_val = 0; ++ ++ reg16_write16(client, 0x0040, 0x8d00); ++ usleep_range(100, 150); /* wait 100 us */ ++ reg16_write16(client, 0xfc00, addr); ++ reg16_write16(client, 0xfc02, 0x0200); /* 2 bytes */ ++ reg16_write16(client, 0x0040, 0x8d05); ++ usleep_range(100, 150); /* wait 100 us */ ++ reg16_write16(client, 0x0040, 0x8d08); ++ usleep_range(100, 150); /* wait 100 us */ ++ reg16_read16(client, 0xfc00, ®_val); ++ reg16_write16(client, 0x0040, 0x8d02); ++ usleep_range(100, 150); /* wait 100 us */ ++ ++ return reg_val; ++} ++ ++static void ap0101_ar014x_write(struct i2c_client *client, u16 addr, u16 val) ++{ ++ reg16_write16(client, 0x0040, 0x8d00); ++ usleep_range(100, 150); /* wait 100 us */ ++ reg16_write16(client, 0xfc00, addr); ++ reg16_write16(client, 0xfc02, 0x0200 | (val >> 8)); /* 2 bytes */ ++ reg16_write16(client, 0xfc04, (val & 0xff) << 8); ++ reg16_write16(client, 0x0040, 0x8d06); ++ usleep_range(100, 150); /* wait 100 us */ ++ reg16_write16(client, 0x0040, 0x8d08); ++ usleep_range(100, 150); /* wait 100 us */ ++ reg16_write16(client, 0x0040, 0x8d02); ++ usleep_range(100, 150); /* wait 100 us */ ++} ++ +static int ap0101_s_stream(struct v4l2_subdev *sd, int enable) +{ + return 0; @@ -280,6 +299,8 @@ index 0000000..4757657 + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ap0101_priv *priv = to_ap0101(client); + ++ ap0101_otp_id_read(client); ++ + memcpy(edid->edid, priv->id, 6); + + edid->edid[6] = 0xff; @@ -448,6 +469,19 @@ index 0000000..4757657 + +static void ap0101_otp_id_read(struct i2c_client *client) +{ ++ struct ap0101_priv *priv = to_ap0101(client); ++ int i; ++ ++ /* read camera id from ar014x OTP memory */ ++ ap0101_ar014x_write(client, 0x3054, 0x400); ++ ap0101_ar014x_write(client, 0x304a, 0x110); ++ usleep_range(25000, 25500); /* wait 25 ms */ ++ ++ for (i = 0; i < 6; i += 2) { ++ /* first 4 bytes are equal on all ar014x */ ++ priv->id[i] = ap0101_ar014x_read(client, 0x3800 + i + 4) >> 8; ++ priv->id[i + 1] = ap0101_ar014x_read(client, 0x3800 + i + 4) & 0xff; ++ } +} + +static ssize_t ap0101_otp_id_show(struct device *dev, @@ -457,6 +491,8 @@ index 0000000..4757657 + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ap0101_priv *priv = to_ap0101(client); + ++ ap0101_otp_id_read(client); ++ + return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n", + priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); +} @@ -482,7 +518,6 @@ index 0000000..4757657 + + /* Program wizard registers */ + ap0101_set_regs(client, ap0101_regs_wizard, ARRAY_SIZE(ap0101_regs_wizard)); -+ + /* Read OTP IDs */ + ap0101_otp_id_read(client); + @@ -709,10 +744,10 @@ index 0000000..16599a1 +}; diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c new file mode 100644 -index 0000000..bbaeeaae +index 0000000..c0ac733 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ar0132.c -@@ -0,0 +1,581 @@ +@@ -0,0 +1,565 @@ +/* + * ON Semiconductor AR0132 sensor camera driver + * @@ -743,7 +778,7 @@ index 0000000..bbaeeaae +#define AR0132_PID 0x3000 +#define AR0132_VERSION_REG 0x2400 + -+#define AR0132_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12 ++#define AR0132_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12 + +struct ar0132_priv { + struct v4l2_subdev sd; @@ -759,8 +794,7 @@ index 0000000..bbaeeaae + /* serializers */ + int max9286_addr; + int max9271_addr; -+ int ti964_addr; -+ int ti954_addr; ++ int ti9x4_addr; + int ti9x3_addr; + int port; + int gpio_resetb; @@ -782,6 +816,7 @@ index 0000000..bbaeeaae + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -1107,19 +1142,13 @@ index 0000000..bbaeeaae + break; + + if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && -+ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") && -+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_addr) && -+ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) -+ break; -+ -+ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && -+ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") && -+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && + !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) + break; + } + -+ if (!priv->max9286_addr && !priv->ti964_addr && !priv->ti954_addr) { ++ if (!priv->max9286_addr && !priv->ti9x4_addr) { + dev_err(&client->dev, "deserializer does not present for AR0132\n"); + return -EINVAL; + } @@ -1135,18 +1164,8 @@ index 0000000..bbaeeaae + reg8_write(client, 0x0A, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */ + usleep_range(2000, 2500); /* wait 2ms */ + }; -+ if (priv->ti964_addr) { -+ client->addr = priv->ti964_addr; /* Deserializer I2C address */ -+ -+ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ -+ reg8_write(client, 0x5d, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */ -+ -+ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */ -+ } -+ if (priv->ti954_addr) { -+ client->addr = priv->ti954_addr; /* Deserializer I2C address */ ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ + + reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ + usleep_range(2000, 2500); /* wait 2ms */ @@ -1296,12 +1315,12 @@ index 0000000..bbaeeaae +#endif diff --git a/drivers/media/i2c/soc_camera/ar0132.h b/drivers/media/i2c/soc_camera/ar0132.h new file mode 100644 -index 0000000..bcee0e5 +index 0000000..7dfc4e3 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ar0132.h -@@ -0,0 +1,213 @@ +@@ -0,0 +1,212 @@ +/* -+ * ON Semiconductor ar0132 sensor camera wizard 1110x620@30/BGGR/BT601/12bit ++ * ON Semiconductor AR0132 sensor camera wizard 1110x620@30/BGGR/BT601/12bit + * + * Copyright (C) 2017 Cogent Embedded, Inc. + * @@ -1316,16 +1335,15 @@ index 0000000..bcee0e5 + +#define AR0132_EMBEDDED_LINE + -+#define AR0132_MAX_WIDTH 1665 // (1110*3/2) ++#define AR0132_MAX_WIDTH 1104 +#define AR0132_MAX_HEIGHT 624 + +#define AR0132_DELAY 0xffff + +#define AR0132_MAX_ROI_DIM_X 1288 +#define AR0132_MAX_ROI_DIM_Y 968 -+#define AR0132_InfoLines 4 + -+#define AR0132_ROI_DIM_X 1110 // 1104 ++#define AR0132_ROI_DIM_X 1104 +#define AR0132_ROI_DIM_Y 620 // AR0132_MAX_HEIGHT + +#define AR0132_ROI_Y_START 0x00AE @@ -1359,11 +1377,11 @@ index 0000000..bcee0e5 + //256: Walking 1 test pattern (12 bit) +#ifdef AR0132_DISPLAY_PATTERN_FIXED +{0x3070, 0x0001}, ++#endif +{0x3072, 0x0123}, // R +{0x3074, 0x0456}, // G(GR row) +{0x3076, 0x0abc}, // B +{0x3078, 0x0def}, // G(GB row) -+#endif +#ifdef AR0132_DISPLAY_PATTERN_COLOR_BAR +{0x3070, 0x0002}, +#endif @@ -1452,7 +1470,7 @@ index 0000000..bcee0e5 +{0x302E, AR0132_PLL_Pre_Clk_Div}, +{0x3030, AR0132_PLL_Multiplier}, +{0x3032, 0x0000}, // SCALING_MODE = 0 -+{0x3040, 0xC000}, // READ_MODE = read_mode_vert_flip | read_mode_horiz_mirror ++{0x3040, 0x0000}, // READ_MODE = read_mode_vert_flip | read_mode_horiz_mirror +{0x3044, 0x0404}, // Dark Control = 1028 +{0x30A6, 0x0001}, // Y Odd Inc. (A) = 1 +{0x30A8, 0x0001}, // Y Odd Inc. (B) = 1 @@ -1513,12 +1531,4967 @@ index 0000000..bcee0e5 +{0x31D0, 0x0001}, +{0x30B0, 0x2002}, +}; +diff --git a/drivers/media/i2c/soc_camera/ar0220.c b/drivers/media/i2c/soc_camera/ar0220.c +new file mode 100644 +index 0000000..eb20187 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/ar0220.c +@@ -0,0 +1,538 @@ ++/* ++ * ON Semiconductor AR0220 sensor camera driver ++ * ++ * Copyright (C) 2017-2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include <linux/delay.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/module.h> ++#include <linux/videodev2.h> ++ ++#include <media/soc_camera.h> ++#include <media/v4l2-common.h> ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-of.h> ++ ++#include "ar0220.h" ++ ++#define AR0220_I2C_ADDR 0x10 ++//#define AR0220_I2C_ADDR 0x54 // eeprom ++ ++#define AR0220_PID 0x3000 ++#define AR0220_VERSION_REG 0x0C54 ++ ++#define AR0220_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG14_1X14 ++ ++struct ar0220_priv { ++ struct v4l2_subdev sd; ++ struct v4l2_ctrl_handler hdl; ++ struct media_pad pad; ++ struct v4l2_rect rect; ++ int init_complete; ++ u8 id[6]; ++ int exposure; ++ int gain; ++ int autogain; ++ /* serializers */ ++ int ti9x4_addr; ++ int ti9x3_addr; ++ int port; ++ int gpio_resetb; ++ int gpio_fsin; ++}; ++ ++static inline struct ar0220_priv *to_ar0220(const struct i2c_client *client) ++{ ++ return container_of(i2c_get_clientdata(client), struct ar0220_priv, sd); ++} ++ ++static int ar0220_set_regs(struct i2c_client *client, ++ const struct ar0220_reg *regs, int nr_regs) ++{ ++ int i; ++ ++ for (i = 0; i < nr_regs; i++) { ++ if (regs[i].reg == AR0220_DELAY) { ++ mdelay(regs[i].val); ++ continue; ++ } ++ ++ reg16_write16(client, regs[i].reg, regs[i].val); ++ } ++ ++ return 0; ++} ++ ++static int ar0220_s_stream(struct v4l2_subdev *sd, int enable) ++{ ++ return 0; ++} ++ ++static int ar0220_get_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0220_priv *priv = to_ar0220(client); ++ ++ if (format->pad) ++ return -EINVAL; ++ ++ mf->width = priv->rect.width; ++ mf->height = priv->rect.height; ++ mf->code = AR0220_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ return 0; ++} ++ ++static int ar0220_set_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ ++ mf->code = AR0220_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ if (format->which == V4L2_SUBDEV_FORMAT_TRY) ++ cfg->try_fmt = *mf; ++ ++ return 0; ++} ++ ++static int ar0220_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ if (code->pad || code->index > 0) ++ return -EINVAL; ++ ++ code->code = AR0220_MEDIA_BUS_FMT; ++ ++ return 0; ++} ++ ++static int ar0220_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0220_priv *priv = to_ar0220(client); ++ ++ memcpy(edid->edid, priv->id, 6); ++ ++ edid->edid[6] = 0xff; ++ edid->edid[7] = client->addr; ++ edid->edid[8] = AR0220_VERSION_REG >> 8; ++ edid->edid[9] = AR0220_VERSION_REG & 0xff; ++ ++ return 0; ++} ++ ++static int ar0220_set_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct v4l2_rect *rect = &sel->r; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0220_priv *priv = to_ar0220(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || ++ sel->target != V4L2_SEL_TGT_CROP) ++ return -EINVAL; ++ ++ rect->left = ALIGN(rect->left, 2); ++ rect->top = ALIGN(rect->top, 2); ++ rect->width = ALIGN(rect->width, 2); ++ rect->height = ALIGN(rect->height, 2); ++ ++ if ((rect->left + rect->width > AR0220_MAX_WIDTH) || ++ (rect->top + rect->height > AR0220_MAX_HEIGHT)) ++ *rect = priv->rect; ++ ++ priv->rect.left = rect->left; ++ priv->rect.top = rect->top; ++ priv->rect.width = rect->width; ++ priv->rect.height = rect->height; ++ ++ return 0; ++} ++ ++static int ar0220_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0220_priv *priv = to_ar0220(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) ++ return -EINVAL; ++ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = AR0220_MAX_WIDTH; ++ sel->r.height = AR0220_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = AR0220_MAX_WIDTH; ++ sel->r.height = AR0220_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP: ++ sel->r = priv->rect; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int ar0220_g_mbus_config(struct v4l2_subdev *sd, ++ struct v4l2_mbus_config *cfg) ++{ ++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | ++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; ++ cfg->type = V4L2_MBUS_CSI2; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++static int ar0220_g_register(struct v4l2_subdev *sd, ++ struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ int ret; ++ u16 val = 0; ++ ++ ret = reg16_read16(client, (u16)reg->reg, &val); ++ if (ret < 0) ++ return ret; ++ ++ reg->val = val; ++ reg->size = sizeof(u16); ++ ++ return 0; ++} ++ ++static int ar0220_s_register(struct v4l2_subdev *sd, ++ const struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ ++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val); ++} ++#endif ++ ++static struct v4l2_subdev_core_ops ar0220_core_ops = { ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ .g_register = ar0220_g_register, ++ .s_register = ar0220_s_register, ++#endif ++}; ++ ++static int ar0220_s_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct v4l2_subdev *sd = to_sd(ctrl); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0220_priv *priv = to_ar0220(client); ++ int ret = -EINVAL; ++ ++ if (!priv->init_complete) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_BRIGHTNESS: ++ case V4L2_CID_CONTRAST: ++ case V4L2_CID_SATURATION: ++ case V4L2_CID_HUE: ++ case V4L2_CID_GAMMA: ++ case V4L2_CID_SHARPNESS: ++ case V4L2_CID_AUTOGAIN: ++ case V4L2_CID_GAIN: ++ case V4L2_CID_EXPOSURE: ++ case V4L2_CID_HFLIP: ++ case V4L2_CID_VFLIP: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops ar0220_ctrl_ops = { ++ .s_ctrl = ar0220_s_ctrl, ++}; ++ ++static struct v4l2_subdev_video_ops ar0220_video_ops = { ++ .s_stream = ar0220_s_stream, ++ .g_mbus_config = ar0220_g_mbus_config, ++}; ++ ++static const struct v4l2_subdev_pad_ops ar0220_subdev_pad_ops = { ++ .get_edid = ar0220_get_edid, ++ .enum_mbus_code = ar0220_enum_mbus_code, ++ .get_selection = ar0220_get_selection, ++ .set_selection = ar0220_set_selection, ++ .get_fmt = ar0220_get_fmt, ++ .set_fmt = ar0220_set_fmt, ++}; ++ ++static struct v4l2_subdev_ops ar0220_subdev_ops = { ++ .core = &ar0220_core_ops, ++ .video = &ar0220_video_ops, ++ .pad = &ar0220_subdev_pad_ops, ++}; ++ ++static void ar0220_otp_id_read(struct i2c_client *client) ++{ ++} ++ ++static ssize_t ar0220_otp_id_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev)); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0220_priv *priv = to_ar0220(client); ++ ++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n", ++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++} ++ ++static DEVICE_ATTR(otp_id_ar0220, S_IRUGO, ar0220_otp_id_show, NULL); ++ ++static int ar0220_initialize(struct i2c_client *client) ++{ ++ struct ar0220_priv *priv = to_ar0220(client); ++ u16 val = 0; ++ u16 pid = 0; ++ int ret = 0; ++ int tmp_addr; ++ ++ /* check and show model ID */ ++ reg16_read16(client, AR0220_PID, &pid); ++ ++ if (pid != AR0220_VERSION_REG) { ++ dev_dbg(&client->dev, "Product ID error %x\n", pid); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ /* setup XCLK */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=27MHz: CLKDIV=2, M=15, N=251: 22.5792*160/8*15/251=26.987MHz=CLK_OUT */ ++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */ ++ reg8_write(client, 0x06, 0x6f); /* Set CLKDIV and M */ ++ reg8_write(client, 0x07, 0xfb); /* Set N */ ++ } ++ client->addr = tmp_addr; ++ ++ /* Program wizard registers */ ++ ar0220_set_regs(client, ar0220_regs_wizard, ARRAY_SIZE(ar0220_regs_wizard)); ++ ++ /* Enable stream */ ++ reg16_read16(client, 0x301a, &val); // read inital reset_register value ++ val |= (1 << 2); // Set streamOn bit ++ reg16_write16(client, 0x301a, val); // Start Streaming ++ ++ /* Read OTP IDs */ ++ ar0220_otp_id_read(client); ++ ++ dev_info(&client->dev, "ar0220 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pid, AR0220_MAX_WIDTH, AR0220_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++err: ++ return ret; ++} ++ ++static int ar0220_parse_dt(struct device_node *np, struct ar0220_priv *priv) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd); ++ int i; ++ struct device_node *endpoint = NULL, *rendpoint = NULL; ++ int tmp_addr = 0; ++ ++ for (i = 0; ; i++) { ++ endpoint = of_graph_get_next_endpoint(np, endpoint); ++ if (!endpoint) ++ break; ++ ++ of_node_put(endpoint); ++ ++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0); ++ if (!rendpoint) ++ continue; ++ ++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && ++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) ++ break; ++ } ++ ++ if (!priv->ti9x4_addr) { ++ dev_err(&client->dev, "deserializer does not present\n"); ++ return -EINVAL; ++ } ++ ++ /* setup I2C translator address */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ ++ ++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ ++ reg8_write(client, 0x5d, AR0220_I2C_ADDR << 1); /* Sensor native I2C address */ ++ ++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */ ++ } ++ client->addr = tmp_addr; ++ ++ mdelay(10); ++ ++ return 0; ++} ++ ++static int ar0220_probe(struct i2c_client *client, ++ const struct i2c_device_id *did) ++{ ++ struct ar0220_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0220_subdev_ops); ++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ priv->exposure = 0x100; ++ priv->gain = 0x100; ++ priv->autogain = 1; ++ v4l2_ctrl_handler_init(&priv->hdl, 4); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_CONTRAST, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_SATURATION, 0, 7, 1, 2); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_HUE, 0, 23, 1, 12); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_GAMMA, -128, 128, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_SHARPNESS, 0, 10, 1, 3); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 1); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ priv->sd.ctrl_handler = &priv->hdl; ++ ++ ret = priv->hdl.error; ++ if (ret) ++ goto cleanup; ++ ++ v4l2_ctrl_handler_setup(&priv->hdl); ++ ++ priv->pad.flags = MEDIA_PAD_FL_SOURCE; ++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; ++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad); ++ if (ret < 0) ++ goto cleanup; ++ ++ ret = ar0220_parse_dt(client->dev.of_node, priv); ++ if (ret) ++ goto cleanup; ++ ++ ret = ar0220_initialize(client); ++ if (ret < 0) ++ goto cleanup; ++ ++ priv->rect.left = 0; ++ priv->rect.top = 0; ++ priv->rect.width = AR0220_MAX_WIDTH; ++ priv->rect.height = AR0220_MAX_HEIGHT; ++ ++ ret = v4l2_async_register_subdev(&priv->sd); ++ if (ret) ++ goto cleanup; ++ ++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0220) != 0) { ++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n"); ++ goto cleanup; ++ } ++ ++ priv->init_complete = 1; ++ ++ return 0; ++ ++cleanup: ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++#ifdef CONFIG_SOC_CAMERA_AR0220 ++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n", ++ client->addr, client->adapter->name); ++#endif ++ return ret; ++} ++ ++static int ar0220_remove(struct i2c_client *client) ++{ ++ struct ar0220_priv *priv = i2c_get_clientdata(client); ++ ++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0220); ++ v4l2_async_unregister_subdev(&priv->sd); ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SOC_CAMERA_AR0220 ++static const struct i2c_device_id ar0220_id[] = { ++ { "ar0220", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, ar0220_id); ++ ++static const struct of_device_id ar0220_of_ids[] = { ++ { .compatible = "aptina,ar0220", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, ar0220_of_ids); ++ ++static struct i2c_driver ar0220_i2c_driver = { ++ .driver = { ++ .name = "ar0220", ++ .of_match_table = ar0220_of_ids, ++ }, ++ .probe = ar0220_probe, ++ .remove = ar0220_remove, ++ .id_table = ar0220_id, ++}; ++ ++module_i2c_driver(ar0220_i2c_driver); ++ ++MODULE_DESCRIPTION("SoC Camera driver for AR0220"); ++MODULE_AUTHOR("Vladimir Barinov"); ++MODULE_LICENSE("GPL"); ++#endif +diff --git a/drivers/media/i2c/soc_camera/ar0220.h b/drivers/media/i2c/soc_camera/ar0220.h +new file mode 100644 +index 0000000..205c351 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/ar0220.h +@@ -0,0 +1,43 @@ ++/* ++ * ON Semiconductor AR0220 sensor camera wizard 1820x940@44/RCCB/MIPI ++ * ++ * Copyright (C) 2017 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++//#define AR0220_DISPLAY_PATTERN_FIXED ++//#define AR0220_DISPLAY_PATTERN_COLOR_BAR ++ ++#define AR0220_MAX_WIDTH 1820 ++#define AR0220_MAX_HEIGHT 944 ++ ++#define AR0220_DELAY 0xffff ++ ++struct ar0220_reg { ++ u16 reg; ++ u16 val; ++}; ++ ++static const struct ar0220_reg ar0220_regs_wizard[] = { ++{0x301A, 0x0018}, // RESET_REGISTER ++{AR0220_DELAY, 500}, // Wait 500ms ++{0x3070, 0x0000}, // 1: Solid color test pattern, ++ // 2: Full color bar test pattern, ++ // 3: Fade to grey color bar test pattern, ++ //256: Walking 1 test pattern (12 bit) ++{0x3072, 0x0123}, // R ++{0x3074, 0x0456}, // G(GR row) ++{0x3076, 0x0abc}, // B ++{0x3078, 0x0def}, // G(GB row) ++#ifdef AR0220_DISPLAY_PATTERN_FIXED ++{0x3070, 0x0001}, ++#endif ++#ifdef AR0220_DISPLAY_PATTERN_COLOR_BAR ++{0x3070, 0x0002}, ++#endif ++{AR0220_DELAY, 100}, // Wait 100ms ++}; +diff --git a/drivers/media/i2c/soc_camera/imx390.c b/drivers/media/i2c/soc_camera/imx390.c +new file mode 100644 +index 0000000..61f430d +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/imx390.c +@@ -0,0 +1,533 @@ ++/* ++ * OmniVision IMX390 sensor camera driver ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include <linux/delay.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/module.h> ++#include <linux/videodev2.h> ++ ++#include <media/soc_camera.h> ++#include <media/v4l2-common.h> ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-of.h> ++ ++#include "imx390.h" ++ ++#define IMX390_I2C_ADDR 0x21 ++ ++#define IMX390_PID 0x0330 ++#define IMX390_VER 0x0330 ++#define IMX390_VERSION_REG 0x1515 ++ ++#define IMX390_MEDIA_BUS_FMT MEDIA_BUS_FMT_SRGGB12_1X12 ++ ++struct imx390_priv { ++ struct v4l2_subdev sd; ++ struct v4l2_ctrl_handler hdl; ++ struct media_pad pad; ++ struct v4l2_rect rect; ++ int init_complete; ++ u8 id[6]; ++ int exposure; ++ int gain; ++ int autogain; ++ /* serializers */ ++ int ti9x4_addr; ++ int ti9x3_addr; ++ int port; ++ int gpio_resetb; ++ int gpio_fsin; ++}; ++ ++static inline struct imx390_priv *to_imx390(const struct i2c_client *client) ++{ ++ return container_of(i2c_get_clientdata(client), struct imx390_priv, sd); ++} ++ ++static int imx390_set_regs(struct i2c_client *client, ++ const struct imx390_reg *regs, int nr_regs) ++{ ++ int i; ++ ++ for (i = 0; i < nr_regs; i++) { ++ if (regs[i].reg == IMX390_DELAY) { ++ mdelay(regs[i].val); ++ continue; ++ } ++ ++ reg16_write(client, regs[i].reg, regs[i].val); ++ } ++ ++ return 0; ++} ++ ++static int imx390_s_stream(struct v4l2_subdev *sd, int enable) ++{ ++ return 0; ++} ++ ++static int imx390_get_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct imx390_priv *priv = to_imx390(client); ++ ++ if (format->pad) ++ return -EINVAL; ++ ++ mf->width = priv->rect.width; ++ mf->height = priv->rect.height; ++ mf->code = IMX390_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ return 0; ++} ++ ++static int imx390_set_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ ++ mf->code = IMX390_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ if (format->which == V4L2_SUBDEV_FORMAT_TRY) ++ cfg->try_fmt = *mf; ++ ++ return 0; ++} ++ ++static int imx390_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ if (code->pad || code->index > 0) ++ return -EINVAL; ++ ++ code->code = IMX390_MEDIA_BUS_FMT; ++ ++ return 0; ++} ++ ++static int imx390_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct imx390_priv *priv = to_imx390(client); ++ ++ memcpy(edid->edid, priv->id, 6); ++ ++ edid->edid[6] = 0xff; ++ edid->edid[7] = client->addr; ++ edid->edid[8] = IMX390_VERSION_REG >> 8; ++ edid->edid[9] = IMX390_VERSION_REG & 0xff; ++ ++ return 0; ++} ++ ++static int imx390_set_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct v4l2_rect *rect = &sel->r; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct imx390_priv *priv = to_imx390(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || ++ sel->target != V4L2_SEL_TGT_CROP) ++ return -EINVAL; ++ ++ rect->left = ALIGN(rect->left, 2); ++ rect->top = ALIGN(rect->top, 2); ++ rect->width = ALIGN(rect->width, 2); ++ rect->height = ALIGN(rect->height, 2); ++ ++ if ((rect->left + rect->width > IMX390_MAX_WIDTH) || ++ (rect->top + rect->height > IMX390_MAX_HEIGHT)) ++ *rect = priv->rect; ++ ++ priv->rect.left = rect->left; ++ priv->rect.top = rect->top; ++ priv->rect.width = rect->width; ++ priv->rect.height = rect->height; ++ ++ return 0; ++} ++ ++static int imx390_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct imx390_priv *priv = to_imx390(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) ++ return -EINVAL; ++ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = IMX390_MAX_WIDTH; ++ sel->r.height = IMX390_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = IMX390_MAX_WIDTH; ++ sel->r.height = IMX390_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP: ++ sel->r = priv->rect; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int imx390_g_mbus_config(struct v4l2_subdev *sd, ++ struct v4l2_mbus_config *cfg) ++{ ++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | ++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; ++ cfg->type = V4L2_MBUS_CSI2; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++static int imx390_g_register(struct v4l2_subdev *sd, ++ struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ int ret; ++ u8 val = 0; ++ ++ ret = reg16_read(client, (u16)reg->reg, &val); ++ if (ret < 0) ++ return ret; ++ ++ reg->val = val; ++ reg->size = sizeof(u8); ++ ++ return 0; ++} ++ ++static int imx390_s_register(struct v4l2_subdev *sd, ++ const struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ ++ return reg16_write(client, (u16)reg->reg, (u8)reg->val); ++} ++#endif ++ ++static struct v4l2_subdev_core_ops imx390_core_ops = { ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ .g_register = imx390_g_register, ++ .s_register = imx390_s_register, ++#endif ++}; ++ ++static int imx390_s_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct v4l2_subdev *sd = to_sd(ctrl); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct imx390_priv *priv = to_imx390(client); ++ int ret = -EINVAL; ++ ++ if (!priv->init_complete) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_BRIGHTNESS: ++ case V4L2_CID_CONTRAST: ++ case V4L2_CID_SATURATION: ++ case V4L2_CID_HUE: ++ case V4L2_CID_GAMMA: ++ case V4L2_CID_SHARPNESS: ++ case V4L2_CID_AUTOGAIN: ++ case V4L2_CID_GAIN: ++ case V4L2_CID_EXPOSURE: ++ case V4L2_CID_HFLIP: ++ case V4L2_CID_VFLIP: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops imx390_ctrl_ops = { ++ .s_ctrl = imx390_s_ctrl, ++}; ++ ++static struct v4l2_subdev_video_ops imx390_video_ops = { ++ .s_stream = imx390_s_stream, ++ .g_mbus_config = imx390_g_mbus_config, ++}; ++ ++static const struct v4l2_subdev_pad_ops imx390_subdev_pad_ops = { ++ .get_edid = imx390_get_edid, ++ .enum_mbus_code = imx390_enum_mbus_code, ++ .get_selection = imx390_get_selection, ++ .set_selection = imx390_set_selection, ++ .get_fmt = imx390_get_fmt, ++ .set_fmt = imx390_set_fmt, ++}; ++ ++static struct v4l2_subdev_ops imx390_subdev_ops = { ++ .core = &imx390_core_ops, ++ .video = &imx390_video_ops, ++ .pad = &imx390_subdev_pad_ops, ++}; ++ ++static void imx390_otp_id_read(struct i2c_client *client) ++{ ++} ++ ++static ssize_t imx390_otp_id_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev)); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct imx390_priv *priv = to_imx390(client); ++ ++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n", ++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++} ++ ++static DEVICE_ATTR(otp_id_imx390, S_IRUGO, imx390_otp_id_show, NULL); ++ ++static int imx390_initialize(struct i2c_client *client) ++{ ++ struct imx390_priv *priv = to_imx390(client); ++ u8 val = 0; ++ u16 pid; ++ int ret = 0; ++ int tmp_addr; ++ ++ /* check and show model ID */ ++ reg16_read(client, IMX390_PID, &val); ++ pid = val; ++ reg16_read(client, IMX390_VER, &val); ++ pid = (pid << 8) | val; ++ ++ if (pid != IMX390_VERSION_REG) { ++ dev_dbg(&client->dev, "Product ID error %x\n", pid); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ /* setup XCLK */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=25MHz: CLKDIV=4, M=7, N=253: 22.5792*160/4*7/253=24.989MHz=CLK_OUT */ ++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */ ++ reg8_write(client, 0x06, 0x47); /* Set CLKDIV and M */ ++ reg8_write(client, 0x07, 0xfd); /* Set N */ ++ } ++ client->addr = tmp_addr; ++ ++ /* Program wizard registers */ ++ imx390_set_regs(client, imx390_regs_wizard, ARRAY_SIZE(imx390_regs_wizard)); ++ /* Read OTP IDs */ ++ imx390_otp_id_read(client); ++ ++ dev_info(&client->dev, "imx390 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pid, IMX390_MAX_WIDTH, IMX390_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++err: ++ return ret; ++} ++ ++static int imx390_parse_dt(struct device_node *np, struct imx390_priv *priv) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd); ++ int i; ++ struct device_node *endpoint = NULL, *rendpoint = NULL; ++ int tmp_addr = 0; ++ ++ for (i = 0; ; i++) { ++ endpoint = of_graph_get_next_endpoint(np, endpoint); ++ if (!endpoint) ++ break; ++ ++ of_node_put(endpoint); ++ ++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0); ++ if (!rendpoint) ++ continue; ++ ++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && ++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) ++ break; ++ } ++ ++ if (!priv->ti9x4_addr) { ++ dev_err(&client->dev, "deserializer does not present\n"); ++ return -EINVAL; ++ } ++ ++ /* setup I2C translator address */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ ++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ ++ reg8_write(client, 0x5d, IMX390_I2C_ADDR << 1); /* Sensor native I2C address */ ++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */ ++ } ++ client->addr = tmp_addr; ++ ++ mdelay(10); ++ ++ return 0; ++} ++ ++static int imx390_probe(struct i2c_client *client, ++ const struct i2c_device_id *did) ++{ ++ struct imx390_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ v4l2_i2c_subdev_init(&priv->sd, client, &imx390_subdev_ops); ++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ priv->exposure = 0x100; ++ priv->gain = 0x100; ++ priv->autogain = 1; ++ v4l2_ctrl_handler_init(&priv->hdl, 4); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_CONTRAST, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_SATURATION, 0, 7, 1, 2); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_HUE, 0, 23, 1, 12); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_GAMMA, -128, 128, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_SHARPNESS, 0, 10, 1, 3); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 1); ++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ priv->sd.ctrl_handler = &priv->hdl; ++ ++ ret = priv->hdl.error; ++ if (ret) ++ goto cleanup; ++ ++ v4l2_ctrl_handler_setup(&priv->hdl); ++ ++ priv->pad.flags = MEDIA_PAD_FL_SOURCE; ++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; ++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad); ++ if (ret < 0) ++ goto cleanup; ++ ++ ret = imx390_parse_dt(client->dev.of_node, priv); ++ if (ret) ++ goto cleanup; ++ ++ ret = imx390_initialize(client); ++ if (ret < 0) ++ goto cleanup; ++ ++ priv->rect.left = 0; ++ priv->rect.top = 0; ++ priv->rect.width = IMX390_MAX_WIDTH; ++ priv->rect.height = IMX390_MAX_HEIGHT; ++ ++ ret = v4l2_async_register_subdev(&priv->sd); ++ if (ret) ++ goto cleanup; ++ ++ if (device_create_file(&client->dev, &dev_attr_otp_id_imx390) != 0) { ++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n"); ++ goto cleanup; ++ } ++ ++ priv->init_complete = 1; ++ ++ return 0; ++ ++cleanup: ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++#ifdef CONFIG_SOC_CAMERA_IMX390 ++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n", ++ client->addr, client->adapter->name); ++#endif ++ return ret; ++} ++ ++static int imx390_remove(struct i2c_client *client) ++{ ++ struct imx390_priv *priv = i2c_get_clientdata(client); ++ ++ device_remove_file(&client->dev, &dev_attr_otp_id_imx390); ++ v4l2_async_unregister_subdev(&priv->sd); ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SOC_CAMERA_IMX390 ++static const struct i2c_device_id imx390_id[] = { ++ { "imx390", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, imx390_id); ++ ++static const struct of_device_id imx390_of_ids[] = { ++ { .compatible = "sony,imx390", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, imx390_of_ids); ++ ++static struct i2c_driver imx390_i2c_driver = { ++ .driver = { ++ .name = "imx390", ++ .of_match_table = imx390_of_ids, ++ }, ++ .probe = imx390_probe, ++ .remove = imx390_remove, ++ .id_table = imx390_id, ++}; ++ ++module_i2c_driver(imx390_i2c_driver); ++ ++MODULE_DESCRIPTION("SoC Camera driver for IMX390"); ++MODULE_AUTHOR("Vladimir Barinov"); ++MODULE_LICENSE("GPL"); ++#endif +diff --git a/drivers/media/i2c/soc_camera/imx390.h b/drivers/media/i2c/soc_camera/imx390.h +new file mode 100644 +index 0000000..4217cd9 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/imx390.h +@@ -0,0 +1,3817 @@ ++/* ++ * OmniVision IMX390 sensor camera wizard 1920x1080@30/BGGR/MIPI ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++//#define IMX390_DISPLAY_PATTERN_COLOR_BAR ++ ++#define IMX390_MAX_WIDTH 1920 ++#define IMX390_MAX_HEIGHT 1080 ++ ++#define IMX390_DELAY 0xffff ++#define IMX390_DT 0x2c /* MIPI Data Type RAW12 */ ++ ++struct imx390_reg { ++ u16 reg; ++ u8 val; ++}; ++ ++/* wizard: MIPI 1920x1080 RAW12 Linear 30fps 700Mbps */ ++static const struct imx390_reg imx390_regs_wizard[] = { ++{0x000C, 0xF2}, ++{0x000D, 0x02}, ++{0x000E, 0x00}, ++{0x0010, 0xF2}, ++{0x0011, 0x02}, ++{0x0012, 0x00}, ++{0x0018, 0x15}, ++{0x0019, 0x00}, ++{0x001A, 0x0C}, ++{0x001B, 0x00}, ++{0x0038, 0x00}, ++{0x003C, 0x00}, ++{0x003D, 0x00}, ++{0x003E, 0x00}, ++{0x0040, 0x00}, ++{0x0041, 0x00}, ++{0x0042, 0x00}, ++{0x0044, 0x00}, ++{0x0045, 0x00}, ++{0x0046, 0x00}, ++{0x0048, 0x00}, ++{0x0049, 0x00}, ++{0x004A, 0x00}, ++{0x004C, 0x00}, ++{0x004D, 0x00}, ++{0x004E, 0x00}, ++{0x0050, 0x00}, ++{0x0051, 0x00}, ++{0x0052, 0x00}, ++{0x0054, 0x00}, ++{0x0055, 0x00}, ++{0x0056, 0x00}, ++{0x0058, 0x00}, ++{0x0059, 0x00}, ++{0x005A, 0x00}, ++{0x005C, 0x00}, ++{0x005D, 0x00}, ++{0x005E, 0x00}, ++{0x0060, 0x00}, ++{0x0061, 0x00}, ++{0x0062, 0x00}, ++{0x0064, 0x00}, ++{0x0065, 0x00}, ++{0x0066, 0x00}, ++{0x0068, 0x00}, ++{0x0069, 0x00}, ++{0x006A, 0x00}, ++{0x0078, 0x00}, ++{0x007C, 0x00}, ++{0x007D, 0x00}, ++{0x0080, 0x00}, ++{0x0081, 0x00}, ++{0x00F4, 0x1C}, ++{0x00F5, 0xF8}, ++{0x00F6, 0x01}, ++{0x00F8, 0x03}, ++{0x00F9, 0x00}, ++{0x00FA, 0x00}, ++{0x00FB, 0x00}, ++{0x0114, 0x00}, ++{0x0115, 0x01}, ++{0x0118, 0x20}, ++{0x0119, 0x03}, ++{0x011A, 0x00}, ++{0x011B, 0x41}, ++{0x011C, 0x80}, ++{0x011D, 0x00}, ++{0x0120, 0x20}, ++{0x0121, 0x00}, ++{0x0122, 0x00}, ++{0x0123, 0x44}, ++{0x0124, 0x00}, ++{0x0125, 0x01}, ++{0x0128, 0xAC}, ++{0x0129, 0x0D}, ++{0x012A, 0x00}, ++{0x012B, 0xA4}, ++{0x012C, 0x00}, ++{0x012D, 0x01}, ++{0x0130, 0xC4}, ++{0x0131, 0x09}, ++{0x0132, 0x00}, ++{0x0133, 0xDA}, ++//{0x013A, ,3}, ++{0x013B, 0x01}, ++//{0x013C, ,3}, ++//{0x013D, ,3}, ++//{0x013E, ,3}, ++//{0x0140, ,3}, ++//{0x0141, ,3}, ++//{0x0142, ,3}, ++//{0x0144, ,3}, ++//{0x0145, ,3}, ++//{0x0146, ,3}, ++//{0x0148, ,3}, ++//{0x0149, ,3}, ++//{0x014A, ,3}, ++//{0x014C, ,3}, ++//{0x014D, ,3}, ++//{0x014E, ,3}, ++//{0x0150, ,3}, ++//{0x0151, ,3}, ++//{0x0152, ,3}, ++//{0x0154, ,3}, ++//{0x0155, ,3}, ++//{0x0156, ,3}, ++//{0x0158, ,3}, ++//{0x0159, ,3}, ++//{0x015A, ,3}, ++//{0x015C, ,3}, ++//{0x015D, ,3}, ++//{0x015E, ,3}, ++//{0x0160, ,3}, ++//{0x0161, ,3}, ++//{0x0162, ,3}, ++//{0x0164, ,3}, ++//{0x0165, ,3}, ++//{0x0166, ,3}, ++//{0x0168, ,3}, ++//{0x0169, ,3}, ++//{0x016A, ,3}, ++//{0x016C, ,3}, ++//{0x016D, ,3}, ++//{0x016E, ,3}, ++//{0x0170, ,3}, ++//{0x0171, ,3}, ++//{0x0172, ,3}, ++//{0x0174, ,3}, ++//{0x0175, ,3}, ++//{0x0176, ,3}, ++//{0x0178, ,3}, ++//{0x0179, ,3}, ++//{0x017A, ,3}, ++//{0x017C, ,3}, ++//{0x017D, ,3}, ++//{0x017E, ,3}, ++//{0x0180, ,3}, ++//{0x0181, ,3}, ++//{0x0182, ,3}, ++//{0x0184, ,3}, ++//{0x0185, ,3}, ++//{0x0186, ,3}, ++//{0x0188, ,3}, ++//{0x0189, ,3}, ++//{0x018A, ,3}, ++//{0x018C, ,3}, ++//{0x018D, ,3}, ++//{0x018E, ,3}, ++//{0x0190, ,3}, ++//{0x0191, ,3}, ++//{0x0192, ,3}, ++//{0x0194, ,3}, ++//{0x0195, ,3}, ++//{0x0196, ,3}, ++//{0x0198, ,3}, ++//{0x0199, ,3}, ++//{0x019A, ,3}, ++//{0x019B, ,3}, ++//{0x019C, ,3}, ++//{0x019D, ,3}, ++//{0x019E, ,3}, ++//{0x019F, ,3}, ++//{0x01A0, ,3}, ++//{0x01A1, ,3}, ++//{0x01A2, ,3}, ++//{0x01A3, ,3}, ++//{0x01A4, ,3}, ++//{0x01A5, ,3}, ++//{0x01A6, ,3}, ++//{0x01A7, ,3}, ++//{0x01A8, ,3}, ++//{0x01A9, ,3}, ++//{0x01AA, ,3}, ++//{0x01AB, ,3}, ++//{0x01AC, ,3}, ++//{0x01AD, ,3}, ++//{0x01AE, ,3}, ++//{0x01AF, ,3}, ++//{0x01B0, ,3}, ++//{0x01B1, ,3}, ++//{0x01B2, ,3}, ++//{0x01B3, ,3}, ++//{0x01B4, ,3}, ++//{0x01B5, ,3}, ++//{0x01B6, ,3}, ++//{0x01B7, ,3}, ++//{0x01B8, ,3}, ++//{0x01B9, ,3}, ++//{0x01BA, ,3}, ++//{0x01BB, ,3}, ++//{0x01BC, ,3}, ++//{0x01BD, ,3}, ++//{0x01BE, ,3}, ++//{0x01BF, ,3}, ++//{0x01C0, ,3}, ++//{0x01C1, ,3}, ++//{0x01C2, ,3}, ++//{0x01C3, ,3}, ++{0x01C4, 0x00}, ++{0x01C5, 0x00}, ++{0x01CC, 0x01}, ++{0x01D0, 0x09}, ++{0x01D4, 0x01}, ++{0x0232, 0x7E}, ++{0x0233, 0x00}, ++{0x0390, 0x00}, ++{0x0391, 0x00}, ++{0x0392, 0x00}, ++#ifdef IMX390_DISPLAY_PATTERN_COLOR_BAR ++{0x01DB, 0x32}, ++{0x03C0, 0x02}, ++#else ++{0x03C0, 0x00}, ++#endif ++{0x2000, 0x55}, ++{0x2001, 0x55}, ++{0x2002, 0x55}, ++{0x2003, 0x05}, ++{0x2004, 0x02}, ++{0x2008, 0x65}, ++{0x2009, 0x04}, ++{0x200A, 0x00}, ++{0x200C, 0x30}, ++{0x200D, 0x11}, ++{0x2010, 0x04}, ++{0x2014, 0x01}, ++{0x2018, 0x02}, ++{0x2019, 0x04}, ++{0x201A, 0x00}, ++{0x201C, 0x21}, ++{0x201D, 0x11}, ++{0x201E, 0x00}, ++{0x201F, 0x00}, ++{0x2020, 0xBC}, ++{0x2021, 0x00}, ++{0x2022, 0x7F}, ++{0x2023, 0x00}, ++{0x2024, 0xBA}, ++{0x2025, 0x00}, ++{0x2026, 0x81}, ++{0x2027, 0x00}, ++{0x2028, 0x7D}, ++{0x2029, 0x90}, ++{0x202A, 0x05}, ++{0x202C, 0xFC}, ++{0x202D, 0x02}, ++{0x202E, 0x25}, ++{0x202F, 0x03}, ++{0x2030, 0x05}, ++{0x2031, 0x02}, ++{0x2032, 0xCA}, ++{0x2033, 0x02}, ++{0x2034, 0xFC}, ++{0x2035, 0x02}, ++{0x2036, 0x25}, ++{0x2037, 0x03}, ++{0x2038, 0x25}, ++{0x2039, 0x97}, ++{0x203A, 0xEC}, ++{0x203B, 0x01}, ++{0x203C, 0xF5}, ++{0x203D, 0x8E}, ++{0x203E, 0x0C}, ++{0x203F, 0x2D}, ++{0x2040, 0x69}, ++{0x2041, 0x01}, ++{0x2042, 0x8E}, ++{0x2043, 0x01}, ++{0x2044, 0x0C}, ++{0x2045, 0x02}, ++{0x2046, 0x31}, ++{0x2047, 0x02}, ++{0x2048, 0x6A}, ++{0x2049, 0x01}, ++{0x204A, 0x8E}, ++{0x204B, 0x01}, ++{0x204C, 0x0D}, ++{0x204D, 0x02}, ++{0x204E, 0x31}, ++{0x204F, 0x02}, ++{0x2050, 0x7B}, ++{0x2051, 0x00}, ++{0x2052, 0x7D}, ++{0x2053, 0x00}, ++{0x2054, 0x95}, ++{0x2055, 0x00}, ++{0x2056, 0x97}, ++{0x2057, 0x00}, ++{0x2058, 0xAD}, ++{0x2059, 0x00}, ++{0x205A, 0xAF}, ++{0x205B, 0x00}, ++{0x205C, 0x92}, ++{0x205D, 0x00}, ++{0x205E, 0x94}, ++{0x205F, 0x00}, ++{0x2060, 0x8E}, ++{0x2061, 0x00}, ++{0x2062, 0x90}, ++{0x2063, 0x00}, ++{0x2064, 0xB1}, ++{0x2065, 0x00}, ++{0x2066, 0xB3}, ++{0x2067, 0x00}, ++{0x2068, 0x08}, ++{0x2069, 0x00}, ++{0x206A, 0x04}, ++{0x206B, 0x00}, ++{0x206C, 0x84}, ++{0x206D, 0x00}, ++{0x206E, 0x80}, ++{0x206F, 0x00}, ++{0x2070, 0x04}, ++{0x2071, 0x00}, ++{0x2072, 0x46}, ++{0x2073, 0x00}, ++{0x2074, 0xE9}, ++{0x2075, 0x01}, ++{0x2076, 0x74}, ++{0x2077, 0x02}, ++{0x2078, 0x80}, ++{0x2079, 0x00}, ++{0x207A, 0xC1}, ++{0x207B, 0x00}, ++{0x207C, 0xFF}, ++{0x207D, 0x03}, ++{0x207E, 0xFF}, ++{0x207F, 0x03}, ++{0x2080, 0x78}, ++{0x2081, 0x00}, ++{0x2082, 0x6A}, ++{0x2083, 0x01}, ++{0x2084, 0xE4}, ++{0x2085, 0x01}, ++{0x2086, 0x2B}, ++{0x2087, 0x03}, ++{0x2088, 0x00}, ++{0x2089, 0x00}, ++{0x208A, 0xFF}, ++{0x208B, 0x03}, ++{0x208C, 0xFF}, ++{0x208D, 0x03}, ++{0x208E, 0xFF}, ++{0x208F, 0x03}, ++{0x2090, 0x7D}, ++{0x2091, 0x00}, ++{0x2092, 0x62}, ++{0x2093, 0x01}, ++{0x2094, 0xE9}, ++{0x2095, 0x01}, ++{0x2096, 0x00}, ++{0x2097, 0x00}, ++{0x2098, 0x7C}, ++{0x2099, 0x00}, ++{0x209A, 0x21}, ++{0x209B, 0x03}, ++{0x209C, 0xE9}, ++{0x209D, 0x01}, ++{0x209E, 0x21}, ++{0x209F, 0x03}, ++{0x20A0, 0xFF}, ++{0x20A1, 0x03}, ++{0x20A2, 0xFF}, ++{0x20A3, 0x03}, ++{0x20A4, 0xFF}, ++{0x20A5, 0x03}, ++{0x20A6, 0xFF}, ++{0x20A7, 0x03}, ++{0x20A8, 0xFF}, ++{0x20A9, 0x03}, ++{0x20AA, 0xFF}, ++{0x20AB, 0x03}, ++{0x20AC, 0xFF}, ++{0x20AD, 0x03}, ++{0x20AE, 0xFF}, ++{0x20AF, 0x03}, ++{0x20B0, 0xFF}, ++{0x20B1, 0x03}, ++{0x20B2, 0xFF}, ++{0x20B3, 0x03}, ++{0x20B4, 0x87}, ++{0x20B5, 0xCC}, ++{0x20B6, 0x87}, ++{0x20B7, 0x08}, ++{0x20B8, 0xF4}, ++{0x20B9, 0xA5}, ++{0x20BA, 0x07}, ++{0x20BC, 0x1F}, ++{0x20BD, 0x01}, ++{0x20BE, 0xF6}, ++{0x20BF, 0x00}, ++{0x20C0, 0x90}, ++{0x20C1, 0x01}, ++{0x20C2, 0x67}, ++{0x20C3, 0x01}, ++{0x20C4, 0xFF}, ++{0x20C5, 0x03}, ++{0x20C6, 0xFF}, ++{0x20C7, 0x03}, ++{0x20C8, 0x33}, ++{0x20C9, 0x02}, ++{0x20CA, 0x0A}, ++{0x20CB, 0x02}, ++{0x20CC, 0x7F}, ++{0x20CD, 0x00}, ++{0x20CE, 0xD2}, ++{0x20CF, 0x00}, ++{0x20D0, 0x81}, ++{0x20D1, 0x00}, ++{0x20D2, 0x87}, ++{0x20D3, 0x00}, ++{0x20D4, 0x09}, ++{0x20D5, 0x00}, ++{0x20D8, 0x7F}, ++{0x20D9, 0x00}, ++{0x20DA, 0x62}, ++{0x20DB, 0x01}, ++{0x20DC, 0x7F}, ++{0x20DD, 0x00}, ++{0x20DE, 0x62}, ++{0x20DF, 0x01}, ++{0x20E0, 0x65}, ++{0x20E1, 0x00}, ++{0x20E2, 0x75}, ++{0x20E3, 0x00}, ++{0x20E4, 0xE0}, ++{0x20E5, 0x00}, ++{0x20E6, 0xF0}, ++{0x20E7, 0x00}, ++{0x20E8, 0x4C}, ++{0x20E9, 0x01}, ++{0x20EA, 0x5C}, ++{0x20EB, 0x01}, ++{0x20EC, 0xD1}, ++{0x20ED, 0x01}, ++{0x20EE, 0xE1}, ++{0x20EF, 0x01}, ++{0x20F0, 0x93}, ++{0x20F1, 0x02}, ++{0x20F2, 0xA3}, ++{0x20F3, 0x02}, ++{0x20F4, 0x0D}, ++{0x20F5, 0x03}, ++{0x20F6, 0x1D}, ++{0x20F7, 0x03}, ++{0x20F8, 0x57}, ++{0x20F9, 0x00}, ++{0x20FA, 0x7B}, ++{0x20FB, 0x00}, ++{0x20FC, 0xD2}, ++{0x20FD, 0x00}, ++{0x20FE, 0xF6}, ++{0x20FF, 0x00}, ++{0x2100, 0x3E}, ++{0x2101, 0x01}, ++{0x2102, 0x60}, ++{0x2103, 0x01}, ++{0x2104, 0xC3}, ++{0x2105, 0x01}, ++{0x2106, 0xE5}, ++{0x2107, 0x01}, ++{0x2108, 0x85}, ++{0x2109, 0x02}, ++{0x210A, 0xA9}, ++{0x210B, 0x02}, ++{0x210C, 0xFF}, ++{0x210D, 0x02}, ++{0x210E, 0x21}, ++{0x210F, 0x03}, ++{0x2110, 0xFF}, ++{0x2111, 0x03}, ++{0x2112, 0x00}, ++{0x2113, 0x00}, ++{0x2114, 0xFF}, ++{0x2115, 0x03}, ++{0x2116, 0xFF}, ++{0x2117, 0x03}, ++{0x2118, 0xFF}, ++{0x2119, 0x03}, ++{0x211A, 0xFF}, ++{0x211B, 0x03}, ++{0x211C, 0xFF}, ++{0x211D, 0x03}, ++{0x211E, 0xFF}, ++{0x211F, 0x03}, ++{0x2120, 0xFF}, ++{0x2121, 0x03}, ++{0x2122, 0xFF}, ++{0x2123, 0x03}, ++{0x2124, 0xFF}, ++{0x2125, 0x03}, ++{0x2126, 0xFF}, ++{0x2127, 0x03}, ++{0x2128, 0x7D}, ++{0x2129, 0x90}, ++{0x212A, 0xD5}, ++{0x212B, 0x07}, ++{0x212C, 0x64}, ++{0x212D, 0x01}, ++{0x2130, 0x5F}, ++{0x2131, 0x7D}, ++{0x2132, 0x05}, ++{0x2134, 0x78}, ++{0x2135, 0x00}, ++{0x2136, 0x76}, ++{0x2137, 0x00}, ++{0x2138, 0xF3}, ++{0x2139, 0x00}, ++{0x213A, 0xF1}, ++{0x213B, 0x00}, ++{0x213C, 0xA6}, ++{0x213D, 0x02}, ++{0x213E, 0xA4}, ++{0x213F, 0x02}, ++{0x2140, 0x7D}, ++{0x2141, 0x00}, ++{0x2142, 0x8D}, ++{0x2143, 0x00}, ++{0x2144, 0xA1}, ++{0x2145, 0x01}, ++{0x2146, 0xB1}, ++{0x2147, 0x01}, ++{0x2148, 0xAB}, ++{0x2149, 0x02}, ++{0x214A, 0xBB}, ++{0x214B, 0x02}, ++{0x214C, 0x17}, ++{0x214D, 0x5C}, ++{0x214E, 0x00}, ++{0x2150, 0x00}, ++{0x2151, 0x00}, ++{0x2152, 0xF8}, ++{0x2153, 0x00}, ++{0x2154, 0xBE}, ++{0x2155, 0x00}, ++{0x2156, 0x7D}, ++{0x2157, 0x00}, ++{0x2158, 0x25}, ++{0x2159, 0x00}, ++{0x215A, 0x7D}, ++{0x215B, 0x00}, ++{0x215C, 0x62}, ++{0x215D, 0x01}, ++{0x215E, 0xFF}, ++{0x215F, 0x03}, ++{0x2160, 0x26}, ++{0x2161, 0x00}, ++{0x2162, 0x7D}, ++{0x2163, 0x00}, ++{0x2164, 0x63}, ++{0x2165, 0x01}, ++{0x2166, 0xFF}, ++{0x2167, 0x03}, ++{0x2168, 0xCB}, ++{0x2169, 0x02}, ++{0x216A, 0xCF}, ++{0x216B, 0x02}, ++{0x216C, 0xFF}, ++{0x216D, 0x03}, ++{0x216E, 0xFF}, ++{0x216F, 0x03}, ++{0x2170, 0xFF}, ++{0x2171, 0x03}, ++{0x2172, 0xFF}, ++{0x2173, 0x03}, ++{0x2174, 0xFF}, ++{0x2175, 0x03}, ++{0x2176, 0xFF}, ++{0x2177, 0x03}, ++{0x2178, 0x7E}, ++{0x2179, 0x00}, ++{0x217A, 0xBD}, ++{0x217B, 0x00}, ++{0x217C, 0xEC}, ++{0x217D, 0x01}, ++{0x217E, 0x7B}, ++{0x217F, 0x02}, ++{0x2180, 0xD1}, ++{0x2181, 0x02}, ++{0x2182, 0x25}, ++{0x2183, 0x03}, ++{0x2184, 0x7F}, ++{0x2185, 0x00}, ++{0x2186, 0xBD}, ++{0x2187, 0x00}, ++{0x2188, 0xED}, ++{0x2189, 0x01}, ++{0x218A, 0x7B}, ++{0x218B, 0x02}, ++{0x218C, 0xD2}, ++{0x218D, 0x02}, ++{0x218E, 0x25}, ++{0x218F, 0x03}, ++{0x2190, 0xFF}, ++{0x2191, 0x03}, ++{0x2192, 0xFF}, ++{0x2193, 0x03}, ++{0x2194, 0xE9}, ++{0x2195, 0x01}, ++{0x2196, 0x21}, ++{0x2197, 0x03}, ++{0x2198, 0x17}, ++{0x2199, 0xFC}, ++{0x219A, 0x7F}, ++{0x219B, 0x01}, ++{0x219C, 0xFF}, ++{0x219D, 0x03}, ++{0x21A0, 0x1B}, ++{0x21A1, 0x1B}, ++{0x21A2, 0x1B}, ++{0x21A3, 0x1B}, ++{0x21A4, 0x2E}, ++{0x21A5, 0x80}, ++{0x21A6, 0x00}, ++{0x21A8, 0x04}, ++{0x21A9, 0x98}, ++{0x21AA, 0x60}, ++{0x21AB, 0x03}, ++{0x21AC, 0x7F}, ++{0x21AD, 0x80}, ++{0x21AE, 0x09}, ++{0x21B0, 0x1C}, ++{0x21B1, 0x00}, ++{0x21B2, 0xA0}, ++{0x21B3, 0x00}, ++{0x21B4, 0x0C}, ++{0x21B5, 0x00}, ++{0x21B6, 0x2D}, ++{0x21B7, 0x00}, ++{0x21B8, 0x20}, ++{0x21B9, 0x00}, ++{0x21BA, 0x02}, ++{0x21BB, 0x00}, ++{0x21BC, 0xCC}, ++{0x21BD, 0x00}, ++{0x21BE, 0x4A}, ++{0x21BF, 0x00}, ++{0x21C0, 0xD0}, ++{0x21C1, 0x00}, ++{0x21C2, 0x44}, ++{0x21C3, 0x00}, ++{0x21C4, 0x00}, ++{0x21C5, 0xE0}, ++{0x21C6, 0x00}, ++{0x21C8, 0x11}, ++{0x21C9, 0x00}, ++{0x21CA, 0x02}, ++{0x21CC, 0x08}, ++{0x21CD, 0xC0}, ++{0x21CE, 0x0C}, ++{0x21D0, 0x44}, ++{0x21D1, 0x00}, ++{0x21D2, 0x02}, ++{0x21D4, 0x02}, ++{0x21D5, 0x20}, ++{0x21D6, 0x2C}, ++{0x21D8, 0xFE}, ++{0x21D9, 0x9D}, ++{0x21DA, 0xDF}, ++{0x21DB, 0x03}, ++{0x21DC, 0x62}, ++{0x21DD, 0x01}, ++{0x21DE, 0x7F}, ++{0x21DF, 0x00}, ++{0x21E0, 0xB7}, ++{0x21E1, 0x01}, ++{0x21E2, 0xB5}, ++{0x21E3, 0x01}, ++{0x21E4, 0xC1}, ++{0x21E5, 0x02}, ++{0x21E6, 0xBF}, ++{0x21E7, 0x02}, ++{0x21E8, 0xB3}, ++{0x21E9, 0x0D}, ++{0x21EA, 0x00}, ++{0x21EB, 0x04}, ++#if 1 ++{0x21EC, 0x90}, ++{0x21ED, 0x07}, ++{0x21EE, 0x58}, ++{0x21EF, 0x04}, ++#else ++{0x21EC, 0x80}, ++{0x21ED, 0x07}, ++{0x21EE, 0x38}, ++{0x21EF, 0x04}, ++#endif ++{0x21F0, 0x54}, ++{0x21F1, 0x04}, ++{0x21F4, 0x02}, ++{0x21F5, 0x00}, ++{0x21F6, 0x00}, ++{0x21F8, 0x3C}, ++{0x21F9, 0x00}, ++{0x21FC, 0x28}, ++{0x21FD, 0x00}, ++{0x21FE, 0x3C}, ++{0x21FF, 0x00}, ++{0x2200, 0x00}, ++{0x2204, 0x4C}, ++{0x2205, 0x04}, ++{0x2206, 0x65}, ++{0x2207, 0x04}, ++{0x2208, 0x0A}, ++{0x2209, 0x00}, ++{0x220C, 0x47}, ++{0x220D, 0x00}, ++{0x220E, 0x1F}, ++{0x220F, 0x00}, ++{0x2210, 0x17}, ++{0x2211, 0x00}, ++{0x2212, 0x0F}, ++{0x2213, 0x00}, ++{0x2214, 0x17}, ++{0x2215, 0x00}, ++{0x2216, 0x47}, ++{0x2217, 0x00}, ++{0x2218, 0x0F}, ++{0x2219, 0x00}, ++{0x221A, 0x0F}, ++{0x221B, 0x00}, ++{0x221C, 0x03}, ++{0x2220, 0x20}, ++{0x2221, 0x20}, ++{0x2222, 0x22}, ++{0x2223, 0x02}, ++{0x2224, 0xA7}, ++{0x2225, 0xAA}, ++{0x2226, 0x80}, ++{0x2227, 0x08}, ++{0x2228, 0x01}, ++{0x22B2, 0x92}, ++{0x22B4, 0x20}, ++{0x22B5, 0x00}, ++{0x22B6, 0x20}, ++{0x22B7, 0x00}, ++{0x22B8, 0x20}, ++{0x22B9, 0x00}, ++{0x22BA, 0x20}, ++{0x22BB, 0x00}, ++{0x22BC, 0x20}, ++{0x22BD, 0x00}, ++{0x22BE, 0x20}, ++{0x22BF, 0x00}, ++{0x22C0, 0x20}, ++{0x22C1, 0x00}, ++{0x22C2, 0x20}, ++{0x22C3, 0x00}, ++{0x22C4, 0x20}, ++{0x22C5, 0x00}, ++{0x22C6, 0x20}, ++{0x22C7, 0x00}, ++{0x22C8, 0x20}, ++{0x22C9, 0x00}, ++{0x22CA, 0x20}, ++{0x22CB, 0x00}, ++{0x22CC, 0x20}, ++{0x22CD, 0x00}, ++{0x22CE, 0x20}, ++{0x22CF, 0x00}, ++{0x22DA, 0x00}, ++{0x2308, 0x01}, ++{0x2311, 0x09}, ++{0x2318, 0x40}, ++{0x2319, 0xCD}, ++{0x231A, 0x54}, ++{0x2324, 0x20}, ++{0x2325, 0x00}, ++{0x2328, 0x00}, ++{0x2354, 0x0C}, ++{0x23C0, 0x5D}, ++{0x244C, 0x00}, ++{0x244D, 0x02}, ++{0x244E, 0x54}, ++{0x244F, 0x02}, ++{0x24A0, 0x00}, ++{0x24DA, 0x6F}, ++{0x24DB, 0x00}, ++{0x24DC, 0x62}, ++{0x24DD, 0x01}, ++{0x24EA, 0x32}, ++{0x24EB, 0x00}, ++{0x24EC, 0xDC}, ++{0x24ED, 0x00}, ++{0x24FA, 0x32}, ++{0x24FB, 0x00}, ++{0x24FC, 0xDD}, ++{0x24FD, 0x00}, ++{0x254A, 0x15}, ++{0x254B, 0x01}, ++{0x255A, 0x15}, ++{0x255B, 0x01}, ++{0x2560, 0x01}, ++{0x2561, 0x00}, ++{0x2562, 0x2A}, ++{0x2563, 0x00}, ++{0x2564, 0xF8}, ++{0x2565, 0x00}, ++{0x2566, 0x15}, ++{0x2567, 0x01}, ++{0x2568, 0x0C}, ++{0x2569, 0x02}, ++{0x256A, 0x31}, ++{0x256B, 0x02}, ++{0x2578, 0x90}, ++{0x2579, 0x01}, ++{0x257A, 0x92}, ++{0x257B, 0x01}, ++{0x257C, 0xB8}, ++{0x257D, 0x02}, ++{0x257E, 0xBA}, ++{0x257F, 0x02}, ++{0x2584, 0x90}, ++{0x2585, 0x01}, ++{0x2586, 0x92}, ++{0x2587, 0x01}, ++{0x2588, 0xB8}, ++{0x2589, 0x02}, ++{0x258A, 0xBA}, ++{0x258B, 0x02}, ++{0x26B8, 0x10}, ++{0x26B9, 0x00}, ++{0x26BA, 0x33}, ++{0x26BB, 0x00}, ++{0x26BC, 0x89}, ++{0x26BD, 0x00}, ++{0x26BE, 0xB0}, ++{0x26BF, 0x00}, ++{0x26C4, 0x4E}, ++{0x26C5, 0x00}, ++{0x26C8, 0xC9}, ++{0x26C9, 0x00}, ++{0x26CC, 0x35}, ++{0x26CD, 0x01}, ++{0x26D0, 0xBA}, ++{0x26D1, 0x01}, ++{0x26D4, 0x7C}, ++{0x26D5, 0x02}, ++{0x26D8, 0xF6}, ++{0x26D9, 0x02}, ++{0x26DE, 0x51}, ++{0x26DF, 0x00}, ++{0x26E0, 0x7F}, ++{0x26E1, 0x00}, ++{0x26E2, 0xCC}, ++{0x26E3, 0x00}, ++{0x26E4, 0xF8}, ++{0x26E5, 0x00}, ++{0x26E6, 0x38}, ++{0x26E7, 0x01}, ++{0x26E8, 0x65}, ++{0x26E9, 0x01}, ++{0x26EA, 0xBD}, ++{0x26EB, 0x01}, ++{0x26EE, 0x7F}, ++{0x26EF, 0x02}, ++{0x26F0, 0xAB}, ++{0x26F1, 0x02}, ++{0x26F2, 0xF9}, ++{0x26F3, 0x02}, ++{0x2722, 0x59}, ++{0x2723, 0x02}, ++{0x2938, 0x55}, ++{0x2939, 0x00}, ++{0x293A, 0x17}, ++{0x293B, 0x00}, ++{0x293C, 0xD0}, ++{0x293D, 0x00}, ++{0x293E, 0x91}, ++{0x293F, 0x00}, ++{0x2940, 0x3C}, ++{0x2941, 0x01}, ++{0x2942, 0x0C}, ++{0x2943, 0x01}, ++{0x2944, 0xC1}, ++{0x2945, 0x01}, ++{0x2946, 0x76}, ++{0x2947, 0x01}, ++{0x2948, 0x83}, ++{0x2949, 0x02}, ++{0x294A, 0xFB}, ++{0x294B, 0x01}, ++{0x294C, 0xFD}, ++{0x294D, 0x02}, ++{0x294E, 0xBF}, ++{0x294F, 0x02}, ++{0x2A06, 0xFF}, ++{0x2A07, 0x03}, ++{0x2A20, 0x00}, ++{0x2A21, 0x00}, ++{0x2A22, 0x7D}, ++{0x2A23, 0x00}, ++{0x2B11, 0x19}, ++{0x2B13, 0x15}, ++{0x2B14, 0x14}, ++{0x2B15, 0x13}, ++{0x2B16, 0x12}, ++{0x2B17, 0x11}, ++{0x2B18, 0x10}, ++{0x2B19, 0x0F}, ++{0x2B1A, 0x0E}, ++{0x2B1B, 0x0D}, ++{0x2B1C, 0x0C}, ++{0x2B1D, 0x0B}, ++{0x2B1E, 0x0A}, ++{0x2B1F, 0x09}, ++{0x2B20, 0x08}, ++{0x2B21, 0x07}, ++{0x2B22, 0x06}, ++{0x2B23, 0x05}, ++{0x2B24, 0x04}, ++{0x2B25, 0x03}, ++{0x2B26, 0x03}, ++{0x2B38, 0x01}, ++{0x2B45, 0xE3}, ++{0x2B50, 0x01}, ++{0x2B51, 0x00}, ++//{0x2B62, ,3}, ++{0x2B6D, 0x47}, ++{0x2B70, 0x02}, ++{0x2B71, 0x02}, ++{0x2B72, 0x02}, ++{0x2B7F, 0x7F}, ++{0x2B80, 0x94}, ++{0x2B81, 0x06}, ++{0x2B87, 0x1B}, ++{0x2B88, 0x1B}, ++{0x2B89, 0x17}, ++{0x2B8A, 0x12}, ++{0x2B8B, 0x12}, ++{0x2B8D, 0x2B}, ++{0x2B8E, 0x2B}, ++{0x2B8F, 0x2B}, ++{0x2B90, 0x7F}, ++{0x2B91, 0x1F}, ++{0x2B94, 0x7F}, ++{0x2B95, 0x27}, ++{0x2B98, 0x7F}, ++{0x2B99, 0x57}, ++{0x2BA8, 0xBC}, ++{0x2BA9, 0x62}, ++{0x2BC1, 0x70}, ++{0x2BC5, 0x80}, ++{0x2BD5, 0x30}, ++{0x2BD6, 0xF0}, ++{0x2BD8, 0xDB}, ++{0x2BD9, 0xF6}, ++{0x2BDA, 0x63}, ++{0x2BDB, 0x0C}, ++{0x2BDC, 0x5C}, ++{0x2C98, 0xE1}, ++{0x2C99, 0x2E}, ++{0x2C9B, 0x86}, ++{0x2CA9, 0x80}, ++{0x2CAA, 0x01}, ++{0x2D39, 0x0E}, ++{0x2D54, 0x00}, ++{0x2D5B, 0x58}, ++{0x3000, 0x00}, ++{0x3001, 0x40}, ++{0x3002, 0x23}, ++{0x3003, 0xA1}, ++{0x3004, 0x00}, ++{0x3005, 0x20}, ++{0x3006, 0x94}, ++{0x3007, 0x00}, ++{0x3008, 0x06}, ++{0x3009, 0xB4}, ++{0x300A, 0x1F}, ++{0x300B, 0x28}, ++{0x300C, 0x00}, ++{0x300D, 0x18}, ++{0x300E, 0x90}, ++{0x300F, 0x97}, ++{0x3010, 0x00}, ++{0x3011, 0x40}, ++{0x3012, 0x21}, ++{0x3013, 0x21}, ++{0x3014, 0x00}, ++{0x3015, 0x20}, ++{0x3016, 0x94}, ++{0x3017, 0x00}, ++{0x3018, 0x00}, ++{0x3019, 0x09}, ++{0x301A, 0x46}, ++{0x301B, 0x28}, ++//{0x3053, ,3}, ++{0x3070, 0xC1}, ++{0x3071, 0x81}, ++{0x3072, 0x29}, ++{0x3073, 0x81}, ++//{0x3370, ,3}, ++//{0x3374, ,3}, ++//{0x3375, ,3}, ++//{0x3376, ,3}, ++//{0x3377, ,3}, ++#if 1 ++{0x3410, 0x90}, ++{0x3411, 0x07}, ++{0x3418, 0x48}, ++{0x3419, 0x04}, ++#else ++{0x3410, 0x80}, ++{0x3411, 0x07}, ++{0x3418, 0x38}, ++{0x3419, 0x04}, ++#endif ++//{0x34C0, ,3}, ++//{0x34C1, ,3}, ++//{0x34C2, ,3}, ++//{0x34C3, ,3}, ++//{0x34C4, ,3}, ++//{0x34C5, ,3}, ++//{0x34C6, ,3}, ++//{0x34C7, ,3}, ++//{0x34C8, ,3}, ++//{0x34C9, ,3}, ++//{0x34CA, ,3}, ++//{0x34CB, ,3}, ++//{0x34CC, ,3}, ++//{0x34CD, ,3}, ++//{0x34CE, ,3}, ++//{0x34CF, ,3}, ++{0x3584, 0x00}, ++{0x3586, 0x00}, ++{0x3587, 0x01}, ++{0x3588, 0xE6}, ++{0x3589, 0x00}, ++{0x3590, 0x00}, ++{0x3591, 0x00}, ++{0x3594, 0x40}, ++{0x3598, 0x03}, ++{0x3599, 0x00}, ++{0x359A, 0x80}, ++{0x359B, 0x00}, ++{0x359C, 0x00}, ++{0x359D, 0x01}, ++{0x359E, 0x00}, ++{0x359F, 0x02}, ++{0x35A0, 0x00}, ++{0x35A1, 0x04}, ++{0x35A2, 0x20}, ++{0x35A3, 0x00}, ++{0x35A4, 0x40}, ++{0x35A5, 0x00}, ++{0x35A6, 0x80}, ++{0x35A7, 0x00}, ++{0x35A8, 0x00}, ++{0x35A9, 0x01}, ++{0x35AA, 0x3A}, ++{0x35AB, 0x00}, ++{0x35AC, 0x80}, ++{0x35AD, 0x00}, ++{0x35AE, 0x00}, ++{0x35AF, 0x01}, ++{0x35B0, 0x00}, ++{0x35B1, 0x02}, ++{0x35B2, 0x00}, ++{0x35B3, 0x04}, ++{0x35B4, 0x02}, ++{0x35B5, 0x00}, ++{0x35B6, 0x04}, ++{0x35B7, 0x00}, ++{0x35B8, 0x08}, ++{0x35B9, 0x00}, ++{0x35BA, 0x10}, ++{0x35BB, 0x00}, ++{0x35BC, 0x03}, ++{0x35BD, 0x00}, ++{0x35C8, 0x00}, ++{0x35C9, 0x01}, ++{0x35CA, 0x00}, ++{0x35CB, 0x04}, ++{0x35CC, 0x00}, ++{0x35CD, 0x10}, ++{0x35CE, 0x00}, ++{0x35CF, 0x40}, ++{0x35D0, 0x00}, ++{0x35D1, 0x0C}, ++{0x35D2, 0x00}, ++{0x35D3, 0x0C}, ++{0x35D4, 0x00}, ++{0x35D5, 0x0C}, ++{0x35D6, 0x00}, ++{0x35D7, 0x0C}, ++{0x35D8, 0x00}, ++{0x35D9, 0x00}, ++{0x35DA, 0x08}, ++{0x35DB, 0x00}, ++{0x35DC, 0xD8}, ++{0x35DD, 0x0E}, ++{0x35F0, 0x00}, ++{0x35F1, 0x10}, ++{0x35F2, 0x00}, ++{0x35F3, 0x10}, ++{0x35F4, 0x00}, ++{0x35F5, 0x10}, ++{0x35F6, 0x00}, ++{0x35F7, 0x03}, ++{0x35F8, 0x00}, ++{0x35F9, 0x01}, ++{0x35FA, 0x38}, ++{0x35FB, 0x00}, ++{0x35FC, 0xB3}, ++{0x35FD, 0x01}, ++{0x35FE, 0x00}, ++{0x35FF, 0x00}, ++{0x3600, 0x04}, ++{0x3601, 0x06}, ++{0x3604, 0x03}, ++{0x3605, 0x00}, ++{0x3608, 0x03}, ++{0x3609, 0x00}, ++{0x360C, 0x00}, ++{0x360D, 0x00}, ++{0x3610, 0x10}, ++{0x3611, 0x01}, ++{0x3612, 0x00}, ++{0x3613, 0x00}, ++{0x3614, 0x00}, ++{0x3615, 0x00}, ++{0x361C, 0x00}, ++{0x361D, 0x01}, ++{0x361E, 0x00}, ++{0x361F, 0x01}, ++{0x3620, 0x01}, ++{0x3621, 0x00}, ++{0x3622, 0xB0}, ++{0x3623, 0x04}, ++{0x3624, 0xDC}, ++{0x3625, 0x05}, ++{0x3626, 0x00}, ++{0x3627, 0x01}, ++{0x3628, 0xFF}, ++{0x3629, 0x0F}, ++{0x362A, 0x00}, ++{0x362B, 0x10}, ++{0x362C, 0x00}, ++{0x362D, 0x01}, ++//{0x3630, ,3}, ++//{0x3631, ,3}, ++//{0x3632, ,3}, ++//{0x3633, ,3}, ++//{0x3634, ,3}, ++//{0x3635, ,3}, ++//{0x3636, ,3}, ++//{0x3637, ,3}, ++//{0x3638, ,3}, ++//{0x3639, ,3}, ++//{0x363A, ,3}, ++//{0x363B, ,3}, ++//{0x363C, ,3}, ++//{0x363D, ,3}, ++//{0x363E, ,3}, ++//{0x363F, ,3}, ++{0x36C4, 0x99}, ++{0x36C5, 0x09}, ++{0x36C6, 0x18}, ++{0x36C7, 0x07}, ++{0x36C8, 0x65}, ++{0x36C9, 0x0E}, ++{0x36CC, 0x99}, ++{0x36CD, 0x01}, ++{0x36CE, 0x47}, ++{0x36CF, 0x00}, ++{0x36D0, 0x04}, ++{0x36D1, 0x00}, ++{0x36D4, 0x65}, ++{0x36D5, 0x0E}, ++{0x36D6, 0xA4}, ++{0x36D7, 0x0A}, ++{0x36D8, 0x65}, ++{0x36D9, 0x0E}, ++{0x36DC, 0x65}, ++{0x36DD, 0x0E}, ++{0x36DE, 0xA4}, ++{0x36DF, 0x0A}, ++{0x36E0, 0x65}, ++{0x36E1, 0x0E}, ++{0x36E4, 0x65}, ++{0x36E5, 0x0E}, ++{0x36E6, 0xA4}, ++{0x36E7, 0x0A}, ++{0x36E8, 0x65}, ++{0x36E9, 0x0E}, ++{0x36EE, 0x00}, ++{0x36EF, 0x00}, ++{0x36F0, 0x00}, ++{0x36F1, 0x80}, ++{0x36F8, 0x00}, ++{0x3702, 0x03}, ++{0x3703, 0x04}, ++{0x3704, 0x08}, ++{0x370E, 0x0E}, ++{0x3718, 0x62}, ++{0x3719, 0x4A}, ++{0x371A, 0x38}, ++{0x371B, 0x20}, ++{0x371C, 0x64}, ++{0x371D, 0x42}, ++{0x371E, 0x32}, ++{0x371F, 0x1B}, ++{0x3720, 0x98}, ++{0x3721, 0xA0}, ++{0x3722, 0xA8}, ++{0x3723, 0xB0}, ++{0x3748, 0xA5}, ++{0x3749, 0x9B}, ++{0x374A, 0x91}, ++{0x374B, 0x7D}, ++{0x37C0, 0x00}, ++{0x37C1, 0x00}, ++{0x37C2, 0x00}, ++{0x37C4, 0x00}, ++{0x37C5, 0x00}, ++{0x37C6, 0x00}, ++{0x37C8, 0x00}, ++{0x37C9, 0x00}, ++{0x37CA, 0x00}, ++{0x37CC, 0x00}, ++{0x37CD, 0x00}, ++{0x37CE, 0x00}, ++{0x37D0, 0x00}, ++{0x37D1, 0x00}, ++{0x37D2, 0x00}, ++{0x37D4, 0x00}, ++{0x37D5, 0x00}, ++{0x37D6, 0x00}, ++{0x37D8, 0x00}, ++{0x37D9, 0x00}, ++{0x37DA, 0x00}, ++{0x37DC, 0x00}, ++{0x37DD, 0x00}, ++{0x37DE, 0x00}, ++{0x37E0, 0x00}, ++{0x37E1, 0x00}, ++{0x37E2, 0x00}, ++{0x37E4, 0x00}, ++{0x37E5, 0x00}, ++{0x37E6, 0x00}, ++{0x37E8, 0x00}, ++{0x37E9, 0x00}, ++{0x37EA, 0x00}, ++{0x37EC, 0x00}, ++{0x37ED, 0x00}, ++{0x37EE, 0x00}, ++{0x37F0, 0x00}, ++{0x37F4, 0x00}, ++{0x37F5, 0x1E}, ++{0x37F6, 0x34}, ++{0x37F7, 0x00}, ++{0x37F8, 0xFF}, ++{0x37F9, 0xFF}, ++{0x37FA, 0x03}, ++{0x37FC, 0x00}, ++{0x37FD, 0x00}, ++{0x37FE, 0x04}, ++{0x3800, 0xFF}, ++{0x3801, 0xFF}, ++{0x3802, 0x03}, ++{0x3804, 0x00}, ++{0x3805, 0x00}, ++{0x3806, 0x04}, ++{0x3808, 0x00}, ++{0x3809, 0x00}, ++{0x380A, 0x00}, ++{0x380C, 0x00}, ++{0x380D, 0x00}, ++{0x380E, 0x00}, ++{0x3810, 0x00}, ++{0x3811, 0x00}, ++{0x3812, 0x00}, ++{0x3814, 0x00}, ++{0x3815, 0x00}, ++{0x3816, 0x00}, ++{0x3818, 0x00}, ++{0x3819, 0x00}, ++{0x381A, 0x00}, ++{0x381C, 0x00}, ++{0x381D, 0x00}, ++{0x381E, 0x00}, ++{0x3820, 0x00}, ++{0x3821, 0x00}, ++{0x3822, 0x00}, ++{0x3824, 0x00}, ++{0x3825, 0x00}, ++{0x3826, 0x00}, ++{0x3828, 0x00}, ++{0x3829, 0x00}, ++{0x382A, 0x00}, ++{0x382C, 0x00}, ++{0x382D, 0x00}, ++{0x382E, 0x00}, ++{0x3830, 0x00}, ++{0x3831, 0x00}, ++{0x3832, 0x00}, ++{0x3834, 0x00}, ++{0x3835, 0x00}, ++{0x3836, 0x00}, ++{0x3838, 0x22}, ++{0x3839, 0x00}, ++{0x383A, 0x25}, ++{0x383B, 0x00}, ++{0x383C, 0x1A}, ++{0x383D, 0x00}, ++{0x383E, 0x26}, ++{0x383F, 0x00}, ++{0x3840, 0x07}, ++{0x3841, 0x00}, ++{0x3842, 0x06}, ++{0x3843, 0x00}, ++{0x3844, 0x03}, ++{0x3845, 0x00}, ++{0x3846, 0x02}, ++{0x3847, 0x00}, ++{0x3848, 0xFB}, ++{0x3849, 0xFF}, ++{0x384A, 0xFF}, ++{0x384B, 0xFF}, ++{0x384C, 0xF3}, ++{0x384D, 0xFF}, ++{0x384E, 0xF2}, ++{0x384F, 0xFF}, ++{0x3850, 0xFF}, ++{0x3851, 0x0F}, ++{0x3852, 0x00}, ++{0x3853, 0x10}, ++{0x3854, 0xFF}, ++{0x3855, 0x0F}, ++{0x3856, 0x00}, ++{0x3857, 0x10}, ++{0x3858, 0xFF}, ++{0x3859, 0x0F}, ++{0x385A, 0x00}, ++{0x385B, 0x10}, ++{0x385C, 0x02}, ++{0x385D, 0x00}, ++{0x385E, 0x06}, ++{0x385F, 0x00}, ++{0x3860, 0x06}, ++{0x3861, 0x00}, ++{0x3862, 0x08}, ++{0x3863, 0x00}, ++{0x3864, 0x02}, ++{0x3865, 0x00}, ++{0x38A0, 0x01}, ++{0x38A1, 0x01}, ++{0x38A2, 0x00}, ++{0x38A3, 0x01}, ++{0x38A4, 0x07}, ++{0x38A5, 0x00}, ++{0x38A6, 0x04}, ++{0x38A7, 0x05}, ++{0x38A8, 0x00}, ++{0x38A9, 0x00}, ++{0x38AC, 0x00}, ++{0x38AD, 0x00}, ++{0x38AE, 0x01}, ++{0x38B0, 0x02}, ++{0x38B2, 0x22}, ++{0x38B3, 0x00}, ++{0x38B4, 0x17}, ++{0x38B5, 0x00}, ++{0x38B6, 0x11}, ++{0x38B7, 0x00}, ++{0x38B8, 0x0E}, ++{0x38B9, 0x00}, ++{0x38BA, 0x2A}, ++{0x38BB, 0x00}, ++{0x38BC, 0x1C}, ++{0x38BD, 0x00}, ++{0x38BE, 0x14}, ++{0x38BF, 0x00}, ++{0x38C0, 0x10}, ++{0x38C1, 0x00}, ++{0x38C2, 0x31}, ++{0x38C3, 0x00}, ++{0x38C4, 0x21}, ++{0x38C5, 0x00}, ++{0x38C6, 0x18}, ++{0x38C7, 0x00}, ++{0x38C8, 0x12}, ++{0x38C9, 0x00}, ++{0x38CA, 0x3C}, ++{0x38CB, 0x00}, ++{0x38CC, 0x29}, ++{0x38CD, 0x00}, ++{0x38CE, 0x1D}, ++{0x38CF, 0x00}, ++{0x38D0, 0x15}, ++{0x38D1, 0x00}, ++{0x38D2, 0x4E}, ++{0x38D3, 0x00}, ++{0x38D4, 0x35}, ++{0x38D5, 0x00}, ++{0x38D6, 0x26}, ++{0x38D7, 0x00}, ++{0x38D8, 0x1A}, ++{0x38D9, 0x00}, ++{0x38DA, 0x69}, ++{0x38DB, 0x00}, ++{0x38DC, 0x48}, ++{0x38DD, 0x00}, ++{0x38DE, 0x33}, ++{0x38DF, 0x00}, ++{0x38E0, 0x22}, ++{0x38E1, 0x00}, ++{0x38E2, 0x93}, ++{0x38E3, 0x00}, ++{0x38E4, 0x64}, ++{0x38E5, 0x00}, ++{0x38E6, 0x48}, ++{0x38E7, 0x00}, ++{0x38E8, 0x30}, ++{0x38E9, 0x00}, ++{0x38EA, 0xD3}, ++{0x38EB, 0x00}, ++{0x38EC, 0x90}, ++{0x38ED, 0x00}, ++{0x38EE, 0x69}, ++{0x38EF, 0x00}, ++{0x38F0, 0x49}, ++{0x38F1, 0x00}, ++{0x38F2, 0x39}, ++{0x38F3, 0x01}, ++{0x38F4, 0xD5}, ++{0x38F5, 0x00}, ++{0x38F6, 0x9F}, ++{0x38F7, 0x00}, ++{0x38F8, 0x75}, ++{0x38F9, 0x00}, ++{0x38FA, 0x00}, ++{0x38FB, 0x01}, ++{0x38FC, 0x00}, ++{0x38FD, 0x01}, ++{0x38FE, 0x00}, ++{0x38FF, 0x01}, ++{0x3900, 0x00}, ++{0x3901, 0x01}, ++{0x3902, 0x60}, ++{0x3903, 0x00}, ++{0x3904, 0x25}, ++{0x3905, 0x00}, ++{0x3906, 0x18}, ++{0x3907, 0x00}, ++{0x3908, 0x10}, ++{0x3909, 0x00}, ++{0x390A, 0xFF}, ++{0x390B, 0x00}, ++{0x390C, 0xD5}, ++{0x390D, 0x00}, ++{0x390E, 0xAA}, ++{0x390F, 0x00}, ++{0x3910, 0x85}, ++{0x3911, 0x00}, ++{0x3912, 0xFF}, ++{0x3913, 0x00}, ++{0x3914, 0xD5}, ++{0x3915, 0x00}, ++{0x3916, 0xAA}, ++{0x3917, 0x00}, ++{0x3918, 0x85}, ++{0x3919, 0x00}, ++{0x391A, 0xFF}, ++{0x391B, 0x00}, ++{0x391C, 0xD5}, ++{0x391D, 0x00}, ++{0x391E, 0xAA}, ++{0x391F, 0x00}, ++{0x3920, 0x85}, ++{0x3921, 0x00}, ++{0x3922, 0x40}, ++{0x3923, 0x00}, ++{0x3924, 0x40}, ++{0x3925, 0x00}, ++{0x3926, 0x40}, ++{0x3927, 0x00}, ++{0x3928, 0x40}, ++{0x3929, 0x00}, ++{0x392A, 0x80}, ++{0x392B, 0x00}, ++{0x392C, 0x80}, ++{0x392D, 0x00}, ++{0x392E, 0x80}, ++{0x392F, 0x00}, ++{0x3930, 0x80}, ++{0x3931, 0x00}, ++{0x3932, 0x4C}, ++{0x3933, 0x4C}, ++{0x3934, 0x4C}, ++{0x3940, 0x01}, ++{0x3941, 0x01}, ++{0x3942, 0x00}, ++{0x3943, 0x01}, ++{0x3944, 0x07}, ++{0x3945, 0x00}, ++{0x3946, 0x04}, ++{0x3947, 0x05}, ++{0x3948, 0x00}, ++{0x3949, 0x00}, ++{0x394C, 0x00}, ++{0x394D, 0x00}, ++{0x394E, 0x01}, ++{0x3950, 0x03}, ++{0x3952, 0x14}, ++{0x3953, 0x00}, ++{0x3954, 0x0F}, ++{0x3955, 0x00}, ++{0x3956, 0x0E}, ++{0x3957, 0x00}, ++{0x3958, 0x0E}, ++{0x3959, 0x00}, ++{0x395A, 0x19}, ++{0x395B, 0x00}, ++{0x395C, 0x11}, ++{0x395D, 0x00}, ++{0x395E, 0x0F}, ++{0x395F, 0x00}, ++{0x3960, 0x0E}, ++{0x3961, 0x00}, ++{0x3962, 0x1C}, ++{0x3963, 0x00}, ++{0x3964, 0x13}, ++{0x3965, 0x00}, ++{0x3966, 0x0F}, ++{0x3967, 0x00}, ++{0x3968, 0x0E}, ++{0x3969, 0x00}, ++{0x396A, 0x23}, ++{0x396B, 0x00}, ++{0x396C, 0x15}, ++{0x396D, 0x00}, ++{0x396E, 0x11}, ++{0x396F, 0x00}, ++{0x3970, 0x0E}, ++{0x3971, 0x00}, ++{0x3972, 0x2E}, ++{0x3973, 0x00}, ++{0x3974, 0x1A}, ++{0x3975, 0x00}, ++{0x3976, 0x14}, ++{0x3977, 0x00}, ++{0x3978, 0x0F}, ++{0x3979, 0x00}, ++{0x397A, 0x3E}, ++{0x397B, 0x00}, ++{0x397C, 0x23}, ++{0x397D, 0x00}, ++{0x397E, 0x1A}, ++{0x397F, 0x00}, ++{0x3980, 0x12}, ++{0x3981, 0x00}, ++{0x3982, 0x56}, ++{0x3983, 0x00}, ++{0x3984, 0x31}, ++{0x3985, 0x00}, ++{0x3986, 0x25}, ++{0x3987, 0x00}, ++{0x3988, 0x1A}, ++{0x3989, 0x00}, ++{0x398A, 0x7B}, ++{0x398B, 0x00}, ++{0x398C, 0x49}, ++{0x398D, 0x00}, ++{0x398E, 0x39}, ++{0x398F, 0x00}, ++{0x3990, 0x2C}, ++{0x3991, 0x00}, ++{0x3992, 0xB4}, ++{0x3993, 0x00}, ++{0x3994, 0x75}, ++{0x3995, 0x00}, ++{0x3996, 0x61}, ++{0x3997, 0x00}, ++{0x3998, 0x53}, ++{0x3999, 0x00}, ++{0x399A, 0x00}, ++{0x399B, 0x01}, ++{0x399C, 0x00}, ++{0x399D, 0x01}, ++{0x399E, 0x00}, ++{0x399F, 0x01}, ++{0x39A0, 0x00}, ++{0x39A1, 0x01}, ++{0x39A2, 0x60}, ++{0x39A3, 0x00}, ++{0x39A4, 0x20}, ++{0x39A5, 0x00}, ++{0x39A6, 0x15}, ++{0x39A7, 0x00}, ++{0x39A8, 0x10}, ++{0x39A9, 0x00}, ++{0x39AA, 0xFF}, ++{0x39AB, 0x00}, ++{0x39AC, 0xD5}, ++{0x39AD, 0x00}, ++{0x39AE, 0xAA}, ++{0x39AF, 0x00}, ++{0x39B0, 0x85}, ++{0x39B1, 0x00}, ++{0x39B2, 0xFF}, ++{0x39B3, 0x00}, ++{0x39B4, 0xD5}, ++{0x39B5, 0x00}, ++{0x39B6, 0xAA}, ++{0x39B7, 0x00}, ++{0x39B8, 0x85}, ++{0x39B9, 0x00}, ++{0x39BA, 0xFF}, ++{0x39BB, 0x00}, ++{0x39BC, 0xD5}, ++{0x39BD, 0x00}, ++{0x39BE, 0xAA}, ++{0x39BF, 0x00}, ++{0x39C0, 0x85}, ++{0x39C1, 0x00}, ++{0x39C2, 0x40}, ++{0x39C3, 0x00}, ++{0x39C4, 0x40}, ++{0x39C5, 0x00}, ++{0x39C6, 0x40}, ++{0x39C7, 0x00}, ++{0x39C8, 0x40}, ++{0x39C9, 0x00}, ++{0x39CA, 0x80}, ++{0x39CB, 0x00}, ++{0x39CC, 0x80}, ++{0x39CD, 0x00}, ++{0x39CE, 0x80}, ++{0x39CF, 0x00}, ++{0x39D0, 0x80}, ++{0x39D1, 0x00}, ++{0x39D2, 0x4C}, ++{0x39D3, 0x4C}, ++{0x39D4, 0x4C}, ++{0x39E0, 0x01}, ++{0x39E1, 0x00}, ++{0x39E4, 0x40}, ++{0x39E5, 0x01}, ++{0x39E6, 0x01}, ++{0x39E8, 0x00}, ++{0x39E9, 0x01}, ++{0x39EA, 0x00}, ++{0x39EB, 0x00}, ++{0x39EC, 0x01}, ++{0x39ED, 0x00}, ++{0x39EE, 0x01}, ++{0x39F0, 0x03}, ++{0x39F1, 0x04}, ++{0x39F2, 0x0E}, ++{0x39F4, 0x1C}, ++{0x39F5, 0x00}, ++{0x39F6, 0x13}, ++{0x39F7, 0x00}, ++{0x39F8, 0x0D}, ++{0x39F9, 0x00}, ++{0x39FA, 0x07}, ++{0x39FB, 0x00}, ++{0x39FC, 0x38}, ++{0x39FD, 0x00}, ++{0x39FE, 0x1C}, ++{0x39FF, 0x00}, ++{0x3A00, 0x11}, ++{0x3A01, 0x00}, ++{0x3A02, 0x08}, ++{0x3A03, 0x00}, ++{0x3A04, 0x4A}, ++{0x3A05, 0x00}, ++{0x3A06, 0x23}, ++{0x3A07, 0x00}, ++{0x3A08, 0x15}, ++{0x3A09, 0x00}, ++{0x3A0A, 0x09}, ++{0x3A0B, 0x00}, ++{0x3A0C, 0x65}, ++{0x3A0D, 0x00}, ++{0x3A0E, 0x2D}, ++{0x3A0F, 0x00}, ++{0x3A10, 0x1A}, ++{0x3A11, 0x00}, ++{0x3A12, 0x0B}, ++{0x3A13, 0x00}, ++{0x3A14, 0x8D}, ++{0x3A15, 0x00}, ++{0x3A16, 0x3D}, ++{0x3A17, 0x00}, ++{0x3A18, 0x23}, ++{0x3A19, 0x00}, ++{0x3A1A, 0x0E}, ++{0x3A1B, 0x00}, ++{0x3A1C, 0xC5}, ++{0x3A1D, 0x00}, ++{0x3A1E, 0x55}, ++{0x3A1F, 0x00}, ++{0x3A20, 0x30}, ++{0x3A21, 0x00}, ++{0x3A22, 0x13}, ++{0x3A23, 0x00}, ++{0x3A24, 0x16}, ++{0x3A25, 0x01}, ++{0x3A26, 0x76}, ++{0x3A27, 0x00}, ++{0x3A28, 0x42}, ++{0x3A29, 0x00}, ++{0x3A2A, 0x1A}, ++{0x3A2B, 0x00}, ++{0x3A2C, 0x88}, ++{0x3A2D, 0x01}, ++{0x3A2E, 0xA7}, ++{0x3A2F, 0x00}, ++{0x3A30, 0x5D}, ++{0x3A31, 0x00}, ++{0x3A32, 0x24}, ++{0x3A33, 0x00}, ++{0x3A34, 0x2A}, ++{0x3A35, 0x02}, ++{0x3A36, 0xEB}, ++{0x3A37, 0x00}, ++{0x3A38, 0x83}, ++{0x3A39, 0x00}, ++{0x3A3A, 0x32}, ++{0x3A3B, 0x00}, ++{0x3A3C, 0x00}, ++{0x3A3D, 0x01}, ++{0x3A3E, 0x00}, ++{0x3A3F, 0x01}, ++{0x3A40, 0x00}, ++{0x3A41, 0x01}, ++{0x3A42, 0x00}, ++{0x3A43, 0x01}, ++{0x3A44, 0x70}, ++{0x3A45, 0x00}, ++{0x3A46, 0x25}, ++{0x3A47, 0x00}, ++{0x3A48, 0x18}, ++{0x3A49, 0x00}, ++{0x3A4A, 0x10}, ++{0x3A4B, 0x00}, ++{0x3A4C, 0xFF}, ++{0x3A4D, 0x00}, ++{0x3A4E, 0xD5}, ++{0x3A4F, 0x00}, ++{0x3A50, 0xAA}, ++{0x3A51, 0x00}, ++{0x3A52, 0x85}, ++{0x3A53, 0x00}, ++{0x3A54, 0xFF}, ++{0x3A55, 0x00}, ++{0x3A56, 0xD5}, ++{0x3A57, 0x00}, ++{0x3A58, 0xAA}, ++{0x3A59, 0x00}, ++{0x3A5A, 0x85}, ++{0x3A5B, 0x00}, ++{0x3A5C, 0xFF}, ++{0x3A5D, 0x00}, ++{0x3A5E, 0xD5}, ++{0x3A5F, 0x00}, ++{0x3A60, 0xAA}, ++{0x3A61, 0x00}, ++{0x3A62, 0x85}, ++{0x3A63, 0x00}, ++{0x3A64, 0x1C}, ++{0x3A65, 0x00}, ++{0x3A66, 0x13}, ++{0x3A67, 0x00}, ++{0x3A68, 0x0D}, ++{0x3A69, 0x00}, ++{0x3A6A, 0x07}, ++{0x3A6B, 0x00}, ++{0x3A6C, 0x0D}, ++{0x3A6D, 0x00}, ++{0x3A6E, 0x0B}, ++{0x3A6F, 0x00}, ++{0x3A70, 0x06}, ++{0x3A71, 0x00}, ++{0x3A72, 0x05}, ++{0x3A73, 0x00}, ++{0x3A74, 0x19}, ++{0x3A75, 0x00}, ++{0x3A76, 0x14}, ++{0x3A77, 0x00}, ++{0x3A78, 0x0F}, ++{0x3A79, 0x00}, ++{0x3A7A, 0x0A}, ++{0x3A7B, 0x00}, ++{0x3A7C, 0x80}, ++{0x3A7D, 0x00}, ++{0x3A7E, 0x80}, ++{0x3A7F, 0x00}, ++{0x3A80, 0x80}, ++{0x3A81, 0x00}, ++{0x3A82, 0x80}, ++{0x3A83, 0x00}, ++{0x3A84, 0x08}, ++{0x3A85, 0x00}, ++{0x3A86, 0x05}, ++{0x3A87, 0x00}, ++{0x3A88, 0x04}, ++{0x3A89, 0x00}, ++{0x3A8A, 0x03}, ++{0x3A8B, 0x00}, ++{0x3A8C, 0xCD}, ++{0x3A8D, 0x00}, ++{0x3A8E, 0xAA}, ++{0x3A8F, 0x00}, ++{0x3A90, 0x8C}, ++{0x3A91, 0x00}, ++{0x3A92, 0x64}, ++{0x3A93, 0x00}, ++{0x3A94, 0xCD}, ++{0x3A95, 0x00}, ++{0x3A96, 0xAA}, ++{0x3A97, 0x00}, ++{0x3A98, 0x8C}, ++{0x3A99, 0x00}, ++{0x3A9A, 0x64}, ++{0x3A9B, 0x00}, ++{0x3A9C, 0x08}, ++{0x3A9D, 0x10}, ++{0x3A9E, 0x4C}, ++{0x3A9F, 0x4C}, ++{0x3AA0, 0x4C}, ++{0x3AA1, 0x04}, ++{0x3AA2, 0x05}, ++{0x3AC0, 0x01}, ++{0x3AC4, 0x81}, ++{0x3AC5, 0x00}, ++{0x3AC6, 0x00}, ++{0x3AC7, 0x00}, ++{0x3AC8, 0x00}, ++{0x3AC9, 0x00}, ++{0x3ACA, 0x00}, ++{0x3ACB, 0x00}, ++{0x3ACC, 0x02}, ++{0x3ACD, 0x00}, ++{0x3ACE, 0x81}, ++{0x3ACF, 0x00}, ++{0x3AD0, 0x00}, ++{0x3AD1, 0x00}, ++{0x3AD2, 0xFD}, ++{0x3AD3, 0x03}, ++{0x3AD4, 0x02}, ++{0x3AD5, 0x00}, ++{0x3AD6, 0x00}, ++{0x3AD7, 0x00}, ++{0x3AD8, 0x81}, ++{0x3AD9, 0x00}, ++{0x3ADA, 0xFD}, ++{0x3ADB, 0x03}, ++{0x3ADC, 0xFF}, ++{0x3ADD, 0x03}, ++{0x3ADE, 0x01}, ++{0x3ADF, 0x00}, ++{0x3AE0, 0x01}, ++{0x3AE1, 0x00}, ++{0x3AE2, 0x7E}, ++{0x3AE3, 0x00}, ++{0x3AF4, 0x00}, ++{0x3AF6, 0x40}, ++{0x3AF7, 0x1E}, ++{0x3AF8, 0x01}, ++{0x3AFA, 0x63}, ++{0x3AFB, 0x09}, ++{0x3AFC, 0x11}, ++{0x3AFD, 0x09}, ++{0x3AFE, 0x00}, ++{0x3AFF, 0x00}, ++{0x3B00, 0x00}, ++{0x3B01, 0x00}, ++{0x3B02, 0x84}, ++{0x3B03, 0x06}, ++{0x3B04, 0x30}, ++{0x3B05, 0x06}, ++{0x3B06, 0x00}, ++{0x3B07, 0x00}, ++{0x3B08, 0x00}, ++{0x3B09, 0x00}, ++{0x3B0A, 0x00}, ++{0x3B0B, 0x00}, ++{0x3B0C, 0x00}, ++{0x3B0D, 0x00}, ++{0x3B0E, 0x00}, ++{0x3B0F, 0x00}, ++{0x3B10, 0x00}, ++{0x3B11, 0x00}, ++{0x3B12, 0x00}, ++{0x3B13, 0x00}, ++{0x3B14, 0x00}, ++{0x3B15, 0x00}, ++{0x3B16, 0x00}, ++{0x3B17, 0x00}, ++{0x3B18, 0x00}, ++{0x3B19, 0x00}, ++{0x3B1A, 0x00}, ++{0x3B1B, 0x00}, ++{0x3B1C, 0x00}, ++{0x3B1D, 0x00}, ++{0x3B1E, 0x00}, ++{0x3B1F, 0x00}, ++{0x3B20, 0x00}, ++{0x3B21, 0x00}, ++{0x3B22, 0x00}, ++{0x3B23, 0x00}, ++{0x3B24, 0x00}, ++{0x3B25, 0x00}, ++{0x3B26, 0x00}, ++{0x3B27, 0x00}, ++{0x3B28, 0x00}, ++{0x3B29, 0x00}, ++{0x3B2A, 0x00}, ++{0x3B2C, 0x00}, ++{0x3B2E, 0x00}, ++{0x3B30, 0x00}, ++{0x3B32, 0x0C}, ++{0x4000, 0xD1}, ++{0x4001, 0xC0}, ++{0x4002, 0xC0}, ++{0x4003, 0xB8}, ++{0x4004, 0xC0}, ++{0x4005, 0xB8}, ++{0x4006, 0xB9}, ++{0x4007, 0xB7}, ++{0x4008, 0xB0}, ++{0x4009, 0xAB}, ++{0x400A, 0xAC}, ++{0x400B, 0xAB}, ++{0x400C, 0xA8}, ++{0x400D, 0xA6}, ++{0x400E, 0xA6}, ++{0x400F, 0xA5}, ++{0x4010, 0xA2}, ++{0x4011, 0xA0}, ++{0x4012, 0xA0}, ++{0x4013, 0x9F}, ++{0x4014, 0xA4}, ++{0x4015, 0xA2}, ++{0x4016, 0xA2}, ++{0x4017, 0x9C}, ++{0x4018, 0xA8}, ++{0x4019, 0xA6}, ++{0x401A, 0xA8}, ++{0x401B, 0xAA}, ++{0x401C, 0xB0}, ++{0x401D, 0xAE}, ++{0x401E, 0xAE}, ++{0x401F, 0xAE}, ++{0x4020, 0xBA}, ++{0x4021, 0xAE}, ++{0x4022, 0xAF}, ++{0x4023, 0xAE}, ++{0x4024, 0xC6}, ++{0x4025, 0xBD}, ++{0x4026, 0xBD}, ++{0x4027, 0xBA}, ++{0x4028, 0xB0}, ++{0x4029, 0xA9}, ++{0x402A, 0xAA}, ++{0x402B, 0xA8}, ++{0x402C, 0x9F}, ++{0x402D, 0x9C}, ++{0x402E, 0x9C}, ++{0x402F, 0x9B}, ++{0x4030, 0x93}, ++{0x4031, 0x91}, ++{0x4032, 0x92}, ++{0x4033, 0x91}, ++{0x4034, 0x8D}, ++{0x4035, 0x8C}, ++{0x4036, 0x8C}, ++{0x4037, 0x8C}, ++{0x4038, 0x8F}, ++{0x4039, 0x8E}, ++{0x403A, 0x8E}, ++{0x403B, 0x8E}, ++{0x403C, 0x98}, ++{0x403D, 0x96}, ++{0x403E, 0x96}, ++{0x403F, 0x95}, ++{0x4040, 0xA4}, ++{0x4041, 0xA0}, ++{0x4042, 0xA0}, ++{0x4043, 0x9E}, ++{0x4044, 0xB3}, ++{0x4045, 0xAE}, ++{0x4046, 0xAF}, ++{0x4047, 0xAB}, ++{0x4048, 0xC2}, ++{0x4049, 0xB7}, ++{0x404A, 0xB8}, ++{0x404B, 0xB5}, ++{0x404C, 0xAB}, ++{0x404D, 0xA4}, ++{0x404E, 0xA5}, ++{0x404F, 0xA3}, ++{0x4050, 0x99}, ++{0x4051, 0x96}, ++{0x4052, 0x96}, ++{0x4053, 0x96}, ++{0x4054, 0x8B}, ++{0x4055, 0x8A}, ++{0x4056, 0x8A}, ++{0x4057, 0x8A}, ++{0x4058, 0x82}, ++{0x4059, 0x81}, ++{0x405A, 0x81}, ++{0x405B, 0x81}, ++{0x405C, 0x85}, ++{0x405D, 0x86}, ++{0x405E, 0x85}, ++{0x405F, 0x85}, ++{0x4060, 0x90}, ++{0x4061, 0x90}, ++{0x4062, 0x8F}, ++{0x4063, 0x8F}, ++{0x4064, 0x9D}, ++{0x4065, 0x9B}, ++{0x4066, 0x9B}, ++{0x4067, 0x9A}, ++{0x4068, 0xAF}, ++{0x4069, 0xAA}, ++{0x406A, 0xAC}, ++{0x406B, 0xAA}, ++{0x406C, 0xC2}, ++{0x406D, 0xB7}, ++{0x406E, 0xB8}, ++{0x406F, 0xB5}, ++{0x4070, 0xAB}, ++{0x4071, 0xA4}, ++{0x4072, 0xA4}, ++{0x4073, 0xA3}, ++{0x4074, 0x99}, ++{0x4075, 0x96}, ++{0x4076, 0x96}, ++{0x4077, 0x96}, ++{0x4078, 0x8B}, ++{0x4079, 0x8A}, ++{0x407A, 0x8A}, ++{0x407B, 0x8A}, ++{0x407C, 0x82}, ++{0x407D, 0x82}, ++{0x407E, 0x82}, ++{0x407F, 0x82}, ++{0x4080, 0x85}, ++{0x4081, 0x86}, ++{0x4082, 0x86}, ++{0x4083, 0x86}, ++{0x4084, 0x90}, ++{0x4085, 0x90}, ++{0x4086, 0x8F}, ++{0x4087, 0x8F}, ++{0x4088, 0x9D}, ++{0x4089, 0x9B}, ++{0x408A, 0x9B}, ++{0x408B, 0x99}, ++{0x408C, 0xAE}, ++{0x408D, 0xAA}, ++{0x408E, 0xAA}, ++{0x408F, 0xA7}, ++{0x4090, 0xC7}, ++{0x4091, 0xBA}, ++{0x4092, 0xBC}, ++{0x4093, 0xB9}, ++{0x4094, 0xB1}, ++{0x4095, 0xA8}, ++{0x4096, 0xA8}, ++{0x4097, 0xA7}, ++{0x4098, 0x9F}, ++{0x4099, 0x9B}, ++{0x409A, 0x9B}, ++{0x409B, 0x9B}, ++{0x409C, 0x93}, ++{0x409D, 0x91}, ++{0x409E, 0x91}, ++{0x409F, 0x91}, ++{0x40A0, 0x8D}, ++{0x40A1, 0x8C}, ++{0x40A2, 0x8C}, ++{0x40A3, 0x8C}, ++{0x40A4, 0x8E}, ++{0x40A5, 0x8E}, ++{0x40A6, 0x8D}, ++{0x40A7, 0x8D}, ++{0x40A8, 0x96}, ++{0x40A9, 0x95}, ++{0x40AA, 0x95}, ++{0x40AB, 0x94}, ++{0x40AC, 0xA2}, ++{0x40AD, 0x9F}, ++{0x40AE, 0x9F}, ++{0x40AF, 0x9D}, ++{0x40B0, 0xB1}, ++{0x40B1, 0xAC}, ++{0x40B2, 0xAB}, ++{0x40B3, 0xAA}, ++{0x40B4, 0xD3}, ++{0x40B5, 0xBC}, ++{0x40B6, 0xBD}, ++{0x40B7, 0xBC}, ++{0x40B8, 0xC1}, ++{0x40B9, 0xB7}, ++{0x40BA, 0xB7}, ++{0x40BB, 0xB5}, ++{0x40BC, 0xB0}, ++{0x40BD, 0xAA}, ++{0x40BE, 0xAA}, ++{0x40BF, 0xAA}, ++{0x40C0, 0xA8}, ++{0x40C1, 0xA4}, ++{0x40C2, 0xA4}, ++{0x40C3, 0xA4}, ++{0x40C4, 0xA2}, ++{0x40C5, 0x9F}, ++{0x40C6, 0x9F}, ++{0x40C7, 0x9F}, ++{0x40C8, 0xA3}, ++{0x40C9, 0xA0}, ++{0x40CA, 0xA0}, ++{0x40CB, 0xA0}, ++{0x40CC, 0xA6}, ++{0x40CD, 0xA3}, ++{0x40CE, 0xA3}, ++{0x40CF, 0xA2}, ++{0x40D0, 0xAF}, ++{0x40D1, 0xAB}, ++{0x40D2, 0xAA}, ++{0x40D3, 0xA8}, ++{0x40D4, 0xBA}, ++{0x40D5, 0xAE}, ++{0x40D6, 0xAE}, ++{0x40D7, 0xAB}, ++{0x4100, 0xBD}, ++{0x4101, 0xBA}, ++{0x4102, 0xBD}, ++{0x4103, 0xB7}, ++{0x4104, 0xB7}, ++{0x4105, 0xB7}, ++{0x4106, 0xB8}, ++{0x4107, 0xB5}, ++{0x4108, 0xAB}, ++{0x4109, 0xAA}, ++{0x410A, 0xAC}, ++{0x410B, 0xAB}, ++{0x410C, 0xA4}, ++{0x410D, 0xA5}, ++{0x410E, 0xA5}, ++{0x410F, 0xA4}, ++{0x4110, 0x9F}, ++{0x4111, 0xA0}, ++{0x4112, 0xA0}, ++{0x4113, 0x9F}, ++{0x4114, 0xA0}, ++{0x4115, 0xA0}, ++{0x4116, 0xA0}, ++{0x4117, 0x9F}, ++{0x4118, 0xA1}, ++{0x4119, 0xA1}, ++{0x411A, 0xA1}, ++{0x411B, 0xA0}, ++{0x411C, 0xA7}, ++{0x411D, 0xA6}, ++{0x411E, 0xA6}, ++{0x411F, 0xA6}, ++{0x4120, 0xA7}, ++{0x4121, 0xA6}, ++{0x4122, 0xA6}, ++{0x4123, 0xA3}, ++{0x4124, 0xB9}, ++{0x4125, 0xB9}, ++{0x4126, 0xBA}, ++{0x4127, 0xB8}, ++{0x4128, 0xA6}, ++{0x4129, 0xA7}, ++{0x412A, 0xA7}, ++{0x412B, 0xA6}, ++{0x412C, 0x9B}, ++{0x412D, 0x9B}, ++{0x412E, 0x9B}, ++{0x412F, 0x9B}, ++{0x4130, 0x91}, ++{0x4131, 0x92}, ++{0x4132, 0x92}, ++{0x4133, 0x91}, ++{0x4134, 0x8C}, ++{0x4135, 0x8C}, ++{0x4136, 0x8C}, ++{0x4137, 0x8C}, ++{0x4138, 0x8D}, ++{0x4139, 0x8D}, ++{0x413A, 0x8D}, ++{0x413B, 0x8D}, ++{0x413C, 0x93}, ++{0x413D, 0x93}, ++{0x413E, 0x93}, ++{0x413F, 0x92}, ++{0x4140, 0x9A}, ++{0x4141, 0x9A}, ++{0x4142, 0x9A}, ++{0x4143, 0x99}, ++{0x4144, 0xA7}, ++{0x4145, 0xA5}, ++{0x4146, 0xA6}, ++{0x4147, 0xA6}, ++{0x4148, 0xB8}, ++{0x4149, 0xB4}, ++{0x414A, 0xB4}, ++{0x414B, 0xB3}, ++{0x414C, 0xA3}, ++{0x414D, 0xA2}, ++{0x414E, 0xA3}, ++{0x414F, 0xA2}, ++{0x4150, 0x96}, ++{0x4151, 0x96}, ++{0x4152, 0x96}, ++{0x4153, 0x96}, ++{0x4154, 0x8A}, ++{0x4155, 0x8A}, ++{0x4156, 0x8A}, ++{0x4157, 0x8A}, ++{0x4158, 0x82}, ++{0x4159, 0x82}, ++{0x415A, 0x82}, ++{0x415B, 0x82}, ++{0x415C, 0x84}, ++{0x415D, 0x85}, ++{0x415E, 0x84}, ++{0x415F, 0x84}, ++{0x4160, 0x8D}, ++{0x4161, 0x8D}, ++{0x4162, 0x8D}, ++{0x4163, 0x8D}, ++{0x4164, 0x96}, ++{0x4165, 0x96}, ++{0x4166, 0x96}, ++{0x4167, 0x95}, ++{0x4168, 0xA5}, ++{0x4169, 0xA2}, ++{0x416A, 0xA3}, ++{0x416B, 0xA2}, ++{0x416C, 0xB7}, ++{0x416D, 0xB3}, ++{0x416E, 0xB5}, ++{0x416F, 0xB4}, ++{0x4170, 0xA4}, ++{0x4171, 0xA2}, ++{0x4172, 0xA3}, ++{0x4173, 0xA2}, ++{0x4174, 0x97}, ++{0x4175, 0x96}, ++{0x4176, 0x96}, ++{0x4177, 0x96}, ++{0x4178, 0x8B}, ++{0x4179, 0x8A}, ++{0x417A, 0x8A}, ++{0x417B, 0x8A}, ++{0x417C, 0x81}, ++{0x417D, 0x81}, ++{0x417E, 0x81}, ++{0x417F, 0x81}, ++{0x4180, 0x84}, ++{0x4181, 0x84}, ++{0x4182, 0x84}, ++{0x4183, 0x84}, ++{0x4184, 0x8C}, ++{0x4185, 0x8D}, ++{0x4186, 0x8D}, ++{0x4187, 0x8D}, ++{0x4188, 0x95}, ++{0x4189, 0x96}, ++{0x418A, 0x96}, ++{0x418B, 0x95}, ++{0x418C, 0xA1}, ++{0x418D, 0xA1}, ++{0x418E, 0xA1}, ++{0x418F, 0xA0}, ++{0x4190, 0xBC}, ++{0x4191, 0xB8}, ++{0x4192, 0xB8}, ++{0x4193, 0xB9}, ++{0x4194, 0xA8}, ++{0x4195, 0xA5}, ++{0x4196, 0xA6}, ++{0x4197, 0xA5}, ++{0x4198, 0x9C}, ++{0x4199, 0x9A}, ++{0x419A, 0x9A}, ++{0x419B, 0x9A}, ++{0x419C, 0x91}, ++{0x419D, 0x91}, ++{0x419E, 0x91}, ++{0x419F, 0x91}, ++{0x41A0, 0x8B}, ++{0x41A1, 0x8B}, ++{0x41A2, 0x8B}, ++{0x41A3, 0x8B}, ++{0x41A4, 0x8C}, ++{0x41A5, 0x8C}, ++{0x41A6, 0x8C}, ++{0x41A7, 0x8C}, ++{0x41A8, 0x91}, ++{0x41A9, 0x92}, ++{0x41AA, 0x91}, ++{0x41AB, 0x91}, ++{0x41AC, 0x98}, ++{0x41AD, 0x99}, ++{0x41AE, 0x99}, ++{0x41AF, 0x98}, ++{0x41B0, 0xA3}, ++{0x41B1, 0xA3}, ++{0x41B2, 0xA3}, ++{0x41B3, 0xA2}, ++{0x41B4, 0xC1}, ++{0x41B5, 0xB8}, ++{0x41B6, 0xB9}, ++{0x41B7, 0xBA}, ++{0x41B8, 0xB8}, ++{0x41B9, 0xB4}, ++{0x41BA, 0xB4}, ++{0x41BB, 0xB4}, ++{0x41BC, 0xAA}, ++{0x41BD, 0xA7}, ++{0x41BE, 0xA7}, ++{0x41BF, 0xA8}, ++{0x41C0, 0xA4}, ++{0x41C1, 0xA2}, ++{0x41C2, 0xA2}, ++{0x41C3, 0xA3}, ++{0x41C4, 0x9E}, ++{0x41C5, 0x9D}, ++{0x41C6, 0x9D}, ++{0x41C7, 0x9D}, ++{0x41C8, 0x9E}, ++{0x41C9, 0x9D}, ++{0x41CA, 0x9D}, ++{0x41CB, 0x9D}, ++{0x41CC, 0x9E}, ++{0x41CD, 0x9E}, ++{0x41CE, 0x9E}, ++{0x41CF, 0x9E}, ++{0x41D0, 0xA3}, ++{0x41D1, 0xA3}, ++{0x41D2, 0xA2}, ++{0x41D3, 0xA1}, ++{0x41D4, 0xA7}, ++{0x41D5, 0xA7}, ++{0x41D6, 0xA7}, ++{0x41D7, 0xA3}, ++{0x4200, 0xCE}, ++{0x4201, 0xC0}, ++{0x4202, 0xC1}, ++{0x4203, 0xB9}, ++{0x4204, 0xC3}, ++{0x4205, 0xB9}, ++{0x4206, 0xBC}, ++{0x4207, 0xBD}, ++{0x4208, 0xB3}, ++{0x4209, 0xAE}, ++{0x420A, 0xAF}, ++{0x420B, 0xAE}, ++{0x420C, 0xAA}, ++{0x420D, 0xA8}, ++{0x420E, 0xA8}, ++{0x420F, 0xA6}, ++{0x4210, 0xA4}, ++{0x4211, 0xA2}, ++{0x4212, 0xA2}, ++{0x4213, 0xA0}, ++{0x4214, 0xA4}, ++{0x4215, 0xA3}, ++{0x4216, 0xA2}, ++{0x4217, 0xA0}, ++{0x4218, 0xA7}, ++{0x4219, 0xA5}, ++{0x421A, 0xA3}, ++{0x421B, 0xA1}, ++{0x421C, 0xB0}, ++{0x421D, 0xA8}, ++{0x421E, 0xA8}, ++{0x421F, 0xA6}, ++{0x4220, 0xB4}, ++{0x4221, 0xAA}, ++{0x4222, 0xA5}, ++{0x4223, 0xA3}, ++{0x4224, 0xC7}, ++{0x4225, 0xBC}, ++{0x4226, 0xBE}, ++{0x4227, 0xBC}, ++{0x4228, 0xB0}, ++{0x4229, 0xA9}, ++{0x422A, 0xA9}, ++{0x422B, 0xA8}, ++{0x422C, 0xA0}, ++{0x422D, 0x9D}, ++{0x422E, 0x9D}, ++{0x422F, 0x9C}, ++{0x4230, 0x94}, ++{0x4231, 0x93}, ++{0x4232, 0x93}, ++{0x4233, 0x92}, ++{0x4234, 0x8E}, ++{0x4235, 0x8D}, ++{0x4236, 0x8D}, ++{0x4237, 0x8C}, ++{0x4238, 0x8F}, ++{0x4239, 0x8E}, ++{0x423A, 0x8E}, ++{0x423B, 0x8D}, ++{0x423C, 0x96}, ++{0x423D, 0x94}, ++{0x423E, 0x94}, ++{0x423F, 0x92}, ++{0x4240, 0xA1}, ++{0x4241, 0x9C}, ++{0x4242, 0x9C}, ++{0x4243, 0x99}, ++{0x4244, 0xB0}, ++{0x4245, 0xA8}, ++{0x4246, 0xAB}, ++{0x4247, 0xA7}, ++{0x4248, 0xC3}, ++{0x4249, 0xB7}, ++{0x424A, 0xB7}, ++{0x424B, 0xBC}, ++{0x424C, 0xAB}, ++{0x424D, 0xA4}, ++{0x424E, 0xA5}, ++{0x424F, 0xA5}, ++{0x4250, 0x9A}, ++{0x4251, 0x97}, ++{0x4252, 0x97}, ++{0x4253, 0x98}, ++{0x4254, 0x8C}, ++{0x4255, 0x8B}, ++{0x4256, 0x8B}, ++{0x4257, 0x8B}, ++{0x4258, 0x82}, ++{0x4259, 0x82}, ++{0x425A, 0x82}, ++{0x425B, 0x82}, ++{0x425C, 0x85}, ++{0x425D, 0x85}, ++{0x425E, 0x85}, ++{0x425F, 0x84}, ++{0x4260, 0x8F}, ++{0x4261, 0x8E}, ++{0x4262, 0x8E}, ++{0x4263, 0x8D}, ++{0x4264, 0x9B}, ++{0x4265, 0x98}, ++{0x4266, 0x98}, ++{0x4267, 0x95}, ++{0x4268, 0xAE}, ++{0x4269, 0xA5}, ++{0x426A, 0xA7}, ++{0x426B, 0xA2}, ++{0x426C, 0xC2}, ++{0x426D, 0xB7}, ++{0x426E, 0xB8}, ++{0x426F, 0xB9}, ++{0x4270, 0xAA}, ++{0x4271, 0xA4}, ++{0x4272, 0xA4}, ++{0x4273, 0xA5}, ++{0x4274, 0x99}, ++{0x4275, 0x96}, ++{0x4276, 0x97}, ++{0x4277, 0x98}, ++{0x4278, 0x8B}, ++{0x4279, 0x8A}, ++{0x427A, 0x8A}, ++{0x427B, 0x8B}, ++{0x427C, 0x81}, ++{0x427D, 0x81}, ++{0x427E, 0x81}, ++{0x427F, 0x82}, ++{0x4280, 0x84}, ++{0x4281, 0x84}, ++{0x4282, 0x84}, ++{0x4283, 0x84}, ++{0x4284, 0x8E}, ++{0x4285, 0x8E}, ++{0x4286, 0x8D}, ++{0x4287, 0x8C}, ++{0x4288, 0x9A}, ++{0x4289, 0x97}, ++{0x428A, 0x97}, ++{0x428B, 0x95}, ++{0x428C, 0xAA}, ++{0x428D, 0xA3}, ++{0x428E, 0xA3}, ++{0x428F, 0xA2}, ++{0x4290, 0xC7}, ++{0x4291, 0xBA}, ++{0x4292, 0xC0}, ++{0x4293, 0xC3}, ++{0x4294, 0xB0}, ++{0x4295, 0xA7}, ++{0x4296, 0xA7}, ++{0x4297, 0xA9}, ++{0x4298, 0x9F}, ++{0x4299, 0x9B}, ++{0x429A, 0x9B}, ++{0x429B, 0x9D}, ++{0x429C, 0x93}, ++{0x429D, 0x91}, ++{0x429E, 0x91}, ++{0x429F, 0x92}, ++{0x42A0, 0x8C}, ++{0x42A1, 0x8B}, ++{0x42A2, 0x8B}, ++{0x42A3, 0x8C}, ++{0x42A4, 0x8D}, ++{0x42A5, 0x8C}, ++{0x42A6, 0x8C}, ++{0x42A7, 0x8C}, ++{0x42A8, 0x94}, ++{0x42A9, 0x93}, ++{0x42AA, 0x92}, ++{0x42AB, 0x91}, ++{0x42AC, 0x9E}, ++{0x42AD, 0x9B}, ++{0x42AE, 0x9B}, ++{0x42AF, 0x98}, ++{0x42B0, 0xAC}, ++{0x42B1, 0xA6}, ++{0x42B2, 0xA6}, ++{0x42B3, 0xA2}, ++{0x42B4, 0xCE}, ++{0x42B5, 0xBA}, ++{0x42B6, 0xBC}, ++{0x42B7, 0xB7}, ++{0x42B8, 0xC5}, ++{0x42B9, 0xB5}, ++{0x42BA, 0xBA}, ++{0x42BB, 0xC0}, ++{0x42BC, 0xB1}, ++{0x42BD, 0xA8}, ++{0x42BE, 0xAE}, ++{0x42BF, 0xAF}, ++{0x42C0, 0xA7}, ++{0x42C1, 0xA3}, ++{0x42C2, 0xA3}, ++{0x42C3, 0xA5}, ++{0x42C4, 0xA0}, ++{0x42C5, 0x9D}, ++{0x42C6, 0x9D}, ++{0x42C7, 0x9F}, ++{0x42C8, 0xA0}, ++{0x42C9, 0x9E}, ++{0x42CA, 0x9E}, ++{0x42CB, 0x9F}, ++{0x42CC, 0xA2}, ++{0x42CD, 0xA0}, ++{0x42CE, 0xA0}, ++{0x42CF, 0xA0}, ++{0x42D0, 0xA8}, ++{0x42D1, 0xA5}, ++{0x42D2, 0xA5}, ++{0x42D3, 0xA2}, ++{0x42D4, 0xB3}, ++{0x42D5, 0xAA}, ++{0x42D6, 0xAB}, ++{0x42D7, 0xA3}, ++{0x42D8, 0x00}, ++{0x42D9, 0x00}, ++{0x4300, 0xA2}, ++{0x4301, 0xAE}, ++{0x4302, 0xAD}, ++{0x4303, 0xB5}, ++{0x4304, 0x95}, ++{0x4305, 0x9A}, ++{0x4306, 0x98}, ++{0x4307, 0x9B}, ++{0x4308, 0x8D}, ++{0x4309, 0x90}, ++{0x430A, 0x8F}, ++{0x430B, 0x91}, ++{0x430C, 0x86}, ++{0x430D, 0x88}, ++{0x430E, 0x87}, ++{0x430F, 0x89}, ++{0x4310, 0x86}, ++{0x4311, 0x87}, ++{0x4312, 0x86}, ++{0x4313, 0x88}, ++{0x4314, 0x89}, ++{0x4315, 0x88}, ++{0x4316, 0x88}, ++{0x4317, 0x8E}, ++{0x4318, 0x90}, ++{0x4319, 0x8F}, ++{0x431A, 0x8C}, ++{0x431B, 0x8C}, ++{0x431C, 0x9C}, ++{0x431D, 0x99}, ++{0x431E, 0x98}, ++{0x431F, 0x99}, ++{0x4320, 0xAB}, ++{0x4321, 0xB0}, ++{0x4322, 0xAD}, ++{0x4323, 0xAF}, ++{0x4324, 0x9B}, ++{0x4325, 0x9F}, ++{0x4326, 0x9E}, ++{0x4327, 0xA1}, ++{0x4328, 0x8E}, ++{0x4329, 0x91}, ++{0x432A, 0x90}, ++{0x432B, 0x93}, ++{0x432C, 0x86}, ++{0x432D, 0x88}, ++{0x432E, 0x87}, ++{0x432F, 0x89}, ++{0x4330, 0x82}, ++{0x4331, 0x84}, ++{0x4332, 0x83}, ++{0x4333, 0x84}, ++{0x4334, 0x82}, ++{0x4335, 0x82}, ++{0x4336, 0x82}, ++{0x4337, 0x83}, ++{0x4338, 0x85}, ++{0x4339, 0x84}, ++{0x433A, 0x84}, ++{0x433B, 0x85}, ++{0x433C, 0x8A}, ++{0x433D, 0x89}, ++{0x433E, 0x88}, ++{0x433F, 0x89}, ++{0x4340, 0x93}, ++{0x4341, 0x91}, ++{0x4342, 0x91}, ++{0x4343, 0x93}, ++{0x4344, 0xA0}, ++{0x4345, 0x9E}, ++{0x4346, 0x9D}, ++{0x4347, 0xA1}, ++{0x4348, 0x95}, ++{0x4349, 0x9B}, ++{0x434A, 0x9A}, ++{0x434B, 0x9C}, ++{0x434C, 0x8A}, ++{0x434D, 0x8D}, ++{0x434E, 0x8C}, ++{0x434F, 0x8D}, ++{0x4350, 0x83}, ++{0x4351, 0x85}, ++{0x4352, 0x84}, ++{0x4353, 0x85}, ++{0x4354, 0x80}, ++{0x4355, 0x81}, ++{0x4356, 0x81}, ++{0x4357, 0x81}, ++{0x4358, 0x80}, ++{0x4359, 0x80}, ++{0x435A, 0x80}, ++{0x435B, 0x80}, ++{0x435C, 0x82}, ++{0x435D, 0x81}, ++{0x435E, 0x81}, ++{0x435F, 0x81}, ++{0x4360, 0x85}, ++{0x4361, 0x84}, ++{0x4362, 0x84}, ++{0x4363, 0x85}, ++{0x4364, 0x8D}, ++{0x4365, 0x8B}, ++{0x4366, 0x8B}, ++{0x4367, 0x8D}, ++{0x4368, 0x98}, ++{0x4369, 0x98}, ++{0x436A, 0x95}, ++{0x436B, 0x98}, ++{0x436C, 0x95}, ++{0x436D, 0x9A}, ++{0x436E, 0x99}, ++{0x436F, 0x9A}, ++{0x4370, 0x8A}, ++{0x4371, 0x8D}, ++{0x4372, 0x8C}, ++{0x4373, 0x8C}, ++{0x4374, 0x83}, ++{0x4375, 0x85}, ++{0x4376, 0x84}, ++{0x4377, 0x84}, ++{0x4378, 0x80}, ++{0x4379, 0x80}, ++{0x437A, 0x80}, ++{0x437B, 0x80}, ++{0x437C, 0x7F}, ++{0x437D, 0x7F}, ++{0x437E, 0x7F}, ++{0x437F, 0x7F}, ++{0x4380, 0x81}, ++{0x4381, 0x80}, ++{0x4382, 0x80}, ++{0x4383, 0x81}, ++{0x4384, 0x84}, ++{0x4385, 0x83}, ++{0x4386, 0x83}, ++{0x4387, 0x84}, ++{0x4388, 0x8B}, ++{0x4389, 0x8A}, ++{0x438A, 0x8A}, ++{0x438B, 0x8C}, ++{0x438C, 0x97}, ++{0x438D, 0x96}, ++{0x438E, 0x96}, ++{0x438F, 0x99}, ++{0x4390, 0x99}, ++{0x4391, 0x9F}, ++{0x4392, 0x9E}, ++{0x4393, 0x9D}, ++{0x4394, 0x8D}, ++{0x4395, 0x90}, ++{0x4396, 0x90}, ++{0x4397, 0x8F}, ++{0x4398, 0x85}, ++{0x4399, 0x87}, ++{0x439A, 0x87}, ++{0x439B, 0x86}, ++{0x439C, 0x81}, ++{0x439D, 0x83}, ++{0x439E, 0x82}, ++{0x439F, 0x82}, ++{0x43A0, 0x80}, ++{0x43A1, 0x81}, ++{0x43A2, 0x81}, ++{0x43A3, 0x81}, ++{0x43A4, 0x82}, ++{0x43A5, 0x82}, ++{0x43A6, 0x82}, ++{0x43A7, 0x82}, ++{0x43A8, 0x86}, ++{0x43A9, 0x85}, ++{0x43AA, 0x85}, ++{0x43AB, 0x87}, ++{0x43AC, 0x8D}, ++{0x43AD, 0x8D}, ++{0x43AE, 0x8D}, ++{0x43AF, 0x90}, ++{0x43B0, 0x9A}, ++{0x43B1, 0x9A}, ++{0x43B2, 0x9B}, ++{0x43B3, 0x9D}, ++{0x43B4, 0xA0}, ++{0x43B5, 0xAD}, ++{0x43B6, 0xAC}, ++{0x43B7, 0xAA}, ++{0x43B8, 0x93}, ++{0x43B9, 0x97}, ++{0x43BA, 0x97}, ++{0x43BB, 0x96}, ++{0x43BC, 0x8B}, ++{0x43BD, 0x8E}, ++{0x43BE, 0x8E}, ++{0x43BF, 0x8C}, ++{0x43C0, 0x83}, ++{0x43C1, 0x85}, ++{0x43C2, 0x85}, ++{0x43C3, 0x84}, ++{0x43C4, 0x82}, ++{0x43C5, 0x84}, ++{0x43C6, 0x83}, ++{0x43C7, 0x83}, ++{0x43C8, 0x83}, ++{0x43C9, 0x84}, ++{0x43CA, 0x84}, ++{0x43CB, 0x85}, ++{0x43CC, 0x8A}, ++{0x43CD, 0x8A}, ++{0x43CE, 0x8A}, ++{0x43CF, 0x8C}, ++{0x43D0, 0x92}, ++{0x43D1, 0x93}, ++{0x43D2, 0x93}, ++{0x43D3, 0x96}, ++{0x43D4, 0x9F}, ++{0x43D5, 0xA6}, ++{0x43D6, 0xA5}, ++{0x43D7, 0xAA}, ++{0x4400, 0xA1}, ++{0x4401, 0xAB}, ++{0x4402, 0xA7}, ++{0x4403, 0xB0}, ++{0x4404, 0x91}, ++{0x4405, 0x96}, ++{0x4406, 0x94}, ++{0x4407, 0x99}, ++{0x4408, 0x8A}, ++{0x4409, 0x8E}, ++{0x440A, 0x8C}, ++{0x440B, 0x8F}, ++{0x440C, 0x85}, ++{0x440D, 0x86}, ++{0x440E, 0x86}, ++{0x440F, 0x88}, ++{0x4410, 0x85}, ++{0x4411, 0x86}, ++{0x4412, 0x85}, ++{0x4413, 0x87}, ++{0x4414, 0x88}, ++{0x4415, 0x87}, ++{0x4416, 0x87}, ++{0x4417, 0x89}, ++{0x4418, 0x91}, ++{0x4419, 0x8F}, ++{0x441A, 0x8F}, ++{0x441B, 0x90}, ++{0x441C, 0x9C}, ++{0x441D, 0x9B}, ++{0x441E, 0x9A}, ++{0x441F, 0x9A}, ++{0x4420, 0xB3}, ++{0x4421, 0xB1}, ++{0x4422, 0xB0}, ++{0x4423, 0xB2}, ++{0x4424, 0x96}, ++{0x4425, 0x9C}, ++{0x4426, 0x9A}, ++{0x4427, 0x9E}, ++{0x4428, 0x8B}, ++{0x4429, 0x8F}, ++{0x442A, 0x8E}, ++{0x442B, 0x91}, ++{0x442C, 0x84}, ++{0x442D, 0x87}, ++{0x442E, 0x86}, ++{0x442F, 0x88}, ++{0x4430, 0x82}, ++{0x4431, 0x83}, ++{0x4432, 0x82}, ++{0x4433, 0x84}, ++{0x4434, 0x82}, ++{0x4435, 0x82}, ++{0x4436, 0x82}, ++{0x4437, 0x83}, ++{0x4438, 0x84}, ++{0x4439, 0x84}, ++{0x443A, 0x84}, ++{0x443B, 0x84}, ++{0x443C, 0x8B}, ++{0x443D, 0x89}, ++{0x443E, 0x89}, ++{0x443F, 0x89}, ++{0x4440, 0x95}, ++{0x4441, 0x93}, ++{0x4442, 0x93}, ++{0x4443, 0x93}, ++{0x4444, 0xA2}, ++{0x4445, 0xA2}, ++{0x4446, 0xA1}, ++{0x4447, 0xA0}, ++{0x4448, 0x8F}, ++{0x4449, 0x97}, ++{0x444A, 0x97}, ++{0x444B, 0x98}, ++{0x444C, 0x87}, ++{0x444D, 0x8B}, ++{0x444E, 0x8A}, ++{0x444F, 0x8B}, ++{0x4450, 0x81}, ++{0x4451, 0x83}, ++{0x4452, 0x83}, ++{0x4453, 0x84}, ++{0x4454, 0x7F}, ++{0x4455, 0x80}, ++{0x4456, 0x80}, ++{0x4457, 0x81}, ++{0x4458, 0x80}, ++{0x4459, 0x80}, ++{0x445A, 0x80}, ++{0x445B, 0x80}, ++{0x445C, 0x82}, ++{0x445D, 0x81}, ++{0x445E, 0x81}, ++{0x445F, 0x81}, ++{0x4460, 0x87}, ++{0x4461, 0x85}, ++{0x4462, 0x85}, ++{0x4463, 0x86}, ++{0x4464, 0x90}, ++{0x4465, 0x8E}, ++{0x4466, 0x8E}, ++{0x4467, 0x8E}, ++{0x4468, 0x9B}, ++{0x4469, 0x9C}, ++{0x446A, 0x9A}, ++{0x446B, 0x9A}, ++{0x446C, 0x91}, ++{0x446D, 0x97}, ++{0x446E, 0x95}, ++{0x446F, 0x95}, ++{0x4470, 0x87}, ++{0x4471, 0x8A}, ++{0x4472, 0x8A}, ++{0x4473, 0x89}, ++{0x4474, 0x81}, ++{0x4475, 0x83}, ++{0x4476, 0x83}, ++{0x4477, 0x83}, ++{0x4478, 0x7F}, ++{0x4479, 0x80}, ++{0x447A, 0x80}, ++{0x447B, 0x80}, ++{0x447C, 0x80}, ++{0x447D, 0x80}, ++{0x447E, 0x80}, ++{0x447F, 0x7F}, ++{0x4480, 0x81}, ++{0x4481, 0x81}, ++{0x4482, 0x81}, ++{0x4483, 0x81}, ++{0x4484, 0x85}, ++{0x4485, 0x85}, ++{0x4486, 0x85}, ++{0x4487, 0x85}, ++{0x4488, 0x8E}, ++{0x4489, 0x8D}, ++{0x448A, 0x8D}, ++{0x448B, 0x8E}, ++{0x448C, 0x9D}, ++{0x448D, 0x9C}, ++{0x448E, 0x9C}, ++{0x448F, 0x9C}, ++{0x4490, 0x94}, ++{0x4491, 0x9B}, ++{0x4492, 0x9A}, ++{0x4493, 0x97}, ++{0x4494, 0x8A}, ++{0x4495, 0x8E}, ++{0x4496, 0x8E}, ++{0x4497, 0x8C}, ++{0x4498, 0x84}, ++{0x4499, 0x86}, ++{0x449A, 0x86}, ++{0x449B, 0x84}, ++{0x449C, 0x81}, ++{0x449D, 0x83}, ++{0x449E, 0x83}, ++{0x449F, 0x81}, ++{0x44A0, 0x81}, ++{0x44A1, 0x82}, ++{0x44A2, 0x82}, ++{0x44A3, 0x81}, ++{0x44A4, 0x83}, ++{0x44A5, 0x83}, ++{0x44A6, 0x83}, ++{0x44A7, 0x83}, ++{0x44A8, 0x88}, ++{0x44A9, 0x88}, ++{0x44AA, 0x88}, ++{0x44AB, 0x88}, ++{0x44AC, 0x91}, ++{0x44AD, 0x91}, ++{0x44AE, 0x91}, ++{0x44AF, 0x92}, ++{0x44B0, 0xA0}, ++{0x44B1, 0xA0}, ++{0x44B2, 0xA0}, ++{0x44B3, 0xA0}, ++{0x44B4, 0x9E}, ++{0x44B5, 0xA9}, ++{0x44B6, 0xA8}, ++{0x44B7, 0xA3}, ++{0x44B8, 0x90}, ++{0x44B9, 0x95}, ++{0x44BA, 0x95}, ++{0x44BB, 0x92}, ++{0x44BC, 0x8A}, ++{0x44BD, 0x8E}, ++{0x44BE, 0x8E}, ++{0x44BF, 0x8B}, ++{0x44C0, 0x84}, ++{0x44C1, 0x86}, ++{0x44C2, 0x86}, ++{0x44C3, 0x84}, ++{0x44C4, 0x84}, ++{0x44C5, 0x85}, ++{0x44C6, 0x85}, ++{0x44C7, 0x84}, ++{0x44C8, 0x86}, ++{0x44C9, 0x87}, ++{0x44CA, 0x87}, ++{0x44CB, 0x86}, ++{0x44CC, 0x8D}, ++{0x44CD, 0x8E}, ++{0x44CE, 0x8E}, ++{0x44CF, 0x8D}, ++{0x44D0, 0x98}, ++{0x44D1, 0x98}, ++{0x44D2, 0x99}, ++{0x44D3, 0x9A}, ++{0x44D4, 0xA9}, ++{0x44D5, 0xAA}, ++{0x44D6, 0xAA}, ++{0x44D7, 0xAD}, ++{0x4500, 0x9F}, ++{0x4501, 0xA8}, ++{0x4502, 0xA5}, ++{0x4503, 0xAF}, ++{0x4504, 0x8F}, ++{0x4505, 0x96}, ++{0x4506, 0x92}, ++{0x4507, 0x94}, ++{0x4508, 0x89}, ++{0x4509, 0x8D}, ++{0x450A, 0x8A}, ++{0x450B, 0x8E}, ++{0x450C, 0x84}, ++{0x450D, 0x85}, ++{0x450E, 0x84}, ++{0x450F, 0x87}, ++{0x4510, 0x84}, ++{0x4511, 0x85}, ++{0x4512, 0x84}, ++{0x4513, 0x86}, ++{0x4514, 0x87}, ++{0x4515, 0x86}, ++{0x4516, 0x86}, ++{0x4517, 0x88}, ++{0x4518, 0x8F}, ++{0x4519, 0x8D}, ++{0x451A, 0x8D}, ++{0x451B, 0x8F}, ++{0x451C, 0x9A}, ++{0x451D, 0x9A}, ++{0x451E, 0x98}, ++{0x451F, 0x9A}, ++{0x4520, 0xAF}, ++{0x4521, 0xAF}, ++{0x4522, 0xB2}, ++{0x4523, 0xB1}, ++{0x4524, 0x95}, ++{0x4525, 0x9B}, ++{0x4526, 0x97}, ++{0x4527, 0x9C}, ++{0x4528, 0x8A}, ++{0x4529, 0x8E}, ++{0x452A, 0x8D}, ++{0x452B, 0x90}, ++{0x452C, 0x84}, ++{0x452D, 0x86}, ++{0x452E, 0x85}, ++{0x452F, 0x87}, ++{0x4530, 0x81}, ++{0x4531, 0x82}, ++{0x4532, 0x82}, ++{0x4533, 0x83}, ++{0x4534, 0x81}, ++{0x4535, 0x81}, ++{0x4536, 0x81}, ++{0x4537, 0x82}, ++{0x4538, 0x84}, ++{0x4539, 0x83}, ++{0x453A, 0x83}, ++{0x453B, 0x84}, ++{0x453C, 0x8A}, ++{0x453D, 0x88}, ++{0x453E, 0x88}, ++{0x453F, 0x89}, ++{0x4540, 0x94}, ++{0x4541, 0x92}, ++{0x4542, 0x91}, ++{0x4543, 0x92}, ++{0x4544, 0xA1}, ++{0x4545, 0xA0}, ++{0x4546, 0x9C}, ++{0x4547, 0x9D}, ++{0x4548, 0x8F}, ++{0x4549, 0x96}, ++{0x454A, 0x95}, ++{0x454B, 0x92}, ++{0x454C, 0x87}, ++{0x454D, 0x8A}, ++{0x454E, 0x89}, ++{0x454F, 0x8A}, ++{0x4550, 0x81}, ++{0x4551, 0x83}, ++{0x4552, 0x82}, ++{0x4553, 0x83}, ++{0x4554, 0x7F}, ++{0x4555, 0x80}, ++{0x4556, 0x80}, ++{0x4557, 0x81}, ++{0x4558, 0x7F}, ++{0x4559, 0x80}, ++{0x455A, 0x7F}, ++{0x455B, 0x80}, ++{0x455C, 0x81}, ++{0x455D, 0x81}, ++{0x455E, 0x81}, ++{0x455F, 0x81}, ++{0x4560, 0x86}, ++{0x4561, 0x85}, ++{0x4562, 0x85}, ++{0x4563, 0x85}, ++{0x4564, 0x8F}, ++{0x4565, 0x8D}, ++{0x4566, 0x8D}, ++{0x4567, 0x8D}, ++{0x4568, 0x99}, ++{0x4569, 0x9A}, ++{0x456A, 0x97}, ++{0x456B, 0x99}, ++{0x456C, 0x90}, ++{0x456D, 0x95}, ++{0x456E, 0x93}, ++{0x456F, 0x92}, ++{0x4570, 0x87}, ++{0x4571, 0x8A}, ++{0x4572, 0x88}, ++{0x4573, 0x87}, ++{0x4574, 0x81}, ++{0x4575, 0x83}, ++{0x4576, 0x82}, ++{0x4577, 0x82}, ++{0x4578, 0x7F}, ++{0x4579, 0x80}, ++{0x457A, 0x80}, ++{0x457B, 0x80}, ++{0x457C, 0x80}, ++{0x457D, 0x80}, ++{0x457E, 0x80}, ++{0x457F, 0x80}, ++{0x4580, 0x81}, ++{0x4581, 0x81}, ++{0x4582, 0x81}, ++{0x4583, 0x81}, ++{0x4584, 0x85}, ++{0x4585, 0x85}, ++{0x4586, 0x84}, ++{0x4587, 0x85}, ++{0x4588, 0x8E}, ++{0x4589, 0x8D}, ++{0x458A, 0x8C}, ++{0x458B, 0x8D}, ++{0x458C, 0x9B}, ++{0x458D, 0x9B}, ++{0x458E, 0x9A}, ++{0x458F, 0x98}, ++{0x4590, 0x94}, ++{0x4591, 0x9A}, ++{0x4592, 0x94}, ++{0x4593, 0x90}, ++{0x4594, 0x8A}, ++{0x4595, 0x8D}, ++{0x4596, 0x8C}, ++{0x4597, 0x89}, ++{0x4598, 0x84}, ++{0x4599, 0x86}, ++{0x459A, 0x85}, ++{0x459B, 0x83}, ++{0x459C, 0x82}, ++{0x459D, 0x83}, ++{0x459E, 0x82}, ++{0x459F, 0x80}, ++{0x45A0, 0x81}, ++{0x45A1, 0x82}, ++{0x45A2, 0x81}, ++{0x45A3, 0x80}, ++{0x45A4, 0x83}, ++{0x45A5, 0x83}, ++{0x45A6, 0x83}, ++{0x45A7, 0x83}, ++{0x45A8, 0x88}, ++{0x45A9, 0x87}, ++{0x45AA, 0x87}, ++{0x45AB, 0x88}, ++{0x45AC, 0x91}, ++{0x45AD, 0x90}, ++{0x45AE, 0x90}, ++{0x45AF, 0x91}, ++{0x45B0, 0x9F}, ++{0x45B1, 0x9F}, ++{0x45B2, 0x9E}, ++{0x45B3, 0x9F}, ++{0x45B4, 0x9F}, ++{0x45B5, 0xA8}, ++{0x45B6, 0xA6}, ++{0x45B7, 0xA7}, ++{0x45B8, 0x8D}, ++{0x45B9, 0x95}, ++{0x45BA, 0x90}, ++{0x45BB, 0x8A}, ++{0x45BC, 0x89}, ++{0x45BD, 0x8D}, ++{0x45BE, 0x88}, ++{0x45BF, 0x86}, ++{0x45C0, 0x84}, ++{0x45C1, 0x86}, ++{0x45C2, 0x85}, ++{0x45C3, 0x82}, ++{0x45C4, 0x84}, ++{0x45C5, 0x85}, ++{0x45C6, 0x85}, ++{0x45C7, 0x83}, ++{0x45C8, 0x86}, ++{0x45C9, 0x86}, ++{0x45CA, 0x86}, ++{0x45CB, 0x85}, ++{0x45CC, 0x8E}, ++{0x45CD, 0x8D}, ++{0x45CE, 0x8D}, ++{0x45CF, 0x8C}, ++{0x45D0, 0x99}, ++{0x45D1, 0x98}, ++{0x45D2, 0x98}, ++{0x45D3, 0x98}, ++{0x45D4, 0xA6}, ++{0x45D5, 0xA9}, ++{0x45D6, 0xA7}, ++{0x45D7, 0xAC}, ++{0x7000, 0xAB}, ++{0x7001, 0xBA}, ++{0x7002, 0x40}, ++{0x7003, 0x02}, ++{0x7004, 0x00}, ++{0x7005, 0x00}, ++{0x7006, 0x00}, ++{0x7007, 0x00}, ++{0x7008, 0x00}, ++{0x7009, 0x00}, ++{0x700A, 0x00}, ++{0x700B, 0x00}, ++{0x700C, 0x00}, ++{0x700D, 0x00}, ++{0x700E, 0x00}, ++{0x700F, 0x00}, ++{0x7010, 0x55}, ++{0x7011, 0x88}, ++{0x7012, 0x40}, ++{0x7013, 0x01}, ++{0x7014, 0x72}, ++{0x7015, 0xF1}, ++{0x7016, 0x02}, ++{0x7017, 0xF8}, ++{0x7018, 0x00}, ++{0x7019, 0x00}, ++{0x701A, 0x00}, ++{0x701B, 0x00}, ++{0x701C, 0x00}, ++{0x701D, 0x00}, ++{0x701E, 0x00}, ++{0x701F, 0x00}, ++{0x7020, 0x00}, ++{0x7021, 0x00}, ++{0x7022, 0x00}, ++{0x7023, 0x00}, ++{0x7024, 0x00}, ++{0x7025, 0x00}, ++{0x7026, 0x00}, ++{0x7027, 0x00}, ++{0x7028, 0x00}, ++{0x7029, 0x00}, ++{0x702A, 0x00}, ++{0x702B, 0x00}, ++{0x702C, 0x00}, ++{0x702D, 0x00}, ++{0x702E, 0x00}, ++{0x702F, 0x00}, ++{0x7030, 0x00}, ++{0x7031, 0x00}, ++{0x7032, 0x00}, ++{0x7033, 0x00}, ++{0x7034, 0x00}, ++{0x7035, 0x00}, ++{0x7036, 0x00}, ++{0x7037, 0x00}, ++{0x7038, 0x00}, ++{0x7039, 0x00}, ++{0x703A, 0x00}, ++{0x703B, 0x00}, ++{0x703C, 0x00}, ++{0x703D, 0x00}, ++{0x703E, 0x00}, ++{0x703F, 0x00}, ++{0x7040, 0x00}, ++{0x7041, 0x00}, ++{0x7042, 0x00}, ++{0x7043, 0x00}, ++{0x7044, 0x00}, ++{0x7045, 0x00}, ++{0x7046, 0x00}, ++{0x7047, 0x00}, ++{0x7048, 0x00}, ++{0x7049, 0x00}, ++{0x704A, 0x00}, ++{0x704B, 0x00}, ++{0x704C, 0x00}, ++{0x704D, 0x00}, ++{0x704E, 0x00}, ++{0x704F, 0x00}, ++{0x7050, 0x00}, ++{0x7051, 0x00}, ++{0x7052, 0x00}, ++{0x7053, 0x00}, ++{0x7054, 0x00}, ++{0x7055, 0x00}, ++{0x7056, 0x00}, ++{0x7057, 0x00}, ++{0x7058, 0x00}, ++{0x7059, 0x00}, ++{0x705A, 0x00}, ++{0x705B, 0x00}, ++{0x705C, 0x00}, ++{0x705D, 0x00}, ++{0x705E, 0x00}, ++{0x705F, 0x00}, ++{0x7060, 0x00}, ++{0x7061, 0x00}, ++{0x7062, 0x00}, ++{0x7063, 0x00}, ++{0x7064, 0x00}, ++{0x7065, 0x00}, ++{0x7066, 0x00}, ++{0x7067, 0x00}, ++{0x7068, 0x00}, ++{0x7069, 0x00}, ++{0x706A, 0x00}, ++{0x706B, 0x00}, ++{0x706C, 0x00}, ++{0x706D, 0x00}, ++{0x706E, 0x00}, ++{0x706F, 0x00}, ++{0x7070, 0x00}, ++{0x7071, 0x00}, ++{0x7072, 0x00}, ++{0x7073, 0x00}, ++{0x7074, 0x00}, ++{0x7075, 0x00}, ++{0x7076, 0x00}, ++{0x7077, 0x00}, ++{0x7078, 0x00}, ++{0x7079, 0x00}, ++{0x707A, 0x00}, ++{0x707B, 0x00}, ++{0x707C, 0x00}, ++{0x707D, 0x00}, ++{0x707E, 0x00}, ++{0x707F, 0x00}, ++{0x7080, 0x00}, ++{0x7081, 0x00}, ++{0x7082, 0x00}, ++{0x7083, 0x00}, ++{0x7084, 0x00}, ++{0x7085, 0x00}, ++{0x7086, 0x00}, ++{0x7087, 0x00}, ++{0x7088, 0x00}, ++{0x7089, 0x00}, ++{0x708A, 0x00}, ++{0x708B, 0x00}, ++{0x708C, 0x00}, ++{0x708D, 0x00}, ++{0x708E, 0x00}, ++{0x708F, 0x00}, ++{0x7090, 0x00}, ++{0x7091, 0xF0}, ++{0x7092, 0x02}, ++{0x7093, 0xF8}, ++{0x7094, 0x8D}, ++{0x7095, 0xF6}, ++{0x7096, 0xFA}, ++{0x7097, 0xFF}, ++{0x7098, 0xF0}, ++{0x7099, 0xB5}, ++{0x709A, 0x04}, ++{0x709B, 0x46}, ++{0x709C, 0x8F}, ++{0x709D, 0xB0}, ++{0x709E, 0x5F}, ++{0x709F, 0x48}, ++{0x70A0, 0x0C}, ++{0x70A1, 0x90}, ++{0x70A2, 0x5F}, ++{0x70A3, 0x48}, ++{0x70A4, 0x06}, ++{0x70A5, 0x90}, ++{0x70A6, 0x20}, ++{0x70A7, 0x46}, ++{0x70A8, 0x34}, ++{0x70A9, 0x30}, ++{0x70AA, 0x0B}, ++{0x70AB, 0x90}, ++{0x70AC, 0x5B}, ++{0x70AD, 0x48}, ++{0x70AE, 0x5A}, ++{0x70AF, 0x49}, ++{0x70B0, 0x26}, ++{0x70B1, 0x46}, ++{0x70B2, 0x66}, ++{0x70B3, 0x30}, ++{0x70B4, 0x3A}, ++{0x70B5, 0x31}, ++{0x70B6, 0x3C}, ++{0x70B7, 0x36}, ++{0x70B8, 0x05}, ++{0x70B9, 0x90}, ++{0x70BA, 0x0A}, ++{0x70BB, 0x30}, ++{0x70BC, 0x04}, ++{0x70BD, 0x90}, ++{0x70BE, 0x59}, ++{0x70BF, 0x48}, ++{0x70C0, 0x55}, ++{0x70C1, 0x4A}, ++{0x70C2, 0x40}, ++{0x70C3, 0x6E}, ++{0x70C4, 0xC0}, ++{0x70C5, 0x07}, ++{0x70C6, 0x7D}, ++{0x70C7, 0xD1}, ++{0x70C8, 0x17}, ++{0x70C9, 0x88}, ++{0x70CA, 0x0A}, ++{0x70CB, 0x5E}, ++{0x70CC, 0x0D}, ++{0x70CD, 0x92}, ++{0x70CE, 0x53}, ++{0x70CF, 0x49}, ++{0x70D0, 0x55}, ++{0x70D1, 0x48}, ++{0x70D2, 0x94}, ++{0x70D3, 0x31}, ++{0x70D4, 0x89}, ++{0x70D5, 0x6B}, ++{0x70D6, 0x80}, ++{0x70D7, 0x68}, ++{0x70D8, 0x09}, ++{0x70D9, 0x02}, ++{0x70DA, 0x00}, ++{0x70DB, 0x03}, ++{0x70DC, 0x09}, ++{0x70DD, 0x0E}, ++{0x70DE, 0x00}, ++{0x70DF, 0x0B}, ++{0x70E0, 0x49}, ++{0x70E1, 0x1C}, ++{0x70E2, 0x48}, ++{0x70E3, 0x43}, ++{0x70E4, 0x4D}, ++{0x70E5, 0x49}, ++{0x70E6, 0x6C}, ++{0x70E7, 0x39}, ++{0x70E8, 0x8A}, ++{0x70E9, 0x6A}, ++{0x70EA, 0x07}, ++{0x70EB, 0x92}, ++{0x70EC, 0xCA}, ++{0x70ED, 0x6A}, ++{0x70EE, 0x00}, ++{0x70EF, 0x21}, ++{0x70F0, 0xC9}, ++{0x70F1, 0x43}, ++{0x70F2, 0x03}, ++{0x70F3, 0x92}, ++{0x70F4, 0x00}, ++{0x70F5, 0x22}, ++{0x70F6, 0x00}, ++{0x70F7, 0x91}, ++{0x70F8, 0x01}, ++{0x70F9, 0x92}, ++{0x70FA, 0x39}, ++{0x70FB, 0x46}, ++{0x70FC, 0x8F}, ++{0x70FD, 0xF6}, ++{0x70FE, 0xCE}, ++{0x70FF, 0xFB}, ++{0x7100, 0x01}, ++{0x7101, 0x22}, ++{0x7102, 0x00}, ++{0x7103, 0x23}, ++{0x7104, 0x8C}, ++{0x7105, 0xF6}, ++{0x7106, 0x02}, ++{0x7107, 0xFA}, ++{0x7108, 0x00}, ++{0x7109, 0x21}, ++{0x710A, 0x05}, ++{0x710B, 0x46}, ++{0x710C, 0x01}, ++{0x710D, 0x91}, ++{0x710E, 0x00}, ++{0x710F, 0x90}, ++{0x7110, 0x39}, ++{0x7111, 0x46}, ++{0x7112, 0x07}, ++{0x7113, 0x98}, ++{0x7114, 0x8F}, ++{0x7115, 0xF6}, ++{0x7116, 0xC2}, ++{0x7117, 0xFB}, ++{0x7118, 0x0D}, ++{0x7119, 0x9A}, ++{0x711A, 0xD3}, ++{0x711B, 0x17}, ++{0x711C, 0x80}, ++{0x711D, 0x18}, ++{0x711E, 0x59}, ++{0x711F, 0x41}, ++{0x7120, 0x01}, ++{0x7121, 0x22}, ++{0x7122, 0x00}, ++{0x7123, 0x23}, ++{0x7124, 0x8C}, ++{0x7125, 0xF6}, ++{0x7126, 0xCD}, ++{0x7127, 0xF9}, ++{0x7128, 0x07}, ++{0x7129, 0x90}, ++{0x712A, 0x00}, ++{0x712B, 0x20}, ++{0x712C, 0x01}, ++{0x712D, 0x90}, ++{0x712E, 0x00}, ++{0x712F, 0x95}, ++{0x7130, 0x39}, ++{0x7131, 0x46}, ++{0x7132, 0x03}, ++{0x7133, 0x98}, ++{0x7134, 0x8F}, ++{0x7135, 0xF6}, ++{0x7136, 0xB2}, ++{0x7137, 0xFB}, ++{0x7138, 0x01}, ++{0x7139, 0x22}, ++{0x713A, 0x00}, ++{0x713B, 0x23}, ++{0x713C, 0x8C}, ++{0x713D, 0xF6}, ++{0x713E, 0xE6}, ++{0x713F, 0xF9}, ++{0x7140, 0x02}, ++{0x7141, 0x46}, ++{0x7142, 0x07}, ++{0x7143, 0x98}, ++{0x7144, 0x00}, ++{0x7145, 0x23}, ++{0x7146, 0x81}, ++{0x7147, 0x0B}, ++{0x7148, 0x80}, ++{0x7149, 0x04}, ++{0x714A, 0x7A}, ++{0x714B, 0xF6}, ++{0x714C, 0x54}, ++{0x714D, 0xF8}, ++{0x714E, 0x37}, ++{0x714F, 0x4A}, ++{0x7150, 0x00}, ++{0x7151, 0x23}, ++{0x7152, 0x00}, ++{0x7153, 0x92}, ++{0x7154, 0x01}, ++{0x7155, 0x93}, ++{0x7156, 0x01}, ++{0x7157, 0x22}, ++{0x7158, 0x8C}, ++{0x7159, 0xF6}, ++{0x715A, 0xD8}, ++{0x715B, 0xF9}, ++{0x715C, 0x05}, ++{0x715D, 0x46}, ++{0x715E, 0x60}, ++{0x715F, 0x68}, ++{0x7160, 0x00}, ++{0x7161, 0x23}, ++{0x7162, 0x01}, ++{0x7163, 0x0C}, ++{0x7164, 0x00}, ++{0x7165, 0x04}, ++{0x7166, 0xE2}, ++{0x7167, 0x68}, ++{0x7168, 0x7A}, ++{0x7169, 0xF6}, ++{0x716A, 0x45}, ++{0x716B, 0xF8}, ++{0x716C, 0x00}, ++{0x716D, 0x22}, ++{0x716E, 0xD2}, ++{0x716F, 0x43}, ++{0x7170, 0x00}, ++{0x7171, 0x23}, ++{0x7172, 0x00}, ++{0x7173, 0x92}, ++{0x7174, 0x01}, ++{0x7175, 0x93}, ++{0x7176, 0x1A}, ++{0x7177, 0x46}, ++{0x7178, 0x8C}, ++{0x7179, 0xF6}, ++{0x717A, 0xC8}, ++{0x717B, 0xF9}, ++{0x717C, 0x29}, ++{0x717D, 0x46}, ++{0x717E, 0x8F}, ++{0x717F, 0xF6}, ++{0x7180, 0x8D}, ++{0x7181, 0xFB}, ++{0x7182, 0x8A}, ++{0x7183, 0x03}, ++{0x7184, 0x80}, ++{0x7185, 0x0C}, ++{0x7186, 0x10}, ++{0x7187, 0x43}, ++{0x7188, 0x00}, ++{0x7189, 0x22}, ++{0x718A, 0xD2}, ++{0x718B, 0x43}, ++{0x718C, 0x00}, ++{0x718D, 0x23}, ++{0x718E, 0x00}, ++{0x718F, 0x92}, ++{0x7190, 0x89}, ++{0x7191, 0x0C}, ++{0x7192, 0x01}, ++{0x7193, 0x93}, ++{0x7194, 0x1A}, ++{0x7195, 0x46}, ++{0x7196, 0x8C}, ++{0x7197, 0xF6}, ++{0x7198, 0xB9}, ++{0x7199, 0xF9}, ++{0x719A, 0x00}, ++{0x719B, 0x24}, ++{0x719C, 0x03}, ++{0x719D, 0x90}, ++{0x719E, 0x0C}, ++{0x719F, 0x98}, ++{0x71A0, 0x61}, ++{0x71A1, 0x00}, ++{0x71A2, 0x45}, ++{0x71A3, 0x5A}, ++{0x71A4, 0x06}, ++{0x71A5, 0x98}, ++{0x71A6, 0x22}, ++{0x71A7, 0x4A}, ++{0x71A8, 0x40}, ++{0x71A9, 0x5A}, ++{0x71AA, 0x00}, ++{0x71AB, 0x21}, ++{0x71AC, 0x8C}, ++{0x71AD, 0xF6}, ++{0x71AE, 0xBE}, ++{0x71AF, 0xF9}, ++{0x71B0, 0x07}, ++{0x71B1, 0x46}, ++{0x71B2, 0x28}, ++{0x71B3, 0x46}, ++{0x71B4, 0x03}, ++{0x71B5, 0x99}, ++{0x71B6, 0x8F}, ++{0x71B7, 0xF6}, ++{0x71B8, 0x71}, ++{0x71B9, 0xFB}, ++{0x71BA, 0x3A}, ++{0x71BB, 0x46}, ++{0x71BC, 0x00}, ++{0x71BD, 0x23}, ++{0x71BE, 0x79}, ++{0x71BF, 0xF6}, ++{0x71C0, 0xCA}, ++{0x71C1, 0xFF}, ++{0x71C2, 0x00}, ++{0x71C3, 0xE0}, ++{0x71C4, 0x0F}, ++{0x71C5, 0xE0}, ++{0x71C6, 0x8A}, ++{0x71C7, 0x02}, ++{0x71C8, 0x80}, ++{0x71C9, 0x0D}, ++{0x71CA, 0x10}, ++{0x71CB, 0x43}, ++{0x71CC, 0x19}, ++{0x71CD, 0x4A}, ++{0x71CE, 0x00}, ++{0x71CF, 0x23}, ++{0x71D0, 0x00}, ++{0x71D1, 0x92}, ++{0x71D2, 0x89}, ++{0x71D3, 0x0D}, ++{0x71D4, 0x01}, ++{0x71D5, 0x93}, ++{0x71D6, 0x40}, ++{0x71D7, 0x22}, ++{0x71D8, 0x8C}, ++{0x71D9, 0xF6}, ++{0x71DA, 0x98}, ++{0x71DB, 0xF9}, ++{0x71DC, 0xA1}, ++{0x71DD, 0x00}, ++{0x71DE, 0x64}, ++{0x71DF, 0x1C}, ++{0x71E0, 0x70}, ++{0x71E1, 0x50}, ++{0x71E2, 0x04}, ++{0x71E3, 0x2C}, ++{0x71E4, 0xDB}, ++{0x71E5, 0xD3}, ++{0x71E6, 0x14}, ++{0x71E7, 0x4D}, ++{0x71E8, 0x00}, ++{0x71E9, 0x24}, ++{0x71EA, 0x0B}, ++{0x71EB, 0x98}, ++{0x71EC, 0x67}, ++{0x71ED, 0x00}, ++{0x71EE, 0xC0}, ++{0x71EF, 0x5B}, ++{0x71F0, 0x2A}, ++{0x71F1, 0x46}, ++{0x71F2, 0x40}, ++{0x71F3, 0x21}, ++{0x71F4, 0x8C}, ++{0x71F5, 0xF6}, ++{0x71F6, 0x9A}, ++{0x71F7, 0xF9}, ++{0x71F8, 0x05}, ++{0x71F9, 0x99}, ++{0x71FA, 0x0E}, ++{0x71FB, 0x4A}, ++{0x71FC, 0xC8}, ++{0x71FD, 0x53}, ++{0x71FE, 0xA7}, ++{0x71FF, 0x00}, ++{0x7200, 0xF0}, ++{0x7201, 0x59}, ++{0x7202, 0x40}, ++{0x7203, 0x21}, ++{0x7204, 0x8C}, ++{0x7205, 0xF6}, ++{0x7206, 0x7B}, ++{0x7207, 0xF9}, ++{0x7208, 0x04}, ++{0x7209, 0x99}, ++{0x720A, 0x64}, ++{0x720B, 0x1C}, ++{0x720C, 0xC8}, ++{0x720D, 0x51}, ++{0x720E, 0x04}, ++{0x720F, 0x2C}, ++{0x7210, 0xEB}, ++{0x7211, 0xD3}, ++{0x7212, 0x0F}, ++{0x7213, 0xB0}, ++{0x7214, 0xF0}, ++{0x7215, 0xBD}, ++{0x7216, 0x00}, ++{0x7217, 0x00}, ++{0x7218, 0x76}, ++{0x7219, 0x69}, ++{0x721A, 0x18}, ++{0x721B, 0x00}, ++{0x721C, 0xEC}, ++{0x721D, 0x58}, ++{0x721E, 0x18}, ++{0x721F, 0x00}, ++{0x7220, 0x38}, ++{0x7221, 0x36}, ++{0x7222, 0x18}, ++{0x7223, 0x00}, ++{0x7224, 0x00}, ++{0x7225, 0x35}, ++{0x7226, 0x18}, ++{0x7227, 0x00}, ++{0x7228, 0x00}, ++{0x7229, 0x20}, ++{0x722A, 0x18}, ++{0x722B, 0x00}, ++{0x722C, 0xFF}, ++{0x722D, 0xFF}, ++{0x722E, 0xFF}, ++{0x722F, 0x3F}, ++{0x7230, 0xFF}, ++{0x7231, 0x07}, ++{0x7232, 0x00}, ++{0x7233, 0x00}, ++{0x7234, 0xFF}, ++{0x7235, 0xFF}, ++{0x7236, 0x07}, ++{0x7237, 0x00}, ++{0x7238, 0xFF}, ++{0x7239, 0x1F}, ++{0x723A, 0x00}, ++{0x723B, 0x00}, ++{0x723C, 0x01}, ++{0x723D, 0xF6}, ++{0x723E, 0x45}, ++{0x723F, 0x12}, ++{0x0000, 0x00}, ++}; diff --git a/drivers/media/i2c/soc_camera/max9286.c b/drivers/media/i2c/soc_camera/max9286.c new file mode 100644 -index 0000000..20ef2de +index 0000000..c850196 --- /dev/null +++ b/drivers/media/i2c/soc_camera/max9286.c -@@ -0,0 +1,672 @@ +@@ -0,0 +1,692 @@ +/* + * MAXIM max9286 GMSL driver + * @@ -1535,7 +6508,6 @@ index 0000000..20ef2de +#include <linux/module.h> +#include <linux/notifier.h> +#include <linux/of_gpio.h> -+#include <linux/regulator/consumer.h> +#include <linux/videodev2.h> + +#include <media/v4l2-common.h> @@ -1572,37 +6544,52 @@ index 0000000..20ef2de + int hsync; + int vsync; + int timeout; ++ int poc_delay; + atomic_t use_count; + u32 csi2_outord; + struct i2c_client *client; + int max9271_addr_map[4]; + int ser_id; -+ struct regulator *poc_supply[4]; /* PoC power supply */ ++ struct gpio_desc *poc_gpio[4]; /* PoC power supply */ +}; + ++static char fsync_mode_default[20] = "manual"; /* manual, automatic, semi-automatic, external */ ++ +static int conf_link; +module_param(conf_link, int, 0644); +MODULE_PARM_DESC(conf_link, " Force configuration link. Used only if robust firmware flashing required (f.e. recovery)"); + +static int poc_trig; +module_param(poc_trig, int, 0644); -+MODULE_PARM_DESC(poc_trig, " Use PoC triggering during reverse channel setup. Useful on systems with dedicated PoC and unstable ser-des lock */"); ++MODULE_PARM_DESC(poc_trig, " Use PoC triggering during reverse channel setup. Useful on systems with dedicated PoC and unstable ser-des lock"); + +static int him; +module_param(him, int, 0644); -+MODULE_PARM_DESC(him, " Use High-Immunity mode (default: leagacy mode) */"); ++MODULE_PARM_DESC(him, " Use High-Immunity mode (default: leagacy mode)"); + +static int fsync_period; +module_param(fsync_period, int, 0644); -+MODULE_PARM_DESC(fsync_period, " Frame sync period (default: 3.2MHz) */"); ++MODULE_PARM_DESC(fsync_period, " Frame sync period (default: 3.2MHz)"); + +static int hsync; +module_param(hsync, int, 0644); -+MODULE_PARM_DESC(hsync, " HSYNC invertion (default: 0 - not inverted) */"); ++MODULE_PARM_DESC(hsync, " HSYNC invertion (default: 0 - not inverted)"); + +static int vsync = 1; +module_param(vsync, int, 0644); -+MODULE_PARM_DESC(vsync, " VSYNC invertion (default: 1 - inverted) */"); ++MODULE_PARM_DESC(vsync, " VSYNC invertion (default: 1 - inverted)"); ++ ++static int gpio_resetb; ++module_param(gpio_resetb, int, 0644); ++MODULE_PARM_DESC(gpio_resetb, " Serializer GPIO reset (default: 0 - not used)"); ++ ++static int active_low_resetb; ++module_param(active_low_resetb, int, 0644); ++MODULE_PARM_DESC(active_low_resetb, " Serializer GPIO reset level (default: 0 - active high)"); ++ ++static int poc_delay; ++module_param(poc_delay, int, 0644); ++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms)"); + +static char* ser_name(int id) +{ @@ -1661,6 +6648,16 @@ index 0000000..20ef2de + reg8_write(client, 0x15, 0x9b); /* enable CSI output, VC is set accordingly to Link number, BIT7 magic must be set */ + reg8_write(client, 0x1b, priv->links_mask); /* enable equalizer for CAMs */ + usleep_range(5000, 5500); /* wait 2ms after any change of reverse channel settings */ ++ ++ if (strcmp(priv->fsync_mode, "manual") == 0) { ++ reg8_write(client, 0x01, 0x00); /* manual: FRAMESYNC set manually via [0x06:0x08] regs */ ++ } else if (strcmp(priv->fsync_mode, "automatic") == 0) { ++ reg8_write(client, 0x01, 0x02); /* automatic: FRAMESYNC taken from the slowest Link */ ++ } else if (strcmp(priv->fsync_mode, "semi-automatic") == 0) { ++ reg8_write(client, 0x01, 0x01); /* semi-automatic: FRAMESYNC taken from the slowest Link */ ++ } else if (strcmp(priv->fsync_mode, "external") == 0) { ++ reg8_write(client, 0x01, 0xc0); /* ECU (aka MCU) based FrameSync using GPI-to-GPO */ ++ } +} + +static int max9286_reverse_channel_setup(struct i2c_client *client, int idx) @@ -1715,12 +6712,11 @@ index 0000000..20ef2de + } + + if (timeout == priv->timeout / 2 && poc_trig) { -+ if (!IS_ERR(priv->poc_supply[idx])) { -+ if (regulator_disable(priv->poc_supply[idx])) -+ dev_err(&client->dev, "fail to disable POC%d regulator\n", idx); ++ if (!IS_ERR(priv->poc_gpio[idx])) { ++ gpiod_direction_output(priv->poc_gpio[idx], 0); /* POC power off */ + mdelay(200); -+ if (regulator_enable(priv->poc_supply[idx])) -+ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); ++ gpiod_direction_output(priv->poc_gpio[idx], 1); /* POC power on */ ++ mdelay(priv->poc_delay); + } + } + } @@ -1771,20 +6767,12 @@ index 0000000..20ef2de + dev_err(&client->dev, "CSI2 lanes number is invalid (%d)\n", priv->lanes); + } + ++ /* Start GMSL initialization with FSYNC disabled. This is required for some odd LVDS cameras */ ++ reg8_write(client, 0x01, 0xc0); /* ECU (aka MCU) based FrameSync using GPI-to-GPO */ + reg8_write(client, 0x06, priv->fsync_period & 0xff); + reg8_write(client, 0x07, (priv->fsync_period >> 8) & 0xff); + reg8_write(client, 0x08, priv->fsync_period >> 16); + -+ if (strcmp(priv->fsync_mode, "manual") == 0) { -+ reg8_write(client, 0x01, 0x00); /* manual: FRAMESYNC set manually via [0x06:0x08] regs */ -+ } else if (strcmp(priv->fsync_mode, "automatic") == 0) { -+ reg8_write(client, 0x01, 0x02); /* automatic: FRAMESYNC taken from the slowest Link */ -+ } else if (strcmp(priv->fsync_mode, "semi-automatic") == 0) { -+ reg8_write(client, 0x01, 0x01); /* semi-automatic: FRAMESYNC taken from the slowest Link */ -+ } else if (strcmp(priv->fsync_mode, "external") == 0) { -+ reg8_write(client, 0x01, 0xc0); /* ECU (aka MCU) based FrameSync using GPI-to-GPO */ -+ } -+ + reg8_write(client, 0x63, 0); /* disable overlap window */ + reg8_write(client, 0x64, 0); + reg8_write(client, 0x0c, 0x91 | (priv->vsync ? BIT(3) : 0) | (priv->hsync ? BIT(2) : 0)); /* enable HS/VS encoding, use D14/15 for HS/VS, invert HS/VS */ @@ -1866,9 +6854,9 @@ index 0000000..20ef2de + max9286_initial_setup(client); + + for (idx = 0; idx < priv->links; idx++) { -+ if (!IS_ERR(priv->poc_supply[idx])) { -+ if (regulator_enable(priv->poc_supply[idx])) -+ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); ++ if (!IS_ERR(priv->poc_gpio[idx])) { ++ gpiod_direction_output(priv->poc_gpio[idx], 1); /* POC power on */ ++ mdelay(priv->poc_delay); + } + + ret = max9286_reverse_channel_setup(client, idx); @@ -1975,8 +6963,8 @@ index 0000000..20ef2de + struct property *prop; + int err, pwen, i; + int sensor_delay, gpio0 = 1, gpio1 = 1; -+ char fsync_mode_default[20] = "manual"; /* manual, automatic, semi-automatic, external */ + u8 val = 0; ++ char poc_name[10]; + + if (of_property_read_u32(np, "maxim,links", &priv->links)) + priv->links = 4; @@ -1993,6 +6981,11 @@ index 0000000..20ef2de + + mdelay(250); + ++ for (i = 0; i < 4; i++) { ++ sprintf(poc_name, "POC%d", i); ++ priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, poc_name, 0); ++ } ++ + reg8_read(client, 0x1e, &val); /* read max9286 ID */ + if (val != MAX9286_ID) { + prop = of_find_property(np, "reg", NULL); @@ -2009,17 +7002,15 @@ index 0000000..20ef2de + priv->gpio_resetb = -1; + } else { + if (of_property_read_bool(np, "maxim,resetb-active-high")) -+ priv->active_low_resetb = false; ++ priv->active_low_resetb = 0; + else -+ priv->active_low_resetb = true; ++ priv->active_low_resetb = 1; + } + + if (!of_property_read_u32(np, "maxim,sensor_delay", &sensor_delay)) + mdelay(sensor_delay); -+ + if (of_property_read_string(np, "maxim,fsync-mode", &priv->fsync_mode)) + priv->fsync_mode = fsync_mode_default; -+ + if (of_property_read_u32(np, "maxim,fsync-period", &priv->fsync_period)) + priv->fsync_period = 3200000; /* 96MHz/30fps */ + priv->pclk_rising_edge = true; @@ -2035,6 +7026,8 @@ index 0000000..20ef2de + priv->hsync = 0; + if (of_property_read_u32(np, "maxim,vsync", &priv->vsync)) + priv->vsync = 1; ++ if (of_property_read_u32(np, "maxim,poc-delay", &priv->poc_delay)) ++ priv->poc_delay = 50; + + /* module params override dts */ + if (him) @@ -2047,6 +7040,12 @@ index 0000000..20ef2de + priv->hsync = hsync; + if (!vsync) + priv->vsync = vsync; ++ if (gpio_resetb) ++ priv->gpio_resetb = gpio_resetb; ++ if (active_low_resetb) ++ priv->active_low_resetb = active_low_resetb; ++ if (poc_delay) ++ priv->poc_delay = poc_delay; + + for (i = 0; i < priv->links; i++) { + endpoint = of_graph_get_next_endpoint(np, endpoint); @@ -2104,7 +7103,6 @@ index 0000000..20ef2de +{ + struct max9286_priv *priv; + int err, i; -+ char supply_name[10]; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) @@ -2120,11 +7118,6 @@ index 0000000..20ef2de + if (err) + goto out; + -+ for (i = 0; i < 4; i++) { -+ sprintf(supply_name, "POC%d", i); -+ priv->poc_supply[i] = devm_regulator_get_optional(&client->dev, supply_name); -+ } -+ + err = max9286_initialize(client); + if (err < 0) + goto out; @@ -2443,10 +7436,10 @@ index 0000000..6c2a9e0 +#endif /* _MAX9286_MAX9271_H */ diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c new file mode 100644 -index 0000000..c8da1f4 +index 0000000..8c06e59 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov10635.c -@@ -0,0 +1,758 @@ +@@ -0,0 +1,759 @@ +/* + * OmniVision ov10635 sensor camera driver + * @@ -2519,6 +7512,7 @@ index 0000000..c8da1f4 + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -4412,10 +9406,10 @@ index 0000000..4c3515a +#endif diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c new file mode 100644 -index 0000000..4c797f9 +index 0000000..08786ab --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov106xx.c -@@ -0,0 +1,117 @@ +@@ -0,0 +1,161 @@ +/* + * OmniVision ov10635/ov490-ov10640/ov495-ov2775 sensor camera driver + * @@ -4431,14 +9425,22 @@ index 0000000..4c797f9 +#include "ov490_ov10640.c" +#include "ov495_ov2775.c" +#include "ar0132.c" ++#include "ar0220.c" +#include "ap0101_ar014x.c" ++#include "ov2775.c" ++#include "imx390.c" ++#include "ox03a.c" + +static enum { + ID_OV10635, + ID_OV490_OV10640, + ID_OV495_OV2775, + ID_AR0132, ++ ID_AR0220, + ID_AP0101_AR014X, ++ ID_OV2775, ++ ID_IMX390, ++ ID_OX03A, +} chip_id; + +static int ov106xx_probe(struct i2c_client *client, @@ -4471,12 +9473,36 @@ index 0000000..4c797f9 + goto out; + } + ++ ret = ar0220_probe(client, did); ++ if (!ret) { ++ chip_id = ID_AR0220; ++ goto out; ++ } ++ + ret = ap0101_probe(client, did); + if (!ret) { + chip_id = ID_AP0101_AR014X; + goto out; + } + ++ ret = ov2775_probe(client, did); ++ if (!ret) { ++ chip_id = ID_OV2775; ++ goto out; ++ } ++ ++ ret = imx390_probe(client, did); ++ if (!ret) { ++ chip_id = ID_IMX390; ++ goto out; ++ } ++ ++ ret = ox03a_probe(client, did); ++ if (!ret) { ++ chip_id = ID_OX03A; ++ goto out; ++ } ++ + v4l_err(client, "failed to probe @ 0x%02x (%s)\n", + client->addr, client->adapter->name); +out: @@ -4498,9 +9524,21 @@ index 0000000..4c797f9 + case ID_AR0132: + ar0132_remove(client); + break; ++ case ID_AR0220: ++ ar0220_remove(client); ++ break; + case ID_AP0101_AR014X: + ap0101_remove(client); + break; ++ case ID_OV2775: ++ ov2775_remove(client); ++ break; ++ case ID_IMX390: ++ imx390_remove(client); ++ break; ++ case ID_OX03A: ++ ox03a_remove(client); ++ break; + }; + + return 0; @@ -4530,19 +9568,2410 @@ index 0000000..4c797f9 + +module_i2c_driver(ov106xx_i2c_driver); + -+MODULE_DESCRIPTION("SoC Camera driver for OV10635 or OV490/OV10640 or OV495/OV2775 or AR0132 or AP0101/AR014X"); ++MODULE_DESCRIPTION("SoC Camera driver for OV10635, OV490/OV10640, OV495/OV2775, AR0132, AR0220, AP0101/AR014X"); ++MODULE_AUTHOR("Vladimir Barinov"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/i2c/soc_camera/ov2775.c b/drivers/media/i2c/soc_camera/ov2775.c +new file mode 100644 +index 0000000..f57fc71 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/ov2775.c +@@ -0,0 +1,538 @@ ++/* ++ * OmniVision OV2775 sensor camera driver ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include <linux/delay.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/module.h> ++#include <linux/videodev2.h> ++ ++#include <media/soc_camera.h> ++#include <media/v4l2-common.h> ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-of.h> ++ ++#include "ov2775.h" ++ ++#define OV2775_I2C_ADDR 0x36 ++ ++#define OV2775_PID 0x300a ++#define OV2775_VER 0x300b ++#define OV2775_VERSION_REG 0x2770 ++ ++#define OV2775_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12 ++ ++struct ov2775_priv { ++ struct v4l2_subdev sd; ++ struct v4l2_ctrl_handler hdl; ++ struct media_pad pad; ++ struct v4l2_rect rect; ++ int init_complete; ++ u8 id[6]; ++ int exposure; ++ int gain; ++ int autogain; ++ /* serializers */ ++ int ti9x4_addr; ++ int ti9x3_addr; ++ int port; ++ int gpio_resetb; ++ int gpio_fsin; ++ ++}; ++ ++static inline struct ov2775_priv *to_ov2775(const struct i2c_client *client) ++{ ++ return container_of(i2c_get_clientdata(client), struct ov2775_priv, sd); ++} ++ ++static int ov2775_set_regs(struct i2c_client *client, ++ const struct ov2775_reg *regs, int nr_regs) ++{ ++ int i; ++ ++ for (i = 0; i < nr_regs; i++) { ++ if (regs[i].reg == OV2775_DELAY) { ++ mdelay(regs[i].val); ++ continue; ++ } ++ ++ reg16_write(client, regs[i].reg, regs[i].val); ++ } ++ ++ return 0; ++} ++ ++static int ov2775_s_stream(struct v4l2_subdev *sd, int enable) ++{ ++ return 0; ++} ++ ++static int ov2775_get_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ov2775_priv *priv = to_ov2775(client); ++ ++ if (format->pad) ++ return -EINVAL; ++ ++ mf->width = priv->rect.width; ++ mf->height = priv->rect.height; ++ mf->code = OV2775_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ return 0; ++} ++ ++static int ov2775_set_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ ++ mf->code = OV2775_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ if (format->which == V4L2_SUBDEV_FORMAT_TRY) ++ cfg->try_fmt = *mf; ++ ++ return 0; ++} ++ ++static int ov2775_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ if (code->pad || code->index > 0) ++ return -EINVAL; ++ ++ code->code = OV2775_MEDIA_BUS_FMT; ++ ++ return 0; ++} ++ ++static int ov2775_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ov2775_priv *priv = to_ov2775(client); ++ ++ memcpy(edid->edid, priv->id, 6); ++ ++ edid->edid[6] = 0xff; ++ edid->edid[7] = client->addr; ++ edid->edid[8] = OV2775_VERSION_REG >> 8; ++ edid->edid[9] = OV2775_VERSION_REG & 0xff; ++ ++ return 0; ++} ++ ++static int ov2775_set_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct v4l2_rect *rect = &sel->r; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ov2775_priv *priv = to_ov2775(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || ++ sel->target != V4L2_SEL_TGT_CROP) ++ return -EINVAL; ++ ++ rect->left = ALIGN(rect->left, 2); ++ rect->top = ALIGN(rect->top, 2); ++ rect->width = ALIGN(rect->width, 2); ++ rect->height = ALIGN(rect->height, 2); ++ ++ if ((rect->left + rect->width > OV2775_MAX_WIDTH) || ++ (rect->top + rect->height > OV2775_MAX_HEIGHT)) ++ *rect = priv->rect; ++ ++ priv->rect.left = rect->left; ++ priv->rect.top = rect->top; ++ priv->rect.width = rect->width; ++ priv->rect.height = rect->height; ++ ++ return 0; ++} ++ ++static int ov2775_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ov2775_priv *priv = to_ov2775(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) ++ return -EINVAL; ++ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = OV2775_MAX_WIDTH; ++ sel->r.height = OV2775_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = OV2775_MAX_WIDTH; ++ sel->r.height = OV2775_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP: ++ sel->r = priv->rect; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int ov2775_g_mbus_config(struct v4l2_subdev *sd, ++ struct v4l2_mbus_config *cfg) ++{ ++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | ++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; ++ cfg->type = V4L2_MBUS_CSI2; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++static int ov2775_g_register(struct v4l2_subdev *sd, ++ struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ int ret; ++ u8 val = 0; ++ ++ ret = reg16_read(client, (u16)reg->reg, &val); ++ if (ret < 0) ++ return ret; ++ ++ reg->val = val; ++ reg->size = sizeof(u8); ++ ++ return 0; ++} ++ ++static int ov2775_s_register(struct v4l2_subdev *sd, ++ const struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ ++ return reg16_write(client, (u16)reg->reg, (u8)reg->val); ++} ++#endif ++ ++static struct v4l2_subdev_core_ops ov2775_core_ops = { ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ .g_register = ov2775_g_register, ++ .s_register = ov2775_s_register, ++#endif ++}; ++ ++static int ov2775_s_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct v4l2_subdev *sd = to_sd(ctrl); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ov2775_priv *priv = to_ov2775(client); ++ int ret = -EINVAL; ++ ++ if (!priv->init_complete) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_BRIGHTNESS: ++ case V4L2_CID_CONTRAST: ++ case V4L2_CID_SATURATION: ++ case V4L2_CID_HUE: ++ case V4L2_CID_GAMMA: ++ case V4L2_CID_SHARPNESS: ++ case V4L2_CID_AUTOGAIN: ++ case V4L2_CID_GAIN: ++ case V4L2_CID_EXPOSURE: ++ case V4L2_CID_HFLIP: ++ case V4L2_CID_VFLIP: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops ov2775_ctrl_ops = { ++ .s_ctrl = ov2775_s_ctrl, ++}; ++ ++static struct v4l2_subdev_video_ops ov2775_video_ops = { ++ .s_stream = ov2775_s_stream, ++ .g_mbus_config = ov2775_g_mbus_config, ++}; ++ ++static const struct v4l2_subdev_pad_ops ov2775_subdev_pad_ops = { ++ .get_edid = ov2775_get_edid, ++ .enum_mbus_code = ov2775_enum_mbus_code, ++ .get_selection = ov2775_get_selection, ++ .set_selection = ov2775_set_selection, ++ .get_fmt = ov2775_get_fmt, ++ .set_fmt = ov2775_set_fmt, ++}; ++ ++static struct v4l2_subdev_ops ov2775_subdev_ops = { ++ .core = &ov2775_core_ops, ++ .video = &ov2775_video_ops, ++ .pad = &ov2775_subdev_pad_ops, ++}; ++ ++static void ov2775_otp_id_read(struct i2c_client *client) ++{ ++} ++ ++static ssize_t ov2775_otp_id_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev)); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ov2775_priv *priv = to_ov2775(client); ++ ++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n", ++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++} ++ ++static DEVICE_ATTR(otp_id_ov2775, S_IRUGO, ov2775_otp_id_show, NULL); ++ ++static int ov2775_initialize(struct i2c_client *client) ++{ ++ struct ov2775_priv *priv = to_ov2775(client); ++ u8 val = 0; ++ u16 pid; ++ int ret = 0; ++ int tmp_addr; ++ ++ /* check and show model ID */ ++ reg16_read(client, OV2775_PID, &val); ++ pid = val; ++ reg16_read(client, OV2775_VER, &val); ++ pid = (pid << 8) | val; ++ ++ if (pid != OV2775_VERSION_REG) { ++ dev_dbg(&client->dev, "Product ID error %x\n", pid); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ /* setup XCLK */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=25MHz: CLKDIV=4, M=7, N=253: 22.5792*160/4*7/253=24.989MHz=CLK_OUT */ ++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */ ++ reg8_write(client, 0x06, 0x47); /* Set CLKDIV and M */ ++ reg8_write(client, 0x07, 0xfd); /* Set N */ ++ } ++ client->addr = tmp_addr; ++ ++ /* Program wizard registers */ ++ ov2775_set_regs(client, ov2775_regs_wizard, ARRAY_SIZE(ov2775_regs_wizard)); ++ /* Read OTP IDs */ ++ ov2775_otp_id_read(client); ++ ++ dev_info(&client->dev, "ov2775 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pid, OV2775_MAX_WIDTH, OV2775_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++err: ++ return ret; ++} ++ ++static int ov2775_parse_dt(struct device_node *np, struct ov2775_priv *priv) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd); ++ int i; ++ struct device_node *endpoint = NULL, *rendpoint = NULL; ++ int tmp_addr = 0; ++ ++ for (i = 0; ; i++) { ++ endpoint = of_graph_get_next_endpoint(np, endpoint); ++ if (!endpoint) ++ break; ++ ++ of_node_put(endpoint); ++ ++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0); ++ if (!rendpoint) ++ continue; ++ ++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && ++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) ++ break; ++ } ++ ++ if (!priv->ti9x4_addr) { ++ dev_err(&client->dev, "deserializer does not present\n"); ++ return -EINVAL; ++ } ++ ++ /* setup I2C translator address */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ ++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ ++ reg8_write(client, 0x5d, OV2775_I2C_ADDR << 1); /* Sensor native I2C address */ ++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */ ++ ++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */ ++ reg8_write(client, 0x0d, 0x03); /* unreset gpios */ ++ reg8_write(client, 0x0e, 0xf0); /* unreset gpios */ ++ } ++ client->addr = tmp_addr; ++ ++ mdelay(10); ++ ++ return 0; ++} ++ ++static int ov2775_probe(struct i2c_client *client, ++ const struct i2c_device_id *did) ++{ ++ struct ov2775_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ v4l2_i2c_subdev_init(&priv->sd, client, &ov2775_subdev_ops); ++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ priv->exposure = 0x100; ++ priv->gain = 0x100; ++ priv->autogain = 1; ++ v4l2_ctrl_handler_init(&priv->hdl, 4); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_CONTRAST, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_SATURATION, 0, 7, 1, 2); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_HUE, 0, 23, 1, 12); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_GAMMA, -128, 128, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_SHARPNESS, 0, 10, 1, 3); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 1); ++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ priv->sd.ctrl_handler = &priv->hdl; ++ ++ ret = priv->hdl.error; ++ if (ret) ++ goto cleanup; ++ ++ v4l2_ctrl_handler_setup(&priv->hdl); ++ ++ priv->pad.flags = MEDIA_PAD_FL_SOURCE; ++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; ++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad); ++ if (ret < 0) ++ goto cleanup; ++ ++ ret = ov2775_parse_dt(client->dev.of_node, priv); ++ if (ret) ++ goto cleanup; ++ ++ ret = ov2775_initialize(client); ++ if (ret < 0) ++ goto cleanup; ++ ++ priv->rect.left = 0; ++ priv->rect.top = 0; ++ priv->rect.width = OV2775_MAX_WIDTH; ++ priv->rect.height = OV2775_MAX_HEIGHT; ++ ++ ret = v4l2_async_register_subdev(&priv->sd); ++ if (ret) ++ goto cleanup; ++ ++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov2775) != 0) { ++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n"); ++ goto cleanup; ++ } ++ ++ priv->init_complete = 1; ++ ++ return 0; ++ ++cleanup: ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++#ifdef CONFIG_SOC_CAMERA_OV2775 ++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n", ++ client->addr, client->adapter->name); ++#endif ++ return ret; ++} ++ ++static int ov2775_remove(struct i2c_client *client) ++{ ++ struct ov2775_priv *priv = i2c_get_clientdata(client); ++ ++ device_remove_file(&client->dev, &dev_attr_otp_id_ov2775); ++ v4l2_async_unregister_subdev(&priv->sd); ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SOC_CAMERA_OV2775 ++static const struct i2c_device_id ov2775_id[] = { ++ { "ov2775", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, ov2775_id); ++ ++static const struct of_device_id ov2775_of_ids[] = { ++ { .compatible = "ovti,ov2775", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, ov2775_of_ids); ++ ++static struct i2c_driver ov2775_i2c_driver = { ++ .driver = { ++ .name = "ov2775", ++ .of_match_table = ov2775_of_ids, ++ }, ++ .probe = ov2775_probe, ++ .remove = ov2775_remove, ++ .id_table = ov2775_id, ++}; ++ ++module_i2c_driver(ov2775_i2c_driver); ++ ++MODULE_DESCRIPTION("SoC Camera driver for OV2775"); +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_LICENSE("GPL"); ++#endif +diff --git a/drivers/media/i2c/soc_camera/ov2775.h b/drivers/media/i2c/soc_camera/ov2775.h +new file mode 100644 +index 0000000..7e1ee31 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/ov2775.h +@@ -0,0 +1,1841 @@ ++/* ++ * OmniVision OV2775 sensor camera wizard 1920x1080@30/BGGR/MIPI ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#define OV2775_DISPLAY_PATTERN_COLOR_BAR ++ ++#define OV2775_MAX_WIDTH 1920 ++#define OV2775_MAX_HEIGHT 1080 ++ ++#define OV2775_DELAY 0xffff ++#define OV2775_DT 0x2c /* MIPI Data Type RAW12 */ ++ ++struct ov2775_reg { ++ u16 reg; ++ u8 val; ++}; ++ ++/* wizard: MIPI 1920x1080 RAW12 Linear 30fps 600Mbps XCLK=25MHz */ ++static const struct ov2775_reg ov2775_regs_wizard[] = { ++{0x3013, 0x01}, // s/w reset ++{OV2775_DELAY, 10}, // Wait 10ms ++{0x3000, 0x03}, ++{0x3001, 0x18}, ++{0x3002, 0x01}, ++{0x3003, 0x01}, ++{0x3004, 0x03}, ++{0x3005, 0x1c}, ++{0x3006, 0x00}, ++{0x3007, 0x07}, ++{0x3008, 0x01}, ++{0x3009, 0x00}, ++{0x300c, 0x6c}, ++{0x300e, 0x80}, ++{0x300f, 0x00}, ++{0x3012, 0x00}, ++{0x3013, 0x00}, ++{0x3014, 0x44}, ++{0x3015, 0x00}, ++{0x3017, 0x00}, ++{0x3018, 0x00}, ++{0x3019, 0x00}, ++{0x301a, 0x00}, ++{0x301b, 0x01}, ++{0x301e, 0x17}, ++{0x301f, 0xe1}, ++{0x3030, 0x02}, ++{0x3031, 0x72}, ++{0x3032, 0xf0}, ++{0x3033, 0x30}, ++{0x3034, 0x3f}, ++{0x3035, 0x5f}, ++{0x3036, 0x02}, ++{0x3037, 0x9f}, ++{0x3038, 0x04}, ++{0x3039, 0xb7}, ++{0x303a, 0x04}, ++{0x303b, 0x07}, ++{0x303c, 0xf0}, ++{0x303d, 0x00}, ++{0x303e, 0x0b}, ++{0x303f, 0xe3}, ++{0x3040, 0xf3}, ++{0x3041, 0x29}, ++{0x3042, 0xf6}, ++{0x3043, 0x65}, ++{0x3044, 0x06}, ++{0x3045, 0x0f}, ++{0x3046, 0x59}, ++{0x3047, 0x07}, ++{0x3048, 0x82}, ++{0x3049, 0xcf}, ++{0x304a, 0x12}, ++{0x304b, 0x40}, ++{0x304c, 0x33}, ++{0x304d, 0xa4}, ++{0x304e, 0x0b}, ++{0x304f, 0x3d}, ++{0x3050, 0x10}, ++{0x3060, 0x00}, ++{0x3061, 0x64}, ++{0x3062, 0x00}, ++{0x3063, 0xe4}, ++{0x3066, 0x80}, ++{0x3080, 0x00}, ++{0x3081, 0x00}, ++{0x3082, 0x01}, ++{0x3083, 0xe3}, ++{0x3084, 0x06}, ++{0x3085, 0x00}, ++{0x3086, 0x10}, ++{0x3087, 0x10}, ++{0x3089, 0x00}, ++{0x308a, 0x01}, ++{0x3093, 0x00}, ++{0x30a0, 0x00}, ++{0x30a1, 0x00}, ++{0x30a2, 0x00}, ++{0x30a3, 0x00}, ++{0x30a4, 0x07}, ++{0x30a5, 0x8f}, ++{0x30a6, 0x04}, ++{0x30a7, 0x47}, ++{0x30a8, 0x00}, ++{0x30a9, 0x00}, ++{0x30aa, 0x00}, ++{0x30ab, 0x00}, ++{0x30ac, 0x07}, ++{0x30ad, 0x90}, ++{0x30ae, 0x04}, ++{0x30af, 0x48}, ++{0x30b0, 0x04}, ++{0x30b1, 0x7e}, ++{0x30b2, 0x04}, ++{0x30b3, 0x65}, ++{0x30b4, 0x00}, ++{0x30b5, 0x00}, ++{0x30b6, 0x00}, ++{0x30b7, 0x10}, ++{0x30b8, 0x00}, ++{0x30b9, 0x02}, ++{0x30ba, 0x10}, ++{0x30bb, 0x00}, ++{0x30bc, 0x00}, ++{0x30bd, 0x03}, ++{0x30be, 0x5c}, ++{0x30bf, 0x00}, ++{0x30c0, 0x01}, ++{0x30c1, 0x00}, ++{0x30c2, 0x20}, ++{0x30c3, 0x00}, ++{0x30c4, 0x4a}, ++{0x30c5, 0x00}, ++{0x30c7, 0x00}, ++{0x30c8, 0x00}, ++{0x30d1, 0x00}, ++{0x30d2, 0x00}, ++{0x30d3, 0x80}, ++{0x30d4, 0x00}, ++{0x30d9, 0x09}, ++{0x30da, 0x64}, ++{0x30dd, 0x00}, ++{0x30de, 0x16}, ++{0x30df, 0x00}, ++{0x30e0, 0x17}, ++{0x30e1, 0x00}, ++{0x30e2, 0x18}, ++{0x30e3, 0x10}, ++{0x30e4, 0x04}, ++{0x30e5, 0x00}, ++{0x30e6, 0x00}, ++{0x30e7, 0x00}, ++{0x30e8, 0x00}, ++{0x30e9, 0x00}, ++{0x30ea, 0x00}, ++{0x30eb, 0x00}, ++{0x30ec, 0x00}, ++{0x30ed, 0x00}, ++{0x3101, 0x00}, ++{0x3102, 0x00}, ++{0x3103, 0x00}, ++{0x3104, 0x00}, ++{0x3105, 0x8c}, ++{0x3106, 0x87}, ++{0x3107, 0xc0}, ++{0x3108, 0x9d}, ++{0x3109, 0x8d}, ++{0x310a, 0x8d}, ++{0x310b, 0x6a}, ++{0x310c, 0x3a}, ++{0x310d, 0x5a}, ++{0x310e, 0x00}, ++{0x3120, 0x00}, ++{0x3121, 0x00}, ++{0x3122, 0x00}, ++{0x3123, 0xf0}, ++{0x3124, 0x00}, ++{0x3125, 0x70}, ++{0x3126, 0x1f}, ++{0x3127, 0x0f}, ++{0x3128, 0x00}, ++{0x3129, 0x3a}, ++{0x312a, 0x02}, ++{0x312b, 0x0f}, ++{0x312c, 0x00}, ++{0x312d, 0x0f}, ++{0x312e, 0x1d}, ++{0x312f, 0x00}, ++{0x3130, 0x00}, ++{0x3131, 0x00}, ++{0x3132, 0x00}, ++{0x3140, 0x0a}, ++{0x3141, 0x03}, ++{0x3142, 0x00}, ++{0x3143, 0x00}, ++{0x3144, 0x00}, ++{0x3145, 0x00}, ++{0x3146, 0x00}, ++{0x3147, 0x00}, ++{0x3148, 0x00}, ++{0x3149, 0x00}, ++{0x314a, 0x00}, ++{0x314b, 0x00}, ++{0x314c, 0x00}, ++{0x314d, 0x00}, ++{0x314e, 0x1c}, ++{0x314f, 0xff}, ++{0x3150, 0xff}, ++{0x3151, 0xff}, ++{0x3152, 0x10}, ++{0x3153, 0x10}, ++{0x3154, 0x10}, ++{0x3155, 0x00}, ++{0x3156, 0x03}, ++{0x3157, 0x00}, ++{0x3158, 0x0f}, ++{0x3159, 0xff}, ++{0x315a, 0x01}, ++{0x315b, 0x00}, ++{0x315c, 0x01}, ++{0x315d, 0x00}, ++{0x315e, 0x01}, ++{0x315f, 0x00}, ++{0x3160, 0x00}, ++{0x3161, 0x40}, ++{0x3162, 0x00}, ++{0x3163, 0x40}, ++{0x3164, 0x00}, ++{0x3165, 0x40}, ++{0x3190, 0x08}, ++{0x3191, 0x99}, ++{0x3193, 0x08}, ++{0x3194, 0x13}, ++{0x3195, 0x33}, ++{0x3196, 0x00}, ++{0x3197, 0x10}, ++{0x3198, 0x00}, ++{0x3199, 0x7f}, ++{0x319a, 0x80}, ++{0x319b, 0xff}, ++{0x319c, 0x80}, ++{0x319d, 0xbf}, ++{0x319e, 0xc0}, ++{0x319f, 0xff}, ++{0x31a0, 0x24}, ++{0x31a1, 0x55}, ++{0x31a2, 0x00}, ++{0x31a3, 0x00}, ++{0x31a6, 0x00}, ++{0x31a7, 0x00}, ++{0x31b0, 0x00}, ++{0x31b1, 0x00}, ++{0x31b2, 0x02}, ++{0x31b3, 0x00}, ++{0x31b4, 0x00}, ++{0x31b5, 0x01}, ++{0x31b6, 0x00}, ++{0x31b7, 0x00}, ++{0x31b8, 0x00}, ++{0x31b9, 0x00}, ++{0x31ba, 0x00}, ++{0x31d0, 0x3c}, ++{0x31d1, 0x34}, ++{0x31d2, 0x3c}, ++{0x31d3, 0x00}, ++{0x31d4, 0x2d}, ++{0x31d5, 0x00}, ++{0x31d6, 0x01}, ++{0x31d7, 0x06}, ++{0x31d8, 0x00}, ++{0x31d9, 0x64}, ++{0x31da, 0x00}, ++{0x31db, 0x30}, ++{0x31dc, 0x04}, ++{0x31dd, 0x69}, ++{0x31de, 0x0a}, ++{0x31df, 0x3c}, ++{0x31e0, 0x04}, ++{0x31e1, 0x32}, ++{0x31e2, 0x00}, ++{0x31e3, 0x00}, ++{0x31e4, 0x08}, ++{0x31e5, 0x80}, ++{0x31e6, 0x00}, ++{0x31e7, OV2775_DT}, ++{0x31e8, 0x6c}, ++{0x31e9, 0xac}, ++{0x31ea, 0xec}, ++{0x31eb, 0x3f}, ++{0x31ec, 0x0f}, ++{0x31ed, 0x20}, ++{0x31ee, 0x04}, ++{0x31ef, 0x48}, ++{0x31f0, 0x07}, ++{0x31f1, 0x90}, ++{0x31f2, 0x04}, ++{0x31f3, 0x48}, ++{0x31f4, 0x07}, ++{0x31f5, 0x90}, ++{0x31f6, 0x04}, ++{0x31f7, 0x48}, ++{0x31f8, 0x07}, ++{0x31f9, 0x90}, ++{0x31fa, 0x04}, ++{0x31fb, 0x48}, ++{0x31fd, 0xcb}, ++{0x31fe, 0x0f}, ++{0x31ff, 0x03}, ++{0x3200, 0x00}, ++{0x3201, 0xff}, ++{0x3202, 0x00}, ++{0x3203, 0xff}, ++{0x3204, 0xff}, ++{0x3205, 0xff}, ++{0x3206, 0xff}, ++{0x3207, 0xff}, ++{0x3208, 0xff}, ++{0x3209, 0xff}, ++{0x320a, 0xff}, ++{0x320b, 0x1b}, ++{0x320c, 0x1f}, ++{0x320d, 0x1e}, ++{0x320e, 0x30}, ++{0x320f, 0x2d}, ++{0x3210, 0x2c}, ++{0x3211, 0x2b}, ++{0x3212, 0x2a}, ++{0x3213, 0x24}, ++{0x3214, 0x22}, ++{0x3215, 0x00}, ++{0x3216, 0x04}, ++{0x3217, OV2775_DT}, ++{0x3218, 0x6c}, ++{0x3219, 0xac}, ++{0x321a, 0xec}, ++{0x321b, 0x00}, ++{0x3230, 0x3a}, ++{0x3231, 0x00}, ++{0x3232, 0x80}, ++{0x3233, 0x00}, ++{0x3234, 0x10}, ++{0x3235, 0xaa}, ++{0x3236, 0x55}, ++{0x3237, 0x99}, ++{0x3238, 0x66}, ++{0x3239, 0x08}, ++{0x323a, 0x88}, ++{0x323b, 0x00}, ++{0x323c, 0x00}, ++{0x323d, 0x03}, ++{0x3250, 0x33}, ++{0x3251, 0x00}, ++{0x3252, 0x20}, ++#ifdef OV2775_DISPLAY_PATTERN_COLOR_BAR ++{0x3253, 0xC0}, ++#else ++{0x3253, 0x00}, ++#endif ++{0x3254, 0x00}, ++{0x3255, 0x01}, ++{0x3256, 0x00}, ++{0x3257, 0x00}, ++{0x3258, 0x00}, ++{0x3270, 0x01}, ++{0x3271, 0x60}, ++{0x3272, 0xc0}, ++{0x3273, 0x00}, ++{0x3274, 0x80}, ++{0x3275, 0x40}, ++{0x3276, 0x02}, ++{0x3277, 0x08}, ++{0x3278, 0x10}, ++{0x3279, 0x04}, ++{0x327a, 0x00}, ++{0x327b, 0x03}, ++{0x327c, 0x10}, ++{0x327d, 0x60}, ++{0x327e, 0xc0}, ++{0x327f, 0x06}, ++{0x3288, 0x10}, ++{0x3289, 0x00}, ++{0x328a, 0x08}, ++{0x328b, 0x00}, ++{0x328c, 0x04}, ++{0x328d, 0x00}, ++{0x328e, 0x02}, ++{0x328f, 0x00}, ++{0x3290, 0x20}, ++{0x3291, 0x00}, ++{0x3292, 0x10}, ++{0x3293, 0x00}, ++{0x3294, 0x08}, ++{0x3295, 0x00}, ++{0x3296, 0x04}, ++{0x3297, 0x00}, ++{0x3298, 0x40}, ++{0x3299, 0x00}, ++{0x329a, 0x20}, ++{0x329b, 0x00}, ++{0x329c, 0x10}, ++{0x329d, 0x00}, ++{0x329e, 0x08}, ++{0x329f, 0x00}, ++{0x32a0, 0x7f}, ++{0x32a1, 0xff}, ++{0x32a2, 0x40}, ++{0x32a3, 0x00}, ++{0x32a4, 0x20}, ++{0x32a5, 0x00}, ++{0x32a6, 0x10}, ++{0x32a7, 0x00}, ++{0x32a8, 0x00}, ++{0x32a9, 0x00}, ++{0x32aa, 0x00}, ++{0x32ab, 0x00}, ++{0x32ac, 0x00}, ++{0x32ad, 0x00}, ++{0x32ae, 0x00}, ++{0x32af, 0x00}, ++{0x32b0, 0x00}, ++{0x32b1, 0x00}, ++{0x32b2, 0x00}, ++{0x32b3, 0x00}, ++{0x32b4, 0x00}, ++{0x32b5, 0x00}, ++{0x32b6, 0x00}, ++{0x32b7, 0x00}, ++{0x32b8, 0x00}, ++{0x32b9, 0x00}, ++{0x32ba, 0x00}, ++{0x32bb, 0x00}, ++{0x32bc, 0x00}, ++{0x32bd, 0x00}, ++{0x32be, 0x00}, ++{0x32bf, 0x00}, ++{0x32c0, 0x00}, ++{0x32c1, 0x00}, ++{0x32c2, 0x00}, ++{0x32c3, 0x00}, ++{0x32c4, 0x00}, ++{0x32c5, 0x00}, ++{0x32c6, 0x00}, ++{0x32c7, 0x00}, ++{0x32c8, 0x87}, ++{0x32c9, 0x00}, ++{0x3330, 0x03}, ++{0x3331, 0xc8}, ++{0x3332, 0x02}, ++{0x3333, 0x24}, ++{0x3334, 0x00}, ++{0x3335, 0x00}, ++{0x3336, 0x00}, ++{0x3337, 0x00}, ++{0x3338, 0x03}, ++{0x3339, 0xc8}, ++{0x333a, 0x02}, ++{0x333b, 0x24}, ++{0x333c, 0x00}, ++{0x333d, 0x00}, ++{0x333e, 0x00}, ++{0x333f, 0x00}, ++{0x3340, 0x03}, ++{0x3341, 0xc8}, ++{0x3342, 0x02}, ++{0x3343, 0x24}, ++{0x3344, 0x00}, ++{0x3345, 0x00}, ++{0x3346, 0x00}, ++{0x3347, 0x00}, ++{0x3348, 0x40}, ++{0x3349, 0x00}, ++{0x334a, 0x00}, ++{0x334b, 0x00}, ++{0x334c, 0x00}, ++{0x334d, 0x00}, ++{0x334e, 0x80}, ++{0x3360, 0x01}, ++{0x3361, 0x00}, ++{0x3362, 0x01}, ++{0x3363, 0x00}, ++{0x3364, 0x01}, ++{0x3365, 0x00}, ++{0x3366, 0x01}, ++{0x3367, 0x00}, ++{0x3368, 0x01}, ++{0x3369, 0x00}, ++{0x336a, 0x01}, ++{0x336b, 0x00}, ++{0x336c, 0x01}, ++{0x336d, 0x00}, ++{0x336e, 0x01}, ++{0x336f, 0x00}, ++{0x3370, 0x01}, ++{0x3371, 0x00}, ++{0x3372, 0x01}, ++{0x3373, 0x00}, ++{0x3374, 0x01}, ++{0x3375, 0x00}, ++{0x3376, 0x01}, ++{0x3377, 0x00}, ++{0x3378, 0x00}, ++{0x3379, 0x00}, ++{0x337a, 0x00}, ++{0x337b, 0x00}, ++{0x337c, 0x00}, ++{0x337d, 0x00}, ++{0x337e, 0x00}, ++{0x337f, 0x00}, ++{0x3380, 0x00}, ++{0x3381, 0x00}, ++{0x3382, 0x00}, ++{0x3383, 0x00}, ++{0x3384, 0x00}, ++{0x3385, 0x00}, ++{0x3386, 0x00}, ++{0x3387, 0x00}, ++{0x3388, 0x00}, ++{0x3389, 0x00}, ++{0x338a, 0x00}, ++{0x338b, 0x00}, ++{0x338c, 0x00}, ++{0x338d, 0x00}, ++{0x338e, 0x00}, ++{0x338f, 0x00}, ++{0x3390, 0x00}, ++{0x3391, 0x00}, ++{0x3392, 0x00}, ++{0x3393, 0x00}, ++{0x3394, 0x00}, ++{0x3395, 0x00}, ++{0x3396, 0x00}, ++{0x3397, 0x00}, ++{0x3398, 0x00}, ++{0x3399, 0x00}, ++{0x339a, 0x00}, ++{0x339b, 0x00}, ++{0x33b0, 0x00}, ++{0x33b1, 0x50}, ++{0x33b2, 0x01}, ++{0x33b3, 0xff}, ++{0x33b4, 0xe0}, ++{0x33b5, 0x6b}, ++{0x33b6, 0x00}, ++{0x33b7, 0x00}, ++{0x33b8, 0x00}, ++{0x33b9, 0x00}, ++{0x33ba, 0x00}, ++{0x33bb, 0x1f}, ++{0x33bc, 0x01}, ++{0x33bd, 0x01}, ++{0x33be, 0x01}, ++{0x33bf, 0x01}, ++{0x33c0, 0x00}, ++{0x33c1, 0x00}, ++{0x33c2, 0x00}, ++{0x33c3, 0x00}, ++{0x33e0, 0x14}, ++{0x33e1, 0x0f}, ++{0x33e2, 0x02}, ++{0x33e3, 0x01}, ++{0x33e4, 0x01}, ++{0x33e5, 0x01}, ++{0x33e6, 0x00}, ++{0x33e7, 0x04}, ++{0x33e8, 0x0c}, ++{0x33e9, 0x02}, ++{0x33ea, 0x02}, ++{0x33eb, 0x02}, ++{0x33ec, 0x03}, ++{0x33ed, 0x01}, ++{0x33ee, 0x02}, ++{0x33ef, 0x08}, ++{0x33f0, 0x08}, ++{0x33f1, 0x04}, ++{0x33f2, 0x04}, ++{0x33f3, 0x00}, ++{0x33f4, 0x03}, ++{0x33f5, 0x14}, ++{0x33f6, 0x0f}, ++{0x33f7, 0x02}, ++{0x33f8, 0x01}, ++{0x33f9, 0x01}, ++{0x33fa, 0x01}, ++{0x33fb, 0x00}, ++{0x33fc, 0x04}, ++{0x33fd, 0x0c}, ++{0x33fe, 0x02}, ++{0x33ff, 0x02}, ++{0x3400, 0x02}, ++{0x3401, 0x03}, ++{0x3402, 0x01}, ++{0x3403, 0x02}, ++{0x3404, 0x08}, ++{0x3405, 0x08}, ++{0x3406, 0x04}, ++{0x3407, 0x04}, ++{0x3408, 0x00}, ++{0x3409, 0x03}, ++{0x340a, 0x14}, ++{0x340b, 0x0f}, ++{0x340c, 0x04}, ++{0x340d, 0x02}, ++{0x340e, 0x01}, ++{0x340f, 0x01}, ++{0x3410, 0x00}, ++{0x3411, 0x04}, ++{0x3412, 0x0c}, ++{0x3413, 0x00}, ++{0x3414, 0x01}, ++{0x3415, 0x02}, ++{0x3416, 0x03}, ++{0x3417, 0x02}, ++{0x3418, 0x05}, ++{0x3419, 0x0a}, ++{0x341a, 0x08}, ++{0x341b, 0x04}, ++{0x341c, 0x04}, ++{0x341d, 0x00}, ++{0x341e, 0x03}, ++{0x3440, 0x00}, ++{0x3441, 0x00}, ++{0x3442, 0x00}, ++{0x3443, 0x00}, ++{0x3444, 0x02}, ++{0x3445, 0xf0}, ++{0x3446, 0x02}, ++{0x3447, 0x08}, ++{0x3448, 0x00}, ++{0x3460, 0x40}, ++{0x3461, 0x40}, ++{0x3462, 0x40}, ++{0x3463, 0x40}, ++{0x3464, 0x03}, ++{0x3465, 0x01}, ++{0x3466, 0x01}, ++{0x3467, 0x02}, ++{0x3468, 0x30}, ++{0x3469, 0x00}, ++{0x346a, 0x33}, ++{0x346b, 0xbf}, ++{0x3480, 0x40}, ++{0x3481, 0x00}, ++{0x3482, 0x00}, ++{0x3483, 0x00}, ++{0x3484, 0x0d}, ++{0x3485, 0x00}, ++{0x3486, 0x00}, ++{0x3487, 0x00}, ++{0x3488, 0x00}, ++{0x3489, 0x00}, ++{0x348a, 0x00}, ++{0x348b, 0x04}, ++{0x348c, 0x00}, ++{0x348d, 0x01}, ++{0x348f, 0x01}, ++{0x3030, 0x0a}, ++{0x3030, 0x02}, ++{0x7000, 0x58}, ++{0x7001, 0x7a}, ++{0x7002, 0x1a}, ++{0x7003, 0xc1}, ++{0x7004, 0x03}, ++{0x7005, 0xda}, ++{0x7006, 0xbd}, ++{0x7007, 0x03}, ++{0x7008, 0xbd}, ++{0x7009, 0x06}, ++{0x700a, 0xe6}, ++{0x700b, 0xec}, ++{0x700c, 0xbc}, ++{0x700d, 0xff}, ++{0x700e, 0xbc}, ++{0x700f, 0x73}, ++{0x7010, 0xda}, ++{0x7011, 0x72}, ++{0x7012, 0x76}, ++{0x7013, 0xb6}, ++{0x7014, 0xee}, ++{0x7015, 0xcf}, ++{0x7016, 0xac}, ++{0x7017, 0xd0}, ++{0x7018, 0xac}, ++{0x7019, 0xd1}, ++{0x701a, 0x50}, ++{0x701b, 0xac}, ++{0x701c, 0xd2}, ++{0x701d, 0xbc}, ++{0x701e, 0x2e}, ++{0x701f, 0xb4}, ++{0x7020, 0x00}, ++{0x7021, 0xdc}, ++{0x7022, 0xdf}, ++{0x7023, 0xb0}, ++{0x7024, 0x6e}, ++{0x7025, 0xbd}, ++{0x7026, 0x01}, ++{0x7027, 0xd7}, ++{0x7028, 0xed}, ++{0x7029, 0xe1}, ++{0x702a, 0x36}, ++{0x702b, 0x30}, ++{0x702c, 0xd3}, ++{0x702d, 0x2e}, ++{0x702e, 0x54}, ++{0x702f, 0x46}, ++{0x7030, 0xbc}, ++{0x7031, 0x22}, ++{0x7032, 0x66}, ++{0x7033, 0xbc}, ++{0x7034, 0x24}, ++{0x7035, 0x2c}, ++{0x7036, 0x28}, ++{0x7037, 0xbc}, ++{0x7038, 0x3c}, ++{0x7039, 0xa1}, ++{0x703a, 0xac}, ++{0x703b, 0xd8}, ++{0x703c, 0xd6}, ++{0x703d, 0xb4}, ++{0x703e, 0x04}, ++{0x703f, 0x46}, ++{0x7040, 0xb7}, ++{0x7041, 0x04}, ++{0x7042, 0xbe}, ++{0x7043, 0x08}, ++{0x7044, 0xc3}, ++{0x7045, 0xd9}, ++{0x7046, 0xad}, ++{0x7047, 0xc3}, ++{0x7048, 0xbc}, ++{0x7049, 0x19}, ++{0x704a, 0xc1}, ++{0x704b, 0x27}, ++{0x704c, 0xe7}, ++{0x704d, 0x00}, ++{0x704e, 0x50}, ++{0x704f, 0x20}, ++{0x7050, 0xb8}, ++{0x7051, 0x02}, ++{0x7052, 0xbc}, ++{0x7053, 0x17}, ++{0x7054, 0xdb}, ++{0x7055, 0xc7}, ++{0x7056, 0xb8}, ++{0x7057, 0x00}, ++{0x7058, 0x28}, ++{0x7059, 0x54}, ++{0x705a, 0xb4}, ++{0x705b, 0x14}, ++{0x705c, 0xab}, ++{0x705d, 0xbe}, ++{0x705e, 0x06}, ++{0x705f, 0xd8}, ++{0x7060, 0xd6}, ++{0x7061, 0x00}, ++{0x7062, 0xb4}, ++{0x7063, 0xc7}, ++{0x7064, 0x07}, ++{0x7065, 0xb9}, ++{0x7066, 0x05}, ++{0x7067, 0xee}, ++{0x7068, 0xe6}, ++{0x7069, 0xad}, ++{0x706a, 0xb4}, ++{0x706b, 0x26}, ++{0x706c, 0x19}, ++{0x706d, 0xc1}, ++{0x706e, 0x3a}, ++{0x706f, 0xc3}, ++{0x7070, 0xaf}, ++{0x7071, 0x00}, ++{0x7072, 0xc0}, ++{0x7073, 0x3c}, ++{0x7074, 0xc3}, ++{0x7075, 0xbe}, ++{0x7076, 0xe7}, ++{0x7077, 0x00}, ++{0x7078, 0x15}, ++{0x7079, 0xc2}, ++{0x707a, 0x40}, ++{0x707b, 0xc3}, ++{0x707c, 0xa4}, ++{0x707d, 0xc0}, ++{0x707e, 0x3c}, ++{0x707f, 0x00}, ++{0x7080, 0xb9}, ++{0x7081, 0x64}, ++{0x7082, 0x29}, ++{0x7083, 0x00}, ++{0x7084, 0xb8}, ++{0x7085, 0x12}, ++{0x7086, 0xbe}, ++{0x7087, 0x01}, ++{0x7088, 0xd0}, ++{0x7089, 0xbc}, ++{0x708a, 0x01}, ++{0x708b, 0xac}, ++{0x708c, 0x37}, ++{0x708d, 0xd2}, ++{0x708e, 0xac}, ++{0x708f, 0x45}, ++{0x7090, 0xad}, ++{0x7091, 0x28}, ++{0x7092, 0x00}, ++{0x7093, 0xb8}, ++{0x7094, 0x00}, ++{0x7095, 0xbc}, ++{0x7096, 0x01}, ++{0x7097, 0x36}, ++{0x7098, 0xd3}, ++{0x7099, 0x30}, ++{0x709a, 0x04}, ++{0x709b, 0xe0}, ++{0x709c, 0xd8}, ++{0x709d, 0xb4}, ++{0x709e, 0xe9}, ++{0x709f, 0x00}, ++{0x70a0, 0xbe}, ++{0x70a1, 0x05}, ++{0x70a2, 0x62}, ++{0x70a3, 0x07}, ++{0x70a4, 0xb9}, ++{0x70a5, 0x05}, ++{0x70a6, 0xad}, ++{0x70a7, 0xc3}, ++{0x70a8, 0xcf}, ++{0x70a9, 0x00}, ++{0x70aa, 0x15}, ++{0x70ab, 0xc2}, ++{0x70ac, 0x59}, ++{0x70ad, 0xc3}, ++{0x70ae, 0xc9}, ++{0x70af, 0xc0}, ++{0x70b0, 0x55}, ++{0x70b1, 0x00}, ++{0x70b2, 0x46}, ++{0x70b3, 0xa1}, ++{0x70b4, 0xb9}, ++{0x70b5, 0x64}, ++{0x70b6, 0x29}, ++{0x70b7, 0x00}, ++{0x70b8, 0xb8}, ++{0x70b9, 0x02}, ++{0x70ba, 0xbe}, ++{0x70bb, 0x02}, ++{0x70bc, 0xd0}, ++{0x70bd, 0xdc}, ++{0x70be, 0xac}, ++{0x70bf, 0xbc}, ++{0x70c0, 0x01}, ++{0x70c1, 0x37}, ++{0x70c2, 0xac}, ++{0x70c3, 0xd2}, ++{0x70c4, 0x45}, ++{0x70c5, 0xad}, ++{0x70c6, 0x28}, ++{0x70c7, 0x00}, ++{0x70c8, 0xb8}, ++{0x70c9, 0x00}, ++{0x70ca, 0xbc}, ++{0x70cb, 0x01}, ++{0x70cc, 0x36}, ++{0x70cd, 0x30}, ++{0x70ce, 0xe0}, ++{0x70cf, 0xd8}, ++{0x70d0, 0xb5}, ++{0x70d1, 0x0b}, ++{0x70d2, 0xd6}, ++{0x70d3, 0xbe}, ++{0x70d4, 0x07}, ++{0x70d5, 0x00}, ++{0x70d6, 0x62}, ++{0x70d7, 0x07}, ++{0x70d8, 0xb9}, ++{0x70d9, 0x05}, ++{0x70da, 0xad}, ++{0x70db, 0xc3}, ++{0x70dc, 0xcf}, ++{0x70dd, 0x46}, ++{0x70de, 0xcd}, ++{0x70df, 0x07}, ++{0x70e0, 0xcd}, ++{0x70e1, 0x00}, ++{0x70e2, 0xe3}, ++{0x70e3, 0x18}, ++{0x70e4, 0xc2}, ++{0x70e5, 0xa2}, ++{0x70e6, 0xb9}, ++{0x70e7, 0x64}, ++{0x70e8, 0xd1}, ++{0x70e9, 0xdd}, ++{0x70ea, 0xac}, ++{0x70eb, 0xcf}, ++{0x70ec, 0xdf}, ++{0x70ed, 0xb5}, ++{0x70ee, 0x19}, ++{0x70ef, 0x46}, ++{0x70f0, 0x50}, ++{0x70f1, 0xb6}, ++{0x70f2, 0xee}, ++{0x70f3, 0xe8}, ++{0x70f4, 0xe6}, ++{0x70f5, 0xbc}, ++{0x70f6, 0x31}, ++{0x70f7, 0xe1}, ++{0x70f8, 0x36}, ++{0x70f9, 0x30}, ++{0x70fa, 0xd3}, ++{0x70fb, 0x2e}, ++{0x70fc, 0x54}, ++{0x70fd, 0xbd}, ++{0x70fe, 0x03}, ++{0x70ff, 0xec}, ++{0x7100, 0x2c}, ++{0x7101, 0x50}, ++{0x7102, 0x20}, ++{0x7103, 0x04}, ++{0x7104, 0xb8}, ++{0x7105, 0x02}, ++{0x7106, 0xbc}, ++{0x7107, 0x18}, ++{0x7108, 0xc7}, ++{0x7109, 0xb8}, ++{0x710a, 0x00}, ++{0x710b, 0x28}, ++{0x710c, 0x54}, ++{0x710d, 0xbc}, ++{0x710e, 0x02}, ++{0x710f, 0xb4}, ++{0x7110, 0xda}, ++{0x7111, 0xbe}, ++{0x7112, 0x04}, ++{0x7113, 0xd6}, ++{0x7114, 0xd8}, ++{0x7115, 0xab}, ++{0x7116, 0x00}, ++{0x7117, 0x62}, ++{0x7118, 0x07}, ++{0x7119, 0xb9}, ++{0x711a, 0x05}, ++{0x711b, 0xad}, ++{0x711c, 0xc3}, ++{0x711d, 0xbc}, ++{0x711e, 0xe7}, ++{0x711f, 0xb9}, ++{0x7120, 0x64}, ++{0x7121, 0x29}, ++{0x7122, 0x00}, ++{0x7123, 0xb8}, ++{0x7124, 0x02}, ++{0x7125, 0xbe}, ++{0x7126, 0x00}, ++{0x7127, 0x45}, ++{0x7128, 0xad}, ++{0x7129, 0xe2}, ++{0x712a, 0x28}, ++{0x712b, 0x00}, ++{0x712c, 0xb8}, ++{0x712d, 0x00}, ++{0x712e, 0xe0}, ++{0x712f, 0xd8}, ++{0x7130, 0xb4}, ++{0x7131, 0xe9}, ++{0x7132, 0xbe}, ++{0x7133, 0x03}, ++{0x7134, 0x00}, ++{0x7135, 0x30}, ++{0x7136, 0x62}, ++{0x7137, 0x07}, ++{0x7138, 0xb9}, ++{0x7139, 0x05}, ++{0x713a, 0xad}, ++{0x713b, 0xc3}, ++{0x713c, 0xcf}, ++{0x713d, 0x42}, ++{0x713e, 0xe4}, ++{0x713f, 0xcd}, ++{0x7140, 0x07}, ++{0x7141, 0xcd}, ++{0x7142, 0x00}, ++{0x7143, 0x00}, ++{0x7144, 0x17}, ++{0x7145, 0xc2}, ++{0x7146, 0xbb}, ++{0x7147, 0xde}, ++{0x7148, 0xcf}, ++{0x7149, 0xdf}, ++{0x714a, 0xac}, ++{0x714b, 0xd1}, ++{0x714c, 0x44}, ++{0x714d, 0xac}, ++{0x714e, 0xb9}, ++{0x714f, 0x76}, ++{0x7150, 0xb8}, ++{0x7151, 0x08}, ++{0x7152, 0xb6}, ++{0x7153, 0xfe}, ++{0x7154, 0xb4}, ++{0x7155, 0xca}, ++{0x7156, 0xd6}, ++{0x7157, 0xd8}, ++{0x7158, 0xab}, ++{0x7159, 0x00}, ++{0x715a, 0xe1}, ++{0x715b, 0x36}, ++{0x715c, 0x30}, ++{0x715d, 0xd3}, ++{0x715e, 0xbc}, ++{0x715f, 0x29}, ++{0x7160, 0xb4}, ++{0x7161, 0x1f}, ++{0x7162, 0xaa}, ++{0x7163, 0xbd}, ++{0x7164, 0x01}, ++{0x7165, 0xb8}, ++{0x7166, 0x0c}, ++{0x7167, 0x45}, ++{0x7168, 0xa4}, ++{0x7169, 0xbd}, ++{0x716a, 0x03}, ++{0x716b, 0xec}, ++{0x716c, 0xbc}, ++{0x716d, 0x3d}, ++{0x716e, 0xc3}, ++{0x716f, 0xcf}, ++{0x7170, 0x42}, ++{0x7171, 0xb8}, ++{0x7172, 0x00}, ++{0x7173, 0xe4}, ++{0x7174, 0xd5}, ++{0x7175, 0x00}, ++{0x7176, 0xb6}, ++{0x7177, 0x00}, ++{0x7178, 0x74}, ++{0x7179, 0xbd}, ++{0x717a, 0x03}, ++{0x717b, 0x40}, ++{0x717c, 0xb5}, ++{0x717d, 0x39}, ++{0x717e, 0x58}, ++{0x717f, 0xdd}, ++{0x7180, 0x19}, ++{0x7181, 0xc1}, ++{0x7182, 0xc8}, ++{0x7183, 0xbd}, ++{0x7184, 0x06}, ++{0x7185, 0x17}, ++{0x7186, 0xc1}, ++{0x7187, 0xc6}, ++{0x7188, 0xe8}, ++{0x7189, 0x00}, ++{0x718a, 0xc0}, ++{0x718b, 0xc8}, ++{0x718c, 0xe6}, ++{0x718d, 0x95}, ++{0x718e, 0x15}, ++{0x718f, 0x00}, ++{0x7190, 0xbc}, ++{0x7191, 0x19}, ++{0x7192, 0xb9}, ++{0x7193, 0xf6}, ++{0x7194, 0x14}, ++{0x7195, 0xc1}, ++{0x7196, 0xd0}, ++{0x7197, 0xd1}, ++{0x7198, 0xac}, ++{0x7199, 0x37}, ++{0x719a, 0xbc}, ++{0x719b, 0x35}, ++{0x719c, 0x36}, ++{0x719d, 0x30}, ++{0x719e, 0xe1}, ++{0x719f, 0xd3}, ++{0x71a0, 0x7a}, ++{0x71a1, 0xb6}, ++{0x71a2, 0x0c}, ++{0x71a3, 0xff}, ++{0x71a4, 0xb4}, ++{0x71a5, 0xc7}, ++{0x71a6, 0xd9}, ++{0x71a7, 0x00}, ++{0x71a8, 0xbd}, ++{0x71a9, 0x01}, ++{0x71aa, 0x56}, ++{0x71ab, 0xc0}, ++{0x71ac, 0xda}, ++{0x71ad, 0xb4}, ++{0x71ae, 0x1f}, ++{0x71af, 0x56}, ++{0x71b0, 0xaa}, ++{0x71b1, 0xbc}, ++{0x71b2, 0x08}, ++{0x71b3, 0x00}, ++{0x71b4, 0x57}, ++{0x71b5, 0xe8}, ++{0x71b6, 0xb5}, ++{0x71b7, 0x36}, ++{0x71b8, 0x00}, ++{0x71b9, 0x54}, ++{0x71ba, 0xe7}, ++{0x71bb, 0xc8}, ++{0x71bc, 0xb4}, ++{0x71bd, 0x1f}, ++{0x71be, 0x56}, ++{0x71bf, 0xaa}, ++{0x71c0, 0xbc}, ++{0x71c1, 0x08}, ++{0x71c2, 0x57}, ++{0x71c3, 0x00}, ++{0x71c4, 0xb5}, ++{0x71c5, 0x36}, ++{0x71c6, 0x00}, ++{0x71c7, 0x54}, ++{0x71c8, 0xc8}, ++{0x71c9, 0xb5}, ++{0x71ca, 0x18}, ++{0x71cb, 0xd9}, ++{0x71cc, 0x00}, ++{0x71cd, 0xbd}, ++{0x71ce, 0x01}, ++{0x71cf, 0x56}, ++{0x71d0, 0x08}, ++{0x71d1, 0x57}, ++{0x71d2, 0xe8}, ++{0x71d3, 0xb4}, ++{0x71d4, 0x42}, ++{0x71d5, 0x00}, ++{0x71d6, 0x54}, ++{0x71d7, 0xe7}, ++{0x71d8, 0xc8}, ++{0x71d9, 0xab}, ++{0x71da, 0x00}, ++{0x71db, 0x66}, ++{0x71dc, 0x62}, ++{0x71dd, 0x06}, ++{0x71de, 0x74}, ++{0x71df, 0xb9}, ++{0x71e0, 0x05}, ++{0x71e1, 0xb7}, ++{0x71e2, 0x14}, ++{0x71e3, 0x0e}, ++{0x71e4, 0xb7}, ++{0x71e5, 0x04}, ++{0x71e6, 0xc8}, ++{0x7600, 0x04}, ++{0x7601, 0x80}, ++{0x7602, 0x07}, ++{0x7603, 0x44}, ++{0x7604, 0x05}, ++{0x7605, 0x33}, ++{0x7606, 0x0f}, ++{0x7607, 0x00}, ++{0x7608, 0x07}, ++{0x7609, 0x40}, ++{0x760a, 0x04}, ++{0x760b, 0xe5}, ++{0x760c, 0x06}, ++{0x760d, 0x50}, ++{0x760e, 0x04}, ++{0x760f, 0xe4}, ++{0x7610, 0x00}, ++{0x7611, 0x00}, ++{0x7612, 0x06}, ++{0x7613, 0x5c}, ++{0x7614, 0x00}, ++{0x7615, 0x0f}, ++{0x7616, 0x06}, ++{0x7617, 0x1c}, ++{0x7618, 0x00}, ++{0x7619, 0x02}, ++{0x761a, 0x06}, ++{0x761b, 0xa2}, ++{0x761c, 0x00}, ++{0x761d, 0x01}, ++{0x761e, 0x06}, ++{0x761f, 0xae}, ++{0x7620, 0x00}, ++{0x7621, 0x0e}, ++{0x7622, 0x05}, ++{0x7623, 0x30}, ++{0x7624, 0x07}, ++{0x7625, 0x00}, ++{0x7626, 0x0f}, ++{0x7627, 0x00}, ++{0x7628, 0x04}, ++{0x7629, 0xe5}, ++{0x762a, 0x05}, ++{0x762b, 0x33}, ++{0x762c, 0x06}, ++{0x762d, 0x12}, ++{0x762e, 0x00}, ++{0x762f, 0x01}, ++{0x7630, 0x06}, ++{0x7631, 0x52}, ++{0x7632, 0x00}, ++{0x7633, 0x01}, ++{0x7634, 0x06}, ++{0x7635, 0x5e}, ++{0x7636, 0x04}, ++{0x7637, 0xe4}, ++{0x7638, 0x00}, ++{0x7639, 0x01}, ++{0x763a, 0x05}, ++{0x763b, 0x30}, ++{0x763c, 0x0f}, ++{0x763d, 0x00}, ++{0x763e, 0x06}, ++{0x763f, 0xa6}, ++{0x7640, 0x00}, ++{0x7641, 0x02}, ++{0x7642, 0x06}, ++{0x7643, 0x26}, ++{0x7644, 0x00}, ++{0x7645, 0x02}, ++{0x7646, 0x05}, ++{0x7647, 0x33}, ++{0x7648, 0x06}, ++{0x7649, 0x20}, ++{0x764a, 0x0f}, ++{0x764b, 0x00}, ++{0x764c, 0x06}, ++{0x764d, 0x56}, ++{0x764e, 0x00}, ++{0x764f, 0x02}, ++{0x7650, 0x06}, ++{0x7651, 0x16}, ++{0x7652, 0x05}, ++{0x7653, 0x33}, ++{0x7654, 0x06}, ++{0x7655, 0x10}, ++{0x7656, 0x0f}, ++{0x7657, 0x00}, ++{0x7658, 0x06}, ++{0x7659, 0x10}, ++{0x765a, 0x0f}, ++{0x765b, 0x00}, ++{0x765c, 0x06}, ++{0x765d, 0x20}, ++{0x765e, 0x0f}, ++{0x765f, 0x00}, ++{0x7660, 0x00}, ++{0x7661, 0x00}, ++{0x7662, 0x00}, ++{0x7663, 0x02}, ++{0x7664, 0x04}, ++{0x7665, 0xe5}, ++{0x7666, 0x04}, ++{0x7667, 0xe4}, ++{0x7668, 0x0f}, ++{0x7669, 0x00}, ++{0x766a, 0x00}, ++{0x766b, 0x00}, ++{0x766c, 0x00}, ++{0x766d, 0x01}, ++{0x766e, 0x04}, ++{0x766f, 0xe5}, ++{0x7670, 0x04}, ++{0x7671, 0xe4}, ++{0x7672, 0x0f}, ++{0x7673, 0x00}, ++{0x7674, 0x00}, ++{0x7675, 0x02}, ++{0x7676, 0x04}, ++{0x7677, 0xe4}, ++{0x7678, 0x00}, ++{0x7679, 0x02}, ++{0x767a, 0x04}, ++{0x767b, 0xc4}, ++{0x767c, 0x00}, ++{0x767d, 0x02}, ++{0x767e, 0x04}, ++{0x767f, 0xc4}, ++{0x7680, 0x05}, ++{0x7681, 0x83}, ++{0x7682, 0x0f}, ++{0x7683, 0x00}, ++{0x7684, 0x00}, ++{0x7685, 0x02}, ++{0x7686, 0x04}, ++{0x7687, 0xe4}, ++{0x7688, 0x00}, ++{0x7689, 0x02}, ++{0x768a, 0x04}, ++{0x768b, 0xc4}, ++{0x768c, 0x00}, ++{0x768d, 0x02}, ++{0x768e, 0x04}, ++{0x768f, 0xc4}, ++{0x7690, 0x05}, ++{0x7691, 0x83}, ++{0x7692, 0x03}, ++{0x7693, 0x0b}, ++{0x7694, 0x05}, ++{0x7695, 0x83}, ++{0x7696, 0x00}, ++{0x7697, 0x07}, ++{0x7698, 0x05}, ++{0x7699, 0x03}, ++{0x769a, 0x00}, ++{0x769b, 0x05}, ++{0x769c, 0x05}, ++{0x769d, 0x32}, ++{0x769e, 0x05}, ++{0x769f, 0x30}, ++{0x76a0, 0x00}, ++{0x76a1, 0x02}, ++{0x76a2, 0x05}, ++{0x76a3, 0x78}, ++{0x76a4, 0x00}, ++{0x76a5, 0x01}, ++{0x76a6, 0x05}, ++{0x76a7, 0x7c}, ++{0x76a8, 0x03}, ++{0x76a9, 0x9a}, ++{0x76aa, 0x05}, ++{0x76ab, 0x83}, ++{0x76ac, 0x00}, ++{0x76ad, 0x04}, ++{0x76ae, 0x05}, ++{0x76af, 0x03}, ++{0x76b0, 0x00}, ++{0x76b1, 0x03}, ++{0x76b2, 0x05}, ++{0x76b3, 0x32}, ++{0x76b4, 0x05}, ++{0x76b5, 0x30}, ++{0x76b6, 0x00}, ++{0x76b7, 0x02}, ++{0x76b8, 0x05}, ++{0x76b9, 0x78}, ++{0x76ba, 0x00}, ++{0x76bb, 0x01}, ++{0x76bc, 0x05}, ++{0x76bd, 0x7c}, ++{0x76be, 0x03}, ++{0x76bf, 0x99}, ++{0x76c0, 0x05}, ++{0x76c1, 0x83}, ++{0x76c2, 0x00}, ++{0x76c3, 0x03}, ++{0x76c4, 0x05}, ++{0x76c5, 0x03}, ++{0x76c6, 0x00}, ++{0x76c7, 0x01}, ++{0x76c8, 0x05}, ++{0x76c9, 0x32}, ++{0x76ca, 0x05}, ++{0x76cb, 0x30}, ++{0x76cc, 0x00}, ++{0x76cd, 0x02}, ++{0x76ce, 0x05}, ++{0x76cf, 0x78}, ++{0x76d0, 0x00}, ++{0x76d1, 0x01}, ++{0x76d2, 0x05}, ++{0x76d3, 0x7c}, ++{0x76d4, 0x03}, ++{0x76d5, 0x98}, ++{0x76d6, 0x05}, ++{0x76d7, 0x83}, ++{0x76d8, 0x00}, ++{0x76d9, 0x00}, ++{0x76da, 0x05}, ++{0x76db, 0x03}, ++{0x76dc, 0x00}, ++{0x76dd, 0x01}, ++{0x76de, 0x05}, ++{0x76df, 0x32}, ++{0x76e0, 0x05}, ++{0x76e1, 0x30}, ++{0x76e2, 0x00}, ++{0x76e3, 0x02}, ++{0x76e4, 0x05}, ++{0x76e5, 0x78}, ++{0x76e6, 0x00}, ++{0x76e7, 0x01}, ++{0x76e8, 0x05}, ++{0x76e9, 0x7c}, ++{0x76ea, 0x03}, ++{0x76eb, 0x97}, ++{0x76ec, 0x05}, ++{0x76ed, 0x83}, ++{0x76ee, 0x00}, ++{0x76ef, 0x00}, ++{0x76f0, 0x05}, ++{0x76f1, 0x03}, ++{0x76f2, 0x05}, ++{0x76f3, 0x32}, ++{0x76f4, 0x05}, ++{0x76f5, 0x30}, ++{0x76f6, 0x00}, ++{0x76f7, 0x02}, ++{0x76f8, 0x05}, ++{0x76f9, 0x78}, ++{0x76fa, 0x00}, ++{0x76fb, 0x01}, ++{0x76fc, 0x05}, ++{0x76fd, 0x7c}, ++{0x76fe, 0x03}, ++{0x76ff, 0x96}, ++{0x7700, 0x05}, ++{0x7701, 0x83}, ++{0x7702, 0x05}, ++{0x7703, 0x03}, ++{0x7704, 0x05}, ++{0x7705, 0x32}, ++{0x7706, 0x05}, ++{0x7707, 0x30}, ++{0x7708, 0x00}, ++{0x7709, 0x02}, ++{0x770a, 0x05}, ++{0x770b, 0x78}, ++{0x770c, 0x00}, ++{0x770d, 0x01}, ++{0x770e, 0x05}, ++{0x770f, 0x7c}, ++{0x7710, 0x03}, ++{0x7711, 0x95}, ++{0x7712, 0x05}, ++{0x7713, 0x83}, ++{0x7714, 0x05}, ++{0x7715, 0x03}, ++{0x7716, 0x05}, ++{0x7717, 0x32}, ++{0x7718, 0x05}, ++{0x7719, 0x30}, ++{0x771a, 0x00}, ++{0x771b, 0x02}, ++{0x771c, 0x05}, ++{0x771d, 0x78}, ++{0x771e, 0x00}, ++{0x771f, 0x01}, ++{0x7720, 0x05}, ++{0x7721, 0x7c}, ++{0x7722, 0x03}, ++{0x7723, 0x94}, ++{0x7724, 0x05}, ++{0x7725, 0x83}, ++{0x7726, 0x00}, ++{0x7727, 0x01}, ++{0x7728, 0x05}, ++{0x7729, 0x03}, ++{0x772a, 0x00}, ++{0x772b, 0x01}, ++{0x772c, 0x05}, ++{0x772d, 0x32}, ++{0x772e, 0x05}, ++{0x772f, 0x30}, ++{0x7730, 0x00}, ++{0x7731, 0x02}, ++{0x7732, 0x05}, ++{0x7733, 0x78}, ++{0x7734, 0x00}, ++{0x7735, 0x01}, ++{0x7736, 0x05}, ++{0x7737, 0x7c}, ++{0x7738, 0x03}, ++{0x7739, 0x93}, ++{0x773a, 0x05}, ++{0x773b, 0x83}, ++{0x773c, 0x00}, ++{0x773d, 0x00}, ++{0x773e, 0x05}, ++{0x773f, 0x03}, ++{0x7740, 0x00}, ++{0x7741, 0x00}, ++{0x7742, 0x05}, ++{0x7743, 0x32}, ++{0x7744, 0x05}, ++{0x7745, 0x30}, ++{0x7746, 0x00}, ++{0x7747, 0x02}, ++{0x7748, 0x05}, ++{0x7749, 0x78}, ++{0x774a, 0x00}, ++{0x774b, 0x01}, ++{0x774c, 0x05}, ++{0x774d, 0x7c}, ++{0x774e, 0x03}, ++{0x774f, 0x92}, ++{0x7750, 0x05}, ++{0x7751, 0x83}, ++{0x7752, 0x05}, ++{0x7753, 0x03}, ++{0x7754, 0x00}, ++{0x7755, 0x00}, ++{0x7756, 0x05}, ++{0x7757, 0x32}, ++{0x7758, 0x05}, ++{0x7759, 0x30}, ++{0x775a, 0x00}, ++{0x775b, 0x02}, ++{0x775c, 0x05}, ++{0x775d, 0x78}, ++{0x775e, 0x00}, ++{0x775f, 0x01}, ++{0x7760, 0x05}, ++{0x7761, 0x7c}, ++{0x7762, 0x03}, ++{0x7763, 0x91}, ++{0x7764, 0x05}, ++{0x7765, 0x83}, ++{0x7766, 0x05}, ++{0x7767, 0x03}, ++{0x7768, 0x05}, ++{0x7769, 0x32}, ++{0x776a, 0x05}, ++{0x776b, 0x30}, ++{0x776c, 0x00}, ++{0x776d, 0x02}, ++{0x776e, 0x05}, ++{0x776f, 0x78}, ++{0x7770, 0x00}, ++{0x7771, 0x01}, ++{0x7772, 0x05}, ++{0x7773, 0x7c}, ++{0x7774, 0x03}, ++{0x7775, 0x90}, ++{0x7776, 0x05}, ++{0x7777, 0x83}, ++{0x7778, 0x05}, ++{0x7779, 0x03}, ++{0x777a, 0x05}, ++{0x777b, 0x32}, ++{0x777c, 0x05}, ++{0x777d, 0x30}, ++{0x777e, 0x00}, ++{0x777f, 0x02}, ++{0x7780, 0x05}, ++{0x7781, 0x78}, ++{0x7782, 0x00}, ++{0x7783, 0x01}, ++{0x7784, 0x05}, ++{0x7785, 0x7c}, ++{0x7786, 0x02}, ++{0x7787, 0x90}, ++{0x7788, 0x05}, ++{0x7789, 0x03}, ++{0x778a, 0x07}, ++{0x778b, 0x00}, ++{0x778c, 0x0f}, ++{0x778d, 0x00}, ++{0x778e, 0x08}, ++{0x778f, 0x30}, ++{0x7790, 0x08}, ++{0x7791, 0xee}, ++{0x7792, 0x0f}, ++{0x7793, 0x00}, ++{0x7794, 0x05}, ++{0x7795, 0x33}, ++{0x7796, 0x04}, ++{0x7797, 0xe5}, ++{0x7798, 0x06}, ++{0x7799, 0x52}, ++{0x779a, 0x04}, ++{0x779b, 0xe4}, ++{0x779c, 0x00}, ++{0x779d, 0x00}, ++{0x779e, 0x06}, ++{0x779f, 0x5e}, ++{0x77a0, 0x00}, ++{0x77a1, 0x0f}, ++{0x77a2, 0x06}, ++{0x77a3, 0x1e}, ++{0x77a4, 0x00}, ++{0x77a5, 0x02}, ++{0x77a6, 0x06}, ++{0x77a7, 0xa2}, ++{0x77a8, 0x00}, ++{0x77a9, 0x01}, ++{0x77aa, 0x06}, ++{0x77ab, 0xae}, ++{0x77ac, 0x00}, ++{0x77ad, 0x03}, ++{0x77ae, 0x05}, ++{0x77af, 0x30}, ++{0x77b0, 0x09}, ++{0x77b1, 0x19}, ++{0x77b2, 0x0f}, ++{0x77b3, 0x00}, ++{0x77b4, 0x05}, ++{0x77b5, 0x33}, ++{0x77b6, 0x04}, ++{0x77b7, 0xe5}, ++{0x77b8, 0x06}, ++{0x77b9, 0x52}, ++{0x77ba, 0x04}, ++{0x77bb, 0xe4}, ++{0x77bc, 0x00}, ++{0x77bd, 0x00}, ++{0x77be, 0x06}, ++{0x77bf, 0x5e}, ++{0x77c0, 0x00}, ++{0x77c1, 0x0f}, ++{0x77c2, 0x06}, ++{0x77c3, 0x1e}, ++{0x77c4, 0x00}, ++{0x77c5, 0x02}, ++{0x77c6, 0x06}, ++{0x77c7, 0xa2}, ++{0x77c8, 0x00}, ++{0x77c9, 0x01}, ++{0x77ca, 0x06}, ++{0x77cb, 0xae}, ++{0x77cc, 0x00}, ++{0x77cd, 0x03}, ++{0x77ce, 0x05}, ++{0x77cf, 0x30}, ++{0x77d0, 0x0f}, ++{0x77d1, 0x00}, ++{0x77d2, 0x00}, ++{0x77d3, 0x00}, ++{0x77d4, 0x00}, ++{0x77d5, 0x02}, ++{0x77d6, 0x04}, ++{0x77d7, 0xe5}, ++{0x77d8, 0x04}, ++{0x77d9, 0xe4}, ++{0x77da, 0x05}, ++{0x77db, 0x33}, ++{0x77dc, 0x07}, ++{0x77dd, 0x10}, ++{0x77de, 0x00}, ++{0x77df, 0x00}, ++{0x77e0, 0x01}, ++{0x77e1, 0xbb}, ++{0x77e2, 0x00}, ++{0x77e3, 0x00}, ++{0x77e4, 0x01}, ++{0x77e5, 0xaa}, ++{0x77e6, 0x00}, ++{0x77e7, 0x00}, ++{0x77e8, 0x01}, ++{0x77e9, 0x99}, ++{0x77ea, 0x00}, ++{0x77eb, 0x00}, ++{0x77ec, 0x01}, ++{0x77ed, 0x88}, ++{0x77ee, 0x00}, ++{0x77ef, 0x00}, ++{0x77f0, 0x01}, ++{0x77f1, 0x77}, ++{0x77f2, 0x00}, ++{0x77f3, 0x00}, ++{0x77f4, 0x01}, ++{0x77f5, 0x66}, ++{0x77f6, 0x00}, ++{0x77f7, 0x00}, ++{0x77f8, 0x01}, ++{0x77f9, 0x55}, ++{0x77fa, 0x00}, ++{0x77fb, 0x00}, ++{0x77fc, 0x01}, ++{0x77fd, 0x44}, ++{0x77fe, 0x00}, ++{0x77ff, 0x00}, ++{0x7800, 0x01}, ++{0x7801, 0x33}, ++{0x7802, 0x00}, ++{0x7803, 0x00}, ++{0x7804, 0x01}, ++{0x7805, 0x22}, ++{0x7806, 0x00}, ++{0x7807, 0x00}, ++{0x7808, 0x01}, ++{0x7809, 0x11}, ++{0x780a, 0x00}, ++{0x780b, 0x00}, ++{0x780c, 0x01}, ++{0x780d, 0x00}, ++{0x780e, 0x01}, ++{0x780f, 0xff}, ++{0x7810, 0x07}, ++{0x7811, 0x00}, ++{0x7812, 0x02}, ++{0x7813, 0xa0}, ++{0x7814, 0x0f}, ++{0x7815, 0x00}, ++{0x7816, 0x08}, ++{0x7817, 0x35}, ++{0x7818, 0x06}, ++{0x7819, 0x52}, ++{0x781a, 0x04}, ++{0x781b, 0xe4}, ++{0x781c, 0x00}, ++{0x781d, 0x00}, ++{0x781e, 0x06}, ++{0x781f, 0x5e}, ++{0x7820, 0x05}, ++{0x7821, 0x33}, ++{0x7822, 0x09}, ++{0x7823, 0x19}, ++{0x7824, 0x06}, ++{0x7825, 0x1e}, ++{0x7826, 0x05}, ++{0x7827, 0x33}, ++{0x7828, 0x00}, ++{0x7829, 0x01}, ++{0x782a, 0x06}, ++{0x782b, 0x24}, ++{0x782c, 0x06}, ++{0x782d, 0x20}, ++{0x782e, 0x0f}, ++{0x782f, 0x00}, ++{0x7830, 0x08}, ++{0x7831, 0x35}, ++{0x7832, 0x07}, ++{0x7833, 0x10}, ++{0x7834, 0x00}, ++{0x7835, 0x00}, ++{0x7836, 0x01}, ++{0x7837, 0xbb}, ++{0x7838, 0x00}, ++{0x7839, 0x00}, ++{0x783a, 0x01}, ++{0x783b, 0xaa}, ++{0x783c, 0x00}, ++{0x783d, 0x00}, ++{0x783e, 0x01}, ++{0x783f, 0x99}, ++{0x7840, 0x00}, ++{0x7841, 0x00}, ++{0x7842, 0x01}, ++{0x7843, 0x88}, ++{0x7844, 0x00}, ++{0x7845, 0x00}, ++{0x7846, 0x01}, ++{0x7847, 0x77}, ++{0x7848, 0x00}, ++{0x7849, 0x00}, ++{0x784a, 0x01}, ++{0x784b, 0x66}, ++{0x784c, 0x00}, ++{0x784d, 0x00}, ++{0x784e, 0x01}, ++{0x784f, 0x55}, ++{0x7850, 0x00}, ++{0x7851, 0x00}, ++{0x7852, 0x01}, ++{0x7853, 0x44}, ++{0x7854, 0x00}, ++{0x7855, 0x00}, ++{0x7856, 0x01}, ++{0x7857, 0x33}, ++{0x7858, 0x00}, ++{0x7859, 0x00}, ++{0x785a, 0x01}, ++{0x785b, 0x22}, ++{0x785c, 0x00}, ++{0x785d, 0x00}, ++{0x785e, 0x01}, ++{0x785f, 0x11}, ++{0x7860, 0x00}, ++{0x7861, 0x00}, ++{0x7862, 0x01}, ++{0x7863, 0x00}, ++{0x7864, 0x07}, ++{0x7865, 0x00}, ++{0x7866, 0x01}, ++{0x7867, 0xff}, ++{0x7868, 0x02}, ++{0x7869, 0xa0}, ++{0x786a, 0x0f}, ++{0x786b, 0x00}, ++{0x786c, 0x08}, ++{0x786d, 0x3a}, ++{0x786e, 0x08}, ++{0x786f, 0x6a}, ++{0x7870, 0x0f}, ++{0x7871, 0x00}, ++{0x7872, 0x04}, ++{0x7873, 0xc0}, ++{0x7874, 0x09}, ++{0x7875, 0x19}, ++{0x7876, 0x04}, ++{0x7877, 0x99}, ++{0x7878, 0x07}, ++{0x7879, 0x14}, ++{0x787a, 0x00}, ++{0x787b, 0x01}, ++{0x787c, 0x04}, ++{0x787d, 0xa4}, ++{0x787e, 0x00}, ++{0x787f, 0x0f}, ++{0x7880, 0x00}, ++{0x7881, 0x0f}, ++{0x7882, 0x04}, ++{0x7883, 0xa6}, ++{0x7884, 0x00}, ++{0x7885, 0x00}, ++{0x7886, 0x04}, ++{0x7887, 0xa0}, ++{0x7888, 0x04}, ++{0x7889, 0x80}, ++{0x788a, 0x04}, ++{0x788b, 0x00}, ++{0x788c, 0x05}, ++{0x788d, 0x03}, ++{0x788e, 0x06}, ++{0x788f, 0x00}, ++{0x7890, 0x0f}, ++{0x7891, 0x00}, ++{0x7892, 0x0f}, ++{0x7893, 0x00}, ++{0x7894, 0x0f}, ++{0x7895, 0x00}, ++{0x30a0, 0x00}, ++{0x30a1, 0x00}, ++{0x30a2, 0x00}, ++{0x30a3, 0x00}, ++{0x30a4, 0x07}, ++{0x30a5, 0x8f}, ++{0x30a6, 0x04}, ++{0x30a7, 0x47}, ++{0x30a8, 0x00}, ++{0x30a9, 0x04}, ++{0x30aa, 0x00}, ++{0x30ab, 0x04}, ++{0x30ac, 0x07}, /* OV2775_MAX_WIDTH */ ++{0x30ad, 0x88}, ++{0x30ae, 0x04}, /* OV2775_MAX_HEIGHT */ ++{0x30af, 0x40}, ++{0x30b0, 0x0d}, ++{0x30b1, 0xde}, ++{0x30b2, 0x04}, ++{0x30b3, 0x66}, ++{0x3196, 0x00}, ++{0x3197, 0x0a}, ++{0x3195, 0x29}, ++{0x315a, 0x02}, ++{0x315b, 0x00}, ++{0x30bb, 0x40}, ++{0x3250, 0xf7}, ++{0x3012, 0x01}, ++}; diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c new file mode 100644 -index 0000000..be7098e +index 0000000..812f367 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c -@@ -0,0 +1,1156 @@ +@@ -0,0 +1,1133 @@ +/* + * OmniVision ov490-ov10640 sensor camera driver + * -+ * Copyright (C) 2016-2017 Cogent Embedded, Inc. ++ * Copyright (C) 2016-2018 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the @@ -4598,8 +12027,7 @@ index 0000000..be7098e + /* serializers */ + int max9286_addr; + int max9271_addr; -+ int ti964_addr; -+ int ti954_addr; ++ int ti9x4_addr; + int ti9x3_addr; + int port; + int gpio_resetb; @@ -4607,16 +12035,21 @@ index 0000000..be7098e + int gpio_fsin; +}; + -+static int force_conf_link; ++static int conf_link; ++module_param(conf_link, int, 0644); ++MODULE_PARM_DESC(conf_link, " Force configuration link. Used only if robust firmware flashing required (f.e. recovery)"); + -+static __init int ov490_force_conf_link(char *str) -+{ -+ /* force configuration link */ -+ /* used only if robust firmware flashing required (f.e. recovery) */ -+ force_conf_link = 1; -+ return 0; -+} -+early_param("force_conf_link", ov490_force_conf_link); ++static int dvp_order; ++module_param(dvp_order, int, 0644); ++MODULE_PARM_DESC(dvp_order, " DVP bus bits order"); ++ ++static int max_width; ++module_param(max_width, int, 0644); ++MODULE_PARM_DESC(max_width, " Fixed sensor width"); ++ ++static int max_height; ++module_param(max_height, int, 0644); ++MODULE_PARM_DESC(max_height, " Fixed sensor height"); + +static inline struct ov490_priv *to_ov490(const struct i2c_client *client) +{ @@ -4632,7 +12065,7 @@ index 0000000..be7098e + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ -+ usleep_range(2000, 2500); /* wait 2ms */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -4658,18 +12091,8 @@ index 0000000..be7098e + client->addr = tmp_addr; + } + -+ if (priv->ti964_addr) { -+ client->addr = priv->ti964_addr; /* TI964 I2C address */ -+ -+ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x6e, 0x8a); /* set GPIO1 value to reset */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x6e, 0x9a); /* set GPIO1 value to un-reset */ -+ } -+ -+ if (priv->ti954_addr) { -+ client->addr = priv->ti954_addr; /* TI964 I2C address */ ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* TI9x4 I2C address */ + + reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ + usleep_range(2000, 2500); /* wait 2ms */ @@ -5355,7 +12778,7 @@ index 0000000..be7098e + goto err; + } + -+ if (unlikely(force_conf_link)) ++ if (unlikely(conf_link)) + goto out; + +again: @@ -5440,7 +12863,7 @@ index 0000000..be7098e +static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv) +{ + struct i2c_client *client = v4l2_get_subdevdata(&priv->sd); -+ int err, i; ++ int i; + const char *fixed_sensor; + struct device_node *endpoint = NULL, *rendpoint = NULL; + int tmp_addr = 0; @@ -5473,19 +12896,13 @@ index 0000000..be7098e + } + + if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && -+ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") && -+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_addr) && -+ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) -+ break; -+ -+ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && -+ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") && -+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && + !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) + break; + } + -+ if (!priv->max9286_addr && !priv->ti964_addr && !priv->ti954_addr) { ++ if (!priv->max9286_addr && !priv->ti9x4_addr) { + dev_err(&client->dev, "deserializer does not present for OV490\n"); + return -EINVAL; + } @@ -5501,18 +12918,8 @@ index 0000000..be7098e + reg8_write(client, 0x0A, OV490_I2C_ADDR << 1); /* Sensor native I2C address */ + usleep_range(2000, 2500); /* wait 2ms */ + }; -+ if (priv->ti964_addr) { -+ client->addr = priv->ti964_addr; /* Deserializer I2C address */ -+ -+ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ -+ reg8_write(client, 0x5d, OV490_I2C_ADDR << 1); /* Sensor native I2C address */ -+ -+ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */ -+ } -+ if (priv->ti954_addr) { -+ client->addr = priv->ti954_addr; /* Deserializer I2C address */ ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ + + reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ + usleep_range(2000, 2500); /* wait 2ms */ @@ -5523,28 +12930,27 @@ index 0000000..be7098e + } + client->addr = tmp_addr; + -+ err = of_property_read_string(np, "maxim,fixed-sensor", &fixed_sensor); -+ if (err) -+ return 0; ++ if (!of_property_read_string(np, "maxim,fixed-sensor", &fixed_sensor) && ++ strcmp(fixed_sensor, "ov490") == 0) { ++ if (of_property_read_u32(np, "maxim,width", &priv->max_width)) ++ priv->max_width = 1280; + -+ if (strcmp(fixed_sensor, "ov490") == 0) { -+ err = of_property_read_u32(np, "maxim,width", &priv->max_width); -+ if (err) { -+ dev_err(&client->dev, "maxim,width must be set for fixed-sensor\n"); -+ goto out; -+ } ++ if (of_property_read_u32(np, "maxim,height", &priv->max_height)) ++ priv->max_height = 966; + -+ err = of_property_read_u32(np, "maxim,height", &priv->max_height); -+ if (err) { -+ dev_err(&client->dev, "maxim,height must be set for fixed-sensor\n"); -+ goto out; -+ } ++ priv->is_fixed_sensor = true; ++ } + ++ /* module params override dts */ ++ if (dvp_order) ++ priv->dvp_order = dvp_order; ++ if (max_width && max_height) { ++ priv->max_width = max_width; ++ priv->max_height = max_height; + priv->is_fixed_sensor = true; + } + -+out: -+ return err; ++ return 0; +} + +static int ov490_probe(struct i2c_client *client, @@ -5805,10 +13211,10 @@ index 0000000..b22e93e +}; diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.c b/drivers/media/i2c/soc_camera/ov495_ov2775.c new file mode 100644 -index 0000000..6dc0675 +index 0000000..a371e22 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c -@@ -0,0 +1,658 @@ +@@ -0,0 +1,650 @@ +/* + * OmniVision ov495-ov2775 sensor camera driver + * @@ -5860,8 +13266,7 @@ index 0000000..6dc0675 + /* serializers */ + int max9286_addr; + int max9271_addr; -+ int ti960_addr; -+ int ti954_addr; ++ int ti9x4_addr; + int ti9x3_addr; + int port; + int gpio_resetb; @@ -6214,6 +13619,7 @@ index 0000000..6dc0675 + struct ov495_priv *priv = to_ov495(client); + u8 pid = 0, ver = 0; + int ret = 0; ++ int tmp_addr; + + /* check and show product ID and manufacturer ID */ + reg16_write(client, 0xFFFD, 0x80); @@ -6228,6 +13634,16 @@ index 0000000..6dc0675 + goto err; + } + ++ /* setup XCLK */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=25MHz: CLKDIV=4, M=7, N=253: 22.5792*160/4*7/253=24.989MHz=CLK_OUT */ ++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */ ++ reg8_write(client, 0x06, 0x47); /* Set CLKDIV and M */ ++ reg8_write(client, 0x07, 0xfd); /* Set N */ ++ } ++ client->addr = tmp_addr; ++ + if (unlikely(force_conf_link)) + goto out; + @@ -6282,39 +13698,21 @@ index 0000000..6dc0675 + continue; + + if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && -+ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") && -+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti960_addr) && -+ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) -+ break; -+ -+ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && -+ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") && -+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && + !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) + break; + } + -+ if (!priv->ti960_addr && !priv->ti954_addr) { ++ if (!priv->ti9x4_addr) { + dev_err(&client->dev, "deserializer does not present for OV495\n"); + return -EINVAL; + } + + /* setup I2C translator address */ + tmp_addr = client->addr; -+ if (priv->ti960_addr) { -+ client->addr = priv->ti960_addr; /* Deserializer I2C address */ -+ -+ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ -+ reg8_write(client, 0x5d, OV495_I2C_ADDR << 1); /* Sensor native I2C address */ -+ -+ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */ -+ /* TODO: why too long? move logic to workqueue? */ -+ mdelay(350); /* time needed to boot all sensor IPs */ -+ } -+ if (priv->ti954_addr) { -+ client->addr = priv->ti954_addr; /* Deserializer I2C address */ ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ + + reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ + usleep_range(2000, 2500); /* wait 2ms */ @@ -6469,12 +13867,12 @@ index 0000000..6dc0675 +#endif diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.h b/drivers/media/i2c/soc_camera/ov495_ov2775.h new file mode 100644 -index 0000000..3f53689 +index 0000000..17c94ae --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov495_ov2775.h @@ -0,0 +1,23 @@ +/* -+ * OmniVision ov495-ov2775 sensor camera wizard 1280x1080@30/UYVY/BT601/8bit ++ * OmniVision ov495-ov2775 sensor camera wizard 1920x1080@30/UYVY/MIPI + * + * Copyright (C) 2017 Cogent Embedded, Inc. + * @@ -6496,16 +13894,16 @@ index 0000000..3f53689 +{0x8017, 0x1e | (0 << 6)}, +{0x7c10, 0x01}, /* UYVY */ +}; -diff --git a/drivers/media/i2c/soc_camera/ti954_ti9x3.c b/drivers/media/i2c/soc_camera/ti954_ti9x3.c +diff --git a/drivers/media/i2c/soc_camera/ox03a.c b/drivers/media/i2c/soc_camera/ox03a.c new file mode 100644 -index 0000000..1672173 +index 0000000..d51512b9 --- /dev/null -+++ b/drivers/media/i2c/soc_camera/ti954_ti9x3.c -@@ -0,0 +1,431 @@ ++++ b/drivers/media/i2c/soc_camera/ox03a.c +@@ -0,0 +1,526 @@ +/* -+ * TI ti954-(ti913/ti953) FPDLinkIII driver ++ * OmniVision OX03A sensor camera driver + * -+ * Copyright (C) 2017 Cogent Embedded, Inc. ++ * Copyright (C) 2018 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the @@ -6514,190 +13912,213 @@ index 0000000..1672173 + */ + +#include <linux/delay.h> ++#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/module.h> -+#include <linux/notifier.h> -+#include <linux/of_gpio.h> -+#include <linux/regulator/consumer.h> +#include <linux/videodev2.h> + ++#include <media/soc_camera.h> +#include <media/v4l2-common.h> -+#include <media/v4l2-device.h> ++#include <media/v4l2-ctrls.h> +#include <media/v4l2-of.h> -+#include <media/v4l2-subdev.h> + -+#include "ti9x4_ti9x3.h" ++#include "ox03a.h" + -+struct ti954_ti9x3_priv { -+ struct v4l2_subdev sd[4]; -+ struct device_node *sd_of_node[4]; -+ int des_addr; -+ int links; -+ int lanes; -+ int csi_rate; -+ const char *forwarding_mode; -+ const char *cable_mode; -+ atomic_t use_count; -+ struct i2c_client *client; -+ int ti9x3_addr_map[4]; -+ char chip_id[6]; -+ struct regulator *poc_supply[4]; /* PoC power supply */ -+ int xtal_gpio; ++#define OX03A_I2C_ADDR 0x36 ++ ++#define OX03A_PID 0x300A ++#define OX03A_VER 0x300B ++#define OX03A_VERSION_REG 0x5803 ++ ++#define OX03A_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12 ++ ++struct ox03a_priv { ++ struct v4l2_subdev sd; ++ struct v4l2_ctrl_handler hdl; ++ struct media_pad pad; ++ struct v4l2_rect rect; ++ int init_complete; ++ u8 id[6]; ++ int exposure; ++ int gain; ++ int autogain; ++ /* serializers */ ++ int ti9x4_addr; ++ int ti9x3_addr; ++ int port; ++ int gpio_resetb; ++ int gpio_fsin; +}; + -+static int indirect_write(struct i2c_client *client, unsigned int page, u8 reg, u8 val) ++static inline struct ox03a_priv *to_ox03a(const struct i2c_client *client) +{ -+ if (page > 7) -+ return -EINVAL; ++ return container_of(i2c_get_clientdata(client), struct ox03a_priv, sd); ++} + -+ reg8_write(client, 0xb0, page << 2); -+ reg8_write(client, 0xb1, reg); -+ reg8_write(client, 0xb2, val); ++static int ox03a_set_regs(struct i2c_client *client, ++ const struct ox03a_reg *regs, int nr_regs) ++{ ++ int i; ++ ++ for (i = 0; i < nr_regs; i++) { ++ if (regs[i].reg == OX03A_DELAY) { ++ mdelay(regs[i].val); ++ continue; ++ } ++ ++ reg16_write(client, regs[i].reg, regs[i].val); ++ } + + return 0; +} + -+#if 0 -+static int indirect_read(struct i2c_client *client, unsigned int page, u8 reg, u8 *val) ++static int ox03a_s_stream(struct v4l2_subdev *sd, int enable) +{ -+ if (page > 7) ++ return 0; ++} ++ ++static int ox03a_get_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ox03a_priv *priv = to_ox03a(client); ++ ++ if (format->pad) + return -EINVAL; + -+ reg8_write(client, 0xb0, page << 2); -+ reg8_write(client, 0xb1, reg); -+ reg8_read(client, 0xb2, val); ++ mf->width = priv->rect.width; ++ mf->height = priv->rect.height; ++ mf->code = OX03A_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; + + return 0; +} -+#endif + -+static void ti954_ti9x3_read_chipid(struct i2c_client *client) ++static int ox03a_set_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) +{ -+ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client); ++ struct v4l2_mbus_framefmt *mf = &format->format; + -+ /* Chip ID */ -+ reg8_read(client, 0xf1, &priv->chip_id[0]); -+ reg8_read(client, 0xf2, &priv->chip_id[1]); -+ reg8_read(client, 0xf3, &priv->chip_id[2]); -+ reg8_read(client, 0xf4, &priv->chip_id[3]); -+ reg8_read(client, 0xf5, &priv->chip_id[4]); -+ priv->chip_id[5] = '\0'; ++ mf->code = OX03A_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ if (format->which == V4L2_SUBDEV_FORMAT_TRY) ++ cfg->try_fmt = *mf; ++ ++ return 0; +} + -+static void ti954_ti9x3_initial_setup(struct i2c_client *client) ++static int ox03a_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_mbus_code_enum *code) +{ -+ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client); ++ if (code->pad || code->index > 0) ++ return -EINVAL; + -+ /* Initial setup */ -+ client->addr = priv->des_addr; /* TI954 I2C */ -+ reg8_write(client, 0x08, 0x1c); /* I2C glitch filter depth */ -+ reg8_write(client, 0x0a, 0x79); /* I2C high pulse width */ -+ reg8_write(client, 0x0b, 0x79); /* I2C low pulse width */ -+ reg8_write(client, 0x0d, 0xb9); /* VDDIO 3.3V */ -+ switch (priv->csi_rate) { -+ case 1600: /* REFCLK = 25MHZ */ -+ case 1450: /* REFCLK = 22.5MHZ */ -+ reg8_write(client, 0x1f, 0x00); /* CSI rate 1.5/1.6Gbps */ -+ break; -+ case 800: /* REFCLK = 25MHZ */ -+ reg8_write(client, 0x1f, 0x02); /* CSI rate 800Mbps */ -+ break; -+ case 400: /* REFCLK = 25MHZ */ -+ reg8_write(client, 0x1f, 0x03); /* CSI rate 400Mbps */ -+ break; -+ default: -+ dev_err(&client->dev, "unsupported CSI rate %d\n", priv->csi_rate); -+ } ++ code->code = OX03A_MEDIA_BUS_FMT; + -+ if (strcmp(priv->forwarding_mode, "round-robin") == 0) { -+ reg8_write(client, 0x21, 0x01); /* Round Robin forwarding enable */ -+ } else if (strcmp(priv->forwarding_mode, "synchronized") == 0) { -+ reg8_write(client, 0x21, 0x44); /* Basic Syncronized forwarding enable (FrameSync must be enabled!!) */ -+ } -+ -+ reg8_write(client, 0x32, 0x01); /* Select TX (CSI) port 0 */ -+ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4); /* disable CSI output, set CSI lane count, non-continuous CSI mode */ -+ reg8_write(client, 0x20, 0xf0); /* disable port forwarding */ -+#if 0 -+ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/2/FPS*25MHz =1/2/30*25Mhz =416666 -> FS_TIME=416666 */ -+ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/2/FPS*22.5Mhz=1/2/30*22.5Mhz=375000 -> FS_TIME=375000 */ -+// #define FS_TIME (priv->csi_rate == 1450 ? 376000 : 417666) -+ #define FS_TIME (priv->csi_rate == 1450 ? 385000 : 428000) // FPS=29.2 (new vendor's firmware AWB restriction?) -+ reg8_write(client, 0x1a, FS_TIME >> 16); /* FrameSync time 24bit */ -+ reg8_write(client, 0x1b, (FS_TIME >> 8) & 0xff); -+ reg8_write(client, 0x1c, FS_TIME & 0xff); -+ reg8_write(client, 0x18, 0x43); /* Enable FrameSync, 50/50 mode, Frame clock from 25MHz */ -+#else -+ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/FPS/12mks=1/30/12e-6=2777 -> HI=2, LO=2775 */ -+ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/FPS/13.333mks=1/30/13.333e-6=2500 -> HI=2, LO=2498 */ -+ #define FS_TIME (priv->csi_rate == 1450 ? (2498+15) : (2775+15)) -+ reg8_write(client, 0x19, 2 >> 8); /* FrameSync high time MSB */ -+ reg8_write(client, 0x1a, 2 & 0xff); /* FrameSync high time LSB */ -+ reg8_write(client, 0x1b, FS_TIME >> 8); /* FrameSync low time MSB */ -+ reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */ -+ reg8_write(client, 0x18, 0x01); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */ -+#endif ++ return 0; +} + -+//#define SENSOR_ID 0x30 // ov10635 -+//#define SENSOR_ID 0x24 // ov490 -+ -+static void ti954_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx) ++static int ox03a_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) +{ -+ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ox03a_priv *priv = to_ox03a(client); + -+ /* FPDLinkIII setup */ -+ client->addr = priv->des_addr; /* TI954 I2C */ -+ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x58, 0x58); /* Back channel: pass-through/backchannel/CRC enable, Freq=2.5Mbps */ -+ reg8_write(client, 0x5c, priv->ti9x3_addr_map[idx] << 1); /* TI9X3 I2C addr */ -+// reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */ -+// reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */ -+ if (strcmp(priv->cable_mode, "coax") == 0) { -+ reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */ -+ } else if (strcmp(priv->cable_mode, "stp") == 0) { -+ reg8_write(client, 0x6d, 0x78); /* STP, CSI */ -+ } -+ reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */ -+ reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */ -+ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */ ++ memcpy(edid->edid, priv->id, 6); ++ ++ edid->edid[6] = 0xff; ++ edid->edid[7] = client->addr; ++ edid->edid[8] = OX03A_VERSION_REG >> 8; ++ edid->edid[9] = OX03A_VERSION_REG & 0xff; ++ ++ return 0; +} + -+static int ti954_ti9x3_initialize(struct i2c_client *client) ++static int ox03a_set_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) +{ -+ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client); -+ int idx; ++ struct v4l2_rect *rect = &sel->r; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ox03a_priv *priv = to_ox03a(client); + -+ dev_info(&client->dev, "LINKs=%d, LANES=%d, FORWARDING=%s, CABLE=%s, ID=%s\n", -+ priv->links, priv->lanes, priv->forwarding_mode, priv->cable_mode, priv->chip_id); ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || ++ sel->target != V4L2_SEL_TGT_CROP) ++ return -EINVAL; + -+ ti954_ti9x3_initial_setup(client); ++ rect->left = ALIGN(rect->left, 2); ++ rect->top = ALIGN(rect->top, 2); ++ rect->width = ALIGN(rect->width, 2); ++ rect->height = ALIGN(rect->height, 2); + -+ for (idx = 0; idx < priv->links; idx++) { -+ if (!IS_ERR(priv->poc_supply[idx])) { -+ if (regulator_enable(priv->poc_supply[idx])) -+ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); -+ } ++ if ((rect->left + rect->width > OX03A_MAX_WIDTH) || ++ (rect->top + rect->height > OX03A_MAX_HEIGHT)) ++ *rect = priv->rect; ++ ++ priv->rect.left = rect->left; ++ priv->rect.top = rect->top; ++ priv->rect.width = rect->width; ++ priv->rect.height = rect->height; + -+ ti954_ti9x3_fpdlink3_setup(client, idx); ++ return 0; ++} ++ ++static int ox03a_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ox03a_priv *priv = to_ox03a(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) ++ return -EINVAL; ++ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = OX03A_MAX_WIDTH; ++ sel->r.height = OX03A_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = OX03A_MAX_WIDTH; ++ sel->r.height = OX03A_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP: ++ sel->r = priv->rect; ++ return 0; ++ default: ++ return -EINVAL; + } ++} + -+ client->addr = priv->des_addr; ++static int ox03a_g_mbus_config(struct v4l2_subdev *sd, ++ struct v4l2_mbus_config *cfg) ++{ ++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | ++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; ++ cfg->type = V4L2_MBUS_CSI2; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG -+static int ti954_ti9x3_g_register(struct v4l2_subdev *sd, -+ struct v4l2_dbg_register *reg) ++static int ox03a_g_register(struct v4l2_subdev *sd, ++ struct v4l2_dbg_register *reg) +{ -+ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd); -+ struct i2c_client *client = priv->client; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + u8 val = 0; + -+ ret = reg8_read(client, (u8)reg->reg, &val); ++ ret = reg16_read(client, (u16)reg->reg, &val); + if (ret < 0) + return ret; + @@ -6707,108 +14128,127 @@ index 0000000..1672173 + return 0; +} + -+static int ti954_ti9x3_s_register(struct v4l2_subdev *sd, -+ const struct v4l2_dbg_register *reg) ++static int ox03a_s_register(struct v4l2_subdev *sd, ++ const struct v4l2_dbg_register *reg) +{ -+ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd); -+ struct i2c_client *client = priv->client; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); + -+ return reg8_write(client, (u8)reg->reg, (u8)reg->val); ++ return reg16_write(client, (u16)reg->reg, (u8)reg->val); +} +#endif + -+static int ti954_ti9x3_s_power(struct v4l2_subdev *sd, int on) ++static struct v4l2_subdev_core_ops ox03a_core_ops = { ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ .g_register = ox03a_g_register, ++ .s_register = ox03a_s_register, ++#endif ++}; ++ ++static int ox03a_s_ctrl(struct v4l2_ctrl *ctrl) +{ -+ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd); -+ struct i2c_client *client = priv->client; ++ struct v4l2_subdev *sd = to_sd(ctrl); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ox03a_priv *priv = to_ox03a(client); ++ int ret = -EINVAL; + -+ if (on) { -+ if (atomic_inc_return(&priv->use_count) == 1) -+ reg8_write(client, 0x20, 0x00); /* enable port forwarding to CSI */ -+ } else { -+ if (atomic_dec_return(&priv->use_count) == 0) -+ reg8_write(client, 0x20, 0xf0); /* disable port forwarding to CSI */ ++ if (!priv->init_complete) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_BRIGHTNESS: ++ case V4L2_CID_CONTRAST: ++ case V4L2_CID_SATURATION: ++ case V4L2_CID_HUE: ++ case V4L2_CID_GAMMA: ++ case V4L2_CID_SHARPNESS: ++ case V4L2_CID_AUTOGAIN: ++ case V4L2_CID_GAIN: ++ case V4L2_CID_EXPOSURE: ++ case V4L2_CID_HFLIP: ++ case V4L2_CID_VFLIP: ++ break; + } + -+ return 0; ++ return ret; +} + -+static int ti954_ti9x3_registered_async(struct v4l2_subdev *sd) -+{ -+ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd); -+ struct i2c_client *client = priv->client; -+ -+ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4 | 0x1); /* enable CSI output, set CSI lane count, non-continuous CSI mode */ ++static const struct v4l2_ctrl_ops ox03a_ctrl_ops = { ++ .s_ctrl = ox03a_s_ctrl, ++}; + -+ return 0; -+} ++static struct v4l2_subdev_video_ops ox03a_video_ops = { ++ .s_stream = ox03a_s_stream, ++ .g_mbus_config = ox03a_g_mbus_config, ++}; + -+static struct v4l2_subdev_core_ops ti954_ti9x3_subdev_core_ops = { -+#ifdef CONFIG_VIDEO_ADV_DEBUG -+ .g_register = ti954_ti9x3_g_register, -+ .s_register = ti954_ti9x3_s_register, -+#endif -+ .s_power = ti954_ti9x3_s_power, -+ .registered_async = ti954_ti9x3_registered_async, ++static const struct v4l2_subdev_pad_ops ox03a_subdev_pad_ops = { ++ .get_edid = ox03a_get_edid, ++ .enum_mbus_code = ox03a_enum_mbus_code, ++ .get_selection = ox03a_get_selection, ++ .set_selection = ox03a_set_selection, ++ .get_fmt = ox03a_get_fmt, ++ .set_fmt = ox03a_set_fmt, +}; + -+static struct v4l2_subdev_ops ti954_ti9x3_subdev_ops = { -+ .core = &ti954_ti9x3_subdev_core_ops, ++static struct v4l2_subdev_ops ox03a_subdev_ops = { ++ .core = &ox03a_core_ops, ++ .video = &ox03a_video_ops, ++ .pad = &ox03a_subdev_pad_ops, +}; + -+static int ti954_ti9x3_parse_dt(struct i2c_client *client) ++static void ox03a_otp_id_read(struct i2c_client *client) +{ -+ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client); -+ struct device_node *np = client->dev.of_node; -+ struct device_node *endpoint = NULL, *rendpoint = NULL; -+ struct property *prop; -+ int err, i; -+ int sensor_delay; -+ char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */ -+ char cable_mode_default[5] = "coax"; /* coax, stp */ -+ struct property *csi_rate_prop, *dvp_order_prop; -+ u8 val = 0; ++} + -+ if (of_property_read_u32(np, "ti,links", &priv->links)) -+ priv->links = 2; ++static ssize_t ox03a_otp_id_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev)); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ox03a_priv *priv = to_ox03a(client); + -+ if (of_property_read_u32(np, "ti,lanes", &priv->lanes)) -+ priv->lanes = 4; ++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n", ++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++} + -+ priv->xtal_gpio = of_get_gpio(np, 0); -+ if (priv->xtal_gpio > 0) { -+ err = devm_gpio_request_one(&client->dev, priv->xtal_gpio, GPIOF_OUT_INIT_LOW, dev_name(&client->dev)); -+ if (err) -+ dev_err(&client->dev, "cannot request XTAL gpio %d: %d\n", priv->xtal_gpio, err); -+ else -+ mdelay(250); -+ } ++static DEVICE_ATTR(otp_id_ox03a, S_IRUGO, ox03a_otp_id_show, NULL); + -+ reg8_read(client, 0x00, &val); /* read TI954 I2C address */ -+ if (val != (priv->des_addr << 1)) { -+ prop = of_find_property(np, "reg", NULL); -+ if (prop) -+ of_remove_property(np, prop); -+ return -ENODEV; -+ } ++static int ox03a_initialize(struct i2c_client *client) ++{ ++ struct ox03a_priv *priv = to_ox03a(client); ++ u8 val = 0; ++ u16 pid; ++ int ret = 0; + -+ ti954_ti9x3_read_chipid(client); ++ /* check and show model ID */ ++ reg16_read(client, OX03A_PID, &val); ++ pid = val; ++ reg16_read(client, OX03A_VER, &val); ++ pid = (pid << 8) | val; + -+ indirect_write(client, 7, 0x15, 0x30); -+ gpio_set_value(priv->xtal_gpio, 1); -+ usleep_range(5000, 5500); /* wait 5ms */ -+ indirect_write(client, 7, 0x15, 0); ++ if (pid != OX03A_VERSION_REG) { ++ dev_dbg(&client->dev, "Product ID error %x\n", pid); ++ ret = -ENODEV; ++ goto err; ++ } + -+ if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay)) -+ mdelay(sensor_delay); ++ /* Program wizard registers */ ++ ox03a_set_regs(client, ox03a_regs_wizard, ARRAY_SIZE(ox03a_regs_wizard)); ++ /* Read OTP IDs */ ++ ox03a_otp_id_read(client); + -+ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode); -+ if (err) -+ priv->forwarding_mode = forwarding_mode_default; ++ dev_info(&client->dev, "ox03a PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pid, OX03A_MAX_WIDTH, OX03A_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++err: ++ return ret; ++} + -+ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode); -+ if (err) -+ priv->cable_mode = cable_mode_default; ++static int ox03a_parse_dt(struct device_node *np, struct ox03a_priv *priv) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd); ++ int i; ++ struct device_node *endpoint = NULL, *rendpoint = NULL; ++ int tmp_addr = 0; + + for (i = 0; ; i++) { + endpoint = of_graph_get_next_endpoint(np, endpoint); @@ -6817,132 +14257,1915 @@ index 0000000..1672173 + + of_node_put(endpoint); + -+ if (i < priv->links) { -+ if (of_property_read_u32(endpoint, "ti9x3-addr", &priv->ti9x3_addr_map[i])) { -+ dev_err(&client->dev, "ti9x3-addr not set\n"); -+ return -EINVAL; -+ } -+ priv->sd_of_node[i] = endpoint; -+ } -+ + rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0); + if (!rendpoint) + continue; + -+ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL); -+ if (csi_rate_prop) { -+ of_property_read_u32(endpoint, "csi-rate", &priv->csi_rate); -+ of_update_property(rendpoint, csi_rate_prop); -+ } ++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && ++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) ++ break; ++ } + -+ dvp_order_prop = of_find_property(endpoint, "dvp-order", NULL); -+ if (dvp_order_prop) -+ of_update_property(rendpoint, dvp_order_prop); ++ if (!priv->ti9x4_addr) { ++ dev_err(&client->dev, "deserializer does not present\n"); ++ return -EINVAL; + } + ++ /* setup I2C translator address */ ++ tmp_addr = client->addr; ++ if (priv->ti9x4_addr) { ++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ ++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ ++ reg8_write(client, 0x5d, OX03A_I2C_ADDR << 1); /* Sensor native I2C address */ ++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */ ++ ++// client->addr = priv->ti9x3_addr; /* Serializer I2C address */ ++// reg8_write(client, 0x0d, 0x03); /* unreset gpios */ ++// reg8_write(client, 0x0e, 0xf0); /* unreset gpios */ ++ } ++ client->addr = tmp_addr; ++ ++ mdelay(10); ++ + return 0; +} + -+static int ti954_ti9x3_probe(struct i2c_client *client, -+ const struct i2c_device_id *did) ++static int ox03a_probe(struct i2c_client *client, ++ const struct i2c_device_id *did) +{ -+ struct ti954_ti9x3_priv *priv; -+ int err, i; -+ char supply_name[10]; ++ struct ox03a_priv *priv; ++ int ret; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + -+ i2c_set_clientdata(client, priv); -+ priv->des_addr = client->addr; -+ priv->client = client; -+ atomic_set(&priv->use_count, 0); ++ v4l2_i2c_subdev_init(&priv->sd, client, &ox03a_subdev_ops); ++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + -+ err = ti954_ti9x3_parse_dt(client); -+ if (err) -+ goto out; ++ priv->exposure = 0x100; ++ priv->gain = 0x100; ++ priv->autogain = 1; ++ v4l2_ctrl_handler_init(&priv->hdl, 4); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_CONTRAST, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_SATURATION, 0, 7, 1, 2); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_HUE, 0, 23, 1, 12); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_GAMMA, -128, 128, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_SHARPNESS, 0, 10, 1, 3); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 1); ++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ priv->sd.ctrl_handler = &priv->hdl; + -+ for (i = 0; i < 4; i++) { -+ sprintf(supply_name, "POC%d", i); -+ priv->poc_supply[i] = devm_regulator_get_optional(&client->dev, supply_name); -+ } ++ ret = priv->hdl.error; ++ if (ret) ++ goto cleanup; + -+ err = ti954_ti9x3_initialize(client); -+ if (err < 0) -+ goto out; ++ v4l2_ctrl_handler_setup(&priv->hdl); + -+ for (i = 0; i < priv->links; i++) { -+ v4l2_subdev_init(&priv->sd[i], &ti954_ti9x3_subdev_ops); -+ priv->sd[i].owner = client->dev.driver->owner; -+ priv->sd[i].dev = &client->dev; -+ priv->sd[i].grp_id = i; -+ v4l2_set_subdevdata(&priv->sd[i], priv); -+ priv->sd[i].of_node = priv->sd_of_node[i]; ++ priv->pad.flags = MEDIA_PAD_FL_SOURCE; ++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; ++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad); ++ if (ret < 0) ++ goto cleanup; + -+ snprintf(priv->sd[i].name, V4L2_SUBDEV_NAME_SIZE, "%s %d-%04x", -+ client->dev.driver->name, i2c_adapter_id(client->adapter), -+ client->addr); ++ ret = ox03a_parse_dt(client->dev.of_node, priv); ++ if (ret) ++ goto cleanup; + -+ err = v4l2_async_register_subdev(&priv->sd[i]); -+ if (err < 0) -+ goto out; ++ ret = ox03a_initialize(client); ++ if (ret < 0) ++ goto cleanup; ++ ++ priv->rect.left = 0; ++ priv->rect.top = 0; ++ priv->rect.width = OX03A_MAX_WIDTH; ++ priv->rect.height = OX03A_MAX_HEIGHT; ++ ++ ret = v4l2_async_register_subdev(&priv->sd); ++ if (ret) ++ goto cleanup; ++ ++ if (device_create_file(&client->dev, &dev_attr_otp_id_ox03a) != 0) { ++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n"); ++ goto cleanup; + } + -+out: -+ return err; ++ priv->init_complete = 1; ++ ++ return 0; ++ ++cleanup: ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++#ifdef CONFIG_SOC_CAMERA_OX03A ++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n", ++ client->addr, client->adapter->name); ++#endif ++ return ret; +} + -+static int ti954_ti9x3_remove(struct i2c_client *client) ++static int ox03a_remove(struct i2c_client *client) +{ -+ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client); -+ int i; ++ struct ox03a_priv *priv = i2c_get_clientdata(client); + -+ for (i = 0; i < priv->links; i++) { -+ v4l2_async_unregister_subdev(&priv->sd[i]); -+ v4l2_device_unregister_subdev(&priv->sd[i]); -+ } ++ device_remove_file(&client->dev, &dev_attr_otp_id_ox03a); ++ v4l2_async_unregister_subdev(&priv->sd); ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); + + return 0; +} + -+static const struct of_device_id ti954_ti9x3_dt_ids[] = { -+ { .compatible = "ti,ti954-ti9x3" }, -+ {}, ++#ifdef CONFIG_SOC_CAMERA_OX03A ++static const struct i2c_device_id ox03a_id[] = { ++ { "ox03a", 0 }, ++ { } +}; -+MODULE_DEVICE_TABLE(of, ti954_ti9x3_dt_ids); ++MODULE_DEVICE_TABLE(i2c, ox03a_id); + -+static const struct i2c_device_id ti954_ti9x3_id[] = { -+ { "ti954_ti9x3", 0 }, ++static const struct of_device_id ox03a_of_ids[] = { ++ { .compatible = "ovti,ox03a", }, + { } +}; -+MODULE_DEVICE_TABLE(i2c, ti954_ti9x3_id); ++MODULE_DEVICE_TABLE(of, ox03a_of_ids); + -+static struct i2c_driver ti954_ti9x3_i2c_driver = { ++static struct i2c_driver ox03a_i2c_driver = { + .driver = { -+ .name = "ti954_ti9x3", -+ .of_match_table = of_match_ptr(ti954_ti9x3_dt_ids), ++ .name = "ox03a", ++ .of_match_table = ox03a_of_ids, + }, -+ .probe = ti954_ti9x3_probe, -+ .remove = ti954_ti9x3_remove, -+ .id_table = ti954_ti9x3_id, ++ .probe = ox03a_probe, ++ .remove = ox03a_remove, ++ .id_table = ox03a_id, +}; + -+module_i2c_driver(ti954_ti9x3_i2c_driver); ++module_i2c_driver(ox03a_i2c_driver); + -+MODULE_DESCRIPTION("FPDLinkIII driver for TI954-TI9X3"); ++MODULE_DESCRIPTION("SoC Camera driver for OX03A"); +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_LICENSE("GPL"); -diff --git a/drivers/media/i2c/soc_camera/ti964_ti9x3.c b/drivers/media/i2c/soc_camera/ti964_ti9x3.c ++#endif +diff --git a/drivers/media/i2c/soc_camera/ox03a.h b/drivers/media/i2c/soc_camera/ox03a.h new file mode 100644 -index 0000000..bffd7c2 +index 0000000..b69273a --- /dev/null -+++ b/drivers/media/i2c/soc_camera/ti964_ti9x3.c -@@ -0,0 +1,400 @@ ++++ b/drivers/media/i2c/soc_camera/ox03a.h +@@ -0,0 +1,1724 @@ +/* -+ * TI (ti964/ti960)-(ti913/ti953) FPDLinkIII driver ++ * OmniVision OX03A sensor camera wizard 1920x1080@30/BGGR/MIPI + * -+ * Copyright (C) 2017 Cogent Embedded, Inc. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#define OX03A_DISPLAY_PATTERN_COLOR_BAR ++ ++#define OX03A_MAX_WIDTH 1920 ++#define OX03A_MAX_HEIGHT 1080 ++ ++#define OX03A_DELAY 0xffff ++#define OX03A_DT 0x2c /* MIPI Data Type RAW12 */ ++ ++struct ox03a_reg { ++ u16 reg; ++ u8 val; ++}; ++ ++/* wizard: MIPI 1920x1280 3x12 30fps 750MBPS */ ++static const struct ox03a_reg ox03a_regs_wizard[] = { ++{0x0103, 0x01}, // s/w reset ++{OX03A_DELAY, 10}, // Wait 10ms ++{0x0100, 0x00}, ++{0x0102, 0x00}, ++{0x0103, 0x00}, ++{0x0104, 0x04}, ++{0x0105, 0x00}, ++{0x0106, 0x00}, ++{0x0107, 0x00}, ++{0x0109, 0x00}, ++{0x0300, 0x00}, ++{0x0301, 0x01}, ++{0x0302, 0x00}, ++{0x0303, 0x02}, ++{0x0304, 0x00}, ++{0x0305, 0x3c}, ++{0x0306, 0x00}, ++{0x0307, 0x00}, ++{0x0308, 0x04}, ++{0x0309, 0x02}, ++{0x030a, 0x00}, ++{0x030c, 0x00}, ++{0x030d, 0x00}, ++{0x0310, 0x00}, ++{0x0311, 0x00}, ++{0x0312, 0x00}, ++{0x0313, 0x00}, ++{0x0314, 0x00}, ++{0x0315, 0x00}, ++{0x0316, 0x00}, ++{0x0317, 0x12}, ++{0x0318, 0x01}, ++{0x0320, 0x00}, ++{0x0321, 0x01}, ++{0x0322, 0x00}, ++{0x0323, 0x02}, ++{0x0324, 0x00}, ++{0x0325, 0x6c}, ++{0x0326, 0x00}, ++{0x0327, 0x05}, ++{0x0328, 0x05}, ++{0x0329, 0x01}, ++{0x032a, 0x02}, ++{0x032b, 0x00}, ++{0x032c, 0x00}, ++{0x0400, 0xe7}, ++{0x0401, 0xff}, ++{0x0404, 0x2b}, ++{0x0405, 0x32}, ++{0x0406, 0x33}, ++{0x0407, 0x8f}, ++{0x0408, 0x0c}, ++{0x040a, 0x00}, ++{0x0410, 0xe7}, ++{0x0411, 0xff}, ++{0x0414, 0x2b}, ++{0x0415, 0x32}, ++{0x0416, 0x33}, ++{0x0417, 0x8f}, ++{0x0418, 0x0c}, ++{0x041a, 0x00}, ++{0x2803, 0x00}, ++{0x3000, 0x00}, ++{0x3001, 0x03}, ++{0x3002, 0x03}, ++{0x3003, 0x00}, ++{0x3004, 0x04}, ++{0x3005, 0x00}, ++{0x3006, 0x00}, ++{0x3007, 0x04}, ++{0x3008, 0x00}, ++{0x3009, 0x06}, ++{0x300d, 0x11}, ++{0x300e, 0x11}, ++{0x300f, 0x11}, ++{0x3012, 0x41}, ++{0x3016, 0xf0}, ++{0x3017, 0xf0}, ++{0x3018, 0xf0}, ++{0x3019, 0xf0}, ++{0x301a, 0xf0}, ++{0x301b, 0xb4}, ++{0x301c, 0x01}, ++{0x301d, 0x02}, ++{0x301e, 0xb8}, ++{0x301f, 0xe1}, ++{0x3020, 0x01}, ++{0x3021, 0x00}, ++{0x3022, 0xf8}, ++{0x3023, 0xf0}, ++{0x3024, 0xf0}, ++{0x3025, 0x02}, ++{0x3026, 0x00}, ++{0x3027, 0x00}, ++{0x3028, 0xf0}, ++{0x3029, 0x80}, ++{0x3035, 0x6c}, ++{0x3036, 0x42}, ++{0x3037, 0x20}, ++{0x3038, 0x00}, ++{0x3700, 0x26}, ++{0x3701, 0x1e}, ++{0x3702, 0x25}, ++{0x3703, 0x28}, ++{0x3704, 0x0f}, ++{0x3705, 0x00}, ++{0x3706, 0x39}, ++{0x3707, 0x0a}, ++{0x3708, 0x36}, ++{0x3709, 0x41}, ++{0x370a, 0x00}, ++{0x370b, 0xa3}, ++{0x370c, 0x0f}, ++{0x370d, 0x00}, ++{0x370e, 0xa6}, ++{0x370f, 0x95}, ++{0x3710, 0x15}, ++{0x3711, 0x72}, ++{0x3712, 0x12}, ++{0x3713, 0x00}, ++{0x3714, 0x22}, ++{0x3715, 0x00}, ++{0x3716, 0x04}, ++{0x3717, 0x02}, ++{0x3718, 0x09}, ++{0x3719, 0x1f}, ++{0x371a, 0x0c}, ++{0x371b, 0x16}, ++{0x371c, 0x00}, ++{0x371d, 0x08}, ++{0x371e, 0x00}, ++{0x371f, 0x02}, ++{0x3720, 0x03}, ++{0x3721, 0x1c}, ++{0x3722, 0x87}, ++{0x3723, 0x08}, ++{0x3724, 0x0d}, ++{0x3725, 0x08}, ++{0x3726, 0x0d}, ++{0x3727, 0x08}, ++{0x3728, 0x04}, ++{0x3729, 0x0c}, ++{0x372a, 0x01}, ++{0x372b, 0x01}, ++{0x372c, 0x17}, ++{0x372d, 0x01}, ++{0x372e, 0x35}, ++{0x372f, 0x43}, ++{0x3730, 0x04}, ++{0x3731, 0x06}, ++{0x3732, 0x01}, ++{0x3733, 0x41}, ++{0x3734, 0x0a}, ++{0x3735, 0x11}, ++{0x3736, 0x11}, ++{0x3737, 0x00}, ++{0x3738, 0x54}, ++{0x3739, 0x54}, ++{0x373a, 0x54}, ++{0x373b, 0x54}, ++{0x373c, 0x11}, ++{0x373d, 0x11}, ++{0x373e, 0x00}, ++{0x373f, 0x4c}, ++{0x3740, 0x4c}, ++{0x3741, 0x4c}, ++{0x3742, 0x23}, ++{0x3743, 0x01}, ++{0x3744, 0x16}, ++{0x3745, 0x08}, ++{0x3746, 0x03}, ++{0x3747, 0x01}, ++{0x3748, 0x07}, ++{0x3749, 0x01}, ++{0x374a, 0x07}, ++{0x374b, 0x03}, ++{0x374c, 0xb1}, ++{0x374d, 0x01}, ++{0x374e, 0x01}, ++{0x374f, 0x01}, ++{0x3750, 0x07}, ++{0x3751, 0x02}, ++{0x3752, 0x03}, ++{0x3753, 0xd0}, ++{0x3754, 0x08}, ++{0x3755, 0x00}, ++{0x3758, 0xdd}, ++{0x3759, 0x50}, ++{0x375a, 0x49}, ++{0x375b, 0x02}, ++{0x375c, 0x2f}, ++{0x375d, 0x00}, ++{0x375e, 0x0f}, ++{0x375f, 0x03}, ++{0x3760, 0x13}, ++{0x3761, 0x12}, ++{0x3762, 0x1c}, ++{0x3763, 0x03}, ++{0x3764, 0x0d}, ++{0x3765, 0x25}, ++{0x3766, 0x08}, ++{0x3767, 0x08}, ++{0x3768, 0x21}, ++{0x3769, 0x01}, ++{0x376a, 0x01}, ++{0x376b, 0x00}, ++{0x376c, 0x15}, ++{0x376d, 0x08}, ++{0x376e, 0x08}, ++{0x376f, 0x08}, ++{0x3770, 0x91}, ++{0x3771, 0x00}, ++{0x3772, 0x00}, ++{0x3773, 0x00}, ++{0x3774, 0x02}, ++{0x3775, 0x00}, ++{0x3776, 0x00}, ++{0x3777, 0x00}, ++{0x3778, 0x00}, ++{0x3779, 0x22}, ++{0x377a, 0x00}, ++{0x377b, 0x00}, ++{0x377c, 0x48}, ++{0x377d, 0x00}, ++{0x377e, 0x00}, ++{0x377f, 0x07}, ++{0x3780, 0x00}, ++{0x3781, 0x02}, ++{0x3782, 0x04}, ++{0x3783, 0x02}, ++{0x3784, 0x08}, ++{0x3785, 0x08}, ++{0x3786, 0x00}, ++{0x3787, 0x04}, ++{0x3788, 0x02}, ++{0x3789, 0x02}, ++{0x378a, 0x04}, ++{0x378b, 0x00}, ++{0x378c, 0x00}, ++{0x378d, 0x00}, ++{0x378e, 0x00}, ++{0x378f, 0x00}, ++{0x3790, 0x10}, ++{0x3791, 0x05}, ++{0x3792, 0x31}, ++{0x3793, 0x00}, ++{0x3795, 0x00}, ++{0x3796, 0x00}, ++{0x3797, 0x00}, ++{0x3798, 0x00}, ++{0x3799, 0x00}, ++{0x379a, 0x00}, ++{0x379b, 0x10}, ++{0x379c, 0x01}, ++{0x379d, 0x00}, ++{0x379e, 0x0d}, ++{0x379f, 0x03}, ++{0x37a0, 0x08}, ++{0x37a1, 0x80}, ++{0x37a2, 0x03}, ++{0x37a3, 0x05}, ++{0x37a4, 0x04}, ++{0x37a5, 0x14}, ++{0x37a6, 0x17}, ++{0x37a7, 0x14}, ++{0x37a8, 0x05}, ++{0x37a9, 0x08}, ++{0x37aa, 0x05}, ++{0x37ab, 0x06}, ++{0x37ac, 0x05}, ++{0x37ad, 0x0d}, ++{0x37ae, 0x0d}, ++{0x37af, 0x01}, ++{0x37b0, 0x0c}, ++{0x37b1, 0x05}, ++{0x37b2, 0x08}, ++{0x37b3, 0x0a}, ++{0x37b4, 0x08}, ++{0x37b5, 0x08}, ++{0x37b6, 0x08}, ++{0x37b7, 0x08}, ++{0x37b8, 0xff}, ++{0x37b9, 0x01}, ++{0x37ba, 0x08}, ++{0x37bb, 0x08}, ++{0x37bd, 0x01}, ++{0x37be, 0x01}, ++{0x37bf, 0x01}, ++{0x37c0, 0x01}, ++{0x37c1, 0x11}, ++{0x37c2, 0x11}, ++{0x37c3, 0x00}, ++{0x37c4, 0x63}, ++{0x37c5, 0x63}, ++{0x37c6, 0x63}, ++{0x37c7, 0x34}, ++{0x37c8, 0x21}, ++{0x37c9, 0x00}, ++{0x37ca, 0x08}, ++{0x37cb, 0x00}, ++{0x37cc, 0x40}, ++{0x37cd, 0x00}, ++{0x37ce, 0x01}, ++{0x37cf, 0x08}, ++{0x37d0, 0x00}, ++{0x37d1, 0x39}, ++{0x37d2, 0x00}, ++{0x37d3, 0xa3}, ++{0x37d4, 0x00}, ++{0x37d5, 0x39}, ++{0x37d6, 0x00}, ++{0x37d7, 0xa3}, ++{0x37da, 0x00}, ++{0x37db, 0x00}, ++{0x37dc, 0x00}, ++{0x37dd, 0x00}, ++{0x37de, 0x00}, ++{0x37df, 0x00}, ++{0x37e0, 0x00}, ++{0x37e1, 0x00}, ++{0x37e2, 0x00}, ++{0x37e3, 0x00}, ++{0x37e4, 0x00}, ++{0x37e5, 0x00}, ++{0x37e6, 0x00}, ++{0x37e7, 0x00}, ++{0x37e8, 0x00}, ++{0x37e9, 0x00}, ++{0x37ea, 0x00}, ++{0x37eb, 0x00}, ++{0x37ec, 0x00}, ++{0x37ed, 0x00}, ++{0x37ee, 0x00}, ++{0x37ef, 0x00}, ++{0x37f0, 0x00}, ++{0x37f1, 0x00}, ++{0x37f2, 0x00}, ++{0x37f3, 0x00}, ++{0x37f4, 0x00}, ++{0x37f5, 0x00}, ++{0x37f6, 0x00}, ++{0x37f7, 0x00}, ++{0x37f8, 0x00}, ++{0x37f9, 0x00}, ++{0x37fa, 0x00}, ++{0x37fb, 0x00}, ++{0x37fc, 0x00}, ++{0x37fd, 0x00}, ++{0x37fe, 0x00}, ++{0x37ff, 0x00}, ++{0x3c00, 0x00}, ++{0x3c01, 0x11}, ++{0x3c02, 0x20}, ++{0x3c03, 0x04}, ++{0x3c04, 0x04}, ++{0x3c05, 0x00}, ++{0x3c06, 0x29}, ++{0x3c07, 0x01}, ++{0x3c08, 0x05}, ++{0x3c09, 0x0c}, ++{0x3c0a, 0x04}, ++{0x3c0b, 0xa8}, ++{0x3c0c, 0x11}, ++{0x3c0d, 0x08}, ++{0x3c0e, 0x03}, ++{0x3c0f, 0x02}, ++{0x3c10, 0x01}, ++{0x3c11, 0x08}, ++{0x3c12, 0x89}, ++{0x3c13, 0x21}, ++{0x3c14, 0x81}, ++{0x3c15, 0x21}, ++{0x3c16, 0x11}, ++{0x3c17, 0x01}, ++{0x3c18, 0x0c}, ++{0x3c19, 0x00}, ++{0x3c1a, 0x16}, ++{0x3c1b, 0x81}, ++{0x3c1c, 0x04}, ++{0x3c1d, 0x16}, ++{0x3c1e, 0x11}, ++{0x3c1f, 0x3a}, ++{0x3c20, 0x20}, ++{0x3c21, 0x00}, ++{0x3c22, 0x17}, ++{0x3c23, 0x07}, ++{0x3c24, 0x1a}, ++{0x3c25, 0x1e}, ++{0x3c26, 0x24}, ++{0x3c27, 0x37}, ++{0x3c28, 0x0a}, ++{0x3c29, 0x14}, ++{0x3c2a, 0xd1}, ++{0x3c2b, 0x27}, ++{0x3c2c, 0x33}, ++{0x3c2d, 0x0c}, ++{0x3c2e, 0x12}, ++{0x3c2f, 0x08}, ++{0x3c30, 0x16}, ++{0x3c31, 0x24}, ++{0x3c32, 0x35}, ++{0x3c33, 0x29}, ++{0x3c34, 0x31}, ++{0x3c35, 0x21}, ++{0x3c36, 0x11}, ++{0x3c37, 0x12}, ++{0x3c38, 0x11}, ++{0x3c39, 0x11}, ++{0x3c3a, 0x08}, ++{0x3c3b, 0x38}, ++{0x3c3c, 0x03}, ++{0x3c3d, 0x23}, ++{0x3c3e, 0x05}, ++{0x3c3f, 0x0a}, ++{0x3c40, 0xc1}, ++{0x3c41, 0x04}, ++{0x3c42, 0x01}, ++{0x3c43, 0x18}, ++{0x3c44, 0x21}, ++{0x3c45, 0x20}, ++{0x3c46, 0x0b}, ++{0x3c47, 0x11}, ++{0x3c48, 0x11}, ++{0x3c4a, 0x02}, ++{0x3c4b, 0x63}, ++{0x3c4c, 0x02}, ++{0x3c4d, 0x63}, ++{0x3c4e, 0x00}, ++{0x3c4f, 0x2a}, ++{0x3c50, 0x2a}, ++{0x3c51, 0x2a}, ++{0x3c52, 0x2a}, ++{0x3c53, 0x08}, ++{0x3c54, 0x1d}, ++{0x3c55, 0xeb}, ++{0x3c56, 0x24}, ++{0x3c57, 0x10}, ++{0x3c58, 0x10}, ++{0x3c59, 0x16}, ++{0x3c5a, 0x55}, ++{0x3c5b, 0x25}, ++{0x3c5c, 0x8e}, ++{0x3ce0, 0x00}, ++{0x3ce1, 0x00}, ++{0x3ce2, 0x00}, ++{0x3ce3, 0x00}, ++{0x3ce4, 0x00}, ++{0x3ce5, 0x00}, ++{0x3ce6, 0x00}, ++{0x3ce7, 0x00}, ++{0x3ce8, 0x00}, ++{0x3ce9, 0x00}, ++{0x3cea, 0x00}, ++{0x3ceb, 0x00}, ++{0x3cec, 0x00}, ++{0x3ced, 0x00}, ++{0x3cee, 0x00}, ++{0x3cef, 0x00}, ++{0x3cf0, 0x00}, ++{0x3cf1, 0x00}, ++{0x3cf2, 0x00}, ++{0x3cf3, 0x00}, ++{0x3cf4, 0x00}, ++{0x3cf5, 0x00}, ++{0x3cf6, 0x00}, ++{0x3cf7, 0x00}, ++{0x3cf8, 0x00}, ++{0x3cf9, 0x00}, ++{0x3cfa, 0x00}, ++{0x3cfb, 0x00}, ++{0x3cfc, 0x00}, ++{0x3cfd, 0x00}, ++{0x3cfe, 0x00}, ++{0x3cff, 0x00}, ++{0x3100, 0x00}, ++{0x3101, 0x32}, ++{0x3102, 0x00}, ++{0x3103, 0x25}, ++{0x3104, 0x01}, ++{0x3105, 0x11}, ++{0x3106, 0x10}, ++{0x3107, 0x01}, ++{0x3108, 0x01}, ++{0x3109, 0x00}, ++{0x3182, 0x10}, ++{0x3183, 0xff}, ++{0x3184, 0xff}, ++{0x3187, 0xff}, ++{0x3189, 0x00}, ++{0x318a, 0x00}, ++{0x318b, 0x00}, ++{0x318c, 0x00}, ++{0x318d, 0x00}, ++{0x318e, 0x00}, ++{0x318f, 0x00}, ++{0x3190, 0x00}, ++{0x3191, 0x00}, ++{0x3192, 0x00}, ++{0x3193, 0x00}, ++{0x3194, 0x00}, ++{0x3200, 0x00}, ++{0x3201, 0x08}, ++{0x3202, 0x10}, ++{0x3203, 0x18}, ++{0x3204, 0x20}, ++{0x3205, 0x30}, ++{0x3206, 0x00}, ++{0x3209, 0x00}, ++{0x320a, 0x00}, ++{0x320b, 0x00}, ++{0x320c, 0x00}, ++{0x320d, 0x01}, ++{0x3216, 0x01}, ++{0x3217, 0x00}, ++{0x3218, 0xf7}, ++{0x3219, 0x55}, ++{0x321b, 0x00}, ++{0x3220, 0x1c}, ++{0x3221, 0x00}, ++{0x3304, 0x04}, ++{0x3305, 0x00}, ++{0x3306, 0x03}, ++{0x3307, 0x00}, ++{0x3308, 0x00}, ++{0x3309, 0x00}, ++{0x330a, 0x00}, ++{0x330b, 0x00}, ++{0x330c, 0x00}, ++{0x330d, 0x00}, ++{0x330e, 0x00}, ++{0x330f, 0x00}, ++{0x3310, 0x06}, ++{0x3311, 0x05}, ++{0x3312, 0x55}, ++{0x3313, 0x0a}, ++{0x3314, 0xaa}, ++{0x3315, 0x0f}, ++{0x3316, 0xf0}, ++{0x3317, 0x00}, ++{0x3400, 0x08}, ++{0x3401, 0x00}, ++{0x3402, 0x00}, ++{0x3403, 0xb1}, ++{0x3404, 0x00}, ++{0x3405, 0x0f}, ++{0x3406, 0x08}, ++{0x3407, 0x08}, ++{0x3408, 0x01}, ++{0x3409, 0x02}, ++{0x340a, 0x02}, ++{0x340c, 0x10}, ++{0x340d, 0x00}, ++{0x3410, 0x00}, ++{0x3412, 0x00}, ++{0x3413, 0x00}, ++{0x3414, 0x00}, ++{0x3415, 0x00}, ++{0x3416, 0x00}, ++{0x3417, 0x00}, ++{0x3420, 0x00}, ++{0x3421, 0x00}, ++{0x3422, 0x00}, ++{0x3423, 0x00}, ++{0x3424, 0x00}, ++{0x3425, 0x00}, ++{0x3426, 0x00}, ++{0x3427, 0x00}, ++{0x3428, 0x00}, ++{0x3429, 0x00}, ++{0x342a, 0x00}, ++{0x342b, 0x00}, ++{0x3501, 0x00}, ++{0x3502, 0x24}, ++{0x3503, 0xa8}, ++{0x3504, 0x08}, ++{0x3506, 0x00}, ++{0x3507, 0x00}, ++{0x3508, 0x01}, ++{0x3509, 0x00}, ++{0x350a, 0x01}, ++{0x350b, 0x00}, ++{0x350c, 0x00}, ++{0x350d, 0x00}, ++{0x3541, 0x00}, ++{0x3542, 0x40}, ++{0x3543, 0xa8}, ++{0x3544, 0x08}, ++{0x3546, 0x00}, ++{0x3547, 0x00}, ++{0x3548, 0x01}, ++{0x3549, 0x00}, ++{0x354a, 0x01}, ++{0x354b, 0x00}, ++{0x354c, 0x00}, ++{0x354d, 0x00}, ++{0x3581, 0x00}, ++{0x3582, 0x24}, ++{0x3583, 0xa8}, ++{0x3584, 0x08}, ++{0x3586, 0x00}, ++{0x3587, 0x00}, ++{0x3588, 0x01}, ++{0x3589, 0x00}, ++{0x358a, 0x01}, ++{0x358b, 0x00}, ++{0x358c, 0x00}, ++{0x358d, 0x00}, ++{0x3600, 0x00}, ++{0x3601, 0x70}, ++{0x3602, 0x42}, ++{0x3603, 0xe3}, ++{0x3604, 0x93}, ++{0x3605, 0x40}, ++{0x3606, 0x80}, ++{0x3607, 0x4a}, ++{0x3608, 0x98}, ++{0x3609, 0x70}, ++{0x360a, 0x90}, ++{0x360b, 0x0a}, ++{0x360c, 0x40}, ++{0x360d, 0x88}, ++{0x360e, 0x88}, ++{0x360f, 0x88}, ++{0x3610, 0x89}, ++{0x3611, 0x4f}, ++{0x3612, 0x4f}, ++{0x3613, 0xba}, ++{0x3614, 0x99}, ++{0x3615, 0x99}, ++{0x3616, 0x00}, ++{0x3617, 0x00}, ++{0x3618, 0x18}, ++{0x3619, 0x00}, ++{0x3620, 0x02}, ++{0x3621, 0x80}, ++{0x3622, 0x00}, ++{0x3623, 0x00}, ++{0x3624, 0x00}, ++{0x3625, 0x00}, ++{0x3626, 0x0e}, ++{0x3627, 0x0f}, ++{0x3628, 0x0a}, ++{0x3629, 0x0a}, ++{0x362a, 0x0e}, ++{0x362b, 0x0e}, ++{0x362c, 0x0e}, ++{0x362d, 0x0e}, ++{0x362e, 0x00}, ++{0x362f, 0x00}, ++{0x3630, 0x00}, ++{0x3631, 0x00}, ++{0x3632, 0x99}, ++{0x3633, 0x99}, ++{0x3634, 0x30}, ++{0x3635, 0x30}, ++{0x3636, 0x30}, ++{0x3637, 0x30}, ++{0x3638, 0x00}, ++{0x3639, 0x00}, ++{0x363a, 0x00}, ++{0x363b, 0x0f}, ++{0x363c, 0x0f}, ++{0x363d, 0x0a}, ++{0x363e, 0x0a}, ++{0x363f, 0x0a}, ++{0x3640, 0x0a}, ++{0x3641, 0x0a}, ++{0x3642, 0x0a}, ++{0x3643, 0x10}, ++{0x3644, 0x00}, ++{0x3645, 0x10}, ++{0x3646, 0x16}, ++{0x3647, 0x10}, ++{0x3648, 0x00}, ++{0x3649, 0x13}, ++{0x364a, 0x1d}, ++{0x364b, 0x00}, ++{0x364c, 0x0e}, ++{0x364d, 0x0e}, ++{0x364e, 0x0e}, ++{0x364f, 0x0e}, ++{0x3650, 0x00}, ++{0x3651, 0x00}, ++{0x3652, 0xc5}, ++{0x3653, 0x00}, ++{0x3654, 0x40}, ++{0x3655, 0x00}, ++{0x3656, 0xcf}, ++{0x3657, 0x2b}, ++{0x3658, 0x09}, ++{0x3659, 0x00}, ++{0x365a, 0x00}, ++{0x365b, 0x00}, ++{0x365c, 0x00}, ++{0x365d, 0x00}, ++{0x3660, 0x01}, ++{0x3661, 0x07}, ++{0x3662, 0x00}, ++{0x3663, 0x20}, ++{0x3664, 0x00}, ++{0x3665, 0x12}, ++{0x3666, 0x13}, ++{0x3667, 0x14}, ++{0x3668, 0x95}, ++{0x3669, 0x16}, ++{0x366a, 0x00}, ++{0x366b, 0x00}, ++{0x366c, 0x00}, ++{0x366d, 0x00}, ++{0x366e, 0x00}, ++{0x366f, 0xc4}, ++{0x3670, 0x6f}, ++{0x3671, 0x0b}, ++{0x3672, 0x1d}, ++{0x3673, 0x6a}, ++{0x3674, 0x6f}, ++{0x3675, 0x1d}, ++{0x3676, 0x6f}, ++{0x3677, 0x1d}, ++{0x3678, 0x80}, ++{0x3679, 0x04}, ++{0x367a, 0x00}, ++{0x367b, 0x04}, ++{0x367c, 0x00}, ++{0x367d, 0x00}, ++{0x367e, 0x00}, ++{0x367f, 0x00}, ++{0x3680, 0x00}, ++{0x3800, 0x00}, ++{0x3801, 0x00}, ++{0x3802, 0x00}, ++{0x3803, 0x04}, ++{0x3804, 0x07}, ++{0x3805, 0x8f}, ++{0x3806, 0x05}, ++{0x3807, 0x0b}, ++{0x3808, 0x07}, ++{0x3809, 0x80}, ++{0x380a, 0x05}, ++{0x380b, 0x00}, ++{0x380c, 0x02}, ++{0x380d, 0x14}, ++{0x380e, 0x05}, ++{0x380f, 0x40}, ++{0x3810, 0x00}, ++{0x3811, 0x08}, ++{0x3812, 0x00}, ++{0x3813, 0x04}, ++{0x3814, 0x01}, ++{0x3815, 0x01}, ++{0x3816, 0x01}, ++{0x3817, 0x01}, ++{0x3818, 0x00}, ++{0x3819, 0x00}, ++{0x381a, 0x00}, ++{0x381b, 0x01}, ++{0x381c, 0x08}, ++{0x381d, 0x00}, ++{0x3820, 0x00}, ++{0x3821, 0x20}, ++{0x3822, 0x04}, ++{0x3823, 0x08}, ++{0x3824, 0x00}, ++{0x3825, 0x20}, ++{0x3826, 0x00}, ++{0x3827, 0x08}, ++{0x3828, 0x38}, ++{0x382a, 0x00}, ++{0x382b, 0x00}, ++{0x382c, 0x00}, ++{0x382d, 0x00}, ++{0x3832, 0x00}, ++{0x3833, 0x00}, ++{0x3834, 0x00}, ++{0x3838, 0x00}, ++{0x3839, 0x00}, ++{0x383a, 0x00}, ++{0x383b, 0x00}, ++{0x383c, 0x48}, ++{0x383d, 0x20}, ++{0x383e, 0x00}, ++{0x3842, 0x00}, ++{0x3843, 0x00}, ++{0x3844, 0x00}, ++{0x384c, 0x02}, ++{0x384d, 0x14}, ++{0x384e, 0x00}, ++{0x384f, 0x40}, ++{0x3850, 0x01}, ++{0x3851, 0x02}, ++{0x3852, 0x01}, ++{0x3853, 0x00}, ++{0x3854, 0x00}, ++{0x3855, 0x05}, ++{0x3856, 0x05}, ++{0x3857, 0x33}, ++{0x3858, 0x7c}, ++{0x3859, 0x00}, ++{0x385a, 0x03}, ++{0x385b, 0x05}, ++{0x385c, 0x32}, ++{0x385d, 0x00}, ++{0x385e, 0x12}, ++{0x385f, 0x00}, ++{0x3860, 0x10}, ++{0x3861, 0x00}, ++{0x3862, 0x40}, ++{0x3863, 0x00}, ++{0x3864, 0x40}, ++{0x3865, 0x00}, ++{0x3866, 0x40}, ++{0x3881, 0x02}, ++{0x3882, 0x00}, ++{0x3883, 0x08}, ++{0x3b40, 0x3e}, ++{0x3b41, 0x00}, ++{0x3b42, 0x02}, ++{0x3b43, 0x00}, ++{0x3b44, 0x03}, ++{0x3b45, 0x00}, ++{0x3b46, 0x03}, ++{0x3b47, 0x00}, ++{0x3b80, 0x00}, ++{0x3b81, 0x00}, ++{0x3b82, 0x07}, ++{0x3b83, 0x87}, ++{0x3b84, 0x36}, ++{0x3b85, 0x00}, ++{0x3b86, 0x00}, ++{0x3b87, 0x04}, ++{0x3b88, 0x00}, ++{0x3b89, 0x04}, ++{0x3b8a, 0x00}, ++{0x3b8b, 0x0a}, ++{0x3b8c, 0x00}, ++{0x3b8d, 0x01}, ++{0x3b8e, 0x03}, ++{0x3b8f, 0xe8}, ++{0x3d82, 0xbc}, ++{0x3d83, 0x08}, ++{0x3d84, 0x00}, ++{0x3d85, 0x1b}, ++{0x3d86, 0x02}, ++{0x3d87, 0x0a}, ++{0x3d88, 0x00}, ++{0x3d89, 0x00}, ++{0x3d8a, 0x03}, ++{0x3d8b, 0xff}, ++{0x3d8c, 0x00}, ++{0x3d8d, 0x00}, ++{0x3d90, 0x00}, ++{0x3d91, 0x00}, ++{0x3d92, 0xe2}, ++{0x3d93, 0x46}, ++{0x3d94, 0x14}, ++{0x3d95, 0x06}, ++{0x3d96, 0x01}, ++{0x3d97, 0x00}, ++{0x3d98, 0x00}, ++{0x3d99, 0x00}, ++{0x3d9a, 0x00}, ++{0x3d9b, 0x00}, ++{0x3d9c, 0x00}, ++{0x3d9d, 0x00}, ++{0x3d9e, 0x00}, ++{0x3d9f, 0x00}, ++{0x3da0, 0x00}, ++{0x3da1, 0x00}, ++{0x3da2, 0x00}, ++{0x3da4, 0x00}, ++{0x3e00, 0x00}, ++{0x3e01, 0x00}, ++{0x3e02, 0x0f}, ++{0x3e03, 0xdb}, ++{0x3e04, 0x14}, ++{0x3e05, 0x00}, ++{0x3e06, 0x03}, ++{0x3e07, 0x40}, ++{0x3e08, 0x00}, ++{0x3e09, 0x00}, ++{0x3e0a, 0x00}, ++{0x3e0b, 0x00}, ++{0x3e0c, 0x00}, ++{0x3e0d, 0x00}, ++{0x3e0e, 0x00}, ++{0x3f00, 0x04}, ++{0x3f01, 0x00}, ++{0x3f02, 0x00}, ++{0x3f03, 0x01}, ++{0x4000, 0xf8}, ++{0x4001, 0xeb}, ++{0x4004, 0x00}, ++{0x4005, 0x40}, ++{0x4006, 0x00}, ++{0x4007, 0x10}, ++{0x4008, 0x00}, ++{0x4009, 0x05}, ++{0x400a, 0x02}, ++{0x400b, 0x00}, ++{0x400c, 0x00}, ++{0x400d, 0x10}, ++{0x400e, 0x00}, ++{0x400f, 0xa0}, ++{0x4010, 0x10}, ++{0x4011, 0xff}, ++{0x4012, 0x08}, ++{0x4013, 0x02}, ++{0x4014, 0x02}, ++{0x4015, 0x02}, ++{0x4016, 0x00}, ++{0x4017, 0x04}, ++{0x4018, 0x18}, ++{0x4019, 0x04}, ++{0x401a, 0x58}, ++{0x4020, 0x00}, ++{0x4021, 0x00}, ++{0x4022, 0x00}, ++{0x4023, 0x00}, ++{0x4024, 0x00}, ++{0x4025, 0x00}, ++{0x4026, 0x00}, ++{0x4027, 0x00}, ++{0x4028, 0x4f}, ++{0x4029, 0x01}, ++{0x402a, 0x00}, ++{0x402b, 0x00}, ++{0x402c, 0x00}, ++{0x402d, 0x00}, ++{0x402e, 0x00}, ++{0x402f, 0x40}, ++{0x4030, 0x00}, ++{0x4031, 0x40}, ++{0x4032, 0x9e}, ++{0x4033, 0x80}, ++{0x4034, 0x00}, ++{0x4035, 0x80}, ++{0x4036, 0x00}, ++{0x4037, 0x80}, ++{0x4038, 0x00}, ++{0x4039, 0x80}, ++{0x403a, 0x00}, ++{0x403b, 0x80}, ++{0x403c, 0x00}, ++{0x403d, 0x00}, ++{0x4040, 0x00}, ++{0x4041, 0x00}, ++{0x4042, 0x00}, ++{0x4043, 0x00}, ++{0x4044, 0x00}, ++{0x4045, 0x00}, ++{0x4046, 0x00}, ++{0x4047, 0x00}, ++{0x4048, 0x00}, ++{0x4049, 0x00}, ++{0x404a, 0x00}, ++{0x404b, 0x00}, ++{0x404c, 0x00}, ++{0x404d, 0x00}, ++{0x404e, 0x00}, ++{0x404f, 0x00}, ++{0x4050, 0x00}, ++{0x4051, 0x05}, ++{0x4052, 0x00}, ++{0x4053, 0x80}, ++{0x4054, 0x00}, ++{0x4055, 0x80}, ++{0x4056, 0x00}, ++{0x4057, 0x80}, ++{0x4058, 0x00}, ++{0x4059, 0x80}, ++{0x405a, 0x30}, ++{0x405b, 0x18}, ++{0x405c, 0x00}, ++{0x405d, 0x00}, ++{0x405e, 0x00}, ++{0x405f, 0x00}, ++{0x4060, 0x00}, ++{0x4065, 0x00}, ++{0x4066, 0x02}, ++{0x406d, 0x00}, ++{0x406e, 0x00}, ++{0x406f, 0x00}, ++{0x40a0, 0x00}, ++{0x40a1, 0x00}, ++{0x40a2, 0x00}, ++{0x40a3, 0x00}, ++{0x40a4, 0x00}, ++{0x40a5, 0x00}, ++{0x40a6, 0x00}, ++{0x40a7, 0x00}, ++{0x40c0, 0x00}, ++{0x40c1, 0x00}, ++{0x40c2, 0x00}, ++{0x40c3, 0x00}, ++{0x40c4, 0x00}, ++{0x40c5, 0x00}, ++{0x40c6, 0x00}, ++{0x40c7, 0x00}, ++{0x40c8, 0x00}, ++{0x40c9, 0x00}, ++{0x40ca, 0x00}, ++{0x40cb, 0x00}, ++{0x40cc, 0x00}, ++{0x40cd, 0x00}, ++{0x40ce, 0x00}, ++{0x40cf, 0x00}, ++{0x4200, 0x00}, ++{0x4201, 0x00}, ++{0x4202, 0x00}, ++{0x4203, 0x00}, ++{0x4204, 0x00}, ++{0x4205, 0x00}, ++{0x4206, 0x00}, ++{0x4207, 0x00}, ++{0x4208, 0x00}, ++{0x4300, 0x00}, ++{0x4301, 0x00}, ++{0x4302, 0x00}, ++{0x4303, 0x00}, ++{0x4304, 0x00}, ++{0x4305, 0x00}, ++{0x4306, 0x00}, ++{0x4307, 0x00}, ++{0x4308, 0x00}, ++{0x4309, 0x00}, ++{0x430a, 0x00}, ++{0x430b, 0xff}, ++{0x430c, 0xff}, ++{0x430d, 0x00}, ++{0x430e, 0x00}, ++{0x430f, 0x02}, ++{0x4500, 0x16}, ++{0x4501, 0x18}, ++{0x4502, 0x00}, ++{0x4503, 0x00}, ++{0x4504, 0x01}, ++{0x4505, 0x00}, ++{0x4506, 0x32}, ++{0x4507, 0x07}, ++{0x4508, 0x1a}, ++{0x4580, 0x68}, ++{0x4581, 0xc7}, ++{0x4582, 0x07}, ++{0x4583, 0x07}, ++{0x4584, 0xec}, ++{0x4585, 0x09}, ++{0x4586, 0xae}, ++{0x4587, 0x04}, ++{0x4588, 0x52}, ++{0x4589, 0x05}, ++{0x458a, 0x47}, ++{0x458b, 0x02}, ++{0x458c, 0xe2}, ++{0x458d, 0x03}, ++{0x458e, 0x85}, ++{0x458f, 0x00}, ++{0x4590, 0x20}, ++{0x4591, 0x09}, ++{0x4592, 0x60}, ++{0x45a6, 0x18}, ++{0x4600, 0x00}, ++{0x4601, 0x30}, ++{0x4602, 0x00}, ++{0x4603, 0x01}, ++{0x4604, 0x00}, ++{0x4605, 0x03}, ++{0x4609, 0x00}, ++{0x460a, 0x30}, ++{0x460b, 0x00}, ++{0x460c, 0x30}, ++{0x460d, 0x01}, ++{0x460e, 0x00}, ++{0x4700, 0x2a}, ++{0x4702, 0x00}, ++{0x4703, 0x80}, ++{0x4704, 0x00}, ++{0x4705, 0x10}, ++{0x4706, 0xaa}, ++{0x4707, 0x55}, ++{0x4708, 0x99}, ++{0x4709, 0x66}, ++{0x470a, 0x08}, ++{0x470b, 0x88}, ++{0x470c, 0x00}, ++{0x470d, 0x02}, ++{0x470e, 0x00}, ++{0x470f, 0x00}, ++{0x4710, 0x00}, ++{0x4711, 0x00}, ++{0x4712, 0x00}, ++{0x4713, 0x00}, ++{0x4800, 0x04}, ++{0x4802, 0x00}, ++{0x4803, 0x00}, ++{0x4804, 0x08}, ++{0x4805, 0x00}, ++{0x4806, 0x00}, ++{0x4807, 0x03}, ++{0x4808, 0x18}, ++{0x480e, 0x04}, ++{0x4810, 0xff}, ++{0x4811, 0xff}, ++{0x4813, 0xe4}, // VC ++{0x4814, 0x2a}, ++{0x4815, 0x2b}, ++{0x4816, 0x2b}, ++{0x4818, 0x00}, ++{0x4819, 0x70}, ++{0x481a, 0x00}, ++{0x481b, 0x3c}, ++{0x481c, 0x01}, ++{0x481d, 0x2c}, ++{0x481e, 0x5f}, ++{0x481f, 0x26}, ++{0x4820, 0x00}, ++{0x4821, 0x3c}, ++{0x4822, 0x00}, ++{0x4823, 0x3c}, ++{0x4824, 0x00}, ++{0x4825, 0x32}, ++{0x4826, 0x32}, ++{0x4827, 0x55}, ++{0x4828, 0x00}, ++{0x4829, 0x64}, ++{0x482a, 0x06}, ++{0x482b, 0x04}, ++{0x482c, 0x00}, ++{0x482d, 0x00}, ++{0x482e, 0x34}, ++{0x482f, 0x00}, ++{0x4830, 0x00}, ++{0x4831, 0x64}, ++{0x4832, 0x00}, ++{0x4833, 0x10}, ++{0x4837, 0x15}, ++{0x4838, 0x00}, ++{0x4839, 0x00}, ++{0x483c, 0x10}, ++{0x483d, 0x00}, ++{0x484a, 0x3f}, ++{0x484b, 0x67}, ++{0x484c, 0x00}, ++{0x484e, 0x10}, ++{0x4850, 0x40}, ++{0x4851, 0xaa}, ++{0x4852, 0xff}, ++{0x4853, 0x8a}, ++{0x4854, 0x08}, ++{0x4855, 0x30}, ++{0x4856, 0x01}, ++{0x4860, 0x00}, ++{0x4861, 0xa0}, ++{0x4862, 0x01}, ++{0x4863, 0x01}, ++{0x4864, 0x02}, ++{0x4865, 0x66}, ++{0x4866, 0x99}, ++{0x4867, 0x88}, ++{0x4868, 0xaa}, ++{0x4869, 0xff}, ++{0x486a, 0x3f}, ++{0x486b, 0x84}, ++{0x486c, 0x36}, ++{0x486d, 0x00}, ++{0x486e, 0x84}, ++{0x486f, 0x36}, ++{0x4870, 0x00}, ++{0x4880, 0x00}, ++{0x4881, 0x00}, ++{0x4882, 0x00}, ++{0x4883, 0x00}, ++{0x4884, 0x08}, ++{0x4885, 0x00}, ++{0x4886, 0x00}, ++{0x4900, 0x08}, ++{0x4901, 0x00}, ++{0x4902, 0x00}, ++{0x4903, 0x80}, ++{0x4f00, 0xff}, ++{0x4f01, 0xff}, ++{0x4f04, 0x00}, ++{0x4f05, 0x01}, ++{0x5180, 0x04}, ++{0x5181, 0x00}, ++{0x5182, 0x04}, ++{0x5183, 0x00}, ++{0x5184, 0x04}, ++{0x5185, 0x00}, ++{0x5186, 0x04}, ++{0x5187, 0x00}, ++{0x5188, 0x00}, ++{0x5189, 0x00}, ++{0x518a, 0x00}, ++{0x518b, 0x10}, ++{0x51a0, 0x04}, ++{0x51a1, 0x00}, ++{0x51a2, 0x04}, ++{0x51a3, 0x00}, ++{0x51a4, 0x04}, ++{0x51a5, 0x00}, ++{0x51a6, 0x04}, ++{0x51a7, 0x00}, ++{0x51a8, 0x00}, ++{0x51a9, 0x00}, ++{0x51aa, 0x00}, ++{0x51ab, 0x10}, ++{0x51c0, 0x04}, ++{0x51c1, 0x00}, ++{0x51c2, 0x04}, ++{0x51c3, 0x00}, ++{0x51c4, 0x04}, ++{0x51c5, 0x00}, ++{0x51c6, 0x04}, ++{0x51c7, 0x00}, ++{0x51c8, 0x00}, ++{0x51c9, 0x00}, ++{0x51ca, 0x00}, ++{0x51cb, 0x10}, ++{0x5380, 0x19}, ++{0x5381, 0x94}, ++{0x5382, 0x2e}, ++{0x5383, 0x24}, ++{0x5384, 0x12}, ++{0x5385, 0x41}, ++{0x5386, 0x48}, ++{0x5387, 0x84}, ++{0x5388, 0x40}, ++{0x5389, 0x00}, ++{0x538a, 0x00}, ++{0x538b, 0x03}, ++{0x538c, 0x00}, ++{0x538d, 0x0f}, ++{0x538e, 0x00}, ++{0x538f, 0x3f}, ++{0x5390, 0x0f}, ++{0x5391, 0xfd}, ++{0x5392, 0xf5}, ++{0x5393, 0xf5}, ++{0x5394, 0x02}, ++{0x5395, 0xff}, ++{0x5396, 0x00}, ++{0x5397, 0x00}, ++{0x53a0, 0x41}, ++{0x53a2, 0x04}, ++{0x53a3, 0x00}, ++{0x53a4, 0x04}, ++{0x53a5, 0x00}, ++{0x53a6, 0x04}, ++{0x53a7, 0x00}, ++{0x53ac, 0x04}, ++{0x53ad, 0x00}, ++{0x53ae, 0x04}, ++{0x53af, 0x00}, ++{0x53b0, 0x04}, ++{0x53b1, 0x00}, ++{0x5400, 0x19}, ++{0x5401, 0x94}, ++{0x5402, 0x2e}, ++{0x5403, 0x24}, ++{0x5404, 0x12}, ++{0x5405, 0x41}, ++{0x5406, 0x48}, ++{0x5407, 0x84}, ++{0x5408, 0x40}, ++{0x5409, 0x00}, ++{0x540a, 0x00}, ++{0x540b, 0x03}, ++{0x540c, 0x00}, ++{0x540d, 0x0f}, ++{0x540e, 0x00}, ++{0x540f, 0x3f}, ++{0x5410, 0x0f}, ++{0x5411, 0xfd}, ++{0x5412, 0xf5}, ++{0x5413, 0xf5}, ++{0x5414, 0x02}, ++{0x5415, 0xff}, ++{0x5416, 0x00}, ++{0x5417, 0x00}, ++{0x5420, 0x41}, ++{0x5422, 0x04}, ++{0x5423, 0x00}, ++{0x5424, 0x04}, ++{0x5425, 0x00}, ++{0x5426, 0x04}, ++{0x5427, 0x00}, ++{0x542c, 0x04}, ++{0x542d, 0x00}, ++{0x542e, 0x04}, ++{0x542f, 0x00}, ++{0x5430, 0x04}, ++{0x5431, 0x00}, ++{0x5480, 0x19}, ++{0x5481, 0x94}, ++{0x5482, 0x2e}, ++{0x5483, 0x24}, ++{0x5484, 0x12}, ++{0x5485, 0x41}, ++{0x5486, 0x48}, ++{0x5487, 0x84}, ++{0x5488, 0x40}, ++{0x5489, 0x00}, ++{0x548a, 0x00}, ++{0x548b, 0x03}, ++{0x548c, 0x00}, ++{0x548d, 0x0f}, ++{0x548e, 0x00}, ++{0x548f, 0x3f}, ++{0x5490, 0x0f}, ++{0x5491, 0xfd}, ++{0x5492, 0xf5}, ++{0x5493, 0xf5}, ++{0x5494, 0x02}, ++{0x5495, 0xff}, ++{0x5496, 0x00}, ++{0x5497, 0x00}, ++{0x54a0, 0x41}, ++{0x54a2, 0x04}, ++{0x54a3, 0x00}, ++{0x54a4, 0x04}, ++{0x54a5, 0x00}, ++{0x54a6, 0x04}, ++{0x54a7, 0x00}, ++{0x54ac, 0x04}, ++{0x54ad, 0x00}, ++{0x54ae, 0x04}, ++{0x54af, 0x00}, ++{0x54b0, 0x04}, ++{0x54b1, 0x00}, ++{0x5800, 0x19}, ++{0x5801, 0x03}, ++{0x5802, 0x60}, ++{0x5803, 0xf0}, ++{0x5804, 0x00}, ++{0x5805, 0x40}, ++{0x5806, 0x01}, ++{0x5807, 0x00}, ++{0x5808, 0x60}, ++{0x5809, 0xf0}, ++{0x580a, 0x33}, ++{0x580b, 0x10}, ++{0x580c, 0x04}, ++{0x580d, 0x00}, ++{0x580e, 0x10}, ++{0x580f, 0x10}, ++{0x5810, 0x02}, ++{0x5811, 0x08}, ++{0x5812, 0x38}, ++{0x5813, 0x00}, ++{0x5814, 0x00}, ++{0x5815, 0x00}, ++{0x5816, 0x00}, ++{0x5000, 0x81}, ++{0x5001, 0x42}, ++{0x5002, 0x19}, ++{0x5003, 0x16}, ++{0x5004, 0x02}, ++{0x5005, 0x00}, ++{0x5006, 0x01}, ++{0x5007, 0x00}, ++{0x5008, 0x00}, ++{0x5009, 0x40}, ++{0x500a, 0x00}, ++{0x500b, 0x00}, ++{0x500c, 0x00}, ++{0x500d, 0x00}, ++{0x500e, 0x00}, ++{0x500f, 0x00}, ++{0x5010, 0x07}, ++{0x5011, 0x8f}, ++{0x5012, 0x05}, ++{0x5013, 0x0f}, ++{0x5014, 0x01}, ++{0x5015, 0x01}, ++{0x5016, 0x01}, ++{0x5017, 0x01}, ++{0x5018, 0x00}, ++{0x5019, 0x00}, ++{0x501a, 0x00}, ++{0x501b, 0x10}, ++{0x501c, 0x00}, ++{0x501d, 0x10}, ++{0x501e, 0x00}, ++{0x501f, 0x10}, ++{0x5020, 0x04}, ++{0x5021, 0x00}, ++{0x5022, 0x04}, ++{0x5023, 0x00}, ++{0x5024, 0x04}, ++{0x5025, 0x00}, ++{0x5026, 0x00}, ++{0x5027, 0x10}, ++{0x5028, 0x00}, ++{0x5029, 0x10}, ++{0x502a, 0x00}, ++{0x502b, 0x10}, ++{0x502c, 0x00}, ++{0x502d, 0x10}, ++{0x502e, 0x00}, ++{0x502f, 0x10}, ++{0x5030, 0x00}, ++{0x5031, 0x10}, ++{0x5032, 0x04}, ++{0x5033, 0x00}, ++{0x5034, 0x04}, ++{0x5035, 0x00}, ++{0x5036, 0x04}, ++{0x5037, 0x00}, ++{0x5038, 0x00}, ++{0x5039, 0x10}, ++{0x503a, 0x00}, ++{0x503b, 0x10}, ++{0x503c, 0x00}, ++{0x503d, 0x10}, ++{0x503e, 0x00}, ++{0x503f, 0x00}, ++{0x5040, 0x00}, ++{0x5041, 0x01}, ++{0x5042, 0x00}, ++{0x5043, 0x00}, ++{0x5600, 0x0f}, ++{0x5601, 0xab}, ++{0x5602, 0x02}, ++{0x5603, 0x58}, ++{0x5604, 0x03}, ++{0x5605, 0x20}, ++{0x5606, 0x02}, ++{0x5607, 0x58}, ++{0x5608, 0x03}, ++{0x5609, 0x20}, ++{0x560a, 0x02}, ++{0x560b, 0x58}, ++{0x560c, 0x03}, ++{0x560d, 0x20}, ++{0x560e, 0x02}, ++{0x560f, 0x58}, ++{0x5610, 0x03}, ++{0x5611, 0x20}, ++{0x5612, 0x02}, ++{0x5613, 0x58}, ++{0x5614, 0x03}, ++{0x5615, 0x20}, ++{0x5616, 0x02}, ++{0x5617, 0x58}, ++{0x5618, 0x03}, ++{0x5619, 0x20}, ++{0x5640, 0x0f}, ++{0x5641, 0xab}, ++{0x5642, 0x02}, ++{0x5643, 0x58}, ++{0x5644, 0x03}, ++{0x5645, 0x20}, ++{0x5646, 0x02}, ++{0x5647, 0x58}, ++{0x5648, 0x03}, ++{0x5649, 0x20}, ++{0x564a, 0x02}, ++{0x564b, 0x58}, ++{0x564c, 0x03}, ++{0x564d, 0x20}, ++{0x564e, 0x02}, ++{0x564f, 0x58}, ++{0x5650, 0x03}, ++{0x5651, 0x20}, ++{0x5652, 0x02}, ++{0x5653, 0x58}, ++{0x5654, 0x03}, ++{0x5655, 0x20}, ++{0x5656, 0x02}, ++{0x5657, 0x58}, ++{0x5658, 0x03}, ++{0x5659, 0x20}, ++{0x5680, 0x0f}, ++{0x5681, 0xab}, ++{0x5682, 0x02}, ++{0x5683, 0x58}, ++{0x5684, 0x03}, ++{0x5685, 0x20}, ++{0x5686, 0x02}, ++{0x5687, 0x58}, ++{0x5688, 0x03}, ++{0x5689, 0x20}, ++{0x568a, 0x02}, ++{0x568b, 0x58}, ++{0x568c, 0x03}, ++{0x568d, 0x20}, ++{0x568e, 0x02}, ++{0x568f, 0x58}, ++{0x5690, 0x03}, ++{0x5691, 0x20}, ++{0x5692, 0x02}, ++{0x5693, 0x58}, ++{0x5694, 0x03}, ++{0x5695, 0x20}, ++{0x5696, 0x02}, ++{0x5697, 0x58}, ++{0x5698, 0x03}, ++{0x5699, 0x20}, ++{0x5700, 0x00}, ++{0x5701, 0x00}, ++{0x5702, 0x00}, ++{0x5703, 0x00}, ++{0x5704, 0x02}, ++{0x5705, 0x80}, ++{0x5706, 0x01}, ++{0x5707, 0xe0}, ++{0x5708, 0x00}, ++{0x5709, 0x0e}, ++{0x5740, 0x00}, ++{0x5741, 0x00}, ++{0x5742, 0x00}, ++{0x5743, 0x00}, ++{0x5744, 0x02}, ++{0x5745, 0x80}, ++{0x5746, 0x01}, ++{0x5747, 0xe0}, ++{0x5748, 0x00}, ++{0x5749, 0x0e}, ++{0x5780, 0x00}, ++{0x5781, 0x00}, ++{0x5782, 0x00}, ++{0x5783, 0x00}, ++{0x5784, 0x02}, ++{0x5785, 0x80}, ++{0x5786, 0x01}, ++{0x5787, 0xe0}, ++{0x5788, 0x00}, ++{0x5789, 0x0e}, ++{0x5200, 0x70}, ++{0x5201, 0x80}, ++{0x5202, 0x73}, ++{0x5203, 0xff}, ++{0x5204, 0x02}, ++{0x5205, 0x6c}, ++{0x5206, 0x00}, ++{0x5207, 0x00}, ++{0x5209, 0x08}, ++{0x520a, 0x00}, ++{0x520b, 0x07}, ++{0x520c, 0x01}, ++{0x520d, 0x01}, ++{0x520e, 0x01}, ++{0x520f, 0x01}, ++{0x5210, 0x00}, ++{0x5211, 0x00}, ++{0x5212, 0x00}, ++{0x5213, 0x00}, ++{0x5214, 0x00}, ++{0x5215, 0x00}, ++{0x5216, 0x07}, ++{0x5217, 0x8b}, ++{0x5218, 0x00}, ++{0x5219, 0x00}, ++{0x5280, 0x00}, ++{0x5281, 0x00}, ++{0x5282, 0xff}, ++{0x5283, 0xff}, ++{0x5284, 0x02}, ++{0x5285, 0x6c}, ++{0x5286, 0x00}, ++{0x5287, 0x00}, ++{0x5289, 0x08}, ++{0x528a, 0x00}, ++{0x528b, 0x07}, ++{0x528c, 0x01}, ++{0x528d, 0x01}, ++{0x528e, 0x01}, ++{0x528f, 0x01}, ++{0x5290, 0x00}, ++{0x5291, 0x00}, ++{0x5292, 0x00}, ++{0x5293, 0x00}, ++{0x5294, 0x00}, ++{0x5295, 0x00}, ++{0x5296, 0x07}, ++{0x5297, 0x8b}, ++{0x5298, 0x00}, ++{0x5299, 0x00}, ++{0x5300, 0x00}, ++{0x5301, 0x00}, ++{0x5302, 0xff}, ++{0x5303, 0xff}, ++{0x5304, 0x02}, ++{0x5305, 0x6c}, ++{0x5306, 0x00}, ++{0x5307, 0x00}, ++{0x5309, 0x08}, ++{0x530a, 0x00}, ++{0x530b, 0x07}, ++{0x530c, 0x01}, ++{0x530d, 0x01}, ++{0x530e, 0x01}, ++{0x530f, 0x01}, ++{0x5310, 0x00}, ++{0x5311, 0x00}, ++{0x5312, 0x00}, ++{0x5313, 0x00}, ++{0x5314, 0x00}, ++{0x5315, 0x00}, ++{0x5316, 0x07}, ++{0x5317, 0x8b}, ++{0x5318, 0x00}, ++{0x5319, 0x00}, ++#ifdef OX03A_DISPLAY_PATTERN_COLOR_BAR ++{0x5080, 0x80}, /* Rolling test pattern for HCG */ ++#else ++{0x5080, 0x00}, ++#endif ++{0x5081, 0x01}, ++{0x5082, 0xb0}, ++{0x5083, 0x0f}, ++{0x5084, 0x00}, ++{0x5085, 0x00}, ++{0x5086, 0x00}, ++{0x5087, 0x01}, ++{0x5088, 0x00}, ++{0x5089, 0x00}, ++{0x508a, 0x00}, ++{0x508b, 0x00}, ++{0x508c, 0x00}, ++{0x508d, 0x00}, ++{0x508e, 0x00}, ++{0x508f, 0x00}, ++{0x5090, 0x00}, ++{0x5091, 0x00}, ++{0x5092, 0x00}, ++{0x5093, 0x00}, ++{0x5094, 0x00}, ++{0x5095, 0x00}, ++{0x5096, 0x00}, ++{0x5097, 0x00}, ++#ifdef OX03A_DISPLAY_PATTERN_COLOR_BAR ++{0x50c0, 0x80}, /* Rolling test pattern for LCG */ ++#else ++{0x50c0, 0x00}, ++#endif ++{0x50c1, 0x01}, ++{0x50c2, 0xb0}, ++{0x50c3, 0x0f}, ++{0x50c4, 0x00}, ++{0x50c5, 0x00}, ++{0x50c6, 0x00}, ++{0x50c7, 0x01}, ++{0x50c8, 0x00}, ++{0x50c9, 0x00}, ++{0x50ca, 0x00}, ++{0x50cb, 0x00}, ++{0x50cc, 0x00}, ++{0x50cd, 0x00}, ++{0x50ce, 0x00}, ++{0x50cf, 0x00}, ++{0x50d0, 0x00}, ++{0x50d1, 0x00}, ++{0x50d2, 0x00}, ++{0x50d3, 0x00}, ++{0x50d4, 0x00}, ++{0x50d5, 0x00}, ++{0x50d6, 0x00}, ++{0x50d7, 0x00}, ++#ifdef OX03A_DISPLAY_PATTERN_COLOR_BAR ++{0x5100, 0x80}, /* Rolling test pattern for VS */ ++#else ++{0x5100, 0x00}, ++#endif ++{0x5101, 0x01}, ++{0x5102, 0xb0}, ++{0x5103, 0x0f}, ++{0x5104, 0x00}, ++{0x5105, 0x00}, ++{0x5106, 0x00}, ++{0x5107, 0x01}, ++{0x5108, 0x00}, ++{0x5109, 0x00}, ++{0x510a, 0x00}, ++{0x510b, 0x00}, ++{0x510c, 0x00}, ++{0x510d, 0x00}, ++{0x510e, 0x00}, ++{0x510f, 0x00}, ++{0x5110, 0x00}, ++{0x5111, 0x00}, ++{0x5112, 0x00}, ++{0x5113, 0x00}, ++{0x5114, 0x00}, ++{0x5115, 0x00}, ++{0x5116, 0x00}, ++{0x5117, 0x00}, ++{0x380e, 0x05}, ++{0x380f, 0x34}, ++{0x380c, 0x06}, ++{0x380d, 0xcc}, ++{0x384c, 0x03}, ++{0x384d, 0xc0}, ++{0x4603, 0x01}, ++{0x4601, 0x00}, ++{0x3501, 0x01}, ++{0x0100, 0x01}, ++}; +diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c +new file mode 100644 +index 0000000..222db9b +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/ti9x4.c +@@ -0,0 +1,518 @@ ++ /* ++ * TI DS90UB954/960/964 FPDLinkIII driver ++ * ++ * Copyright (C) 2017-2018 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the @@ -6955,7 +16178,6 @@ index 0000000..bffd7c2 +#include <linux/module.h> +#include <linux/notifier.h> +#include <linux/of_gpio.h> -+#include <linux/regulator/consumer.h> +#include <linux/videodev2.h> + +#include <media/v4l2-common.h> @@ -6963,9 +16185,9 @@ index 0000000..bffd7c2 +#include <media/v4l2-of.h> +#include <media/v4l2-subdev.h> + -+#include "ti9x4_ti9x3.h" ++#include "ti9x4.h" + -+struct ti964_ti9x3_priv { ++struct ti9x4_priv { + struct v4l2_subdev sd[4]; + struct device_node *sd_of_node[4]; + int des_addr; @@ -6973,17 +16195,72 @@ index 0000000..bffd7c2 + int lanes; + int csi_rate; + const char *forwarding_mode; -+ const char *cable_mode; ++ int is_coax; ++ int dvp_bus; ++ int hsync; ++ int vsync; ++ int poc_delay; + atomic_t use_count; + struct i2c_client *client; + int ti9x3_addr_map[4]; + char chip_id[6]; -+ struct regulator *poc_supply[4]; /* PoC power supply */ ++ int ser_id; ++ struct gpio_desc *poc_gpio[4]; /* PoC power supply */ +}; + -+static void ti964_ti9x3_read_chipid(struct i2c_client *client) ++static int ser_id; ++module_param(ser_id, int, 0644); ++MODULE_PARM_DESC(ser_id, " Serializer ID (default: TI913)"); ++ ++static int is_stp; ++module_param(is_stp, int, 0644); ++MODULE_PARM_DESC(is_stp, " STP cable (default: Coax cable)"); ++ ++static int dvp_bus = 8; ++module_param(dvp_bus, int, 0644); ++MODULE_PARM_DESC(dvp_bus, " DVP/CSI over FPDLink (default: DVP 8-bit)"); ++ ++static int hsync; ++module_param(hsync, int, 0644); ++MODULE_PARM_DESC(hsync, " HSYNC invertion (default: 0 - not inverted)"); ++ ++static int vsync = 1; ++module_param(vsync, int, 0644); ++MODULE_PARM_DESC(vsync, " VSYNC invertion (default: 1 - inverted)"); ++ ++static int poc_delay; ++module_param(poc_delay, int, 0644); ++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms)"); ++ ++#ifdef TI954_SILICON_ERRATA ++static int indirect_write(struct i2c_client *client, unsigned int page, u8 reg, u8 val) +{ -+ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client); ++ if (page > 7) ++ return -EINVAL; ++ ++ reg8_write(client, 0xb0, page << 2); ++ reg8_write(client, 0xb1, reg); ++ reg8_write(client, 0xb2, val); ++ ++ return 0; ++} ++ ++static int indirect_read(struct i2c_client *client, unsigned int page, u8 reg, u8 *val) ++{ ++ if (page > 7) ++ return -EINVAL; ++ ++ reg8_write(client, 0xb0, page << 2); ++ reg8_write(client, 0xb1, reg); ++ reg8_read(client, 0xb2, val); ++ ++ return 0; ++} ++#endif ++ ++static void ti9x4_read_chipid(struct i2c_client *client) ++{ ++ struct ti9x4_priv *priv = i2c_get_clientdata(client); + + /* Chip ID */ + reg8_read(client, 0xf1, &priv->chip_id[0]); @@ -6994,12 +16271,12 @@ index 0000000..bffd7c2 + priv->chip_id[5] = '\0'; +} + -+static void ti964_ti9x3_initial_setup(struct i2c_client *client) ++static void ti9x4_initial_setup(struct i2c_client *client) +{ -+ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client); ++ struct ti9x4_priv *priv = i2c_get_clientdata(client); + + /* Initial setup */ -+ client->addr = priv->des_addr; /* TI964 I2C */ ++ client->addr = priv->des_addr; /* TI9x4 I2C */ + reg8_write(client, 0x08, 0x1c); /* I2C glitch filter depth */ + reg8_write(client, 0x0a, 0x79); /* I2C high pulse width */ + reg8_write(client, 0x0b, 0x79); /* I2C low pulse width */ @@ -7045,7 +16322,7 @@ index 0000000..bffd7c2 + reg8_write(client, 0x19, 2 >> 8); /* FrameSync high time MSB */ + reg8_write(client, 0x1a, 2 & 0xff); /* FrameSync high time LSB */ + reg8_write(client, 0x1b, FS_TIME >> 8); /* FrameSync low time MSB */ -+ reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */ ++ reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */ + reg8_write(client, 0x18, 0x01); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */ +#endif +} @@ -7053,45 +16330,81 @@ index 0000000..bffd7c2 +//#define SENSOR_ID 0x30 // ov10635 +//#define SENSOR_ID 0x24 // ov490 + -+static void ti964_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx) ++static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx) +{ -+ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client); ++ struct ti9x4_priv *priv = i2c_get_clientdata(client); ++ u8 port_config = 0x78; ++ u8 port_config2 = 0; + + /* FPDLinkIII setup */ -+ client->addr = priv->des_addr; /* TI964 I2C */ ++ client->addr = priv->des_addr; /* TI9x4 I2C */ + reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */ + usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x58, 0x58); /* Back channel: pass-through/backchannel/CRC enable, Freq=2.5Mbps */ ++ ++ switch (priv->ser_id) { ++ case TI913_ID: ++ reg8_write(client, 0x58, 0x58); /* Back channel: Freq=2.5Mbps */ ++ break; ++ case TI953_ID: ++ reg8_write(client, 0x58, 0x5e); /* Back channel: Freq=50Mbps */ ++ break; ++ default: ++ break; ++ } ++ + reg8_write(client, 0x5c, priv->ti9x3_addr_map[idx] << 1); /* TI9X3 I2C addr */ +// reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */ +// reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */ -+ if (strcmp(priv->cable_mode, "coax") == 0) { -+ reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */ -+ } else if (strcmp(priv->cable_mode, "stp") == 0) { -+ reg8_write(client, 0x6d, 0x78); /* STP, CSI */ ++ ++ if (priv->is_coax) ++ port_config |= 0x04; /* Coax */ ++ else ++ port_config |= 0x00; /* STP */ ++ ++ switch (priv->dvp_bus) { ++ case 8: ++ port_config2 |= 0x80; /* RAW10 as 8-bit prosessing using upper bits */ ++ /* fall through */ ++ case 10: ++ port_config |= 0x03; /* DVP over FPDLink (TI913 compatible) RAW10/RAW8 */ ++ break; ++ case 12: ++ port_config |= 0x02; /* DVP over FPDLink (TI913 compatible) RAW12 */ ++ break; ++ default: ++ port_config |= 0x00; /* CSI over FPDLink (TI953 compatible) */ + } ++ ++ if (priv->vsync) ++ port_config2 |= 0x01; /* VSYNC acive low */ ++ if (priv->hsync) ++ port_config2 |= 0x02; /* HSYNC acive low */ ++ ++ reg8_write(client, 0x6d, port_config); ++ reg8_write(client, 0x7c, port_config2); + reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */ -+ reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */ ++ reg8_write(client, 0x71, (idx << 6) | 0x2c); /* CSI data type: RAW12, assign VC */ ++ reg8_write(client, 0xbc, 0x00); /* Setup minimal time between FV and LV to 3 PCLKs */ + reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */ +} + -+static int ti964_ti9x3_initialize(struct i2c_client *client) ++static int ti9x4_initialize(struct i2c_client *client) +{ -+ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client); ++ struct ti9x4_priv *priv = i2c_get_clientdata(client); + int idx; + + dev_info(&client->dev, "LINKs=%d, LANES=%d, FORWARDING=%s, CABLE=%s, ID=%s\n", -+ priv->links, priv->lanes, priv->forwarding_mode, priv->cable_mode, priv->chip_id); ++ priv->links, priv->lanes, priv->forwarding_mode, priv->is_coax ? "coax" : "stp", priv->chip_id); + -+ ti964_ti9x3_initial_setup(client); ++ ti9x4_initial_setup(client); + + for (idx = 0; idx < priv->links; idx++) { -+ if (!IS_ERR(priv->poc_supply[idx])) { -+ if (regulator_enable(priv->poc_supply[idx])) -+ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); ++ if (!IS_ERR(priv->poc_gpio[idx])) { ++ gpiod_direction_output(priv->poc_gpio[idx], 1); /* POC power on */ ++ mdelay(priv->poc_delay); + } + -+ ti964_ti9x3_fpdlink3_setup(client, idx); ++ ti9x4_fpdlink3_setup(client, idx); + } + + client->addr = priv->des_addr; @@ -7100,10 +16413,10 @@ index 0000000..bffd7c2 +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG -+static int ti964_ti9x3_g_register(struct v4l2_subdev *sd, ++static int ti9x4_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ -+ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd); ++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd); + struct i2c_client *client = priv->client; + int ret; + u8 val = 0; @@ -7118,19 +16431,19 @@ index 0000000..bffd7c2 + return 0; +} + -+static int ti964_ti9x3_s_register(struct v4l2_subdev *sd, ++static int ti9x4_s_register(struct v4l2_subdev *sd, + const struct v4l2_dbg_register *reg) +{ -+ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd); ++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd); + struct i2c_client *client = priv->client; + + return reg8_write(client, (u8)reg->reg, (u8)reg->val); +} +#endif + -+static int ti964_ti9x3_s_power(struct v4l2_subdev *sd, int on) ++static int ti9x4_s_power(struct v4l2_subdev *sd, int on) +{ -+ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd); ++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd); + struct i2c_client *client = priv->client; + + if (on) { @@ -7144,9 +16457,9 @@ index 0000000..bffd7c2 + return 0; +} + -+static int ti964_ti9x3_registered_async(struct v4l2_subdev *sd) ++static int ti9x4_registered_async(struct v4l2_subdev *sd) +{ -+ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd); ++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd); + struct i2c_client *client = priv->client; + + reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4 | 0x1); /* enable CSI output, set CSI lane count, non-continuous CSI mode */ @@ -7154,31 +16467,31 @@ index 0000000..bffd7c2 + return 0; +} + -+static struct v4l2_subdev_core_ops ti964_ti9x3_subdev_core_ops = { ++static struct v4l2_subdev_core_ops ti9x4_subdev_core_ops = { +#ifdef CONFIG_VIDEO_ADV_DEBUG -+ .g_register = ti964_ti9x3_g_register, -+ .s_register = ti964_ti9x3_s_register, ++ .g_register = ti9x4_g_register, ++ .s_register = ti9x4_s_register, +#endif -+ .s_power = ti964_ti9x3_s_power, -+ .registered_async = ti964_ti9x3_registered_async, ++ .s_power = ti9x4_s_power, ++ .registered_async = ti9x4_registered_async, +}; + -+static struct v4l2_subdev_ops ti964_ti9x3_subdev_ops = { -+ .core = &ti964_ti9x3_subdev_core_ops, ++static struct v4l2_subdev_ops ti9x4_subdev_ops = { ++ .core = &ti9x4_subdev_core_ops, +}; + -+static int ti964_ti9x3_parse_dt(struct i2c_client *client) ++static int ti9x4_parse_dt(struct i2c_client *client) +{ -+ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client); ++ struct ti9x4_priv *priv = i2c_get_clientdata(client); + struct device_node *np = client->dev.of_node; + struct device_node *endpoint = NULL, *rendpoint = NULL; + struct property *prop; + int err, pwen, i; + int sensor_delay; + char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */ -+ char cable_mode_default[5] = "coax"; /* coax, stp */ + struct property *csi_rate_prop, *dvp_order_prop; + u8 val = 0; ++ char poc_name[10]; + + if (of_property_read_u32(np, "ti,links", &priv->links)) + priv->links = 4; @@ -7188,14 +16501,19 @@ index 0000000..bffd7c2 + + pwen = of_get_gpio(np, 0); + if (pwen > 0) { -+ err = devm_gpio_request_one(&client->dev, pwen, GPIOF_OUT_INIT_HIGH, dev_name(&client->dev)); ++ err = devm_gpio_request_one(&client->dev, pwen, GPIOF_OUT_INIT_LOW, dev_name(&client->dev)); + if (err) + dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err); + else + mdelay(250); + } + -+ reg8_read(client, 0x00, &val); /* read TI964 I2C address */ ++ for (i = 0; i < 4; i++) { ++ sprintf(poc_name, "POC%d", i); ++ priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, poc_name, 0); ++ } ++ ++ reg8_read(client, 0x00, &val); /* read TI9x4 I2C address */ + if (val != (priv->des_addr << 1)) { + prop = of_find_property(np, "reg", NULL); + if (prop) @@ -7203,18 +16521,47 @@ index 0000000..bffd7c2 + return -ENODEV; + } + -+ ti964_ti9x3_read_chipid(client); ++ ti9x4_read_chipid(client); + ++#ifdef TI954_SILICON_ERRATA ++ indirect_write(client, 7, 0x15, 0x30); ++ if (pwen > 0) ++ gpio_set_value(pwen, 1); ++ usleep_range(5000, 5500); /* wait 5ms */ ++ indirect_write(client, 7, 0x15, 0); ++#endif + if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay)) + mdelay(sensor_delay); -+ -+ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode); -+ if (err) ++ if (of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode)) + priv->forwarding_mode = forwarding_mode_default; ++ if (of_property_read_bool(np, "ti,stp")) ++ priv->is_coax = 0; ++ else ++ priv->is_coax = 1; ++ if (of_property_read_u32(np, "ti,dvp_bus", &priv->dvp_bus)) ++ priv->dvp_bus = 8; ++ if (of_property_read_u32(np, "ti,hsync", &priv->hsync)) ++ priv->vsync = 0; ++ if (of_property_read_u32(np, "ti,vsync", &priv->vsync)) ++ priv->vsync = 1; ++ if (of_property_read_u32(np, "ti,ser_id", &priv->ser_id)) ++ priv->ser_id = TI913_ID; ++ if (of_property_read_u32(np, "ti,poc-delay", &priv->poc_delay)) ++ priv->poc_delay = 50; + -+ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode); -+ if (err) -+ priv->cable_mode = cable_mode_default; ++ /* module params override dts */ ++ if (is_stp) ++ priv->is_coax = 0; ++ if (dvp_bus != 8) ++ priv->dvp_bus = dvp_bus; ++ if (hsync) ++ priv->hsync = hsync; ++ if (!vsync) ++ priv->vsync = vsync; ++ if (ser_id) ++ priv->ser_id = ser_id; ++ if (poc_delay) ++ priv->poc_delay = poc_delay; + + for (i = 0; ; i++) { + endpoint = of_graph_get_next_endpoint(np, endpoint); @@ -7249,12 +16596,11 @@ index 0000000..bffd7c2 + return 0; +} + -+static int ti964_ti9x3_probe(struct i2c_client *client, ++static int ti9x4_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ -+ struct ti964_ti9x3_priv *priv; ++ struct ti9x4_priv *priv; + int err, i; -+ char supply_name[10]; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) @@ -7265,21 +16611,16 @@ index 0000000..bffd7c2 + priv->client = client; + atomic_set(&priv->use_count, 0); + -+ err = ti964_ti9x3_parse_dt(client); ++ err = ti9x4_parse_dt(client); + if (err) + goto out; + -+ for (i = 0; i < 4; i++) { -+ sprintf(supply_name, "POC%d", i); -+ priv->poc_supply[i] = devm_regulator_get_optional(&client->dev, supply_name); -+ } -+ -+ err = ti964_ti9x3_initialize(client); ++ err = ti9x4_initialize(client); + if (err < 0) + goto out; + + for (i = 0; i < priv->links; i++) { -+ v4l2_subdev_init(&priv->sd[i], &ti964_ti9x3_subdev_ops); ++ v4l2_subdev_init(&priv->sd[i], &ti9x4_subdev_ops); + priv->sd[i].owner = client->dev.driver->owner; + priv->sd[i].dev = &client->dev; + priv->sd[i].grp_id = i; @@ -7299,9 +16640,9 @@ index 0000000..bffd7c2 + return err; +} + -+static int ti964_ti9x3_remove(struct i2c_client *client) ++static int ti9x4_remove(struct i2c_client *client) +{ -+ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client); ++ struct ti9x4_priv *priv = i2c_get_clientdata(client); + int i; + + for (i = 0; i < priv->links; i++) { @@ -7312,39 +16653,39 @@ index 0000000..bffd7c2 + return 0; +} + -+static const struct of_device_id ti964_ti9x3_dt_ids[] = { -+ { .compatible = "ti,ti964-ti9x3" }, ++static const struct of_device_id ti9x4_dt_ids[] = { ++ { .compatible = "ti,ti9x4" }, + {}, +}; -+MODULE_DEVICE_TABLE(of, ti964_ti9x3_dt_ids); ++MODULE_DEVICE_TABLE(of, ti9x4_dt_ids); + -+static const struct i2c_device_id ti964_ti9x3_id[] = { -+ { "ti964_ti9x3", 0 }, ++static const struct i2c_device_id ti9x4_id[] = { ++ { "ti9x4", 0 }, + { } +}; -+MODULE_DEVICE_TABLE(i2c, ti964_ti9x3_id); ++MODULE_DEVICE_TABLE(i2c, ti9x4_id); + -+static struct i2c_driver ti964_ti9x3_i2c_driver = { ++static struct i2c_driver ti9x4_i2c_driver = { + .driver = { -+ .name = "ti964_ti9x3", -+ .of_match_table = of_match_ptr(ti964_ti9x3_dt_ids), ++ .name = "ti9x4", ++ .of_match_table = of_match_ptr(ti9x4_dt_ids), + }, -+ .probe = ti964_ti9x3_probe, -+ .remove = ti964_ti9x3_remove, -+ .id_table = ti964_ti9x3_id, ++ .probe = ti9x4_probe, ++ .remove = ti9x4_remove, ++ .id_table = ti9x4_id, +}; + -+module_i2c_driver(ti964_ti9x3_i2c_driver); ++module_i2c_driver(ti9x4_i2c_driver); + -+MODULE_DESCRIPTION("FPDLinkIII driver for TI964-TI9X3"); ++MODULE_DESCRIPTION("FPDLinkIII driver for DS90UB9x4"); +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_LICENSE("GPL"); -diff --git a/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h +diff --git a/drivers/media/i2c/soc_camera/ti9x4.h b/drivers/media/i2c/soc_camera/ti9x4.h new file mode 100644 -index 0000000..69d3728 +index 0000000..b53b4c6 --- /dev/null -+++ b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h -@@ -0,0 +1,153 @@ ++++ b/drivers/media/i2c/soc_camera/ti9x4.h +@@ -0,0 +1,156 @@ +/* + * TI FPDLinkIII driver include file + * @@ -7366,6 +16707,9 @@ index 0000000..69d3728 +#endif + +#define MAXIM_NUM_RETRIES 1 /* number of read/write retries */ ++#define TI913_ID 0x58 ++#define TI953_ID 0x30 /* or starapped to 0x32 */ ++#define TI9X4_ID 0x00 /* strapped */ +#define BROADCAST 0x6f + +static inline int reg8_read(struct i2c_client *client, u8 reg, u8 *val) @@ -7499,7 +16843,7 @@ index 0000000..69d3728 +} +#endif /* _TI9X4_H */ diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c -index 4d95da6..2ef27e8 100644 +index 4d95da6..53fc644 100644 --- a/drivers/media/platform/soc_camera/rcar_csi2.c +++ b/drivers/media/platform/soc_camera/rcar_csi2.c @@ -37,8 +37,9 @@ @@ -7532,6 +16876,15 @@ index 4d95da6..2ef27e8 100644 #define RCAR_CSI2_PHYCNT_SHUTDOWNZ (1 << 17) #define RCAR_CSI2_PHYCNT_RSTZ (1 << 16) #define RCAR_CSI2_PHYCNT_ENABLECLK (1 << 4) +@@ -80,7 +86,7 @@ + + #define RCAR_CSI2_VCDT_VCDTN_EN (1 << 15) + #define RCAR_CSI2_VCDT_SEL_VCN (1 << 8) +-#define RCAR_CSI2_VCDT_SEL_DTN_ON (1 << 6) ++#define RCAR_CSI2_VCDT_SEL_DTN_ON (0 << 6) + #define RCAR_CSI2_VCDT_SEL_DTN (1 << 0) + + #define RCAR_CSI2_LINKCNT_MONITOR_EN (1 << 31) @@ -106,6 +112,9 @@ #define RCAR_CSI2_LSWAP_L0SEL_PLANE2 (2 << 0) #define RCAR_CSI2_LSWAP_L0SEL_PLANE3 (3 << 0) @@ -7865,7 +17218,7 @@ index 4d95da6..2ef27e8 100644 } return ret; -@@ -543,18 +642,19 @@ static int rcar_csi2_parse_dt(struct device_node *np, +@@ -543,39 +642,30 @@ static int rcar_csi2_parse_dt(struct device_node *np, return -EINVAL; v4l2_of_parse_endpoint(endpoint, &bus_cfg); @@ -7891,25 +17244,42 @@ index 4d95da6..2ef27e8 100644 for (i = 0; i < VC_MAX_CHANNEL; i++) { sprintf(csi_name, "csi2_vc%d", i); -@@ -573,6 +673,8 @@ static int rcar_csi2_parse_dt(struct device_node *np, - config->vcdt |= (0x24 << (i * 16)); - else if (!strcmp(str, "ycbcr422")) - config->vcdt |= (0x1e << (i * 16)); -+ else if (!strcmp(str, "raw8")) -+ config->vcdt |= (0x2a << (i * 16)); - else - config->vcdt |= 0; + vc_ch = of_get_child_by_name(vc_np, csi_name); + if (!vc_ch) + continue; +- ret = of_property_read_string(vc_ch, "data,type", &str); +- if (ret < 0) +- return ret; + ret = of_property_read_u32(vc_ch, "receive,vc", &ch); + if (ret < 0) + return ret; -@@ -587,6 +689,8 @@ static int rcar_csi2_parse_dt(struct device_node *np, - config->vcdt2 |= (0x24 << (j * 16)); - else if (!strcmp(str, "ycbcr422")) - config->vcdt2 |= (0x1e << (j * 16)); -+ else if (!strcmp(str, "raw8")) -+ config->vcdt2 |= (0x2a << (j * 16)); - else - config->vcdt2 |= 0; + if (i < 2) { +- if (!strcmp(str, "rgb888")) +- config->vcdt |= (0x24 << (i * 16)); +- else if (!strcmp(str, "ycbcr422")) +- config->vcdt |= (0x1e << (i * 16)); +- else +- config->vcdt |= 0; +- + config->vcdt |= (ch << (8 + (i * 16))); + config->vcdt |= (RCAR_CSI2_VCDT_VCDTN_EN << (i * 16)) | + (RCAR_CSI2_VCDT_SEL_DTN_ON << (i * 16)); +@@ -583,13 +673,6 @@ static int rcar_csi2_parse_dt(struct device_node *np, + if (i >= 2) { + int j = (i - 2); -@@ -608,6 +712,7 @@ static int rcar_csi2_probe(struct platform_device *pdev) +- if (!strcmp(str, "rgb888")) +- config->vcdt2 |= (0x24 << (j * 16)); +- else if (!strcmp(str, "ycbcr422")) +- config->vcdt2 |= (0x1e << (j * 16)); +- else +- config->vcdt2 |= 0; +- + config->vcdt2 |= (ch << (8 + (j * 16))); + config->vcdt2 |= (RCAR_CSI2_VCDT_VCDTN_EN << (j * 16)) | + (RCAR_CSI2_VCDT_SEL_DTN_ON << (j * 16)); +@@ -608,6 +691,7 @@ static int rcar_csi2_probe(struct platform_device *pdev) /* Platform data specify the PHY, lanes, ECC, CRC */ struct rcar_csi2_pdata *pdata; struct rcar_csi2_link_config link_config; @@ -7917,7 +17287,7 @@ index 4d95da6..2ef27e8 100644 dev_dbg(&pdev->dev, "CSI2 probed.\n"); -@@ -618,12 +723,7 @@ static int rcar_csi2_probe(struct platform_device *pdev) +@@ -618,12 +702,7 @@ static int rcar_csi2_probe(struct platform_device *pdev) if (ret) return ret; @@ -7931,7 +17301,7 @@ index 4d95da6..2ef27e8 100644 } else { pdata = pdev->dev.platform_data; if (!pdata) -@@ -655,23 +755,27 @@ static int rcar_csi2_probe(struct platform_device *pdev) +@@ -655,23 +734,27 @@ static int rcar_csi2_probe(struct platform_device *pdev) return ret; priv->pdev = pdev; @@ -7969,7 +17339,7 @@ index 4d95da6..2ef27e8 100644 spin_lock_init(&priv->lock); -@@ -684,10 +788,11 @@ static int rcar_csi2_probe(struct platform_device *pdev) +@@ -684,10 +767,11 @@ static int rcar_csi2_probe(struct platform_device *pdev) static int rcar_csi2_remove(struct platform_device *pdev) { @@ -7985,7 +17355,7 @@ index 4d95da6..2ef27e8 100644 return 0; diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c -index 74fb005..ac75af6 100644 +index 74fb005..f6119e5 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -95,17 +95,21 @@ @@ -8150,7 +17520,7 @@ index 74fb005..ac75af6 100644 while (priv->state != STOPPED) { /* issue stop if running */ if (priv->state == RUNNING) -@@ -1361,6 +1422,31 @@ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev) +@@ -1361,6 +1422,26 @@ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev) return NULL; } @@ -8158,8 +17528,7 @@ index 74fb005..ac75af6 100644 +{ + struct v4l2_subdev *sd; + char name[] = "max9286"; -+ char name2[] = "ti964_ti9x3"; -+ char name3[] = "ti954_ti9x3"; ++ char name2[] = "ti9x4"; + + v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) { + if (!strncmp(name, sd->name, sizeof(name) - 1)) { @@ -8170,10 +17539,6 @@ index 74fb005..ac75af6 100644 + pcdev->deser_sd = sd; + return sd; + } -+ if (!strncmp(name3, sd->name, sizeof(name3) - 1)) { -+ pcdev->deser_sd = sd; -+ return sd; -+ } + } + + return NULL; @@ -8182,7 +17547,7 @@ index 74fb005..ac75af6 100644 static int rcar_vin_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->parent); -@@ -1375,7 +1461,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) +@@ -1375,7 +1456,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || priv->chip == RCAR_V3M) { struct v4l2_subdev *csi2_sd = find_csi2(priv); @@ -8192,7 +17557,7 @@ index 74fb005..ac75af6 100644 if (csi2_sd) { csi2_sd->grp_id = soc_camera_grp_id(icd); -@@ -1390,6 +1477,18 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) +@@ -1390,6 +1472,18 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) return ret; } @@ -8211,7 +17576,7 @@ index 74fb005..ac75af6 100644 /* * -ENODEV is special: * either csi2_sd == NULL or the CSI-2 driver -@@ -1417,6 +1516,7 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) +@@ -1417,6 +1511,7 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) struct rcar_vin_priv *priv = ici->priv; struct vb2_v4l2_buffer *vbuf; struct v4l2_subdev *csi2_sd = find_csi2(priv); @@ -8219,7 +17584,7 @@ index 74fb005..ac75af6 100644 int i; /* disable capture, disable interrupts */ -@@ -1443,6 +1543,8 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) +@@ -1443,6 +1538,8 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) if ((csi2_sd) && (priv->csi_sync)) v4l2_subdev_call(csi2_sd, core, s_power, 0); @@ -8228,7 +17593,7 @@ index 74fb005..ac75af6 100644 dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n", icd->devnum); -@@ -1621,13 +1723,19 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd) +@@ -1621,13 +1718,19 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd) if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || priv->chip == RCAR_V3M) { @@ -8250,7 +17615,7 @@ index 74fb005..ac75af6 100644 (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV16) || (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV12)) iowrite32(ALIGN(cam->out_width, 0x20), -@@ -1868,6 +1976,14 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) +@@ -1868,6 +1971,14 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) .layout = SOC_MBUS_LAYOUT_PACKED, }, { @@ -8265,7 +17630,7 @@ index 74fb005..ac75af6 100644 .fourcc = V4L2_PIX_FMT_RGB565, .name = "RGB565", .bits_per_sample = 16, -@@ -1899,6 +2015,22 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) +@@ -1899,6 +2010,22 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) .order = SOC_MBUS_ORDER_LE, .layout = SOC_MBUS_LAYOUT_PACKED, }, @@ -8288,7 +17653,7 @@ index 74fb005..ac75af6 100644 }; static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, -@@ -2012,6 +2144,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, +@@ -2012,6 +2139,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YUYV10_2X10: case MEDIA_BUS_FMT_RGB888_1X24: @@ -8297,7 +17662,7 @@ index 74fb005..ac75af6 100644 if (cam->extra_fmt) break; -@@ -2218,12 +2352,15 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd, +@@ -2218,12 +2347,15 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd, case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YUYV: @@ -8313,7 +17678,7 @@ index 74fb005..ac75af6 100644 default: can_scale = false; break; -@@ -2316,7 +2453,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, +@@ -2316,7 +2448,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, /* odd number clipping by pixel post clip processing, */ /* it is outputted to a memory per even pixels. */ if ((pixfmt == V4L2_PIX_FMT_NV16) || (pixfmt == V4L2_PIX_FMT_NV12) || @@ -8323,7 +17688,7 @@ index 74fb005..ac75af6 100644 v4l_bound_align_image(&pix->width, 5, priv->max_width, 1, &pix->height, 2, priv->max_height, 0, 0); else -@@ -2486,6 +2624,19 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, +@@ -2486,6 +2619,19 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, } #endif @@ -8343,7 +17708,7 @@ index 74fb005..ac75af6 100644 static struct soc_camera_host_ops rcar_vin_host_ops = { .owner = THIS_MODULE, .add = rcar_vin_add_device, -@@ -2504,6 +2655,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, +@@ -2504,6 +2650,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, .get_selection = rcar_vin_get_selection, .cropcap = rcar_vin_cropcap, #endif @@ -8351,7 +17716,7 @@ index 74fb005..ac75af6 100644 }; #ifdef CONFIG_OF -@@ -2524,7 +2676,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, +@@ -2524,7 +2671,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, MODULE_DEVICE_TABLE(of, rcar_vin_of_table); #endif @@ -8360,19 +17725,18 @@ index 74fb005..ac75af6 100644 static DECLARE_BITMAP(device_map, MAP_MAX_NUM); static DEFINE_MUTEX(list_lock); -@@ -2714,7 +2866,11 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2714,7 +2861,10 @@ static int rcar_vin_probe(struct platform_device *pdev) const char *str; unsigned int i; struct device_node *epn = NULL, *ren = NULL; -+ struct device_node *csi2_ren = NULL, *max9286_ren = NULL, *ti964_ren = NULL, *ti954_ren = NULL; ++ struct device_node *csi2_ren = NULL, *max9286_ren = NULL, *ti9x4_ren = NULL; bool csi_use = false; + bool max9286_use = false; -+ bool ti964_use = false; -+ bool ti954_use = false; ++ bool ti9x4_use = false; match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev); -@@ -2741,13 +2897,27 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2741,13 +2891,22 @@ static int rcar_vin_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "node name:%s\n", of_node_full_name(ren->parent)); @@ -8390,21 +17754,16 @@ index 74fb005..ac75af6 100644 - if (i) - break; -+ if (strcmp(ren->parent->name, "ti964-ti9x3") == 0) { -+ ti964_ren = of_parse_phandle(epn, "remote-endpoint", 0); -+ ti964_use = true; -+ } -+ -+ if (strcmp(ren->parent->name, "ti954-ti9x3") == 0) { -+ ti954_ren = of_parse_phandle(epn, "remote-endpoint", 0); -+ ti954_use = true; ++ if (strcmp(ren->parent->name, "ti9x4") == 0) { ++ ti9x4_ren = of_parse_phandle(epn, "remote-endpoint", 0); ++ ti9x4_use = true; + } + + of_node_put(ren); } ret = v4l2_of_parse_endpoint(np, &ep); -@@ -2799,6 +2969,7 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2799,6 +2958,7 @@ static int rcar_vin_probe(struct platform_device *pdev) priv->ici.drv_name = dev_name(&pdev->dev); priv->ici.ops = &rcar_vin_host_ops; priv->csi_sync = false; @@ -8412,7 +17771,7 @@ index 74fb005..ac75af6 100644 priv->pdata_flags = pdata_flags; if (!match) { -@@ -2983,7 +3154,25 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2983,7 +3143,19 @@ static int rcar_vin_probe(struct platform_device *pdev) goto cleanup; if (csi_use) { @@ -8428,19 +17787,13 @@ index 74fb005..ac75af6 100644 + goto cleanup; + } + -+ if (ti964_use) { -+ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti964_ren); -+ if (ret) -+ goto cleanup; -+ } -+ -+ if (ti954_use) { -+ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti954_ren); ++ if (ti9x4_use) { ++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti9x4_ren); if (ret) goto cleanup; } diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c -index edd1c1d..54f4c9d 100644 +index edd1c1d..ae04c6e 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -49,7 +49,7 @@ @@ -8452,7 +17805,7 @@ index edd1c1d..54f4c9d 100644 static DECLARE_BITMAP(device_map, MAP_MAX_NUM); static LIST_HEAD(hosts); static LIST_HEAD(devices); -@@ -1106,6 +1106,18 @@ static int soc_camera_s_parm(struct file *file, void *fh, +@@ -1106,6 +1106,44 @@ static int soc_camera_s_parm(struct file *file, void *fh, return -ENOIOCTLCMD; } @@ -8468,10 +17821,36 @@ index edd1c1d..54f4c9d 100644 + return -ENOIOCTLCMD; +} + ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++static int soc_camera_g_register(struct file *file, void *priv, ++ struct v4l2_dbg_register *reg) ++{ ++ struct soc_camera_device *icd = file->private_data; ++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent); ++ ++ if (ici->ops->get_register) ++ return ici->ops->get_register(icd, reg); ++ ++ return -ENOIOCTLCMD; ++} ++ ++static int soc_camera_s_register(struct file *file, void *priv, ++ const struct v4l2_dbg_register *reg) ++{ ++ struct soc_camera_device *icd = file->private_data; ++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent); ++ ++ if (ici->ops->set_register) ++ return ici->ops->set_register(icd, reg); ++ ++ return -ENOIOCTLCMD; ++} ++#endif ++ static int soc_camera_probe(struct soc_camera_host *ici, struct soc_camera_device *icd); -@@ -1664,7 +1676,7 @@ static void scan_of_host(struct soc_camera_host *ici) +@@ -1664,7 +1702,7 @@ static void scan_of_host(struct soc_camera_host *ici) of_node_put(ren); if (i) { @@ -8480,16 +17859,20 @@ index edd1c1d..54f4c9d 100644 break; } } -@@ -2077,6 +2089,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd) +@@ -2077,6 +2115,11 @@ static int soc_camera_device_register(struct soc_camera_device *icd) .vidioc_s_selection = soc_camera_s_selection, .vidioc_g_parm = soc_camera_g_parm, .vidioc_s_parm = soc_camera_s_parm, + .vidioc_g_edid = soc_camera_g_edid, ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ .vidioc_g_register = soc_camera_g_register, ++ .vidioc_s_register = soc_camera_s_register, ++#endif }; static int video_dev_create(struct soc_camera_device *icd) diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c -index e3e665e..84754a4 100644 +index e3e665e..b47d515 100644 --- a/drivers/media/platform/soc_camera/soc_mediabus.c +++ b/drivers/media/platform/soc_camera/soc_mediabus.c @@ -57,6 +57,16 @@ @@ -8509,7 +17892,24 @@ index e3e665e..84754a4 100644 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555, -@@ -403,6 +413,10 @@ int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf, +@@ -382,6 +392,16 @@ + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, ++}, { ++ .code = MEDIA_BUS_FMT_SBGGR16_1X16, ++ .fmt = { ++ .fourcc = V4L2_PIX_FMT_SBGGR16, ++ .name = "Bayer 16 RGGB", ++ .bits_per_sample = 16, ++ .packing = SOC_MBUS_PACKING_NONE, ++ .order = SOC_MBUS_ORDER_LE, ++ .layout = SOC_MBUS_LAYOUT_PACKED, ++ }, + }, + }; + +@@ -403,6 +423,10 @@ int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf, *numerator = 2; *denominator = 1; return 0; @@ -8520,7 +17920,7 @@ index e3e665e..84754a4 100644 case SOC_MBUS_PACKING_1_5X8: *numerator = 3; *denominator = 2; -@@ -428,6 +442,8 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) +@@ -428,6 +452,8 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) case SOC_MBUS_PACKING_2X8_PADLO: case SOC_MBUS_PACKING_EXTEND16: return width * 2; @@ -8551,14 +17951,18 @@ index 2ff7737..e5f3f53 100644 SOC_MBUS_PACKING_VARIABLE, SOC_MBUS_PACKING_1_5X8, diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h -index 1a15c3e..dad1ed8 100644 +index 1a15c3e..76e90be 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h -@@ -125,6 +125,7 @@ struct soc_camera_host_ops { +@@ -125,6 +125,11 @@ struct soc_camera_host_ops { int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *); int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *); unsigned int (*poll)(struct file *, poll_table *); + int (*get_edid)(struct soc_camera_device *, struct v4l2_edid *); ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ int (*get_register)(struct soc_camera_device *, struct v4l2_dbg_register *reg); ++ int (*set_register)(struct soc_camera_device *, const struct v4l2_dbg_register *reg); ++#endif }; #define SOCAM_SENSOR_INVERT_PCLK (1 << 0) diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0035-regulator-fixed-probe-after-i2c.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0035-regulator-fixed-probe-after-i2c.patch deleted file mode 100644 index 31c79ce..0000000 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0035-regulator-fixed-probe-after-i2c.patch +++ /dev/null @@ -1,53 +0,0 @@ -From ef0ae334de1e1b318f4fb26bc8045451318a60c4 Mon Sep 17 00:00:00 2001 -From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> -Date: Sun, 26 Nov 2017 21:35:54 +0300 -Subject: [PATCH] regulator: fixed: probe after i2c - -This is a workaround for LVDS cameras that use I2C gpio expanders. -Set fixed regulator booted after i2c expander to have PoC -power controlled in LVDS driver. - -Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> ---- - drivers/Makefile | 4 +++- - drivers/regulator/fixed.c | 2 +- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/Makefile b/drivers/Makefile -index 194d20b..f49ed8f 100644 ---- a/drivers/Makefile -+++ b/drivers/Makefile -@@ -41,6 +41,8 @@ obj-y += soc/ - obj-$(CONFIG_VIRTIO) += virtio/ - obj-$(CONFIG_XEN) += xen/ - -+obj-y += i2c/ -+ - # regulators early, since some subsystems rely on them to initialize - obj-$(CONFIG_REGULATOR) += regulator/ - -@@ -105,7 +107,7 @@ obj-$(CONFIG_SERIO) += input/serio/ - obj-$(CONFIG_GAMEPORT) += input/gameport/ - obj-$(CONFIG_INPUT) += input/ - obj-$(CONFIG_RTC_LIB) += rtc/ --obj-y += i2c/ media/ -+obj-y += media/ - obj-$(CONFIG_PPS) += pps/ - obj-$(CONFIG_PTP_1588_CLOCK) += ptp/ - obj-$(CONFIG_W1) += w1/ -diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c -index 988a747..44a169c 100644 ---- a/drivers/regulator/fixed.c -+++ b/drivers/regulator/fixed.c -@@ -211,7 +211,7 @@ static int __init regulator_fixed_voltage_init(void) - { - return platform_driver_register(®ulator_fixed_voltage_driver); - } --subsys_initcall(regulator_fixed_voltage_init); -+module_init(regulator_fixed_voltage_init); - - static void __exit regulator_fixed_voltage_exit(void) - { --- -1.9.1 - diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch index 5387ae8..ce37154 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch @@ -1,4 +1,4 @@ -From 51718d8f768ba719a8a295e013e3456e13b70a98 Mon Sep 17 00:00:00 2001 +From c3908942394fed76f3f8272e3b2a77a465dbaf15 Mon Sep 17 00:00:00 2001 From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> Date: Fri, 14 Jul 2017 15:05:42 +0300 Subject: [PATCH] arm64: dts: renesas: add ADAS boards @@ -14,29 +14,35 @@ H3ULCB.HAD board on R8A7795 SoC Kingfisher board on R8A7795 ES1.x SoC Kingfisher board on R8A7795 SoC Kingfisher board on R8A7796 SoC -Kingfisher board on R8A7797 SoC +Kingfisher board on R8A7797 ES1.0/2.0 SoC Videobox board on R8A7795 ES1.x SoC Videobox board on R8A7795 SoC -Eagle board on R8A7797 SoC -Eagle Function board on R8A7797 SoC -V3MSK board on R8A7797 SoC -V3MSK.View board on R8A7797 SoC +Eagle board on R8A7797 ES1.0/2.0 SoC +Eagle Function board on R8A7797 ES1.0/2.0 SoC +V3MSK board on R8A7797 ES1.0/2.0 SoC +V3MSK.View board on R8A7797 ES1.0/2.0 SoC +V3MZF board on R8A7797 SoC Videobox Mini board on R8A7795 ES1.x SoC Videobox Mini board on R8A7795 SoC -Videobox Mini board on R8A7797 SoC +Videobox Mini board on R8A7797 ES1.0/2.0 SoC +Videobox Mini V2 board on R8A7797 ES1.0/2.0 SoC Videobox2 board on R8A7795 ES1.x SoC Videobox2 board on R8A7795 SoC +Condor board on R8A7798 SoC +V3HSK board on R8A7798 SoC +Videobox Mini board on R8A7798 SoC +Videobox Mini V2 board on R8A7798 SoC Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- - arch/arm64/boot/dts/renesas/Makefile | 20 + + arch/arm64/boot/dts/renesas/Makefile | 30 + arch/arm64/boot/dts/renesas/legacy/Makefile | 8 + - .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts | 1710 +++++++++++++++++++ - .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts | 441 +++++ - .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts | 1724 +++++++++++++++++++ - .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts | 465 +++++ - .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts | 1214 +++++++++++++ - .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts | 465 +++++ + .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts | 1624 +++++++++++++++++++ + .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts | 441 ++++++ + .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts | 1638 ++++++++++++++++++++ + .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts | 465 ++++++ + .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts | 1171 ++++++++++++++ + .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts | 465 ++++++ .../dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts | 82 + .../boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi | 75 + .../arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi | 77 + @@ -47,35 +53,51 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> .../boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts | 69 + .../boot/dts/renesas/r8a7795-es1-h3ulcb-vb2.dts | 77 + .../boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts | 26 + - .../boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 546 ++++++ - .../dts/renesas/r8a7795-es1-salvator-x-view.dts | 552 ++++++ + .../boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 544 +++++++ + .../dts/renesas/r8a7795-es1-salvator-x-view.dts | 550 +++++++ .../boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts | 22 + .../boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts | 23 + .../arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi | 215 +++ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 39 + arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts | 68 + - arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts | 68 + + arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts | 94 ++ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts | 26 + - .../arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 546 ++++++ - .../boot/dts/renesas/r8a7795-salvator-x-view.dts | 552 ++++++ + .../arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 544 +++++++ + .../boot/dts/renesas/r8a7795-salvator-x-view.dts | 550 +++++++ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 40 + - .../arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 287 ++++ - .../boot/dts/renesas/r8a7796-salvator-x-view.dts | 318 ++++ + .../arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 286 ++++ + .../boot/dts/renesas/r8a7796-salvator-x-view.dts | 317 ++++ .../boot/dts/renesas/r8a7797-eagle-function.dts | 62 + - arch/arm64/boot/dts/renesas/r8a7797-eagle.dts | 575 +++++++ - arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts | 578 +++++++ - arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts | 518 ++++++ - arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts | 298 ++++ - arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts | 314 ++++ - arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi | 545 ++++++ + arch/arm64/boot/dts/renesas/r8a7797-eagle.dts | 598 +++++++ + .../dts/renesas/r8a7797-es1-eagle-function.dts | 17 + + arch/arm64/boot/dts/renesas/r8a7797-es1-eagle.dts | 17 + + .../boot/dts/renesas/r8a7797-es1-v3msk-kf.dts | 17 + + .../boot/dts/renesas/r8a7797-es1-v3msk-vbm-v2.dts | 17 + + .../boot/dts/renesas/r8a7797-es1-v3msk-vbm.dts | 17 + + .../boot/dts/renesas/r8a7797-es1-v3msk-view.dts | 17 + + arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk.dts | 17 + + arch/arm64/boot/dts/renesas/r8a7797-es1.dtsi | 116 ++ + arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts | 520 +++++++ + .../boot/dts/renesas/r8a7797-v3msk-vbm-v2-isp.dts | 69 + + .../boot/dts/renesas/r8a7797-v3msk-vbm-v2.dts | 81 + + arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts | 507 ++++++ + arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts | 297 ++++ + arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts | 345 +++++ + arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts | 462 ++++++ + arch/arm64/boot/dts/renesas/r8a7798-condor.dts | 963 ++++++++++++ + .../boot/dts/renesas/r8a7798-v3hsk-vbm-v2-isp.dts | 70 + + .../boot/dts/renesas/r8a7798-v3hsk-vbm-v2.dts | 72 + + arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm.dts | 505 ++++++ + arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts | 358 +++++ + arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi | 462 ++++++ arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi | 30 + arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi | 46 + - arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 1542 +++++++++++++++++ - arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi | 515 ++++++ - arch/arm64/boot/dts/renesas/ulcb-vb.dtsi | 1726 +++++++++++++++++++ - arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi | 1792 ++++++++++++++++++++ - arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi | 578 +++++++ - 46 files changed, 19179 insertions(+) + arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 1456 +++++++++++++++++ + arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi | 459 ++++++ + arch/arm64/boot/dts/renesas/ulcb-vb.dtsi | 1610 +++++++++++++++++++ + arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi | 1605 +++++++++++++++++++ + arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi | 543 +++++++ + 62 files changed, 21226 insertions(+) create mode 100644 arch/arm64/boot/dts/renesas/legacy/Makefile create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts @@ -109,10 +131,26 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> create mode 100644 arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-eagle-function.dts create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-eagle.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1-eagle-function.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1-eagle.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-kf.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm-v2.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-view.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-es1.dtsi create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2-isp.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2.dts create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7798-condor.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2-isp.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm.dts + create mode 100644 arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi @@ -123,10 +161,10 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile -index f9c71df..1c63893 100644 +index f9c71df..077666a 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile -@@ -6,5 +6,25 @@ dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb +@@ -6,5 +6,35 @@ dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-xs.dtb @@ -142,10 +180,20 @@ index f9c71df..1c63893 100644 +dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.dtb r8a7795-es1-h3ulcb-vb2.dtb +dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vbm.dtb r8a7795-es1-h3ulcb-vbm.dtb +dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-eagle.dtb r8a7797-eagle-function.dtb -+dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk.dtb -+dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-view.dtb -+dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf.dtb -+dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-vbm.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-es1-eagle.dtb r8a7797-es1-eagle-function.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk.dtb r8a7797-es1-v3msk.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-view.dtb r8a7797-es1-v3msk-view.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf.dtb r8a7797-es1-v3msk-kf.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-vbm.dtb r8a7797-es1-v3msk-vbm.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-vbm-v2.dtb r8a7797-es1-v3msk-vbm-v2.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3mzf.dtb ++dtb-$(CONFIG_ARCH_R8A7798) += r8a7798-condor.dtb ++dtb-$(CONFIG_ARCH_R8A7798) += r8a7798-v3hsk.dtb ++dtb-$(CONFIG_ARCH_R8A7798) += r8a7798-v3hsk-vbm.dtb ++dtb-$(CONFIG_ARCH_R8A7798) += r8a7798-v3hsk-vbm-v2.dtb ++# boards with ISP ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-vbm-v2-isp.dtb ++dtb-$(CONFIG_ARCH_R8A7798) += r8a7798-v3hsk-vbm-v2-isp.dtb + +# ADAS legacy boards +subdir-y := legacy @@ -168,10 +216,10 @@ index 0000000..7f25079 +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts new file mode 100644 -index 0000000..fe07e22 +index 0000000..01aef82 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts -@@ -0,0 +1,1710 @@ +@@ -0,0 +1,1624 @@ +/* + * Device Tree Source for the H3ULCB Kingfisher V0 board on r8a7795 ES1.x + * @@ -760,11 +808,8 @@ index 0000000..fe07e22 + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ ov106xx_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -784,11 +829,8 @@ index 0000000..fe07e22 + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ ov106xx_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -808,8 +850,8 @@ index 0000000..fe07e22 + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -829,15 +871,15 @@ index 0000000..fe07e22 + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; @@ -846,60 +888,29 @@ index 0000000..fe07e22 + ti,cable-mode = "coax"; + + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_40_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@0 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ -+ port@0 { -+ ti954_des0ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in0>; -+ }; -+ ti954_des0ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in1>; -+ }; -+ }; -+ port@1 { -+ ti954_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -969,11 +980,8 @@ index 0000000..fe07e22 + ov106xx_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ ov106xx_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ ov106xx_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ ov106xx_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -993,11 +1001,8 @@ index 0000000..fe07e22 + ov106xx_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ ov106xx_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ ov106xx_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ ov106xx_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -1017,8 +1022,8 @@ index 0000000..fe07e22 + ov106xx_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ ov106xx_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ ov106xx_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -1038,15 +1043,15 @@ index 0000000..fe07e22 + ov106xx_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ ov106xx_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ ov106xx_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@1 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@1 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; @@ -1055,60 +1060,29 @@ index 0000000..fe07e22 + ti,cable-mode = "coax"; + + port@0 { -+ ti964_des1ep0: endpoint@0 { ++ ti9x4_des1ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in4>; + }; -+ ti964_des1ep1: endpoint@1 { ++ ti9x4_des1ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in5>; + }; -+ ti964_des1ep2: endpoint@2 { ++ ti9x4_des1ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in6>; + }; -+ ti964_des1ep3: endpoint@3 { ++ ti9x4_des1ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in7>; + }; + }; + port@1 { -+ ti964_csi2ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_41_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@1 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ -+ port@0 { -+ ti954_des1ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in4>; -+ }; -+ ti954_des1ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in5>; -+ }; -+ }; -+ port@1 { -+ ti954_csi2ep0: endpoint { ++ ti9x4_csi2ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_41_ep>; + }; @@ -1470,11 +1444,8 @@ index 0000000..fe07e22 + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ vin0_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -1504,11 +1475,8 @@ index 0000000..fe07e22 + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ vin1_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -1538,8 +1506,8 @@ index 0000000..fe07e22 + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -1569,8 +1537,8 @@ index 0000000..fe07e22 + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -1600,11 +1568,8 @@ index 0000000..fe07e22 + vin4_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ vin4_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ vin4_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ vin4_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -1634,11 +1599,8 @@ index 0000000..fe07e22 + vin5_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ vin5_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ vin5_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ vin5_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -1668,8 +1630,8 @@ index 0000000..fe07e22 + vin6_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ vin6_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ vin6_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -1699,8 +1661,8 @@ index 0000000..fe07e22 + vin7_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ vin7_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ vin7_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; @@ -2331,10 +2293,10 @@ index 0000000..ac6a12b +}; diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts new file mode 100644 -index 0000000..c19bc58 +index 0000000..dd1aadc --- /dev/null +++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts -@@ -0,0 +1,1724 @@ +@@ -0,0 +1,1638 @@ +/* + * Device Tree Source for the H3ULCB Kingfisher V0 board on r8a7795 + * @@ -2923,11 +2885,8 @@ index 0000000..c19bc58 + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ ov106xx_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -2947,11 +2906,8 @@ index 0000000..c19bc58 + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ ov106xx_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -2971,8 +2927,8 @@ index 0000000..c19bc58 + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -2992,15 +2948,15 @@ index 0000000..c19bc58 + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; @@ -3009,60 +2965,29 @@ index 0000000..c19bc58 + ti,cable-mode = "coax"; + + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_40_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@0 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ -+ port@0 { -+ ti954_des0ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in0>; -+ }; -+ ti954_des0ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in1>; -+ }; -+ }; -+ port@1 { -+ ti954_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -3132,11 +3057,8 @@ index 0000000..c19bc58 + ov106xx_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ ov106xx_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ ov106xx_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ ov106xx_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -3156,11 +3078,8 @@ index 0000000..c19bc58 + ov106xx_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ ov106xx_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ ov106xx_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ ov106xx_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -3180,8 +3099,8 @@ index 0000000..c19bc58 + ov106xx_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ ov106xx_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ ov106xx_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -3201,15 +3120,15 @@ index 0000000..c19bc58 + ov106xx_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ ov106xx_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ ov106xx_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@1 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@1 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; @@ -3218,60 +3137,29 @@ index 0000000..c19bc58 + ti,cable-mode = "coax"; + + port@0 { -+ ti964_des1ep0: endpoint@0 { ++ ti9x4_des1ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in4>; + }; -+ ti964_des1ep1: endpoint@1 { ++ ti9x4_des1ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in5>; + }; -+ ti964_des1ep2: endpoint@2 { ++ ti9x4_des1ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in6>; + }; -+ ti964_des1ep3: endpoint@3 { ++ ti9x4_des1ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in7>; + }; + }; + port@1 { -+ ti964_csi2ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_41_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@1 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ -+ port@0 { -+ ti954_des1ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in4>; -+ }; -+ ti954_des1ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in5>; -+ }; -+ }; -+ port@1 { -+ ti954_csi2ep0: endpoint { ++ ti9x4_csi2ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_41_ep>; + }; @@ -3640,11 +3528,8 @@ index 0000000..c19bc58 + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ vin0_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -3674,11 +3559,8 @@ index 0000000..c19bc58 + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ vin1_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -3708,8 +3590,8 @@ index 0000000..c19bc58 + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -3739,8 +3621,8 @@ index 0000000..c19bc58 + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -3770,11 +3652,8 @@ index 0000000..c19bc58 + vin4_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ vin4_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ vin4_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ vin4_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -3804,11 +3683,8 @@ index 0000000..c19bc58 + vin5_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ vin5_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ vin5_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ vin5_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -3838,8 +3714,8 @@ index 0000000..c19bc58 + vin6_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ vin6_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ vin6_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -3869,8 +3745,8 @@ index 0000000..c19bc58 + vin7_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ vin7_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ vin7_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; @@ -4532,10 +4408,10 @@ index 0000000..14b6f52 +}; diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts new file mode 100644 -index 0000000..8e7de0f +index 0000000..b17a42e --- /dev/null +++ b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts -@@ -0,0 +1,1214 @@ +@@ -0,0 +1,1171 @@ +/* + * Device Tree Source for the M3ULCB Kingfisher V0 board on r8a7796 + * @@ -5124,11 +5000,8 @@ index 0000000..8e7de0f + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ ov106xx_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -5148,11 +5021,8 @@ index 0000000..8e7de0f + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ ov106xx_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -5172,8 +5042,8 @@ index 0000000..8e7de0f + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -5193,15 +5063,15 @@ index 0000000..8e7de0f + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; @@ -5210,60 +5080,29 @@ index 0000000..8e7de0f + ti,cable-mode = "coax"; + + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_40_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@0 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ -+ port@0 { -+ ti954_des0ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in0>; -+ }; -+ ti954_des0ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in1>; -+ }; -+ }; -+ port@1 { -+ ti954_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -5495,11 +5334,8 @@ index 0000000..8e7de0f + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ vin0_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -5529,11 +5365,8 @@ index 0000000..8e7de0f + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ vin1_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -5563,8 +5396,8 @@ index 0000000..8e7de0f + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -5594,8 +5427,8 @@ index 0000000..8e7de0f + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -6994,10 +6827,10 @@ index 0000000..323722c +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts new file mode 100644 -index 0000000..6eb7cac +index 0000000..d91120e --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -@@ -0,0 +1,546 @@ +@@ -0,0 +1,544 @@ +/* + * Device Tree Source for the H3ULCB.View board on r8a7795 ES1.x + * @@ -7164,7 +6997,6 @@ index 0000000..6eb7cac + compatible = "maxim,max9286"; + reg = <0x4c>; + gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -7206,7 +7038,6 @@ index 0000000..6eb7cac + compatible = "maxim,max9286"; + reg = <0x6c>; + gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -7546,10 +7377,10 @@ index 0000000..6eb7cac +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts new file mode 100644 -index 0000000..d4caf46 +index 0000000..a00147c --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -@@ -0,0 +1,552 @@ +@@ -0,0 +1,550 @@ +/* + * Device Tree Source for the Salvator-X.View board on r8a7795 ES1.x + * @@ -7731,7 +7562,6 @@ index 0000000..d4caf46 + compatible = "maxim,max9286"; + reg = <0x4c>; + gpios = <&gpio6 30 GPIO_ACTIVE_LOW>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -7772,7 +7602,6 @@ index 0000000..d4caf46 + max9286@1 { + compatible = "maxim,max9286"; + reg = <0x6c>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -8501,10 +8330,10 @@ index 0000000..330bba2 +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts new file mode 100644 -index 0000000..e862d3e +index 0000000..726a2a6 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts -@@ -0,0 +1,68 @@ +@@ -0,0 +1,94 @@ +/* + * Device Tree Source for the H3ULCB Videobox board V2 on r8a7795 + * @@ -8533,6 +8362,13 @@ index 0000000..e862d3e + }; +}; + ++&pfc { ++ usb3_pins: usb3 { ++ groups = "usb3"; ++ function = "usb3"; ++ }; ++}; ++ +&du { + ports { + port@2 { @@ -8570,9 +8406,28 @@ index 0000000..e862d3e + }; +}; + ++&usb2_phy3 { ++ pinctrl-0 = <&usb3_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++}; ++ ++&ehci3 { ++ status = "okay"; ++}; ++ ++&ohci3 { ++ status = "okay"; ++}; ++ +&hsusb0 { + status = "okay"; +}; ++ ++&hsusb3 { ++ status = "okay"; ++}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts new file mode 100644 index 0000000..87f1889 @@ -8607,10 +8462,10 @@ index 0000000..87f1889 +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts new file mode 100644 -index 0000000..8541518 +index 0000000..d6adc07 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -@@ -0,0 +1,546 @@ +@@ -0,0 +1,544 @@ +/* + * Device Tree Source for the H3ULCB.View board + * @@ -8777,7 +8632,6 @@ index 0000000..8541518 + compatible = "maxim,max9286"; + reg = <0x4c>; + gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -8819,7 +8673,6 @@ index 0000000..8541518 + compatible = "maxim,max9286"; + reg = <0x6c>; + gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -9159,10 +9012,10 @@ index 0000000..8541518 +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts new file mode 100644 -index 0000000..14539ea +index 0000000..54c585d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -@@ -0,0 +1,552 @@ +@@ -0,0 +1,550 @@ +/* + * Device Tree Source for the Salvator-X.View board + * @@ -9344,7 +9197,6 @@ index 0000000..14539ea + compatible = "maxim,max9286"; + reg = <0x4c>; + gpios = <&gpio6 30 GPIO_ACTIVE_LOW>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -9385,7 +9237,6 @@ index 0000000..14539ea + max9286@1 { + compatible = "maxim,max9286"; + reg = <0x6c>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -9763,10 +9614,10 @@ index 0000000..a409402 +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts new file mode 100644 -index 0000000..ea7f378 +index 0000000..bfbd897 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts -@@ -0,0 +1,287 @@ +@@ -0,0 +1,286 @@ +/* + * Device Tree Source for the M3ULCB.View board on r8a7796 + * @@ -9861,7 +9712,6 @@ index 0000000..ea7f378 + compatible = "maxim,max9286"; + reg = <0x4c>; + gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -10056,10 +9906,10 @@ index 0000000..ea7f378 +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts new file mode 100644 -index 0000000..319120f +index 0000000..c515046 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts -@@ -0,0 +1,318 @@ +@@ -0,0 +1,317 @@ +/* + * Device Tree Source for the Salvator-X.View board + * @@ -10169,7 +10019,6 @@ index 0000000..319120f + compatible = "maxim,max9286"; + reg = <0x4c>; + gpios = <&gpio6 30 GPIO_ACTIVE_LOW>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -10448,10 +10297,10 @@ index 0000000..82d6513 +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts new file mode 100644 -index 0000000..ce7a88e +index 0000000..a982db9 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts -@@ -0,0 +1,575 @@ +@@ -0,0 +1,598 @@ +/* + * Device Tree Source for the Eagle board + * @@ -10598,8 +10447,6 @@ index 0000000..ce7a88e +}; + +&du { -+ pinctrl-0 = <&du_pins>; -+ pinctrl-names = "default"; + status = "okay"; + + ports { @@ -10652,11 +10499,6 @@ index 0000000..ce7a88e + groups = "avb0_mdc"; + function = "avb0"; + }; -+ -+ du_pins: du { -+ groups = "du_rgb666", "du_sync", "du_clk_out_0", "du_disp"; -+ function = "du"; -+ }; +}; + +&scif0 { @@ -10716,6 +10558,36 @@ index 0000000..ce7a88e + gpio-controller; + #gpio-cells = <2>; + }; ++ ++ pmic@5A { ++ compatible = "dlg,da9063"; ++ reg = <0x5A>; ++ interrupt-parent = <&intc_ex>; ++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; ++ ++ rtc { ++ compatible = "dlg,da9063-rtc"; ++ }; ++ ++ wdt { ++ compatible = "dlg,da9063-watchdog"; ++ }; ++ ++ regulators { ++ DA9063_LDO11: bmem { ++ regulator-name = "bmem"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ }; ++ ++ onkey { ++ compatible = "dlg,da9063-onkey"; ++ }; ++ }; +}; + +&i2c3 { @@ -11027,12 +10899,295 @@ index 0000000..ce7a88e + }; + }; +}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1-eagle-function.dts b/arch/arm64/boot/dts/renesas/r8a7797-es1-eagle-function.dts +new file mode 100644 +index 0000000..74351b8 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1-eagle-function.dts +@@ -0,0 +1,17 @@ ++/* ++ * Device Tree Source for the Eagle Function board on r8a7797 ES1.0 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-eagle-function.dts" ++#include "r8a7797-es1.dtsi" ++ ++/ { ++ model = "Renesas Eagle Function board based on r8a7797 ES1.0"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1-eagle.dts b/arch/arm64/boot/dts/renesas/r8a7797-es1-eagle.dts +new file mode 100644 +index 0000000..f65f69d +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1-eagle.dts +@@ -0,0 +1,17 @@ ++/* ++ * Device Tree Source for the Eagle board on r8a7797 ES1.0 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-eagle.dts" ++#include "r8a7797-es1.dtsi" ++ ++/ { ++ model = "Renesas Eagle board based on r8a7797 ES1.0"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-kf.dts +new file mode 100644 +index 0000000..c811e6f +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-kf.dts +@@ -0,0 +1,17 @@ ++/* ++ * Device Tree Source for the V3MSK Kingfisher board on r8a7797 ES1.0 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-v3msk-kf.dts" ++#include "r8a7797-es1.dtsi" ++ ++/ { ++ model = "Renesas V3MSK Kingfisher board based on r8a7797 ES1.0"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm-v2.dts b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm-v2.dts +new file mode 100644 +index 0000000..c6fcffd +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm-v2.dts +@@ -0,0 +1,17 @@ ++/* ++ * Device Tree Source for the V3MSK Videobox Mini V2 board on r8a7797 ES1.0 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-v3msk-vbm-v2.dts" ++#include "r8a7797-es1.dtsi" ++ ++/ { ++ model = "Renesas V3MSK Videobox Mini V2 board based on r8a7797 ES1.0"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm.dts +new file mode 100644 +index 0000000..90b7439 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-vbm.dts +@@ -0,0 +1,17 @@ ++/* ++ * Device Tree Source for the V3MSK Videobox Mini board on r8a7797 ES1.0 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-v3msk-vbm.dts" ++#include "r8a7797-es1.dtsi" ++ ++/ { ++ model = "Renesas V3MSK Videobox Mini board based on r8a7797 ES1.0"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-view.dts b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-view.dts +new file mode 100644 +index 0000000..576d21c +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk-view.dts +@@ -0,0 +1,17 @@ ++/* ++ * Device Tree Source for the V3MSK View board on r8a7797 ES1.0 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-v3msk-view.dts" ++#include "r8a7797-es1.dtsi" ++ ++/ { ++ model = "Renesas V3MSK View board based on r8a7797 ES1.0"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk.dts +new file mode 100644 +index 0000000..3257d7e +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1-v3msk.dts +@@ -0,0 +1,17 @@ ++/* ++ * Device Tree Source for the V3M Starter Kit board on r8a7797 ES1.0 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-v3msk.dts" ++#include "r8a7797-es1.dtsi" ++ ++/ { ++ model = "Renesas V3M Starter Kit board based on r8a7797 ES1.0"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7797-es1.dtsi +new file mode 100644 +index 0000000..dab9adc +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-es1.dtsi +@@ -0,0 +1,116 @@ ++/* ++ * Device Tree Source for the r8a7797 SoC ES1.0 SoC ++ * (append to r8a7797 SoC ES2.0 SoC) ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++/ { ++ soc { ++ imp_distributer: impdes0 { ++ compatible = "renesas,impx4-distributer"; ++ reg = <0 0xffa00000 0 0x10000>; ++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 830>; ++ power-domains = <&sysc R8A7797_PD_A3IR>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ }; ++ ++ imp0 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff900000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <0>; ++ clocks = <&cpg CPG_MOD 827>; ++ power-domains = <&sysc R8A7797_PD_A2IR0>; ++ }; ++ ++ imp1 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff920000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <1>; ++ clocks = <&cpg CPG_MOD 826>; ++ power-domains = <&sysc R8A7797_PD_A2IR1>; ++ }; ++ ++ imp2 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff940000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <2>; ++ clocks = <&cpg CPG_MOD 825>; ++ power-domains = <&sysc R8A7797_PD_A2IR2>; ++ }; ++ ++ imp3 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff960000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <3>; ++ clocks = <&cpg CPG_MOD 824>; ++ power-domains = <&sysc R8A7797_PD_A2IR3>; ++ }; ++ ++ impsc0 { ++ compatible = "renesas,impx4-shader"; ++ reg = <0 0xff980000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <4>; ++ clocks = <&cpg CPG_MOD 829>; ++ power-domains = <&sysc R8A7797_PD_A2SC0>; ++ }; ++ ++ impsc1 { ++ compatible = "renesas,impx4-shader"; ++ reg = <0 0xff990000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <5>; ++ clocks = <&cpg CPG_MOD 828>; ++ power-domains = <&sysc R8A7797_PD_A2SC1>; ++ }; ++ ++ impdm0 { ++ compatible = "renesas,impx5-dmac"; ++ reg = <0 0xffa10000 0 0x1000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <16>; ++ clocks = <&cpg CPG_MOD 830>; ++ power-domains = <&sysc R8A7797_PD_A3IR>; ++ }; ++ ++ impdm1 { ++ compatible = "renesas,impx5-dmac"; ++ reg = <0 0xffa10000 0 0x1000>, ++ <0 0xffa10800 0 0x0800>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <17>; ++ clocks = <&cpg CPG_MOD 830>; ++ power-domains = <&sysc R8A7797_PD_A3IR>; ++ }; ++ ++ imppsc0 { ++ compatible = "renesas,impx5+-psc"; ++ reg = <0 0xffa20000 0 0x4000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <12>; ++ clocks = <&cpg CPG_MOD 830>; ++ power-domains = <&sysc R8A7797_PD_A3IR>; ++ }; ++ ++ /delete-node/impcnn0; ++ ++ impc0 { ++ compatible = "renesas,impx4-memory"; ++ reg = <0 0xed000000 0 0xe0000>; ++ clocks = <&cpg CPG_MOD 830>; ++ power-domains = <&sysc R8A7797_PD_A3IR>; ++ }; ++ }; ++}; diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts new file mode 100644 -index 0000000..b92fe83 +index 0000000..862236f --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts -@@ -0,0 +1,578 @@ +@@ -0,0 +1,520 @@ +/* + * Device Tree Source for the V3MSK Kingfisher board on r8a7797 + * @@ -11138,11 +11293,8 @@ index 0000000..b92fe83 + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ ov106xx_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -11162,11 +11314,8 @@ index 0000000..b92fe83 + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ ov106xx_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -11186,8 +11335,8 @@ index 0000000..b92fe83 + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -11207,77 +11356,50 @@ index 0000000..b92fe83 + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; -+ ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "coax"; + ++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; ++ + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { -+ csi-rate = <800>; -+ remote-endpoint = <&csi2_40_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@0 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ -+ port@0 { -+ ti954_des0ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in0>; -+ }; -+ ti954_des0ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in1>; -+ }; -+ }; -+ port@1 { -+ ti954_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <800>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -11288,13 +11410,17 @@ index 0000000..b92fe83 + max9286@0 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; + ++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; ++ + port@0 { + max9286_des0ep0: endpoint@0 { + max9271-addr = <0x50>; @@ -11332,9 +11458,10 @@ index 0000000..b92fe83 + reg = <6>; + /* Slot B (CN11) */ + -+ video_a_ext0: pca9535@27 { ++ /* PCA9535 is a redundant/deprecated card */ ++ gpio_exp_a_26: gpio@26 { + compatible = "nxp,pca9535"; -+ reg = <0x27>; ++ reg = <0x26>; + gpio-controller; + #gpio-cells = <2>; + @@ -11394,7 +11521,7 @@ index 0000000..b92fe83 + }; + }; + -+ video_a_ext1: max7325@5c { ++ gpio_exp_a_5c: gpio@5c { + compatible = "maxim,max7325"; + reg = <0x5c>; + gpio-controller; @@ -11424,30 +11551,6 @@ index 0000000..b92fe83 + output-high; + line-name = "Video-A PWR_SHDN"; + }; -+ video_a_cam_pwr0 { -+ gpio-hog; -+ gpios = <8 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR0"; -+ }; -+ video_a_cam_pwr1 { -+ gpio-hog; -+ gpios = <9 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR1"; -+ }; -+ video_a_cam_pwr2 { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR2"; -+ }; -+ video_a_cam_pwr3 { -+ gpio-hog; -+ gpios = <11 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR3"; -+ }; + video_a_des_shdn { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; @@ -11506,11 +11609,8 @@ index 0000000..b92fe83 + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ vin0_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -11540,11 +11640,8 @@ index 0000000..b92fe83 + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ vin1_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -11574,8 +11671,8 @@ index 0000000..b92fe83 + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -11605,20 +11702,20 @@ index 0000000..b92fe83 + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; +}; -diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2-isp.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2-isp.dts new file mode 100644 -index 0000000..26f8c70 +index 0000000..2d95bc9 --- /dev/null -+++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts -@@ -0,0 +1,518 @@ ++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2-isp.dts +@@ -0,0 +1,69 @@ +/* -+ * Device Tree Source for the V3MSK Videobox Mini board on r8a7797 ++ * Device Tree Source for the V3MSK Videobox Mini V2 board on r8a7797 + * + * Copyright (C) 2017 Cogent Embedded, Inc. + * @@ -11627,49 +11724,175 @@ index 0000000..26f8c70 + * kind, whether express or implied. + */ + -+#include "r8a7797-v3msk.dts" ++#include "r8a7797-v3msk-vbm-v2.dts" ++ ++&ov106xx_in0 { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&isp0ep0>; ++}; ++ ++&ti9x4_csi0ep0 { ++ csi-rate = <1450>; ++ remote-endpoint = <&csi2_40_ep>; ++}; ++ ++&isp0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ isp0ep0: endpoint { ++ csi,select = "csi40"; ++ virtual,channel = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ }; ++ port@1 { ++ csi0isp0ep0: endpoint { ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ port@2 { ++ isp0_max9286_des0ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep0>; ++ }; ++ isp0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; ++ }; ++ }; ++ }; ++}; ++ ++&vin0 { ++ status = "disabled"; ++}; ++ ++&vin1 { ++ status = "disabled"; ++}; ++ ++&vin2 { ++ status = "disabled"; ++}; ++ ++&vin3 { ++ status = "disabled"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2.dts +new file mode 100644 +index 0000000..74a3df6 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm-v2.dts +@@ -0,0 +1,81 @@ ++/* ++ * Device Tree Source for the V3MSK Videobox Mini board V2 on r8a7797 ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-v3msk-vbm.dts" + +/ { -+ model = "Renesas V3MSK Videobox Mini board based on r8a7797"; ++ model = "Renesas V3MSK Videobox Mini board V2 based on r8a7797"; + -+ aliases { -+ serial1 = &scif3; ++ leds { ++ compatible = "gpio-leds"; ++ ++ led5 { ++ label = "board:status"; ++ gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; + }; ++}; + -+ pwr0: regulator-pwr0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR0"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++&gpio0 { ++ /delete-node/can0stby; ++ ++ can0_stby { ++ gpio-hog; ++ gpios = <12 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "CAN0STBY"; + }; + -+ pwr1: regulator-pwr1 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR1"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++ can1_stby { ++ gpio-hog; ++ gpios = <14 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "CAN1STBY"; + }; ++}; + -+ pwr2: regulator-pwr2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR2"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++&pfc { ++ msiof1_pins: msiof1 { ++ groups = "msiof1_clk", "msiof1_sync", "msiof1_txd", "msiof1_rxd"; ++ function = "msiof1"; + }; + -+ pwr3: regulator-pwr3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR3"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++ msiof2_pins: msiof2 { ++ groups = "msiof2_clk", "msiof2_sync", "msiof2_txd", "msiof2_rxd"; ++ function = "msiof2"; ++ }; ++}; ++ ++&scif3 { ++ /* pin conflict with msiof2 */ ++ /* set R240 and remove R241 before enabling */ ++ status = "disabled"; ++}; ++ ++&msiof1 { ++ pinctrl-0 = <&msiof1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ spidev@0 { ++ compatible = "renesas,sh-msiof"; ++ reg = <0>; ++ spi-max-frequency = <66666666>; ++ }; ++}; ++ ++&msiof2 { ++ pinctrl-0 = <&msiof2_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ spi-slave; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts +new file mode 100644 +index 0000000..70c0f66 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts +@@ -0,0 +1,507 @@ ++/* ++ * Device Tree Source for the V3MSK Videobox Mini board on r8a7797 ++ * ++ * Copyright (C) 2017 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7797-v3msk.dts" ++ ++/ { ++ model = "Renesas V3MSK Videobox Mini board based on r8a7797"; ++ ++ aliases { ++ serial1 = &scif3; + }; +}; + @@ -11755,8 +11978,8 @@ index 0000000..26f8c70 + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -11776,8 +11999,8 @@ index 0000000..26f8c70 + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -11797,8 +12020,8 @@ index 0000000..26f8c70 + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -11818,8 +12041,8 @@ index 0000000..26f8c70 + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -11827,16 +12050,16 @@ index 0000000..26f8c70 + max9286@0 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; -+ POC0-supply = <&pwr0>; -+ POC1-supply = <&pwr1>; -+ POC2-supply = <&pwr2>; -+ POC3-supply = <&pwr3>; ++ ++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; + + port@0 { + max9286_des0ep0: endpoint@0 { @@ -11868,43 +12091,42 @@ index 0000000..26f8c70 + }; + }; + -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; -+ ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "coax"; -+ POC0-supply = <&pwr0>; -+ POC1-supply = <&pwr1>; -+ POC2-supply = <&pwr2>; -+ POC3-supply = <&pwr3>; ++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; + + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <700>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -11955,6 +12177,18 @@ index 0000000..26f8c70 + }; + }; + }; ++ ++ i2c@3 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <3>; ++ ++ /* fan node - lm96063 */ ++ fan_ctrl: lm96063@4c { ++ compatible = "lm96163"; ++ reg = <0x4c>; ++ }; ++ }; + }; +}; + @@ -11981,6 +12215,20 @@ index 0000000..26f8c70 + output-low; + line-name = "can0_120R_load"; + }; ++ ++ wake_pin_7 { ++ gpio-hog; ++ gpios = <8 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "WAKE INPUT PIN 7"; ++ }; ++ ++ wake_pin_8 { ++ gpio-hog; ++ gpios = <9 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "WAKE INPUT PIN 8"; ++ }; +}; + +&pfc { @@ -12036,8 +12284,8 @@ index 0000000..26f8c70 + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -12067,8 +12315,8 @@ index 0000000..26f8c70 + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -12098,8 +12346,8 @@ index 0000000..26f8c70 + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -12129,18 +12377,18 @@ index 0000000..26f8c70 + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts new file mode 100644 -index 0000000..6f82385 +index 0000000..58f82bf --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts -@@ -0,0 +1,298 @@ +@@ -0,0 +1,297 @@ +/* + * Device Tree Source for the V3MSK View board on r8a7797 + * @@ -12274,7 +12522,6 @@ index 0000000..6f82385 + compatible = "maxim,max9286"; + reg = <0x6c>; + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; -+ maxim,sensor_delay = <0>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; @@ -12441,10 +12688,10 @@ index 0000000..6f82385 +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts new file mode 100644 -index 0000000..91d10c5 +index 0000000..33c6c0d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts -@@ -0,0 +1,314 @@ +@@ -0,0 +1,345 @@ +/* + * Device Tree Source for the V3M Starter Kit board on r8a7797 + * @@ -12477,7 +12724,7 @@ index 0000000..91d10c5 + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ -+ reg = <0x0 0x48000000 0x0 0x38000000>; ++ reg = <0x0 0x48000000 0x0 0x78000000>; + }; + + reserved-memory { @@ -12574,7 +12821,7 @@ index 0000000..91d10c5 + + port { + hdmi_con: endpoint { -+ remote-endpoint = <&adv7511_out>; ++ remote-endpoint = <&adv7511_out>; + }; + }; + }; @@ -12712,6 +12959,37 @@ index 0000000..91d10c5 + }; + }; + }; ++ ++ pmic@5A { ++ compatible = "dlg,da9063"; ++ reg = <0x5A>; ++ interrupt-parent = <&intc_ex>; ++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; ++ ++ rtc { ++ compatible = "dlg,da9063-rtc"; ++ }; ++ ++ wdt { ++ compatible = "dlg,da9063-watchdog"; ++ }; ++ ++ regulators { ++ DA9063_LDO11: bmem { ++ regulator-name = "bmem"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ }; ++ ++ onkey { ++ compatible = "dlg,da9063-onkey"; ++ }; ++ }; ++ +}; + +&wdt0 { @@ -12759,63 +13037,2491 @@ index 0000000..91d10c5 + non-removable; + status = "okay"; +}; -diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts new file mode 100644 -index 0000000..b469ca6 +index 0000000..71d7bad --- /dev/null -+++ b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi -@@ -0,0 +1,545 @@ ++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts +@@ -0,0 +1,462 @@ +/* -+ * Device Tree Source for the H3ULCB Kingfisher board: -+ * this adding conflicting resource on VIN4/VIN5/VIN6/VIN7 for CN11 -+ * use CN11 instead default CN29/CN48 ++ * Device Tree Source for the V3MZF board + * -+ * Copyright (C) 2017 Renesas Electronics Corp. -+ * Copyright (C) 2017 Cogent Embedded, Inc. ++ * Copyright (C) 2018 Cogent Embedded, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + ++/dts-v1/; ++#include "r8a7797.dtsi" ++#include <dt-bindings/gpio/gpio.h> ++ +/ { -+ pwr0B: regulator-pwr0B { ++ model = "Renesas V3MZF board based on r8a7797"; ++ compatible = "renesas,v3mzf", "renesas,r8a7797"; ++ ++ aliases { ++ serial0 = &scif0; ++ ethernet0 = &avb; ++ }; ++ ++ chosen { ++ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp"; ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ memory@48000000 { ++ device_type = "memory"; ++ /* first 128MB is reserved for secure area. */ ++ reg = <0x0 0x48000000 0x0 0x38000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ /* device specific region for Lossy Decompression */ ++ lossy_decompress: linux,lossy_decompress { ++ no-map; ++ reg = <0x00000000 0x6c000000 0x0 0x03000000>; ++ }; ++ ++ /* global autoconfigured region for contiguous allocations */ ++ linux,cma { ++ compatible = "shared-dma-pool"; ++ reusable; ++ reg = <0x00000000 0x6f000000 0x0 0x11000000>; ++ linux,cma-default; ++ }; ++ }; ++ ++ mmngr { ++ compatible = "renesas,mmngr"; ++ memory-region = <&lossy_decompress>; ++ }; ++ ++ mmngrbuf { ++ compatible = "renesas,mmngrbuf"; ++ }; ++ ++ vspm_if { ++ compatible = "renesas,vspm_if"; ++ }; ++ ++ lvds-encoder { ++ compatible = "thine,thc63lvdm83d"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ lvds_enc_in: endpoint { ++ remote-endpoint = <&du_out_lvds0>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ lvds_enc_out: endpoint { ++ remote-endpoint = <&lvds_in>; ++ }; ++ }; ++ }; ++ }; ++ ++ lvds { ++ compatible = "lvds-connector"; ++ ++ width-mm = <210>; ++ height-mm = <158>; ++ ++ panel-timing { ++ clock-frequency = <65000000>; ++ hactive = <1280>; ++ vactive = <800>; ++ hsync-len = <40>; ++ hfront-porch = <80>; ++ hback-porch = <40>; ++ vfront-porch = <14>; ++ vback-porch = <14>; ++ vsync-len = <4>; ++ }; ++ ++ port { ++ lvds_in: endpoint { ++ remote-endpoint = <&lvds_enc_out>; ++ }; ++ }; ++ }; ++ ++ dclkin_p0: clock-out0 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <148500000>; ++ }; ++ ++ msiof_ref_clk: msiof-ref-clock { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <66666666>; ++ }; ++ ++ vcc_3v3: regulator0 { + compatible = "regulator-fixed"; -+ regulator-name = "PWR0B"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++ regulator-name = "fixed-VCC3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; + }; + -+ pwr1B: regulator-pwr1B { ++ vcc_vddq_vin0: regulator1 { + compatible = "regulator-fixed"; -+ regulator-name = "PWR1B"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++ regulator-name = "VCC-VDDQ-VIN0"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&avb { ++ pinctrl-0 = <&avb_pins>; ++ pinctrl-names = "default"; ++ renesas,no-ether-link; ++ phy-handle = <&phy0>; ++ status = "okay"; ++ phy-int-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>; ++ ++ phy0: ethernet-phy@0 { ++ rxc-skew-ps = <1500>; ++ rxdv-skew-ps = <420>; /* default */ ++ rxd0-skew-ps = <420>; /* default */ ++ rxd1-skew-ps = <420>; /* default */ ++ rxd2-skew-ps = <420>; /* default */ ++ rxd3-skew-ps = <420>; /* default */ ++ txc-skew-ps = <900>; /* default */ ++ txen-skew-ps = <420>; /* default */ ++ txd0-skew-ps = <420>; /* default */ ++ txd1-skew-ps = <420>; /* default */ ++ txd2-skew-ps = <420>; /* default */ ++ txd3-skew-ps = <420>; /* default */ ++ reg = <0>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>; ++ max-speed = <1000>; + }; ++}; ++ ++&canfd { ++ pinctrl-0 = <&canfd0_pins &canfd1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ channel0 { ++ status = "okay"; ++ }; ++ ++ channel1 { ++ status = "okay"; ++ }; ++}; ++ ++&csi2_40 { ++ status = "okay"; ++ ++ virtual,channel { ++ csi2_vc0 { ++ data,type = "raw8"; ++ receive,vc = <0>; ++ }; ++ }; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ csi2_40_ep: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ csi-rate = <300>; ++ }; ++ }; ++}; ++ ++&du { ++ status = "okay"; ++ ++ ports { ++ port@0 { ++ endpoint { ++ remote-endpoint = <&lvds_in>; ++ }; ++ }; ++ }; ++}; ++ ++&extal_clk { ++ clock-frequency = <16666666>; ++}; ++ ++&extalr_clk { ++ clock-frequency = <32768>; ++}; ++ ++&gpio1 { ++ pdb_ser_enable { ++ gpio-hog; ++ gpios = <26 GPIO_ACTIVE_HIGH>; ++ output-high; ++ line-name = "PDB_SER_Enable"; ++ }; ++ ++ lvds_sw_sel { ++ gpio-hog; ++ gpios = <27 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "LVDS_SW_SEL"; ++ }; ++}; ++ ++&gpio2 { ++ can0_inh_v3m { ++ gpio-hog; ++ gpios = <14 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "CAN0_INH_V3M"; ++ }; ++ ++ can1_inh_v3m { ++ gpio-hog; ++ gpios = <15 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "CAN1_INH_V3M"; ++ }; ++}; ++ ++&gpio3 { ++ pdb_des_enable { ++ gpio-hog; ++ gpios = <0 GPIO_ACTIVE_HIGH>; ++ output-high; ++ line-name = "PDB_DES_Enable"; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-0 = <&i2c0_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ clock-frequency = <400000>; ++}; ++ ++&i2c3 { ++ pinctrl-0 = <&i2c3_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ clock-frequency = <400000>; ++ ++ ov106xx@0 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x60>; ++ ++ port@0 { ++ ov106xx_in0: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin0ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_ti9x4_des0ep0: endpoint@0 { ++ remote-endpoint = <&ti9x4_des0ep0>; ++ }; ++ }; ++ }; ++ ++ ti9x4@30 { ++ compatible = "ti,ti9x4"; ++ reg = <0x30>; ++ ti,links = <1>; ++ ti,lanes = <4>; ++ ti,forwarding-mode = "round-robin"; ++ ti,dvp_bus = <0>; ++ ti,ser_id = <0x30>; ++ ++ port@0 { ++ ti9x4_des0ep0: endpoint@0 { ++ ti9x3-addr = <0x0c>; ++ dvp-order = <0>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ }; ++ port@1 { ++ ti9x4_csi0ep0: endpoint { ++ csi-rate = <800>; ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ }; ++}; + -+ pwr2B: regulator-pwr2B { ++&msiof2 { ++ pinctrl-0 = <&msiof2_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ num-cs = <2>; ++ spidev@0 { ++ compatible = "renesas,sh-msiof"; ++ reg = <1>; ++ spi-max-frequency = <66666666>; ++ }; ++}; ++ ++&msiof3 { ++ pinctrl-0 = <&msiof3_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ spi-slave; ++}; ++ ++&pfc { ++ pinctrl-0 = <&scif_clk_pins>; ++ pinctrl-names = "default"; ++ ++ avb_pins: avb { ++ groups = "avb0_mdc"; ++ function = "avb0"; ++ }; ++ ++ canfd0_pins: canfd0 { ++ groups = "canfd0_data_a"; ++ function = "canfd0"; ++ }; ++ ++ canfd1_pins: canfd1 { ++ groups = "canfd1_data"; ++ function = "canfd1"; ++ }; ++ ++ i2c0_pins: i2c0 { ++ groups = "i2c0"; ++ function = "i2c0"; ++ }; ++ ++ i2c3_pins: i2c3 { ++ groups = "i2c3"; ++ function = "i2c3"; ++ }; ++ ++ msiof2_pins: msiof2 { ++ groups = "msiof2_clk", "msiof2_txd", "msiof2_rxd", "msiof2_ss1"; ++ function = "msiof2"; ++ }; ++ ++ msiof3_pins: msiof3 { ++ groups = "msiof3_clk", "msiof3_txd", "msiof3_rxd", "msiof3_sync"; ++ function = "msiof3"; ++ }; ++ ++ scif0_pins: scif0 { ++ groups = "scif0_data"; ++ function = "scif0"; ++ }; ++ ++ scif_clk_pins: scif_clk { ++ groups = "scif_clk_b"; ++ function = "scif_clk"; ++ }; ++ ++ sdhi2_pins_3v3: sdhi2_3v3 { ++ groups = "mmc_data8", "mmc_ctrl"; ++ function = "mmc"; ++ power-source = <3300>; ++ }; ++}; ++ ++&scif0 { ++ pinctrl-0 = <&scif0_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++}; ++ ++&scif_clk { ++ clock-frequency = <14745600>; ++ status = "okay"; ++}; ++ ++&sdhi2 { ++ /* used for on-board eMMC */ ++ pinctrl-0 = <&sdhi2_pins_3v3>; ++ pinctrl-names = "default"; ++ ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vcc_vddq_vin0>; ++ no-1-8-v; ++ cap-mmc-highspeed; ++ bus-width = <8>; ++ non-removable; ++ status = "okay"; ++}; ++ ++&vin0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin0ep0: endpoint { ++ csi,select = "csi40"; ++ virtual,channel = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ }; ++ port@1 { ++ csi0ep0: endpoint { ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ port@2 { ++ vin0_ti9x4_des0ep0: endpoint@0 { ++ remote-endpoint = <&ti9x4_des0ep0>; ++ }; ++ }; ++ }; ++}; ++ ++&wdt0 { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7798-condor.dts b/arch/arm64/boot/dts/renesas/r8a7798-condor.dts +new file mode 100644 +index 0000000..4dd7a28 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7798-condor.dts +@@ -0,0 +1,963 @@ ++/* ++ * Device Tree Source for the Condor board ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++/dts-v1/; ++#include "r8a7798.dtsi" ++#include <dt-bindings/gpio/gpio.h> ++ ++/ { ++ model = "Renesas Condor board based on r8a7798"; ++ compatible = "renesas,condor", "renesas,r8a7798"; ++ ++ aliases { ++ serial0 = &scif0; ++ ethernet0 = &avb; ++ ethernet1 = &gether; ++ }; ++ ++ chosen { ++ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp"; ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ ++ memory@48000000 { ++ device_type = "memory"; ++ /* first 128MB is reserved for secure area. */ ++ reg = <0x0 0x48000000 0x0 0x78000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ /* device specific region for Lossy Decompression */ ++ lossy_decompress: linux,lossy_decompress { ++ no-map; ++ reg = <0x00000000 0x6c000000 0x0 0x03000000>; ++ }; ++ ++ /* global autoconfigured region for contiguous allocations */ ++ linux,cma { ++ compatible = "shared-dma-pool"; ++ reusable; ++ reg = <0x00000000 0x6f000000 0x0 0x10000000>; ++ linux,cma-default; ++ }; ++ ++ /* device specific region for contiguous allocations */ ++ linux,multimedia { ++ compatible = "shared-dma-pool"; ++ reusable; ++ reg = <0x00000000 0x7f000000 0x0 0x01000000>; ++ }; ++ }; ++ ++ mmngr { ++ compatible = "renesas,mmngr"; ++ memory-region = <&lossy_decompress>; ++ }; ++ ++ mmngrbuf { ++ compatible = "renesas,mmngrbuf"; ++ }; ++ ++ vspm_if { ++ compatible = "renesas,vspm_if"; ++ }; ++ ++ lvds-encoder { ++ compatible = "thine,thc63lvdm83d"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ lvds_enc_in: endpoint { ++ remote-endpoint = <&du_out_lvds0>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ lvds_enc_out: endpoint { ++ remote-endpoint = <&lvds_in>; ++ }; ++ }; ++ }; ++ }; ++ ++ lvds { ++ compatible = "lvds-connector"; ++ ++ width-mm = <210>; ++ height-mm = <158>; ++ ++ panel-timing { ++ clock-frequency = <138000000>; ++ hactive = <1920>; ++ vactive = <1080>; ++ hsync-len = <32>; ++ hfront-porch = <20>; ++ hback-porch = <160>; ++ vfront-porch = <3>; ++ vback-porch = <31>; ++ vsync-len = <5>; ++ }; ++ ++ port { ++ lvds_in: endpoint { ++ remote-endpoint = <&lvds_enc_out>; ++ }; ++ }; ++ }; ++ ++ hdmi-out { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con: endpoint { ++ remote-endpoint = <&adv7511_out>; ++ }; ++ }; ++ }; ++ ++ dclkin_p0: clock-out0 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <148500000>; ++ }; ++ ++ msiof_ref_clk: msiof-ref-clock { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <66666666>; ++ }; ++ ++ vcc_3v3: regulator0 { + compatible = "regulator-fixed"; -+ regulator-name = "PWR2B"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++ regulator-name = "fixed-VCC3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; + }; + -+ pwr3B: regulator-pwr3B { ++ vcc_vddq_vin0: regulator1 { + compatible = "regulator-fixed"; -+ regulator-name = "PWR3B"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>; -+ enable-active-high; ++ regulator-name = "VCC-VDDQ-VIN0"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; + }; +}; + ++&du { ++ status = "okay"; ++ ++ ports { ++ port@0 { ++ endpoint { ++ remote-endpoint = <&adv7511_in>; ++ }; ++ }; ++ }; ++}; ++ ++&extal_clk { ++ clock-frequency = <16666666>; ++}; ++ ++&extalr_clk { ++ clock-frequency = <32768>; ++}; ++ ++&pfc { ++ pinctrl-0 = <&scif_clk_pins>; ++ pinctrl-names = "default"; ++ ++ canfd0_pins: canfd0 { ++ groups = "canfd0_data_a"; ++ function = "canfd0"; ++ }; ++ ++ scif0_pins: scif0 { ++ groups = "scif0_data"; ++ function = "scif0"; ++ }; ++ ++ scif_clk_pins: scif_clk { ++ groups = "scif_clk_b"; ++ function = "scif_clk"; ++ }; ++ ++ i2c0_pins: i2c0 { ++ groups = "i2c0"; ++ function = "i2c0"; ++ }; ++ ++ i2c1_pins: i2c1 { ++ groups = "i2c1"; ++ function = "i2c1"; ++ }; ++ ++ avb_pins: avb { ++ groups = "avb_mdc"; ++ function = "avb"; ++ }; ++ ++ gether_pins: gether { ++ groups = "gether_mdc_a"; ++ function = "gether"; ++ }; ++ ++ sdhi2_pins_1v8: sdhi2_1v8 { ++ groups = "mmc_data8", "mmc_ctrl", "mmc_ds"; ++ function = "mmc"; ++ power-source = <1800>; ++ }; ++ ++ sdhi2_pins_3v3: sdhi2_3v3 { ++ groups = "mmc_data8", "mmc_ctrl", "mmc_ds"; ++ function = "mmc"; ++ power-source = <3300>; ++ }; ++ ++ tpu_pins: tpu { ++ /* GP1_19 pin; CP4 test point */ ++ groups = "tpu_to0"; ++ function = "tpu"; ++ }; ++}; ++ ++&scif0 { ++ pinctrl-0 = <&scif0_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++}; ++ ++&scif_clk { ++ clock-frequency = <14745600>; ++ status = "okay"; ++}; ++ ++&sdhi2 { ++ /* used for on-board eMMC */ ++ pinctrl-0 = <&sdhi2_pins_3v3>; ++ pinctrl-1 = <&sdhi2_pins_1v8>; ++ pinctrl-names = "default", "state_uhs"; ++ ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vcc_vddq_vin0>; ++ mmc-hs200-1_8v; ++ mmc-hs400-1_8v; ++ bus-width = <8>; ++ non-removable; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ pinctrl-0 = <&i2c0_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ clock-frequency = <400000>; ++ ++ hdmi@39{ ++ compatible = "adi,adv7511w"; ++ #sound-dai-cells = <0>; ++ reg = <0x39>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <20 IRQ_TYPE_LEVEL_LOW>; ++ ++ adi,input-depth = <8>; ++ adi,input-colorspace = "rgb"; ++ adi,input-clock = "1x"; ++ adi,input-style = <1>; ++ adi,input-justification = "evenly"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ adv7511_in: endpoint { ++ remote-endpoint = <&lvds_enc_out>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ adv7511_out: endpoint { ++ remote-endpoint = <&hdmi_con>; ++ }; ++ }; ++ }; ++ }; ++ ++ gpio_exp_20: gpio@20 { ++ compatible = "onsemi,pca9654"; ++ reg = <0x20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ ++ gpio_exp_21: gpio@21 { ++ compatible = "onsemi,pca9654"; ++ reg = <0x21>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-0 = <&i2c1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ clock-frequency = <400000>; ++ ++ ov106xx@0 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x60>; ++ ++ port@0 { ++ ov106xx_in0: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin0ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des0ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep0>; ++ }; ++ }; ++ }; ++ ++ ov106xx@1 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x61>; ++ ++ port@0 { ++ ov106xx_in1: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin1ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des0ep1: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep1>; ++ }; ++ }; ++ }; ++ ++ ov106xx@2 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x62>; ++ ++ port@0 { ++ ov106xx_in2: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin2ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des0ep2: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep2>; ++ }; ++ }; ++ }; ++ ++ ov106xx@3 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x63>; ++ ++ port@0 { ++ ov106xx_in3: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin3ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_des0ep3: endpoint { ++ remote-endpoint = <&max9286_des0ep3>; ++ }; ++ }; ++ }; ++ ++ ov106xx@4 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x64>; ++ ++ port@0 { ++ ov106xx_in4: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin4ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des1ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des1ep0>; ++ }; ++ }; ++ }; ++ ++ ov106xx@5 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x65>; ++ ++ port@0 { ++ ov106xx_in5: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin5ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des1ep1: endpoint@0 { ++ remote-endpoint = <&max9286_des1ep1>; ++ }; ++ }; ++ }; ++ ++ ov106xx@6 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x66>; ++ ++ port@0 { ++ ov106xx_in6: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin6ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des1ep2: endpoint@0 { ++ remote-endpoint = <&max9286_des1ep2>; ++ }; ++ }; ++ }; ++ ++ ov106xx@7 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x67>; ++ ++ port@0 { ++ ov106xx_in7: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin7ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_des1ep3: endpoint { ++ remote-endpoint = <&max9286_des1ep3>; ++ }; ++ }; ++ }; ++ ++ max9286@0 { ++ compatible = "maxim,max9286"; ++ reg = <0x48>; ++ gpios = <&gpio_exp_20 0 GPIO_ACTIVE_LOW>; /* MAX9286 PWDN */ ++ maxim,gpio0 = <0>; ++ maxim,sensor_delay = <100>; ++ maxim,links = <4>; ++ maxim,lanes = <4>; ++ maxim,resetb-gpio = <1>; ++ maxim,fsync-mode = "automatic"; ++ maxim,timeout = <100>; ++ ++ port@0 { ++ max9286_des0ep0: endpoint@0 { ++ max9271-addr = <0x50>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ max9286_des0ep1: endpoint@1 { ++ max9271-addr = <0x51>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in1>; ++ }; ++ max9286_des0ep2: endpoint@2 { ++ max9271-addr = <0x52>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in2>; ++ }; ++ max9286_des0ep3: endpoint@3 { ++ max9271-addr = <0x53>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in3>; ++ }; ++ }; ++ port@1 { ++ max9286_csi0ep0: endpoint { ++ csi-rate = <700>; ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ }; ++ ++ max9286@1 { ++ compatible = "maxim,max9286"; ++ reg = <0x4a>; ++ gpios = <&gpio_exp_21 0 GPIO_ACTIVE_LOW>; /* MAX9286 PWDN */ ++ maxim,gpio0 = <0>; ++ maxim,sensor_delay = <100>; ++ maxim,links = <4>; ++ maxim,lanes = <4>; ++ maxim,resetb-gpio = <1>; ++ maxim,fsync-mode = "automatic"; ++ maxim,timeout = <100>; ++ ++ port@0 { ++ max9286_des1ep0: endpoint@0 { ++ max9271-addr = <0x54>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in4>; ++ }; ++ max9286_des1ep1: endpoint@1 { ++ max9271-addr = <0x55>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in5>; ++ }; ++ max9286_des1ep2: endpoint@2 { ++ max9271-addr = <0x56>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in6>; ++ }; ++ max9286_des1ep3: endpoint@3 { ++ max9271-addr = <0x57>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in7>; ++ }; ++ }; ++ port@1 { ++ max9286_csi1ep0: endpoint { ++ csi-rate = <700>; ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ }; ++}; ++ ++&pcie_bus_clk { ++ clock-frequency = <100000000>; ++ status = "okay"; ++}; ++ ++&pciec { ++ status = "okay"; ++}; ++ ++&wdt0 { ++ timeout-sec = <60>; ++ status = "okay"; ++}; ++ ++&cmt0 { ++ status = "okay"; ++}; ++ ++&cmt1 { ++ status = "okay"; ++}; ++ ++&cmt2 { ++ status = "okay"; ++}; ++ ++&cmt3 { ++ status = "okay"; ++}; ++ ++&tpu { ++ pinctrl-0 = <&tpu_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&tmu0 { ++ status = "okay"; ++}; ++ ++&tmu1 { ++ status = "okay"; ++}; ++ ++&tmu2 { ++ status = "okay"; ++}; ++ ++&tmu3 { ++ status = "okay"; ++}; ++ ++&tmu4 { ++ status = "okay"; ++}; ++ ++&avb { ++ pinctrl-0 = <&avb_pins>; ++ pinctrl-names = "default"; ++ renesas,no-ether-link; ++ phy-handle = <&phy0>; ++// status = "okay"; ++ phy-int-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>; ++ ++ phy0: ethernet-phy@0 { ++ rxc-skew-ps = <1500>; ++ rxdv-skew-ps = <420>; /* default */ ++ rxd0-skew-ps = <420>; /* default */ ++ rxd1-skew-ps = <420>; /* default */ ++ rxd2-skew-ps = <420>; /* default */ ++ rxd3-skew-ps = <420>; /* default */ ++ txc-skew-ps = <900>; /* default */ ++ txen-skew-ps = <420>; /* default */ ++ txd0-skew-ps = <420>; /* default */ ++ txd1-skew-ps = <420>; /* default */ ++ txd2-skew-ps = <420>; /* default */ ++ txd3-skew-ps = <420>; /* default */ ++ reg = <0>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>; ++ max-speed = <1000>; ++ }; ++}; ++ ++&gether { ++ pinctrl-0 = <&gether_pins>; ++ pinctrl-names = "default"; ++ renesas,no-ether-link; ++ phy-handle = <&gether_phy>; ++ status = "okay"; ++ phy-gpios = <&gpio4 23 GPIO_ACTIVE_LOW>; ++ phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; ++ ++ gether_phy: ethernet-phy@0 { ++ reg = <0>; ++ interrupt-parent = <&gpio4>; ++ interrupts = <23 IRQ_TYPE_LEVEL_LOW>; ++ max-speed = <1000>; ++ }; ++}; ++ ++&vin0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin0ep0: endpoint { ++ csi,select = "csi40"; ++ virtual,channel = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ }; ++ port@1 { ++ csi0ep0: endpoint { ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ port@2 { ++ vin0_max9286_des0ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep0>; ++ }; ++ }; ++ }; ++}; ++ ++&vin1 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin1ep0: endpoint { ++ csi,select = "csi40"; ++ virtual,channel = <1>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in1>; ++ }; ++ }; ++ port@1 { ++ csi0ep1: endpoint { ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ port@2 { ++ vin1_max9286_des0ep1: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep1>; ++ }; ++ }; ++ }; ++}; ++ ++&vin2 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin2ep0: endpoint { ++ csi,select = "csi40"; ++ virtual,channel = <2>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in2>; ++ }; ++ }; ++ port@1 { ++ csi0ep2: endpoint { ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ port@2 { ++ vin2_max9286_des0ep2: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep2>; ++ }; ++ }; ++ }; ++}; ++ ++&vin3 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin3ep0: endpoint { ++ csi,select = "csi40"; ++ virtual,channel = <3>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in3>; ++ }; ++ }; ++ port@1 { ++ csi0ep3: endpoint { ++ remote-endpoint = <&csi2_40_ep>; ++ }; ++ }; ++ port@2 { ++ vin3_max9286_des0ep3: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep3>; ++ }; ++ }; ++ }; ++}; ++ ++&vin4 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin4ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in4>; ++ }; ++ }; ++ port@1 { ++ csi1ep0: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin4_max9286_des1ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des1ep0>; ++ }; ++ }; ++ }; ++}; ++ ++&vin5 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin5ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <1>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in5>; ++ }; ++ }; ++ port@1 { ++ csi1ep1: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin5_max9286_des1ep1: endpoint@0 { ++ remote-endpoint = <&max9286_des1ep1>; ++ }; ++ }; ++ }; ++}; ++ ++&vin6 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin6ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <2>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in6>; ++ }; ++ }; ++ port@1 { ++ csi1ep2: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin6_max9286_des1ep2: endpoint@0 { ++ remote-endpoint = <&max9286_des1ep2>; ++ }; ++ }; ++ }; ++}; ++ ++&vin7 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin7ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <3>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in7>; ++ }; ++ }; ++ port@1 { ++ csi1ep3: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin7_max9286_des1ep3: endpoint@0 { ++ remote-endpoint = <&max9286_des1ep3>; ++ }; ++ }; ++ }; ++}; ++ ++&canfd { ++ pinctrl-0 = <&canfd0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ channel0 { ++ status = "okay"; ++ }; ++}; ++ ++&csi2_40 { ++ status = "okay"; ++ ++ virtual,channel { ++ csi2_vc0 { ++ data,type = "ycbcr422"; ++ receive,vc = <0>; ++ }; ++ csi2_vc1 { ++ data,type = "ycbcr422"; ++ receive,vc = <1>; ++ }; ++ csi2_vc2 { ++ data,type = "ycbcr422"; ++ receive,vc = <2>; ++ }; ++ csi2_vc3 { ++ data,type = "ycbcr422"; ++ receive,vc = <3>; ++ }; ++ }; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ csi2_40_ep: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ csi-rate = <300>; ++ }; ++ }; ++}; ++ ++&csi2_41 { ++ status = "okay"; ++ ++ virtual,channel { ++ csi2_vc0 { ++ data,type = "ycbcr422"; ++ receive,vc = <0>; ++ }; ++ csi2_vc1 { ++ data,type = "ycbcr422"; ++ receive,vc = <1>; ++ }; ++ csi2_vc2 { ++ data,type = "ycbcr422"; ++ receive,vc = <2>; ++ }; ++ csi2_vc3 { ++ data,type = "ycbcr422"; ++ receive,vc = <3>; ++ }; ++ }; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ csi2_41_ep: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ csi-rate = <300>; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2-isp.dts b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2-isp.dts +new file mode 100644 +index 0000000..584a5e5 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2-isp.dts +@@ -0,0 +1,70 @@ ++/* ++ ++ * Device Tree Source for the V3HSK Videobox Mini V2 board on r8a7798 ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7798-v3hsk-vbm-v2.dts" ++ ++&ov106xx_in0 { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&isp1ep0>; ++}; ++ ++&ti9x4_csi0ep0 { ++ csi-rate = <1450>; ++ remote-endpoint = <&csi2_41_ep>; ++}; ++ ++&isp1 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ isp1ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ }; ++ port@1 { ++ csi0isp1ep0: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ isp1_max9286_des0ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep0>; ++ }; ++ isp1_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; ++ }; ++ }; ++ }; ++}; ++ ++&vin4 { ++ status = "disabled"; ++}; ++ ++&vin5 { ++ status = "disabled"; ++}; ++ ++&vin6 { ++ status = "disabled"; ++}; ++ ++&vin7 { ++ status = "disabled"; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2.dts b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2.dts +new file mode 100644 +index 0000000..7bf1d6f +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm-v2.dts +@@ -0,0 +1,72 @@ ++/* ++ * Device Tree Source for the V3HSK Videobox Mini board V2 on r8a7798 ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7798-v3hsk-vbm.dts" ++ ++/ { ++ model = "Renesas V3HSK Videobox Mini board V2 based on r8a7798"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led5 { ++ label = "board:status"; ++ gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++}; ++ ++&gpio0 { ++ can1_stby { ++ gpio-hog; ++ gpios = <21 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "CAN1STBY"; ++ }; ++}; ++ ++&pfc { ++ msiof1_pins: msiof1 { ++ groups = "msiof1_clk", "msiof1_sync", "msiof1_txd", "msiof1_rxd"; ++ function = "msiof1"; ++ }; ++ ++ msiof2_pins: msiof2 { ++ groups = "msiof2_clk", "msiof2_sync", "msiof2_txd", "msiof2_rxd"; ++ function = "msiof2"; ++ }; ++}; ++ ++&scif3 { ++ /* pin conflict with msiof2 */ ++ /* set R240 and remove R241 before enabling */ ++ status = "disabled"; ++}; ++ ++&msiof1 { ++ pinctrl-0 = <&msiof1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ spidev@0 { ++ compatible = "renesas,sh-msiof"; ++ reg = <0>; ++ spi-max-frequency = <66666666>; ++ }; ++}; ++ ++&msiof2 { ++ pinctrl-0 = <&msiof2_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ spi-slave; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm.dts +new file mode 100644 +index 0000000..16b2616 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk-vbm.dts +@@ -0,0 +1,505 @@ ++/* ++ * Device Tree Source for the V3HSK Videobox Mini board on r8a7798 ++ * ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "r8a7798-v3hsk.dts" ++ ++/ { ++ model = "Renesas V3HSK Videobox Mini board based on r8a7798"; ++ ++ aliases { ++ serial1 = &scif3; ++ }; ++}; ++ ++&canfd { ++ pinctrl-0 = <&canfd0_pins &canfd1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ channel0 { ++ status = "okay"; ++ }; ++ ++ channel1 { ++ status = "okay"; ++ }; ++}; ++ ++&csi2_41 { ++ status = "okay"; ++ ++ virtual,channel { ++ csi2_vc0 { ++ data,type = "ycbcr422"; ++ receive,vc = <0>; ++ }; ++ csi2_vc1 { ++ data,type = "ycbcr422"; ++ receive,vc = <1>; ++ }; ++ csi2_vc2 { ++ data,type = "ycbcr422"; ++ receive,vc = <2>; ++ }; ++ csi2_vc3 { ++ data,type = "ycbcr422"; ++ receive,vc = <3>; ++ }; ++ }; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ csi2_41_ep: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ csi-rate = <300>; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-0 = <&i2c1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ clock-frequency = <400000>; ++ ++ i2cswitch1: i2c-switch@74 { ++ compatible = "nxp,pca9548"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x74>; ++ reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; ++ ++ i2c@0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ ++ ov106xx@0 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x60>; ++ ++ port@0 { ++ ov106xx_in0: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin4ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des0ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep0>; ++ }; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; ++ }; ++ }; ++ }; ++ ++ ov106xx@1 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x61>; ++ ++ port@0 { ++ ov106xx_in1: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin5ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des0ep1: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep1>; ++ }; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; ++ }; ++ }; ++ }; ++ ++ ov106xx@2 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x62>; ++ ++ port@0 { ++ ov106xx_in2: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin6ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des0ep2: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep2>; ++ }; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; ++ }; ++ }; ++ }; ++ ++ ov106xx@3 { ++ compatible = "ovti,ov106xx"; ++ reg = <0x63>; ++ ++ port@0 { ++ ov106xx_in3: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&vin7ep0>; ++ }; ++ }; ++ port@1 { ++ ov106xx_max9286_des0ep3: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep3>; ++ }; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; ++ }; ++ }; ++ }; ++ ++ max9286@0 { ++ compatible = "maxim,max9286"; ++ reg = <0x2c>; ++ maxim,links = <4>; ++ maxim,lanes = <4>; ++ maxim,resetb-gpio = <1>; ++ maxim,fsync-mode = "automatic"; ++ maxim,timeout = <100>; ++ ++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; ++ ++ port@0 { ++ max9286_des0ep0: endpoint@0 { ++ max9271-addr = <0x50>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ max9286_des0ep1: endpoint@1 { ++ max9271-addr = <0x51>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in1>; ++ }; ++ max9286_des0ep2: endpoint@2 { ++ max9271-addr = <0x52>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in2>; ++ }; ++ max9286_des0ep3: endpoint@3 { ++ max9271-addr = <0x53>; ++ dvp-order = <1>; ++ remote-endpoint = <&ov106xx_in3>; ++ }; ++ }; ++ port@1 { ++ max9286_csi0ep0: endpoint { ++ csi-rate = <700>; ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ }; ++ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; ++ reg = <0x3a>; ++ ti,links = <4>; ++ ti,lanes = <4>; ++ ti,forwarding-mode = "round-robin"; ++ ti,cable-mode = "coax"; ++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; ++ ++ port@0 { ++ ti9x4_des0ep0: endpoint@0 { ++ ti9x3-addr = <0x0c>; ++ dvp-order = <0>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ ti9x4_des0ep1: endpoint@1 { ++ ti9x3-addr = <0x0d>; ++ dvp-order = <0>; ++ remote-endpoint = <&ov106xx_in1>; ++ }; ++ ti9x4_des0ep2: endpoint@2 { ++ ti9x3-addr = <0x0e>; ++ dvp-order = <0>; ++ remote-endpoint = <&ov106xx_in2>; ++ }; ++ ti9x4_des0ep3: endpoint@3 { ++ ti9x3-addr = <0x0f>; ++ dvp-order = <0>; ++ remote-endpoint = <&ov106xx_in3>; ++ }; ++ }; ++ port@1 { ++ ti9x4_csi0ep0: endpoint { ++ csi-rate = <700>; ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ }; ++ }; ++ ++ i2c@1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <1>; ++ ++ gpio_exp_6c: gpio@6c { ++ compatible = "maxim,max7325"; ++ reg = <0x6c>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ virq { ++ gpio-hog; ++ gpios = <5 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "VIRQ"; ++ }; ++ des_cfg { ++ gpio-hog; ++ gpios = <6 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "CNFG0"; ++ }; ++ pwr_shdn { ++ gpio-hog; ++ gpios = <14 GPIO_ACTIVE_HIGH>; ++ output-high; ++ line-name = "PWR_SHDN"; ++ }; ++ des_shdn { ++ gpio-hog; ++ gpios = <13 GPIO_ACTIVE_HIGH>; ++ output-high; ++ line-name = "Des_SHDN"; ++ }; ++ fpdl_shdn { ++ gpio-hog; ++ gpios = <15 GPIO_ACTIVE_HIGH>; ++ output-high; ++ line-name = "FPDL_SHDN"; ++ }; ++ }; ++ }; ++ ++ i2c@3 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <3>; ++ ++ /* fan node - lm96063 */ ++ fan_ctrl: lm96063@4c { ++ compatible = "lm96163"; ++ reg = <0x4c>; ++ }; ++ }; ++ }; ++}; ++ ++&gpio2 { ++ can0_load { ++ gpio-hog; ++ gpios = <16 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "can0_120R_load"; ++ }; ++ ++ can0stby { ++ gpio-hog; ++ gpios = <27 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "CAN0STBY"; ++ }; ++ ++ can1_load { ++ gpio-hog; ++ gpios = <29 GPIO_ACTIVE_HIGH>; ++ output-low; ++ line-name = "can1_120R_load"; ++ }; ++ ++ wake_pin_7 { ++ gpio-hog; ++ gpios = <8 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "WAKE INPUT PIN 7"; ++ }; ++ ++ wake_pin_8 { ++ gpio-hog; ++ gpios = <9 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "WAKE INPUT PIN 8"; ++ }; ++}; ++ ++&pfc { ++ canfd0_pins: canfd0 { ++ groups = "canfd0_data_a"; ++ function = "canfd0"; ++ }; ++ ++ canfd1_pins: canfd1 { ++ groups = "canfd1_data"; ++ function = "canfd1"; ++ }; ++ ++ i2c1_pins: i2c1 { ++ groups = "i2c1"; ++ function = "i2c1"; ++ }; ++ ++ scif3_pins: scif3 { ++ groups = "scif3_data"; ++ function = "scif3"; ++ }; ++}; ++ ++&scif3 { ++ pinctrl-0 = <&scif3_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++}; ++ ++&vin4 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin4ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <0>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in0>; ++ }; ++ }; ++ port@1 { ++ csi0ep0: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin4_max9286_des0ep0: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep0>; ++ }; ++ vin4_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; ++ }; ++ }; ++ }; ++}; ++ ++&vin5 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin5ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <1>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in1>; ++ }; ++ }; ++ port@1 { ++ csi0ep1: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin5_max9286_des0ep1: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep1>; ++ }; ++ vin5_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; ++ }; ++ }; ++ }; ++}; ++ ++&vin6 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin6ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <2>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in2>; ++ }; ++ }; ++ port@1 { ++ csi0ep2: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin6_max9286_des0ep2: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep2>; ++ }; ++ vin6_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; ++ }; ++ }; ++ }; ++}; ++ ++&vin7 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ vin7ep0: endpoint { ++ csi,select = "csi41"; ++ virtual,channel = <3>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&ov106xx_in3>; ++ }; ++ }; ++ port@1 { ++ csi0ep3: endpoint { ++ remote-endpoint = <&csi2_41_ep>; ++ }; ++ }; ++ port@2 { ++ vin7_max9286_des0ep3: endpoint@0 { ++ remote-endpoint = <&max9286_des0ep3>; ++ }; ++ vin7_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts +new file mode 100644 +index 0000000..bf8abe6 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts +@@ -0,0 +1,358 @@ ++/* ++ * Device Tree Source for the V3H Starter Kit board on r8a7798 ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++/dts-v1/; ++#include "r8a7798.dtsi" ++#include <dt-bindings/gpio/gpio.h> ++ ++/ { ++ model = "Renesas V3H Starter Kit board based on r8a7798"; ++ compatible = "renesas,v3hsk", "renesas,r8a7798"; ++ ++ aliases { ++ serial0 = &scif0; ++ ethernet0 = &gether; ++ }; ++ ++ chosen { ++ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp"; ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ ++ memory@48000000 { ++ device_type = "memory"; ++ /* first 128MB is reserved for secure area. */ ++ reg = <0x0 0x48000000 0x0 0x78000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ /* device specific region for Lossy Decompression */ ++ lossy_decompress: linux,lossy_decompress { ++ no-map; ++ reg = <0x00000000 0x6c000000 0x0 0x03000000>; ++ }; ++ ++ /* global autoconfigured region for contiguous allocations */ ++ linux,cma { ++ compatible = "shared-dma-pool"; ++ reusable; ++ reg = <0x00000000 0x6f000000 0x0 0x10000000>; ++ linux,cma-default; ++ }; ++ ++ /* device specific region for contiguous allocations */ ++ linux,multimedia { ++ compatible = "shared-dma-pool"; ++ reusable; ++ reg = <0x00000000 0x7f000000 0x0 0x01000000>; ++ }; ++ }; ++ ++ mmngr { ++ compatible = "renesas,mmngr"; ++ memory-region = <&lossy_decompress>; ++ }; ++ ++ mmngrbuf { ++ compatible = "renesas,mmngrbuf"; ++ }; ++ ++ vspm_if { ++ compatible = "renesas,vspm_if"; ++ }; ++ ++ lvds-encoder { ++ compatible = "thine,thc63lvdm83d"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ lvds_enc_in: endpoint { ++ remote-endpoint = <&du_out_lvds0>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ lvds_enc_out: endpoint { ++ remote-endpoint = <&lvds_in>; ++ }; ++ }; ++ }; ++ }; ++ ++ lvds { ++ compatible = "lvds-connector"; ++ ++ width-mm = <210>; ++ height-mm = <158>; ++ ++ panel-timing { ++ clock-frequency = <65000000>; ++ hactive = <1280>; ++ vactive = <720>; ++ hsync-len = <40>; ++ hfront-porch = <80>; ++ hback-porch = <40>; ++ vfront-porch = <14>; ++ vback-porch = <14>; ++ vsync-len = <4>; ++ }; ++ ++ port { ++ lvds_in: endpoint { ++ remote-endpoint = <&lvds_enc_out>; ++ }; ++ }; ++ }; ++ ++ hdmi-out { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con: endpoint { ++ remote-endpoint = <&adv7511_out>; ++ }; ++ }; ++ }; ++ ++ dclkin_p0: clock-out0 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <148500000>; ++ }; ++ ++ msiof_ref_clk: msiof-ref-clock { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <66666666>; ++ }; ++ ++ vcc_3v3: regulator0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-VCC3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ vcc_vddq_vin0: regulator1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "VCC-VDDQ-VIN0"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&du { ++ status = "okay"; ++ ++ ports { ++ port@0 { ++ endpoint { ++ remote-endpoint = <&adv7511_in>; ++// remote-endpoint = <&lvds_in>; ++ }; ++ }; ++ }; ++}; ++ ++&extal_clk { ++ clock-frequency = <16666666>; ++}; ++ ++&extalr_clk { ++ clock-frequency = <32768>; ++}; ++ ++&pfc { ++ pinctrl-0 = <&scif_clk_pins>; ++ pinctrl-names = "default"; ++ ++ scif0_pins: scif0 { ++ groups = "scif0_data"; ++ function = "scif0"; ++ }; ++ ++ scif_clk_pins: scif_clk { ++ groups = "scif_clk_b"; ++ function = "scif_clk"; ++ }; ++ ++ i2c0_pins: i2c0 { ++ groups = "i2c0"; ++ function = "i2c0"; ++ }; ++ ++ gether_pins: gether { ++ groups = "gether_mdc_a"; ++ function = "gether"; ++ }; ++ ++ sdhi2_pins_1v8: sdhi2_1v8 { ++ groups = "mmc_data8", "mmc_ctrl", "mmc_ds"; ++ function = "mmc"; ++ power-source = <1800>; ++ }; ++ ++ sdhi2_pins_3v3: sdhi2_3v3 { ++ groups = "mmc_data8", "mmc_ctrl", "mmc_ds"; ++ function = "mmc"; ++ power-source = <3300>; ++ }; ++ ++ tpu_pins: tpu { ++ /* GP1_19 pin; CP4 test point */ ++ groups = "tpu_to0"; ++ function = "tpu"; ++ }; ++}; ++ ++&scif0 { ++ pinctrl-0 = <&scif0_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++}; ++ ++&scif_clk { ++ clock-frequency = <14745600>; ++ status = "okay"; ++}; ++ ++&sdhi2 { ++ /* used for on-board eMMC */ ++ pinctrl-0 = <&sdhi2_pins_3v3>; ++ pinctrl-1 = <&sdhi2_pins_1v8>; ++ pinctrl-names = "default", "state_uhs"; ++ ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vcc_vddq_vin0>; ++ mmc-hs200-1_8v; ++ bus-width = <8>; ++ non-removable; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ pinctrl-0 = <&i2c0_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ clock-frequency = <400000>; ++ ++ hdmi@39{ ++ compatible = "adi,adv7511w"; ++ #sound-dai-cells = <0>; ++ reg = <0x39>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <20 IRQ_TYPE_LEVEL_LOW>; ++ ++ adi,input-depth = <8>; ++ adi,input-colorspace = "rgb"; ++ adi,input-clock = "1x"; ++ adi,input-style = <1>; ++ adi,input-justification = "evenly"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ adv7511_in: endpoint { ++ remote-endpoint = <&lvds_enc_out>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ adv7511_out: endpoint { ++ remote-endpoint = <&hdmi_con>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&wdt0 { ++ timeout-sec = <60>; ++ status = "okay"; ++}; ++ ++&cmt0 { ++ status = "okay"; ++}; ++ ++&cmt1 { ++ status = "okay"; ++}; ++ ++&cmt2 { ++ status = "okay"; ++}; ++ ++&cmt3 { ++ status = "okay"; ++}; ++ ++&tpu { ++ pinctrl-0 = <&tpu_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&tmu0 { ++ status = "okay"; ++}; ++ ++&tmu1 { ++ status = "okay"; ++}; ++ ++&tmu2 { ++ status = "okay"; ++}; ++ ++&tmu3 { ++ status = "okay"; ++}; ++ ++&tmu4 { ++ status = "okay"; ++}; ++ ++&gether { ++ pinctrl-0 = <&gether_pins>; ++ pinctrl-names = "default"; ++ renesas,no-ether-link; ++ phy-handle = <&gether_phy>; ++ status = "okay"; ++ phy-gpios = <&gpio4 23 GPIO_ACTIVE_LOW>; ++ phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; ++ ++ gether_phy: ethernet-phy@0 { ++ reg = <0>; ++ interrupt-parent = <&gpio4>; ++ interrupts = <23 IRQ_TYPE_LEVEL_LOW>; ++ max-speed = <1000>; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi +new file mode 100644 +index 0000000..a87c38b +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi +@@ -0,0 +1,462 @@ ++/* ++ * Device Tree Source for the H3ULCB Kingfisher board: ++ * this adding conflicting resource on VIN4/VIN5/VIN6/VIN7 for CN11 ++ * use CN11 instead default CN29/CN48 ++ * ++ * Copyright (C) 2017 Renesas Electronics Corp. ++ * Copyright (C) 2017 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ +&i2cswitch4 { + i2c@2 { + #address-cells = <1>; @@ -12838,11 +15544,8 @@ index 0000000..b469ca6 + ov106xx_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ ov106xx_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ ov106xx_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ ov106xx_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -12862,11 +15565,8 @@ index 0000000..b469ca6 + ov106xx_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ ov106xx_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ ov106xx_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ ov106xx_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -12885,8 +15585,8 @@ index 0000000..b469ca6 + ov106xx_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ ov106xx_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ ov106xx_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -12905,85 +15605,51 @@ index 0000000..b469ca6 + ov106xx_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ ov106xx_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ ov106xx_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@1 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@1 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "coax"; -+ POC0-supply = <&pwr0B>; -+ POC1-supply = <&pwr1B>; -+ POC2-supply = <&pwr2B>; -+ POC3-supply = <&pwr3B>; ++ ++ POC0-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>; + + port@0 { -+ ti964_des1ep0: endpoint@0 { ++ ti9x4_des1ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in4>; + }; -+ ti964_des1ep1: endpoint@1 { ++ ti9x4_des1ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in5>; + }; -+ ti964_des1ep2: endpoint@2 { ++ ti9x4_des1ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in6>; + }; -+ ti964_des1ep3: endpoint@3 { ++ ti9x4_des1ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in7>; + }; + }; + port@1 { -+ ti964_csi2ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_41_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@1 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ POC0-supply = <&pwr0B>; -+ POC1-supply = <&pwr1B>; -+ POC2-supply = <&pwr2B>; -+ POC3-supply = <&pwr3B>; -+ -+ port@0 { -+ ti954_des1ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in4>; -+ }; -+ ti954_des1ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in5>; -+ }; -+ }; -+ port@1 { -+ ti954_csi2ep0: endpoint { ++ ti9x4_csi2ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_41_ep>; + }; @@ -13000,10 +15666,11 @@ index 0000000..b469ca6 + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; -+ POC0-supply = <&pwr1B>; -+ POC1-supply = <&pwr0B>; -+ POC2-supply = <&pwr3B>; -+ POC3-supply = <&pwr2B>; ++ ++ POC0-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>; + + port@0 { + max9286_des1ep0: endpoint@0 { @@ -13173,11 +15840,8 @@ index 0000000..b469ca6 + vin4_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ vin4_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ vin4_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ vin4_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -13205,11 +15869,8 @@ index 0000000..b469ca6 + vin5_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ vin5_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ vin5_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ vin5_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -13239,8 +15900,8 @@ index 0000000..b469ca6 + vin6_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ vin6_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ vin6_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -13270,8 +15931,8 @@ index 0000000..b469ca6 + vin7_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ vin7_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ vin7_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; @@ -13400,10 +16061,10 @@ index 0000000..b854216 +}; diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi new file mode 100644 -index 0000000..d7ffd79 +index 0000000..0a927e2 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi -@@ -0,0 +1,1542 @@ +@@ -0,0 +1,1456 @@ +/* + * Device Tree Source for the ULCB Kingfisher board + * @@ -13523,42 +16184,6 @@ index 0000000..d7ffd79 + enable-active-high; + }; + -+ pwr0A: regulator-pwr0A { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR0A"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ pwr1A: regulator-pwr1A { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR1A"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ pwr2A: regulator-pwr2A { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR2A"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ pwr3A: regulator-pwr3A { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR3A"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ + kim { + compatible = "kim"; + shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>; @@ -13874,8 +16499,6 @@ index 0000000..d7ffd79 +}; + +&i2c2 { -+ clock-frequency = <400000>; -+ + gpio_ext_74: pca9539@74 { + compatible = "nxp,pca9539"; + reg = <0x74>; @@ -14219,11 +16842,8 @@ index 0000000..d7ffd79 + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ ov106xx_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -14243,11 +16863,8 @@ index 0000000..d7ffd79 + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ ov106xx_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -14267,8 +16884,8 @@ index 0000000..d7ffd79 + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -14288,85 +16905,50 @@ index 0000000..d7ffd79 + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; -+ ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "coax"; -+ POC0-supply = <&pwr0A>; -+ POC1-supply = <&pwr1A>; -+ POC2-supply = <&pwr2A>; -+ POC3-supply = <&pwr3A>; ++ ++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; + + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_40_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@0 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ POC0-supply = <&pwr0A>; -+ POC1-supply = <&pwr1A>; -+ POC2-supply = <&pwr2A>; -+ POC3-supply = <&pwr3A>; -+ -+ port@0 { -+ ti954_des0ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in0>; -+ }; -+ ti954_des0ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in1>; -+ }; -+ }; -+ port@1 { -+ ti954_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -14377,17 +16959,16 @@ index 0000000..d7ffd79 + max9286@0 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; -+ + maxim,timeout = <100>; -+ POC0-supply = <&pwr1A>; -+ POC1-supply = <&pwr0A>; -+ POC2-supply = <&pwr3A>; -+ POC3-supply = <&pwr2A>; ++ ++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; + + port@0 { + max9286_des0ep0: endpoint@0 { @@ -14618,11 +17199,8 @@ index 0000000..d7ffd79 + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ vin0_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -14652,11 +17230,8 @@ index 0000000..d7ffd79 + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ vin1_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -14686,8 +17261,8 @@ index 0000000..d7ffd79 + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -14717,8 +17292,8 @@ index 0000000..d7ffd79 + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -14948,10 +17523,10 @@ index 0000000..d7ffd79 + diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi new file mode 100644 -index 0000000..d5c4f46 +index 0000000..b29fc18 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi -@@ -0,0 +1,515 @@ +@@ -0,0 +1,459 @@ +/* + * Device Tree Source for the H3ULCB Videobox board: + * this adding conflicting resource on VIN4/VIN5/VIN6/VIN7 for CN12 @@ -14986,11 +17561,8 @@ index 0000000..d5c4f46 + ov106xx_max9286_des2ep0: endpoint@0 { + remote-endpoint = <&max9286_des2ep0>; + }; -+ ov106xx_ti964_des2ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep0>; -+ }; -+ ov106xx_ti954_des2ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des2ep0>; ++ ov106xx_ti9x4_des2ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep0>; + }; + }; + }; @@ -15010,11 +17582,8 @@ index 0000000..d5c4f46 + ov106xx_max9286_des2ep1: endpoint@0 { + remote-endpoint = <&max9286_des2ep1>; + }; -+ ov106xx_ti964_des2ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep1>; -+ }; -+ ov106xx_ti954_des2ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des2ep1>; ++ ov106xx_ti9x4_des2ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep1>; + }; + }; + }; @@ -15034,8 +17603,8 @@ index 0000000..d5c4f46 + ov106xx_max9286_des2ep2: endpoint@0 { + remote-endpoint = <&max9286_des2ep2>; + }; -+ ov106xx_ti964_des2ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep2>; ++ ov106xx_ti9x4_des2ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep2>; + }; + }; + }; @@ -15055,15 +17624,15 @@ index 0000000..d5c4f46 + ov106xx_max9286_des2ep3: endpoint@0 { + remote-endpoint = <&max9286_des2ep3>; + }; -+ ov106xx_ti964_des2ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep3>; ++ ov106xx_ti9x4_des2ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@2 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@2 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; @@ -15071,61 +17640,35 @@ index 0000000..d5c4f46 + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "coax"; + ++ POC0-gpios = <&gpio_exp_c_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_c_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_c_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_c_5c 11 GPIO_ACTIVE_HIGH>; ++ + port@0 { -+ ti964_des2ep0: endpoint@0 { ++ ti9x4_des2ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in8>; + }; -+ ti964_des2ep1: endpoint@1 { ++ ti9x4_des2ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in9>; + }; -+ ti964_des2ep2: endpoint@2 { ++ ti9x4_des2ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in10>; + }; -+ ti964_des2ep3: endpoint@3 { ++ ti9x4_des2ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in11>; + }; + }; + port@1 { -+ ti964_csi1ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_20_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@2 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_c_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <2>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "coax"; -+ -+ port@0 { -+ ti954_des2ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in8>; -+ }; -+ ti954_des2ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in9>; -+ }; -+ }; -+ port@1 { -+ ti954_csi1ep0: endpoint { ++ ti9x4_csi1ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_20_ep>; + }; @@ -15143,6 +17686,11 @@ index 0000000..d5c4f46 + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; + ++ POC0-gpios = <&gpio_exp_c_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_c_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_c_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_c_5c 10 GPIO_ACTIVE_HIGH>; ++ + port@0 { + max9286_des2ep0: endpoint@0 { + max9271-addr = <0x50>; @@ -15180,7 +17728,8 @@ index 0000000..d5c4f46 + reg = <4>; + /* Slot C (CN12) */ + -+ video_c_ext0: pca9535@26 { ++ /* PCA9535 is a redundand/deprecated card */ ++ gpio_exp_c_27: gpio@27 { + compatible = "nxp,pca9535"; + reg = <0x26>; + gpio-controller; @@ -15242,7 +17791,7 @@ index 0000000..d5c4f46 + }; + }; + -+ video_c_ext1: max7325@5c { ++ gpio_exp_c_5c: gpio@5c { + compatible = "maxim,max7325"; + reg = <0x5c>; + gpio-controller; @@ -15272,30 +17821,6 @@ index 0000000..d5c4f46 + output-high; + line-name = "Video-C PWR_SHDN"; + }; -+ video_c_cam_pwr0 { -+ gpio-hog; -+ gpios = <8 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-C PWR0"; -+ }; -+ video_c_cam_pwr1 { -+ gpio-hog; -+ gpios = <9 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-C PWR1"; -+ }; -+ video_c_cam_pwr2 { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-C PWR2"; -+ }; -+ video_c_cam_pwr3 { -+ gpio-hog; -+ gpios = <11 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-C PWR3"; -+ }; + video_c_des_shdn { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; @@ -15334,11 +17859,8 @@ index 0000000..d5c4f46 + vin4_max9286_des2ep0: endpoint@0 { + remote-endpoint = <&max9286_des2ep0>; + }; -+ vin4_ti964_des2ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep0>; -+ }; -+ vin4_ti954_des2ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des2ep0>; ++ vin4_ti9x4_des2ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep0>; + }; + }; + }; @@ -15366,11 +17888,8 @@ index 0000000..d5c4f46 + vin5_max9286_des2ep1: endpoint@0 { + remote-endpoint = <&max9286_des2ep1>; + }; -+ vin5_ti964_des2ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep1>; -+ }; -+ vin5_ti954_des2ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des2ep1>; ++ vin5_ti9x4_des2ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep1>; + }; + }; + }; @@ -15398,8 +17917,8 @@ index 0000000..d5c4f46 + vin6_max9286_des2ep2: endpoint@0 { + remote-endpoint = <&max9286_des2ep2>; + }; -+ vin6_ti964_des2ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep2>; ++ vin6_ti9x4_des2ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep2>; + }; + }; + }; @@ -15427,8 +17946,8 @@ index 0000000..d5c4f46 + vin7_max9286_des2ep3: endpoint@0 { + remote-endpoint = <&max9286_des2ep3>; + }; -+ vin7_ti964_des2ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des2ep3>; ++ vin7_ti9x4_des2ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des2ep3>; + }; + }; + }; @@ -15469,10 +17988,10 @@ index 0000000..d5c4f46 +}; diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb.dtsi new file mode 100644 -index 0000000..4fcb320 +index 0000000..0185e46 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/ulcb-vb.dtsi -@@ -0,0 +1,1726 @@ +@@ -0,0 +1,1610 @@ +/* + * Device Tree Source for the ULCB Videobox board + * @@ -15929,11 +18448,8 @@ index 0000000..4fcb320 + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ ov106xx_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -15953,11 +18469,8 @@ index 0000000..4fcb320 + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ ov106xx_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -15977,8 +18490,8 @@ index 0000000..4fcb320 + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -15998,77 +18511,50 @@ index 0000000..4fcb320 + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; -+ ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "stp"; + ++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; ++ + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_40_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@0 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "stp"; -+ -+ port@0 { -+ ti954_des0ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in0>; -+ }; -+ ti954_des0ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in1>; -+ }; -+ }; -+ port@1 { -+ ti954_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -16079,13 +18565,17 @@ index 0000000..4fcb320 + max9286@0 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; + ++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; ++ + port@0 { + max9286_des0ep0: endpoint@0 { + max9271-addr = <0x50>; @@ -16138,11 +18628,8 @@ index 0000000..4fcb320 + ov106xx_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ ov106xx_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ ov106xx_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ ov106xx_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -16162,11 +18649,8 @@ index 0000000..4fcb320 + ov106xx_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ ov106xx_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ ov106xx_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ ov106xx_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -16186,8 +18670,8 @@ index 0000000..4fcb320 + ov106xx_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ ov106xx_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ ov106xx_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -16207,77 +18691,50 @@ index 0000000..4fcb320 + ov106xx_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ ov106xx_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ ov106xx_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@1 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@1 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; -+ ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "stp"; + ++ POC0-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>; ++ + port@0 { -+ ti964_des1ep0: endpoint@0 { ++ ti9x4_des1ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in4>; + }; -+ ti964_des1ep1: endpoint@1 { ++ ti9x4_des1ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in5>; + }; -+ ti964_des1ep2: endpoint@2 { ++ ti9x4_des1ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in6>; + }; -+ ti964_des1ep3: endpoint@3 { ++ ti9x4_des1ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in7>; + }; + }; + port@1 { -+ ti964_csi2ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_41_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@1 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "stp"; -+ -+ port@0 { -+ ti954_des1ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in4>; -+ }; -+ ti954_des1ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in5>; -+ }; -+ }; -+ port@1 { -+ ti954_csi2ep0: endpoint { ++ ti9x4_csi2ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_41_ep>; + }; @@ -16288,13 +18745,17 @@ index 0000000..4fcb320 + max9286@1 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; + ++ POC0-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>; ++ + port@0 { + max9286_des1ep0: endpoint@0 { + max9271-addr = <0x50>; @@ -16339,7 +18800,8 @@ index 0000000..4fcb320 + reg = <1>; + /* Slot A (CN10) */ + -+ video_a_ext0: pca9535@26 { ++ /* PCA9535 is a redundant/deprecated card */ ++ gpio_exp_a_26: gpio@26 { + compatible = "nxp,pca9535"; + reg = <0x26>; + gpio-controller; @@ -16401,7 +18863,7 @@ index 0000000..4fcb320 + }; + }; + -+ video_a_ext1: max7325@5c { ++ gpio_exp_a_5c: gpio@5c { + compatible = "maxim,max7325"; + reg = <0x5c>; + gpio-controller; @@ -16431,30 +18893,6 @@ index 0000000..4fcb320 + output-high; + line-name = "Video-A PWR_SHDN"; + }; -+ video_a_cam_pwr0 { -+ gpio-hog; -+ gpios = <8 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR0"; -+ }; -+ video_a_cam_pwr1 { -+ gpio-hog; -+ gpios = <9 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR1"; -+ }; -+ video_a_cam_pwr2 { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR2"; -+ }; -+ video_a_cam_pwr3 { -+ gpio-hog; -+ gpios = <11 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR3"; -+ }; + video_a_des_shdn { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; @@ -16476,7 +18914,8 @@ index 0000000..4fcb320 + reg = <5>; + /* Slot B (CN11) */ + -+ video_b_ext0: pca9535@26 { ++ /* PCA9535 is a redundant/deprecated card */ ++ gpio_exp_b_26: gpio@26 { + compatible = "nxp,pca9535"; + reg = <0x26>; + gpio-controller; @@ -16538,7 +18977,7 @@ index 0000000..4fcb320 + }; + }; + -+ video_b_ext1: max7325@5c { ++ gpio_exp_b_5c: gpio@5c { + compatible = "maxim,max7325"; + reg = <0x5c>; + gpio-controller; @@ -16568,30 +19007,6 @@ index 0000000..4fcb320 + output-high; + line-name = "Video-B PWR_SHDN"; + }; -+ video_b_cam_pwr0 { -+ gpio-hog; -+ gpios = <8 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR0"; -+ }; -+ video_b_cam_pwr1 { -+ gpio-hog; -+ gpios = <9 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR1"; -+ }; -+ video_b_cam_pwr2 { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR2"; -+ }; -+ video_b_cam_pwr3 { -+ gpio-hog; -+ gpios = <11 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR3"; -+ }; + video_b_des_shdn { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; @@ -16810,11 +19225,8 @@ index 0000000..4fcb320 + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ vin0_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -16844,11 +19256,8 @@ index 0000000..4fcb320 + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ vin1_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -16878,8 +19287,8 @@ index 0000000..4fcb320 + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -16909,8 +19318,8 @@ index 0000000..4fcb320 + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -16940,11 +19349,8 @@ index 0000000..4fcb320 + vin4_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ vin4_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ vin4_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ vin4_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -16974,11 +19380,8 @@ index 0000000..4fcb320 + vin5_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ vin5_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ vin5_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ vin5_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -17008,8 +19411,8 @@ index 0000000..4fcb320 + vin6_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ vin6_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ vin6_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -17039,8 +19442,8 @@ index 0000000..4fcb320 + vin7_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ vin7_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ vin7_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; @@ -17201,10 +19604,10 @@ index 0000000..4fcb320 +//#include "ulcb-vb-cn12.dtsi" diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi new file mode 100644 -index 0000000..67b6085 +index 0000000..6746723 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi -@@ -0,0 +1,1792 @@ +@@ -0,0 +1,1605 @@ +/* + * Device Tree Source for the ULCB Videobox V2 board + * @@ -17245,13 +19648,6 @@ index 0000000..67b6085 + }; + }; + -+ snd_clk: snd_clk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <24576000>; -+ clock-output-names = "scki"; -+ }; -+ + vcc_sdhi3: regulator-vcc-sdhi3 { + compatible = "regulator-fixed"; + @@ -17301,28 +19697,6 @@ index 0000000..67b6085 + regulator-always-on; + }; + -+ /delete-node/sound; -+ -+ rsnd_ak4613: sound@0 { -+ pinctrl-0 = <&sound_0_pins>; -+ pinctrl-names = "default"; -+ compatible = "simple-audio-card"; -+ -+ simple-audio-card,format = "left_j"; -+ simple-audio-card,name = "ak4613"; -+ -+ simple-audio-card,bitclock-master = <&sndcpu>; -+ simple-audio-card,frame-master = <&sndcpu>; -+ -+ sndcpu: simple-audio-card,cpu@1 { -+ sound-dai = <&rcar_sound>; -+ }; -+ -+ sndcodec: simple-audio-card,codec@1 { -+ sound-dai = <&ak4613>; -+ }; -+ }; -+ + lvds-encoder { + compatible = "thine,thc63lvdm83d"; + @@ -17409,6 +19783,7 @@ index 0000000..67b6085 + spican0: spidev@0 { + compatible = "microchip,mcp2515"; + reg = <0>; ++ reset-gpios = <&gpio_ext_pwr 8 GPIO_ACTIVE_HIGH>; + clocks = <&excan_ref_clk>; + interrupt-parent = <&gpio0>; + interrupts = <15 GPIO_ACTIVE_LOW>; @@ -17417,6 +19792,7 @@ index 0000000..67b6085 + spican1: spidev@1 { + compatible = "microchip,mcp2515"; + reg = <1>; ++ reset-gpios = <&gpio_ext_pwr 9 GPIO_ACTIVE_HIGH>; + clocks = <&excan_ref_clk>; + interrupt-parent = <&gpio1>; + interrupts = <5 GPIO_ACTIVE_LOW>; @@ -17431,13 +19807,6 @@ index 0000000..67b6085 + function = "hscif4"; + }; + -+ /delete-node/sound; -+ -+ sound_0_pins: sound1 { -+ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a"; -+ function = "ssi"; -+ }; -+ + usb0_pins: usb0 { + groups = "usb0"; + function = "usb0"; @@ -17502,9 +19871,21 @@ index 0000000..67b6085 + input; + line-name = "Video-C irq"; + }; ++ can2_irq { ++ gpio-hog; ++ gpios = <15 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "CAN2 irq"; ++ }; +}; + +&gpio1 { ++ can3_irq { ++ gpio-hog; ++ gpios = <5 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "CAN3 irq"; ++ }; + gpioext_4_22_irq { + gpio-hog; + gpios = <25 GPIO_ACTIVE_HIGH>; @@ -17629,8 +20010,6 @@ index 0000000..67b6085 +}; + +&i2c2 { -+ clock-frequency = <400000>; -+ + i2cswitch2: pca9548@74 { + compatible = "nxp,pca9548"; + #address-cells = <1>; @@ -17667,11 +20046,8 @@ index 0000000..67b6085 + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ ov106xx_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -17691,11 +20067,8 @@ index 0000000..67b6085 + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ ov106xx_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -17715,8 +20088,8 @@ index 0000000..67b6085 + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -17736,77 +20109,50 @@ index 0000000..67b6085 + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; -+ ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "stp"; + ++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; ++ + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_40_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@0 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "stp"; -+ -+ port@0 { -+ ti954_des0ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in0>; -+ }; -+ ti954_des0ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in1>; -+ }; -+ }; -+ port@1 { -+ ti954_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_40_ep>; + }; @@ -17817,13 +20163,17 @@ index 0000000..67b6085 + max9286@0 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; + ++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>; ++ + port@0 { + max9286_des0ep0: endpoint@0 { + max9271-addr = <0x50>; @@ -17876,11 +20226,8 @@ index 0000000..67b6085 + ov106xx_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ ov106xx_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ ov106xx_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ ov106xx_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -17900,11 +20247,8 @@ index 0000000..67b6085 + ov106xx_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ ov106xx_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ ov106xx_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ ov106xx_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -17924,8 +20268,8 @@ index 0000000..67b6085 + ov106xx_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ ov106xx_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ ov106xx_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -17945,77 +20289,50 @@ index 0000000..67b6085 + ov106xx_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ ov106xx_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ ov106xx_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; + -+ /* DS90UB964 @ 0x3a */ -+ ti964-ti9x3@1 { -+ compatible = "ti,ti964-ti9x3"; ++ /* DS90UB9x4 @ 0x3a */ ++ ti9x4@1 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; -+ ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "stp"; + ++ POC0-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>; ++ + port@0 { -+ ti964_des1ep0: endpoint@0 { ++ ti9x4_des1ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in4>; + }; -+ ti964_des1ep1: endpoint@1 { ++ ti9x4_des1ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in5>; + }; -+ ti964_des1ep2: endpoint@2 { ++ ti9x4_des1ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in6>; + }; -+ ti964_des1ep3: endpoint@3 { ++ ti9x4_des1ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in7>; + }; + }; + port@1 { -+ ti964_csi2ep0: endpoint { -+ csi-rate = <1450>; -+ remote-endpoint = <&csi2_41_ep>; -+ }; -+ }; -+ }; -+ -+ /* DS90UB954 @ 0x38 */ -+ ti954-ti9x3@1 { -+ compatible = "ti,ti954-ti9x3"; -+ reg = <0x38>; -+ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */ -+ ti,sensor_delay = <350>; -+ ti,links = <2>; -+ ti,lanes = <4>; -+ ti,forwarding-mode = "round-robin"; -+ ti,cable-mode = "stp"; -+ -+ port@0 { -+ ti954_des1ep0: endpoint@0 { -+ ti9x3-addr = <0x0c>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in4>; -+ }; -+ ti954_des1ep1: endpoint@1 { -+ ti9x3-addr = <0x0d>; -+ dvp-order = <0>; -+ remote-endpoint = <&ov106xx_in5>; -+ }; -+ }; -+ port@1 { -+ ti954_csi2ep0: endpoint { ++ ti9x4_csi2ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_41_ep>; + }; @@ -18026,13 +20343,17 @@ index 0000000..67b6085 + max9286@1 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; + ++ POC0-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>; ++ + port@0 { + max9286_des1ep0: endpoint@0 { + max9271-addr = <0x50>; @@ -18077,24 +20398,13 @@ index 0000000..67b6085 + reg = <0>; + /* Slot A (CN10) */ + -+ video_a_ext0: pca9535@26 { ++ /* PCA9535 is a redundant/deprecated card */ ++ gpio_exp_a_26: gpio@26 { + compatible = "nxp,pca9535"; + reg = <0x26>; + gpio-controller; + #gpio-cells = <2>; + -+ video_a_des_cfg1 { -+ gpio-hog; -+ gpios = <5 GPIO_ACTIVE_HIGH>; -+ input; -+ line-name = "Video-A cfg1"; -+ }; -+ video_a_des_cfg0 { -+ gpio-hog; -+ gpios = <6 GPIO_ACTIVE_HIGH>; -+ input; -+ line-name = "Video-A cfg0"; -+ }; + video_a_pwr_shdn { + gpio-hog; + gpios = <3 GPIO_ACTIVE_HIGH>; @@ -18139,24 +20449,12 @@ index 0000000..67b6085 + }; + }; + -+ video_a_ext1: max7325@5c { ++ gpio_exp_a_5c: gpio@5c { + compatible = "maxim,max7325"; + reg = <0x5c>; + gpio-controller; + #gpio-cells = <2>; + -+ video_a_des_cfg2 { -+ gpio-hog; -+ gpios = <4 GPIO_ACTIVE_HIGH>; -+ input; -+ line-name = "Video-A cfg2"; -+ }; -+ video_a_des_cfg1 { -+ gpio-hog; -+ gpios = <6 GPIO_ACTIVE_HIGH>; -+ input; -+ line-name = "Video-A cfg1"; -+ }; + video_a_des_cfg0 { + gpio-hog; + gpios = <7 GPIO_ACTIVE_HIGH>; @@ -18169,30 +20467,6 @@ index 0000000..67b6085 + output-high; + line-name = "Video-A PWR_SHDN"; + }; -+ video_a_cam_pwr0 { -+ gpio-hog; -+ gpios = <8 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR0"; -+ }; -+ video_a_cam_pwr1 { -+ gpio-hog; -+ gpios = <9 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR1"; -+ }; -+ video_a_cam_pwr2 { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR2"; -+ }; -+ video_a_cam_pwr3 { -+ gpio-hog; -+ gpios = <11 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-A PWR3"; -+ }; + video_a_des_shdn { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; @@ -18214,7 +20488,8 @@ index 0000000..67b6085 + reg = <2>; + /* Slot B (CN11) */ + -+ video_b_ext0: pca9535@26 { ++ /* PCA9535 is a redundant/deprecated card */ ++ gpio_exp_b_26: gpio@26 { + compatible = "nxp,pca9535"; + reg = <0x26>; + gpio-controller; @@ -18276,7 +20551,7 @@ index 0000000..67b6085 + }; + }; + -+ video_b_ext1: max7325@5c { ++ gpio_exp_b_5c: gpio@5c { + compatible = "maxim,max7325"; + reg = <0x5c>; + gpio-controller; @@ -18306,30 +20581,6 @@ index 0000000..67b6085 + output-high; + line-name = "Video-B PWR_SHDN"; + }; -+ video_b_cam_pwr0 { -+ gpio-hog; -+ gpios = <8 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR0"; -+ }; -+ video_b_cam_pwr1 { -+ gpio-hog; -+ gpios = <9 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR1"; -+ }; -+ video_b_cam_pwr2 { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR2"; -+ }; -+ video_b_cam_pwr3 { -+ gpio-hog; -+ gpios = <11 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "Video-B PWR3"; -+ }; + video_b_des_shdn { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; @@ -18460,7 +20711,7 @@ index 0000000..67b6085 + can0_load { + gpio-hog; + gpios = <0 GPIO_ACTIVE_HIGH>; -+ output-low; ++ output-high; + line-name = "can0_120R_load"; + }; + /* CAN1 */ @@ -18473,7 +20724,7 @@ index 0000000..67b6085 + can1_load { + gpio-hog; + gpios = <1 GPIO_ACTIVE_HIGH>; -+ output-low; ++ output-high; + line-name = "can1_120R_load"; + }; + /* CAN2 */ @@ -18486,14 +20737,8 @@ index 0000000..67b6085 + can2_load { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; -+ output-low; -+ line-name = "can2_120R_load"; -+ }; -+ can2_rst { -+ gpio-hog; -+ gpios = <8 GPIO_ACTIVE_HIGH>; + output-high; -+ line-name = "can2_rst"; ++ line-name = "can2_120R_load"; + }; + /* CAN3 */ + can3_stby { @@ -18505,20 +20750,10 @@ index 0000000..67b6085 + can3_load { + gpio-hog; + gpios = <3 GPIO_ACTIVE_HIGH>; -+ output-low; -+ line-name = "can3_120R_load"; -+ }; -+ can3_rst { -+ gpio-hog; -+ gpios = <9 GPIO_ACTIVE_HIGH>; + output-high; -+ line-name = "can3_rst"; ++ line-name = "can3_120R_load"; + }; + }; -+ rtc@68 { -+ compatible = "dallas,ds1338"; -+ reg = <0x68>; -+ }; + }; + + i2c@3 { @@ -18549,6 +20784,10 @@ index 0000000..67b6085 + + /* gpios 0..7 are used for indication LEDs, low-active */ + }; ++ rtc: mcp79411@6f { ++ compatible = "microchip,mcp7941x"; ++ reg = <0x6f>; ++ }; + }; + + /* port 7 is not used */ @@ -18592,11 +20831,8 @@ index 0000000..67b6085 + vin0_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin0_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; -+ }; -+ vin0_ti954_des0ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep0>; ++ vin0_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -18626,11 +20862,8 @@ index 0000000..67b6085 + vin1_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin1_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; -+ }; -+ vin1_ti954_des0ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des0ep1>; ++ vin1_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -18660,8 +20893,8 @@ index 0000000..67b6085 + vin2_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin2_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin2_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -18691,8 +20924,8 @@ index 0000000..67b6085 + vin3_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin3_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin3_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -18722,11 +20955,8 @@ index 0000000..67b6085 + vin4_max9286_des1ep0: endpoint@0 { + remote-endpoint = <&max9286_des1ep0>; + }; -+ vin4_ti964_des1ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep0>; -+ }; -+ vin4_ti954_des1ep0: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep0>; ++ vin4_ti9x4_des1ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep0>; + }; + }; + }; @@ -18756,11 +20986,8 @@ index 0000000..67b6085 + vin5_max9286_des1ep1: endpoint@0 { + remote-endpoint = <&max9286_des1ep1>; + }; -+ vin5_ti964_des1ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep1>; -+ }; -+ vin5_ti954_des1ep1: endpoint@2 { -+ remote-endpoint = <&ti954_des1ep1>; ++ vin5_ti9x4_des1ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep1>; + }; + }; + }; @@ -18790,8 +21017,8 @@ index 0000000..67b6085 + vin6_max9286_des1ep2: endpoint@0 { + remote-endpoint = <&max9286_des1ep2>; + }; -+ vin6_ti964_des1ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep2>; ++ vin6_ti9x4_des1ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep2>; + }; + }; + }; @@ -18821,8 +21048,8 @@ index 0000000..67b6085 + vin7_max9286_des1ep3: endpoint@0 { + remote-endpoint = <&max9286_des1ep3>; + }; -+ vin7_ti964_des1ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des1ep3>; ++ vin7_ti9x4_des1ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des1ep3>; + }; + }; + }; @@ -18896,19 +21123,8 @@ index 0000000..67b6085 + }; +}; + -+&rcar_sound { -+ pinctrl-0 = <&sound_clk_pins>; -+ -+ /* Multi DAI */ -+ #sound-dai-cells = <1>; -+}; -+ -+&sata { -+ status = "okay"; -+}; -+ -+&ssi1 { -+ /delete-property/shared-pin; ++&rsnd_ak4613 { ++ simple-audio-card,name = "ak4613"; +}; + +&sdhi3 { @@ -18996,13 +21212,13 @@ index 0000000..67b6085 +}; + +/* uncomment to enable CN12 on VIN4-7 */ -+//#include "ulcb-vb-cn12.dtsi" ++//#include "ulcb-vb2-cn12.dtsi" diff --git a/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi new file mode 100644 -index 0000000..7728bdd +index 0000000..ed04695 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi -@@ -0,0 +1,578 @@ +@@ -0,0 +1,543 @@ +/* + * Device Tree Source for the ULCB Videobox Mini board + * @@ -19018,42 +21234,6 @@ index 0000000..7728bdd + serial1 = &scif1; + }; + -+ pwr0: regulator-pwr0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR0"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ pwr1: regulator-pwr1 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR1"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ pwr2: regulator-pwr2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR2"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ pwr3: regulator-pwr3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "PWR3"; -+ regulator-min-microvolt = <9000000>; -+ regulator-max-microvolt = <9000000>; -+ gpio = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ + lvds-encoder { + compatible = "thine,thc63lvdm83d"; + @@ -19197,8 +21377,8 @@ index 0000000..7728bdd + ov106xx_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ ov106xx_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; ++ ov106xx_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -19218,8 +21398,8 @@ index 0000000..7728bdd + ov106xx_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ ov106xx_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; ++ ov106xx_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -19239,8 +21419,8 @@ index 0000000..7728bdd + ov106xx_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ ov106xx_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ ov106xx_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -19260,8 +21440,8 @@ index 0000000..7728bdd + ov106xx_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ ov106xx_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ ov106xx_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; @@ -19269,16 +21449,16 @@ index 0000000..7728bdd + max9286@0 { + compatible = "maxim,max9286"; + reg = <0x2c>; -+ maxim,sensor_delay = <350>; + maxim,links = <4>; + maxim,lanes = <4>; + maxim,resetb-gpio = <1>; + maxim,fsync-mode = "automatic"; + maxim,timeout = <100>; -+ POC0-supply = <&pwr0>; -+ POC1-supply = <&pwr1>; -+ POC2-supply = <&pwr2>; -+ POC3-supply = <&pwr3>; ++ ++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; + + port@0 { + max9286_des0ep0: endpoint@0 { @@ -19310,43 +21490,44 @@ index 0000000..7728bdd + }; + }; + -+ ti964-ti9x3@0 { -+ compatible = "ti,ti964-ti9x3"; ++ ti9x4@0 { ++ compatible = "ti,ti9x4"; + reg = <0x3a>; + ti,sensor_delay = <350>; + ti,links = <4>; + ti,lanes = <4>; + ti,forwarding-mode = "round-robin"; + ti,cable-mode = "coax"; -+ POC0-supply = <&pwr0>; -+ POC1-supply = <&pwr1>; -+ POC2-supply = <&pwr2>; -+ POC3-supply = <&pwr3>; ++ ++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>; ++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>; ++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>; ++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>; + + port@0 { -+ ti964_des0ep0: endpoint@0 { ++ ti9x4_des0ep0: endpoint@0 { + ti9x3-addr = <0x0c>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in0>; + }; -+ ti964_des0ep1: endpoint@1 { ++ ti9x4_des0ep1: endpoint@1 { + ti9x3-addr = <0x0d>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in1>; + }; -+ ti964_des0ep2: endpoint@2 { ++ ti9x4_des0ep2: endpoint@2 { + ti9x3-addr = <0x0e>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in2>; + }; -+ ti964_des0ep3: endpoint@3 { ++ ti9x4_des0ep3: endpoint@3 { + ti9x3-addr = <0x0f>; + dvp-order = <0>; + remote-endpoint = <&ov106xx_in3>; + }; + }; + port@1 { -+ ti964_csi0ep0: endpoint { ++ ti9x4_csi0ep0: endpoint { + csi-rate = <1450>; + remote-endpoint = <&csi2_41_ep>; + }; @@ -19481,8 +21662,8 @@ index 0000000..7728bdd + vin4_max9286_des0ep0: endpoint@0 { + remote-endpoint = <&max9286_des0ep0>; + }; -+ vin4_ti964_des0ep0: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep0>; ++ vin4_ti9x4_des0ep0: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep0>; + }; + }; + }; @@ -19512,8 +21693,8 @@ index 0000000..7728bdd + vin5_max9286_des0ep1: endpoint@0 { + remote-endpoint = <&max9286_des0ep1>; + }; -+ vin5_ti964_des0ep1: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep1>; ++ vin5_ti9x4_des0ep1: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep1>; + }; + }; + }; @@ -19543,8 +21724,8 @@ index 0000000..7728bdd + vin6_max9286_des0ep2: endpoint@0 { + remote-endpoint = <&max9286_des0ep2>; + }; -+ vin6_ti964_des0ep2: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep2>; ++ vin6_ti9x4_des0ep2: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep2>; + }; + }; + }; @@ -19574,8 +21755,8 @@ index 0000000..7728bdd + vin7_max9286_des0ep3: endpoint@0 { + remote-endpoint = <&max9286_des0ep3>; + }; -+ vin7_ti964_des0ep3: endpoint@1 { -+ remote-endpoint = <&ti964_des0ep3>; ++ vin7_ti9x4_des0ep3: endpoint@1 { ++ remote-endpoint = <&ti9x4_des0ep3>; + }; + }; + }; diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch deleted file mode 100644 index d368b6a..0000000 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 67d29f4fe320f555366ea45f5439ac52641472ec Mon Sep 17 00:00:00 2001 -From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> -Date: Mon, 15 May 2017 19:16:23 +0300 -Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE1 first 4 cameras - -This set 4 cameras to TYPE1 in DT - -Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> ---- - arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts | 8 ++++---- - 9 files changed, 36 insertions(+), 36 deletions(-) - -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -index 50a37e0..8da87dd 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -@@ -780,22 +780,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -index de56fa4..b36b9d8 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -@@ -175,22 +175,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -index 3f3d66a..c063899 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -@@ -190,22 +190,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -index 94c86f6..b26d8e2 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -@@ -780,22 +780,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -index 2c24b85..a8b9eea 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -@@ -175,22 +175,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -index fb12a39f3..eb09ef0 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -@@ -190,22 +190,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts -index ffaef74..83c6355 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts -@@ -780,22 +780,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts -index 1ac0041..096fb5f 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts -@@ -103,22 +103,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts -index cc6866c..7a592d1 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts -@@ -118,22 +118,22 @@ - port@0 { - max9286_des0ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in0>; - }; - max9286_des0ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in1>; - }; - max9286_des0ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in2>; - }; - max9286_des0ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in3>; - }; - }; --- -1.9.1 - diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch index d52106e..e4d34a0 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch @@ -304,16 +304,16 @@ index f214f26..d3e91f1 100644 }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi -index 118a473..05b50ca 100644 +index 5319b1a..a5552d6 100644 --- a/arch/arm64/boot/dts/renesas/r8a7797.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi -@@ -967,6 +967,113 @@ +@@ -1121,6 +1121,113 @@ status = "okay"; }; + imp_distributer: impdes0 { + compatible = "renesas,impx5+-distributer"; -+ reg = <0 0xffa00000 0 0x4000>; ++ reg = <0 0xffa00000 0 0x10000>; + interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 830>; + power-domains = <&sysc R8A7797_PD_A3IR>; @@ -413,7 +413,7 @@ index 118a473..05b50ca 100644 + + impc0 { + compatible = "renesas,impx4-memory"; -+ reg = <0 0xed000000 0 0x100000>; ++ reg = <0 0xed000000 0 0xe0000>; + clocks = <&cpg CPG_MOD 830>; + power-domains = <&sysc R8A7797_PD_A3IR>; + }; diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch deleted file mode 100644 index a09c485..0000000 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch +++ /dev/null @@ -1,206 +0,0 @@ -From d9ec2149ffc47fd2ea4ab5e9a503a3be7c6f09f5 Mon Sep 17 00:00:00 2001 -From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> -Date: Mon, 15 May 2017 19:18:06 +0300 -Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE1 second 4 cameras - -This set 4 cameras to TYPE1 in DT - -Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> ---- - arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 8 ++++---- - arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 8 ++++---- - 6 files changed, 24 insertions(+), 24 deletions(-) - -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -index 8da87dd..d2e6f66 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -@@ -989,22 +989,22 @@ - port@0 { - max9286_des1ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in4>; - }; - max9286_des1ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in5>; - }; - max9286_des1ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in6>; - }; - max9286_des1ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in7>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -index b36b9d8..e3a9414 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -@@ -216,22 +216,22 @@ - port@0 { - max9286_des1ep0: endpoint@0 { - max9271-addr = <0x54>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in4>; - }; - max9286_des1ep1: endpoint@1 { - max9271-addr = <0x55>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in5>; - }; - max9286_des1ep2: endpoint@2 { - max9271-addr = <0x56>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in6>; - }; - max9286_des1ep3: endpoint@3 { - max9271-addr = <0x57>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in7>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -index c063899..2785fd7 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -@@ -230,22 +230,22 @@ - port@0 { - max9286_des1ep0: endpoint@0 { - max9271-addr = <0x54>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in4>; - }; - max9286_des1ep1: endpoint@1 { - max9271-addr = <0x55>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in5>; - }; - max9286_des1ep2: endpoint@2 { - max9271-addr = <0x56>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in6>; - }; - max9286_des1ep3: endpoint@3 { - max9271-addr = <0x57>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in7>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -index b26d8e2..b8f8819 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -@@ -989,22 +989,22 @@ - port@0 { - max9286_des1ep0: endpoint@0 { - max9271-addr = <0x50>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in4>; - }; - max9286_des1ep1: endpoint@1 { - max9271-addr = <0x51>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in5>; - }; - max9286_des1ep2: endpoint@2 { - max9271-addr = <0x52>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in6>; - }; - max9286_des1ep3: endpoint@3 { - max9271-addr = <0x53>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in7>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -index a8b9eea..86ed4a8 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -@@ -216,22 +216,22 @@ - port@0 { - max9286_des1ep0: endpoint@0 { - max9271-addr = <0x54>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in4>; - }; - max9286_des1ep1: endpoint@1 { - max9271-addr = <0x55>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in5>; - }; - max9286_des1ep2: endpoint@2 { - max9271-addr = <0x56>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in6>; - }; - max9286_des1ep3: endpoint@3 { - max9271-addr = <0x57>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in7>; - }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -index eb09ef0..37eabc0 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -@@ -230,22 +230,22 @@ - port@0 { - max9286_des1ep0: endpoint@0 { - max9271-addr = <0x54>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in4>; - }; - max9286_des1ep1: endpoint@1 { - max9271-addr = <0x55>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in5>; - }; - max9286_des1ep2: endpoint@2 { - max9271-addr = <0x56>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in6>; - }; - max9286_des1ep3: endpoint@3 { - max9271-addr = <0x57>; -- dvp-order = <1>; -+ dvp-order = <2>; - remote-endpoint = <&ov106xx_in7>; - }; - }; --- -1.9.1 - diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch new file mode 100644 index 0000000..d9eb2fa --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch @@ -0,0 +1,6512 @@ +From e8fd03e53c50c67a2aebf19f39a9f14b583f0e2d Mon Sep 17 00:00:00 2001 +From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> +Date: Sun, 14 May 2017 14:48:08 +0300 +Subject: [PATCH] arm64: renesas: r8a7798: Add Renesas R8A7798 SoC support + +This adds Renesas R8A7798 SoC support + +Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> +Signed-off-by: Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com> +--- + arch/arm64/Kconfig.platforms | 8 + + arch/arm64/boot/dts/renesas/r8a7798.dtsi | 1724 ++++++++++++++ + drivers/clk/renesas/Kconfig | 1 + + drivers/clk/renesas/Makefile | 1 + + drivers/clk/renesas/r8a7798-cpg-mssr.c | 292 +++ + drivers/clk/renesas/rcar-gen3-cpg.c | 19 +- + drivers/clk/renesas/renesas-cpg-mssr.c | 6 + + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + drivers/gpio/gpio-rcar.c | 4 + + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 1 + + drivers/gpu/drm/rcar-du/rcar_du_group.c | 5 +- + drivers/i2c/busses/i2c-rcar.c | 1 + + drivers/iommu/ipmmu-vmsa.c | 3 + + drivers/media/platform/soc_camera/Kconfig | 2 +- + drivers/media/platform/soc_camera/rcar_csi2.c | 15 +- + drivers/media/platform/soc_camera/rcar_vin.c | 97 +- + drivers/media/platform/vsp1/vsp1_lif.c | 8 +- + drivers/mmc/host/sh_mobile_sdhi.c | 1 + + drivers/net/ethernet/renesas/ravb_main.c | 1 + + drivers/net/ethernet/renesas/sh_eth.c | 53 +- + drivers/net/ethernet/renesas/sh_eth.h | 5 +- + drivers/pci/host/pcie-rcar.c | 59 +- + drivers/pinctrl/sh-pfc/Kconfig | 5 + + drivers/pinctrl/sh-pfc/Makefile | 1 + + drivers/pinctrl/sh-pfc/core.c | 6 + + drivers/pinctrl/sh-pfc/pfc-r8a7798.c | 3151 +++++++++++++++++++++++++ + drivers/pinctrl/sh-pfc/sh_pfc.h | 9 +- + drivers/soc/renesas/Makefile | 4 + + drivers/soc/renesas/r8a7798-sysc.c | 57 + + drivers/soc/renesas/rcar-rst.c | 1 + + drivers/soc/renesas/rcar-sysc.c | 3 + + drivers/soc/renesas/rcar-sysc.h | 1 + + drivers/soc/renesas/rcar_ems_ctrl.c | 5 +- + drivers/soc/renesas/renesas-soc.c | 8 + + drivers/spi/spi-sh-msiof.c | 4 +- + drivers/thermal/rcar_gen3_thermal.c | 10 + + include/dt-bindings/clock/r8a7798-cpg-mssr.h | 56 + + include/dt-bindings/power/r8a7798-sysc.h | 46 + + 39 files changed, 5642 insertions(+), 33 deletions(-) + create mode 100644 arch/arm64/boot/dts/renesas/r8a7798.dtsi + create mode 100644 drivers/clk/renesas/r8a7798-cpg-mssr.c + create mode 100644 drivers/pinctrl/sh-pfc/pfc-r8a7798.c + create mode 100644 drivers/soc/renesas/r8a7798-sysc.c + create mode 100644 include/dt-bindings/clock/r8a7798-cpg-mssr.h + create mode 100644 include/dt-bindings/power/r8a7798-sysc.h + +diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms +index 9cebaad..3646b6e 100644 +--- a/arch/arm64/Kconfig.platforms ++++ b/arch/arm64/Kconfig.platforms +@@ -174,6 +174,14 @@ config ARCH_R8A7797 + help + This enables support for the Renesas R-Car V3M SoC. + ++config ARCH_R8A7798 ++ bool "Renesas R-Car V3H SoC Platform" ++ select SYS_SUPPORTS_SH_TMU ++ select SYS_SUPPORTS_SH_CMT ++ depends on ARCH_RENESAS ++ help ++ This enables support for the Renesas R-Car V3H SoC. ++ + config ARCH_STRATIX10 + bool "Altera's Stratix 10 SoCFPGA Family" + help +diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +new file mode 100644 +index 0000000..00bd4d6 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +@@ -0,0 +1,1722 @@ ++/* ++ * Device Tree Source for the r8a7798 SoC ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include <dt-bindings/clock/r8a7798-cpg-mssr.h> ++#include <dt-bindings/interrupt-controller/arm-gic.h> ++#include <dt-bindings/power/r8a7798-sysc.h> ++ ++/ { ++ compatible = "renesas,r8a7798"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ aliases { ++ csi2_40 = &csi2_40; ++ csi2_41 = &csi2_41; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2c2 = &i2c2; ++ i2c3 = &i2c3; ++ i2c4 = &i2c4; ++ i2c5 = &i2c5; ++ spi1 = &msiof0; ++ spi2 = &msiof1; ++ spi3 = &msiof2; ++ spi4 = &msiof3; ++ vin0 = &vin0; ++ vin1 = &vin1; ++ vin2 = &vin2; ++ vin3 = &vin3; ++ vin4 = &vin4; ++ vin5 = &vin5; ++ vin6 = &vin6; ++ vin7 = &vin7; ++ vin8 = &vin8; ++ vin9 = &vin9; ++ vin10 = &vin10; ++ vin11 = &vin11; ++ vin12 = &vin12; ++ vin13 = &vin13; ++ vin14 = &vin14; ++ vin15 = &vin15; ++ tsc0 = &tsc1; ++ tsc1 = &tsc2; ++ isp0 = &isp0; ++ isp1 = &isp1; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ a53_0: cpu@0 { ++ compatible = "arm,cortex-a53", "arm,armv8"; ++ reg = <0x0>; ++ device_type = "cpu"; ++ power-domains = <&sysc R8A7798_PD_CA53_CPU0>; ++ next-level-cache = <&L2_CA53>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ #cooling-cells = <2>; ++ dynamic-power-coefficient = <277>; ++ cooling-min-level = <0>; ++ cooling-max-level = <2>; ++ clocks =<&cpg CPG_CORE R8A7798_CLK_Z2>; ++ operating-points-v2 = <&cluster0_opp_tb0>; ++ /*cpu-supply = <&vdd_dvfs>;*/ ++ }; ++ ++ a53_1: cpu@1 { ++ compatible = "arm,cortex-a53","arm,armv8"; ++ reg = <0x1>; ++ device_type = "cpu"; ++ power-domains = <&sysc R8A7798_PD_CA53_CPU1>; ++ next-level-cache = <&L2_CA53>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ operating-points-v2 = <&cluster0_opp_tb0>; ++ }; ++ ++ a53_2: cpu@2 { ++ compatible = "arm,cortex-a53","arm,armv8"; ++ reg = <0x2>; ++ device_type = "cpu"; ++ power-domains = <&sysc R8A7798_PD_CA53_CPU2>; ++ next-level-cache = <&L2_CA53>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ operating-points-v2 = <&cluster0_opp_tb0>; ++ }; ++ ++ a53_3: cpu@3 { ++ compatible = "arm,cortex-a53","arm,armv8"; ++ reg = <0x3>; ++ device_type = "cpu"; ++ power-domains = <&sysc R8A7798_PD_CA53_CPU3>; ++ next-level-cache = <&L2_CA53>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ operating-points-v2 = <&cluster0_opp_tb0>; ++ }; ++ ++ idle-states { ++ entry-method = "psci"; ++ ++ CPU_SLEEP_0: cpu-sleep-0 { ++ compatible = "arm,idle-state"; ++ arm,psci-suspend-param = <0x0010000>; ++ local-timer-stop; ++ entry-latency-us = <639>; ++ exit-latency-us = <680>; ++ min-residency-us = <1088>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ L2_CA53: cache-controller@1 { ++ compatible = "cache"; ++ power-domains = <&sysc R8A7798_PD_CA53_SCU>; ++ cache-unified; ++ cache-level = <2>; ++ }; ++ ++ cluster0_opp_tb0: opp_table0 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp@1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <850000>; /* TBD; section 87.2 */ ++ clock-latency-ns = <300000>; ++ }; ++ }; ++ ++ extal_clk: extal { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ /* This value must be overridden by the board */ ++ clock-frequency = <0>; ++ }; ++ ++ extalr_clk: extalr { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ /* This value must be overridden by the board */ ++ clock-frequency = <0>; ++ }; ++ ++ can_clk: can { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <0>; ++ }; ++ ++ /* MSIOF reference clock - to be overridden by boards that provide it */ ++ msiof_ref_clk: msiof-ref-clock { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <0>; ++ }; ++ ++ /* External PCIe clock - can be overridden by the board */ ++ pcie_bus_clk: pcie_bus { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <0>; ++ }; ++ ++ /* External SCIF clock - to be overridden by boards that provide it */ ++ scif_clk: scif { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <0>; ++ }; ++ ++ /* DU input dot clock - tob be overriden by boards that provide it */ ++ du_dotclkin0: dclkin-0 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <148500000>; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ gic: interrupt-controller@0xf1010000 { ++ compatible = "arm,gic-400"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ reg = <0x0 0xf1010000 0 0x1000>, ++ <0x0 0xf1020000 0 0x20000>, ++ <0x0 0xf1040000 0 0x20000>, ++ <0x0 0xf1060000 0 0x20000>; ++ interrupts = <GIC_PPI 9 ++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>; ++ }; ++ ++ gpio0: gpio@e6050000 { ++ compatible = "renesas,gpio-r8a7798", ++ "renesas,gpio-rcar"; ++ reg = <0 0xe6050000 0 0x50>; ++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ gpio-ranges = <&pfc 0 0 22>; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ clocks = <&cpg CPG_MOD 912>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ gpio1: gpio@e6051000 { ++ compatible = "renesas,gpio-r8a7798", ++ "renesas,gpio-rcar"; ++ reg = <0 0xe6051000 0 0x50>; ++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ gpio-ranges = <&pfc 0 32 28>; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ clocks = <&cpg CPG_MOD 911>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ gpio2: gpio@e6052000 { ++ compatible = "renesas,gpio-r8a7798", ++ "renesas,gpio-rcar"; ++ reg = <0 0xe6052000 0 0x50>; ++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ gpio-ranges = <&pfc 0 64 29>; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ clocks = <&cpg CPG_MOD 910>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ gpio3: gpio@e6053000 { ++ compatible = "renesas,gpio-r8a7798", ++ "renesas,gpio-rcar"; ++ reg = <0 0xe6053000 0 0x50>; ++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ gpio-ranges = <&pfc 0 96 17>; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ clocks = <&cpg CPG_MOD 909>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ gpio4: gpio@e6054000 { ++ compatible = "renesas,gpio-r8a7798", ++ "renesas,gpio-rcar"; ++ reg = <0 0xe6054000 0 0x50>; ++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ gpio-ranges = <&pfc 0 128 25>; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ clocks = <&cpg CPG_MOD 908>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ gpio5: gpio@e6055000 { ++ compatible = "renesas,gpio-r8a7798", ++ "renesas,gpio-rcar"; ++ reg = <0 0xe6055000 0 0x50>; ++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ gpio-ranges = <&pfc 0 160 15>; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ clocks = <&cpg CPG_MOD 907>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ pmu_a53 { ++ compatible = "arm,cortex-a53-pmu"; ++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-affinity = <&a53_0>, ++ <&a53_1>, ++ <&a53_2>, ++ <&a53_3>; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = <GIC_PPI 13 ++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 14 ++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 11 ++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 10 ++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; ++ }; ++ ++ wdt0: wdt@e6020000 { ++ compatible = "renesas,r8a7798-wdt", "renesas,rcar-gen3-wdt"; ++ reg = <0 0xe6020000 0 0x0c>; ++ clocks = <&cpg CPG_MOD 402>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ cpg: clock-controller@e6150000 { ++ compatible = "renesas,r8a7798-cpg-mssr"; ++ reg = <0 0xe6150000 0 0x1000>; ++ clocks = <&extal_clk>, <&extalr_clk>; ++ clock-names = "extal", "extalr"; ++ #clock-cells = <2>; ++ #power-domain-cells = <0>; ++ }; ++ ++ csi2_40: csi2@feaa0000 { ++ compatible = "renesas,r8a7798-csi2"; ++ reg = <0 0xfeaa0000 0 0x10000>; ++ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 716>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ csi2_41: csi2@feab0000 { ++ compatible = "renesas,r8a7798-csi2"; ++ reg = <0 0xfeab0000 0 0x10000>; ++ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 715>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ prr: chipid@fff00044 { ++ compatible = "renesas,prr"; ++ reg = <0 0xfff00044 0 4>; ++ }; ++ ++ rst: reset-controller@e6160000 { ++ compatible = "renesas,r8a7798-rst"; ++ reg = <0 0xe6160000 0 0x0200>; ++ }; ++ ++ sysc: system-controller@e6180000 { ++ compatible = "renesas,r8a7798-sysc"; ++ reg = <0 0xe6180000 0 0x0440>; ++ #power-domain-cells = <1>; ++ }; ++ ++ pfc: pfc@e6060000 { ++ compatible = "renesas,pfc-r8a7798"; ++ reg = <0 0xe6060000 0 0x50c>; ++ }; ++ ++ intc_ex: interrupt-controller@e61c0000 { ++ compatible = "renesas,intc-ex-r8a7798", "renesas,irqc"; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ reg = <0 0xe61c0000 0 0x200>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>; /* SPI1:IRQ1, SPI2:IRQ2, SPI3:IRQ3, SPI18:IRQ4, SPI161:IRQ5 */ ++ clocks = <&cpg CPG_MOD 407>; /* RMSTPCR4/bit7:INTC-EX */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ ipmmu_vi: mmu@febd0000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xfebd0000 0 0x1000>; /* IPMMU-VI */ ++ renesas,ipmmu-main = <&ipmmu_mm 14>; ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ipmmu_vc: mmu@fe6b0000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xfe6b0000 0 0x1000>; /* IPMMU-VC */ ++ renesas,ipmmu-main = <&ipmmu_mm 12>; ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ipmmu_ir: mmu@ff8b0000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xff8b0000 0 0x1000>; /* IPMMU-IR */ ++ renesas,ipmmu-main = <&ipmmu_mm 3>; ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ipmmu_rt: mmu@ffc80000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xffc80000 0 0x1000>; /* IPMMU-RT */ ++ renesas,ipmmu-main = <&ipmmu_mm 10>; ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ipmmu_ds0: mmu@e6740000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xe6740000 0 0x1000>; /* IPMMU-DS1 */ ++ renesas,ipmmu-main = <&ipmmu_mm 0>; ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ipmmu_vip0: mmu@e7b00000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xe7b00000 0 0x1000>; /* IPMMU-VIP0 */ ++ renesas,ipmmu-main = <&ipmmu_mm 0>; /* FIXME missing in datasheet */ ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ipmmu_vip1: mmu@e7960000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xe7960000 0 0x1000>; /* IPMMU-VIP1 */ ++ renesas,ipmmu-main = <&ipmmu_mm 0>; /* FIXME missing in datasheet */ ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ipmmu_mm: mmu@e67b0000 { ++ compatible = "renesas,ipmmu-r8a7798"; ++ reg = <0 0xe67b0000 0 0x1000>; /* IPMMU-MM */ ++ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; ++ #iommu-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ dmac1: dma-controller@e7300000 { ++ compatible = "renesas,dmac-r8a7798", ++ "renesas,rcar-dmac"; ++ reg = <0 0xe7300000 0 0x10000>; ++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; ++ ++ interrupt-names = "error", ++ "ch0", "ch1", "ch2", "ch3", ++ "ch4", "ch5", "ch6", "ch7", ++ "ch8", "ch9", "ch10", "ch11", ++ "ch12", "ch13", "ch14", "ch15"; ++ clocks = <&cpg CPG_MOD 218>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #dma-cells = <1>; ++ dma-channels = <16>; ++ iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>, ++ <&ipmmu_ds0 2>, <&ipmmu_ds0 3>, ++ <&ipmmu_ds0 4>, <&ipmmu_ds0 5>, ++ <&ipmmu_ds0 6>, <&ipmmu_ds0 7>, ++ <&ipmmu_ds0 8>, <&ipmmu_ds0 9>, ++ <&ipmmu_ds0 10>, <&ipmmu_ds0 11>, ++ <&ipmmu_ds0 12>, <&ipmmu_ds0 13>, ++ <&ipmmu_ds0 14>, <&ipmmu_ds0 15>; ++ }; ++ ++ dmac2: dma-controller@e7310000 { ++ compatible = "renesas,dmac-r8a7798", ++ "renesas,rcar-dmac"; ++ reg = <0 0xe7310000 0 0x10000>; ++ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>; /* SPI307::SYS-DMAC2 err, ++ SPI312~319:SYS-DMAC2.ch0~SYS-DMAC1.ch7 */ ++ interrupt-names = "error", ++ "ch0", "ch1", "ch2", "ch3", ++ "ch4", "ch5", "ch6", "ch7", ++ "ch8", "ch9", "ch10", "ch11", ++ "ch12", "ch13", "ch14", "ch15"; ++ clocks = <&cpg CPG_MOD 217>; /* RMSTPCR2/bit17:SYS-DMAC2 */ ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #dma-cells = <1>; ++ dma-channels = <16>; ++ iommus = <&ipmmu_ds0 16>, <&ipmmu_ds0 17>, ++ <&ipmmu_ds0 18>, <&ipmmu_ds0 19>, ++ <&ipmmu_ds0 20>, <&ipmmu_ds0 21>, ++ <&ipmmu_ds0 22>, <&ipmmu_ds0 23>, ++ <&ipmmu_ds0 24>, <&ipmmu_ds0 25>, ++ <&ipmmu_ds0 26>, <&ipmmu_ds0 27>, ++ <&ipmmu_ds0 28>, <&ipmmu_ds0 29>, ++ <&ipmmu_ds0 30>, <&ipmmu_ds0 31>; ++ }; ++ ++ avb: ethernet@e6800000 { ++ compatible = "renesas,etheravb-r8a7798", ++ "renesas,etheravb-rcar-gen3"; ++ reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>; ++ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; /* SPI39~63:Ethernet AVB.ch0~24 */ ++ /* @@ errreq_avb_p[0]~[3] add (T.B.D) */ ++ interrupt-names = "ch0", "ch1", "ch2", "ch3", ++ "ch4", "ch5", "ch6", "ch7", ++ "ch8", "ch9", "ch10", "ch11", ++ "ch12", "ch13", "ch14", "ch15", ++ "ch16", "ch17", "ch18", "ch19", ++ "ch20", "ch21", "ch22", "ch23", ++ "ch24"; ++ clocks = <&cpg CPG_MOD 812>; /* RMSTPCR8/bit12:EAVB-IF */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ phy-mode = "rgmii-id"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ gether: ethernet@e7400000 { ++ compatible = "renesas,gether-r8a7798"; ++ reg = <0 0xe7400000 0 0x1000>; ++ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 813>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ phy-mode = "rgmii"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ canfd: canfd@e66c0000 { ++ compatible = "renesas,r8a7798-canfd", ++ "renesas,rcar-gen3-canfd"; ++ reg = <0 0xe66c0000 0 0x8000>; ++ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 914>, ++ <&cpg CPG_CORE R8A7798_CLK_CANFD>, ++ <&can_clk>; ++ clock-names = "fck", "canfd", "can_clk"; ++ assigned-clocks = <&cpg CPG_CORE R8A7798_CLK_CANFD>; ++ assigned-clock-rates = <40000000>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ ++ channel0 { ++ status = "disabled"; ++ }; ++ ++ channel1 { ++ status = "disabled"; ++ }; ++ }; ++ ++ ++ cmt0: timer@e60f0000 { ++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2"; ++ reg = <0 0xe60f0000 0 0x1004>; ++ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 303>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ ++ renesas,channels-mask = <0x60>; ++ ++ status = "disabled"; ++ }; ++ ++ cmt1: timer@e6130000 { ++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2"; ++ reg = <0 0xe6130000 0 0x1004>; ++ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 302>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ ++ renesas,channels-mask = <0xff>; ++ ++ status = "disabled"; ++ }; ++ ++ cmt2: timer@e6140000 { ++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2"; ++ reg = <0 0xe6140000 0 0x1004>; ++ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 301>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ ++ renesas,channels-mask = <0xff>; ++ ++ status = "disabled"; ++ }; ++ ++ cmt3: timer@e6148000 { ++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2"; ++ reg = <0 0xe6148000 0 0x1004>; ++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 300>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ ++ renesas,channels-mask = <0xff>; ++ ++ status = "disabled"; ++ }; ++ ++ tpu: pwm@e6e80000 { ++ compatible = "renesas,tpu-r8a7798", "renesas,tpu"; ++ reg = <0 0xe6e80000 0 0x100>; ++ clocks = <&cpg CPG_MOD 304>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ #pwm-cells = <4>; ++ }; ++ ++ tmu0: timer@e61e0000 { ++ compatible = "renesas,tmu-r8a7798", "renesas,tmu"; ++ reg = <0 0xe61e0000 0 0x30>; ++ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 125>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #renesas,channels = <3>; ++ status = "disabled"; ++ }; ++ ++ tmu1: timer@e6fc0000 { ++ compatible = "renesas,tmu-r8a7798", "renesas,tmu"; ++ reg = <0 0xe6fc0000 0 0x30>; ++ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 124>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #renesas,channels = <3>; ++ status = "disabled"; ++ }; ++ ++ tmu2: timer@e6fd0000 { ++ compatible = "renesas,tmu-r8a7798", "renesas,tmu"; ++ reg = <0 0xe6fd0000 0 0x30>; ++ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 123>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #renesas,channels = <3>; ++ status = "disabled"; ++ }; ++ ++ tmu3: timer@e6fe0000 { ++ compatible = "renesas,tmu-r8a7798", "renesas,tmu"; ++ reg = <0 0xe6fe0000 0 0x30>; ++ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 122>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #renesas,channels = <3>; ++ status = "disabled"; ++ }; ++ ++ tmu4: timer@ffc00000 { ++ compatible = "renesas,tmu-r8a7798", "renesas,tmu"; ++ reg = <0 0xffc00000 0 0x30>; ++ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 121>; ++ clock-names = "fck"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #renesas,channels = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm0: pwm@e6e30000 { ++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar"; ++ reg = <0 0xe6e30000 0 0x10>; ++ #pwm-cells = <2>; ++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ pwm1: pwm@e6e31000 { ++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar"; ++ reg = <0 0xe6e31000 0 0x10>; ++ #pwm-cells = <2>; ++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ pwm2: pwm@e6e32000 { ++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar"; ++ reg = <0 0xe6e32000 0 0x10>; ++ #pwm-cells = <2>; ++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ pwm3: pwm@e6e33000 { ++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar"; ++ reg = <0 0xe6e33000 0 0x10>; ++ #pwm-cells = <2>; ++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ pwm4: pwm@e6e34000 { ++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar"; ++ reg = <0 0xe6e34000 0 0x10>; ++ #pwm-cells = <2>; ++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ hscif0: serial@e6540000 { ++ compatible = "renesas,hscif-r8a7798", ++ "renesas,rcar-gen3-hscif", ++ "renesas,hscif"; ++ reg = <0 0xe6540000 0 96>; ++ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; /* SPI154:HSCIF.ch0 */ ++ clocks = <&cpg CPG_MOD 520>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR5/bit20:HSCIF0 */ ++ clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x31>, <&dmac1 0x30>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ hscif1: serial@e6550000 { ++ compatible = "renesas,hscif-r8a7798", ++ "renesas,rcar-gen3-hscif", ++ "renesas,hscif"; ++ reg = <0 0xe6550000 0 96>; ++ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; /* SPI155:HSCIF.ch1 */ ++ clocks = <&cpg CPG_MOD 519>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR5/bit19:HSCIF1 */ ++ clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x33>, <&dmac1 0x32>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ hscif2: serial@e6560000 { ++ compatible = "renesas,hscif-r8a7798", ++ "renesas,rcar-gen3-hscif", ++ "renesas,hscif"; ++ reg = <0 0xe6560000 0 96>; ++ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; /* SPI144:HSCIF.ch2 */ ++ clocks = <&cpg CPG_MOD 518>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR5/bit18:HSCIF2 */ ++ clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x35>, <&dmac1 0x34>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ hscif3: serial@e66a0000 { ++ compatible = "renesas,hscif-r8a7798", ++ "renesas,rcar-gen3-hscif", ++ "renesas,hscif"; ++ reg = <0 0xe66a0000 0 96>; ++ //interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; /* SPI145:HSCIF.ch3 */ ++ clocks = <&cpg CPG_MOD 517>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR5/bit17:HSCIF3 */ ++ clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x37>, <&dmac1 0x36>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ scif0: serial@e6e60000 { ++ compatible = "renesas,scif-r8a7798", ++ "renesas,rcar-gen3-scif", "renesas,scif"; ++ reg = <0 0xe6e60000 0 64>; ++ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; /* SPI152:SCIF.ch0 */ ++ clocks = <&cpg CPG_MOD 207>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR2/bit7:SCIF0 */ ++ /*clock-names = "fck", "sck", "brg_int", "scif_clk"; */ ++ clock-names = "fck"; ++ dmas = <&dmac1 0x51>, <&dmac1 0x50>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ scif1: serial@e6e68000 { ++ compatible = "renesas,scif-r8a7798", ++ "renesas,rcar-gen3-scif", "renesas,scif"; ++ reg = <0 0xe6e68000 0 64>; ++ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; /* SPI153:SCIF.ch1 */ ++ clocks = <&cpg CPG_MOD 206>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR2/bit6:SCIF1 */ ++ clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x53>, <&dmac1 0x52>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ scif3: serial@e6c50000 { ++ compatible = "renesas,scif-r8a7798", ++ "renesas,rcar-gen3-scif", "renesas,scif"; ++ reg = <0 0xe6c50000 0 64>; ++ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; /* SPI23:SCIF.ch3 */ ++ clocks = <&cpg CPG_MOD 204>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR2/bit4:SCIF3 */ ++ clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x57>, <&dmac1 0x56>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ scif4: serial@e6c40000 { ++ compatible = "renesas,scif-r8a7798", ++ "renesas,rcar-gen3-scif", "renesas,scif"; ++ reg = <0 0xe6c40000 0 64>; ++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; /* SPI16:SCIF.ch4 */ ++ clocks = <&cpg CPG_MOD 203>, ++ <&cpg CPG_CORE R8A7798_CLK_S2D1>, ++ <&scif_clk>; /* RMSTPCR2/bit3:SCIF4 */ ++ clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x59>, <&dmac1 0x58>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@e6500000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7798"; ++ reg = <0 0xe6500000 0 0x40>; ++ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 931>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ dmas = <&dmac1 0x91>, <&dmac1 0x90>; ++ dma-names = "tx", "rx"; ++ i2c-scl-internal-delay-ns = <6>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@e6508000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7798"; ++ reg = <0 0xe6508000 0 0x40>; ++ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 930>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ dmas = <&dmac1 0x93>, <&dmac1 0x92>; ++ dma-names = "tx", "rx"; ++ i2c-scl-internal-delay-ns = <6>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@e6510000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7798"; ++ reg = <0 0xe6510000 0 0x40>; ++ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 929>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ dmas = <&dmac1 0x95>, <&dmac1 0x94>; ++ dma-names = "tx", "rx"; ++ i2c-scl-internal-delay-ns = <6>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@e66d0000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7798"; ++ reg = <0 0xe66d0000 0 0x40>; ++ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 928>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ dmas = <&dmac1 0x97>, <&dmac1 0x96>; ++ dma-names = "tx", "rx"; ++ i2c-scl-internal-delay-ns = <6>; ++ status = "disabled"; ++ }; ++ ++ i2c4: i2c@e66d8000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7798"; ++ reg = <0 0xe66d8000 0 0x40>; ++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 927>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ dmas = <&dmac1 0x99>, <&dmac1 0x98>; ++ dma-names = "tx", "rx"; ++ i2c-scl-internal-delay-ns = <6>; ++ status = "disabled"; ++ }; ++ ++ i2c5: i2c@e66e0000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7798"; ++ reg = <0 0xe66e0000 0 0x40>; ++ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 00>; /* FIXME missing entry in MSSR */ ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ dmas = <&dmac1 0x99>, <&dmac1 0x98>; ++ dma-names = "tx", "rx"; ++ i2c-scl-internal-delay-ns = <6>; ++ status = "disabled"; ++ }; ++ ++ msiof0: spi@e6e90000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,msiof-r8a7798"; ++ reg = <0 0xe6e90000 0 0x64>; ++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 211>, <&msiof_ref_clk>; ++ clock-names = "msiof_clk", "msiof_ref_clk"; ++ dmas = <&dmac1 0x41>, <&dmac1 0x40>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ msiof1: spi@e6ea0000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,msiof-r8a7798"; ++ reg = <0 0xe6ea0000 0 0x0064>; ++ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 210>, <&msiof_ref_clk>; ++ clock-names = "msiof_clk", "msiof_ref_clk"; ++ dmas = <&dmac1 0x43>, <&dmac1 0x42>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ msiof2: spi@e6c00000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,msiof-r8a7798"; ++ reg = <0 0xe6c00000 0 0x0064>; ++ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 209>, <&msiof_ref_clk>; ++ clock-names = "msiof_clk", "msiof_ref_clk"; ++ dmas = <&dmac1 0x45>, <&dmac1 0x44>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ msiof3: spi@e6c10000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,msiof-r8a7798"; ++ reg = <0 0xe6c10000 0 0x0064>; ++ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 208>, <&msiof_ref_clk>; ++ clock-names = "msiof_clk", "msiof_ref_clk"; ++ dmas = <&dmac1 0x47>, <&dmac1 0x46>; ++ dma-names = "tx", "rx"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ ++ pciec: pcie@fe000000 { ++ compatible = "renesas,pcie-r8a7798", ++ "renesas,pcie-rcar-gen3"; ++ reg = <0 0xfe000000 0 0x80000>, ++ <0 0xe65d0000 0 0x8000>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ bus-range = <0x00 0xff>; ++ device_type = "pci"; ++ ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000 ++ 0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000 ++ 0x02000000 0 0x30000000 0 0x30000000 0 0x08000000 ++ 0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>; ++ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>; ++ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>; ++ clock-names = "pcie", "pcie_bus"; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin0: video@e6ef0000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef0000 0 0x1000>; ++ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 811>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin1: video@e6ef1000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef1000 0 0x1000>; ++ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 810>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin2: video@e6ef2000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef2000 0 0x1000>; ++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 809>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin3: video@e6ef3000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef3000 0 0x1000>; ++ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 808>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin4: video@e6ef4000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef4000 0 0x1000>; ++ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 807>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin5: video@e6ef5000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef5000 0 0x1000>; ++ interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 806>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin6: video@e6ef6000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef6000 0 0x1000>; ++ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 805>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin7: video@e6ef7000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef7000 0 0x1000>; ++ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 804>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin8: video@e6ef8000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef8000 0 0x1000>; ++ interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 628>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin9: video@e6ef9000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6ef9000 0 0x1000>; ++ interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 627>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin10: video@e6efa000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6efa000 0 0x1000>; ++ interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 625>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin11: video@e6efb000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6efb000 0 0x1000>; ++ interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 618>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin12: video@e6efc000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6efc000 0 0x1000>; ++ interrupts = <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 612>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin13: video@e6efd000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6efd000 0 0x1000>; ++ interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 608>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin14: video@e6efe000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6efe000 0 0x1000>; ++ interrupts = <GIC_SPI 000 IRQ_TYPE_LEVEL_HIGH>; /* FIXME no info in datasheet */ ++ clocks = <&cpg CPG_MOD 605>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ vin15: video@e6eff000 { ++ compatible = "renesas,vin-r8a7798"; ++ reg = <0 0xe6eff000 0 0x1000>; ++ interrupts = <GIC_SPI 000 IRQ_TYPE_LEVEL_HIGH>; /* FIXME no info in datasheet */ ++ clocks = <&cpg CPG_MOD 604>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ ++ sdhi2: sd@ee140000 { ++ compatible = "renesas,sdhi-r8a7798"; ++ reg = <0 0xee140000 0 0x2000>; ++ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 314>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ renesas,clk-rate = <200000000>; ++ status = "disabled"; ++ }; ++ ++ qos@e67e0000 { ++ compatible = "renesas,qos"; ++ }; ++ ++ vspd0: vsp@fea20000 { ++ compatible = "renesas,vsp2"; ++ reg = <0 0xfea20000 0 0x4000>; ++ ++ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 623>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ ++ renesas,fcp = <&fcpvd0>; ++ }; ++ ++ fcpvd0: fcp@fea27000 { ++ compatible = "renesas,r8a7798-fcpv", "renesas,fcpv"; ++ reg = <0 0xfea27000 0 0x200>; ++ clocks = <&cpg CPG_MOD 603>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ du: display@feb00000 { ++ compatible = "renesas,du-r8a7798"; ++ reg = <0 0xfeb00000 0 0x80000>, ++ <0 0xfeb90000 0 0x14>; ++ reg-names = "du", "lvds.0"; ++ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 724>, ++ <&cpg CPG_MOD 727>, ++ <&dclkin_p0>; ++ clock-names = "du.0", "lvds.0", "dclkin.0"; ++ status = "disabled"; ++ ++ vsps = <&vspd0>; ++ ++ interlaced = <1>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ du_out_lvds0: endpoint { ++ }; ++ }; ++ }; ++ }; ++ ++ tsc1: thermal@0xe6198000 { ++ compatible = "renesas,thermal-r8a7798"; ++ reg = <0 0xe6198000 0 0x5c>; ++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 522>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #thermal-sensor-cells = <0>; ++ status = "okay"; ++ }; ++ ++ tsc2: thermal@0xe61a0000 { ++ compatible = "renesas,thermal-r8a7798"; ++ reg = <0 0xe61a0000 0 0x5c>; ++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 522>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ #thermal-sensor-cells = <0>; ++ status = "okay"; ++ }; ++ ++ thermal-zones { ++ emergency { ++ polling-delay = <1000>; ++ on-temperature = <110000>; ++ off-temperature = <95000>; ++ target_cpus = <&a53_1>, ++ <&a53_2>, ++ <&a53_3>; ++ status = "disabled"; ++ }; ++ ++ sensor_thermal1: sensor-thermal1 { ++ polling-delay-passive = <250>; ++ polling-delay = <0>; ++ sustainable-power = <0>; /* TBD; HWM 87.4 */ ++ ++ thermal-sensors = <&tsc1>; ++ ++ trips { ++ sensor1_crit: sensor1-crit { ++ temperature = <120000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ sensor_thermal2: sensor-thermal2 { ++ polling-delay-passive = <250>; ++ polling-delay = <0>; ++ sustainable-power = <0>; /* TBD; HWM 87.4 */ ++ ++ thermal-sensors = <&tsc2>; ++ ++ trips { ++ sensor2_crit: sensor2-crit { ++ temperature = <120000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; ++ ++ mfis: mfis@e6260000 { ++ compatible = "renesas,mfis-r8a7798", "renesas,mfis"; ++ reg = <0 0xe6260000 0 0x0200>; ++ clocks = <&cpg CPG_MOD 213>; ++ clock-names = "mfis"; ++ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "eicr0"; ++ status = "okay"; ++ }; ++ ++ mfis_lock: mfis-lock@e62600c0 { ++ compatible = "renesas,mfis-lock-r8a7798", ++ "renesas,mfis-lock"; ++ reg = <0 0xe62600c0 0 0x0020>; ++ status = "okay"; ++ }; ++ ++ imp_distributer: impdes0 { ++ compatible = "renesas,impx5+-distributer"; ++ reg = <0 0xffa00000 0 0x10000>; ++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 830>; ++ power-domains = <&sysc R8A7798_PD_A3IR>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ }; ++ ++ imp0 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff900000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <0>; ++ clocks = <&cpg CPG_MOD 827>; ++ power-domains = <&sysc R8A7798_PD_A2IR0>; ++ }; ++ ++ imp1 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff920000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <1>; ++ clocks = <&cpg CPG_MOD 826>; ++ power-domains = <&sysc R8A7798_PD_A2IR1>; ++ }; ++ ++ imp2 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff940000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <2>; ++ clocks = <&cpg CPG_MOD 825>; ++ power-domains = <&sysc R8A7798_PD_A2IR2>; ++ }; ++ ++ imp3 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff960000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <3>; ++ clocks = <&cpg CPG_MOD 824>; ++ power-domains = <&sysc R8A7798_PD_A2IR3>; ++ }; ++ ++ imp4 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xffa80000 0 0x20000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <4>; ++ clocks = <&cpg CPG_MOD 521>; ++ power-domains = <&sysc R8A7798_PD_A2IR4>; ++ }; ++ ++ impslc0 { ++ compatible = "renesas,impx4-legacy"; ++ reg = <0 0xff9c0000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <5>; ++ clocks = <&cpg CPG_MOD 500>; ++ power-domains = <&sysc R8A7798_PD_A2IR5>; ++ }; ++ ++ impsc0 { ++ compatible = "renesas,impx4-shader"; ++ reg = <0 0xff980000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <6>; ++ clocks = <&cpg CPG_MOD 829>; ++ power-domains = <&sysc R8A7798_PD_A2SC0>; ++ }; ++ ++ impsc1 { ++ compatible = "renesas,impx4-shader"; ++ reg = <0 0xff990000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <7>; ++ clocks = <&cpg CPG_MOD 828>; ++ power-domains = <&sysc R8A7798_PD_A2SC1>; ++ }; ++ ++ impsc2 { ++ compatible = "renesas,impx4-shader"; ++ reg = <0 0xff9a0000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <8>; ++ clocks = <&cpg CPG_MOD 531>; ++ power-domains = <&sysc R8A7798_PD_A2SC2>; ++ }; ++ ++ impsc3 { ++ compatible = "renesas,impx4-shader"; ++ reg = <0 0xff9b0000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <9>; ++ clocks = <&cpg CPG_MOD 529>; ++ power-domains = <&sysc R8A7798_PD_A2SC3>; ++ }; ++ ++ impsc4 { ++ compatible = "renesas,impx4-shader"; ++ reg = <0 0xffa40000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <10>; ++ clocks = <&cpg CPG_MOD 528>; ++ power-domains = <&sysc R8A7798_PD_A2SC4>; ++ }; ++ ++ impdm0 { ++ compatible = "renesas,impx5-dmac"; ++ reg = <0 0xffa10000 0 0x1000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <11>; ++ clocks = <&cpg CPG_MOD 527>; ++ power-domains = <&sysc R8A7798_PD_A2PD0>; ++ }; ++ ++ impdm1 { ++ compatible = "renesas,impx5-dmac"; ++ reg = <0 0xffa11000 0 0x1000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <12>; ++ clocks = <&cpg CPG_MOD 527>; ++ power-domains = <&sysc R8A7798_PD_A2PD0>; ++ }; ++ ++ impdm2 { ++ compatible = "renesas,impx5-dmac"; ++ reg = <0 0xffa14000 0 0x1000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <13>; ++ clocks = <&cpg CPG_MOD 526>; ++ power-domains = <&sysc R8A7798_PD_A2PD1>; ++ }; ++ ++ impdm3 { ++ compatible = "renesas,impx5-dmac"; ++ reg = <0 0xffa15000 0 0x1000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <14>; ++ clocks = <&cpg CPG_MOD 526>; ++ power-domains = <&sysc R8A7798_PD_A2PD1>; ++ }; ++ ++ imppsc0 { ++ compatible = "renesas,impx5+-psc"; ++ reg = <0 0xffa20000 0 0x4000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <15>; ++ clocks = <&cpg CPG_MOD 525>; ++ power-domains = <&sysc R8A7798_PD_A2PD0>; ++ }; ++ ++ imppsc1 { ++ compatible = "renesas,impx5+-psc"; ++ reg = <0 0xffa24000 0 0x4000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <16>; ++ clocks = <&cpg CPG_MOD 524>; ++ power-domains = <&sysc R8A7798_PD_A2PD1>; ++ }; ++ ++ impcnn0 { ++ compatible = "renesas,impx5+-cnn"; ++ reg = <0 0xff9e0000 0 0x10000>; ++ interrupt-parent = <&imp_distributer>; ++ interrupts = <17>; ++ clocks = <&cpg CPG_MOD 831>; ++ power-domains = <&sysc R8A7798_PD_A2CN>; ++ }; ++ ++ impc0 { ++ compatible = "renesas,impx4-memory"; ++ reg = <0 0xed000000 0 0x200000>; ++ clocks = <&cpg CPG_MOD 830>; ++ power-domains = <&sysc R8A7798_PD_A3IR>; ++ }; ++ ++ imrlx4_ch0: imr-lx4@fe860000 { ++ compatible = "renesas,imr-lx4"; ++ reg = <0 0xfe860000 0 0x2000>; ++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 823>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ imrlx4_ch1: imr-lx4@fe870000 { ++ compatible = "renesas,imr-lx4"; ++ reg = <0 0xfe870000 0 0x2000>; ++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 822>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ imrlx4_ch2: imr-lx4@fe880000 { ++ compatible = "renesas,imr-lx4"; ++ reg = <0 0xfe880000 0 0x2000>; ++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 821>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ imrlx4_ch3: imr-lx4@fe890000 { ++ compatible = "renesas,imr-lx4"; ++ reg = <0 0xfe890000 0 0x2000>; ++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 820>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ imrlx4_ch4: imr-lx4@fe8a0000 { ++ compatible = "renesas,imr-lx4"; ++ reg = <0 0xfe8a0000 0 0x2000>; ++ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 707>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ rse; ++ }; ++ ++ imrlx4_ch5: imr-lx4@fe8b0000 { ++ compatible = "renesas,imr-lx4"; ++ reg = <0 0xfe8b0000 0 0x2000>; ++ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 706>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ rse; ++ }; ++ ++ disp { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a00000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 101>; ++ power-domains = <&sysc R8A7798_PD_A3VIP>; ++ }; ++ ++ umf { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a10000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 102>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ smd_ps { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a20000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1102>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ smd_est { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a30000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1101>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ smd_post { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a40000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1100>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ cle0 { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a50000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1004>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ cle1 { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a60000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1003>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ cle2 { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a70000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1002>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ cle3 { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a80000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1001>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ cle4 { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a90000 0 0x10000>; ++ clocks = <&cpg CPG_MOD 1000>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ isp0: isp@fec00000 { ++ compatible = "renesas,isp-r8a7798"; ++ reg = <0 0xfec00000 0 0x20000>, ++ <0 0xfed00000 0 0x10000>; ++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 817>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ ++ isp1: isp@fee00000 { ++ compatible = "renesas,isp-r8a7798"; ++ reg = <0 0xfee00000 0 0x20000>, ++ <0 0xfed20000 0 0x10000>; ++ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 814>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ }; ++ }; ++}; +diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig +index b52e907..4e6d24d 100644 +--- a/drivers/clk/renesas/Kconfig ++++ b/drivers/clk/renesas/Kconfig +@@ -6,6 +6,7 @@ config CLK_RENESAS_CPG_MSSR + default y if ARCH_R8A7796 + default y if ARCH_R8A77965 + default y if ARCH_R8A7797 ++ default y if ARCH_R8A7798 + + config CLK_RENESAS_CPG_MSTP + bool +diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile +index c2ef11e..9f659d5 100644 +--- a/drivers/clk/renesas/Makefile ++++ b/drivers/clk/renesas/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o + obj-$(CONFIG_ARCH_R8A7796) += r8a7796-cpg-mssr.o rcar-gen3-cpg.o + obj-$(CONFIG_ARCH_R8A77965) += r8a77965-cpg-mssr.o rcar-gen3-cpg.o + obj-$(CONFIG_ARCH_R8A7797) += r8a7797-cpg-mssr.o rcar-gen3-cpg.o ++obj-$(CONFIG_ARCH_R8A7798) += r8a7798-cpg-mssr.o rcar-gen3-cpg.o + obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o + + obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o +diff --git a/drivers/clk/renesas/r8a7798-cpg-mssr.c b/drivers/clk/renesas/r8a7798-cpg-mssr.c +new file mode 100644 +index 0000000..40ad314 +--- /dev/null ++++ b/drivers/clk/renesas/r8a7798-cpg-mssr.c +@@ -0,0 +1,292 @@ ++/* ++ * r8a7798 Clock Pulse Generator / Module Standby and Software Reset ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ */ ++ ++#include <linux/device.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/soc/renesas/rcar-rst.h> ++#include <linux/sys_soc.h> ++ ++#include <dt-bindings/clock/r8a7798-cpg-mssr.h> ++ ++#include "renesas-cpg-mssr.h" ++#include "rcar-gen3-cpg.h" ++ ++enum clk_ids { ++ /* Core Clock Outputs exported to DT */ ++ LAST_DT_CORE_CLK = R8A7798_CLK_OSC, ++ ++ /* External Input Clocks */ ++ CLK_EXTAL, ++ CLK_EXTALR, ++ ++ /* Internal Core Clocks */ ++ CLK_MAIN, ++ CLK_PLL1, ++ CLK_PLL2, ++ CLK_PLL3, ++ CLK_PLL1_DIV2, ++ CLK_PLL1_DIV4, ++ CLK_S0, ++ CLK_S1, ++ CLK_S2, ++ CLK_S3, ++ CLK_SDSRC, ++ CLK_RINT, ++ ++ /* Module Clocks */ ++ MOD_CLK_BASE ++}; ++ ++static const struct cpg_core_clk r8a7798_core_clks[] __initconst = { ++ /* External Clock Inputs */ ++ DEF_INPUT("extal", CLK_EXTAL), ++ DEF_INPUT("extalr", CLK_EXTALR), ++ ++ /* Internal Core Clocks */ ++ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), ++ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), ++ DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), ++ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), ++ ++ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), ++ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), ++ DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), ++ DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), ++ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), ++ DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), ++ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), ++ ++ /* Core Clock Outputs */ ++ DEF_BASE("z2", R8A7798_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), ++ DEF_FIXED("ztr", R8A7798_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), ++ DEF_FIXED("ztrd2", R8A7798_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), ++ DEF_FIXED("zt", R8A7798_CLK_ZT, CLK_PLL1_DIV2, 4, 1), ++ DEF_FIXED("zx", R8A7798_CLK_ZX, CLK_PLL1_DIV2, 3, 1), ++ DEF_FIXED("s0d1", R8A7798_CLK_S0D1, CLK_S0, 1, 1), ++ DEF_FIXED("s0d2", R8A7798_CLK_S0D2, CLK_S0, 2, 1), ++ DEF_FIXED("s0d3", R8A7798_CLK_S0D3, CLK_S0, 3, 1), ++ DEF_FIXED("s0d4", R8A7798_CLK_S0D4, CLK_S0, 4, 1), ++ DEF_FIXED("s0d6", R8A7798_CLK_S0D6, CLK_S0, 6, 1), ++ DEF_FIXED("s0d12", R8A7798_CLK_S0D12, CLK_S0, 12, 1), ++ DEF_FIXED("s0d24", R8A7798_CLK_S0D24, CLK_S0, 24, 1), ++ DEF_FIXED("s1d1", R8A7798_CLK_S1D1, CLK_S1, 1, 1), ++ DEF_FIXED("s1d2", R8A7798_CLK_S1D2, CLK_S1, 2, 1), ++ DEF_FIXED("s1d4", R8A7798_CLK_S1D4, CLK_S1, 4, 1), ++ DEF_FIXED("s2d1", R8A7798_CLK_S2D1, CLK_S2, 1, 1), ++ DEF_FIXED("s2d2", R8A7798_CLK_S2D2, CLK_S2, 2, 1), ++ DEF_FIXED("s2d4", R8A7798_CLK_S2D4, CLK_S2, 4, 1), ++ DEF_FIXED("s3d1", R8A7798_CLK_S3D1, CLK_S3, 1, 1), ++ DEF_FIXED("s3d2", R8A7798_CLK_S3D2, CLK_S3, 2, 1), ++ DEF_FIXED("s3d4", R8A7798_CLK_S3D4, CLK_S3, 4, 1), ++ ++ DEF_GEN3_SD("sd0", R8A7798_CLK_SD0, CLK_SDSRC, 0x0074), /* OK? */ ++ ++ DEF_FIXED("cl", R8A7798_CLK_CL, CLK_PLL1_DIV2, 48, 1), ++ DEF_FIXED("cp", R8A7798_CLK_CP, CLK_EXTAL, 2, 1), ++ ++ DEF_DIV6P1("canfd", R8A7798_CLK_CANFD, CLK_PLL1_DIV4, 0x244), ++ DEF_DIV6P1("csi0", R8A7798_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), ++ DEF_DIV6P1("mso", R8A7798_CLK_MSO, CLK_PLL1_DIV4, 0x014), ++ ++ DEF_BASE("osc", R8A7798_CLK_OSC, CLK_TYPE_GEN3_OSC, CLK_EXTAL), ++ DEF_BASE("r_int", CLK_RINT, CLK_TYPE_GEN3_RINT, CLK_EXTAL), ++ ++ DEF_BASE("r", R8A7798_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), ++}; ++ ++static const struct mssr_mod_clk r8a7798_mod_clks[] __initconst = { ++ /*... skip crc, umf, disp, rt-sram, cle, smd_ */ ++ DEF_MOD("disp", 101, R8A7798_CLK_S1D1), ++ DEF_MOD("umf", 102, R8A7798_CLK_S1D1), ++ DEF_MOD("tmu4", 121, R8A7798_CLK_S0D6), ++ DEF_MOD("tmu3", 122, R8A7798_CLK_S0D6), ++ DEF_MOD("tmu2", 123, R8A7798_CLK_S0D6), ++ DEF_MOD("tmu1", 124, R8A7798_CLK_S0D6), ++ DEF_MOD("tmu0", 125, R8A7798_CLK_CP), ++ DEF_MOD("ivcp1e", 127, R8A7798_CLK_S3D1), /* FIXME parent clk? */ ++ DEF_MOD("scif4", 203, R8A7798_CLK_S3D4), ++ DEF_MOD("scif3", 204, R8A7798_CLK_S3D4), ++ DEF_MOD("scif1", 206, R8A7798_CLK_S3D4), ++ DEF_MOD("scif0", 207, R8A7798_CLK_S3D4), ++ DEF_MOD("msiof3", 208, R8A7798_CLK_MSO), ++ DEF_MOD("msiof2", 209, R8A7798_CLK_MSO), ++ DEF_MOD("msiof1", 210, R8A7798_CLK_MSO), ++ DEF_MOD("msiof0", 211, R8A7798_CLK_MSO), ++ DEF_MOD("mfis", 213, R8A7798_CLK_S2D2), /* FIXME parent clk? */ ++ DEF_MOD("sys-dmac2", 217, R8A7798_CLK_S0D3), /* OK? */ ++ DEF_MOD("sys-dmac1", 218, R8A7798_CLK_S0D3), /* OK? */ ++ DEF_MOD("cmt3", 300, R8A7798_CLK_R), ++ DEF_MOD("cmt2", 301, R8A7798_CLK_R), ++ DEF_MOD("cmt1", 302, R8A7798_CLK_R), ++ DEF_MOD("cmt0", 303, R8A7798_CLK_R), ++ DEF_MOD("tpu", 304, R8A7798_CLK_S3D4), ++ DEF_MOD("sdif", 314, R8A7798_CLK_SD0), /* OK */ ++ DEF_MOD("pciec", 319, R8A7798_CLK_S3D1), ++ DEF_MOD("rwdt0", 402, R8A7798_CLK_R), ++ DEF_MOD("intc-ex", 407, R8A7798_CLK_CP), /* OK */ ++ DEF_MOD("intc-ap", 408, R8A7798_CLK_S0D3), ++ DEF_MOD("simp", 500, R8A7798_CLK_S1D1), ++ DEF_MOD("hscif3", 517, R8A7798_CLK_S3D1), ++ DEF_MOD("hscif2", 518, R8A7798_CLK_S3D1), ++ DEF_MOD("hscif1", 519, R8A7798_CLK_S3D1), ++ DEF_MOD("hscif0", 520, R8A7798_CLK_S3D1), ++ DEF_MOD("imp4", 521, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("thermal", 522, R8A7798_CLK_CP), ++ DEF_MOD("pwm", 523, R8A7798_CLK_S0D12), ++ DEF_MOD("imppsc1", 524, R8A7798_CLK_S1D1), ++ DEF_MOD("imppsc0", 525, R8A7798_CLK_S1D1), ++ DEF_MOD("impdma1", 526, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("impdma0", 527, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("imp-ocv4", 528, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("imp-ocv3", 529, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("imp-ocv2", 531, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("fcpvd0", 603, R8A7798_CLK_S3D1), ++ DEF_MOD("vin15", 604, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("vin14", 605, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("vin13", 608, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("vin12", 612, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("vin11", 618, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("vspd0", 623, R8A7798_CLK_S3D1), ++ DEF_MOD("vin10", 625, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("vin9", 627, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("vin8", 628, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("imr5", 706, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("imr4", 707, R8A7798_CLK_S2D1), /* FIXME parent clk? */ ++ DEF_MOD("csi41", 715, R8A7798_CLK_CSI0), ++ DEF_MOD("csi40", 716, R8A7798_CLK_CSI0), ++ DEF_MOD("du0", 724, R8A7798_CLK_S2D1), ++ DEF_MOD("lvds", 727, R8A7798_CLK_S2D1), ++ DEF_MOD("vin7", 804, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("vin6", 805, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("vin5", 806, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("vin4", 807, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("vin3", 808, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("vin2", 809, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("vin1", 810, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("vin0", 811, R8A7798_CLK_S0D2), /* FIXME parent clk? */ ++ DEF_MOD("etheravb", 812, R8A7798_CLK_S3D2), /* OK */ ++ DEF_MOD("gether", 813, R8A7798_CLK_S3D2), /* OK */ ++ DEF_MOD("isp1", 814, R8A7798_CLK_S3D1), /* FIXME parent clk? */ ++ DEF_MOD("isp0", 817, R8A7798_CLK_S3D1), /* FIXME parent clk? */ ++ DEF_MOD("imr3", 820, R8A7798_CLK_S2D1), /* FIXME check clk? */ ++ DEF_MOD("imr2", 821, R8A7798_CLK_S2D1), /* FIXME check clk? */ ++ DEF_MOD("imr1", 822, R8A7798_CLK_S2D1), /* FIXME check clk? */ ++ DEF_MOD("imr0", 823, R8A7798_CLK_S2D1), /* FIXME check clk? */ ++ DEF_MOD("imp3", 824, R8A7798_CLK_S1D1), /* OK? figure 8.1e CPG block diag */ ++ DEF_MOD("imp2", 825, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("imp1", 826, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("imp0", 827, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("imp-ocv1", 828, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("imp-ocv0", 829, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("impram", 830, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("impcnn", 831, R8A7798_CLK_S1D1), /* OK? */ ++ DEF_MOD("gpio5", 907, R8A7798_CLK_CP), ++ DEF_MOD("gpio4", 908, R8A7798_CLK_CP), ++ DEF_MOD("gpio3", 909, R8A7798_CLK_CP), ++ DEF_MOD("gpio2", 910, R8A7798_CLK_CP), ++ DEF_MOD("gpio1", 911, R8A7798_CLK_CP), ++ DEF_MOD("gpio0", 912, R8A7798_CLK_CP), ++ DEF_MOD("can-fd", 914, R8A7798_CLK_S3D2), ++ /* FIXME missing MSSR for i2c5; should it be 919 as in H3/M3? */ ++ /* DEF_MOD("i2c4", 919, R8A7798_CLK_S3D2), */ ++ DEF_MOD("i2c4", 927, R8A7798_CLK_S0D6), ++ DEF_MOD("i2c3", 928, R8A7798_CLK_S0D6), ++ DEF_MOD("i2c2", 929, R8A7798_CLK_S3D2), ++ DEF_MOD("i2c1", 930, R8A7798_CLK_S3D2), ++ DEF_MOD("i2c0", 931, R8A7798_CLK_S3D2), ++ DEF_MOD("cle4", 1000, R8A7798_CLK_S1D1), ++ DEF_MOD("cle3", 1001, R8A7798_CLK_S1D1), ++ DEF_MOD("cle2", 1002, R8A7798_CLK_S1D1), ++ DEF_MOD("cle1", 1003, R8A7798_CLK_S1D1), ++ DEF_MOD("cle0", 1004, R8A7798_CLK_S1D1), ++ DEF_MOD("smd_post", 1100, R8A7798_CLK_S0D3), ++ DEF_MOD("smd_est", 1101, R8A7798_CLK_S0D3), ++ DEF_MOD("smd_ps", 1102, R8A7798_CLK_S0D3), ++}; ++ ++static const unsigned int r8a7798_crit_mod_clks[] __initconst = { ++ MOD_CLK_ID(408), /* INTC-AP (GIC) */ ++}; ++ ++ ++/* ++ * CPG Clock Data ++ */ ++ ++/* ++ * MD EXTAL PLL2 PLL1 PLL3 ++ * 14 13 19 (MHz) ++ *------------------------------------------------- ++ * 0 0 0 16.66 x 1 x240 x192 x192 ++ * 0 0 1 16.66 x 1 x240 x192 x192 ++ * 0 1 0 20 x 1 x200 x160 x160 ++ * 0 1 1 20 x 1 x200 x160 x160 ++ * 1 0 0 27 x 1 x148 x118 x118 ++ * 1 0 1 27 x 1 x148 x118 x118 ++ * 1 1 0 33.33 / 2 x240 x192 x192 ++ * 1 1 1 33.33 / 2 x240 x192 x192 ++ */ ++#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ ++ (((md) & BIT(13)) >> 12) | \ ++ (((md) & BIT(19)) >> 19)) ++ ++static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[8] __initconst = { ++ /* EXTAL div PLL1 mult PLL3 mult */ ++ { 1, 192, 192,}, ++ { 1, 192, 192,}, ++ { 1, 160, 160,}, ++ { 1, 160, 160,}, ++ { 1, 118, 118,}, ++ { 1, 118, 118,}, ++ { 2, 192, 192,}, ++ { 2, 192, 192,}, ++}; ++ ++static int __init r8a7798_cpg_mssr_init(struct device *dev) ++{ ++ const struct rcar_gen3_cpg_pll_config *cpg_pll_config; ++ u32 cpg_mode; ++ int error; ++ ++ error = rcar_rst_read_mode_pins(&cpg_mode); ++ if (error) ++ return error; ++ ++ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; ++ if (!cpg_pll_config->extal_div) { ++ dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); ++ return -EINVAL; ++ } ++ ++ return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); ++} ++ ++const struct cpg_mssr_info r8a7798_cpg_mssr_info __initconst = { ++ /* Core Clocks */ ++ .core_clks = r8a7798_core_clks, ++ .num_core_clks = ARRAY_SIZE(r8a7798_core_clks), ++ .last_dt_core_clk = LAST_DT_CORE_CLK, ++ .num_total_core_clks = MOD_CLK_BASE, ++ ++ /* Module Clocks */ ++ .mod_clks = r8a7798_mod_clks, ++ .num_mod_clks = ARRAY_SIZE(r8a7798_mod_clks), ++ .num_hw_mod_clks = 12 * 32, ++ ++ /* Critical Module Clocks */ ++ .crit_mod_clks = r8a7798_crit_mod_clks, ++ .num_crit_mod_clks = ARRAY_SIZE(r8a7798_crit_mod_clks), ++ ++ /* Callbacks */ ++ .init = r8a7798_cpg_mssr_init, ++ .cpg_clk_register = rcar_gen3_cpg_clk_register, ++}; +diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c +index b145f14..930fa3d 100644 +--- a/drivers/clk/renesas/rcar-gen3-cpg.c ++++ b/drivers/clk/renesas/rcar-gen3-cpg.c +@@ -33,6 +33,11 @@ + { /* sentinel */ } + }; + ++static const struct soc_device_attribute r8a7798[] = { ++ { .soc_id = "r8a7798" }, ++ { } ++}; ++ + #define CPG_PLL0CR 0x00d8 + #define CPG_PLL2CR 0x002c + #define CPG_PLL4CR 0x01f4 +@@ -242,6 +247,10 @@ static unsigned long cpg_z2_clk_recalc_rate(struct clk_hw *hw, + mult = 32 - val; + + rate = div_u64((u64)parent_rate * mult + 16, 32); ++ ++ if (soc_device_match(r8a7798)) ++ rate /= 2; ++ + /* Round to closest value at 100MHz unit */ + rate = 100000000*DIV_ROUND_CLOSEST(rate, 100000000); + return rate; +@@ -303,6 +312,9 @@ static long cpg_z2_clk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate = *parent_rate; + unsigned int mult; + ++ if (soc_device_match(r8a7798)) ++ prate /= 2; ++ + mult = div_u64((u64)rate * 32 + prate/2, prate); + mult = clamp(mult, 1U, 32U); + +@@ -382,7 +394,7 @@ static int cpg_z2_clk_set_rate(struct clk_hw *hw, unsigned long rate, + u32 val, kick; + unsigned int i; + +- if (soc_device_match(r8a7797)){ ++ if (soc_device_match(r8a7797) || soc_device_match(r8a7798)){ + pr_info("Do not support V3M's Z2 clock changing\n"); + return 0; + } +@@ -916,6 +928,11 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, + if (cpg_quirks & RCLK_CKSEL_RESEVED) + break; + ++ if (soc_device_match(r8a7798) && (cpg_mode ^ BIT(29))) { ++ parent = clks[cpg_clk_extalr]; ++ break; ++ } ++ + /* Select parent clock of RCLK by MD28 */ + if (cpg_mode & BIT(28)) + parent = clks[cpg_clk_extalr]; +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index bd901a6..f1a81ed 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -600,6 +600,12 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, + .data = &r8a7797_cpg_mssr_info, + }, + #endif ++#ifdef CONFIG_ARCH_R8A7798 ++ { ++ .compatible = "renesas,r8a7798-cpg-mssr", ++ .data = &r8a7798_cpg_mssr_info, ++ }, ++#endif + { /* sentinel */ } + }; + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h +index ce3546a..70cb4cb 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.h ++++ b/drivers/clk/renesas/renesas-cpg-mssr.h +@@ -136,6 +136,7 @@ struct cpg_mssr_info { + extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; + extern const struct cpg_mssr_info r8a77965_cpg_mssr_info; + extern const struct cpg_mssr_info r8a7797_cpg_mssr_info; ++extern const struct cpg_mssr_info r8a7798_cpg_mssr_info; + + + /* +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 5a2ec23..2d7d41c 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -61,6 +61,7 @@ + { .compatible = "renesas,r8a7796", }, + { .compatible = "renesas,r8a77965", }, + { .compatible = "renesas,r8a7797", }, ++ { .compatible = "renesas,r8a7798", }, + { .compatible = "renesas,sh73a0", }, + + { .compatible = "rockchip,rk2928", }, +diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c +index fd15649..11044cd 100644 +--- a/drivers/gpio/gpio-rcar.c ++++ b/drivers/gpio/gpio-rcar.c +@@ -371,6 +371,10 @@ struct gpio_rcar_info { + /* Gen3 GPIO is identical to Gen2. */ + .data = &gpio_rcar_info_gen2, + }, { ++ .compatible = "renesas,gpio-r8a7798", ++ /* Gen3 GPIO is identical to Gen2. */ ++ .data = &gpio_rcar_info_gen2, ++ }, { + .compatible = "renesas,gpio-rcar", + .data = &gpio_rcar_info_gen1, + }, { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index f74f264..6fea1e2 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -360,6 +360,7 @@ + { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info }, + { .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info }, + { .compatible = "renesas,du-r8a7797", .data = &rcar_du_r8a7797_info }, ++ { .compatible = "renesas,du-r8a7798", .data = &rcar_du_r8a7797_info }, + { } + }; + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c +index 3916b63..22c7713 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c +@@ -35,8 +35,9 @@ + #include "rcar_du_group.h" + #include "rcar_du_regs.h" + +-static const struct soc_device_attribute r8a7797[] = { ++static const struct soc_device_attribute r8a7797_8[] = { + { .soc_id = "r8a7797" }, ++ { .soc_id = "r8a7798" }, + { } + }; + +@@ -161,7 +162,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp) + + /* Apply planes to CRTCs association. */ + mutex_lock(&rgrp->lock); +- if (!soc_device_match(r8a7797)) ++ if (!soc_device_match(r8a7797_8)) + rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) | + rgrp->dptsr_planes); + +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index ea451cd..6528f72 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -837,6 +837,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap) + { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 }, + { .compatible = "renesas,i2c-r8a77965", .data = (void *)I2C_RCAR_GEN3 }, + { .compatible = "renesas,i2c-r8a7797", .data = (void *)I2C_RCAR_GEN3 }, ++ { .compatible = "renesas,i2c-r8a7798", .data = (void *)I2C_RCAR_GEN3 }, + {}, + }; + MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids); +diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c +index 1ae9174..41e14fa 100644 +--- a/drivers/iommu/ipmmu-vmsa.c ++++ b/drivers/iommu/ipmmu-vmsa.c +@@ -1280,6 +1280,9 @@ static void ipmmu_device_reset(struct ipmmu_vmsa_device *mmu) + .compatible = "renesas,ipmmu-r8a7797", + .data = &ipmmu_features_rcar_gen3, + }, { ++ .compatible = "renesas,ipmmu-r8a7798", ++ .data = &ipmmu_features_rcar_gen3, ++ }, { + /* Terminator */ + }, + }; +diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig +index d60909a..4ed8009 100644 +--- a/drivers/media/platform/soc_camera/Kconfig ++++ b/drivers/media/platform/soc_camera/Kconfig +@@ -39,7 +39,7 @@ config VIDEO_RCAR_VIN_LEGACY_DEBUG + config VIDEO_RCAR_CSI2_LEGACY + tristate "R-Car MIPI CSI-2 Interface driver" + depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK +- depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A7797 || COMPILE_TEST ++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A7797 || ARCH_R8A7798 || COMPILE_TEST + ---help--- + This is a v4l2 driver for the R-Car CSI-2 Interface + +diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c +index 53fc644..20ffba1 100644 +--- a/drivers/media/platform/soc_camera/rcar_csi2.c ++++ b/drivers/media/platform/soc_camera/rcar_csi2.c +@@ -163,6 +163,11 @@ + #define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1) + #define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0) + ++static const struct soc_device_attribute r8a7798[] = { ++ { .soc_id = "r8a7798" }, ++ { } ++}; ++ + static const struct soc_device_attribute r8a7797[] = { + { .soc_id = "r8a7797" }, + { } +@@ -410,7 +415,7 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv) + iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) | + RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44, + priv->base + RCAR_CSI2_PHTW); +- else if (soc_device_match(r8a7795)) ++ else if (soc_device_match(r8a7795) || soc_device_match(r8a7798)) + iowrite32(hs_freq_range_h3[bps_per_lane] << 16, + priv->base + RCAR_CSI2_PHYPLL); + else +@@ -497,8 +502,8 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv) + return -EINVAL; + } + +- if (soc_device_match(r8a7795)) { +- /* Set PHY Test Interface Write Register in R-Car H3(ES2.0) */ ++ if (soc_device_match(r8a7795) || soc_device_match(r8a7798)) { ++ /* Set PHY Test Interface Write Register in R-Car H3(ES2.0)/V3H */ + iowrite32(0x01cc01e2, priv->base + RCAR_CSI2_PHTW); + iowrite32(0x010101e3, priv->base + RCAR_CSI2_PHTW); + iowrite32(0x010101e4, priv->base + RCAR_CSI2_PHTW); +@@ -515,7 +520,7 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv) + /* Set CSI0CLK Frequency Configuration Preset Register + * in R-Car H3(ES2.0) + */ +- if (soc_device_match(r8a7795)) ++ if (soc_device_match(r8a7795) || soc_device_match(r8a7798)) + iowrite32(CSI0CLKFREQRANGE(32), priv->base + RCAR_CSI2_CSI0CLKFCPR); + + /* Enable lanes */ +@@ -609,6 +614,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on) + + #ifdef CONFIG_OF + static const struct of_device_id rcar_csi2_of_table[] = { ++ { .compatible = "renesas,r8a7798-csi2", .data = (void *)RCAR_GEN3 }, + { .compatible = "renesas,r8a7797-csi2", .data = (void *)RCAR_GEN3 }, + { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 }, + { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 }, +@@ -618,6 +624,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on) + #endif + + static struct platform_device_id rcar_csi2_id_table[] = { ++ { "r8a7798-csi2", RCAR_GEN3 }, + { "r8a7797-csi2", RCAR_GEN3 }, + { "r8a7796-csi2", RCAR_GEN3 }, + { "r8a7795-csi2", RCAR_GEN3 }, +diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c +index b7ec03c..37f1a11 100644 +--- a/drivers/media/platform/soc_camera/rcar_vin.c ++++ b/drivers/media/platform/soc_camera/rcar_vin.c +@@ -162,7 +162,7 @@ + #define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */ + + #define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */ +-#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40, V3M:CSI40 */ ++#define VNCSI_IFMD_DES0 (1 << 25) /* H3,V3H:CSI40/41, M3:CSI40, V3M:CSI40 */ + + #define VNCSI_IFMD_CSI_CHSEL(n) (n << 0) + #define VNCSI_IFMD_SEL_NUMBER 5 +@@ -197,6 +197,7 @@ + + enum chip_id { + RCAR_GEN3, ++ RCAR_V3H, + RCAR_V3M, + RCAR_M3, + RCAR_H3, +@@ -416,6 +417,69 @@ struct vin_gen3_ifmd { + }, + }; + ++static const struct vin_gen3_ifmd vin_v3h_vc_ifmd[] = { ++ { 0x0000, ++ { ++ {RCAR_CSI40, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI40, RCAR_VIRTUAL_CH1}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH1}, ++ } ++ }, ++ { 0x0001, ++ { ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI40, RCAR_VIRTUAL_CH1}, ++ {RCAR_CSI40, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH1}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ } ++ }, ++ { 0x0002, ++ { ++ {RCAR_CSI40, RCAR_VIRTUAL_CH1}, ++ {RCAR_CSI40, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH1}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ } ++ }, ++ { 0x0003, ++ { ++ {RCAR_CSI40, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI40, RCAR_VIRTUAL_CH1}, ++ {RCAR_CSI40, RCAR_VIRTUAL_CH2}, ++ {RCAR_CSI40, RCAR_VIRTUAL_CH3}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH0}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH1}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH2}, ++ {RCAR_CSI41, RCAR_VIRTUAL_CH3}, ++ } ++ }, ++ { 0x0004, ++ { ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE}, ++ } ++ }, ++}; ++ + enum csi2_fmt { + RCAR_CSI_FMT_NONE = -1, + RCAR_CSI_RGB888, +@@ -911,7 +975,7 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq, + struct rcar_vin_cam *cam = icd->host_priv; + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) { + dev_err(icd->parent, "Scaling rate parameter error\n"); + return -EINVAL; +@@ -1020,7 +1084,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) + switch (icd->current_fmt->host_fmt->fourcc) { + case V4L2_PIX_FMT_NV12: + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + iowrite32(ALIGN((cam->out_width * cam->out_height), + 0x80), priv->base + VNUVAOF_REG); + dmr = VNDMR_DTMD_YCSEP_YCBCR420; +@@ -1056,7 +1120,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) + break; + case V4L2_PIX_FMT_XBGR32: + if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 && +- priv->chip != RCAR_V3M && ++ priv->chip != RCAR_V3M && priv->chip != RCAR_V3H && + priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 && + priv->chip != RCAR_E1) + goto e_format; +@@ -1065,7 +1129,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) + break; + case V4L2_PIX_FMT_ABGR32: + if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 && +- priv->chip != RCAR_V3M) ++ priv->chip != RCAR_V3M && priv->chip != RCAR_V3H) + goto e_format; + + dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB; +@@ -1086,7 +1150,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) + vnmc |= VNMC_BPS; + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + if (priv->pdata_flags & RCAR_VIN_CSI2) + vnmc &= ~VNMC_DPINE; + else +@@ -1457,7 +1521,7 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) + pm_runtime_get_sync(ici->v4l2_dev.dev); + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + struct v4l2_subdev *csi2_sd = find_csi2(priv); + struct v4l2_subdev *deser_sd = find_deser(priv); + int ret = 0; +@@ -1720,7 +1784,7 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd) + } + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) && + (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) && + (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12) +@@ -1878,7 +1942,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd) + return ret; + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + if (cfg.type == V4L2_MBUS_CSI2) + vnmc &= ~VNMC_DPINE; + else +@@ -1886,7 +1950,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd) + } + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) + val = VNDMR2_FTEV; + else + val = VNDMR2_FTEV | VNDMR2_VLV(1); +@@ -2484,7 +2548,7 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, + return ret; + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + /* Adjust max scaling size for Gen3 */ + if (pix->width > 4096) + pix->width = priv->max_width; +@@ -2663,6 +2727,7 @@ static int rcar_vin_get_edid(struct soc_camera_device *icd, + + #ifdef CONFIG_OF + static const struct of_device_id rcar_vin_of_table[] = { ++ { .compatible = "renesas,vin-r8a7798", .data = (void *)RCAR_V3H }, + { .compatible = "renesas,vin-r8a7797", .data = (void *)RCAR_V3M }, + { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 }, + { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 }, +@@ -2978,7 +3043,7 @@ static int rcar_vin_probe(struct platform_device *pdev) + } + + if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) { + priv->max_width = 4096; + priv->max_height = 4096; + } else { +@@ -2987,7 +3052,8 @@ static int rcar_vin_probe(struct platform_device *pdev) + } + + if ((priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || +- priv->chip == RCAR_V3M) && !of_property_read_string(np, "csi,select", &str)) { ++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) && ++ !of_property_read_string(np, "csi,select", &str)) { + u32 ifmd = 0; + bool match_flag = false; + const struct vin_gen3_ifmd *gen3_ifmd_table = NULL; +@@ -3062,6 +3128,8 @@ static int rcar_vin_probe(struct platform_device *pdev) + gen3_ifmd_table = vin_m3_vc_ifmd; + else if (priv->chip == RCAR_V3M) + gen3_ifmd_table = vin_v3_vc_ifmd; ++ else if (priv->chip == RCAR_V3H) ++ gen3_ifmd_table = vin_v3h_vc_ifmd; + + for (i = 0; i < num; i++) { + if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch +@@ -3219,6 +3287,9 @@ static int rcar_vin_resume(struct device *dev) + } else if (priv->chip == RCAR_V3M) { + ifmd = VNCSI_IFMD_DES1; + gen3_ifmd_table = vin_v3_vc_ifmd; ++ } else if (priv->chip == RCAR_V3H) { ++ ifmd = VNCSI_IFMD_DES0; ++ gen3_ifmd_table = vin_v3h_vc_ifmd; + } + + for (i = 0; i < num; i++) { +diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c +index e79f9e6..22fb76a 100644 +--- a/drivers/media/platform/vsp1/vsp1_lif.c ++++ b/drivers/media/platform/vsp1/vsp1_lif.c +@@ -29,6 +29,11 @@ + { } + }; + ++static const struct soc_device_attribute r8a7798[] = { ++ { .soc_id = "r8a7798" }, ++ { } ++}; ++ + /* ----------------------------------------------------------------------------- + * Device Access + */ +@@ -151,7 +156,8 @@ static void lif_configure(struct vsp1_entity *entity, + format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config, + LIF_PAD_SOURCE); + +- if (vsp1_gen3_vspdl_check(vsp1) || soc_device_match(r8a7797)) ++ if (vsp1_gen3_vspdl_check(vsp1) || ++ soc_device_match(r8a7797) || soc_device_match(r8a7798)) + obth = 1500; + else + obth = 3000; +diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c +index 040f474..72b46bb 100644 +--- a/drivers/mmc/host/sh_mobile_sdhi.c ++++ b/drivers/mmc/host/sh_mobile_sdhi.c +@@ -141,6 +141,7 @@ struct sh_mobile_sdhi_of_data { + { .compatible = "renesas,sdhi-r8a77965", + .data = &of_rcar_gen3_compatible, }, + { .compatible = "renesas,sdhi-r8a7797", .data = &of_rcar_gen3_compatible, }, ++ { .compatible = "renesas,sdhi-r8a7798", .data = &of_rcar_gen3_compatible, }, + {}, + }; + MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match); +diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c +index 73fa286..c539234 100644 +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -1921,6 +1921,7 @@ static int ravb_mdio_release(struct ravb_private *priv) + { .compatible = "renesas,etheravb-r8a7796", .data = (void *)RCAR_GEN3 }, + { .compatible = "renesas,etheravb-r8a77965", .data = (void *)RCAR_GEN3 }, + { .compatible = "renesas,etheravb-r8a7797", .data = (void *)RCAR_GEN3 }, ++ { .compatible = "renesas,etheravb-r8a7798", .data = (void *)RCAR_GEN3 }, + { .compatible = "renesas,etheravb-rcar-gen3", .data = (void *)RCAR_GEN3 }, + { } + }; +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index d18b452..f87cae6 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -456,6 +456,9 @@ static void sh_eth_select_mii(struct net_device *ndev) + u32 value; + + switch (mdp->phy_interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ value = 0x3; ++ break; + case PHY_INTERFACE_MODE_GMII: + value = 0x2; + break; +@@ -645,6 +648,36 @@ static void sh_eth_set_rate_r8a777x(struct net_device *ndev) + .rmiimode = 1, + .magic = 1, + }; ++ ++/* R8A7798 */ ++static struct sh_eth_cpu_data r8a7798_data = { ++ .set_duplex = sh_eth_set_duplex, ++ .set_rate = sh_eth_set_rate_gether, ++ ++ .register_type = SH_ETH_REG_GIGABIT, ++ ++ .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD | ECSR_MPD, ++ .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP | ++ ECSIPR_MPDIP, ++ .eesipr_value = 0x01ff009f, ++ ++ .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, ++ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | ++ EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | ++ EESR_TDE | EESR_ECI, ++ .fdr_value = 0x0000070f, ++ ++ .apr = 1, ++ .mpr = 1, ++ .tpauser = 1, ++ .nbst = 1, ++ .hw_swap = 1, ++ .no_trimd = 1, ++ .no_ade = 1, ++ .select_mii = 1, ++ .shift_rd0 = 1, ++ .magic = 1, ++}; + #endif /* CONFIG_OF */ + + static void sh_eth_set_rate_sh7724(struct net_device *ndev) +@@ -1088,14 +1121,14 @@ static void sh_eth_ring_free(struct net_device *ndev) + + if (mdp->rx_ring) { + ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; +- dma_free_coherent(NULL, ringsize, mdp->rx_ring, ++ dma_free_coherent(&ndev->dev, ringsize, mdp->rx_ring, + mdp->rx_desc_dma); + mdp->rx_ring = NULL; + } + + if (mdp->tx_ring) { + ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; +- dma_free_coherent(NULL, ringsize, mdp->tx_ring, ++ dma_free_coherent(&ndev->dev, ringsize, mdp->tx_ring, + mdp->tx_desc_dma); + mdp->tx_ring = NULL; + } +@@ -1209,9 +1242,16 @@ static int sh_eth_ring_init(struct net_device *ndev) + if (!mdp->tx_skbuff) + goto ring_free; + ++#ifdef CONFIG_ARM64 ++ { ++ struct device_node *np; ++ np = of_find_compatible_node(NULL, NULL, "shared-dma-pool"); ++ of_dma_configure(&ndev->dev, np); ++ } ++#endif + /* Allocate all Rx descriptors. */ + rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; +- mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, ++ mdp->rx_ring = dma_alloc_coherent(&ndev->dev, rx_ringsize, &mdp->rx_desc_dma, + GFP_KERNEL); + if (!mdp->rx_ring) + goto ring_free; +@@ -1220,7 +1260,7 @@ static int sh_eth_ring_init(struct net_device *ndev) + + /* Allocate all Tx descriptors. */ + tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; +- mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, ++ mdp->tx_ring = dma_alloc_coherent(&ndev->dev, tx_ringsize, &mdp->tx_desc_dma, + GFP_KERNEL); + if (!mdp->tx_ring) + goto ring_free; +@@ -1261,6 +1301,10 @@ static int sh_eth_dev_init(struct net_device *ndev) + #endif + sh_eth_write(ndev, 0, EDMR); + ++ /* DMA transfer burst mode */ ++ if (mdp->cd->nbst) ++ sh_eth_modify(ndev, EDMR, EDMR_NBST, EDMR_NBST); ++ + /* FIFO size set */ + sh_eth_write(ndev, mdp->cd->fdr_value, FDR); + sh_eth_write(ndev, 0, TFTR); +@@ -3001,6 +3045,7 @@ static struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev) + { .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data }, + { .compatible = "renesas,ether-r8a7793", .data = &r8a779x_data }, + { .compatible = "renesas,ether-r8a7794", .data = &r8a779x_data }, ++ { .compatible = "renesas,gether-r8a7798", .data = &r8a7798_data }, + { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data }, + { } + }; +diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h +index 4ceed00..2c4ddd6 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.h ++++ b/drivers/net/ethernet/renesas/sh_eth.h +@@ -163,7 +163,8 @@ enum { + }; + + /* Driver's parameters */ +-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) ++#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) || \ ++ defined(CONFIG_ARCH_R8A7798) + #define SH_ETH_RX_ALIGN 32 + #else + #define SH_ETH_RX_ALIGN 2 +@@ -184,6 +185,7 @@ enum GECMR_BIT { + + /* EDMR */ + enum DMAC_M_BIT { ++ EDMR_NBST = 0x80, + EDMR_EL = 0x40, /* Litte endian */ + EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, + EDMR_SRST_GETHER = 0x03, +@@ -484,6 +486,7 @@ struct sh_eth_cpu_data { + unsigned tpauser:1; /* EtherC have TPAUSER */ + unsigned bculr:1; /* EtherC have BCULR */ + unsigned tsu:1; /* EtherC have TSU */ ++ unsigned nbst:1; /* E-DMAC have NBST bit in EDMR */ + unsigned hw_swap:1; /* E-DMAC have DE bit in EDMR */ + unsigned rpadir:1; /* E-DMAC have RPADIR */ + unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */ +diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c +index ccc29b3..ebe7e92 100644 +--- a/drivers/pci/host/pcie-rcar.c ++++ b/drivers/pci/host/pcie-rcar.c +@@ -30,6 +30,7 @@ + #include <linux/platform_device.h> + #include <linux/pm_runtime.h> + #include <linux/slab.h> ++#include <linux/sys_soc.h> + + #define PCIECAR 0x000010 + #define PCIECCTLR 0x000018 +@@ -41,6 +42,8 @@ + #define PCIEINTXR 0x000400 + #define PCIEMSITXR 0x000840 + ++#define GEN3_PCIEPHYSR 0x07f0 ++ + /* Transfer control */ + #define PCIETCTLR 0x02000 + #define DL_DOWN (1 << 3) +@@ -118,6 +121,9 @@ + #define GEN2_PCIEPHYDATA 0x784 + #define GEN2_PCIEPHYCTRL 0x78c + ++/* R-Car Gen3 R8A7798 */ ++#define R8A7798_PCIEPHYCTL 0x4000 ++ + #define INT_PCI_MSI_NR 32 + + #define RCONF(x) (PCICONF(0)+(x)) +@@ -132,6 +138,11 @@ + #define RCAR_PCI_MAX_RESOURCES 4 + #define MAX_NR_INBOUND_MAPS 6 + ++static const struct soc_device_attribute r8a7798[] = { ++ { .soc_id = "r8a7798" }, ++ { } ++}; ++ + struct rcar_msi { + DECLARE_BITMAP(used, INT_PCI_MSI_NR); + struct irq_domain *domain; +@@ -151,6 +162,7 @@ static inline struct rcar_msi *to_rcar_msi(struct msi_controller *chip) + struct rcar_pcie { + struct device *dev; + void __iomem *base; ++ void __iomem *phy_base; + struct list_head resources; + int root_bus_nr; + struct clk *clk; +@@ -160,6 +172,18 @@ struct rcar_pcie { + + static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie); + ++static void rcar_pci_phy_write_reg(struct rcar_pcie *pcie, unsigned long val, ++ unsigned long reg) ++{ ++ writel(val, pcie->phy_base + reg); ++} ++ ++static unsigned long rcar_pci_phy_read_reg(struct rcar_pcie *pcie, ++ unsigned long reg) ++{ ++ return readl(pcie->phy_base + reg); ++} ++ + static void rcar_pci_write_reg(struct rcar_pcie *pcie, unsigned long val, + unsigned long reg) + { +@@ -672,6 +696,22 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie) + return 0; + } + ++static int rcar_pcie_hw_init_r8a7798(struct rcar_pcie *pcie) ++{ ++ unsigned int timeout = 10; ++ ++ rcar_pci_phy_write_reg(pcie, 0, R8A7798_PCIEPHYCTL); ++ ++ while (timeout--) { ++ if (rcar_pci_read_reg(pcie, GEN3_PCIEPHYSR)) ++ return rcar_pcie_hw_init(pcie); ++ ++ msleep(5); ++ } ++ ++ return -ETIMEDOUT; ++} ++ + static int rcar_pcie_hw_init_h1(struct rcar_pcie *pcie) + { + unsigned int timeout = 10; +@@ -998,6 +1038,16 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie) + if (IS_ERR(pcie->base)) + return PTR_ERR(pcie->base); + ++ if (soc_device_match(r8a7798)) { ++ err = of_address_to_resource(dev->of_node, 1, &res); ++ if (err) ++ return err; ++ ++ pcie->phy_base = devm_ioremap_resource(dev, &res); ++ if (IS_ERR(pcie->phy_base)) ++ return PTR_ERR(pcie->base); ++ } ++ + pcie->bus_clk = devm_clk_get(dev, "pcie_bus"); + if (IS_ERR(pcie->bus_clk)) { + dev_err(dev, "cannot get pcie bus clock\n"); +@@ -1153,6 +1203,7 @@ static int rcar_pcie_parse_map_dma_ranges(struct rcar_pcie *pcie, + { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init }, + { .compatible = "renesas,pcie-r8a7796", .data = rcar_pcie_hw_init }, + { .compatible = "renesas,pcie-r8a77965", .data = rcar_pcie_hw_init }, ++ { .compatible = "renesas,pcie-r8a7798", .data = rcar_pcie_hw_init_r8a7798 }, + {}, + }; + +@@ -1347,7 +1398,13 @@ static SIMPLE_DEV_PM_OPS(rcar_pcie_pm_ops, + }, + .probe = rcar_pcie_probe, + }; +-builtin_platform_driver(rcar_pcie_driver); ++/* builtin_platform_driver(rcar_pcie_driver); */ ++ ++static int __init rcar_pcie_init(void) ++{ ++ return platform_driver_register(&rcar_pcie_driver); ++} ++late_initcall(rcar_pcie_init); + + static int rcar_pcie_pci_notifier(struct notifier_block *nb, + unsigned long action, void *data) +diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig +index 4aaf0be..6ae17af 100644 +--- a/drivers/pinctrl/sh-pfc/Kconfig ++++ b/drivers/pinctrl/sh-pfc/Kconfig +@@ -89,6 +89,11 @@ config PINCTRL_PFC_R8A7797 + depends on ARCH_R8A7797 + select PINCTRL_SH_PFC + ++config PINCTRL_PFC_R8A7798 ++ def_bool y ++ depends on ARCH_R8A7798 ++ select PINCTRL_SH_PFC ++ + config PINCTRL_PFC_SH7203 + def_bool y + depends on CPU_SUBTYPE_SH7203 +diff --git a/drivers/pinctrl/sh-pfc/Makefile b/drivers/pinctrl/sh-pfc/Makefile +index e263c14..5f2f619 100644 +--- a/drivers/pinctrl/sh-pfc/Makefile ++++ b/drivers/pinctrl/sh-pfc/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795-es1.o + obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o + obj-$(CONFIG_PINCTRL_PFC_R8A77965) += pfc-r8a77965.o + obj-$(CONFIG_PINCTRL_PFC_R8A7797) += pfc-r8a7797.o ++obj-$(CONFIG_PINCTRL_PFC_R8A7798) += pfc-r8a7798.o + obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o + obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o + obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o +diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c +index 9aba933..d685090 100644 +--- a/drivers/pinctrl/sh-pfc/core.c ++++ b/drivers/pinctrl/sh-pfc/core.c +@@ -552,6 +552,12 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc) + .data = &r8a7797_pinmux_info, + }, + #endif ++#ifdef CONFIG_PINCTRL_PFC_R8A7798 ++ { ++ .compatible = "renesas,pfc-r8a7798", ++ .data = &r8a7798_pinmux_info, ++ }, ++#endif + #ifdef CONFIG_PINCTRL_PFC_SH73A0 + { + .compatible = "renesas,pfc-sh73a0", +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7798.c b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c +new file mode 100644 +index 0000000..39aba74 +--- /dev/null ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c +@@ -0,0 +1,3151 @@ ++/* ++ * R8A7798 processor support - PFC hardware block. ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This file is based on the drivers/pinctrl/sh-pfc/pfc-r8a7795.c ++ * ++ * R-Car Gen3 processor support - PFC hardware block. ++ * ++ * Copyright (C) 2015 Renesas Electronics Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ */ ++ ++#include <linux/io.h> ++#include <linux/kernel.h> ++#include <linux/sys_soc.h> ++ ++#include "core.h" ++#include "sh_pfc.h" ++ ++/* mmc in gpsr3, so do POC; check if any other reg needs it */ ++#define CPU_ALL_PORT(fn, sfx) \ ++ PORT_GP_CFG_22(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ ++ PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ ++ PORT_GP_CFG_30(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ ++ PORT_GP_CFG_17(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | \ ++ SH_PFC_PIN_CFG_IO_VOLTAGE), \ ++ PORT_GP_CFG_25(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ ++ PORT_GP_CFG_15(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH) ++/* ++ * F_() : just information ++ * FM() : macro for FN_xxx / xxx_MARK ++ */ ++ ++/* GPSR0 */ ++#define GPSR0_21 F_(DU_EXODDF_DU_ODDF_DISP_CDE, IP2_23_20) ++#define GPSR0_20 F_(DU_EXVSYNC_DU_VSYNC, IP2_19_16) ++#define GPSR0_19 F_(DU_EXHSYNC_DU_HSYNC, IP2_15_12) ++#define GPSR0_18 F_(DU_DOTCLKOUT, IP2_11_8) ++#define GPSR0_17 F_(DU_DB7, IP2_7_4) ++#define GPSR0_16 F_(DU_DB6, IP2_3_0) ++#define GPSR0_15 F_(DU_DB5, IP1_31_28) ++#define GPSR0_14 F_(DU_DB4, IP1_27_24) ++#define GPSR0_13 F_(DU_DB3, IP1_23_20) ++#define GPSR0_12 F_(DU_DB2, IP1_19_16) ++#define GPSR0_11 F_(DU_DG7, IP1_15_12) ++#define GPSR0_10 F_(DU_DG6, IP1_11_8) ++#define GPSR0_9 F_(DU_DG5, IP1_7_4) ++#define GPSR0_8 F_(DU_DG4, IP1_3_0) ++#define GPSR0_7 F_(DU_DG3, IP0_31_28) ++#define GPSR0_6 F_(DU_DG2, IP0_27_24) ++#define GPSR0_5 F_(DU_DR7, IP0_23_20) ++#define GPSR0_4 F_(DU_DR6, IP0_19_16) ++#define GPSR0_3 F_(DU_DR5, IP0_15_12) ++#define GPSR0_2 F_(DU_DR4, IP0_11_8) ++#define GPSR0_1 F_(DU_DR3, IP0_7_4) ++#define GPSR0_0 F_(DU_DR2, IP0_3_0) ++ ++/* GPSR1 */ ++#define GPSR1_27 F_(DIGRF_CLKOUT, IP8_31_28) ++#define GPSR1_26 F_(DIGRF_CLKIN, IP8_27_24) ++#define GPSR1_25 F_(CANFD_CLK_A, IP8_23_20) /* OK? */ ++#define GPSR1_24 F_(CANFD1_RX, IP8_19_16) ++#define GPSR1_23 F_(CANFD1_TX, IP8_15_12) ++#define GPSR1_22 F_(CANFD0_RX_A, IP8_11_8) ++#define GPSR1_21 F_(CANFD0_TX_A, IP8_7_4) ++#define GPSR1_20 F_(AVB_AVTP_CAPTURE, IP8_3_0) ++#define GPSR1_19 F_(AVB_AVTP_MATCH, IP7_31_28) ++#define GPSR1_18 FM(AVB_LINK) ++#define GPSR1_17 FM(AVB_PHY_INT) ++#define GPSR1_16 FM(AVB_MAGIC) ++#define GPSR1_15 FM(AVB_MDC) ++#define GPSR1_14 FM(AVB_MDIO) ++#define GPSR1_13 FM(AVB_TXCREFCLK) ++#define GPSR1_12 FM(AVB_TD3) ++#define GPSR1_11 FM(AVB_TD2) ++#define GPSR1_10 FM(AVB_TD1) ++#define GPSR1_9 FM(AVB_TD0) ++#define GPSR1_8 FM(AVB_TXC) ++#define GPSR1_7 FM(AVB_TX_CTL) ++#define GPSR1_6 FM(AVB_RD3) ++#define GPSR1_5 FM(AVB_RD2) ++#define GPSR1_4 FM(AVB_RD1) ++#define GPSR1_3 FM(AVB_RD0) ++#define GPSR1_2 FM(AVB_RXC) ++#define GPSR1_1 FM(AVB_RX_CTL) ++#define GPSR1_0 F_(IRQ0, IP2_27_24) ++ ++/* GPSR2 */ ++#define GPSR2_29 F_(FSO_TOE_N, IP10_19_16) ++#define GPSR2_28 F_(FSO_CFE_1_N, IP10_15_12) ++#define GPSR2_27 F_(FSO_CFE_0_N, IP10_11_8) ++#define GPSR2_26 F_(SDA3, IP10_7_4) ++#define GPSR2_25 F_(SCL3, IP10_3_0) ++#define GPSR2_24 F_(MSIOF0_SS2, IP9_31_28) ++#define GPSR2_23 F_(MSIOF0_SS1, IP9_27_24) ++#define GPSR2_22 F_(MSIOF0_SYNC, IP9_23_20) ++#define GPSR2_21 F_(MSIOF0_SCK, IP9_19_16) ++#define GPSR2_20 F_(MSIOF0_TXD, IP9_15_12) ++#define GPSR2_19 F_(MSIOF0_RXD, IP9_11_8) ++#define GPSR2_18 F_(IRQ5, IP9_7_4) ++#define GPSR2_17 F_(IRQ4, IP9_3_0) ++#define GPSR2_16 F_(VI0_FIELD, IP4_31_28) ++#define GPSR2_15 F_(VI0_DATA11, IP4_27_24) ++#define GPSR2_14 F_(VI0_DATA10, IP4_23_20) ++#define GPSR2_13 F_(VI0_DATA9, IP4_19_16) ++#define GPSR2_12 F_(VI0_DATA8, IP4_15_12) ++#define GPSR2_11 F_(VI0_DATA7, IP4_11_8) ++#define GPSR2_10 F_(VI0_DATA6, IP4_7_4) ++#define GPSR2_9 F_(VI0_DATA5, IP4_3_0) ++#define GPSR2_8 F_(VI0_DATA4, IP3_31_28) ++#define GPSR2_7 F_(VI0_DATA3, IP3_27_24) ++#define GPSR2_6 F_(VI0_DATA2, IP3_23_20) ++#define GPSR2_5 F_(VI0_DATA1, IP3_19_16) ++#define GPSR2_4 F_(VI0_DATA0, IP3_15_12) ++#define GPSR2_3 F_(VI0_VSYNC_N, IP3_11_8) ++#define GPSR2_2 F_(VI0_HSYNC_N, IP3_7_4) ++#define GPSR2_1 F_(VI0_CLKENB, IP3_3_0) ++#define GPSR2_0 F_(VI0_CLK, IP2_31_28) ++ ++/* GPSR3 */ ++#define GPSR3_16 F_(VI1_FIELD, IP7_3_0) ++#define GPSR3_15 F_(VI1_DATA11, IP6_31_28) ++#define GPSR3_14 F_(VI1_DATA10, IP6_27_24) ++#define GPSR3_13 F_(VI1_DATA9, IP6_23_20) ++#define GPSR3_12 F_(VI1_DATA8, IP6_19_16) ++#define GPSR3_11 F_(VI1_DATA7, IP6_15_12) ++#define GPSR3_10 F_(VI1_DATA6, IP6_11_8) ++#define GPSR3_9 F_(VI1_DATA5, IP6_7_4) ++#define GPSR3_8 F_(VI1_DATA4, IP6_3_0) ++#define GPSR3_7 F_(VI1_DATA3, IP5_31_28) ++#define GPSR3_6 F_(VI1_DATA2, IP5_27_24) ++#define GPSR3_5 F_(VI1_DATA1, IP5_23_20) ++#define GPSR3_4 F_(VI1_DATA0, IP5_19_16) ++#define GPSR3_3 F_(VI1_VSYNC_N, IP5_15_12) ++#define GPSR3_2 F_(VI1_HSYNC_N, IP5_11_8) ++#define GPSR3_1 F_(VI1_CLKENB, IP5_7_4) ++#define GPSR3_0 F_(VI1_CLK, IP5_3_0) ++ ++/* GPSR4 */ ++#define GPSR4_24 FM(GETHER_LINK_A) ++#define GPSR4_23 FM(GETHER_PHY_INT_A) ++#define GPSR4_22 FM(GETHER_MAGIC) ++#define GPSR4_21 FM(GETHER_MDC_A) ++#define GPSR4_20 FM(GETHER_MDIO_A) ++#define GPSR4_19 FM(GETHER_TXCREFCLK_MEGA) ++#define GPSR4_18 FM(GETHER_TXCREFCLK) ++#define GPSR4_17 FM(GETHER_TD3) ++#define GPSR4_16 FM(GETHER_TD2) ++#define GPSR4_15 FM(GETHER_TD1) ++#define GPSR4_14 FM(GETHER_TD0) ++#define GPSR4_13 FM(GETHER_TXC) ++#define GPSR4_12 FM(GETHER_TX_CTL) ++#define GPSR4_11 FM(GETHER_RD3) ++#define GPSR4_10 FM(GETHER_RD2) ++#define GPSR4_9 FM(GETHER_RD1) ++#define GPSR4_8 FM(GETHER_RD0) ++#define GPSR4_7 FM(GETHER_RXC) ++#define GPSR4_6 FM(GETHER_RX_CTL) ++#define GPSR4_5 F_(SDA2, IP7_27_24) ++#define GPSR4_4 F_(SCL2, IP7_23_20) ++#define GPSR4_3 F_(SDA1, IP7_19_16) ++#define GPSR4_2 F_(SCL1, IP7_15_12) ++#define GPSR4_1 F_(SDA0, IP7_11_8) ++#define GPSR4_0 F_(SCL0, IP7_7_4) ++ ++/* GPSR5 */ ++#define GPSR5_14 FM(RPC_INT_N) ++#define GPSR5_13 FM(RPC_WP_N) ++#define GPSR5_12 FM(RPC_RESET_N) ++#define GPSR5_11 FM(QSPI1_SSL) ++#define GPSR5_10 FM(QSPI1_IO3) ++#define GPSR5_9 FM(QSPI1_IO2) ++#define GPSR5_8 FM(QSPI1_MISO_IO1) ++#define GPSR5_7 FM(QSPI1_MOSI_IO0) ++#define GPSR5_6 FM(QSPI1_SPCLK) ++#define GPSR5_5 FM(QSPI0_SSL) ++#define GPSR5_4 FM(QSPI0_IO3) ++#define GPSR5_3 FM(QSPI0_IO2) ++#define GPSR5_2 FM(QSPI0_MISO_IO1) ++#define GPSR5_1 FM(QSPI0_MOSI_IO0) ++#define GPSR5_0 FM(QSPI0_SPCLK) ++ ++ ++/* IPSRx */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ /* 8 */ /* 9 */ /* A */ /* B */ /* C */ /* D */ /* E */ /* F */ ++#define IP0_3_0 FM(DU_DR2) FM(SCK4) FM(GETHER_RMII_CRS_DV) FM(A0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0_7_4 FM(DU_DR3) FM(RX4) FM(GETHER_RMII_RX_ER) FM(A1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0_11_8 FM(DU_DR4) FM(TX4) FM(GETHER_RMII_RXD0) FM(A2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0_15_12 FM(DU_DR5) FM(CTS4_N) FM(GETHER_RMII_RXD1) FM(A3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0_19_16 FM(DU_DR6) FM(RTS4_N_TANS) FM(GETHER_RMII_TXD_EN) FM(A4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0_23_20 FM(DU_DR7) F_(0, 0) FM(GETHER_RMII_TXD0) FM(A5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0_27_24 FM(DU_DG2) F_(0, 0) FM(GETHER_RMII_TXD1) FM(A6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0_31_28 FM(DU_DG3) FM(CPG_CPCKOUT) FM(GETHER_RMII_REFCLK) FM(A7) FM(PWMFSW0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_3_0 FM(DU_DG4) FM(SCL5) F_(0, 0) FM(A8) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_7_4 FM(DU_DG5) FM(SDA5) FM(GETHER_MDC_B) FM(A9) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_11_8 FM(DU_DG6) FM(SCIF_CLK_A) FM(GETHER_MDIO_B) FM(A10) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_15_12 FM(DU_DG7) FM(HRX0_A) F_(0, 0) FM(A11) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_19_16 FM(DU_DB2) FM(HSCK0_A) F_(0, 0) FM(A12) FM(IRQ1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_23_20 FM(DU_DB3) FM(HRTS0_N_A) F_(0, 0) FM(A13) FM(IRQ2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_27_24 FM(DU_DB4) FM(HCTS0_N_A) F_(0, 0) FM(A14) FM(IRQ3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1_31_28 FM(DU_DB5) FM(HTX0_A) FM(PWM0_A) FM(A15) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_3_0 FM(DU_DB6) FM(MSIOF3_RXD) F_(0, 0) FM(A16) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_7_4 FM(DU_DB7) FM(MSIOF3_TXD) F_(0, 0) FM(A17) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_11_8 FM(DU_DOTCLKOUT) FM(MSIOF3_SS1) FM(GETHER_LINK_B) FM(A18) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_15_12 FM(DU_EXHSYNC_DU_HSYNC) FM(MSIOF3_SS2) FM(GETHER_PHY_INT_B) FM(A19) FM(FXR_TXENA_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_19_16 FM(DU_EXVSYNC_DU_VSYNC) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) FM(FXR_TXENB_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_23_20 FM(DU_EXODDF_DU_ODDF_DISP_CDE) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_27_24 FM(IRQ0) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2_31_28 FM(VI0_CLK) FM(MSIOF2_SCK) FM(SCK3) F_(0, 0) FM(HSCK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_3_0 FM(VI0_CLKENB) FM(MSIOF2_RXD) FM(RX3) FM(RD_WR_N) FM(HCTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_7_4 FM(VI0_HSYNC_N) FM(MSIOF2_TXD) FM(TX3) F_(0, 0) FM(HRTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_11_8 FM(VI0_VSYNC_N) FM(MSIOF2_SYNC) FM(CTS3_N) F_(0, 0) FM(HTX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_15_12 FM(VI0_DATA0) FM(MSIOF2_SS1) FM(RTS3_N_TANS) F_(0, 0) FM(HRX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_19_16 FM(VI0_DATA1) FM(MSIOF2_SS2) FM(SCK1) F_(0, 0) FM(SPEEDIN_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_23_20 FM(VI0_DATA2) FM(AVB_AVTP_PPS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_27_24 FM(VI0_DATA3) FM(HSCK1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3_31_28 FM(VI0_DATA4) FM(HRTS1_N) FM(RX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_3_0 FM(VI0_DATA5) FM(HCTS1_N) FM(TX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_7_4 FM(VI0_DATA6) FM(HTX1) FM(CTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_11_8 FM(VI0_DATA7) FM(HRX1) FM(RTS1_N_TANS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_15_12 FM(VI0_DATA8) FM(HSCK2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_19_16 FM(VI0_DATA9) FM(HCTS2_N) FM(PWM1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_23_20 FM(VI0_DATA10) FM(HRTS2_N) FM(PWM2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_27_24 FM(VI0_DATA11) FM(HTX2) FM(PWM3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP4_31_28 FM(VI0_FIELD) FM(HRX2) FM(PWM4_A) FM(CS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_3_0 FM(VI1_CLK) FM(MSIOF1_RXD) F_(0, 0) FM(CS0_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_7_4 FM(VI1_CLKENB) FM(MSIOF1_TXD) F_(0, 0) FM(D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_11_8 FM(VI1_HSYNC_N) FM(MSIOF1_SCK) F_(0, 0) FM(D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_15_12 FM(VI1_VSYNC_N) FM(MSIOF1_SYNC) F_(0, 0) FM(D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_19_16 FM(VI1_DATA0) FM(MSIOF1_SS1) F_(0, 0) FM(D3) FM(MMC_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_23_20 FM(VI1_DATA1) FM(MSIOF1_SS2) F_(0, 0) FM(D4) FM(MMC_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_27_24 FM(VI1_DATA2) FM(CANFD0_TX_B) F_(0, 0) FM(D5) FM(MMC_DS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP5_31_28 FM(VI1_DATA3) FM(CANFD0_RX_B) F_(0, 0) FM(D6) FM(MMC_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_3_0 FM(VI1_DATA4) FM(CANFD_CLK_B) F_(0, 0) FM(D7) FM(MMC_D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_7_4 FM(VI1_DATA5) F_(0, 0) F_(0, 0) FM(D8) FM(MMC_D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_11_8 FM(VI1_DATA6) F_(0, 0) F_(0, 0) FM(D9) FM(MMC_D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_15_12 FM(VI1_DATA7) F_(0, 0) F_(0, 0) FM(D10) FM(MMC_D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_19_16 FM(VI1_DATA8) F_(0, 0) F_(0, 0) FM(D11) FM(MMC_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_23_20 FM(VI1_DATA9) FM(TCLK1_A) F_(0, 0) FM(D12) FM(MMC_D4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_27_24 FM(VI1_DATA10) FM(TCLK2_A) F_(0, 0) FM(D13) FM(MMC_D5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP6_31_28 FM(VI1_DATA11) FM(SCL4) F_(0, 0) FM(D14) FM(MMC_D6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_3_0 FM(VI1_FIELD) FM(SDA4) F_(0, 0) FM(D15) FM(MMC_D7) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_7_4 FM(SCL0) F_(0, 0) F_(0, 0) FM(CLKOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_11_8 FM(SDA0) F_(0, 0) F_(0, 0) FM(BS_N) FM(SCK0) FM(HSCK0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_15_12 FM(SCL1) F_(0, 0) FM(TPU0TO2) FM(RD_N) FM(CTS0_N) FM(HCTS0_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_19_16 FM(SDA1) F_(0, 0) FM(TPU0TO3) FM(WE0_N) FM(RTS0_N_TANS) FM(HRTS0_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_23_20 FM(SCL2) F_(0, 0) F_(0, 0) FM(WE1_N) FM(RX0) FM(HRX0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_27_24 FM(SDA2) F_(0, 0) F_(0, 0) FM(EX_WAIT0) FM(TX0) FM(HTX0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP7_31_28 FM(AVB_AVTP_MATCH) FM(TPU0TO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_3_0 FM(AVB_AVTP_CAPTURE) FM(TPU0TO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_7_4 FM(CANFD0_TX_A) FM(FXR_TXDA) FM(PWM0_B) FM(DU_DISP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_11_8 FM(CANFD0_RX_A) FM(RXDA_EXTFXR) FM(PWM1_B) FM(DU_CDE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_15_12 FM(CANFD1_TX) FM(FXR_TXDB) FM(PWM2_B) FM(TCLK1_B) FM(TX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_19_16 FM(CANFD1_RX) FM(RXDB_EXTFXR) FM(PWM3_B) FM(TCLK2_B) FM(RX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_23_20 FM(CANFD_CLK_A) FM(CLK_EXTFXR) FM(PWM4_B) FM(SPEEDIN_B) FM(SCIF_CLK_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_27_24 FM(DIGRF_CLKIN) FM(DIGRF_CLKEN_IN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP8_31_28 FM(DIGRF_CLKOUT) FM(DIGRF_CLKEN_OUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_3_0 FM(IRQ4) F_(0, 0) F_(0, 0) FM(VI0_DATA12) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_7_4 FM(IRQ5) F_(0, 0) F_(0, 0) FM(VI0_DATA13) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_11_8 FM(MSIOF0_RXD) FM(DU_DR0) F_(0, 0) FM(VI0_DATA14) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_15_12 FM(MSIOF0_TXD) FM(DU_DR1) F_(0, 0) FM(VI0_DATA15) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_19_16 FM(MSIOF0_SCK) FM(DU_DG0) F_(0, 0) FM(VI0_DATA16) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_23_20 FM(MSIOF0_SYNC) FM(DU_DG1) F_(0, 0) FM(VI0_DATA17) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_27_24 FM(MSIOF0_SS1) FM(DU_DB0) FM(TCLK3) FM(VI0_DATA18) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP9_31_28 FM(MSIOF0_SS2) FM(DU_DB1) FM(TCLK4) FM(VI0_DATA19) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_3_0 FM(SCL3) F_(0, 0) F_(0, 0) FM(VI0_DATA20) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_7_4 FM(SDA3) F_(0, 0) F_(0, 0) FM(VI0_DATA21) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_11_8 FM(FSO_CFE_0_N) F_(0, 0) F_(0, 0) FM(VI0_DATA22) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_15_12 FM(FSO_CFE_1_N) F_(0, 0) F_(0, 0) FM(VI0_DATA23) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_19_16 FM(FSO_TOE_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_23_20 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_27_24 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP10_31_28 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++ ++#define PINMUX_GPSR \ ++\ ++ GPSR2_29 \ ++ GPSR2_28 \ ++ GPSR1_27 GPSR2_27 \ ++ GPSR1_26 GPSR2_26 \ ++ GPSR1_25 GPSR2_25 \ ++ GPSR1_24 GPSR2_24 GPSR4_24 \ ++ GPSR1_23 GPSR2_23 GPSR4_23 \ ++ GPSR1_22 GPSR2_22 GPSR4_22 \ ++GPSR0_21 GPSR1_21 GPSR2_21 GPSR4_21 \ ++GPSR0_20 GPSR1_20 GPSR2_20 GPSR4_20 \ ++GPSR0_19 GPSR1_19 GPSR2_19 GPSR4_19 \ ++GPSR0_18 GPSR1_18 GPSR2_18 GPSR4_18 \ ++GPSR0_17 GPSR1_17 GPSR2_17 GPSR4_17 \ ++GPSR0_16 GPSR1_16 GPSR2_16 GPSR3_16 GPSR4_16 \ ++GPSR0_15 GPSR1_15 GPSR2_15 GPSR3_15 GPSR4_15 \ ++GPSR0_14 GPSR1_14 GPSR2_14 GPSR3_14 GPSR4_14 GPSR5_14 \ ++GPSR0_13 GPSR1_13 GPSR2_13 GPSR3_13 GPSR4_13 GPSR5_13 \ ++GPSR0_12 GPSR1_12 GPSR2_12 GPSR3_12 GPSR4_12 GPSR5_12 \ ++GPSR0_11 GPSR1_11 GPSR2_11 GPSR3_11 GPSR4_11 GPSR5_11 \ ++GPSR0_10 GPSR1_10 GPSR2_10 GPSR3_10 GPSR4_10 GPSR5_10 \ ++GPSR0_9 GPSR1_9 GPSR2_9 GPSR3_9 GPSR4_9 GPSR5_9 \ ++GPSR0_8 GPSR1_8 GPSR2_8 GPSR3_8 GPSR4_8 GPSR5_8 \ ++GPSR0_7 GPSR1_7 GPSR2_7 GPSR3_7 GPSR4_7 GPSR5_7 \ ++GPSR0_6 GPSR1_6 GPSR2_6 GPSR3_6 GPSR4_6 GPSR5_6 \ ++GPSR0_5 GPSR1_5 GPSR2_5 GPSR3_5 GPSR4_5 GPSR5_5 \ ++GPSR0_4 GPSR1_4 GPSR2_4 GPSR3_4 GPSR4_4 GPSR5_4 \ ++GPSR0_3 GPSR1_3 GPSR2_3 GPSR3_3 GPSR4_3 GPSR5_3 \ ++GPSR0_2 GPSR1_2 GPSR2_2 GPSR3_2 GPSR4_2 GPSR5_2 \ ++GPSR0_1 GPSR1_1 GPSR2_1 GPSR3_1 GPSR4_1 GPSR5_1 \ ++GPSR0_0 GPSR1_0 GPSR2_0 GPSR3_0 GPSR4_0 GPSR5_0 ++ ++#define PINMUX_IPSR \ ++\ ++FM(IP0_3_0) IP0_3_0 FM(IP1_3_0) IP1_3_0 FM(IP2_3_0) IP2_3_0 FM(IP3_3_0) IP3_3_0 \ ++FM(IP0_7_4) IP0_7_4 FM(IP1_7_4) IP1_7_4 FM(IP2_7_4) IP2_7_4 FM(IP3_7_4) IP3_7_4 \ ++FM(IP0_11_8) IP0_11_8 FM(IP1_11_8) IP1_11_8 FM(IP2_11_8) IP2_11_8 FM(IP3_11_8) IP3_11_8 \ ++FM(IP0_15_12) IP0_15_12 FM(IP1_15_12) IP1_15_12 FM(IP2_15_12) IP2_15_12 FM(IP3_15_12) IP3_15_12 \ ++FM(IP0_19_16) IP0_19_16 FM(IP1_19_16) IP1_19_16 FM(IP2_19_16) IP2_19_16 FM(IP3_19_16) IP3_19_16 \ ++FM(IP0_23_20) IP0_23_20 FM(IP1_23_20) IP1_23_20 FM(IP2_23_20) IP2_23_20 FM(IP3_23_20) IP3_23_20 \ ++FM(IP0_27_24) IP0_27_24 FM(IP1_27_24) IP1_27_24 FM(IP2_27_24) IP2_27_24 FM(IP3_27_24) IP3_27_24 \ ++FM(IP0_31_28) IP0_31_28 FM(IP1_31_28) IP1_31_28 FM(IP2_31_28) IP2_31_28 FM(IP3_31_28) IP3_31_28 \ ++\ ++FM(IP4_3_0) IP4_3_0 FM(IP5_3_0) IP5_3_0 FM(IP6_3_0) IP6_3_0 FM(IP7_3_0) IP7_3_0 \ ++FM(IP4_7_4) IP4_7_4 FM(IP5_7_4) IP5_7_4 FM(IP6_7_4) IP6_7_4 FM(IP7_7_4) IP7_7_4 \ ++FM(IP4_11_8) IP4_11_8 FM(IP5_11_8) IP5_11_8 FM(IP6_11_8) IP6_11_8 FM(IP7_11_8) IP7_11_8 \ ++FM(IP4_15_12) IP4_15_12 FM(IP5_15_12) IP5_15_12 FM(IP6_15_12) IP6_15_12 FM(IP7_15_12) IP7_15_12 \ ++FM(IP4_19_16) IP4_19_16 FM(IP5_19_16) IP5_19_16 FM(IP6_19_16) IP6_19_16 FM(IP7_19_16) IP7_19_16 \ ++FM(IP4_23_20) IP4_23_20 FM(IP5_23_20) IP5_23_20 FM(IP6_23_20) IP6_23_20 FM(IP7_23_20) IP7_23_20 \ ++FM(IP4_27_24) IP4_27_24 FM(IP5_27_24) IP5_27_24 FM(IP6_27_24) IP6_27_24 FM(IP7_27_24) IP7_27_24 \ ++FM(IP4_31_28) IP4_31_28 FM(IP5_31_28) IP5_31_28 FM(IP6_31_28) IP6_31_28 FM(IP7_31_28) IP7_31_28 \ ++\ ++FM(IP8_3_0) IP8_3_0 FM(IP9_3_0) IP9_3_0 FM(IP10_3_0) IP10_3_0 \ ++FM(IP8_7_4) IP8_7_4 FM(IP9_7_4) IP9_7_4 FM(IP10_7_4) IP10_7_4 \ ++FM(IP8_11_8) IP8_11_8 FM(IP9_11_8) IP9_11_8 FM(IP10_11_8) IP10_11_8 \ ++FM(IP8_15_12) IP8_15_12 FM(IP9_15_12) IP9_15_12 FM(IP10_15_12) IP10_15_12 \ ++FM(IP8_19_16) IP8_19_16 FM(IP9_19_16) IP9_19_16 FM(IP10_19_16) IP10_19_16 \ ++FM(IP8_23_20) IP8_23_20 FM(IP9_23_20) IP9_23_20 FM(IP10_23_20) IP10_23_20 \ ++FM(IP8_27_24) IP8_27_24 FM(IP9_27_24) IP9_27_24 FM(IP10_27_24) IP10_27_24 \ ++FM(IP8_31_28) IP8_31_28 FM(IP9_31_28) IP9_31_28 FM(IP10_31_28) IP10_31_28 ++ ++/* ++ Set Value = H'0 Set Value = H'1 ++Register Function Pin Function Pin ++------------------------------------------------------------ ++sel_canfd0 CANFD0_TX_A CANFD0_TX_A CANFD0_TX_B VI1_DATA2 ++ CANFD0_RX_A CANFD0_RX_A CANFD0_TX_B VI1_DATA3 ++ CANFD_CLK_A CANFD_CLK_A CANFD_CLK_B VI1_DATA4 ++sel_gether GETHER_MDC_A GETHER_MDC_A GETHER_MDC_B DU_DG5 ++ GETHER_MDIO_A GETHER_MDIO_A GETHER_MDIO_B DU_DG6 ++ GETHER_LINK_A GETHER_LINK_A GETHER_LINK_B DU_DOTCLKOUT ++ GETHER_PHY_INT_A GETHER_PHY_INT_A GETHER_PHY_INT_B DU_EXHSYNC_DU_HSYNC ++sel_hscif0 HSCK0_A DU_DB2 HSCK0_B SDA0 ++ HCTS0_N_A DU_DB4 HCTS_N_B SCL1 ++ HRTS0_N_A DU_DB3 HRTS_N_B SDA1 ++ HRX0_A DU_DG7 HRX0_B SCL2 ++ HTX0_A DU_DB5 HTX0_B SDA2 ++ SCIF_CLK_A DU_DG6 SCIF_CLK_B CANFD_CLK_A ++sel_pwm0 PWM0_A DU_DB5 PWM0_B CANFD0_TX_A ++sel_pwm1 PWM1_A VI0_DATA9 PWM1_B CANFD0_RX_A ++sel_pwm2 PWM2_A VI0_DATA10 PWM2_B CANFD1_TX ++sel_pwm3 PWM3_A VI0_DATA11 PWM3_B CANFD1_RX ++sel_pwm4 PWM4_A VI0_FIELD PWM4_B CANFD_CLK_A ++sel_rsp SPEEDIN_A VI0_DATA1 SPEEDIN_B CANFD_CLK_A ++sel_scif1 RX1_A VI0_DATA4 RX1_B CANFD1_RX ++ TX1_A VI0_DATA5 TX1_B CANFD1_TX ++sel_tmu TCLK1_A VI1_DATA9 TCLK1_B CANFD1_TX ++ TCLK2_A VI1_DATA10 TCLK2_B CANFD1_RX ++*/ ++/* MOD_SEL0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ ++#define MOD_SEL0_11 FM(SEL_CANFD0_0) FM(SEL_CANFD0_1) ++#define MOD_SEL0_10 FM(SEL_GETHER_0) FM(SEL_GETHER_1) ++#define MOD_SEL0_9 FM(SEL_HSCIF0_0) FM(SEL_HSCIF0_1) ++#define MOD_SEL0_8 FM(SEL_PWM0_0) FM(SEL_PWM0_1) ++#define MOD_SEL0_7 FM(SEL_PWM1_0) FM(SEL_PWM1_1) ++#define MOD_SEL0_6 FM(SEL_PWM2_0) FM(SEL_PWM2_1) ++#define MOD_SEL0_5 FM(SEL_PWM3_0) FM(SEL_PWM3_1) ++#define MOD_SEL0_4 FM(SEL_PWM4_0) FM(SEL_PWM4_1) ++#define MOD_SEL0_2 FM(SEL_RSP_0) FM(SEL_RSP_1) ++#define MOD_SEL0_1 FM(SEL_SCIF1_0) FM(SEL_SCIF1_1) ++#define MOD_SEL0_0 FM(SEL_TMU1_0) FM(SEL_TMU1_1) ++ ++#define PINMUX_MOD_SELS \ ++\ ++MOD_SEL0_11 \ ++MOD_SEL0_10 \ ++MOD_SEL0_9 \ ++MOD_SEL0_8 \ ++MOD_SEL0_7 \ ++MOD_SEL0_6 \ ++MOD_SEL0_5 \ ++MOD_SEL0_4 \ ++MOD_SEL0_2 \ ++MOD_SEL0_1 \ ++MOD_SEL0_0 ++ ++enum { ++ PINMUX_RESERVED = 0, ++ ++ PINMUX_DATA_BEGIN, ++ GP_ALL(DATA), ++ PINMUX_DATA_END, ++ ++#define F_(x, y) ++#define FM(x) FN_##x, ++ PINMUX_FUNCTION_BEGIN, ++ GP_ALL(FN), ++ PINMUX_GPSR ++ PINMUX_IPSR ++ PINMUX_MOD_SELS ++ PINMUX_FUNCTION_END, ++#undef F_ ++#undef FM ++ ++#define F_(x, y) ++#define FM(x) x##_MARK, ++ PINMUX_MARK_BEGIN, ++ PINMUX_GPSR ++ PINMUX_IPSR ++ PINMUX_MOD_SELS ++ PINMUX_MARK_END, ++#undef F_ ++#undef FM ++}; ++ ++static const u16 pinmux_data[] = { ++ PINMUX_DATA_GP_ALL(), ++ ++ PINMUX_SINGLE(AVB_RX_CTL), ++ PINMUX_SINGLE(AVB_RXC), ++ PINMUX_SINGLE(AVB_RD0), ++ PINMUX_SINGLE(AVB_RD1), ++ PINMUX_SINGLE(AVB_RD2), ++ PINMUX_SINGLE(AVB_RD3), ++ PINMUX_SINGLE(AVB_TX_CTL), ++ PINMUX_SINGLE(AVB_TXC), ++ PINMUX_SINGLE(AVB_TD0), ++ PINMUX_SINGLE(AVB_TD1), ++ PINMUX_SINGLE(AVB_TD2), ++ PINMUX_SINGLE(AVB_TD3), ++ PINMUX_SINGLE(AVB_TXCREFCLK), ++ PINMUX_SINGLE(AVB_MDIO), ++ PINMUX_SINGLE(AVB_MDC), ++ PINMUX_SINGLE(AVB_MAGIC), ++ PINMUX_SINGLE(AVB_PHY_INT), ++ PINMUX_SINGLE(AVB_LINK), ++ ++ PINMUX_SINGLE(GETHER_RX_CTL), ++ PINMUX_SINGLE(GETHER_RXC), ++ PINMUX_SINGLE(GETHER_RD0), ++ PINMUX_SINGLE(GETHER_RD1), ++ PINMUX_SINGLE(GETHER_RD2), ++ PINMUX_SINGLE(GETHER_RD3), ++ PINMUX_SINGLE(GETHER_TX_CTL), ++ PINMUX_SINGLE(GETHER_TXC), ++ PINMUX_SINGLE(GETHER_TD0), ++ PINMUX_SINGLE(GETHER_TD1), ++ PINMUX_SINGLE(GETHER_TD2), ++ PINMUX_SINGLE(GETHER_TD3), ++ PINMUX_SINGLE(GETHER_TXCREFCLK), ++ PINMUX_SINGLE(GETHER_TXCREFCLK_MEGA), ++ PINMUX_SINGLE(GETHER_MDIO_A), ++ PINMUX_SINGLE(GETHER_MDC_A), ++ PINMUX_SINGLE(GETHER_MAGIC), ++ PINMUX_SINGLE(GETHER_PHY_INT_A), ++ PINMUX_SINGLE(GETHER_LINK_A), ++ ++ PINMUX_SINGLE(QSPI0_SPCLK), ++ PINMUX_SINGLE(QSPI0_MOSI_IO0), ++ PINMUX_SINGLE(QSPI0_MISO_IO1), ++ PINMUX_SINGLE(QSPI0_IO2), ++ PINMUX_SINGLE(QSPI0_IO3), ++ PINMUX_SINGLE(QSPI0_SSL), ++ PINMUX_SINGLE(QSPI1_SPCLK), ++ PINMUX_SINGLE(QSPI1_MOSI_IO0), ++ PINMUX_SINGLE(QSPI1_MISO_IO1), ++ PINMUX_SINGLE(QSPI1_IO2), ++ PINMUX_SINGLE(QSPI1_IO3), ++ PINMUX_SINGLE(QSPI1_SSL), ++ PINMUX_SINGLE(RPC_RESET_N), ++ PINMUX_SINGLE(RPC_WP_N), ++ PINMUX_SINGLE(RPC_INT_N), ++ ++ /* IPSR0 */ ++ PINMUX_IPSR_GPSR(IP0_3_0, DU_DR2), ++ PINMUX_IPSR_GPSR(IP0_3_0, SCK4), ++ PINMUX_IPSR_GPSR(IP0_3_0, GETHER_RMII_CRS_DV), ++ PINMUX_IPSR_GPSR(IP0_3_0, A0), ++ ++ PINMUX_IPSR_GPSR(IP0_7_4, DU_DR3), ++ PINMUX_IPSR_GPSR(IP0_7_4, RX4), ++ PINMUX_IPSR_GPSR(IP0_7_4, GETHER_RMII_RX_ER), ++ PINMUX_IPSR_GPSR(IP0_7_4, A1), ++ ++ PINMUX_IPSR_GPSR(IP0_11_8, DU_DR4), ++ PINMUX_IPSR_GPSR(IP0_11_8, TX4), ++ PINMUX_IPSR_GPSR(IP0_11_8, GETHER_RMII_RXD0), ++ PINMUX_IPSR_GPSR(IP0_11_8, A2), ++ ++ PINMUX_IPSR_GPSR(IP0_15_12, DU_DR5), ++ PINMUX_IPSR_GPSR(IP0_15_12, CTS4_N), ++ PINMUX_IPSR_GPSR(IP0_15_12, GETHER_RMII_RXD1), ++ PINMUX_IPSR_GPSR(IP0_15_12, A3), ++ ++ PINMUX_IPSR_GPSR(IP0_19_16, DU_DR6), ++ PINMUX_IPSR_GPSR(IP0_19_16, RTS4_N_TANS), ++ PINMUX_IPSR_GPSR(IP0_19_16, GETHER_RMII_TXD_EN), ++ PINMUX_IPSR_GPSR(IP0_19_16, A4), ++ ++ PINMUX_IPSR_GPSR(IP0_23_20, DU_DR7), ++ PINMUX_IPSR_GPSR(IP0_23_20, GETHER_RMII_TXD0), ++ PINMUX_IPSR_GPSR(IP0_23_20, A5), ++ ++ PINMUX_IPSR_GPSR(IP0_27_24, DU_DG2), ++ PINMUX_IPSR_GPSR(IP0_27_24, GETHER_RMII_TXD1), ++ PINMUX_IPSR_GPSR(IP0_27_24, A6), ++ ++ PINMUX_IPSR_GPSR(IP0_31_28, DU_DG3), ++ PINMUX_IPSR_GPSR(IP0_31_28, CPG_CPCKOUT), ++ PINMUX_IPSR_GPSR(IP0_31_28, GETHER_RMII_REFCLK), ++ PINMUX_IPSR_GPSR(IP0_31_28, A7), ++ PINMUX_IPSR_GPSR(IP0_31_28, PWMFSW0), ++ ++ /* IPSR1 */ ++ PINMUX_IPSR_GPSR(IP1_3_0, DU_DG4), ++ PINMUX_IPSR_GPSR(IP1_3_0, SCL5), ++ PINMUX_IPSR_GPSR(IP1_3_0, A8), ++ ++ PINMUX_IPSR_GPSR(IP1_7_4, DU_DG5), ++ PINMUX_IPSR_GPSR(IP1_7_4, SDA5), ++ PINMUX_IPSR_MSEL(IP1_7_4, GETHER_MDC_B, SEL_GETHER_1), ++ PINMUX_IPSR_GPSR(IP1_7_4, A9), ++ ++ PINMUX_IPSR_GPSR(IP1_11_8, DU_DG6), ++ PINMUX_IPSR_MSEL(IP1_11_8, SCIF_CLK_A, SEL_HSCIF0_0), ++ PINMUX_IPSR_MSEL(IP1_11_8, GETHER_MDIO_B, SEL_GETHER_1), ++ PINMUX_IPSR_GPSR(IP1_11_8, A10), ++ ++ PINMUX_IPSR_GPSR(IP1_15_12, DU_DG7), ++ PINMUX_IPSR_MSEL(IP1_15_12, HRX0_A, SEL_HSCIF0_0), ++ PINMUX_IPSR_GPSR(IP1_15_12, A11), ++ ++ PINMUX_IPSR_GPSR(IP1_19_16, DU_DB2), ++ PINMUX_IPSR_MSEL(IP1_19_16, HSCK0_A, SEL_HSCIF0_0), ++ PINMUX_IPSR_GPSR(IP1_19_16, A12), ++ PINMUX_IPSR_GPSR(IP1_19_16, IRQ1), ++ ++ PINMUX_IPSR_GPSR(IP1_23_20, DU_DB3), ++ PINMUX_IPSR_MSEL(IP1_23_20, HRTS0_N_A, SEL_HSCIF0_0), ++ PINMUX_IPSR_GPSR(IP1_23_20, A13), ++ PINMUX_IPSR_GPSR(IP1_23_20, IRQ2), ++ ++ PINMUX_IPSR_GPSR(IP1_27_24, DU_DB4), ++ PINMUX_IPSR_MSEL(IP1_27_24, HCTS0_N_A, SEL_HSCIF0_0), ++ PINMUX_IPSR_GPSR(IP1_27_24, A14), ++ PINMUX_IPSR_GPSR(IP1_27_24, IRQ3), ++ ++ PINMUX_IPSR_GPSR(IP1_31_28, DU_DB5), ++ PINMUX_IPSR_MSEL(IP1_31_28, HTX0_A, SEL_HSCIF0_0), ++ PINMUX_IPSR_MSEL(IP1_31_28, PWM0_A, SEL_PWM0_0), ++ PINMUX_IPSR_GPSR(IP1_31_28, A15), ++ ++ /* IPSR2 */ ++ PINMUX_IPSR_GPSR(IP2_3_0, DU_DB6), ++ PINMUX_IPSR_GPSR(IP2_3_0, MSIOF3_RXD), ++ PINMUX_IPSR_GPSR(IP2_3_0, A16), ++ ++ PINMUX_IPSR_GPSR(IP2_7_4, DU_DB7), ++ PINMUX_IPSR_GPSR(IP2_7_4, MSIOF3_TXD), ++ PINMUX_IPSR_GPSR(IP2_7_4, A17), ++ ++ PINMUX_IPSR_GPSR(IP2_11_8, DU_DOTCLKOUT), ++ PINMUX_IPSR_GPSR(IP2_11_8, MSIOF3_SS1), ++ PINMUX_IPSR_MSEL(IP2_11_8, GETHER_LINK_B, SEL_GETHER_1), ++ PINMUX_IPSR_GPSR(IP2_11_8, A18), ++ ++ PINMUX_IPSR_GPSR(IP2_15_12, DU_EXHSYNC_DU_HSYNC), ++ PINMUX_IPSR_GPSR(IP2_15_12, MSIOF3_SS2), ++ PINMUX_IPSR_MSEL(IP2_15_12, GETHER_PHY_INT_B, SEL_GETHER_1), ++ PINMUX_IPSR_GPSR(IP2_15_12, A19), ++ PINMUX_IPSR_GPSR(IP2_15_12, FXR_TXENA_N), ++ ++ PINMUX_IPSR_GPSR(IP2_19_16, DU_EXVSYNC_DU_VSYNC), ++ PINMUX_IPSR_GPSR(IP2_19_16, MSIOF3_SCK), ++ PINMUX_IPSR_GPSR(IP2_19_16, FXR_TXENB_N), ++ ++ PINMUX_IPSR_GPSR(IP2_23_20, DU_EXODDF_DU_ODDF_DISP_CDE), ++ PINMUX_IPSR_GPSR(IP2_23_20, MSIOF3_SYNC), ++ ++ PINMUX_IPSR_GPSR(IP2_27_24, IRQ0), ++ PINMUX_IPSR_GPSR(IP2_27_24, CC5_OSCOUT), ++ ++ PINMUX_IPSR_GPSR(IP2_31_28, VI0_CLK), ++ PINMUX_IPSR_GPSR(IP2_31_28, MSIOF2_SCK), ++ PINMUX_IPSR_GPSR(IP2_31_28, SCK3), ++ PINMUX_IPSR_GPSR(IP2_31_28, HSCK3), ++ ++ /* IPSR3 */ ++ PINMUX_IPSR_GPSR(IP3_3_0, VI0_CLKENB), ++ PINMUX_IPSR_GPSR(IP3_3_0, MSIOF2_RXD), ++ PINMUX_IPSR_GPSR(IP3_3_0, RX3), ++ PINMUX_IPSR_GPSR(IP3_3_0, RD_WR_N), ++ PINMUX_IPSR_GPSR(IP3_3_0, HCTS3_N), ++ ++ PINMUX_IPSR_GPSR(IP3_7_4, VI0_HSYNC_N), ++ PINMUX_IPSR_GPSR(IP3_7_4, MSIOF2_TXD), ++ PINMUX_IPSR_GPSR(IP3_7_4, TX3), ++ PINMUX_IPSR_GPSR(IP3_7_4, HRTS3_N), ++ ++ PINMUX_IPSR_GPSR(IP3_11_8, VI0_VSYNC_N), ++ PINMUX_IPSR_GPSR(IP3_11_8, MSIOF2_SYNC), ++ PINMUX_IPSR_GPSR(IP3_11_8, CTS3_N), ++ PINMUX_IPSR_GPSR(IP3_11_8, HTX3), ++ ++ PINMUX_IPSR_GPSR(IP3_15_12, VI0_DATA0), ++ PINMUX_IPSR_GPSR(IP3_15_12, MSIOF2_SS1), ++ PINMUX_IPSR_GPSR(IP3_15_12, RTS3_N_TANS), ++ PINMUX_IPSR_GPSR(IP3_15_12, HRX3), ++ ++ PINMUX_IPSR_GPSR(IP3_19_16, VI0_DATA1), ++ PINMUX_IPSR_GPSR(IP3_19_16, MSIOF2_SS2), ++ PINMUX_IPSR_GPSR(IP3_19_16, SCK1), ++ PINMUX_IPSR_MSEL(IP3_19_16, SPEEDIN_A, SEL_RSP_0), ++ ++ PINMUX_IPSR_GPSR(IP3_23_20, VI0_DATA2), ++ PINMUX_IPSR_GPSR(IP3_23_20, AVB_AVTP_PPS), ++ ++ PINMUX_IPSR_GPSR(IP3_27_24, VI0_DATA3), ++ PINMUX_IPSR_GPSR(IP3_27_24, HSCK1), ++ ++ PINMUX_IPSR_GPSR(IP3_31_28, VI0_DATA4), ++ PINMUX_IPSR_GPSR(IP3_31_28, HRTS1_N), ++ PINMUX_IPSR_MSEL(IP3_31_28, RX1_A, SEL_SCIF1_0), ++ ++ /* IPSR4 */ ++ PINMUX_IPSR_GPSR(IP4_3_0, VI0_DATA5), ++ PINMUX_IPSR_GPSR(IP4_3_0, HCTS1_N), ++ PINMUX_IPSR_MSEL(IP4_3_0, TX1_A, SEL_SCIF1_0), ++ ++ PINMUX_IPSR_GPSR(IP4_7_4, VI0_DATA6), ++ PINMUX_IPSR_GPSR(IP4_7_4, HTX1), ++ PINMUX_IPSR_GPSR(IP4_7_4, CTS1_N), ++ ++ PINMUX_IPSR_GPSR(IP4_11_8, VI0_DATA7), ++ PINMUX_IPSR_GPSR(IP4_11_8, HRX1), ++ PINMUX_IPSR_GPSR(IP4_11_8, RTS1_N_TANS), ++ ++ PINMUX_IPSR_GPSR(IP4_15_12, VI0_DATA8), ++ PINMUX_IPSR_GPSR(IP4_15_12, HSCK2), ++ ++ PINMUX_IPSR_GPSR(IP4_19_16, VI0_DATA9), ++ PINMUX_IPSR_GPSR(IP4_19_16, HCTS2_N), ++ PINMUX_IPSR_MSEL(IP4_19_16, PWM1_A, SEL_PWM1_0), ++ ++ PINMUX_IPSR_GPSR(IP4_23_20, VI0_DATA10), ++ PINMUX_IPSR_GPSR(IP4_23_20, HRTS2_N), ++ PINMUX_IPSR_MSEL(IP4_23_20, PWM2_A, SEL_PWM2_0), ++ ++ PINMUX_IPSR_GPSR(IP4_27_24, VI0_DATA11), ++ PINMUX_IPSR_GPSR(IP4_27_24, HTX2), ++ PINMUX_IPSR_MSEL(IP4_27_24, PWM3_A, SEL_PWM3_0), ++ ++ PINMUX_IPSR_GPSR(IP4_31_28, VI0_FIELD), ++ PINMUX_IPSR_GPSR(IP4_31_28, HRX2), ++ PINMUX_IPSR_MSEL(IP4_31_28, PWM4_A, SEL_PWM4_0), ++ PINMUX_IPSR_GPSR(IP4_31_28, CS1_N), ++ ++ /* IPSR5 */ ++ PINMUX_IPSR_GPSR(IP5_3_0, VI1_CLK), ++ PINMUX_IPSR_GPSR(IP5_3_0, MSIOF1_RXD), ++ PINMUX_IPSR_GPSR(IP5_3_0, CS0_N), ++ ++ PINMUX_IPSR_GPSR(IP5_7_4, VI1_CLKENB), ++ PINMUX_IPSR_GPSR(IP5_7_4, MSIOF1_TXD), ++ PINMUX_IPSR_GPSR(IP5_7_4, D0), ++ ++ PINMUX_IPSR_GPSR(IP5_11_8, VI1_HSYNC_N), ++ PINMUX_IPSR_GPSR(IP5_11_8, MSIOF1_SCK), ++ PINMUX_IPSR_GPSR(IP5_11_8, D1), ++ ++ PINMUX_IPSR_GPSR(IP5_15_12, VI1_VSYNC_N), ++ PINMUX_IPSR_GPSR(IP5_15_12, MSIOF1_SYNC), ++ PINMUX_IPSR_GPSR(IP5_15_12, D2), ++ ++ PINMUX_IPSR_GPSR(IP5_19_16, VI1_DATA0), ++ PINMUX_IPSR_GPSR(IP5_19_16, MSIOF1_SS1), ++ PINMUX_IPSR_GPSR(IP5_19_16, D3), ++ PINMUX_IPSR_GPSR(IP5_19_16, MMC_WP), ++ ++ PINMUX_IPSR_GPSR(IP5_23_20, VI1_DATA1), ++ PINMUX_IPSR_GPSR(IP5_23_20, MSIOF1_SS2), ++ PINMUX_IPSR_GPSR(IP5_23_20, D4), ++ PINMUX_IPSR_GPSR(IP5_23_20, MMC_CD), ++ ++ PINMUX_IPSR_GPSR(IP5_27_24, VI1_DATA2), ++ PINMUX_IPSR_MSEL(IP5_27_24, CANFD0_TX_B, SEL_CANFD0_1), ++ PINMUX_IPSR_GPSR(IP5_27_24, D5), ++ PINMUX_IPSR_GPSR(IP5_27_24, MMC_DS), ++ ++ PINMUX_IPSR_GPSR(IP5_31_28, VI1_DATA3), ++ PINMUX_IPSR_MSEL(IP5_31_28, CANFD0_RX_B, SEL_CANFD0_1), ++ PINMUX_IPSR_GPSR(IP5_31_28, D6), ++ PINMUX_IPSR_GPSR(IP5_31_28, MMC_CMD), ++ ++ /* IPSR6 */ ++ PINMUX_IPSR_GPSR(IP6_3_0, VI1_DATA4), ++ PINMUX_IPSR_MSEL(IP6_3_0, CANFD_CLK_B, SEL_CANFD0_1), ++ PINMUX_IPSR_GPSR(IP6_3_0, D7), ++ PINMUX_IPSR_GPSR(IP6_3_0, MMC_D0), ++ ++ PINMUX_IPSR_GPSR(IP6_7_4, VI1_DATA5), ++ PINMUX_IPSR_GPSR(IP6_7_4, D8), ++ PINMUX_IPSR_GPSR(IP6_7_4, MMC_D1), ++ ++ PINMUX_IPSR_GPSR(IP6_11_8, VI1_DATA6), ++ PINMUX_IPSR_GPSR(IP6_11_8, D9), ++ PINMUX_IPSR_GPSR(IP6_11_8, MMC_D2), ++ ++ PINMUX_IPSR_GPSR(IP6_15_12, VI1_DATA7), ++ PINMUX_IPSR_GPSR(IP6_15_12, D10), ++ PINMUX_IPSR_GPSR(IP6_15_12, MMC_D3), ++ ++ PINMUX_IPSR_GPSR(IP6_19_16, VI1_DATA8), ++ PINMUX_IPSR_GPSR(IP6_19_16, D11), ++ PINMUX_IPSR_GPSR(IP6_19_16, MMC_CLK), ++ ++ PINMUX_IPSR_GPSR(IP6_23_20, VI1_DATA9), ++ PINMUX_IPSR_MSEL(IP6_23_20, TCLK1_A, SEL_TMU1_0), ++ PINMUX_IPSR_GPSR(IP6_23_20, D12), ++ PINMUX_IPSR_GPSR(IP6_23_20, MMC_D4), ++ ++ PINMUX_IPSR_GPSR(IP6_27_24, VI1_DATA10), ++ PINMUX_IPSR_MSEL(IP6_27_24, TCLK2_A, SEL_TMU1_0), ++ PINMUX_IPSR_GPSR(IP6_27_24, D13), ++ PINMUX_IPSR_GPSR(IP6_27_24, MMC_D5), ++ ++ PINMUX_IPSR_GPSR(IP6_31_28, VI1_DATA11), ++ PINMUX_IPSR_GPSR(IP6_31_28, SCL4), ++ PINMUX_IPSR_GPSR(IP6_31_28, D14), ++ PINMUX_IPSR_GPSR(IP6_31_28, MMC_D6), ++ ++ /* IPSR7 */ ++ PINMUX_IPSR_GPSR(IP7_3_0, VI1_FIELD), ++ PINMUX_IPSR_GPSR(IP7_3_0, SDA4), ++ PINMUX_IPSR_GPSR(IP7_3_0, D15), ++ PINMUX_IPSR_GPSR(IP7_3_0, MMC_D7), ++ ++ PINMUX_IPSR_GPSR(IP7_7_4, SCL0), ++ PINMUX_IPSR_GPSR(IP7_7_4, CLKOUT), ++ ++ PINMUX_IPSR_GPSR(IP7_11_8, SDA0), ++ PINMUX_IPSR_GPSR(IP7_11_8, BS_N), ++ PINMUX_IPSR_GPSR(IP7_11_8, SCK0), ++ PINMUX_IPSR_MSEL(IP7_11_8, HSCK0_B, SEL_HSCIF0_1), ++ ++ PINMUX_IPSR_GPSR(IP7_15_12, SCL1), ++ PINMUX_IPSR_GPSR(IP7_15_12, TPU0TO2), ++ PINMUX_IPSR_GPSR(IP7_15_12, RD_N), ++ PINMUX_IPSR_GPSR(IP7_15_12, CTS0_N), ++ PINMUX_IPSR_GPSR(IP7_15_12, HCTS0_N_B), ++ ++ PINMUX_IPSR_GPSR(IP7_19_16, SDA1), ++ PINMUX_IPSR_GPSR(IP7_19_16, TPU0TO3), ++ PINMUX_IPSR_GPSR(IP7_19_16, WE0_N), ++ PINMUX_IPSR_GPSR(IP7_19_16, RTS0_N_TANS), ++ PINMUX_IPSR_GPSR(IP7_19_16, HRTS0_N_B), ++ ++ PINMUX_IPSR_GPSR(IP7_23_20, SCL2), ++ PINMUX_IPSR_GPSR(IP7_23_20, WE1_N), ++ PINMUX_IPSR_GPSR(IP7_23_20, RX0), ++ PINMUX_IPSR_MSEL(IP7_23_20, HRX0_B, SEL_HSCIF0_1), ++ ++ PINMUX_IPSR_GPSR(IP7_27_24, SDA2), ++ PINMUX_IPSR_GPSR(IP7_27_24, EX_WAIT0), ++ PINMUX_IPSR_GPSR(IP7_27_24, TX0), ++ PINMUX_IPSR_MSEL(IP7_27_24, HTX0_B, SEL_HSCIF0_1), ++ ++ PINMUX_IPSR_GPSR(IP7_31_28, AVB_AVTP_MATCH), ++ PINMUX_IPSR_GPSR(IP7_31_28, TPU0TO0), ++ ++ /* IPSR8 */ ++ PINMUX_IPSR_GPSR(IP8_3_0, AVB_AVTP_CAPTURE), ++ PINMUX_IPSR_GPSR(IP8_3_0, TPU0TO1), ++ ++ PINMUX_IPSR_MSEL(IP8_7_4, CANFD0_TX_A, SEL_CANFD0_0), ++ PINMUX_IPSR_GPSR(IP8_7_4, FXR_TXDA), ++ PINMUX_IPSR_MSEL(IP8_7_4, PWM0_B, SEL_PWM0_1), ++ PINMUX_IPSR_GPSR(IP8_7_4, DU_DISP), ++ ++ PINMUX_IPSR_MSEL(IP8_11_8, CANFD0_RX_A, SEL_CANFD0_0), ++ PINMUX_IPSR_GPSR(IP8_11_8, RXDA_EXTFXR), ++ PINMUX_IPSR_MSEL(IP8_11_8, PWM1_B, SEL_PWM1_1), ++ PINMUX_IPSR_GPSR(IP8_11_8, DU_CDE), ++ ++ PINMUX_IPSR_GPSR(IP8_15_12, CANFD1_TX), ++ PINMUX_IPSR_GPSR(IP8_15_12, FXR_TXDB), ++ PINMUX_IPSR_MSEL(IP8_15_12, PWM2_B, SEL_PWM2_1), ++ PINMUX_IPSR_MSEL(IP8_15_12, TCLK1_B, SEL_TMU1_1), ++ PINMUX_IPSR_MSEL(IP8_15_12, TX1_B, SEL_SCIF1_1), ++ ++ PINMUX_IPSR_GPSR(IP8_19_16, CANFD1_RX), ++ PINMUX_IPSR_GPSR(IP8_19_16, RXDB_EXTFXR), ++ PINMUX_IPSR_MSEL(IP8_19_16, PWM3_B, SEL_PWM3_1), ++ PINMUX_IPSR_MSEL(IP8_19_16, TCLK2_B, SEL_TMU1_1), ++ PINMUX_IPSR_MSEL(IP8_19_16, RX1_B, SEL_SCIF1_1), ++ ++ PINMUX_IPSR_MSEL(IP8_23_20, CANFD_CLK_A, SEL_CANFD0_0), ++ PINMUX_IPSR_GPSR(IP8_23_20, CLK_EXTFXR), ++ PINMUX_IPSR_MSEL(IP8_23_20, PWM4_B, SEL_PWM4_1), ++ PINMUX_IPSR_MSEL(IP8_23_20, SPEEDIN_B, SEL_RSP_1), ++ PINMUX_IPSR_MSEL(IP8_23_20, SCIF_CLK_B, SEL_HSCIF0_1), ++ ++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKIN), ++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKEN_IN), ++ ++ PINMUX_IPSR_GPSR(IP8_31_28, DIGRF_CLKOUT), ++ PINMUX_IPSR_GPSR(IP8_31_28, DIGRF_CLKEN_OUT), ++ ++ /* IPSR9 */ ++ PINMUX_IPSR_GPSR(IP9_3_0, IRQ4), ++ PINMUX_IPSR_GPSR(IP9_3_0, VI0_DATA12), ++ ++ PINMUX_IPSR_GPSR(IP9_7_4, IRQ5), ++ PINMUX_IPSR_GPSR(IP9_7_4, VI0_DATA13), ++ ++ PINMUX_IPSR_GPSR(IP9_11_8, MSIOF0_RXD), ++ PINMUX_IPSR_GPSR(IP9_11_8, DU_DR0), ++ PINMUX_IPSR_GPSR(IP9_11_8, VI0_DATA14), ++ ++ PINMUX_IPSR_GPSR(IP9_15_12, MSIOF0_TXD), ++ PINMUX_IPSR_GPSR(IP9_15_12, DU_DR1), ++ PINMUX_IPSR_GPSR(IP9_15_12, VI0_DATA15), ++ ++ PINMUX_IPSR_GPSR(IP9_19_16, MSIOF0_SCK), ++ PINMUX_IPSR_GPSR(IP9_19_16, DU_DG0), ++ PINMUX_IPSR_GPSR(IP9_19_16, VI0_DATA16), ++ ++ PINMUX_IPSR_GPSR(IP9_23_20, MSIOF0_SYNC), ++ PINMUX_IPSR_GPSR(IP9_23_20, DU_DG1), ++ PINMUX_IPSR_GPSR(IP9_23_20, VI0_DATA17), ++ ++ PINMUX_IPSR_GPSR(IP9_27_24, MSIOF0_SS1), ++ PINMUX_IPSR_GPSR(IP9_27_24, DU_DB0), ++ PINMUX_IPSR_GPSR(IP9_27_24, TCLK3), ++ PINMUX_IPSR_GPSR(IP9_27_24, VI0_DATA18), ++ ++ PINMUX_IPSR_GPSR(IP9_31_28, MSIOF0_SS2), ++ PINMUX_IPSR_GPSR(IP9_31_28, DU_DB1), ++ PINMUX_IPSR_GPSR(IP9_31_28, TCLK4), ++ PINMUX_IPSR_GPSR(IP9_31_28, VI0_DATA19), ++ ++ /* IPSR10 */ ++ PINMUX_IPSR_GPSR(IP10_3_0, SCL3), ++ PINMUX_IPSR_GPSR(IP10_3_0, VI0_DATA20), ++ ++ PINMUX_IPSR_GPSR(IP10_7_4, SDA3), ++ PINMUX_IPSR_GPSR(IP10_7_4, VI0_DATA21), ++ ++ PINMUX_IPSR_GPSR(IP10_11_8, FSO_CFE_0_N), ++ PINMUX_IPSR_GPSR(IP10_11_8, VI0_DATA22), ++ ++ PINMUX_IPSR_GPSR(IP10_15_12, FSO_CFE_1_N), ++ PINMUX_IPSR_GPSR(IP10_15_12, VI0_DATA23), ++ ++ PINMUX_IPSR_GPSR(IP10_19_16, FSO_TOE_N), ++}; ++ ++static const struct sh_pfc_pin pinmux_pins[] = { ++ PINMUX_GPIO_GP_ALL(), ++}; ++ ++/* - EtherAVB --------------------------------------------------------------- */ ++static const unsigned int avb_rx_ctrl_pins[] = { ++ /* AVB_RX_CTL */ ++ RCAR_GP_PIN(1, 1), ++}; ++static const unsigned int avb_rx_ctrl_mux[] = { ++ AVB_RX_CTL_MARK, ++}; ++static const unsigned int avb_rxc_pins[] = { ++ /* AVB_RXC */ ++ RCAR_GP_PIN(1, 2), ++}; ++static const unsigned int avb_rxc_mux[] = { ++ AVB_RXC_MARK, ++}; ++static const unsigned int avb_rd0_pins[] = { ++ /* AVB_RD[0] */ ++ RCAR_GP_PIN(1, 3), ++}; ++static const unsigned int avb_rd0_mux[] = { ++ AVB_RD0_MARK, ++}; ++static const unsigned int avb_rd1_pins[] = { ++ /* AVB_RD[1] */ ++ RCAR_GP_PIN(1, 4), ++}; ++static const unsigned int avb_rd1_mux[] = { ++ AVB_RD1_MARK, ++}; ++static const unsigned int avb_rd2_pins[] = { ++ /* AVB_RD[2] */ ++ RCAR_GP_PIN(1, 5), ++}; ++static const unsigned int avb_rd2_mux[] = { ++ AVB_RD2_MARK, ++}; ++static const unsigned int avb_rd3_pins[] = { ++ /* AVB_RD[3] */ ++ RCAR_GP_PIN(1, 6), ++}; ++static const unsigned int avb_rd3_mux[] = { ++ AVB_RD3_MARK, ++}; ++static const unsigned int avb_rd4_pins[] = { ++ /* AVB_RD[3:0] */ ++ RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 4), ++ RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6), ++}; ++static const unsigned int avb_rd4_mux[] = { ++ AVB_RD0_MARK, AVB_RD1_MARK, ++ AVB_RD2_MARK, AVB_RD3_MARK, ++}; ++static const unsigned int avb_tx_ctrl_pins[] = { ++ /* AVB_TX_CTL */ ++ RCAR_GP_PIN(1, 7), ++}; ++static const unsigned int avb_tx_ctrl_mux[] = { ++ AVB_TX_CTL_MARK, ++}; ++static const unsigned int avb_txc_pins[] = { ++ /* AVB_TXC */ ++ RCAR_GP_PIN(1, 8), ++}; ++static const unsigned int avb_txc_mux[] = { ++ AVB_TXC_MARK, ++}; ++static const unsigned int avb_td0_pins[] = { ++ /* AVB_TD[0] */ ++ RCAR_GP_PIN(1, 9), ++}; ++static const unsigned int avb_td0_mux[] = { ++ AVB_TD0_MARK, ++}; ++static const unsigned int avb_td1_pins[] = { ++ /* AVB_TD[1] */ ++ RCAR_GP_PIN(1, 10), ++}; ++static const unsigned int avb_td1_mux[] = { ++ AVB_TD1_MARK, ++}; ++static const unsigned int avb_td2_pins[] = { ++ /* AVB_TD[2] */ ++ RCAR_GP_PIN(1, 11), ++}; ++static const unsigned int avb_td2_mux[] = { ++ AVB_TD2_MARK, ++}; ++static const unsigned int avb_td3_pins[] = { ++ /* AVB_TD[3] */ ++ RCAR_GP_PIN(1, 12), ++}; ++static const unsigned int avb_td3_mux[] = { ++ AVB_TD3_MARK, ++}; ++static const unsigned int avb_td4_pins[] = { ++ /* AVB_TD[3:0] */ ++ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 10), ++ RCAR_GP_PIN(1, 11), RCAR_GP_PIN(1, 12), ++}; ++static const unsigned int avb_td4_mux[] = { ++ AVB_TD0_MARK, AVB_TD1_MARK, ++ AVB_TD2_MARK, AVB_TD3_MARK, ++}; ++static const unsigned int avb_txcrefclk_pins[] = { ++ /* AVB_TXCREFCLK */ ++ RCAR_GP_PIN(1, 13), ++}; ++static const unsigned int avb_txcrefclk_mux[] = { ++ AVB_TXCREFCLK_MARK, ++}; ++static const unsigned int avb_mdio_pins[] = { ++ /* AVB_MDIO */ ++ RCAR_GP_PIN(1, 14), ++}; ++static const unsigned int avb_mdio_mux[] = { ++ AVB_MDIO_MARK, ++}; ++static const unsigned int avb_mdc_pins[] = { ++ /* AVB_MDC */ ++ RCAR_GP_PIN(1, 15), ++}; ++static const unsigned int avb_mdc_mux[] = { ++ AVB_MDC_MARK, ++}; ++static const unsigned int avb_magic_pins[] = { ++ /* AVB_MAGIC */ ++ RCAR_GP_PIN(1, 16), ++}; ++static const unsigned int avb_magic_mux[] = { ++ AVB_MAGIC_MARK, ++}; ++static const unsigned int avb_phy_int_pins[] = { ++ /* AVB_PHY_INT */ ++ RCAR_GP_PIN(1, 17), ++}; ++static const unsigned int avb_phy_int_mux[] = { ++ AVB_PHY_INT_MARK, ++}; ++static const unsigned int avb_link_pins[] = { ++ /* AVB_LINK */ ++ RCAR_GP_PIN(1, 18), ++}; ++static const unsigned int avb_link_mux[] = { ++ AVB_LINK_MARK, ++}; ++static const unsigned int avb_avtp_match_pins[] = { ++ /* AVB_AVTP_MATCH */ ++ RCAR_GP_PIN(1, 19), ++}; ++static const unsigned int avb_avtp_match_mux[] = { ++ AVB_AVTP_MATCH_MARK, ++}; ++static const unsigned int avb_avtp_capture_pins[] = { ++ /* AVB_AVTP_CAPTURE */ ++ RCAR_GP_PIN(1, 20), ++}; ++static const unsigned int avb_avtp_capture_mux[] = { ++ AVB_AVTP_CAPTURE_MARK, ++}; ++static const unsigned int avb_avtp_pps_pins[] = { ++ /* AVB_AVTP_PPS */ ++ RCAR_GP_PIN(2, 6), ++}; ++static const unsigned int avb_avtp_pps_mux[] = { ++ AVB_AVTP_PPS_MARK, ++}; ++ ++/* - GETHER ----------------------------------------------------------------- */ ++static const unsigned int gether_rx_ctrl_pins[] = { ++ /* GETHER_RX_CTL */ ++ RCAR_GP_PIN(4, 6), ++}; ++static const unsigned int gether_rx_ctrl_mux[] = { ++ GETHER_RX_CTL_MARK, ++}; ++static const unsigned int gether_rxc_pins[] = { ++ /* GETHER_RXC */ ++ RCAR_GP_PIN(4, 7), ++}; ++static const unsigned int gether_rxc_mux[] = { ++ GETHER_RXC_MARK, ++}; ++static const unsigned int gether_rd0_pins[] = { ++ /* GETHER_RD[0] */ ++ RCAR_GP_PIN(4, 8), ++}; ++static const unsigned int gether_rd0_mux[] = { ++ GETHER_RD0_MARK, ++}; ++static const unsigned int gether_rd1_pins[] = { ++ /* GETHER_RD[1] */ ++ RCAR_GP_PIN(4, 9), ++}; ++static const unsigned int gether_rd1_mux[] = { ++ GETHER_RD1_MARK, ++}; ++static const unsigned int gether_rd2_pins[] = { ++ /* GETHER_RD[2] */ ++ RCAR_GP_PIN(4, 10), ++}; ++static const unsigned int gether_rd2_mux[] = { ++ GETHER_RD2_MARK, ++}; ++static const unsigned int gether_rd3_pins[] = { ++ /* GETHER_RD[3] */ ++ RCAR_GP_PIN(4, 11), ++}; ++static const unsigned int gether_rd3_mux[] = { ++ GETHER_RD3_MARK, ++}; ++static const unsigned int gether_rd4_pins[] = { ++ /* GETHER_RD[3:0] */ ++ RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 9), ++ RCAR_GP_PIN(4, 10), RCAR_GP_PIN(4, 11), ++}; ++static const unsigned int gether_rd4_mux[] = { ++ GETHER_RD0_MARK, AVB_RD1_MARK, ++ GETHER_RD2_MARK, AVB_RD3_MARK, ++}; ++static const unsigned int gether_tx_ctrl_pins[] = { ++ /* GETHER_TX_CTL */ ++ RCAR_GP_PIN(4, 12), ++}; ++static const unsigned int gether_tx_ctrl_mux[] = { ++ GETHER_TX_CTL_MARK, ++}; ++static const unsigned int gether_txc_pins[] = { ++ /* GETHER_TXC */ ++ RCAR_GP_PIN(4, 13), ++}; ++static const unsigned int gether_txc_mux[] = { ++ GETHER_TXC_MARK, ++}; ++static const unsigned int gether_td0_pins[] = { ++ /* GETHER_TD[0] */ ++ RCAR_GP_PIN(4, 14), ++}; ++static const unsigned int gether_td0_mux[] = { ++ GETHER_TD0_MARK, ++}; ++static const unsigned int gether_td1_pins[] = { ++ /* GETHER_TD[1] */ ++ RCAR_GP_PIN(4, 15), ++}; ++static const unsigned int gether_td1_mux[] = { ++ GETHER_TD1_MARK, ++}; ++static const unsigned int gether_td2_pins[] = { ++ /* GETHER_TD[2] */ ++ RCAR_GP_PIN(4, 16), ++}; ++static const unsigned int gether_td2_mux[] = { ++ GETHER_TD2_MARK, ++}; ++static const unsigned int gether_td3_pins[] = { ++ /* GETHER_TD[3] */ ++ RCAR_GP_PIN(4, 17), ++}; ++static const unsigned int gether_td3_mux[] = { ++ GETHER_TD3_MARK, ++}; ++static const unsigned int gether_td4_pins[] = { ++ /* GETHER_TD[3:0] */ ++ RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 15), ++ RCAR_GP_PIN(4, 16), RCAR_GP_PIN(1, 17), ++}; ++static const unsigned int gether_td4_mux[] = { ++ GETHER_TD0_MARK, GETHER_TD1_MARK, ++ GETHER_TD2_MARK, GETHER_TD3_MARK, ++}; ++static const unsigned int gether_txcrefclk_pins[] = { ++ /* GETHER_TXCREFCLK */ ++ RCAR_GP_PIN(4, 18), ++}; ++static const unsigned int gether_txcrefclk_mux[] = { ++ GETHER_TXCREFCLK_MARK, ++}; ++static const unsigned int gether_txcrefclk_mega_pins[] = { ++ /* GETHER_TXCREFCLK_MEGA */ ++ RCAR_GP_PIN(4, 19), ++}; ++static const unsigned int gether_txcrefclk_mega_mux[] = { ++ GETHER_TXCREFCLK_MEGA_MARK, ++}; ++static const unsigned int gether_mdio_a_pins[] = { ++ /* GETHER_MDIO_A */ ++ RCAR_GP_PIN(4, 20), ++}; ++static const unsigned int gether_mdio_a_mux[] = { ++ GETHER_MDIO_A_MARK, ++}; ++static const unsigned int gether_mdc_a_pins[] = { ++ /* GETHER_MDC_A */ ++ RCAR_GP_PIN(4, 21), ++}; ++static const unsigned int gether_mdc_a_mux[] = { ++ GETHER_MDC_A_MARK, ++}; ++static const unsigned int gether_magic_pins[] = { ++ /* GETHER_MAGIC */ ++ RCAR_GP_PIN(4, 22), ++}; ++static const unsigned int gether_magic_mux[] = { ++ GETHER_MAGIC_MARK, ++}; ++static const unsigned int gether_phy_int_a_pins[] = { ++ /* GETHER_PHY_INT_A */ ++ RCAR_GP_PIN(4, 23), ++}; ++static const unsigned int gether_phy_int_a_mux[] = { ++ GETHER_PHY_INT_A_MARK, ++}; ++static const unsigned int gether_link_a_pins[] = { ++ /* GETHER_LINK_A */ ++ RCAR_GP_PIN(4, 24), ++}; ++static const unsigned int gether_link_a_mux[] = { ++ GETHER_LINK_A_MARK, ++}; ++ ++static const unsigned int gether_mdio_b_pins[] = { ++ /* GETHER_MDIO_B */ ++ RCAR_GP_PIN(0, 10), ++}; ++static const unsigned int gether_mdio_b_mux[] = { ++ GETHER_MDIO_B_MARK, ++}; ++static const unsigned int gether_mdc_b_pins[] = { ++ /* GETHER_MDC_B */ ++ RCAR_GP_PIN(0, 9), ++}; ++static const unsigned int gether_mdc_b_mux[] = { ++ GETHER_MDC_B_MARK, ++}; ++static const unsigned int gether_phy_int_b_pins[] = { ++ /* GETHER_PHY_INT_B */ ++ RCAR_GP_PIN(0, 19), ++}; ++static const unsigned int gether_phy_int_b_mux[] = { ++ GETHER_PHY_INT_B_MARK, ++}; ++static const unsigned int gether_link_b_pins[] = { ++ /* GETHER_LINK_B */ ++ RCAR_GP_PIN(0, 18), ++}; ++static const unsigned int gether_link_b_mux[] = { ++ GETHER_LINK_B_MARK, ++}; ++ ++/* OK? */ ++static const unsigned int gether_rmii_pins[] = { ++ /* GETHER_RMII_CRS_DV GETHER_RMII_RX_ER GETHER_RMII_RXD0 GETHER_RMII_RXD1 */ ++ /* GETHER_RMII_TXD_EN GETHER_RMII_TXD0 GETHER_RMII_TXD1 GETHER_RMII_REFCLK */ ++ RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1), ++ RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3), ++ RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5), ++ RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7), ++}; ++static const unsigned int gether_rmii_mux[] = { ++ GETHER_RMII_CRS_DV_MARK, GETHER_RMII_RX_ER_MARK, ++ GETHER_RMII_RXD0_MARK, GETHER_RMII_RXD1_MARK, ++ GETHER_RMII_TXD_EN_MARK, GETHER_RMII_TXD0_MARK, ++ GETHER_RMII_TXD1_MARK, GETHER_RMII_REFCLK_MARK, ++}; ++ ++/* - CANFD0 ----------------------------------------------------------------- */ ++static const unsigned int canfd0_data_a_pins[] = { ++ /* TX, RX */ ++ RCAR_GP_PIN(1, 21), RCAR_GP_PIN(1, 22), ++}; ++static const unsigned int canfd0_data_a_mux[] = { ++ CANFD0_TX_A_MARK, CANFD0_RX_A_MARK, ++}; ++static const unsigned int canfd_clk_a_pins[] = { ++ /* CLK */ ++ RCAR_GP_PIN(1, 25), ++}; ++static const unsigned int canfd_clk_a_mux[] = { ++ CANFD_CLK_A_MARK, ++}; ++static const unsigned int canfd0_data_b_pins[] = { ++ /* TX, RX */ ++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7), ++}; ++static const unsigned int canfd0_data_b_mux[] = { ++ CANFD0_TX_B_MARK, CANFD0_RX_B_MARK, ++}; ++static const unsigned int canfd_clk_b_pins[] = { ++ /* CLK */ ++ RCAR_GP_PIN(3, 8), ++}; ++static const unsigned int canfd_clk_b_mux[] = { ++ CANFD_CLK_B_MARK, ++}; ++ ++/* - CANFD1 ----------------------------------------------------------------- */ ++static const unsigned int canfd1_data_pins[] = { ++ /* TX, RX */ ++ RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 24), ++}; ++static const unsigned int canfd1_data_mux[] = { ++ CANFD1_TX_MARK, CANFD1_RX_MARK, ++}; ++ ++/* - DU --------------------------------------------------------------------- */ ++/* D_[1:0] ??? */ ++static const unsigned int du_rgb666_pins[] = { ++ /* R[7:0] */ ++ RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 4), ++ RCAR_GP_PIN(0, 3), RCAR_GP_PIN(0, 2), ++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 0), ++ /* G[7:0] */ ++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10), ++ RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8), ++ RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 6), ++ /* B[7:0] */ ++ RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16), ++ RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), ++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 12), ++}; ++static const unsigned int du_rgb666_mux[] = { ++ DU_DR7_MARK, DU_DR6_MARK, ++ DU_DR5_MARK, DU_DR4_MARK, ++ DU_DR3_MARK, DU_DR2_MARK, ++ DU_DG7_MARK, DU_DG6_MARK, ++ DU_DG5_MARK, DU_DG4_MARK, ++ DU_DG3_MARK, DU_DG2_MARK, ++ DU_DB7_MARK, DU_DB6_MARK, ++ DU_DB5_MARK, DU_DB4_MARK, ++ DU_DB3_MARK, DU_DB2_MARK, ++}; ++static const unsigned int du_clk_out_0_pins[] = { ++ /* CLKOUT0 */ ++ RCAR_GP_PIN(0, 18), ++}; ++static const unsigned int du_clk_out_0_mux[] = { ++ DU_DOTCLKOUT_MARK, ++}; ++static const unsigned int du_clk_out_1_pins[] = { ++ /* CLKOUT1 */ ++ RCAR_GP_PIN(0, 18), /* @@ */ ++}; ++static const unsigned int du_clk_out_1_mux[] = { ++ DU_DOTCLKOUT_MARK, ++}; ++static const unsigned int du_sync_pins[] = { ++ /* EXVSYNC/VSYNC, EXHSYNC/HSYNC */ ++ RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 19), ++}; ++static const unsigned int du_sync_mux[] = { ++ DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK, ++}; ++static const unsigned int du_oddf_pins[] = { ++ /* EXDISP/EXODDF/EXCDE */ ++ RCAR_GP_PIN(0, 21), ++}; ++static const unsigned int du_oddf_mux[] = { ++ DU_EXODDF_DU_ODDF_DISP_CDE_MARK, ++}; ++static const unsigned int du_cde_pins[] = { ++ /* CDE */ ++ RCAR_GP_PIN(1, 22), ++}; ++static const unsigned int du_cde_mux[] = { ++ DU_CDE_MARK, ++}; ++static const unsigned int du_disp_pins[] = { ++ /* DISP */ ++ RCAR_GP_PIN(1, 21), ++}; ++static const unsigned int du_disp_mux[] = { ++ DU_DISP_MARK, ++}; ++ ++/* - HSCIF0 ----------------------------------------------------------------- */ ++static const unsigned int hscif0_data_a_pins[] = { ++ /* HRX0_A, HTX0_A */ ++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 15), ++}; ++static const unsigned int hscif0_data_a_mux[] = { ++ HRX0_A_MARK, HTX0_A_MARK, ++}; ++static const unsigned int hscif0_clk_a_pins[] = { ++ /* HSCK0_A */ ++ RCAR_GP_PIN(0, 12), ++}; ++static const unsigned int hscif0_clk_a_mux[] = { ++ HSCK0_A_MARK, ++}; ++static const unsigned int hscif0_ctrl_a_pins[] = { ++ /* HRTS0#_A, HCTS0#_A */ ++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 14), ++}; ++static const unsigned int hscif0_ctrl_a_mux[] = { ++ HRTS0_N_A_MARK, HCTS0_N_A_MARK, ++}; ++ ++static const unsigned int hscif0_data_b_pins[] = { ++ /* HRX0_B, HTX0_B */ ++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 15), ++}; ++static const unsigned int hscif0_data_b_mux[] = { ++ HRX0_B_MARK, HTX0_B_MARK, ++}; ++static const unsigned int hscif0_clk_b_pins[] = { ++ /* HSCK0_B */ ++ RCAR_GP_PIN(0, 12), ++}; ++static const unsigned int hscif0_clk_b_mux[] = { ++ HSCK0_B_MARK, ++}; ++static const unsigned int hscif0_ctrl_b_pins[] = { ++ /* HRTS0#_B, HCTS0#_B */ ++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 14), ++}; ++static const unsigned int hscif0_ctrl_b_mux[] = { ++ HRTS0_N_B_MARK, HCTS0_N_B_MARK, ++}; ++ ++/* - HSCIF1 ----------------------------------------------------------------- */ ++static const unsigned int hscif1_data_pins[] = { ++ /* HRX1, HTX1 */ ++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10), ++}; ++static const unsigned int hscif1_data_mux[] = { ++ HRX1_MARK, HTX1_MARK, ++}; ++static const unsigned int hscif1_clk_pins[] = { ++ /* HSCK1 */ ++ RCAR_GP_PIN(2, 7), ++}; ++static const unsigned int hscif1_clk_mux[] = { ++ HSCK1_MARK, ++}; ++static const unsigned int hscif1_ctrl_pins[] = { ++ /* HRTS1#, HCTS1# */ ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++}; ++static const unsigned int hscif1_ctrl_mux[] = { ++ HRTS1_N_MARK, HCTS1_N_MARK, ++}; ++ ++/* - HSCIF2 ----------------------------------------------------------------- */ ++static const unsigned int hscif2_data_pins[] = { ++ /* HRX2, HTX2 */ ++ RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 15), ++}; ++static const unsigned int hscif2_data_mux[] = { ++ HRX2_MARK, HTX2_MARK, ++}; ++static const unsigned int hscif2_clk_pins[] = { ++ /* HSCK2 */ ++ RCAR_GP_PIN(2, 12), ++}; ++static const unsigned int hscif2_clk_mux[] = { ++ HSCK2_MARK, ++}; ++static const unsigned int hscif2_ctrl_pins[] = { ++ /* HRTS2#, HCTS2# */ ++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 13), ++}; ++static const unsigned int hscif2_ctrl_mux[] = { ++ HRTS2_N_MARK, HCTS2_N_MARK, ++}; ++ ++/* - HSCIF3 ----------------------------------------------------------------- */ ++static const unsigned int hscif3_data_pins[] = { ++ /* HRX3, HTX3 */ ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3), ++}; ++static const unsigned int hscif3_data_mux[] = { ++ HRX3_MARK, HTX3_MARK, ++}; ++static const unsigned int hscif3_clk_pins[] = { ++ /* HSCK3 */ ++ RCAR_GP_PIN(2, 0), ++}; ++static const unsigned int hscif3_clk_mux[] = { ++ HSCK3_MARK, ++}; ++static const unsigned int hscif3_ctrl_pins[] = { ++ /* HRTS3#, HCTS3# */ ++ RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 1), ++}; ++static const unsigned int hscif3_ctrl_mux[] = { ++ HRTS3_N_MARK, HCTS3_N_MARK, ++}; ++ ++/* - SCIF Clock ------------------------------------------------------------- */ ++static const unsigned int scif_clk_a_pins[] = { ++ /* SCIF_CLK */ ++ RCAR_GP_PIN(0, 10), ++}; ++static const unsigned int scif_clk_a_mux[] = { ++ SCIF_CLK_A_MARK, ++}; ++static const unsigned int scif_clk_b_pins[] = { ++ /* SCIF_CLK */ ++ RCAR_GP_PIN(1, 25), ++}; ++static const unsigned int scif_clk_b_mux[] = { ++ SCIF_CLK_B_MARK, ++}; ++ ++/* - I2C -------------------------------------------------------------------- */ ++static const unsigned int i2c0_pins[] = { ++ /* SDA0, SCL0 */ ++ RCAR_GP_PIN(4, 1), RCAR_GP_PIN(4, 0), ++}; ++static const unsigned int i2c0_mux[] = { ++ SDA0_MARK, SCL0_MARK, ++}; ++static const unsigned int i2c1_pins[] = { ++ /* SDA1, SCL1 */ ++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2), ++}; ++static const unsigned int i2c1_mux[] = { ++ SDA1_MARK, SCL1_MARK, ++}; ++static const unsigned int i2c2_pins[] = { ++ /* SDA2, SCL2 */ ++ RCAR_GP_PIN(4, 5), RCAR_GP_PIN(4, 4), ++}; ++static const unsigned int i2c2_mux[] = { ++ SDA2_MARK, SCL2_MARK, ++}; ++static const unsigned int i2c3_pins[] = { ++ /* SDA3, SCL3 */ ++ RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 25), ++}; ++static const unsigned int i2c3_mux[] = { ++ SDA3_MARK, SCL3_MARK, ++}; ++static const unsigned int i2c4_pins[] = { ++ /* SDA4, SCL4 */ ++ RCAR_GP_PIN(3, 16), RCAR_GP_PIN(3, 15), ++}; ++static const unsigned int i2c4_mux[] = { ++ SDA4_MARK, SCL4_MARK, ++}; ++static const unsigned int i2c5_pins[] = { ++ /* SDA5, SCL5 */ ++ RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8), ++}; ++static const unsigned int i2c5_mux[] = { ++ SDA5_MARK, SCL5_MARK, ++}; ++ ++/* - INTC-EX ---------------------------------------------------------------- */ ++static const unsigned int intc_ex_irq0_pins[] = { ++ /* IRQ0 */ ++ RCAR_GP_PIN(1, 0), ++}; ++static const unsigned int intc_ex_irq0_mux[] = { ++ IRQ0_MARK, ++}; ++static const unsigned int intc_ex_irq1_pins[] = { ++ /* IRQ1 */ ++ RCAR_GP_PIN(0, 12), ++}; ++static const unsigned int intc_ex_irq1_mux[] = { ++ IRQ1_MARK, ++}; ++static const unsigned int intc_ex_irq2_pins[] = { ++ /* IRQ2 */ ++ RCAR_GP_PIN(0, 13), ++}; ++static const unsigned int intc_ex_irq2_mux[] = { ++ IRQ2_MARK, ++}; ++static const unsigned int intc_ex_irq3_pins[] = { ++ /* IRQ3 */ ++ RCAR_GP_PIN(0, 14), ++}; ++static const unsigned int intc_ex_irq3_mux[] = { ++ IRQ3_MARK, ++}; ++static const unsigned int intc_ex_irq4_pins[] = { ++ /* IRQ4 */ ++ RCAR_GP_PIN(2, 17), ++}; ++static const unsigned int intc_ex_irq4_mux[] = { ++ IRQ4_MARK, ++}; ++static const unsigned int intc_ex_irq5_pins[] = { ++ /* IRQ5 */ ++ RCAR_GP_PIN(2, 18), ++}; ++static const unsigned int intc_ex_irq5_mux[] = { ++ IRQ5_MARK, ++}; ++ ++/* - MSIOF0 ----------------------------------------------------------------- */ ++static const unsigned int msiof0_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(2, 21), ++}; ++static const unsigned int msiof0_clk_mux[] = { ++ MSIOF0_SCK_MARK, ++}; ++static const unsigned int msiof0_sync_pins[] = { ++ /* SYNC */ ++ RCAR_GP_PIN(2, 22), ++}; ++static const unsigned int msiof0_sync_mux[] = { ++ MSIOF0_SYNC_MARK, ++}; ++static const unsigned int msiof0_ss1_pins[] = { ++ /* SS1 */ ++ RCAR_GP_PIN(2, 23), ++}; ++static const unsigned int msiof0_ss1_mux[] = { ++ MSIOF0_SS1_MARK, ++}; ++static const unsigned int msiof0_ss2_pins[] = { ++ /* SS2 */ ++ RCAR_GP_PIN(2, 24), ++}; ++static const unsigned int msiof0_ss2_mux[] = { ++ MSIOF0_SS2_MARK, ++}; ++static const unsigned int msiof0_txd_pins[] = { ++ /* TXD */ ++ RCAR_GP_PIN(2, 20), ++}; ++static const unsigned int msiof0_txd_mux[] = { ++ MSIOF0_TXD_MARK, ++}; ++static const unsigned int msiof0_rxd_pins[] = { ++ /* RXD */ ++ RCAR_GP_PIN(2, 19), ++}; ++static const unsigned int msiof0_rxd_mux[] = { ++ MSIOF0_RXD_MARK, ++}; ++ ++/* - MSIOF1 ----------------------------------------------------------------- */ ++static const unsigned int msiof1_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(3, 2), ++}; ++static const unsigned int msiof1_clk_mux[] = { ++ MSIOF1_SCK_MARK, ++}; ++static const unsigned int msiof1_sync_pins[] = { ++ /* SYNC */ ++ RCAR_GP_PIN(3, 3), ++}; ++static const unsigned int msiof1_sync_mux[] = { ++ MSIOF1_SYNC_MARK, ++}; ++static const unsigned int msiof1_ss1_pins[] = { ++ /* SS1 */ ++ RCAR_GP_PIN(3, 4), ++}; ++static const unsigned int msiof1_ss1_mux[] = { ++ MSIOF1_SS1_MARK, ++}; ++static const unsigned int msiof1_ss2_pins[] = { ++ /* SS2 */ ++ RCAR_GP_PIN(3, 5), ++}; ++static const unsigned int msiof1_ss2_mux[] = { ++ MSIOF1_SS2_MARK, ++}; ++static const unsigned int msiof1_txd_pins[] = { ++ /* TXD */ ++ RCAR_GP_PIN(3, 1), ++}; ++static const unsigned int msiof1_txd_mux[] = { ++ MSIOF1_TXD_MARK, ++}; ++static const unsigned int msiof1_rxd_pins[] = { ++ /* RXD */ ++ RCAR_GP_PIN(3, 0), ++}; ++static const unsigned int msiof1_rxd_mux[] = { ++ MSIOF1_RXD_MARK, ++}; ++ ++/* - MSIOF2 ----------------------------------------------------------------- */ ++static const unsigned int msiof2_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(2, 0), ++}; ++static const unsigned int msiof2_clk_mux[] = { ++ MSIOF2_SCK_MARK, ++}; ++static const unsigned int msiof2_sync_pins[] = { ++ /* SYNC */ ++ RCAR_GP_PIN(2, 3), ++}; ++static const unsigned int msiof2_sync_mux[] = { ++ MSIOF2_SYNC_MARK, ++}; ++static const unsigned int msiof2_ss1_pins[] = { ++ /* SS1 */ ++ RCAR_GP_PIN(2, 4), ++}; ++static const unsigned int msiof2_ss1_mux[] = { ++ MSIOF2_SS1_MARK, ++}; ++static const unsigned int msiof2_ss2_pins[] = { ++ /* SS2 */ ++ RCAR_GP_PIN(2, 5), ++}; ++static const unsigned int msiof2_ss2_mux[] = { ++ MSIOF2_SS2_MARK, ++}; ++static const unsigned int msiof2_txd_pins[] = { ++ /* TXD */ ++ RCAR_GP_PIN(2, 2), ++}; ++static const unsigned int msiof2_txd_mux[] = { ++ MSIOF2_TXD_MARK, ++}; ++static const unsigned int msiof2_rxd_pins[] = { ++ /* RXD */ ++ RCAR_GP_PIN(2, 1), ++}; ++static const unsigned int msiof2_rxd_mux[] = { ++ MSIOF2_RXD_MARK, ++}; ++ ++/* - MSIOF3 ----------------------------------------------------------------- */ ++static const unsigned int msiof3_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(0, 20), ++}; ++static const unsigned int msiof3_clk_mux[] = { ++ MSIOF3_SCK_MARK, ++}; ++static const unsigned int msiof3_sync_pins[] = { ++ /* SYNC */ ++ RCAR_GP_PIN(0, 21), ++}; ++static const unsigned int msiof3_sync_mux[] = { ++ MSIOF3_SYNC_MARK, ++}; ++static const unsigned int msiof3_ss1_pins[] = { ++ /* SS1 */ ++ RCAR_GP_PIN(0, 18), ++}; ++static const unsigned int msiof3_ss1_mux[] = { ++ MSIOF3_SS1_MARK, ++}; ++static const unsigned int msiof3_ss2_pins[] = { ++ /* SS2 */ ++ RCAR_GP_PIN(0, 19), ++}; ++static const unsigned int msiof3_ss2_mux[] = { ++ MSIOF3_SS2_MARK, ++}; ++static const unsigned int msiof3_txd_pins[] = { ++ /* TXD */ ++ RCAR_GP_PIN(0, 17), ++}; ++static const unsigned int msiof3_txd_mux[] = { ++ MSIOF3_TXD_MARK, ++}; ++static const unsigned int msiof3_rxd_pins[] = { ++ /* RXD */ ++ RCAR_GP_PIN(0, 16), ++}; ++static const unsigned int msiof3_rxd_mux[] = { ++ MSIOF3_RXD_MARK, ++}; ++ ++/* - TPU ------------------------------------------------------------------- */ ++static const unsigned int tpu_to0_pins[] = { ++ /* TPU0TO0 */ ++ RCAR_GP_PIN(1, 19), ++}; ++static const unsigned int tpu_to0_mux[] = { ++ TPU0TO0_MARK, ++}; ++static const unsigned int tpu_to1_pins[] = { ++ /* TPU0TO1 */ ++ RCAR_GP_PIN(1, 20), ++}; ++static const unsigned int tpu_to1_mux[] = { ++ TPU0TO1_MARK, ++}; ++static const unsigned int tpu_to2_pins[] = { ++ /* TPU0TO2 */ ++ RCAR_GP_PIN(4, 2), ++}; ++static const unsigned int tpu_to2_mux[] = { ++ TPU0TO2_MARK, ++}; ++static const unsigned int tpu_to3_pins[] = { ++ /* TPU0TO3 */ ++ RCAR_GP_PIN(4, 3), ++}; ++static const unsigned int tpu_to3_mux[] = { ++ TPU0TO3_MARK, ++}; ++ ++/* - PWM0 ------------------------------------------------------------------- */ ++static const unsigned int pwm0_a_pins[] = { ++ /* PWM0 */ ++ RCAR_GP_PIN(0, 15), ++}; ++static const unsigned int pwm0_a_mux[] = { ++ PWM0_A_MARK, ++}; ++static const unsigned int pwm0_b_pins[] = { ++ /* PWM0 */ ++ RCAR_GP_PIN(1, 21), ++}; ++static const unsigned int pwm0_b_mux[] = { ++ PWM0_B_MARK, ++}; ++ ++/* - PWM1 ------------------------------------------------------------------- */ ++static const unsigned int pwm1_a_pins[] = { ++ /* PWM1 */ ++ RCAR_GP_PIN(2, 13), ++}; ++static const unsigned int pwm1_a_mux[] = { ++ PWM1_A_MARK, ++}; ++static const unsigned int pwm1_b_pins[] = { ++ /* PWM1 */ ++ RCAR_GP_PIN(1, 22), ++}; ++static const unsigned int pwm1_b_mux[] = { ++ PWM1_B_MARK, ++}; ++ ++/* - PWM2 ------------------------------------------------------------------- */ ++static const unsigned int pwm2_a_pins[] = { ++ /* PWM2 */ ++ RCAR_GP_PIN(2, 14), ++}; ++static const unsigned int pwm2_a_mux[] = { ++ PWM2_A_MARK, ++}; ++static const unsigned int pwm2_b_pins[] = { ++ /* PWM2 */ ++ RCAR_GP_PIN(1, 23), ++}; ++static const unsigned int pwm2_b_mux[] = { ++ PWM2_B_MARK, ++}; ++ ++/* - PWM3 ------------------------------------------------------------------- */ ++static const unsigned int pwm3_a_pins[] = { ++ /* PWM3 */ ++ RCAR_GP_PIN(2, 15), ++}; ++static const unsigned int pwm3_a_mux[] = { ++ PWM3_A_MARK, ++}; ++static const unsigned int pwm3_b_pins[] = { ++ /* PWM3 */ ++ RCAR_GP_PIN(1, 24), ++}; ++static const unsigned int pwm3_b_mux[] = { ++ PWM3_B_MARK, ++}; ++ ++/* - PWM4 ------------------------------------------------------------------- */ ++static const unsigned int pwm4_a_pins[] = { ++ /* PWM4 */ ++ RCAR_GP_PIN(2, 16), ++}; ++static const unsigned int pwm4_a_mux[] = { ++ PWM4_A_MARK, ++}; ++static const unsigned int pwm4_b_pins[] = { ++ /* PWM4 */ ++ RCAR_GP_PIN(1, 25), ++}; ++static const unsigned int pwm4_b_mux[] = { ++ PWM4_B_MARK, ++}; ++ ++/* - SCIF0 ------------------------------------------------------------------ */ ++static const unsigned int scif0_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5), ++}; ++static const unsigned int scif0_data_mux[] = { ++ RX0_MARK, TX0_MARK, ++}; ++static const unsigned int scif0_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(4, 1), ++}; ++static const unsigned int scif0_clk_mux[] = { ++ SCK0_MARK, ++}; ++static const unsigned int scif0_ctrl_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2), ++}; ++static const unsigned int scif0_ctrl_mux[] = { ++ RTS0_N_TANS_MARK, CTS0_N_MARK, ++}; ++ ++/* - SCIF1 ------------------------------------------------------------------ */ ++static const unsigned int scif1_data_a_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++}; ++static const unsigned int scif1_data_a_mux[] = { ++ RX1_A_MARK, TX1_A_MARK, ++}; ++static const unsigned int scif1_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(2, 5), ++}; ++static const unsigned int scif1_clk_mux[] = { ++ SCK1_MARK, ++}; ++static const unsigned int scif1_ctrl_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10), ++}; ++static const unsigned int scif1_ctrl_mux[] = { ++ RTS1_N_TANS_MARK, CTS1_N_MARK, ++}; ++static const unsigned int scif1_data_b_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 23), ++}; ++static const unsigned int scif1_data_b_mux[] = { ++ RX1_B_MARK, TX1_B_MARK, ++}; ++ ++/* - SCIF3 ------------------------------------------------------------------ */ ++static const unsigned int scif3_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2), ++}; ++static const unsigned int scif3_data_mux[] = { ++ RX3_MARK, TX3_MARK, ++}; ++static const unsigned int scif3_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(2, 0), ++}; ++static const unsigned int scif3_clk_mux[] = { ++ SCK3_MARK, ++}; ++static const unsigned int scif3_ctrl_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3), ++}; ++static const unsigned int scif3_ctrl_mux[] = { ++ RTS3_N_TANS_MARK, CTS3_N_MARK, ++}; ++ ++/* - SCIF4 ------------------------------------------------------------------ */ ++static const unsigned int scif4_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 2), ++}; ++static const unsigned int scif4_data_mux[] = { ++ RX4_MARK, TX4_MARK, ++}; ++static const unsigned int scif4_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(0, 0), ++}; ++static const unsigned int scif4_clk_mux[] = { ++ SCK4_MARK, ++}; ++static const unsigned int scif4_ctrl_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 3), ++}; ++static const unsigned int scif4_ctrl_mux[] = { ++ RTS4_N_TANS_MARK, CTS4_N_MARK, ++}; ++ ++/* - MMC -------------------------------------------------------------------- */ ++static const unsigned int mmc_data1_pins[] = { ++ /* D0 */ ++ RCAR_GP_PIN(3, 8), ++}; ++static const unsigned int mmc_data1_mux[] = { ++ MMC_D0_MARK, ++}; ++static const unsigned int mmc_data4_pins[] = { ++ /* D[0:3] */ ++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9), ++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11), ++}; ++static const unsigned int mmc_data4_mux[] = { ++ MMC_D0_MARK, MMC_D1_MARK, ++ MMC_D2_MARK, MMC_D3_MARK, ++}; ++static const unsigned int mmc_data8_pins[] = { ++ /* D[0:7] */ ++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9), ++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11), ++ RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14), ++ RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 16), ++}; ++static const unsigned int mmc_data8_mux[] = { ++ MMC_D0_MARK, MMC_D1_MARK, ++ MMC_D2_MARK, MMC_D3_MARK, ++ MMC_D4_MARK, MMC_D5_MARK, ++ MMC_D6_MARK, MMC_D7_MARK, ++}; ++static const unsigned int mmc_ctrl_pins[] = { ++ /* CLK, CMD */ ++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 7), ++}; ++static const unsigned int mmc_ctrl_mux[] = { ++ MMC_CLK_MARK, MMC_CMD_MARK, ++}; ++static const unsigned int mmc_cd_pins[] = { ++ /* CD */ ++ RCAR_GP_PIN(3, 5), ++}; ++static const unsigned int mmc_cd_mux[] = { ++ MMC_CD_MARK, ++}; ++static const unsigned int mmc_wp_pins[] = { ++ /* WP */ ++ RCAR_GP_PIN(3, 4), ++}; ++static const unsigned int mmc_wp_mux[] = { ++ MMC_WP_MARK, ++}; ++static const unsigned int mmc_ds_pins[] = { ++ /* DS */ ++ RCAR_GP_PIN(3, 6), ++}; ++static const unsigned int mmc_ds_mux[] = { ++ MMC_DS_MARK, ++}; ++ ++/* - TMU -------------------------------------------------------------------- */ ++static const unsigned int tmu_tclk1_a_pins[] = { ++ /* TCLK1 */ ++ RCAR_GP_PIN(3, 13), ++}; ++static const unsigned int tmu_tclk1_a_mux[] = { ++ TCLK1_A_MARK, ++}; ++static const unsigned int tmu_tclk1_b_pins[] = { ++ /* TCLK1 */ ++ RCAR_GP_PIN(1, 23), ++}; ++static const unsigned int tmu_tclk1_b_mux[] = { ++ TCLK1_B_MARK, ++}; ++static const unsigned int tmu_tclk2_a_pins[] = { ++ /* TCLK2 */ ++ RCAR_GP_PIN(3, 14), ++}; ++static const unsigned int tmu_tclk2_a_mux[] = { ++ TCLK2_A_MARK, ++}; ++static const unsigned int tmu_tclk2_b_pins[] = { ++ /* TCLK2 */ ++ RCAR_GP_PIN(1, 24), ++}; ++static const unsigned int tmu_tclk2_b_mux[] = { ++ TCLK2_B_MARK, ++}; ++ ++/* - VIN0 ------------------------------------------------------------------- */ ++static const unsigned int vin0_data8_pins[] = { ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), ++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7), ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), ++}; ++static const unsigned int vin0_data8_mux[] = { ++ VI0_DATA0_MARK, VI0_DATA1_MARK, ++ VI0_DATA2_MARK, VI0_DATA3_MARK, ++ VI0_DATA4_MARK, VI0_DATA5_MARK, ++ VI0_DATA6_MARK, VI0_DATA7_MARK, ++}; ++static const unsigned int vin0_data10_pins[] = { ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), ++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7), ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), ++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13), ++}; ++static const unsigned int vin0_data10_mux[] = { ++ VI0_DATA0_MARK, VI0_DATA1_MARK, ++ VI0_DATA2_MARK, VI0_DATA3_MARK, ++ VI0_DATA4_MARK, VI0_DATA5_MARK, ++ VI0_DATA6_MARK, VI0_DATA7_MARK, ++ VI0_DATA8_MARK, VI0_DATA9_MARK, ++}; ++static const unsigned int vin0_data12_pins[] = { ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), ++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7), ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), ++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13), ++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15), ++}; ++static const unsigned int vin0_data12_mux[] = { ++ VI0_DATA0_MARK, VI0_DATA1_MARK, ++ VI0_DATA2_MARK, VI0_DATA3_MARK, ++ VI0_DATA4_MARK, VI0_DATA5_MARK, ++ VI0_DATA6_MARK, VI0_DATA7_MARK, ++ VI0_DATA8_MARK, VI0_DATA9_MARK, ++ VI0_DATA10_MARK, VI0_DATA11_MARK, ++}; ++static const unsigned int vin0_data16_pins[] = { ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), ++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7), ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), ++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13), ++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15), ++ RCAR_GP_PIN(2, 17), RCAR_GP_PIN(2, 18), ++ RCAR_GP_PIN(2, 19), RCAR_GP_PIN(2, 20), ++}; ++static const unsigned int vin0_data16_mux[] = { ++ VI0_DATA0_MARK, VI0_DATA1_MARK, ++ VI0_DATA2_MARK, VI0_DATA3_MARK, ++ VI0_DATA4_MARK, VI0_DATA5_MARK, ++ VI0_DATA6_MARK, VI0_DATA7_MARK, ++ VI0_DATA8_MARK, VI0_DATA9_MARK, ++ VI0_DATA10_MARK, VI0_DATA11_MARK, ++ VI0_DATA12_MARK, VI0_DATA13_MARK, ++ VI0_DATA14_MARK, VI0_DATA15_MARK, ++}; ++static const unsigned int vin0_data20_pins[] = { ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), ++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7), ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), ++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13), ++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15), ++ RCAR_GP_PIN(2, 17), RCAR_GP_PIN(2, 18), ++ RCAR_GP_PIN(2, 19), RCAR_GP_PIN(2, 20), ++ RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22), ++ RCAR_GP_PIN(2, 23), RCAR_GP_PIN(2, 24), ++}; ++static const unsigned int vin0_data20_mux[] = { ++ VI0_DATA0_MARK, VI0_DATA1_MARK, ++ VI0_DATA2_MARK, VI0_DATA3_MARK, ++ VI0_DATA4_MARK, VI0_DATA5_MARK, ++ VI0_DATA6_MARK, VI0_DATA7_MARK, ++ VI0_DATA8_MARK, VI0_DATA9_MARK, ++ VI0_DATA10_MARK, VI0_DATA11_MARK, ++ VI0_DATA12_MARK, VI0_DATA13_MARK, ++ VI0_DATA14_MARK, VI0_DATA15_MARK, ++ VI0_DATA16_MARK, VI0_DATA17_MARK, ++ VI0_DATA18_MARK, VI0_DATA19_MARK, ++}; ++static const unsigned int vin0_data24_pins[] = { ++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), ++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7), ++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), ++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), ++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13), ++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15), ++ RCAR_GP_PIN(2, 17), RCAR_GP_PIN(2, 18), ++ RCAR_GP_PIN(2, 19), RCAR_GP_PIN(2, 20), ++ RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22), ++ RCAR_GP_PIN(2, 23), RCAR_GP_PIN(2, 24), ++ RCAR_GP_PIN(2, 25), RCAR_GP_PIN(2, 26), ++ RCAR_GP_PIN(2, 27), RCAR_GP_PIN(2, 28), ++}; ++static const unsigned int vin0_data24_mux[] = { ++ VI0_DATA0_MARK, VI0_DATA1_MARK, ++ VI0_DATA2_MARK, VI0_DATA3_MARK, ++ VI0_DATA4_MARK, VI0_DATA5_MARK, ++ VI0_DATA6_MARK, VI0_DATA7_MARK, ++ VI0_DATA8_MARK, VI0_DATA9_MARK, ++ VI0_DATA10_MARK, VI0_DATA11_MARK, ++ VI0_DATA12_MARK, VI0_DATA13_MARK, ++ VI0_DATA14_MARK, VI0_DATA15_MARK, ++ VI0_DATA16_MARK, VI0_DATA17_MARK, ++ VI0_DATA18_MARK, VI0_DATA19_MARK, ++ VI0_DATA20_MARK, VI0_DATA21_MARK, ++ VI0_DATA22_MARK, VI0_DATA23_MARK, ++}; ++static const unsigned int vin0_sync_pins[] = { ++ /* VSYNC_N, HSYNC_N */ ++ RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 2), ++}; ++static const unsigned int vin0_sync_mux[] = { ++ VI0_HSYNC_N_MARK, VI0_VSYNC_N_MARK, ++}; ++static const unsigned int vin0_field_pins[] = { ++ /* FIELD */ ++ RCAR_GP_PIN(2, 16), ++}; ++static const unsigned int vin0_field_mux[] = { ++ VI0_FIELD_MARK, ++}; ++static const unsigned int vin0_clkenb_pins[] = { ++ /* CLKENB */ ++ RCAR_GP_PIN(2, 1), ++}; ++static const unsigned int vin0_clkenb_mux[] = { ++ VI0_CLKENB_MARK, ++}; ++static const unsigned int vin0_clk_pins[] = { ++ /* CLK */ ++ RCAR_GP_PIN(2, 0), ++}; ++static const unsigned int vin0_clk_mux[] = { ++ VI0_CLK_MARK, ++}; ++/* - VIN1 ------------------------------------------------------------------- */ ++static const unsigned int vin1_data8_pins[] = { ++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5), ++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7), ++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9), ++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11), ++}; ++static const unsigned int vin1_data8_mux[] = { ++ VI1_DATA0_MARK, VI1_DATA1_MARK, ++ VI1_DATA2_MARK, VI1_DATA3_MARK, ++ VI1_DATA4_MARK, VI1_DATA5_MARK, ++ VI1_DATA6_MARK, VI1_DATA7_MARK, ++}; ++static const unsigned int vin1_data10_pins[] = { ++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5), ++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7), ++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9), ++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11), ++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13), ++}; ++static const unsigned int vin1_data10_mux[] = { ++ VI1_DATA0_MARK, VI1_DATA1_MARK, ++ VI1_DATA2_MARK, VI1_DATA3_MARK, ++ VI1_DATA4_MARK, VI1_DATA5_MARK, ++ VI1_DATA6_MARK, VI1_DATA7_MARK, ++ VI1_DATA8_MARK, VI1_DATA9_MARK, ++}; ++static const unsigned int vin1_data12_pins[] = { ++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5), ++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7), ++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9), ++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11), ++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13), ++ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15), ++}; ++static const unsigned int vin1_data12_mux[] = { ++ VI1_DATA0_MARK, VI1_DATA1_MARK, ++ VI1_DATA2_MARK, VI1_DATA3_MARK, ++ VI1_DATA4_MARK, VI1_DATA5_MARK, ++ VI1_DATA6_MARK, VI1_DATA7_MARK, ++ VI1_DATA8_MARK, VI1_DATA9_MARK, ++ VI1_DATA10_MARK, VI1_DATA11_MARK, ++}; ++static const unsigned int vin1_sync_pins[] = { ++ /* VSYNC_N, HSYNC_N */ ++ RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 2), ++}; ++static const unsigned int vin1_sync_mux[] = { ++ VI1_HSYNC_N_MARK, VI1_VSYNC_N_MARK, ++}; ++static const unsigned int vin1_field_pins[] = { ++ /* FIELD */ ++ RCAR_GP_PIN(3, 16), ++}; ++static const unsigned int vin1_field_mux[] = { ++ VI1_FIELD_MARK, ++}; ++static const unsigned int vin1_clkenb_pins[] = { ++ /* CLKENB */ ++ RCAR_GP_PIN(3, 1), ++}; ++static const unsigned int vin1_clkenb_mux[] = { ++ VI1_CLKENB_MARK, ++}; ++static const unsigned int vin1_clk_pins[] = { ++ /* CLK */ ++ RCAR_GP_PIN(3, 0), ++}; ++static const unsigned int vin1_clk_mux[] = { ++ VI1_CLK_MARK, ++}; ++ ++static const struct sh_pfc_pin_group pinmux_groups[] = { ++ SH_PFC_PIN_GROUP(avb_rx_ctrl), ++ SH_PFC_PIN_GROUP(avb_rxc), ++ SH_PFC_PIN_GROUP(avb_rd0), ++ SH_PFC_PIN_GROUP(avb_rd1), ++ SH_PFC_PIN_GROUP(avb_rd2), ++ SH_PFC_PIN_GROUP(avb_rd3), ++ SH_PFC_PIN_GROUP(avb_rd4), ++ SH_PFC_PIN_GROUP(avb_tx_ctrl), ++ SH_PFC_PIN_GROUP(avb_txc), ++ SH_PFC_PIN_GROUP(avb_td0), ++ SH_PFC_PIN_GROUP(avb_td1), ++ SH_PFC_PIN_GROUP(avb_td2), ++ SH_PFC_PIN_GROUP(avb_td3), ++ SH_PFC_PIN_GROUP(avb_td4), ++ SH_PFC_PIN_GROUP(avb_txcrefclk), ++ SH_PFC_PIN_GROUP(avb_mdio), ++ SH_PFC_PIN_GROUP(avb_mdc), ++ SH_PFC_PIN_GROUP(avb_magic), ++ SH_PFC_PIN_GROUP(avb_phy_int), ++ SH_PFC_PIN_GROUP(avb_link), ++ SH_PFC_PIN_GROUP(avb_avtp_match), ++ SH_PFC_PIN_GROUP(avb_avtp_capture), ++ SH_PFC_PIN_GROUP(avb_avtp_pps), ++ SH_PFC_PIN_GROUP(gether_rx_ctrl), ++ SH_PFC_PIN_GROUP(gether_rxc), ++ SH_PFC_PIN_GROUP(gether_rd0), ++ SH_PFC_PIN_GROUP(gether_rd1), ++ SH_PFC_PIN_GROUP(gether_rd2), ++ SH_PFC_PIN_GROUP(gether_rd3), ++ SH_PFC_PIN_GROUP(gether_rd4), ++ SH_PFC_PIN_GROUP(gether_tx_ctrl), ++ SH_PFC_PIN_GROUP(gether_txc), ++ SH_PFC_PIN_GROUP(gether_td0), ++ SH_PFC_PIN_GROUP(gether_td1), ++ SH_PFC_PIN_GROUP(gether_td2), ++ SH_PFC_PIN_GROUP(gether_td3), ++ SH_PFC_PIN_GROUP(gether_td4), ++ SH_PFC_PIN_GROUP(gether_txcrefclk), ++ SH_PFC_PIN_GROUP(gether_txcrefclk_mega), ++ SH_PFC_PIN_GROUP(gether_mdio_a), ++ SH_PFC_PIN_GROUP(gether_mdio_b), ++ SH_PFC_PIN_GROUP(gether_mdc_a), ++ SH_PFC_PIN_GROUP(gether_mdc_b), ++ SH_PFC_PIN_GROUP(gether_magic), ++ SH_PFC_PIN_GROUP(gether_phy_int_a), ++ SH_PFC_PIN_GROUP(gether_phy_int_b), ++ SH_PFC_PIN_GROUP(gether_link_a), ++ SH_PFC_PIN_GROUP(gether_link_b), ++ SH_PFC_PIN_GROUP(gether_rmii), ++ SH_PFC_PIN_GROUP(canfd0_data_a), ++ SH_PFC_PIN_GROUP(canfd_clk_a), ++ SH_PFC_PIN_GROUP(canfd0_data_b), ++ SH_PFC_PIN_GROUP(canfd_clk_b), ++ SH_PFC_PIN_GROUP(canfd1_data), ++ SH_PFC_PIN_GROUP(du_rgb666), ++ SH_PFC_PIN_GROUP(du_clk_out_0), ++ SH_PFC_PIN_GROUP(du_clk_out_1), ++ SH_PFC_PIN_GROUP(du_sync), ++ SH_PFC_PIN_GROUP(du_oddf), ++ SH_PFC_PIN_GROUP(du_cde), ++ SH_PFC_PIN_GROUP(du_disp), ++ SH_PFC_PIN_GROUP(hscif0_data_a), ++ SH_PFC_PIN_GROUP(hscif0_clk_a), ++ SH_PFC_PIN_GROUP(hscif0_ctrl_a), ++ SH_PFC_PIN_GROUP(hscif0_data_b), ++ SH_PFC_PIN_GROUP(hscif0_clk_b), ++ SH_PFC_PIN_GROUP(hscif0_ctrl_b), ++ SH_PFC_PIN_GROUP(hscif1_data), ++ SH_PFC_PIN_GROUP(hscif1_clk), ++ SH_PFC_PIN_GROUP(hscif1_ctrl), ++ SH_PFC_PIN_GROUP(hscif2_data), ++ SH_PFC_PIN_GROUP(hscif2_clk), ++ SH_PFC_PIN_GROUP(hscif2_ctrl), ++ SH_PFC_PIN_GROUP(hscif3_data), ++ SH_PFC_PIN_GROUP(hscif3_clk), ++ SH_PFC_PIN_GROUP(hscif3_ctrl), ++ SH_PFC_PIN_GROUP(scif_clk_a), ++ SH_PFC_PIN_GROUP(scif_clk_b), ++ SH_PFC_PIN_GROUP(i2c0), ++ SH_PFC_PIN_GROUP(i2c1), ++ SH_PFC_PIN_GROUP(i2c2), ++ SH_PFC_PIN_GROUP(i2c3), ++ SH_PFC_PIN_GROUP(i2c4), ++ SH_PFC_PIN_GROUP(i2c5), ++ SH_PFC_PIN_GROUP(intc_ex_irq0), ++ SH_PFC_PIN_GROUP(intc_ex_irq1), ++ SH_PFC_PIN_GROUP(intc_ex_irq2), ++ SH_PFC_PIN_GROUP(intc_ex_irq3), ++ SH_PFC_PIN_GROUP(intc_ex_irq4), ++ SH_PFC_PIN_GROUP(intc_ex_irq5), ++ SH_PFC_PIN_GROUP(msiof0_clk), ++ SH_PFC_PIN_GROUP(msiof0_sync), ++ SH_PFC_PIN_GROUP(msiof0_ss1), ++ SH_PFC_PIN_GROUP(msiof0_ss2), ++ SH_PFC_PIN_GROUP(msiof0_txd), ++ SH_PFC_PIN_GROUP(msiof0_rxd), ++ SH_PFC_PIN_GROUP(msiof1_clk), ++ SH_PFC_PIN_GROUP(msiof1_sync), ++ SH_PFC_PIN_GROUP(msiof1_ss1), ++ SH_PFC_PIN_GROUP(msiof1_ss2), ++ SH_PFC_PIN_GROUP(msiof1_txd), ++ SH_PFC_PIN_GROUP(msiof1_rxd), ++ SH_PFC_PIN_GROUP(msiof2_clk), ++ SH_PFC_PIN_GROUP(msiof2_sync), ++ SH_PFC_PIN_GROUP(msiof2_ss1), ++ SH_PFC_PIN_GROUP(msiof2_ss2), ++ SH_PFC_PIN_GROUP(msiof2_txd), ++ SH_PFC_PIN_GROUP(msiof2_rxd), ++ SH_PFC_PIN_GROUP(msiof3_clk), ++ SH_PFC_PIN_GROUP(msiof3_sync), ++ SH_PFC_PIN_GROUP(msiof3_ss1), ++ SH_PFC_PIN_GROUP(msiof3_ss2), ++ SH_PFC_PIN_GROUP(msiof3_txd), ++ SH_PFC_PIN_GROUP(msiof3_rxd), ++ SH_PFC_PIN_GROUP(tpu_to0), ++ SH_PFC_PIN_GROUP(tpu_to1), ++ SH_PFC_PIN_GROUP(tpu_to2), ++ SH_PFC_PIN_GROUP(tpu_to3), ++ SH_PFC_PIN_GROUP(pwm0_a), ++ SH_PFC_PIN_GROUP(pwm0_b), ++ SH_PFC_PIN_GROUP(pwm1_a), ++ SH_PFC_PIN_GROUP(pwm1_b), ++ SH_PFC_PIN_GROUP(pwm2_a), ++ SH_PFC_PIN_GROUP(pwm2_b), ++ SH_PFC_PIN_GROUP(pwm3_a), ++ SH_PFC_PIN_GROUP(pwm3_b), ++ SH_PFC_PIN_GROUP(pwm4_a), ++ SH_PFC_PIN_GROUP(pwm4_b), ++ SH_PFC_PIN_GROUP(scif0_data), ++ SH_PFC_PIN_GROUP(scif0_clk), ++ SH_PFC_PIN_GROUP(scif0_ctrl), ++ SH_PFC_PIN_GROUP(scif1_data_a), ++ SH_PFC_PIN_GROUP(scif1_clk), ++ SH_PFC_PIN_GROUP(scif1_ctrl), ++ SH_PFC_PIN_GROUP(scif1_data_b), ++ SH_PFC_PIN_GROUP(scif3_data), ++ SH_PFC_PIN_GROUP(scif3_clk), ++ SH_PFC_PIN_GROUP(scif3_ctrl), ++ SH_PFC_PIN_GROUP(scif4_data), ++ SH_PFC_PIN_GROUP(scif4_clk), ++ SH_PFC_PIN_GROUP(scif4_ctrl), ++ SH_PFC_PIN_GROUP(mmc_data1), ++ SH_PFC_PIN_GROUP(mmc_data4), ++ SH_PFC_PIN_GROUP(mmc_data8), ++ SH_PFC_PIN_GROUP(mmc_ctrl), ++ SH_PFC_PIN_GROUP(mmc_cd), ++ SH_PFC_PIN_GROUP(mmc_wp), ++ SH_PFC_PIN_GROUP(mmc_ds), ++ SH_PFC_PIN_GROUP(tmu_tclk1_a), ++ SH_PFC_PIN_GROUP(tmu_tclk1_b), ++ SH_PFC_PIN_GROUP(tmu_tclk2_a), ++ SH_PFC_PIN_GROUP(tmu_tclk2_b), ++ SH_PFC_PIN_GROUP(vin0_data8), ++ SH_PFC_PIN_GROUP(vin0_data10), ++ SH_PFC_PIN_GROUP(vin0_data12), ++ SH_PFC_PIN_GROUP(vin0_data16), ++ SH_PFC_PIN_GROUP(vin0_data20), ++ SH_PFC_PIN_GROUP(vin0_data24), ++ SH_PFC_PIN_GROUP(vin0_sync), ++ SH_PFC_PIN_GROUP(vin0_field), ++ SH_PFC_PIN_GROUP(vin0_clkenb), ++ SH_PFC_PIN_GROUP(vin0_clk), ++ SH_PFC_PIN_GROUP(vin1_data8), ++ SH_PFC_PIN_GROUP(vin1_data10), ++ SH_PFC_PIN_GROUP(vin1_data12), ++ SH_PFC_PIN_GROUP(vin1_sync), ++ SH_PFC_PIN_GROUP(vin1_field), ++ SH_PFC_PIN_GROUP(vin1_clkenb), ++ SH_PFC_PIN_GROUP(vin1_clk), ++}; ++ ++static const char * const avb_groups[] = { ++ "avb_rx_ctrl", ++ "avb_rxc", ++ "avb_rd1", ++ "avb_rd4", ++ "avb_tx_ctrl", ++ "avb_txc", ++ "avb_td1", ++ "avb_td4", ++ "avb_txcrefclk", ++ "avb_mdio", ++ "avb_mdc", ++ "avb_magic", ++ "avb_phy_int", ++ "avb_link", ++ "avb_avtp_match", ++ "avb_avtp_capture", ++ "avb_avtp_pps", ++}; ++ ++static const char * const gether_groups[] = { ++ "gether_rx_ctrl", ++ "gether_rxc", ++ "gether_rd1", ++ "gether_rd4", ++ "gether_tx_ctrl", ++ "gether_txc", ++ "gether_td1", ++ "gether_td4", ++ "gether_txcrefclk", ++ "gether_txcrefclk_mega", ++ "gether_mdio_a", ++ "gether_mdc_a", ++ "gether_mdio_b", ++ "gether_mdc_b", ++ "gether_magic", ++ "gether_phy_int_a", ++ "gether_link_a", ++ "gether_phy_int_b", ++ "gether_link_b", ++ "gether_rmii", ++}; ++ ++static const char * const canfd0_groups[] = { ++ "canfd0_data_a", ++ "canfd_clk_a", ++ "canfd0_data_b", ++ "canfd_clk_b", ++}; ++ ++static const char * const canfd1_groups[] = { ++ "canfd1_data", ++}; ++ ++static const char * const du_groups[] = { ++ "du_rgb666", ++ "du_clk_out_0", ++ "du_clk_out_1", ++ "du_sync", ++ "du_oddf", ++ "du_cde", ++ "du_disp", ++}; ++ ++static const char * const hscif0_groups[] = { ++ "hscif0_data_a", ++ "hscif0_clk_a", ++ "hscif0_ctrl_a", ++ "hscif0_data_b", ++ "hscif0_clk_b", ++ "hscif0_ctrl_b", ++}; ++ ++static const char * const hscif1_groups[] = { ++ "hscif1_data", ++ "hscif1_clk", ++ "hscif1_ctrl", ++}; ++ ++static const char * const hscif2_groups[] = { ++ "hscif2_data", ++ "hscif2_clk", ++ "hscif2_ctrl", ++}; ++ ++static const char * const hscif3_groups[] = { ++ "hscif3_data", ++ "hscif3_clk", ++ "hscif3_ctrl", ++}; ++ ++static const char * const scif_clk_groups[] = { ++ "scif_clk_a", ++ "scif_clk_b", ++}; ++ ++static const char * const i2c0_groups[] = { ++ "i2c0", ++}; ++ ++static const char * const i2c1_groups[] = { ++ "i2c1", ++}; ++ ++static const char * const i2c2_groups[] = { ++ "i2c2", ++}; ++ ++static const char * const i2c3_groups[] = { ++ "i2c3", ++}; ++ ++static const char * const i2c4_groups[] = { ++ "i2c4", ++}; ++ ++static const char * const i2c5_groups[] = { ++ "i2c5", ++}; ++ ++static const char * const intc_ex_groups[] = { ++ "intc_ex_irq0", ++ "intc_ex_irq1", ++ "intc_ex_irq2", ++ "intc_ex_irq3", ++ "intc_ex_irq4", ++ "intc_ex_irq5", ++}; ++ ++static const char * const msiof0_groups[] = { ++ "msiof0_clk", ++ "msiof0_sync", ++ "msiof0_ss1", ++ "msiof0_ss2", ++ "msiof0_txd", ++ "msiof0_rxd", ++}; ++ ++static const char * const msiof1_groups[] = { ++ "msiof1_clk", ++ "msiof1_sync", ++ "msiof1_ss1", ++ "msiof1_ss2", ++ "msiof1_txd", ++ "msiof1_rxd", ++}; ++ ++static const char * const msiof2_groups[] = { ++ "msiof2_clk", ++ "msiof2_sync", ++ "msiof2_ss1", ++ "msiof2_ss2", ++ "msiof2_txd", ++ "msiof2_rxd", ++}; ++ ++static const char * const msiof3_groups[] = { ++ "msiof3_clk", ++ "msiof3_sync", ++ "msiof3_ss1", ++ "msiof3_ss2", ++ "msiof3_txd", ++ "msiof3_rxd", ++}; ++ ++static const char * const tpu_groups[] = { ++ "tpu_to0", ++ "tpu_to1", ++ "tpu_to2", ++ "tpu_to3", ++}; ++ ++static const char * const pwm0_groups[] = { ++ "pwm0_a", ++ "pwm0_b", ++}; ++ ++static const char * const pwm1_groups[] = { ++ "pwm1_a", ++ "pwm1_b", ++}; ++ ++static const char * const pwm2_groups[] = { ++ "pwm2_a", ++ "pwm2_b", ++}; ++ ++static const char * const pwm3_groups[] = { ++ "pwm3_a", ++ "pwm3_b", ++}; ++ ++static const char * const pwm4_groups[] = { ++ "pwm4_a", ++ "pwm4_b", ++}; ++ ++static const char * const scif0_groups[] = { ++ "scif0_data", ++// "scif0_clk", ++// "scif0_ctrl", ++}; ++ ++static const char * const scif1_groups[] = { ++ "scif1_data_a", ++ "scif1_clk", ++ "scif1_ctrl", ++ "scif1_data_b", ++}; ++ ++static const char * const scif3_groups[] = { ++ "scif3_data", ++ "scif3_clk", ++ "scif3_ctrl", ++}; ++ ++static const char * const scif4_groups[] = { ++ "scif4_data", ++ "scif4_clk", ++ "scif4_ctrl", ++}; ++ ++static const char * const mmc_groups[] = { ++ "mmc_data1", ++ "mmc_data4", ++ "mmc_data8", ++ "mmc_ctrl", ++ "mmc_cd", ++ "mmc_wp", ++ "mmc_ds", ++}; ++ ++static const char * const tmu_groups[] = { ++ "tmu_tclk1_a", ++ "tmu_tclk1_b", ++ "tmu_tclk2_a", ++ "tmu_tclk2_b", ++}; ++ ++static const char * const vin0_groups[] = { ++ "vin0_data8", ++ "vin0_data10", ++ "vin0_data12", ++ "vin0_data16", ++ "vin0_data20", ++ "vin0_data24", ++ "vin0_sync", ++ "vin0_field", ++ "vin0_clkenb", ++ "vin0_clk", ++}; ++ ++static const char * const vin1_groups[] = { ++ "vin1_data8", ++ "vin1_data10", ++ "vin1_data12", ++ "vin1_sync", ++ "vin1_field", ++ "vin1_clkenb", ++ "vin1_clk", ++}; ++ ++static const struct sh_pfc_function pinmux_functions[] = { ++ SH_PFC_FUNCTION(avb), ++ SH_PFC_FUNCTION(gether), ++ SH_PFC_FUNCTION(canfd0), ++ SH_PFC_FUNCTION(canfd1), ++ SH_PFC_FUNCTION(du), ++ SH_PFC_FUNCTION(hscif0), ++ SH_PFC_FUNCTION(hscif1), ++ SH_PFC_FUNCTION(hscif2), ++ SH_PFC_FUNCTION(hscif3), ++ SH_PFC_FUNCTION(scif_clk), ++ SH_PFC_FUNCTION(i2c0), ++ SH_PFC_FUNCTION(i2c1), ++ SH_PFC_FUNCTION(i2c2), ++ SH_PFC_FUNCTION(i2c3), ++ SH_PFC_FUNCTION(i2c4), ++ SH_PFC_FUNCTION(i2c5), ++ SH_PFC_FUNCTION(intc_ex), ++ SH_PFC_FUNCTION(msiof0), ++ SH_PFC_FUNCTION(msiof1), ++ SH_PFC_FUNCTION(msiof2), ++ SH_PFC_FUNCTION(msiof3), ++ SH_PFC_FUNCTION(tpu), ++ SH_PFC_FUNCTION(pwm0), ++ SH_PFC_FUNCTION(pwm1), ++ SH_PFC_FUNCTION(pwm2), ++ SH_PFC_FUNCTION(pwm3), ++ SH_PFC_FUNCTION(pwm4), ++ SH_PFC_FUNCTION(scif0), ++ SH_PFC_FUNCTION(scif1), ++ SH_PFC_FUNCTION(scif3), ++ SH_PFC_FUNCTION(scif4), ++ SH_PFC_FUNCTION(mmc), ++ SH_PFC_FUNCTION(tmu), ++ SH_PFC_FUNCTION(vin0), ++ SH_PFC_FUNCTION(vin1), ++}; ++ ++static const struct pinmux_cfg_reg pinmux_config_regs[] = { ++#define F_(x, y) FN_##y ++#define FM(x) FN_##x ++ { PINMUX_CFG_REG("GPSR0", 0xe6060100, 32, 1) { ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ GP_0_21_FN, GPSR0_21, ++ GP_0_20_FN, GPSR0_20, ++ GP_0_19_FN, GPSR0_19, ++ GP_0_18_FN, GPSR0_18, ++ GP_0_17_FN, GPSR0_17, ++ GP_0_16_FN, GPSR0_16, ++ GP_0_15_FN, GPSR0_15, ++ GP_0_14_FN, GPSR0_14, ++ GP_0_13_FN, GPSR0_13, ++ GP_0_12_FN, GPSR0_12, ++ GP_0_11_FN, GPSR0_11, ++ GP_0_10_FN, GPSR0_10, ++ GP_0_9_FN, GPSR0_9, ++ GP_0_8_FN, GPSR0_8, ++ GP_0_7_FN, GPSR0_7, ++ GP_0_6_FN, GPSR0_6, ++ GP_0_5_FN, GPSR0_5, ++ GP_0_4_FN, GPSR0_4, ++ GP_0_3_FN, GPSR0_3, ++ GP_0_2_FN, GPSR0_2, ++ GP_0_1_FN, GPSR0_1, ++ GP_0_0_FN, GPSR0_0, } ++ }, ++ { PINMUX_CFG_REG("GPSR1", 0xe6060104, 32, 1) { ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ GP_1_27_FN, GPSR1_27, ++ GP_1_26_FN, GPSR1_26, ++ GP_1_25_FN, GPSR1_25, ++ GP_1_24_FN, GPSR1_24, ++ GP_1_23_FN, GPSR1_23, ++ GP_1_22_FN, GPSR1_22, ++ GP_1_21_FN, GPSR1_21, ++ GP_1_20_FN, GPSR1_20, ++ GP_1_19_FN, GPSR1_19, ++ GP_1_18_FN, GPSR1_18, ++ GP_1_17_FN, GPSR1_17, ++ GP_1_16_FN, GPSR1_16, ++ GP_1_15_FN, GPSR1_15, ++ GP_1_14_FN, GPSR1_14, ++ GP_1_13_FN, GPSR1_13, ++ GP_1_12_FN, GPSR1_12, ++ GP_1_11_FN, GPSR1_11, ++ GP_1_10_FN, GPSR1_10, ++ GP_1_9_FN, GPSR1_9, ++ GP_1_8_FN, GPSR1_8, ++ GP_1_7_FN, GPSR1_7, ++ GP_1_6_FN, GPSR1_6, ++ GP_1_5_FN, GPSR1_5, ++ GP_1_4_FN, GPSR1_4, ++ GP_1_3_FN, GPSR1_3, ++ GP_1_2_FN, GPSR1_2, ++ GP_1_1_FN, GPSR1_1, ++ GP_1_0_FN, GPSR1_0, } ++ }, ++ { PINMUX_CFG_REG("GPSR2", 0xe6060108, 32, 1) { ++ 0, 0, ++ 0, 0, ++ GP_2_29_FN, GPSR2_29, ++ GP_2_28_FN, GPSR2_28, ++ GP_2_27_FN, GPSR2_27, ++ GP_2_26_FN, GPSR2_26, ++ GP_2_25_FN, GPSR2_25, ++ GP_2_24_FN, GPSR2_24, ++ GP_2_23_FN, GPSR2_23, ++ GP_2_22_FN, GPSR2_22, ++ GP_2_21_FN, GPSR2_21, ++ GP_2_20_FN, GPSR2_20, ++ GP_2_19_FN, GPSR2_19, ++ GP_2_18_FN, GPSR2_18, ++ GP_2_17_FN, GPSR2_17, ++ GP_2_16_FN, GPSR2_16, ++ GP_2_15_FN, GPSR2_15, ++ GP_2_14_FN, GPSR2_14, ++ GP_2_13_FN, GPSR2_13, ++ GP_2_12_FN, GPSR2_12, ++ GP_2_11_FN, GPSR2_11, ++ GP_2_10_FN, GPSR2_10, ++ GP_2_9_FN, GPSR2_9, ++ GP_2_8_FN, GPSR2_8, ++ GP_2_7_FN, GPSR2_7, ++ GP_2_6_FN, GPSR2_6, ++ GP_2_5_FN, GPSR2_5, ++ GP_2_4_FN, GPSR2_4, ++ GP_2_3_FN, GPSR2_3, ++ GP_2_2_FN, GPSR2_2, ++ GP_2_1_FN, GPSR2_1, ++ GP_2_0_FN, GPSR2_0, } ++ }, ++ { PINMUX_CFG_REG("GPSR3", 0xe606010c, 32, 1) { ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ GP_3_16_FN, GPSR3_16, ++ GP_3_15_FN, GPSR3_15, ++ GP_3_14_FN, GPSR3_14, ++ GP_3_13_FN, GPSR3_13, ++ GP_3_12_FN, GPSR3_12, ++ GP_3_11_FN, GPSR3_11, ++ GP_3_10_FN, GPSR3_10, ++ GP_3_9_FN, GPSR3_9, ++ GP_3_8_FN, GPSR3_8, ++ GP_3_7_FN, GPSR3_7, ++ GP_3_6_FN, GPSR3_6, ++ GP_3_5_FN, GPSR3_5, ++ GP_3_4_FN, GPSR3_4, ++ GP_3_3_FN, GPSR3_3, ++ GP_3_2_FN, GPSR3_2, ++ GP_3_1_FN, GPSR3_1, ++ GP_3_0_FN, GPSR3_0, } ++ }, ++ { PINMUX_CFG_REG("GPSR4", 0xe6060110, 32, 1) { ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ GP_4_24_FN, GPSR4_24, ++ GP_4_23_FN, GPSR4_23, ++ GP_4_22_FN, GPSR4_22, ++ GP_4_21_FN, GPSR4_21, ++ GP_4_20_FN, GPSR4_20, ++ GP_4_19_FN, GPSR4_19, ++ GP_4_18_FN, GPSR4_18, ++ GP_4_17_FN, GPSR4_17, ++ GP_4_16_FN, GPSR4_16, ++ GP_4_15_FN, GPSR4_15, ++ GP_4_14_FN, GPSR4_14, ++ GP_4_13_FN, GPSR4_13, ++ GP_4_12_FN, GPSR4_12, ++ GP_4_11_FN, GPSR4_11, ++ GP_4_10_FN, GPSR4_10, ++ GP_4_9_FN, GPSR4_9, ++ GP_4_8_FN, GPSR4_8, ++ GP_4_7_FN, GPSR4_7, ++ GP_4_6_FN, GPSR4_6, ++ GP_4_5_FN, GPSR4_5, ++ GP_4_4_FN, GPSR4_4, ++ GP_4_3_FN, GPSR4_3, ++ GP_4_2_FN, GPSR4_2, ++ GP_4_1_FN, GPSR4_1, ++ GP_4_0_FN, GPSR4_0, } ++ }, ++ { PINMUX_CFG_REG("GPSR5", 0xe6060114, 32, 1) { ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ GP_5_14_FN, GPSR5_14, ++ GP_5_13_FN, GPSR5_13, ++ GP_5_12_FN, GPSR5_12, ++ GP_5_11_FN, GPSR5_11, ++ GP_5_10_FN, GPSR5_10, ++ GP_5_9_FN, GPSR5_9, ++ GP_5_8_FN, GPSR5_8, ++ GP_5_7_FN, GPSR5_7, ++ GP_5_6_FN, GPSR5_6, ++ GP_5_5_FN, GPSR5_5, ++ GP_5_4_FN, GPSR5_4, ++ GP_5_3_FN, GPSR5_3, ++ GP_5_2_FN, GPSR5_2, ++ GP_5_1_FN, GPSR5_1, ++ GP_5_0_FN, GPSR5_0, } ++ }, ++#undef F_ ++#undef FM ++ ++#define F_(x, y) x, ++#define FM(x) FN_##x, ++ { PINMUX_CFG_REG("IPSR0", 0xe6060200, 32, 4) { ++ IP0_31_28 ++ IP0_27_24 ++ IP0_23_20 ++ IP0_19_16 ++ IP0_15_12 ++ IP0_11_8 ++ IP0_7_4 ++ IP0_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR1", 0xe6060204, 32, 4) { ++ IP1_31_28 ++ IP1_27_24 ++ IP1_23_20 ++ IP1_19_16 ++ IP1_15_12 ++ IP1_11_8 ++ IP1_7_4 ++ IP1_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR2", 0xe6060208, 32, 4) { ++ IP2_31_28 ++ IP2_27_24 ++ IP2_23_20 ++ IP2_19_16 ++ IP2_15_12 ++ IP2_11_8 ++ IP2_7_4 ++ IP2_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR3", 0xe606020c, 32, 4) { ++ IP3_31_28 ++ IP3_27_24 ++ IP3_23_20 ++ IP3_19_16 ++ IP3_15_12 ++ IP3_11_8 ++ IP3_7_4 ++ IP3_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR4", 0xe6060210, 32, 4) { ++ IP4_31_28 ++ IP4_27_24 ++ IP4_23_20 ++ IP4_19_16 ++ IP4_15_12 ++ IP4_11_8 ++ IP4_7_4 ++ IP4_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR5", 0xe6060214, 32, 4) { ++ IP5_31_28 ++ IP5_27_24 ++ IP5_23_20 ++ IP5_19_16 ++ IP5_15_12 ++ IP5_11_8 ++ IP5_7_4 ++ IP5_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR6", 0xe6060218, 32, 4) { ++ IP6_31_28 ++ IP6_27_24 ++ IP6_23_20 ++ IP6_19_16 ++ IP6_15_12 ++ IP6_11_8 ++ IP6_7_4 ++ IP6_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR7", 0xe606021c, 32, 4) { ++ IP7_31_28 ++ IP7_27_24 ++ IP7_23_20 ++ IP7_19_16 ++ IP7_15_12 ++ IP7_11_8 ++ IP7_7_4 ++ IP7_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR8", 0xe6060220, 32, 4) { ++ IP8_31_28 ++ IP8_27_24 ++ IP8_23_20 ++ IP8_19_16 ++ IP8_15_12 ++ IP8_11_8 ++ IP8_7_4 ++ IP8_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR9", 0xe6060224, 32, 4) { ++ IP8_31_28 ++ IP8_27_24 ++ IP8_23_20 ++ IP8_19_16 ++ IP8_15_12 ++ IP8_11_8 ++ IP8_7_4 ++ IP8_3_0 } ++ }, ++ { PINMUX_CFG_REG("IPSR10", 0xe6060228, 32, 4) { ++ IP8_31_28 ++ IP8_27_24 ++ IP8_23_20 ++ IP8_19_16 ++ IP8_15_12 ++ IP8_11_8 ++ IP8_7_4 ++ IP8_3_0 } ++ }, ++#undef F_ ++#undef FM ++ ++#define F_(x, y) x, ++#define FM(x) FN_##x, ++ { PINMUX_CFG_REG("MOD_SEL0", 0xe6060500, 32, 1) { ++ /* RESERVED 31..12 */ ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ MOD_SEL0_11 ++ MOD_SEL0_10 ++ MOD_SEL0_9 ++ MOD_SEL0_8 ++ MOD_SEL0_7 ++ MOD_SEL0_6 ++ MOD_SEL0_5 ++ MOD_SEL0_4 ++ 0, 0, ++ MOD_SEL0_2 ++ MOD_SEL0_1 ++ MOD_SEL0_0 } ++ }, ++ { }, ++}; ++ ++#define POC0 0xe6060380 ++#define POC1 0xe6060384 ++#define POC2 0xe6060388 ++ ++/* TODO make it nice */ ++static int r8a7798_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl) ++{ ++ int bit = -EINVAL; ++ ++ *pocctrl = POC0; ++ ++ if (pin >= RCAR_GP_PIN(0, 0) && pin <= RCAR_GP_PIN(0, 21)) ++ bit = pin & 0x1f; ++ else if (pin >= RCAR_GP_PIN(2, 0) && pin <= RCAR_GP_PIN(2, 9)) ++ bit = (pin & 0x1f) + 22; ++ ++ if (bit != -EINVAL) ++ goto out; ++ ++ *pocctrl = POC1; ++ ++ if (pin >= RCAR_GP_PIN(2, 10) && pin <= RCAR_GP_PIN(2, 16)) ++ bit = (pin & 0x1f) - 10; ++ else if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 16)) ++ bit = (pin & 0x1f) + 7; ++ else if (pin >= RCAR_GP_PIN(2, 17) && pin <= RCAR_GP_PIN(2, 24)) ++ bit = (pin & 0x1f) + 7; ++ ++ if (bit != -EINVAL) ++ goto out; ++ ++ *pocctrl = POC2; ++ ++ if (pin >= RCAR_GP_PIN(2, 25) && pin <= RCAR_GP_PIN(2, 29)) ++ bit = (pin & 0x1f) - 25; ++ ++out: ++ return bit; ++} ++ ++static const struct sh_pfc_soc_operations pinmux_ops = { ++ .pin_to_pocctrl = r8a7798_pin_to_pocctrl, ++}; ++ ++const struct sh_pfc_soc_info r8a7798_pinmux_info = { ++ .name = "r8a77980_pfc", ++ .ops = &pinmux_ops, ++ .unlock_reg = 0xe6060000, /* PMMR */ ++ ++ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, ++ ++ .pins = pinmux_pins, ++ .nr_pins = ARRAY_SIZE(pinmux_pins), ++ .groups = pinmux_groups, ++ .nr_groups = ARRAY_SIZE(pinmux_groups), ++ .functions = pinmux_functions, ++ .nr_functions = ARRAY_SIZE(pinmux_functions), ++ ++ .cfg_regs = pinmux_config_regs, ++ ++ .pinmux_data = pinmux_data, ++ .pinmux_data_size = ARRAY_SIZE(pinmux_data), ++}; +diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h +index 062af89..eaf052d 100644 +--- a/drivers/pinctrl/sh-pfc/sh_pfc.h ++++ b/drivers/pinctrl/sh-pfc/sh_pfc.h +@@ -289,6 +289,7 @@ struct sh_pfc_soc_info { + extern const struct sh_pfc_soc_info r8a7796_pinmux_info; + extern const struct sh_pfc_soc_info r8a77965_pinmux_info; + extern const struct sh_pfc_soc_info r8a7797_pinmux_info; ++extern const struct sh_pfc_soc_info r8a7798_pinmux_info; + extern const struct sh_pfc_soc_info sh7203_pinmux_info; + extern const struct sh_pfc_soc_info sh7264_pinmux_info; + extern const struct sh_pfc_soc_info sh7269_pinmux_info; +@@ -465,9 +466,13 @@ struct sh_pfc_soc_info { + PORT_GP_CFG_1(bank, 23, fn, sfx, cfg) + #define PORT_GP_24(bank, fn, sfx) PORT_GP_CFG_24(bank, fn, sfx, 0) + +-#define PORT_GP_CFG_26(bank, fn, sfx, cfg) \ ++#define PORT_GP_CFG_25(bank, fn, sfx, cfg) \ + PORT_GP_CFG_24(bank, fn, sfx, cfg), \ +- PORT_GP_CFG_1(bank, 24, fn, sfx, cfg), \ ++ PORT_GP_CFG_1(bank, 24, fn, sfx, cfg) ++#define PORT_GP_24(bank, fn, sfx) PORT_GP_CFG_24(bank, fn, sfx, 0) ++ ++#define PORT_GP_CFG_26(bank, fn, sfx, cfg) \ ++ PORT_GP_CFG_25(bank, fn, sfx, cfg), \ + PORT_GP_CFG_1(bank, 25, fn, sfx, cfg) + #define PORT_GP_26(bank, fn, sfx) PORT_GP_CFG_26(bank, fn, sfx, 0) + +diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile +index 2ba6a76..164b3e7 100644 +--- a/drivers/soc/renesas/Makefile ++++ b/drivers/soc/renesas/Makefile +@@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_R8A7795) += rcar-rst.o + obj-$(CONFIG_ARCH_R8A7796) += rcar-rst.o + obj-$(CONFIG_ARCH_R8A77965) += rcar-rst.o + obj-$(CONFIG_ARCH_R8A7797) += rcar-rst.o ++obj-$(CONFIG_ARCH_R8A7798) += rcar-rst.o + + obj-$(CONFIG_ARCH_R8A7743) += rcar-sysc.o r8a7743-sysc.o + obj-$(CONFIG_ARCH_R8A7745) += rcar-sysc.o r8a7745-sysc.o +@@ -20,15 +21,18 @@ obj-$(CONFIG_ARCH_R8A7795) += rcar-sysc.o r8a7795-sysc.o + obj-$(CONFIG_ARCH_R8A7796) += rcar-sysc.o r8a7796-sysc.o + obj-$(CONFIG_ARCH_R8A77965) += rcar-sysc.o r8a77965-sysc.o + obj-$(CONFIG_ARCH_R8A7797) += rcar-sysc.o r8a7797-sysc.o ++obj-$(CONFIG_ARCH_R8A7798) += rcar-sysc.o r8a7798-sysc.o + + obj-$(CONFIG_ARCH_R8A7795) += rcar-avs.o + obj-$(CONFIG_ARCH_R8A7796) += rcar-avs.o + obj-$(CONFIG_ARCH_R8A77965) += rcar-avs.o + obj-$(CONFIG_ARCH_R8A7797) += rcar-avs.o ++obj-$(CONFIG_ARCH_R8A7798) += rcar-avs.o + # EMS for R-Car Gen3 + obj-$(CONFIG_ARCH_R8A7795) += rcar_ems_ctrl.o + obj-$(CONFIG_ARCH_R8A7796) += rcar_ems_ctrl.o + obj-$(CONFIG_ARCH_R8A77965) += rcar_ems_ctrl.o + obj-$(CONFIG_ARCH_R8A7797) += rcar_ems_ctrl.o ++obj-$(CONFIG_ARCH_R8A7798) += rcar_ems_ctrl.o + + obj-$(CONFIG_RCAR_DDR_BACKUP) += s2ram_ddr_backup.o +diff --git a/drivers/soc/renesas/r8a7798-sysc.c b/drivers/soc/renesas/r8a7798-sysc.c +new file mode 100644 +index 0000000..128e79d +--- /dev/null ++++ b/drivers/soc/renesas/r8a7798-sysc.c +@@ -0,0 +1,57 @@ ++/* ++ * Renesas R-Car V3H System Controller ++ * ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ */ ++ ++#include <linux/bug.h> ++#include <linux/kernel.h> ++ ++#include <dt-bindings/power/r8a7798-sysc.h> ++ ++#include "rcar-sysc.h" ++ ++static const struct rcar_sysc_area r8a7798_areas[] __initconst = { ++ { "always-on", 0, 0, R8A7798_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, ++ { "ca53-scu", 0x140, 0, R8A7798_PD_CA53_SCU, R8A7798_PD_ALWAYS_ON, ++ PD_SCU }, ++ { "ca53-cpu0", 0x200, 0, R8A7798_PD_CA53_CPU0, R8A7798_PD_CA53_SCU, ++ PD_CPU_NOCR }, ++ { "ca53-cpu1", 0x200, 1, R8A7798_PD_CA53_CPU1, R8A7798_PD_CA53_SCU, ++ PD_CPU_NOCR }, ++ { "ca53-cpu2", 0x200, 2, R8A7798_PD_CA53_CPU2, R8A7798_PD_CA53_SCU, ++ PD_CPU_NOCR }, ++ { "ca53-cpu3", 0x200, 3, R8A7798_PD_CA53_CPU3, R8A7798_PD_CA53_SCU, ++ PD_CPU_NOCR }, ++ { "cr7", 0x240, 0, R8A7798_PD_CR7, R8A7798_PD_ALWAYS_ON }, ++ ++ { "a3ir", 0x180, 0, R8A7798_PD_A3IR, R8A7798_PD_ALWAYS_ON }, ++ { "a2ir0", 0x400, 0, R8A7798_PD_A2IR0, R8A7798_PD_A3IR }, ++ { "a2ir1", 0x400, 1, R8A7798_PD_A2IR1, R8A7798_PD_A3IR }, ++ { "a2ir2", 0x400, 2, R8A7798_PD_A2IR2, R8A7798_PD_A3IR }, ++ { "a2ir3", 0x400, 3, R8A7798_PD_A2IR3, R8A7798_PD_A3IR }, ++ { "a2ir4", 0x400, 4, R8A7798_PD_A2IR4, R8A7798_PD_A3IR }, ++ { "a2ir5", 0x400, 5, R8A7798_PD_A2IR5, R8A7798_PD_A3IR }, ++ { "a2sc0", 0x400, 6, R8A7798_PD_A2SC0, R8A7798_PD_A3IR }, ++ { "a2sc1", 0x400, 7, R8A7798_PD_A2SC1, R8A7798_PD_A3IR }, ++ { "a2sc2", 0x400, 8, R8A7798_PD_A2SC2, R8A7798_PD_A3IR }, ++ { "a2sc3", 0x400, 9, R8A7798_PD_A2SC3, R8A7798_PD_A3IR }, ++ { "a2sc4", 0x400, 10, R8A7798_PD_A2SC4, R8A7798_PD_A3IR }, ++ { "a2pd0", 0x400, 11, R8A7798_PD_A2PD0, R8A7798_PD_A3IR }, ++ { "a2pd1", 0x400, 12, R8A7798_PD_A2PD1, R8A7798_PD_A3IR }, ++ { "a2cn", 0x400, 13, R8A7798_PD_A2CN, R8A7798_PD_A3IR }, ++ ++ { "a3vip", 0x2c0, 0, R8A7798_PD_A3VIP, R8A7798_PD_ALWAYS_ON }, ++ { "a3vip1", 0x300, 0, R8A7798_PD_A3VIP1, R8A7798_PD_ALWAYS_ON }, ++ { "a3vip2", 0x280, 0, R8A7798_PD_A3VIP2, R8A7798_PD_ALWAYS_ON }, ++}; ++ ++const struct rcar_sysc_info r8a7798_sysc_info __initconst = { ++ .areas = r8a7798_areas, ++ .num_areas = ARRAY_SIZE(r8a7798_areas), ++}; +diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c +index bc3632b..8906817 100644 +--- a/drivers/soc/renesas/rcar-rst.c ++++ b/drivers/soc/renesas/rcar-rst.c +@@ -43,6 +43,7 @@ struct rst_config { + { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 }, + { .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen2 }, + { .compatible = "renesas,r8a7797-rst", .data = &rcar_rst_gen2 }, ++ { .compatible = "renesas,r8a7798-rst", .data = &rcar_rst_gen2 }, + { /* sentinel */ } + }; + +diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c +index 1d5d440..bfde184 100644 +--- a/drivers/soc/renesas/rcar-sysc.c ++++ b/drivers/soc/renesas/rcar-sysc.c +@@ -327,6 +327,9 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd) + #ifdef CONFIG_ARCH_R8A7797 + { .compatible = "renesas,r8a7797-sysc", .data = &r8a7797_sysc_info }, + #endif ++#ifdef CONFIG_ARCH_R8A7798 ++ { .compatible = "renesas,r8a7798-sysc", .data = &r8a7798_sysc_info }, ++#endif + { /* sentinel */ } + }; + +diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h +index 1eb4e6d..dc58a58 100644 +--- a/drivers/soc/renesas/rcar-sysc.h ++++ b/drivers/soc/renesas/rcar-sysc.h +@@ -62,4 +62,5 @@ struct rcar_sysc_info { + extern const struct rcar_sysc_info r8a7796_sysc_info; + extern const struct rcar_sysc_info r8a77965_sysc_info; + extern const struct rcar_sysc_info r8a7797_sysc_info; ++extern const struct rcar_sysc_info r8a7798_sysc_info; + #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */ +diff --git a/drivers/soc/renesas/rcar_ems_ctrl.c b/drivers/soc/renesas/rcar_ems_ctrl.c +index 388c570..516858d 100644 +--- a/drivers/soc/renesas/rcar_ems_ctrl.c ++++ b/drivers/soc/renesas/rcar_ems_ctrl.c +@@ -30,8 +30,9 @@ + + #define EMS_THERMAL_ZONE_MAX 10 + +-static const struct soc_device_attribute r8a7797[] = { ++static const struct soc_device_attribute r8a7797_8[] = { + { .soc_id = "r8a7797" }, ++ { .soc_id = "r8a7798" }, + { } + }; + +@@ -274,7 +275,7 @@ static int __init rcar_ems_cpu_shutdown_init(void) + + for_each_online_cpu(cpu) { + tmp_node = of_get_cpu_node(cpu, NULL); +- if (soc_device_match(r8a7797)) { ++ if (soc_device_match(r8a7797_8)) { + if (!of_device_is_compatible(tmp_node, "arm,cortex-a53")) + continue; + } +diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c +index 63f943d..b1fcae1 100644 +--- a/drivers/soc/renesas/renesas-soc.c ++++ b/drivers/soc/renesas/renesas-soc.c +@@ -144,6 +144,11 @@ struct renesas_soc { + .id = 0x54, + }; + ++static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = { ++ .family = &fam_rcar_gen3, ++ .id = 0x56, ++}; ++ + static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = { + .family = &fam_shmobile, + .id = 0x37, +@@ -199,6 +204,9 @@ struct renesas_soc { + #ifdef CONFIG_ARCH_R8A7797 + { .compatible = "renesas,r8a7797", .data = &soc_rcar_v3m }, + #endif ++#ifdef CONFIG_ARCH_R8A7798 ++ { .compatible = "renesas,r8a7798", .data = &soc_rcar_v3h }, ++#endif + #ifdef CONFIG_ARCH_SH73A0 + { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 }, + #endif +diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c +index 1488964..9ae47e5 100644 +--- a/drivers/spi/spi-sh-msiof.c ++++ b/drivers/spi/spi-sh-msiof.c +@@ -217,7 +217,8 @@ static int msiof_rcar_is_gen3(struct device *dev) + return of_device_is_compatible(node, "renesas,msiof-r8a7795") || + of_device_is_compatible(node, "renesas,msiof-r8a7796") || + of_device_is_compatible(node, "renesas,msiof-r8a77965") || +- of_device_is_compatible(node, "renesas,msiof-r8a7797"); ++ of_device_is_compatible(node, "renesas,msiof-r8a7797") || ++ of_device_is_compatible(node, "renesas,msiof-r8a7798"); + } + + static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) +@@ -1192,6 +1193,7 @@ static int sh_msiof_transfer_one(struct spi_master *master, + { .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data }, + { .compatible = "renesas,msiof-r8a77965", .data = &r8a779x_data }, + { .compatible = "renesas,msiof-r8a7797", .data = &r8a779x_data }, ++ { .compatible = "renesas,msiof-r8a7798", .data = &r8a779x_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, sh_msiof_match); +diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c +index a23dd44..90978c2 100644 +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -415,6 +415,11 @@ static int rcar_gen3_r8a7797_thermal_init(struct rcar_thermal_priv *priv) + return 0; + } + ++static int rcar_gen3_r8a7798_thermal_init(struct rcar_thermal_priv *priv) ++{ ++ return rcar_gen3_r8a7796_thermal_init(priv); ++} ++ + /* + * Interrupt + */ +@@ -500,11 +505,16 @@ static int rcar_gen3_thermal_remove(struct platform_device *pdev) + .thermal_init = rcar_gen3_r8a7797_thermal_init, + }; + ++static const struct rcar_thermal_data r8a7798_data = { ++ .thermal_init = rcar_gen3_r8a7798_thermal_init, ++}; ++ + static const struct of_device_id rcar_thermal_dt_ids[] = { + { .compatible = "renesas,thermal-r8a7795", .data = &r8a7795_data}, + { .compatible = "renesas,thermal-r8a7796", .data = &r8a7796_data}, + { .compatible = "renesas,thermal-r8a77965", .data = &r8a7796_data}, + { .compatible = "renesas,thermal-r8a7797", .data = &r8a7797_data}, ++ { .compatible = "renesas,thermal-r8a7798", .data = &r8a7798_data}, + {}, + }; + MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); +diff --git a/include/dt-bindings/clock/r8a7798-cpg-mssr.h b/include/dt-bindings/clock/r8a7798-cpg-mssr.h +new file mode 100644 +index 0000000..3d85730 +--- /dev/null ++++ b/include/dt-bindings/clock/r8a7798-cpg-mssr.h +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++#ifndef __DT_BINDINGS_CLOCK_R8A7798_CPG_MSSR_H__ ++#define __DT_BINDINGS_CLOCK_R8A7798_CPG_MSSR_H__ ++ ++#include <dt-bindings/clock/renesas-cpg-mssr.h> ++ ++/* r8a7798 CPG Core Clocks */ ++#define R8A7798_CLK_Z2 0 ++#define R8A7798_CLK_ZR 1 ++#define R8A7798_CLK_ZTR 2 ++#define R8A7798_CLK_ZTRD2 3 ++#define R8A7798_CLK_ZT 4 ++#define R8A7798_CLK_ZX 5 ++#define R8A7798_CLK_S0D1 6 ++#define R8A7798_CLK_S0D2 7 ++#define R8A7798_CLK_S0D3 8 ++#define R8A7798_CLK_S0D4 9 ++#define R8A7798_CLK_S0D6 10 ++#define R8A7798_CLK_S0D12 11 ++#define R8A7798_CLK_S0D24 12 ++#define R8A7798_CLK_S1D1 13 ++#define R8A7798_CLK_S1D2 14 ++#define R8A7798_CLK_S1D4 15 ++#define R8A7798_CLK_S2D1 16 ++#define R8A7798_CLK_S2D2 17 ++#define R8A7798_CLK_S2D4 18 ++#define R8A7798_CLK_S3D1 19 ++#define R8A7798_CLK_S3D2 20 ++#define R8A7798_CLK_S3D4 21 ++#define R8A7798_CLK_LB 22 ++#define R8A7798_CLK_CL 23 ++#define R8A7798_CLK_ZB3 24 ++#define R8A7798_CLK_ZB3D2 25 ++#define R8A7798_CLK_ZB3D4 26 ++#define R8A7798_CLK_SD0H 27 ++#define R8A7798_CLK_SD0 28 ++#define R8A7798_CLK_RPC 29 ++#define R8A7798_CLK_RPCD2 30 ++#define R8A7798_CLK_MSO 31 ++#define R8A7798_CLK_CANFD 32 ++#define R8A7798_CLK_CSI0 33 ++#define R8A7798_CLK_CSIREF 34 ++#define R8A7798_CLK_CP 35 ++#define R8A7798_CLK_CPEX 36 ++#define R8A7798_CLK_R 37 ++#define R8A7798_CLK_OSC 38 ++ ++#endif /* __DT_BINDINGS_CLOCK_R8A7798_CPG_MSSR_H__ */ +diff --git a/include/dt-bindings/power/r8a7798-sysc.h b/include/dt-bindings/power/r8a7798-sysc.h +new file mode 100644 +index 0000000..c10d60e +--- /dev/null ++++ b/include/dt-bindings/power/r8a7798-sysc.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2018 Renesas Electronics Corp. ++ * Copyright (C) 2018 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ */ ++#ifndef __DT_BINDINGS_POWER_R8A7798_SYSC_H__ ++#define __DT_BINDINGS_POWER_R8A7798_SYSC_H__ ++ ++/* ++ * These power domain indices match the numbers of the interrupt bits ++ * representing the power areas in the various Interrupt Registers ++ * (e.g. SYSCISR, Interrupt Status Register) ++ */ ++ ++#define R8A7798_PD_A2SC2 0 ++#define R8A7798_PD_A2SC3 1 ++#define R8A7798_PD_A2SC4 2 ++#define R8A7798_PD_A2PD0 3 ++#define R8A7798_PD_A2PD1 4 ++#define R8A7798_PD_CA53_CPU0 5 ++#define R8A7798_PD_CA53_CPU1 6 ++#define R8A7798_PD_CA53_CPU2 7 ++#define R8A7798_PD_CA53_CPU3 8 ++#define R8A7798_PD_A2CN 10 ++#define R8A7798_PD_A3VIP 11 ++#define R8A7798_PD_A2IR5 12 ++#define R8A7798_PD_CR7 13 ++#define R8A7798_PD_A2IR4 15 ++#define R8A7798_PD_CA53_SCU 21 ++#define R8A7798_PD_A2IR0 23 ++#define R8A7798_PD_A3IR 24 ++#define R8A7798_PD_A3VIP1 25 ++#define R8A7798_PD_A3VIP2 26 ++#define R8A7798_PD_A2IR1 27 ++#define R8A7798_PD_A2IR2 28 ++#define R8A7798_PD_A2IR3 29 ++#define R8A7798_PD_A2SC0 30 ++#define R8A7798_PD_A2SC1 31 ++ ++/* Always-on power area */ ++#define R8A7798_PD_ALWAYS_ON 32 ++ ++#endif /* __DT_BINDINGS_POWER_R8A7798_SYSC_H__ */ +-- +1.9.1 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch deleted file mode 100644 index 2c4d9f3..0000000 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch +++ /dev/null @@ -1,527 +0,0 @@ -From fa7c75c71d40c8ce44b0fbaea79031daaede2ba7 Mon Sep 17 00:00:00 2001 -From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> -Date: Mon, 15 May 2017 19:24:29 +0300 -Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE2 first 4 cameras - -This set 4 cameras to TYPE2 in DT - -Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> ---- - arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 17 +++++++++++++++-- - arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 17 +++++++++++++++-- - .../boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 17 +++++++++++++++-- - arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 17 +++++++++++++++-- - arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 17 +++++++++++++++-- - arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 17 +++++++++++++++-- - arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 17 +++++++++++++++-- - arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 17 +++++++++++++++-- - arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts | 17 +++++++++++++++-- - 9 files changed, 135 insertions(+), 18 deletions(-) - -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -index 50a37e0..8808e80 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts -@@ -609,6 +609,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -633,6 +636,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -657,6 +663,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -678,6 +687,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -773,8 +785,9 @@ - maxim,sensor_delay = <350>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - - port@0 { -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -index de56fa4..007aa7a 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts -@@ -20,6 +20,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -38,6 +41,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -56,6 +62,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -74,6 +83,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -167,8 +179,9 @@ - maxim,sensor_delay = <0>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - maxim,i2c-quirk = <0x6c>; - -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -index 3f3d66a..4b3513a 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts -@@ -35,6 +35,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -53,6 +56,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -71,6 +77,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -89,6 +98,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -182,8 +194,9 @@ - maxim,sensor_delay = <0>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - maxim,i2c-quirk = <0x6c>; - -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -index 94c86f6..e650c5b 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts -@@ -609,6 +609,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -633,6 +636,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -657,6 +663,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -678,6 +687,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -773,8 +785,9 @@ - maxim,sensor_delay = <350>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - - port@0 { -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -index 2c24b85..ac0723d 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts -@@ -20,6 +20,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -38,6 +41,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -56,6 +62,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -74,6 +83,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -167,8 +179,9 @@ - maxim,sensor_delay = <0>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - maxim,i2c-quirk = <0x6c>; - -diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -index fb12a39f3..ef0895e 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts -@@ -35,6 +35,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -53,6 +56,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -71,6 +77,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -89,6 +98,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -182,8 +194,9 @@ - maxim,sensor_delay = <0>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - maxim,i2c-quirk = <0x6c>; - -diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts -index ffaef74..5670f3a 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts -@@ -609,6 +609,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -633,6 +636,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -657,6 +663,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -678,6 +687,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -773,8 +785,9 @@ - maxim,sensor_delay = <350>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - - port@0 { -diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts -index 1ac0041..8a67c5f 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts -@@ -20,6 +20,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -38,6 +41,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -56,6 +62,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -74,6 +83,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -95,8 +107,9 @@ - maxim,sensor_delay = <0>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - maxim,i2c-quirk = <0x6c>; - -diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts -index cc6866c..ab6e28a 100644 ---- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts -+++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts -@@ -35,6 +35,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x60>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in0: endpoint { - clock-lanes = <0>; -@@ -53,6 +56,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x61>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in1: endpoint { - clock-lanes = <0>; -@@ -71,6 +77,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x62>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in2: endpoint { - clock-lanes = <0>; -@@ -89,6 +98,9 @@ - compatible = "ovti,ov106xx"; - reg = <0x63>; - -+ maxim,fixed-sensor = "ov490"; -+ maxim,width = <1280>; -+ maxim,height = <966>; - port@0 { - ov106xx_in3: endpoint { - clock-lanes = <0>; -@@ -110,8 +122,9 @@ - maxim,sensor_delay = <0>; - maxim,links = <4>; - maxim,lanes = <4>; -- maxim,resetb-gpio = <1>; -- maxim,fsync-mode = "automatic"; -+ maxim,resetb-gpio = <4>; -+ maxim,resetb-active-high; -+ maxim,fsync-mode = "manual"; - maxim,timeout = <100>; - maxim,i2c-quirk = <0x6c>; - --- -1.9.1 - diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch new file mode 100644 index 0000000..9cad500 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch @@ -0,0 +1,278 @@ +From 01fdcd06bd73807c03a6c8cf077fa53841861b58 Mon Sep 17 00:00:00 2001 +From: Shinyu Ninomiya <shinyu.ninomiya.pd@renesas.com> +Date: Fri, 26 Jan 2018 21:38:58 +0900 +Subject: [PATCH] soc: renesas: rcar-sysc: Add workaround for A3 PD issue + +Before turning ON/OFF power domain of A3VIP0, A3VIP1, A3VIP2 the clock is supplied for BoschIP +by deactivating MSTP assigned for BoschIP before. This issue is also occurred at A3IR. +MSTP for impdes0 and impc0 should be deactivated before turning off A3IR domain. +This implements workaround to implement the sequence above. + +Signed-off-by: Shinyu Ninomiya <shinyu.ninomiya.pd@renesas.com> +--- + drivers/soc/renesas/r8a7797-sysc.c | 3 +- + drivers/soc/renesas/r8a7798-sysc.c | 12 +++-- + drivers/soc/renesas/rcar-sysc.c | 108 ++++++++++++++++++++++++++++++++++++- + drivers/soc/renesas/rcar-sysc.h | 6 +++ + 4 files changed, 123 insertions(+), 6 deletions(-) + +diff --git a/drivers/soc/renesas/r8a7797-sysc.c b/drivers/soc/renesas/r8a7797-sysc.c +index cde7d9e..5725ad0 100644 +--- a/drivers/soc/renesas/r8a7797-sysc.c ++++ b/drivers/soc/renesas/r8a7797-sysc.c +@@ -24,7 +24,8 @@ static const struct rcar_sysc_area r8a7797_areas[] __initconst = { + { "ca53-cpu1", 0x200, 1, R8A7797_PD_CA53_CPU1, R8A7797_PD_CA53_SCU, + PD_CPU_NOCR }, + { "cr7", 0x240, 0, R8A7797_PD_CR7, R8A7797_PD_ALWAYS_ON }, +- { "a3ir", 0x180, 0, R8A7797_PD_A3IR, R8A7797_PD_ALWAYS_ON }, ++ { "a3ir", 0x180, 0, R8A7797_PD_A3IR, R8A7797_PD_ALWAYS_ON, ++ PD_WA_CLK, {"impram"} }, + { "a2ir0", 0x400, 0, R8A7797_PD_A2IR0, R8A7797_PD_A3IR }, + { "a2ir1", 0x400, 1, R8A7797_PD_A2IR1, R8A7797_PD_A3IR }, + { "a2ir2", 0x400, 2, R8A7797_PD_A2IR2, R8A7797_PD_A3IR }, +diff --git a/drivers/soc/renesas/r8a7798-sysc.c b/drivers/soc/renesas/r8a7798-sysc.c +index 128e79d..2affaa2 100644 +--- a/drivers/soc/renesas/r8a7798-sysc.c ++++ b/drivers/soc/renesas/r8a7798-sysc.c +@@ -30,7 +30,8 @@ static const struct rcar_sysc_area r8a7798_areas[] __initconst = { + PD_CPU_NOCR }, + { "cr7", 0x240, 0, R8A7798_PD_CR7, R8A7798_PD_ALWAYS_ON }, + +- { "a3ir", 0x180, 0, R8A7798_PD_A3IR, R8A7798_PD_ALWAYS_ON }, ++ { "a3ir", 0x180, 0, R8A7798_PD_A3IR, R8A7798_PD_ALWAYS_ON, ++ PD_WA_CLK, {"impram"} }, + { "a2ir0", 0x400, 0, R8A7798_PD_A2IR0, R8A7798_PD_A3IR }, + { "a2ir1", 0x400, 1, R8A7798_PD_A2IR1, R8A7798_PD_A3IR }, + { "a2ir2", 0x400, 2, R8A7798_PD_A2IR2, R8A7798_PD_A3IR }, +@@ -46,9 +47,12 @@ static const struct rcar_sysc_area r8a7798_areas[] __initconst = { + { "a2pd1", 0x400, 12, R8A7798_PD_A2PD1, R8A7798_PD_A3IR }, + { "a2cn", 0x400, 13, R8A7798_PD_A2CN, R8A7798_PD_A3IR }, + +- { "a3vip", 0x2c0, 0, R8A7798_PD_A3VIP, R8A7798_PD_ALWAYS_ON }, +- { "a3vip1", 0x300, 0, R8A7798_PD_A3VIP1, R8A7798_PD_ALWAYS_ON }, +- { "a3vip2", 0x280, 0, R8A7798_PD_A3VIP2, R8A7798_PD_ALWAYS_ON }, ++ { "a3vip", 0x2c0, 0, R8A7798_PD_A3VIP, R8A7798_PD_ALWAYS_ON, ++ PD_WA_CLK, {"disp"} }, ++ { "a3vip1", 0x300, 0, R8A7798_PD_A3VIP1, R8A7798_PD_ALWAYS_ON, ++ PD_WA_CLK, {"umf", "smd_post", "smd_est", "smd_ps"} }, ++ { "a3vip2", 0x280, 0, R8A7798_PD_A3VIP2, R8A7798_PD_ALWAYS_ON, ++ PD_WA_CLK, {"cle0", "cle1", "cle2", "cle3", "cle4"} }, + }; + + const struct rcar_sysc_info r8a7798_sysc_info __initconst = { +diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c +index bfde184..f3f18d0 100644 +--- a/drivers/soc/renesas/rcar-sysc.c ++++ b/drivers/soc/renesas/rcar-sysc.c +@@ -20,6 +20,8 @@ + #include <linux/syscore_ops.h> + #include <linux/io.h> + #include <linux/soc/renesas/rcar-sysc.h> ++#include <linux/clk.h> ++#include <linux/clk-provider.h> + + #include "rcar-sysc.h" + +@@ -64,6 +66,7 @@ static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */ + + + static const char *to_pd_name(const struct rcar_sysc_ch *sysc_ch); ++static int rcar_sysc_wa_clk(const struct rcar_sysc_ch *sysc_ch, int en); + + static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) + { +@@ -110,6 +113,12 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) + int ret = 0; + int k; + ++ ret = rcar_sysc_wa_clk(sysc_ch, 1); ++ if (ret) { ++ pr_err("%s: Failed to enable clock for workaround\n", to_pd_name(sysc_ch)); ++ return ret; ++ } ++ + spin_lock_irqsave(&rcar_sysc_lock, flags); + + iowrite32(isr_mask, rcar_sysc_base + SYSCISCR); +@@ -148,6 +157,8 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) + out: + spin_unlock_irqrestore(&rcar_sysc_lock, flags); + ++ rcar_sysc_wa_clk(sysc_ch, 0); ++ + pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off", + sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret); + return ret; +@@ -178,9 +189,35 @@ struct rcar_sysc_pd { + struct generic_pm_domain genpd; + struct rcar_sysc_ch ch; + unsigned int flags; ++ struct clk *wa_clk[RCAR_SYSC_MAX_WA_CLKS]; + char name[0]; + }; + ++static int rcar_sysc_wa_clk(const struct rcar_sysc_ch *sysc_ch, int en) ++{ ++ int i, ret; ++ struct rcar_sysc_pd *pd = container_of(sysc_ch, struct rcar_sysc_pd, ch); ++ ++ if (pd->flags & PD_WA_CLK) { ++ if (!(pd->flags & PD_WA_CLK_RDY)) ++ return -EBUSY; ++ ++ for (i = 0; i < RCAR_SYSC_MAX_WA_CLKS; i++) { ++ if (!pd->wa_clk[i]) ++ break; ++ ++ if (en) { ++ ret = clk_enable(pd->wa_clk[i]); ++ if (ret) ++ return ret; ++ } else ++ clk_disable(pd->wa_clk[i]); ++ } ++ } ++ ++ return 0; ++} ++ + static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d) + { + return container_of(d, struct rcar_sysc_pd, genpd); +@@ -231,6 +268,7 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd) + struct generic_pm_domain *genpd = &pd->genpd; + const char *name = pd->genpd.name; + struct dev_power_governor *gov = &simple_qos_governor; ++ bool is_off = false; + + if (pd->flags & PD_CPU) { + /* +@@ -278,6 +316,12 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd) + goto finalize; + } + ++ if (pd->flags & PD_NO_INIT_ON) { ++ is_off = rcar_sysc_power_is_off(&pd->ch); ++ pr_debug("%s: %s is initialy %s\n", __func__, genpd->name, is_off ? "off" : "on"); ++ goto finalize; ++ } ++ + if (!rcar_sysc_power_is_off(&pd->ch)) { + pr_debug("%s: %s is already powered\n", __func__, genpd->name); + goto finalize; +@@ -286,7 +330,7 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd) + rcar_sysc_power_up(&pd->ch); + + finalize: +- pm_genpd_init(genpd, gov, false); ++ pm_genpd_init(genpd, gov, is_off); + } + + static const struct of_device_id rcar_sysc_matches[] = { +@@ -442,6 +486,12 @@ static int __init rcar_sysc_pd_init(void) + pd->ch.isr_bit = area->isr_bit; + pd->flags = area->flags; + ++ if ((pd->flags & PD_WA_CLK) || ++ (area->parent >= 0 && (container_of(domains->domains[area->parent], ++ struct rcar_sysc_pd, genpd)->flags & PD_NO_INIT_ON)) ++ ) ++ pd->flags |= PD_NO_INIT_ON; ++ + rcar_sysc_pd_setup(pd); + if (area->parent >= 0) + pm_genpd_add_subdomain(domains->domains[area->parent], +@@ -479,6 +529,62 @@ static int __init rcar_sysc_pd_init2(void) + postcore_initcall(rcar_sysc_pd_init2); + #endif + ++#if IS_ENABLED(CONFIG_ARCH_R8A7797) || \ ++ IS_ENABLED(CONFIG_ARCH_R8A7798) ++static int __init rcar_sysc_pd_init3(void) ++{ ++ const struct rcar_sysc_info *info; ++ const struct of_device_id *match; ++ struct device_node *np; ++ unsigned int i, j; ++ ++ np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match); ++ if (!np) ++ return -ENODEV; ++ ++ info = match->data; ++ ++ for (i = 0; i < info->num_areas; i++) { ++ const struct rcar_sysc_area *area = &info->areas[i]; ++ struct rcar_sysc_pd *pd = rcar_domains[i]; ++ ++ if (pd->flags & PD_WA_CLK) { ++ int err = 0; ++ ++ for (j = 0; j < RCAR_SYSC_MAX_WA_CLKS; j++) { ++ struct clk *wa_clk; ++ const char *wa_clk_name = area->wa_clk_names[j]; ++ ++ if (!wa_clk_name) ++ break; ++ ++ wa_clk = __clk_lookup(wa_clk_name); ++ if (!wa_clk) { ++ err = -ENODEV; ++ pr_err("%s: Unable to get clock %s for workaround\n", pd->name, wa_clk_name); ++ break; ++ } ++ ++ err = clk_prepare(wa_clk); ++ if (err) { ++ pr_err("%s: Unable to prepare clock %s for workaround\n", pd->name, wa_clk_name); ++ break; ++ } ++ ++ pd->wa_clk[j] = wa_clk; ++ } ++ ++ if (!err) ++ pd->flags |= PD_WA_CLK_RDY; ++ } ++ } ++ ++ return 0; ++} ++/* Should be called after cpg_mssr_driver is initialized */ ++subsys_initcall_sync(rcar_sysc_pd_init3); ++#endif ++ + void __init rcar_sysc_init(phys_addr_t base, u32 syscier) + { + u32 syscimr; +diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h +index dc58a58..b991103 100644 +--- a/drivers/soc/renesas/rcar-sysc.h ++++ b/drivers/soc/renesas/rcar-sysc.h +@@ -23,10 +23,15 @@ + #define PD_BUSY BIT(3) /* Busy, for internal use only */ + #define PD_ON_ONCE BIT(4) /* Turned on once at boot */ + ++#define PD_WA_CLK BIT(5) /* Use clocks for workaround */ ++#define PD_WA_CLK_RDY BIT(6) /* Clock ready, for internal use only */ ++#define PD_NO_INIT_ON BIT(7) /* Do not power on at initialization, for internal use */ ++ + #define PD_CPU_CR PD_CPU /* CPU area has CR (R-Car H1) */ + #define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR (R-Car Gen2/3) */ + #define PD_ALWAYS_ON PD_NO_CR /* Always-on area */ + ++#define RCAR_SYSC_MAX_WA_CLKS 8 + + /* + * Description of a Power Area +@@ -39,6 +44,7 @@ struct rcar_sysc_area { + u8 isr_bit; /* Bit in SYSCI*R */ + int parent; /* -1 if none */ + unsigned int flags; /* See PD_* */ ++ const char* wa_clk_names[RCAR_SYSC_MAX_WA_CLKS]; /* Clocks needed by workaround for A3 PD issue */ + }; + + +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-and-TI-hubs.patch index 4989e05..7adfb2e 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-and-TI-hubs.patch @@ -1,31 +1,34 @@ -From 8276db72581e4d1e3f89ccce84555c9fea145e16 Mon Sep 17 00:00:00 2001 +From f05c07d846b5b815709cd741a85e922ddb72b958 Mon Sep 17 00:00:00 2001 From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> Date: Fri, 11 Aug 2017 17:30:40 +0300 -Subject: [PATCH] usb: hub: disable autosuspend for SMSC hubs +Subject: [PATCH] usb: hub: disable autosuspend for SMSC and TI hubs -Disable autosuspend for SMSC hubs (USB5534B/USB2134B devices) -This is a workaround for RCar Gen3 XHCI +Disable autosuspend for SMSC hubs (USB5534B/USB2134B devices) and +TI hub (TUSB8041) +This is a workaround for RCar Gen3 XHCI on VB and VB2 Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> +Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com> --- - drivers/usb/core/hub.c | 9 +++++++++ - 1 file changed, 9 insertions(+) + drivers/usb/core/hub.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index cbb1467..2c4c006 100644 +index cbb1467..6f5575f 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -34,7 +34,9 @@ +@@ -34,7 +34,10 @@ #include "otg_whitelist.h" #define USB_VENDOR_GENESYS_LOGIC 0x05e3 +#define USB_VENDOR_SMSC 0x0424 ++#define USB_VENDOR_TI 0x0451 #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 +#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02 /* Protect struct usb_device->state and ->children members * Note: Both are also protected by ->dev.sem, except that ->state can -@@ -1845,6 +1847,9 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) +@@ -1845,6 +1848,9 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND) hub->quirk_check_port_auto_suspend = 1; @@ -35,7 +38,7 @@ index cbb1467..2c4c006 100644 if (hub_configure(hub, endpoint) >= 0) return 0; -@@ -5226,6 +5231,10 @@ static void hub_event(struct work_struct *work) +@@ -5226,6 +5232,14 @@ static void hub_event(struct work_struct *work) } static const struct usb_device_id hub_id_table[] = { @@ -43,6 +46,10 @@ index cbb1467..2c4c006 100644 + .idVendor = USB_VENDOR_SMSC, + .bInterfaceClass = USB_CLASS_HUB, + .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, ++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS, ++ .idVendor = USB_VENDOR_TI, ++ .bInterfaceClass = USB_CLASS_HUB, ++ .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS, .idVendor = USB_VENDOR_GENESYS_LOGIC, diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0083-spi-Document-DT-bindings-for-SPI-controllers-in-slav.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0083-spi-Document-DT-bindings-for-SPI-controllers-in-slav.patch new file mode 100644 index 0000000..0266378 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0083-spi-Document-DT-bindings-for-SPI-controllers-in-slav.patch @@ -0,0 +1,118 @@ +From c71da12ba9738ac1441fb431100cb03662ba9ac1 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Fri, 17 Jun 2016 18:05:32 +0200 +Subject: [PATCH 1/7] spi: Document DT bindings for SPI controllers in slave + mode + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +Reviewed-by: Rob Herring <robh@kernel.org> +--- + Documentation/devicetree/bindings/spi/spi-bus.txt | 76 ++++++++++++--------- + 1 file changed, 45 insertions(+), 31 deletions(-) + +diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt +index 4b1d6e7..1f6e86f 100644 +--- a/Documentation/devicetree/bindings/spi/spi-bus.txt ++++ b/Documentation/devicetree/bindings/spi/spi-bus.txt +@@ -1,17 +1,23 @@ + SPI (Serial Peripheral Interface) busses + +-SPI busses can be described with a node for the SPI master device +-and a set of child nodes for each SPI slave on the bus. For this +-discussion, it is assumed that the system's SPI controller is in +-SPI master mode. This binding does not describe SPI controllers +-in slave mode. ++SPI busses can be described with a node for the SPI controller device ++and a set of child nodes for each SPI slave on the bus. The system's SPI ++controller may be described for use in SPI master mode or in SPI slave mode, ++but not for both at the same time. + +-The SPI master node requires the following properties: ++The SPI controller node requires the following properties: ++- compatible - Name of SPI bus controller following generic names ++ recommended practice. ++ ++In master mode, the SPI controller node requires the following additional ++properties: + - #address-cells - number of cells required to define a chip select + address on the SPI bus. + - #size-cells - should be zero. +-- compatible - name of SPI bus controller following generic names +- recommended practice. ++ ++In slave mode, the SPI controller node requires one additional property: ++- spi-slave - Empty property. ++ + No other properties are required in the SPI bus node. It is assumed + that a driver for an SPI bus device will understand that it is an SPI bus. + However, the binding does not attempt to define the specific method for +@@ -21,7 +27,7 @@ assumption that board specific platform code will be used to manage + chip selects. Individual drivers can define additional properties to + support describing the chip select layout. + +-Optional properties: ++Optional properties (master mode only): + - cs-gpios - gpios chip select. + - num-cs - total number of chipselects. + +@@ -41,28 +47,36 @@ cs1 : native + cs2 : &gpio1 1 0 + cs3 : &gpio1 2 0 + +-SPI slave nodes must be children of the SPI master node and can +-contain the following properties. +-- reg - (required) chip select address of device. +-- compatible - (required) name of SPI device following generic names +- recommended practice. +-- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz. +-- spi-cpol - (optional) Empty property indicating device requires +- inverse clock polarity (CPOL) mode. +-- spi-cpha - (optional) Empty property indicating device requires +- shifted clock phase (CPHA) mode. +-- spi-cs-high - (optional) Empty property indicating device requires +- chip select active high. +-- spi-3wire - (optional) Empty property indicating device requires +- 3-wire mode. +-- spi-lsb-first - (optional) Empty property indicating device requires +- LSB first mode. +-- spi-tx-bus-width - (optional) The bus width (number of data wires) that is +- used for MOSI. Defaults to 1 if not present. +-- spi-rx-bus-width - (optional) The bus width (number of data wires) that is +- used for MISO. Defaults to 1 if not present. +-- spi-rx-delay-us - (optional) Microsecond delay after a read transfer. +-- spi-tx-delay-us - (optional) Microsecond delay after a write transfer. ++ ++SPI slave nodes must be children of the SPI controller node. ++ ++In master mode, one or more slave nodes (up to the number of chip selects) can ++be present. Required properties are: ++- compatible - Name of SPI device following generic names recommended ++ practice. ++- reg - Chip select address of device. ++- spi-max-frequency - Maximum SPI clocking speed of device in Hz. ++ ++In slave mode, the (single) slave node is optional. ++If present, it must be called "slave". Required properties are: ++- compatible - Name of SPI device following generic names recommended ++ practice. ++ ++All slave nodes can contain the following optional properties: ++- spi-cpol - Empty property indicating device requires inverse clock ++ polarity (CPOL) mode. ++- spi-cpha - Empty property indicating device requires shifted clock ++ phase (CPHA) mode. ++- spi-cs-high - Empty property indicating device requires chip select ++ active high. ++- spi-3wire - Empty property indicating device requires 3-wire mode. ++- spi-lsb-first - Empty property indicating device requires LSB first mode. ++- spi-tx-bus-width - The bus width (number of data wires) that is used for MOSI. ++ Defaults to 1 if not present. ++- spi-rx-bus-width - The bus width (number of data wires) that is used for MISO. ++ Defaults to 1 if not present. ++- spi-rx-delay-us - Microsecond delay after a read transfer. ++- spi-tx-delay-us - Microsecond delay after a write transfer. + + Some SPI controllers and devices support Dual and Quad SPI transfer mode. + It allows data in the SPI system to be transferred using 2 wires (DUAL) or 4 +-- +1.7.10.4 diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0084-spi-core-Add-support-for-registering-SPI-slave-contr.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0084-spi-core-Add-support-for-registering-SPI-slave-contr.patch new file mode 100644 index 0000000..780459c --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0084-spi-core-Add-support-for-registering-SPI-slave-contr.patch @@ -0,0 +1,445 @@ +From 069206bafab71d97d2c427ed664e7cbacbe0678c Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Fri, 17 Jun 2016 16:45:37 +0200 +Subject: [PATCH 2/7] spi: core: Add support for registering SPI slave + controllers + +Add support for registering SPI slave controllers using the existing SPI +master framework: + - SPI slave controllers must use spi_alloc_slave() instead of + spi_alloc_master(), and should provide an additional callback + "slave_abort" to abort an ongoing SPI transfer request, + - SPI slave controllers are added to a new "spi_slave" device class, + - SPI slave handlers can be bound to the SPI slave device represented + by an SPI slave controller using a DT child node named "slave", + - Alternatively, (un)binding an SPI slave handler to the SPI slave + device represented by an SPI slave controller can be done by + (un)registering the slave device through a sysfs virtual file named + "slave". + +From the point of view of an SPI slave protocol handler, an SPI slave +controller looks almost like an ordinary SPI master controller. The only +exception is that a transfer request will block on the remote SPI +master, and may be cancelled using spi_slave_abort(). + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +--- + drivers/spi/Kconfig | 14 +++- + drivers/spi/Makefile | 2 + + drivers/spi/spi.c | 179 ++++++++++++++++++++++++++++++++++++++++------- + include/linux/spi/spi.h | 35 +++++++-- + 4 files changed, 201 insertions(+), 29 deletions(-) + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index fb418d5..8c97790 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -781,6 +781,18 @@ config SPI_TLE62X0 + + endif # SPI_MASTER + +-# (slave support would go here) ++# ++# SLAVE side ... listening to other SPI masters ++# ++ ++config SPI_SLAVE ++ bool "SPI slave protocol handlers" ++ help ++ If your system has a slave-capable SPI controller, you can enable ++ slave protocol handlers. ++ ++if SPI_SLAVE ++ ++endif # SPI_SLAVE + + endif # SPI +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index aa939d9..2428b0f 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -102,3 +102,5 @@ obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o + obj-$(CONFIG_SPI_XLP) += spi-xlp.o + obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o + obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o ++ ++# SPI slave protocol handlers +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 838783c..a403e3a 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -1513,15 +1513,6 @@ static int spi_master_initialize_queue(struct spi_master *master) + goto err_out; + } + +- /* Device address */ +- rc = of_property_read_u32(nc, "reg", &value); +- if (rc) { +- dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", +- nc->full_name, rc); +- goto err_out; +- } +- spi->chip_select = value; +- + /* Mode (clock phase/polarity/etc.) */ + if (of_find_property(nc, "spi-cpha", NULL)) + spi->mode |= SPI_CPHA; +@@ -1571,6 +1562,24 @@ static int spi_master_initialize_queue(struct spi_master *master) + } + } + ++ if (spi_controller_is_slave(master)) { ++ if (strcmp(nc->name, "slave")) { ++ dev_err(&master->dev, "%s is not called 'slave'\n", ++ nc->full_name); ++ return -EINVAL; ++ } ++ return 0; ++ } ++ ++ /* Device address */ ++ rc = of_property_read_u32(nc, "reg", &value); ++ if (rc) { ++ dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", ++ nc->full_name, rc); ++ return rc; ++ } ++ spi->chip_select = value; ++ + /* Device speed */ + rc = of_property_read_u32(nc, "spi-max-frequency", &value); + if (rc) { +@@ -1603,8 +1612,8 @@ static int spi_master_initialize_queue(struct spi_master *master) + * of_register_spi_devices() - Register child devices onto the SPI bus + * @master: Pointer to spi_master device + * +- * Registers an spi_device for each child node of master node which has a 'reg' +- * property. ++ * Registers an spi_device for each child node of controller node which ++ * represents a valid SPI slave. + */ + static void of_register_spi_devices(struct spi_master *master) + { +@@ -1771,28 +1780,129 @@ static void spi_master_release(struct device *dev) + .dev_groups = spi_master_groups, + }; + ++#ifdef CONFIG_SPI_SLAVE ++/** ++ * spi_slave_abort - abort the ongoing transfer request on an SPI slave ++ * controller ++ * @spi: device used for the current transfer ++ */ ++int spi_slave_abort(struct spi_device *spi) ++{ ++ struct spi_master *master = spi->master; ++ ++ if (spi_controller_is_slave(master) && master->slave_abort) ++ return master->slave_abort(master); ++ ++ return -ENOTSUPP; ++} ++EXPORT_SYMBOL_GPL(spi_slave_abort); ++ ++static int match_true(struct device *dev, void *data) ++{ ++ return 1; ++} ++ ++static ssize_t spi_slave_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct spi_master *ctlr = container_of(dev, struct spi_master, dev); ++ struct device *child; ++ ++ child = device_find_child(&ctlr->dev, NULL, match_true); ++ return sprintf(buf, "%s\n", ++ child ? to_spi_device(child)->modalias : NULL); ++} ++ ++static ssize_t spi_slave_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, ++ size_t count) ++{ ++ struct spi_master *ctlr = container_of(dev, struct spi_master, dev); ++ struct spi_device *spi; ++ struct device *child; ++ char name[32]; ++ int rc; ++ ++ rc = sscanf(buf, "%31s", name); ++ if (rc != 1 || !name[0]) ++ return -EINVAL; ++ ++ child = device_find_child(&ctlr->dev, NULL, match_true); ++ if (child) { ++ /* Remove registered slave */ ++ device_unregister(child); ++ put_device(child); ++ } ++ ++ if (strcmp(name, "(null)")) { ++ /* Register new slave */ ++ spi = spi_alloc_device(ctlr); ++ if (!spi) ++ return -ENOMEM; ++ ++ strlcpy(spi->modalias, name, sizeof(spi->modalias)); ++ ++ rc = spi_add_device(spi); ++ if (rc) { ++ spi_dev_put(spi); ++ return rc; ++ } ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(slave, 0644, spi_slave_show, spi_slave_store); ++ ++static struct attribute *spi_slave_attrs[] = { ++ &dev_attr_slave.attr, ++ NULL, ++}; ++ ++static const struct attribute_group spi_slave_group = { ++ .attrs = spi_slave_attrs, ++}; ++ ++static const struct attribute_group *spi_slave_groups[] = { ++ &spi_master_statistics_group, ++ &spi_slave_group, ++ NULL, ++}; ++ ++static struct class spi_slave_class = { ++ .name = "spi_slave", ++ .owner = THIS_MODULE, ++ .dev_release = spi_master_release, ++ .dev_groups = spi_slave_groups, ++}; ++#else ++extern struct class spi_slave_class; /* dummy */ ++#endif + + /** +- * spi_alloc_master - allocate SPI master controller ++ * __spi_alloc_controller - allocate an SPI master or slave controller + * @dev: the controller, possibly using the platform_bus + * @size: how much zeroed driver-private data to allocate; the pointer to this + * memory is in the driver_data field of the returned device, + * accessible with spi_master_get_devdata(). ++ * @slave: flag indicating whether to allocate an SPI master (false) or SPI ++ * slave (true) controller + * Context: can sleep + * +- * This call is used only by SPI master controller drivers, which are the ++ * This call is used only by SPI controller drivers, which are the + * only ones directly touching chip registers. It's how they allocate + * an spi_master structure, prior to calling spi_register_master(). + * + * This must be called from context that can sleep. + * +- * The caller is responsible for assigning the bus number and initializing +- * the master's methods before calling spi_register_master(); and (after errors ++ * The caller is responsible for assigning the bus number and initializing the ++ * controller's methods before calling spi_register_master(); and (after errors + * adding the device) calling spi_master_put() to prevent a memory leak. + * +- * Return: the SPI master structure on success, else NULL. ++ * Return: the SPI controller structure on success, else NULL. + */ +-struct spi_master *spi_alloc_master(struct device *dev, unsigned size) ++struct spi_master *__spi_alloc_controller(struct device *dev, ++ unsigned int size, bool slave) + { + struct spi_master *master; + +@@ -1806,14 +1916,18 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) + device_initialize(&master->dev); + master->bus_num = -1; + master->num_chipselect = 1; +- master->dev.class = &spi_master_class; ++ master->slave = slave; ++ if (IS_ENABLED(CONFIG_SPI_SLAVE) && slave) ++ master->dev.class = &spi_slave_class; ++ else ++ master->dev.class = &spi_master_class; + master->dev.parent = dev; + pm_suspend_ignore_children(&master->dev, true); + spi_master_set_devdata(master, &master[1]); + + return master; + } +-EXPORT_SYMBOL_GPL(spi_alloc_master); ++EXPORT_SYMBOL_GPL(__spi_alloc_controller); + + #ifdef CONFIG_OF + static int of_spi_register_master(struct spi_master *master) +@@ -1889,9 +2003,11 @@ int spi_register_master(struct spi_master *master) + if (!dev) + return -ENODEV; + +- status = of_spi_register_master(master); +- if (status) +- return status; ++ if (!spi_controller_is_slave(master)) { ++ status = of_spi_register_master(master); ++ if (status) ++ return status; ++ } + + /* even if it's just one always-selected device, there must + * be at least one chipselect +@@ -1928,8 +2044,9 @@ int spi_register_master(struct spi_master *master) + status = device_add(&master->dev); + if (status < 0) + goto done; +- dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), +- dynamic ? " (dynamic)" : ""); ++ dev_dbg(dev, "registered %s %s%s\n", ++ spi_controller_is_slave(master) ? "slave" : "master", ++ dev_name(&master->dev), dynamic ? " (dynamic)" : ""); + + /* If we're using a queued driver, start the queue */ + if (master->transfer) +@@ -3102,6 +3219,9 @@ static struct spi_master *of_find_spi_master_by_node(struct device_node *node) + + dev = class_find_device(&spi_master_class, NULL, node, + __spi_of_master_match); ++ if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) ++ dev = class_find_device(&spi_slave_class, NULL, node, ++ __spi_of_master_match); + if (!dev) + return NULL; + +@@ -3183,6 +3303,9 @@ static struct spi_master *acpi_spi_find_master_by_adev(struct acpi_device *adev) + + dev = class_find_device(&spi_master_class, NULL, adev, + spi_acpi_master_match); ++ if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) ++ dev = class_find_device(&spi_slave_class, NULL, adev, ++ spi_acpi_master_match); + if (!dev) + return NULL; + +@@ -3255,6 +3378,12 @@ static int __init spi_init(void) + if (status < 0) + goto err2; + ++ if (IS_ENABLED(CONFIG_SPI_SLAVE)) { ++ status = class_register(&spi_slave_class); ++ if (status < 0) ++ goto err3; ++ } ++ + if (IS_ENABLED(CONFIG_OF_DYNAMIC)) + WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); + if (IS_ENABLED(CONFIG_ACPI)) +@@ -3262,6 +3391,8 @@ static int __init spi_init(void) + + return 0; + ++err3: ++ class_unregister(&spi_master_class); + err2: + bus_unregister(&spi_bus_type); + err1: +diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h +index 4b743ac..f9bbd33 100644 +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -28,8 +28,8 @@ + struct spi_flash_read_message; + + /* +- * INTERFACES between SPI master-side drivers and SPI infrastructure. +- * (There's no SPI slave support for Linux yet...) ++ * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, ++ * and SPI infrastructure. + */ + extern struct bus_type spi_bus_type; + +@@ -310,6 +310,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) + * @min_speed_hz: Lowest supported transfer speed + * @max_speed_hz: Highest supported transfer speed + * @flags: other constraints relevant to this driver ++ * @slave: indicates that this is an SPI slave controller + * @max_transfer_size: function that returns the max transfer size for + * a &spi_device; may be %NULL, so the default %SIZE_MAX will be used. + * @max_message_size: function that returns the max message size for +@@ -373,6 +374,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) + * @handle_err: the subsystem calls the driver to handle an error that occurs + * in the generic implementation of transfer_one_message(). + * @unprepare_message: undo any work done by prepare_message(). ++ * @slave_abort: abort the ongoing transfer request on an SPI slave controller + * @spi_flash_read: to support spi-controller hardwares that provide + * accelerated interface to read from flash devices. + * @flash_read_supported: spi device supports flash read +@@ -443,6 +445,9 @@ struct spi_master { + #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ + #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ + ++ /* flag indicating this is an SPI slave controller */ ++ bool slave; ++ + /* + * on some hardware transfer / message size may be constrained + * the limit may depend on device transfer settings +@@ -535,6 +540,7 @@ struct spi_master { + struct spi_message *message); + int (*unprepare_message)(struct spi_master *master, + struct spi_message *message); ++ int (*slave_abort)(struct spi_master *spi); + int (*spi_flash_read)(struct spi_device *spi, + struct spi_flash_read_message *msg); + bool (*flash_read_supported)(struct spi_device *spi); +@@ -589,6 +595,11 @@ static inline void spi_master_put(struct spi_master *master) + put_device(&master->dev); + } + ++static inline bool spi_controller_is_slave(struct spi_master *ctlr) ++{ ++ return IS_ENABLED(CONFIG_SPI_SLAVE) && ctlr->slave; ++} ++ + /* PM calls that need to be issued by the driver */ + extern int spi_master_suspend(struct spi_master *master); + extern int spi_master_resume(struct spi_master *master); +@@ -599,8 +610,23 @@ static inline void spi_master_put(struct spi_master *master) + extern void spi_finalize_current_transfer(struct spi_master *master); + + /* the spi driver core manages memory for the spi_master classdev */ +-extern struct spi_master * +-spi_alloc_master(struct device *host, unsigned size); ++extern struct spi_master *__spi_alloc_controller(struct device *host, ++ unsigned int size, bool slave); ++ ++static inline struct spi_master *spi_alloc_master(struct device *host, ++ unsigned int size) ++{ ++ return __spi_alloc_controller(host, size, false); ++} ++ ++static inline struct spi_master *spi_alloc_slave(struct device *host, ++ unsigned int size) ++{ ++ if (!IS_ENABLED(CONFIG_SPI_SLAVE)) ++ return NULL; ++ ++ return __spi_alloc_controller(host, size, true); ++} + + extern int spi_register_master(struct spi_master *master); + extern int devm_spi_register_master(struct device *dev, +@@ -906,6 +932,7 @@ static inline void spi_message_free(struct spi_message *m) + extern int spi_async(struct spi_device *spi, struct spi_message *message); + extern int spi_async_locked(struct spi_device *spi, + struct spi_message *message); ++extern int spi_slave_abort(struct spi_device *spi); + + static inline size_t + spi_max_message_size(struct spi_device *spi) +-- +1.7.10.4 diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0085-spi-Document-SPI-slave-controller-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0085-spi-Document-SPI-slave-controller-support.patch new file mode 100644 index 0000000..57436d2 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0085-spi-Document-SPI-slave-controller-support.patch @@ -0,0 +1,66 @@ +From 0be2c71f293e8c8423e5378cc73f71e10205ad54 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Thu, 8 Sep 2016 15:01:48 +0200 +Subject: [PATCH 3/7] spi: Document SPI slave controller support + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +--- + Documentation/spi/spi-summary | 27 ++++++++++++++++++++------- + 1 file changed, 20 insertions(+), 7 deletions(-) + +diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary +index d1824b3..1721c1b 100644 +--- a/Documentation/spi/spi-summary ++++ b/Documentation/spi/spi-summary +@@ -62,8 +62,8 @@ chips described as using "three wire" signaling: SCK, data, nCSx. + (That data line is sometimes called MOMI or SISO.) + + Microcontrollers often support both master and slave sides of the SPI +-protocol. This document (and Linux) currently only supports the master +-side of SPI interactions. ++protocol. This document (and Linux) supports both the master and slave ++sides of SPI interactions. + + + Who uses it? On what kinds of systems? +@@ -154,9 +154,8 @@ control audio interfaces, present touchscreen sensors as input interfaces, + or monitor temperature and voltage levels during industrial processing. + And those might all be sharing the same controller driver. + +-A "struct spi_device" encapsulates the master-side interface between +-those two types of driver. At this writing, Linux has no slave side +-programming interface. ++A "struct spi_device" encapsulates the controller-side interface between ++those two types of drivers. + + There is a minimal core of SPI programming interfaces, focussing on + using the driver model to connect controller and protocol drivers using +@@ -177,10 +176,24 @@ shows up in sysfs in several locations: + /sys/bus/spi/drivers/D ... driver for one or more spi*.* devices + + /sys/class/spi_master/spiB ... symlink (or actual device node) to +- a logical node which could hold class related state for the +- controller managing bus "B". All spiB.* devices share one ++ a logical node which could hold class related state for the SPI ++ master controller managing bus "B". All spiB.* devices share one + physical SPI bus segment, with SCLK, MOSI, and MISO. + ++ /sys/devices/.../CTLR/slave ... virtual file for (un)registering the ++ slave device for an SPI slave controller. ++ Writing the driver name of an SPI slave handler to this file ++ registers the slave device; writing "(null)" unregisters the slave ++ device. ++ Reading from this file shows the name of the slave device ("(null)" ++ if not registered). ++ ++ /sys/class/spi_slave/spiB ... symlink (or actual device node) to ++ a logical node which could hold class related state for the SPI ++ slave controller on bus "B". When registered, a single spiB.* ++ device is present here, possible sharing the physical SPI bus ++ segment with other SPI slave devices. ++ + Note that the actual location of the controller's class state depends + on whether you enabled CONFIG_SYSFS_DEPRECATED or not. At this time, + the only class-specific state is the bus number ("B" in "spiB"), so +-- +1.7.10.4 diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0086-spi-sh-msiof-Add-slave-mode-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0086-spi-sh-msiof-Add-slave-mode-support.patch new file mode 100644 index 0000000..ef0b74b --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0086-spi-sh-msiof-Add-slave-mode-support.patch @@ -0,0 +1,468 @@ +From cf9e4784f3bde3e4749163384f27450ddffe746c Mon Sep 17 00:00:00 2001 +From: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Date: Mon, 22 May 2017 15:11:43 +0200 +Subject: [PATCH] spi: sh-msiof: Add slave mode support + +Add slave mode support to the MSIOF driver, in both PIO and DMA mode. + +For now this only supports the transmission of messages with a size +that is known in advance. + +Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> +Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Signed-off-by: Hiromitsu Yamasaki <hiromitsu.yamasaki.ym@renesas.com> +[geert: Timeout handling cleanup, spi core integration, cancellation, + rewording] +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + Documentation/devicetree/bindings/spi/sh-msiof.txt | 2 + + drivers/spi/spi-sh-msiof.c | 193 +++++++++------------ + include/linux/spi/sh_msiof.h | 4 +- + 3 files changed, 90 insertions(+), 109 deletions(-) + +diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt +index f1dbc15..9e43f30 100644 +--- a/Documentation/devicetree/bindings/spi/sh-msiof.txt ++++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt +@@ -34,6 +34,8 @@ Optional properties: + specifiers, one for transmission, and one for + reception. + - dma-names : Must contain a list of two DMA names, "tx" and "rx". ++- spi-slave : Empty property indicating the SPI controller is used ++ in slave mode. + - renesas,dtdl : delay sync signal (setup) in transmit mode. + Must contain one of the following values: + 0 (no bit delay) +diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c +index 13fd706..916377b 100644 +--- a/drivers/spi/spi-sh-msiof.c ++++ b/drivers/spi/spi-sh-msiof.c +@@ -3,7 +3,8 @@ + * + * Copyright (C) 2016-2017 Renesas Electronics Corporation + * Copyright (c) 2009 Magnus Damm +- * Copyright (C) 2014 Glider bvba ++ * Copyright (C) 2014 Renesas Electronics Corporation ++ * Copyright (C) 2014-2017 Glider bvba + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as +@@ -35,7 +36,6 @@ + + #include <asm/unaligned.h> + +- + struct sh_msiof_chipdata { + u16 tx_fifo_size; + u16 rx_fifo_size; +@@ -62,6 +62,7 @@ struct sh_msiof_spi_priv { + void *rx_dma_page; + dma_addr_t tx_dma_addr; + dma_addr_t rx_dma_addr; ++ bool slave_aborted; + unsigned int quirks; + }; + +@@ -402,18 +403,21 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, + tmp |= lsb_first << MDR1_BITLSB_SHIFT; + tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p); + if (p->quirks & TRANSFER_WORKAROUND_H3WS10) { +- if (p->mode == SPI_MSIOF_MASTER) { ++ if (!spi_controller_is_slave(p->master)) { + tmp &= ~MDR1_DTDL_MASK; + tmp |= 0 << MDR1_DTDL_SHIFT; + } + } + if (p->quirks & TRANSFER_WORKAROUND_H3WS11) { +- if (p->mode == SPI_MSIOF_MASTER) { ++ if (!spi_controller_is_slave(p->master)) { + tmp &= ~MDR1_DTDL_MASK; + tmp |= 1 << MDR1_DTDL_SHIFT; + } + } +- if (p->mode == SPI_MSIOF_MASTER) { ++ ++ if (spi_controller_is_slave(p->master)) { ++ sh_msiof_write(p, TMDR1, tmp | TMDR1_PCON); ++ } else { + if (p->cs == 1) + tmp |= MDR1_SYNCCH_SS1; + else if (p->cs == 2) +@@ -421,16 +425,15 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, + else + tmp &= ~MDR1_SYNCCH_MASK; + sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); +- } else +- sh_msiof_write(p, TMDR1, tmp | TMDR1_PCON); ++ } + if (p->quirks & TRANSFER_WORKAROUND_H3WS10) { +- if (p->mode == SPI_MSIOF_MASTER) { ++ if (!spi_controller_is_slave(p->master)) { + tmp &= ~MDR1_DTDL_MASK; + tmp |= 2 << MDR1_DTDL_SHIFT; + } + } + if (p->quirks & TRANSFER_WORKAROUND_H3WS11) { +- if (p->mode == SPI_MSIOF_MASTER) { ++ if (!spi_controller_is_slave(p->master)) { + tmp &= ~MDR1_DTDL_MASK; + tmp |= 1 << MDR1_DTDL_SHIFT; + } +@@ -443,7 +446,7 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, + + tmp = 0; + if (p->quirks & TRANSFER_WORKAROUND_H3WS10) { +- if (p->mode == SPI_MSIOF_MASTER) { ++ if (!spi_controller_is_slave(p->master)) { + tmp |= 0 << CTR_TSCKIZ_POL_SHIFT; + tmp |= 0 << CTR_RSCKIZ_POL_SHIFT; + } else { +@@ -680,10 +683,11 @@ static int sh_msiof_prepare_message(struct spi_master *master, + + static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf) + { ++ bool slave = spi_controller_is_slave(p->master); + int ret = 0; + + /* setup clock and rx/tx signals */ +- if (p->mode == SPI_MSIOF_MASTER) ++ if (!slave) + ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE); + if (rx_buf && !ret) + ret = sh_msiof_modify_ctr_wait(p, 0, CTR_RXE); +@@ -691,7 +695,7 @@ static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf) + ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TXE); + + /* start by setting frame bit */ +- if (!ret && p->mode == SPI_MSIOF_MASTER) ++ if (!ret && !slave) + ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE); + + return ret; +@@ -699,21 +703,50 @@ static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf) + + static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf) + { ++ bool slave = spi_controller_is_slave(p->master); + int ret = 0; + + /* shut down frame, rx/tx and clock signals */ +- if (p->mode == SPI_MSIOF_MASTER) ++ if (!slave) + ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0); + if (!ret) + ret = sh_msiof_modify_ctr_wait(p, CTR_TXE, 0); + if (rx_buf && !ret) + ret = sh_msiof_modify_ctr_wait(p, CTR_RXE, 0); +- if (!ret && p->mode == SPI_MSIOF_MASTER) ++ if (!ret && !slave) + ret = sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0); + + return ret; + } + ++static int sh_msiof_slave_abort(struct spi_master *master) ++{ ++ struct sh_msiof_spi_priv *p = spi_master_get_devdata(master); ++ ++ p->slave_aborted = true; ++ complete(&p->done); ++ return 0; ++} ++ ++static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p, ++ struct completion *done) ++{ ++ if (spi_controller_is_slave(p->master)) { ++ if (wait_for_completion_interruptible(done) || ++ p->slave_aborted) { ++ dev_dbg(&p->pdev->dev, "interrupted\n"); ++ return -EINTR; ++ } ++ } else { ++ if (!wait_for_completion_timeout(done, HZ)) { ++ dev_err(&p->pdev->dev, "timeout\n"); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ return 0; ++} ++ + static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, + void (*tx_fifo)(struct sh_msiof_spi_priv *, + const void *, int, int), +@@ -724,9 +757,6 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, + { + int fifo_shift; + int ret; +- unsigned long timeout; +- +- timeout = (p->mode == SPI_MSIOF_MASTER) ? HZ : MAX_SCHEDULE_TIMEOUT; + + /* limit maximum word transfer to rx/tx fifo size */ + if (tx_buf) +@@ -749,6 +779,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, + tx_fifo(p, tx_buf, words, fifo_shift); + + reinit_completion(&p->done); ++ p->slave_aborted = false; + + ret = sh_msiof_spi_start(p, rx_buf); + if (ret) { +@@ -757,21 +788,9 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, + } + + /* wait for tx fifo to be emptied / rx fifo to be filled */ +- if (p->mode == SPI_MSIOF_MASTER) +- ret = wait_for_completion_timeout(&p->done, timeout); +- else { +- ret = wait_for_completion_interruptible_timeout( +- &p->done, timeout); +- if (ret == -ERESTARTSYS) { +- dev_err(&p->pdev->dev, "PIO mode. Task interrupt\n"); +- goto stop_reset; +- } +- } +- if (!ret) { +- dev_err(&p->pdev->dev, "PIO timeout\n"); +- ret = -ETIMEDOUT; ++ ret = sh_msiof_wait_for_completion(p, &p->done); ++ if (ret) + goto stop_reset; +- } + + /* read rx fifo */ + if (rx_buf) +@@ -817,9 +836,6 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, + struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL; + dma_cookie_t cookie; + int ret; +- unsigned long timeout; +- +- timeout = (p->mode == SPI_MSIOF_MASTER) ? HZ : MAX_SCHEDULE_TIMEOUT; + + /* First prepare and submit the DMA request(s), as this may fail */ + if (rx) { +@@ -869,6 +885,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, + reinit_completion(&p->done); + reinit_completion(&p->done_dma_tx); + reinit_completion(&p->done_dma_rx); ++ p->slave_aborted = false; + + /* Now start DMA */ + if (rx) +@@ -884,64 +901,23 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, + + /* wait for Tx/Rx DMA completion */ + if (tx) { +- if (p->mode == SPI_MSIOF_MASTER) +- ret = wait_for_completion_timeout( +- &p->done_dma_tx, timeout); +- else { +- ret = wait_for_completion_interruptible_timeout( +- &p->done_dma_tx, timeout); +- if (ret == -ERESTARTSYS) { +- dev_err(&p->pdev->dev, "Tx DMA. Task interrupt\n"); +- goto stop_reset; +- } +- } +- if (!ret) { +- dev_err(&p->pdev->dev, "Tx DMA timeout\n"); +- ret = -ETIMEDOUT; ++ ret = sh_msiof_wait_for_completion(p, &p->done_dma_tx); ++ if (ret) + goto stop_reset; +- } ++ + if (!rx) { + ier_bits = IER_TEOFE; + sh_msiof_write(p, IER, ier_bits); + + /* wait for tx fifo to be emptied */ +- if (p->mode == SPI_MSIOF_MASTER) +- ret = wait_for_completion_timeout( +- &p->done, timeout); +- else { +- ret = wait_for_completion_interruptible_timeout( +- &p->done, timeout); +- if (ret == -ERESTARTSYS) { +- dev_err(&p->pdev->dev, +- "Tx fifo to be emptied. Task interrupt\n"); +- goto stop_reset; +- } +- } +- if (!ret) { +- dev_err(&p->pdev->dev, +- "Tx fifo to be emptied timeout\n"); +- ret = -ETIMEDOUT; ++ if (sh_msiof_wait_for_completion(p, &p->done)) + goto stop_reset; +- } + } + } + if (rx) { +- if (p->mode == SPI_MSIOF_MASTER) +- ret = wait_for_completion_timeout( +- &p->done_dma_rx, timeout); +- else { +- ret = wait_for_completion_interruptible_timeout( +- &p->done_dma_rx, timeout); +- if (ret == -ERESTARTSYS) { +- dev_err(&p->pdev->dev, "Rx DMA. Task interrupt\n"); +- goto stop_reset; +- } +- } +- if (!ret) { +- dev_err(&p->pdev->dev, "Rx DMA timeout\n"); +- ret = -ETIMEDOUT; ++ ret = sh_msiof_wait_for_completion(p, &p->done_dma_rx); ++ if (ret) + goto stop_reset; +- } + } + + sh_msiof_write(p, IER, 0); +@@ -1040,7 +1016,7 @@ static int sh_msiof_transfer_one(struct spi_master *master, + sh_msiof_spi_reset_regs(p); + + /* setup clocks (clock already enabled in chipselect()) */ +- if (p->mode == SPI_MSIOF_MASTER) ++ if (!spi_controller_is_slave(p->master)) + sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz); + + while (master->dma_tx && len > 15) { +@@ -1071,7 +1047,7 @@ static int sh_msiof_transfer_one(struct spi_master *master, + copy32(p->tx_dma_page, tx_buf, l / 4); + + #ifdef CONFIG_SPI_SH_MSIOF_TRANSFER_SYNC_DEBUG +- if (p->mode == SPI_MSIOF_MASTER) ++ if (!spi_controller_is_slave(p->master)) + msleep(TRANSFAR_SYNC_DELAY); + #endif /* CONFIG_SPI_SH_MSIOF_TRANSFER_SYNC_DEBUG */ + +@@ -1148,9 +1124,8 @@ static int sh_msiof_transfer_one(struct spi_master *master, + words = len / bytes_per_word; + + while (words > 0) { +- + #ifdef CONFIG_SPI_SH_MSIOF_TRANSFER_SYNC_DEBUG +- if (p->mode == SPI_MSIOF_MASTER) ++ if (!spi_controller_is_slave(p->master)) + msleep(TRANSFAR_SYNC_DELAY); + #endif /* CONFIG_SPI_SH_MSIOF_TRANSFER_SYNC_DEBUG */ + +@@ -1209,8 +1184,12 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev) + if (!info) + return NULL; + ++ info->mode = of_property_read_bool(np, "spi-slave") ? MSIOF_SPI_SLAVE ++ : MSIOF_SPI_MASTER; ++ + /* Parse the MSIOF properties */ +- of_property_read_u32(np, "num-cs", &num_cs); ++ if (info->mode == MSIOF_SPI_MASTER) ++ of_property_read_u32(np, "num-cs", &num_cs); + of_property_read_u32(np, "renesas,tx-fifo-size", + &info->tx_fifo_override); + of_property_read_u32(np, "renesas,rx-fifo-size", +@@ -1218,11 +1197,6 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev) + of_property_read_u32(np, "renesas,dtdl", &info->dtdl); + of_property_read_u32(np, "renesas,syncdl", &info->syncdl); + +- if (of_property_read_bool(np, "slave")) +- info->mode = SPI_MSIOF_SLAVE; +- else +- info->mode = SPI_MSIOF_MASTER; +- + info->num_chipselect = num_cs; + + return info; +@@ -1372,6 +1346,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) + struct spi_master *master; + const struct sh_msiof_chipdata *chipdata; + const struct of_device_id *of_id; ++ struct sh_msiof_spi_info *info; + struct sh_msiof_spi_priv *p; + struct clk *ref_clk; + u32 clk_rate = 0; +@@ -1379,32 +1354,35 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) + int ret; + const struct soc_device_attribute *attr; + +- master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv)); +- if (master == NULL) { +- dev_err(&pdev->dev, "failed to allocate spi master\n"); +- return -ENOMEM; +- } +- +- p = spi_master_get_devdata(master); +- +- platform_set_drvdata(pdev, p); +- p->master = master; +- + of_id = of_match_device(sh_msiof_match, &pdev->dev); + if (of_id) { + chipdata = of_id->data; +- p->info = sh_msiof_spi_parse_dt(&pdev->dev); ++ info = sh_msiof_spi_parse_dt(&pdev->dev); + } else { + chipdata = (const void *)pdev->id_entry->driver_data; +- p->info = dev_get_platdata(&pdev->dev); ++ info = dev_get_platdata(&pdev->dev); + } + +- if (!p->info) { ++ if (!info) { + dev_err(&pdev->dev, "failed to obtain device info\n"); +- ret = -ENXIO; +- goto err1; ++ return -ENXIO; + } + ++ if (info->mode == MSIOF_SPI_SLAVE) ++ master = spi_alloc_slave(&pdev->dev, ++ sizeof(struct sh_msiof_spi_priv)); ++ else ++ master = spi_alloc_master(&pdev->dev, ++ sizeof(struct sh_msiof_spi_priv)); ++ if (master == NULL) ++ return -ENOMEM; ++ ++ p = spi_master_get_devdata(master); ++ ++ platform_set_drvdata(pdev, p); ++ p->master = master; ++ p->info = info; ++ + attr = soc_device_match(rcar_quirks_match); + if (attr) + p->quirks = (uintptr_t)attr->data; +@@ -1462,6 +1440,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) + master->num_chipselect = p->info->num_chipselect; + master->setup = sh_msiof_spi_setup; + master->prepare_message = sh_msiof_prepare_message; ++ master->slave_abort = sh_msiof_slave_abort; + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); + master->auto_runtime_pm = true; + master->transfer_one = sh_msiof_transfer_one; +diff --git a/include/linux/spi/sh_msiof.h b/include/linux/spi/sh_msiof.h +index f723aa4..f74b581 100644 +--- a/include/linux/spi/sh_msiof.h ++++ b/include/linux/spi/sh_msiof.h +@@ -2,8 +2,8 @@ + #define __SPI_SH_MSIOF_H__ + + enum { +- SPI_MSIOF_MASTER, +- SPI_MSIOF_SLAVE, ++ MSIOF_SPI_MASTER, ++ MSIOF_SPI_SLAVE, + }; + + struct sh_msiof_spi_info { +-- +1.9.1 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch new file mode 100644 index 0000000..1c9be85 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch @@ -0,0 +1,182 @@ +From 8b3a09269db92be56455d98bc8cb01f779733f0a Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Fri, 17 Jun 2016 17:00:25 +0200 +Subject: [PATCH 5/7] spi: slave: Add SPI slave handler reporting uptime at + previous message + +Add an example SPI slave handler responding with the uptime at the time +of reception of the last SPI message. + +This can be used by an external microcontroller as a dead man's switch. + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +--- + drivers/spi/Kconfig | 6 ++ + drivers/spi/Makefile | 1 + + drivers/spi/spi-slave-time.c | 129 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 136 insertions(+) + create mode 100644 drivers/spi/spi-slave-time.c + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 8c97790..267bedf 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -793,6 +793,12 @@ config SPI_SLAVE + + if SPI_SLAVE + ++config SPI_SLAVE_TIME ++ tristate "SPI slave handler reporting boot up time" ++ help ++ SPI slave handler responding with the time of reception of the last ++ SPI message. ++ + endif # SPI_SLAVE + + endif # SPI +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index 2428b0f..5e2e537 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -104,3 +104,4 @@ obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o + obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o + + # SPI slave protocol handlers ++obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o +diff --git a/drivers/spi/spi-slave-time.c b/drivers/spi/spi-slave-time.c +new file mode 100644 +index 0000000..fbeaa5b +--- /dev/null ++++ b/drivers/spi/spi-slave-time.c +@@ -0,0 +1,129 @@ ++/* ++ * SPI slave handler reporting uptime at reception of previous SPI message ++ * ++ * This SPI slave handler sends the time of reception of the last SPI message ++ * as two 32-bit unsigned integers in binary format and in network byte order, ++ * representing the number of seconds and fractional seconds (in microseconds) ++ * since boot up. ++ * ++ * Copyright (C) 2016-2017 Glider bvba ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Usage (assuming /dev/spidev2.0 corresponds to the SPI master on the remote ++ * system): ++ * ++ * # spidev_test -D /dev/spidev2.0 -p dummy-8B ++ * spi mode: 0x0 ++ * bits per word: 8 ++ * max speed: 500000 Hz (500 KHz) ++ * RX | 00 00 04 6D 00 09 5B BB ... ++ * ^^^^^ ^^^^^^^^ ++ * seconds microseconds ++ */ ++ ++#include <linux/completion.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/spi/spi.h> ++ ++ ++struct spi_slave_time_priv { ++ struct spi_device *spi; ++ struct completion finished; ++ struct spi_transfer xfer; ++ struct spi_message msg; ++ __be32 buf[2]; ++}; ++ ++static int spi_slave_time_submit(struct spi_slave_time_priv *priv); ++ ++static void spi_slave_time_complete(void *arg) ++{ ++ struct spi_slave_time_priv *priv = arg; ++ int ret; ++ ++ ret = priv->msg.status; ++ if (ret) ++ goto terminate; ++ ++ ret = spi_slave_time_submit(priv); ++ if (ret) ++ goto terminate; ++ ++ return; ++ ++terminate: ++ dev_info(&priv->spi->dev, "Terminating\n"); ++ complete(&priv->finished); ++} ++ ++static int spi_slave_time_submit(struct spi_slave_time_priv *priv) ++{ ++ u32 rem_us; ++ int ret; ++ u64 ts; ++ ++ ts = local_clock(); ++ rem_us = do_div(ts, 1000000000) / 1000; ++ ++ priv->buf[0] = cpu_to_be32(ts); ++ priv->buf[1] = cpu_to_be32(rem_us); ++ ++ spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); ++ ++ priv->msg.complete = spi_slave_time_complete; ++ priv->msg.context = priv; ++ ++ ret = spi_async(priv->spi, &priv->msg); ++ if (ret) ++ dev_err(&priv->spi->dev, "spi_async() failed %d\n", ret); ++ ++ return ret; ++} ++ ++static int spi_slave_time_probe(struct spi_device *spi) ++{ ++ struct spi_slave_time_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->spi = spi; ++ init_completion(&priv->finished); ++ priv->xfer.tx_buf = priv->buf; ++ priv->xfer.len = sizeof(priv->buf); ++ ++ ret = spi_slave_time_submit(priv); ++ if (ret) ++ return ret; ++ ++ spi_set_drvdata(spi, priv); ++ return 0; ++} ++ ++static int spi_slave_time_remove(struct spi_device *spi) ++{ ++ struct spi_slave_time_priv *priv = spi_get_drvdata(spi); ++ ++ spi_slave_abort(spi); ++ wait_for_completion(&priv->finished); ++ return 0; ++} ++ ++static struct spi_driver spi_slave_time_driver = { ++ .driver = { ++ .name = "spi-slave-time", ++ }, ++ .probe = spi_slave_time_probe, ++ .remove = spi_slave_time_remove, ++}; ++module_spi_driver(spi_slave_time_driver); ++ ++MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>"); ++MODULE_DESCRIPTION("SPI slave reporting uptime at previous SPI message"); ++MODULE_LICENSE("GPL v2"); +-- +1.7.10.4 diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch new file mode 100644 index 0000000..3752e98 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch @@ -0,0 +1,205 @@ +From 6acf67e94cbd406b57315f03937a8d4d37a2952c Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Fri, 17 Jun 2016 17:05:45 +0200 +Subject: [PATCH 6/7] spi: slave: Add SPI slave handler controlling system + state + +Add an example SPI slave handler to allow remote control of system +reboot, power off, halt, and suspend. + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +--- + drivers/spi/Kconfig | 6 ++ + drivers/spi/Makefile | 1 + + drivers/spi/spi-slave-system-control.c | 154 ++++++++++++++++++++++++++++++++ + 3 files changed, 161 insertions(+) + create mode 100644 drivers/spi/spi-slave-system-control.c + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 267bedf..45208ec 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -799,6 +799,12 @@ config SPI_SLAVE_TIME + SPI slave handler responding with the time of reception of the last + SPI message. + ++config SPI_SLAVE_SYSTEM_CONTROL ++ tristate "SPI slave handler controlling system state" ++ help ++ SPI slave handler to allow remote control of system reboot, power ++ off, halt, and suspend. ++ + endif # SPI_SLAVE + + endif # SPI +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index 5e2e537..d4d5050 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -105,3 +105,4 @@ obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o + + # SPI slave protocol handlers + obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o ++obj-$(CONFIG_SPI_SLAVE_SYSTEM_CONTROL) += spi-slave-system-control.o +diff --git a/drivers/spi/spi-slave-system-control.c b/drivers/spi/spi-slave-system-control.c +new file mode 100644 +index 0000000..c0257e9 +--- /dev/null ++++ b/drivers/spi/spi-slave-system-control.c +@@ -0,0 +1,154 @@ ++/* ++ * SPI slave handler controlling system state ++ * ++ * This SPI slave handler allows remote control of system reboot, power off, ++ * halt, and suspend. ++ * ++ * Copyright (C) 2016-2017 Glider bvba ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Usage (assuming /dev/spidev2.0 corresponds to the SPI master on the remote ++ * system): ++ * ++ * # reboot='\x7c\x50' ++ * # poweroff='\x71\x3f' ++ * # halt='\x38\x76' ++ * # suspend='\x1b\x1b' ++ * # spidev_test -D /dev/spidev2.0 -p $suspend # or $reboot, $poweroff, $halt ++ */ ++ ++#include <linux/completion.h> ++#include <linux/module.h> ++#include <linux/reboot.h> ++#include <linux/suspend.h> ++#include <linux/spi/spi.h> ++ ++/* ++ * The numbers are chosen to display something human-readable on two 7-segment ++ * displays connected to two 74HC595 shift registers ++ */ ++#define CMD_REBOOT 0x7c50 /* rb */ ++#define CMD_POWEROFF 0x713f /* OF */ ++#define CMD_HALT 0x3876 /* HL */ ++#define CMD_SUSPEND 0x1b1b /* ZZ */ ++ ++struct spi_slave_system_control_priv { ++ struct spi_device *spi; ++ struct completion finished; ++ struct spi_transfer xfer; ++ struct spi_message msg; ++ __be16 cmd; ++}; ++ ++static ++int spi_slave_system_control_submit(struct spi_slave_system_control_priv *priv); ++ ++static void spi_slave_system_control_complete(void *arg) ++{ ++ struct spi_slave_system_control_priv *priv = arg; ++ u16 cmd; ++ int ret; ++ ++ if (priv->msg.status) ++ goto terminate; ++ ++ cmd = be16_to_cpu(priv->cmd); ++ switch (cmd) { ++ case CMD_REBOOT: ++ dev_info(&priv->spi->dev, "Rebooting system...\n"); ++ kernel_restart(NULL); ++ ++ case CMD_POWEROFF: ++ dev_info(&priv->spi->dev, "Powering off system...\n"); ++ kernel_power_off(); ++ break; ++ ++ case CMD_HALT: ++ dev_info(&priv->spi->dev, "Halting system...\n"); ++ kernel_halt(); ++ break; ++ ++ case CMD_SUSPEND: ++ dev_info(&priv->spi->dev, "Suspending system...\n"); ++ pm_suspend(PM_SUSPEND_MEM); ++ break; ++ ++ default: ++ dev_warn(&priv->spi->dev, "Unknown command 0x%x\n", cmd); ++ break; ++ } ++ ++ ret = spi_slave_system_control_submit(priv); ++ if (ret) ++ goto terminate; ++ ++ return; ++ ++terminate: ++ dev_info(&priv->spi->dev, "Terminating\n"); ++ complete(&priv->finished); ++} ++ ++static ++int spi_slave_system_control_submit(struct spi_slave_system_control_priv *priv) ++{ ++ int ret; ++ ++ spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); ++ ++ priv->msg.complete = spi_slave_system_control_complete; ++ priv->msg.context = priv; ++ ++ ret = spi_async(priv->spi, &priv->msg); ++ if (ret) ++ dev_err(&priv->spi->dev, "spi_async() failed %d\n", ret); ++ ++ return ret; ++} ++ ++static int spi_slave_system_control_probe(struct spi_device *spi) ++{ ++ struct spi_slave_system_control_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->spi = spi; ++ init_completion(&priv->finished); ++ priv->xfer.rx_buf = &priv->cmd; ++ priv->xfer.len = sizeof(priv->cmd); ++ ++ ret = spi_slave_system_control_submit(priv); ++ if (ret) ++ return ret; ++ ++ spi_set_drvdata(spi, priv); ++ return 0; ++} ++ ++static int spi_slave_system_control_remove(struct spi_device *spi) ++{ ++ struct spi_slave_system_control_priv *priv = spi_get_drvdata(spi); ++ ++ spi_slave_abort(spi); ++ wait_for_completion(&priv->finished); ++ return 0; ++} ++ ++static struct spi_driver spi_slave_system_control_driver = { ++ .driver = { ++ .name = "spi-slave-system-control", ++ }, ++ .probe = spi_slave_system_control_probe, ++ .remove = spi_slave_system_control_remove, ++}; ++module_spi_driver(spi_slave_system_control_driver); ++ ++MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>"); ++MODULE_DESCRIPTION("SPI slave handler controlling system state"); ++MODULE_LICENSE("GPL v2"); +-- +1.7.10.4 diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0089-spi-Generalize-SPI-master-to-controller.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0089-spi-Generalize-SPI-master-to-controller.patch new file mode 100644 index 0000000..2c1e0eb --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0089-spi-Generalize-SPI-master-to-controller.patch @@ -0,0 +1,3048 @@ +From 5767a2cd113534b904593d143175e1ba71ea6555 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Wed, 3 May 2017 17:28:39 +0200 +Subject: [PATCH 7/7] spi: Generalize SPI "master" to "controller" + +Now struct spi_master is used for both SPI master and slave controllers, +it makes sense to rename it to struct spi_controller, and replace +"master" by "controller" where appropriate. + +For now this conversion is done for SPI core infrastructure only. +Wrappers are provided for backwards compatibility, until all SPI drivers +have been converted. + +Noteworthy details: + - SPI_MASTER_GPIO_SS is retained, as it only makes sense for SPI + master controllers, + - spi_busnum_to_master() is kept, as it looks up masters only, + - A new field spi_device.controller is added, but spi_device.master is + retained for compatibility (both are always initialized by + spi_alloc_device()), + - spi_flash_read() is used by SPI masters only. + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +--- + drivers/spi/spi.c | 1073 ++++++++++++++++++++++---------------------- + include/linux/spi/spi.h | 197 ++++---- + include/trace/events/spi.h | 26 +- + 3 files changed, 664 insertions(+), 632 deletions(-) + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index a403e3a..cd2e271 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -46,11 +46,11 @@ static void spidev_release(struct device *dev) + { + struct spi_device *spi = to_spi_device(dev); + +- /* spi masters may cleanup for released devices */ +- if (spi->master->cleanup) +- spi->master->cleanup(spi); ++ /* spi controllers may cleanup for released devices */ ++ if (spi->controller->cleanup) ++ spi->controller->cleanup(spi); + +- spi_master_put(spi->master); ++ spi_controller_put(spi->controller); + kfree(spi); + } + +@@ -69,17 +69,17 @@ static void spidev_release(struct device *dev) + static DEVICE_ATTR_RO(modalias); + + #define SPI_STATISTICS_ATTRS(field, file) \ +-static ssize_t spi_master_##field##_show(struct device *dev, \ +- struct device_attribute *attr, \ +- char *buf) \ ++static ssize_t spi_controller_##field##_show(struct device *dev, \ ++ struct device_attribute *attr, \ ++ char *buf) \ + { \ +- struct spi_master *master = container_of(dev, \ +- struct spi_master, dev); \ +- return spi_statistics_##field##_show(&master->statistics, buf); \ ++ struct spi_controller *ctlr = container_of(dev, \ ++ struct spi_controller, dev); \ ++ return spi_statistics_##field##_show(&ctlr->statistics, buf); \ + } \ +-static struct device_attribute dev_attr_spi_master_##field = { \ ++static struct device_attribute dev_attr_spi_controller_##field = { \ + .attr = { .name = file, .mode = S_IRUGO }, \ +- .show = spi_master_##field##_show, \ ++ .show = spi_controller_##field##_show, \ + }; \ + static ssize_t spi_device_##field##_show(struct device *dev, \ + struct device_attribute *attr, \ +@@ -199,51 +199,51 @@ static void spidev_release(struct device *dev) + NULL, + }; + +-static struct attribute *spi_master_statistics_attrs[] = { +- &dev_attr_spi_master_messages.attr, +- &dev_attr_spi_master_transfers.attr, +- &dev_attr_spi_master_errors.attr, +- &dev_attr_spi_master_timedout.attr, +- &dev_attr_spi_master_spi_sync.attr, +- &dev_attr_spi_master_spi_sync_immediate.attr, +- &dev_attr_spi_master_spi_async.attr, +- &dev_attr_spi_master_bytes.attr, +- &dev_attr_spi_master_bytes_rx.attr, +- &dev_attr_spi_master_bytes_tx.attr, +- &dev_attr_spi_master_transfer_bytes_histo0.attr, +- &dev_attr_spi_master_transfer_bytes_histo1.attr, +- &dev_attr_spi_master_transfer_bytes_histo2.attr, +- &dev_attr_spi_master_transfer_bytes_histo3.attr, +- &dev_attr_spi_master_transfer_bytes_histo4.attr, +- &dev_attr_spi_master_transfer_bytes_histo5.attr, +- &dev_attr_spi_master_transfer_bytes_histo6.attr, +- &dev_attr_spi_master_transfer_bytes_histo7.attr, +- &dev_attr_spi_master_transfer_bytes_histo8.attr, +- &dev_attr_spi_master_transfer_bytes_histo9.attr, +- &dev_attr_spi_master_transfer_bytes_histo10.attr, +- &dev_attr_spi_master_transfer_bytes_histo11.attr, +- &dev_attr_spi_master_transfer_bytes_histo12.attr, +- &dev_attr_spi_master_transfer_bytes_histo13.attr, +- &dev_attr_spi_master_transfer_bytes_histo14.attr, +- &dev_attr_spi_master_transfer_bytes_histo15.attr, +- &dev_attr_spi_master_transfer_bytes_histo16.attr, +- &dev_attr_spi_master_transfers_split_maxsize.attr, ++static struct attribute *spi_controller_statistics_attrs[] = { ++ &dev_attr_spi_controller_messages.attr, ++ &dev_attr_spi_controller_transfers.attr, ++ &dev_attr_spi_controller_errors.attr, ++ &dev_attr_spi_controller_timedout.attr, ++ &dev_attr_spi_controller_spi_sync.attr, ++ &dev_attr_spi_controller_spi_sync_immediate.attr, ++ &dev_attr_spi_controller_spi_async.attr, ++ &dev_attr_spi_controller_bytes.attr, ++ &dev_attr_spi_controller_bytes_rx.attr, ++ &dev_attr_spi_controller_bytes_tx.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo0.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo1.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo2.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo3.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo4.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo5.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo6.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo7.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo8.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo9.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo10.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo11.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo12.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo13.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo14.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo15.attr, ++ &dev_attr_spi_controller_transfer_bytes_histo16.attr, ++ &dev_attr_spi_controller_transfers_split_maxsize.attr, + NULL, + }; + +-static const struct attribute_group spi_master_statistics_group = { ++static const struct attribute_group spi_controller_statistics_group = { + .name = "statistics", +- .attrs = spi_master_statistics_attrs, ++ .attrs = spi_controller_statistics_attrs, + }; + + static const struct attribute_group *spi_master_groups[] = { +- &spi_master_statistics_group, ++ &spi_controller_statistics_group, + NULL, + }; + + void spi_statistics_add_transfer_stats(struct spi_statistics *stats, + struct spi_transfer *xfer, +- struct spi_master *master) ++ struct spi_controller *ctlr) + { + unsigned long flags; + int l2len = min(fls(xfer->len), SPI_STATISTICS_HISTO_SIZE) - 1; +@@ -258,10 +258,10 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats, + + stats->bytes += xfer->len; + if ((xfer->tx_buf) && +- (xfer->tx_buf != master->dummy_tx)) ++ (xfer->tx_buf != ctlr->dummy_tx)) + stats->bytes_tx += xfer->len; + if ((xfer->rx_buf) && +- (xfer->rx_buf != master->dummy_rx)) ++ (xfer->rx_buf != ctlr->dummy_rx)) + stats->bytes_rx += xfer->len; + + spin_unlock_irqrestore(&stats->lock, flags); +@@ -403,7 +403,7 @@ int __spi_register_driver(struct module *owner, struct spi_driver *sdrv) + /*-------------------------------------------------------------------------*/ + + /* SPI devices should normally not be created by SPI device drivers; that +- * would make them board-specific. Similarly with SPI master drivers. ++ * would make them board-specific. Similarly with SPI controller drivers. + * Device registration normally goes into like arch/.../mach.../board-YYY.c + * with other readonly (flashable) information about mainboard devices. + */ +@@ -414,17 +414,17 @@ struct boardinfo { + }; + + static LIST_HEAD(board_list); +-static LIST_HEAD(spi_master_list); ++static LIST_HEAD(spi_controller_list); + + /* + * Used to protect add/del opertion for board_info list and +- * spi_master list, and their matching process ++ * spi_controller list, and their matching process + */ + static DEFINE_MUTEX(board_lock); + + /** + * spi_alloc_device - Allocate a new SPI device +- * @master: Controller to which device is connected ++ * @ctlr: Controller to which device is connected + * Context: can sleep + * + * Allows a driver to allocate and initialize a spi_device without +@@ -433,27 +433,27 @@ struct boardinfo { + * spi_add_device() on it. + * + * Caller is responsible to call spi_add_device() on the returned +- * spi_device structure to add it to the SPI master. If the caller ++ * spi_device structure to add it to the SPI controller. If the caller + * needs to discard the spi_device without adding it, then it should + * call spi_dev_put() on it. + * + * Return: a pointer to the new device, or NULL. + */ +-struct spi_device *spi_alloc_device(struct spi_master *master) ++struct spi_device *spi_alloc_device(struct spi_controller *ctlr) + { + struct spi_device *spi; + +- if (!spi_master_get(master)) ++ if (!spi_controller_get(ctlr)) + return NULL; + + spi = kzalloc(sizeof(*spi), GFP_KERNEL); + if (!spi) { +- spi_master_put(master); ++ spi_controller_put(ctlr); + return NULL; + } + +- spi->master = master; +- spi->dev.parent = &master->dev; ++ spi->master = spi->controller = ctlr; ++ spi->dev.parent = &ctlr->dev; + spi->dev.bus = &spi_bus_type; + spi->dev.release = spidev_release; + spi->cs_gpio = -ENOENT; +@@ -474,7 +474,7 @@ static void spi_dev_set_name(struct spi_device *spi) + return; + } + +- dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev), ++ dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev), + spi->chip_select); + } + +@@ -483,7 +483,7 @@ static int spi_dev_check(struct device *dev, void *data) + struct spi_device *spi = to_spi_device(dev); + struct spi_device *new_spi = data; + +- if (spi->master == new_spi->master && ++ if (spi->controller == new_spi->controller && + spi->chip_select == new_spi->chip_select) + return -EBUSY; + return 0; +@@ -501,15 +501,14 @@ static int spi_dev_check(struct device *dev, void *data) + int spi_add_device(struct spi_device *spi) + { + static DEFINE_MUTEX(spi_add_lock); +- struct spi_master *master = spi->master; +- struct device *dev = master->dev.parent; ++ struct spi_controller *ctlr = spi->controller; ++ struct device *dev = ctlr->dev.parent; + int status; + + /* Chipselects are numbered 0..max; validate. */ +- if (spi->chip_select >= master->num_chipselect) { +- dev_err(dev, "cs%d >= max %d\n", +- spi->chip_select, +- master->num_chipselect); ++ if (spi->chip_select >= ctlr->num_chipselect) { ++ dev_err(dev, "cs%d >= max %d\n", spi->chip_select, ++ ctlr->num_chipselect); + return -EINVAL; + } + +@@ -529,8 +528,8 @@ int spi_add_device(struct spi_device *spi) + goto done; + } + +- if (master->cs_gpios) +- spi->cs_gpio = master->cs_gpios[spi->chip_select]; ++ if (ctlr->cs_gpios) ++ spi->cs_gpio = ctlr->cs_gpios[spi->chip_select]; + + /* Drivers may modify this initial i/o setup, but will + * normally rely on the device being setup. Devices +@@ -559,7 +558,7 @@ int spi_add_device(struct spi_device *spi) + + /** + * spi_new_device - instantiate one new SPI device +- * @master: Controller to which device is connected ++ * @ctlr: Controller to which device is connected + * @chip: Describes the SPI device + * Context: can sleep + * +@@ -571,7 +570,7 @@ int spi_add_device(struct spi_device *spi) + * + * Return: the new device, or NULL. + */ +-struct spi_device *spi_new_device(struct spi_master *master, ++struct spi_device *spi_new_device(struct spi_controller *ctlr, + struct spi_board_info *chip) + { + struct spi_device *proxy; +@@ -584,7 +583,7 @@ struct spi_device *spi_new_device(struct spi_master *master, + * suggests syslogged diagnostics are best here (ugh). + */ + +- proxy = spi_alloc_device(master); ++ proxy = spi_alloc_device(ctlr); + if (!proxy) + return NULL; + +@@ -614,7 +613,7 @@ struct spi_device *spi_new_device(struct spi_master *master, + * @spi: spi_device to unregister + * + * Start making the passed SPI device vanish. Normally this would be handled +- * by spi_unregister_master(). ++ * by spi_unregister_controller(). + */ + void spi_unregister_device(struct spi_device *spi) + { +@@ -629,17 +628,17 @@ void spi_unregister_device(struct spi_device *spi) + } + EXPORT_SYMBOL_GPL(spi_unregister_device); + +-static void spi_match_master_to_boardinfo(struct spi_master *master, +- struct spi_board_info *bi) ++static void spi_match_controller_to_boardinfo(struct spi_controller *ctlr, ++ struct spi_board_info *bi) + { + struct spi_device *dev; + +- if (master->bus_num != bi->bus_num) ++ if (ctlr->bus_num != bi->bus_num) + return; + +- dev = spi_new_device(master, bi); ++ dev = spi_new_device(ctlr, bi); + if (!dev) +- dev_err(master->dev.parent, "can't create new device for %s\n", ++ dev_err(ctlr->dev.parent, "can't create new device for %s\n", + bi->modalias); + } + +@@ -677,13 +676,14 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) + return -ENOMEM; + + for (i = 0; i < n; i++, bi++, info++) { +- struct spi_master *master; ++ struct spi_controller *ctlr; + + memcpy(&bi->board_info, info, sizeof(*info)); + mutex_lock(&board_lock); + list_add_tail(&bi->list, &board_list); +- list_for_each_entry(master, &spi_master_list, list) +- spi_match_master_to_boardinfo(master, &bi->board_info); ++ list_for_each_entry(ctlr, &spi_controller_list, list) ++ spi_match_controller_to_boardinfo(ctlr, ++ &bi->board_info); + mutex_unlock(&board_lock); + } + +@@ -699,12 +699,12 @@ static void spi_set_cs(struct spi_device *spi, bool enable) + + if (gpio_is_valid(spi->cs_gpio)) + gpio_set_value(spi->cs_gpio, !enable); +- else if (spi->master->set_cs) +- spi->master->set_cs(spi, !enable); ++ else if (spi->controller->set_cs) ++ spi->controller->set_cs(spi, !enable); + } + + #ifdef CONFIG_HAS_DMA +-static int spi_map_buf(struct spi_master *master, struct device *dev, ++static int spi_map_buf(struct spi_controller *ctlr, struct device *dev, + struct sg_table *sgt, void *buf, size_t len, + enum dma_data_direction dir) + { +@@ -728,7 +728,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, + desc_len = min_t(int, max_seg_size, PAGE_SIZE); + sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len); + } else if (virt_addr_valid(buf)) { +- desc_len = min_t(int, max_seg_size, master->max_dma_len); ++ desc_len = min_t(int, max_seg_size, ctlr->max_dma_len); + sgs = DIV_ROUND_UP(len, desc_len); + } else { + return -EINVAL; +@@ -776,7 +776,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, + return 0; + } + +-static void spi_unmap_buf(struct spi_master *master, struct device *dev, ++static void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev, + struct sg_table *sgt, enum dma_data_direction dir) + { + if (sgt->orig_nents) { +@@ -785,31 +785,31 @@ static void spi_unmap_buf(struct spi_master *master, struct device *dev, + } + } + +-static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) ++static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) + { + struct device *tx_dev, *rx_dev; + struct spi_transfer *xfer; + int ret; + +- if (!master->can_dma) ++ if (!ctlr->can_dma) + return 0; + +- if (master->dma_tx) +- tx_dev = master->dma_tx->device->dev; ++ if (ctlr->dma_tx) ++ tx_dev = ctlr->dma_tx->device->dev; + else +- tx_dev = &master->dev; ++ tx_dev = &ctlr->dev; + +- if (master->dma_rx) +- rx_dev = master->dma_rx->device->dev; ++ if (ctlr->dma_rx) ++ rx_dev = ctlr->dma_rx->device->dev; + else +- rx_dev = &master->dev; ++ rx_dev = &ctlr->dev; + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { +- if (!master->can_dma(master, msg->spi, xfer)) ++ if (!ctlr->can_dma(ctlr, msg->spi, xfer)) + continue; + + if (xfer->tx_buf != NULL) { +- ret = spi_map_buf(master, tx_dev, &xfer->tx_sg, ++ ret = spi_map_buf(ctlr, tx_dev, &xfer->tx_sg, + (void *)xfer->tx_buf, xfer->len, + DMA_TO_DEVICE); + if (ret != 0) +@@ -817,79 +817,78 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) + } + + if (xfer->rx_buf != NULL) { +- ret = spi_map_buf(master, rx_dev, &xfer->rx_sg, ++ ret = spi_map_buf(ctlr, rx_dev, &xfer->rx_sg, + xfer->rx_buf, xfer->len, + DMA_FROM_DEVICE); + if (ret != 0) { +- spi_unmap_buf(master, tx_dev, &xfer->tx_sg, ++ spi_unmap_buf(ctlr, tx_dev, &xfer->tx_sg, + DMA_TO_DEVICE); + return ret; + } + } + } + +- master->cur_msg_mapped = true; ++ ctlr->cur_msg_mapped = true; + + return 0; + } + +-static int __spi_unmap_msg(struct spi_master *master, struct spi_message *msg) ++static int __spi_unmap_msg(struct spi_controller *ctlr, struct spi_message *msg) + { + struct spi_transfer *xfer; + struct device *tx_dev, *rx_dev; + +- if (!master->cur_msg_mapped || !master->can_dma) ++ if (!ctlr->cur_msg_mapped || !ctlr->can_dma) + return 0; + +- if (master->dma_tx) +- tx_dev = master->dma_tx->device->dev; ++ if (ctlr->dma_tx) ++ tx_dev = ctlr->dma_tx->device->dev; + else +- tx_dev = &master->dev; ++ tx_dev = &ctlr->dev; + +- if (master->dma_rx) +- rx_dev = master->dma_rx->device->dev; ++ if (ctlr->dma_rx) ++ rx_dev = ctlr->dma_rx->device->dev; + else +- rx_dev = &master->dev; ++ rx_dev = &ctlr->dev; + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { +- if (!master->can_dma(master, msg->spi, xfer)) ++ if (!ctlr->can_dma(ctlr, msg->spi, xfer)) + continue; + +- spi_unmap_buf(master, rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE); +- spi_unmap_buf(master, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE); ++ spi_unmap_buf(ctlr, rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE); ++ spi_unmap_buf(ctlr, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE); + } + + return 0; + } + #else /* !CONFIG_HAS_DMA */ +-static inline int spi_map_buf(struct spi_master *master, +- struct device *dev, struct sg_table *sgt, +- void *buf, size_t len, ++static inline int spi_map_buf(struct spi_controller *ctlr, struct device *dev, ++ struct sg_table *sgt, void *buf, size_t len, + enum dma_data_direction dir) + { + return -EINVAL; + } + +-static inline void spi_unmap_buf(struct spi_master *master, ++static inline void spi_unmap_buf(struct spi_controller *ctlr, + struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir) + { + } + +-static inline int __spi_map_msg(struct spi_master *master, ++static inline int __spi_map_msg(struct spi_controller *ctlr, + struct spi_message *msg) + { + return 0; + } + +-static inline int __spi_unmap_msg(struct spi_master *master, ++static inline int __spi_unmap_msg(struct spi_controller *ctlr, + struct spi_message *msg) + { + return 0; + } + #endif /* !CONFIG_HAS_DMA */ + +-static inline int spi_unmap_msg(struct spi_master *master, ++static inline int spi_unmap_msg(struct spi_controller *ctlr, + struct spi_message *msg) + { + struct spi_transfer *xfer; +@@ -899,63 +898,63 @@ static inline int spi_unmap_msg(struct spi_master *master, + * Restore the original value of tx_buf or rx_buf if they are + * NULL. + */ +- if (xfer->tx_buf == master->dummy_tx) ++ if (xfer->tx_buf == ctlr->dummy_tx) + xfer->tx_buf = NULL; +- if (xfer->rx_buf == master->dummy_rx) ++ if (xfer->rx_buf == ctlr->dummy_rx) + xfer->rx_buf = NULL; + } + +- return __spi_unmap_msg(master, msg); ++ return __spi_unmap_msg(ctlr, msg); + } + +-static int spi_map_msg(struct spi_master *master, struct spi_message *msg) ++static int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) + { + struct spi_transfer *xfer; + void *tmp; + unsigned int max_tx, max_rx; + +- if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) { ++ if (ctlr->flags & (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX)) { + max_tx = 0; + max_rx = 0; + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { +- if ((master->flags & SPI_MASTER_MUST_TX) && ++ if ((ctlr->flags & SPI_CONTROLLER_MUST_TX) && + !xfer->tx_buf) + max_tx = max(xfer->len, max_tx); +- if ((master->flags & SPI_MASTER_MUST_RX) && ++ if ((ctlr->flags & SPI_CONTROLLER_MUST_RX) && + !xfer->rx_buf) + max_rx = max(xfer->len, max_rx); + } + + if (max_tx) { +- tmp = krealloc(master->dummy_tx, max_tx, ++ tmp = krealloc(ctlr->dummy_tx, max_tx, + GFP_KERNEL | GFP_DMA); + if (!tmp) + return -ENOMEM; +- master->dummy_tx = tmp; ++ ctlr->dummy_tx = tmp; + memset(tmp, 0, max_tx); + } + + if (max_rx) { +- tmp = krealloc(master->dummy_rx, max_rx, ++ tmp = krealloc(ctlr->dummy_rx, max_rx, + GFP_KERNEL | GFP_DMA); + if (!tmp) + return -ENOMEM; +- master->dummy_rx = tmp; ++ ctlr->dummy_rx = tmp; + } + + if (max_tx || max_rx) { + list_for_each_entry(xfer, &msg->transfers, + transfer_list) { + if (!xfer->tx_buf) +- xfer->tx_buf = master->dummy_tx; ++ xfer->tx_buf = ctlr->dummy_tx; + if (!xfer->rx_buf) +- xfer->rx_buf = master->dummy_rx; ++ xfer->rx_buf = ctlr->dummy_rx; + } + } + } + +- return __spi_map_msg(master, msg); ++ return __spi_map_msg(ctlr, msg); + } + + /* +@@ -965,14 +964,14 @@ static int spi_map_msg(struct spi_master *master, struct spi_message *msg) + * drivers which implement a transfer_one() operation. It provides + * standard handling of delays and chip select management. + */ +-static int spi_transfer_one_message(struct spi_master *master, ++static int spi_transfer_one_message(struct spi_controller *ctlr, + struct spi_message *msg) + { + struct spi_transfer *xfer; + bool keep_cs = false; + int ret = 0; + unsigned long long ms = 1; +- struct spi_statistics *statm = &master->statistics; ++ struct spi_statistics *statm = &ctlr->statistics; + struct spi_statistics *stats = &msg->spi->statistics; + + spi_set_cs(msg->spi, true); +@@ -983,13 +982,13 @@ static int spi_transfer_one_message(struct spi_master *master, + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + trace_spi_transfer_start(msg, xfer); + +- spi_statistics_add_transfer_stats(statm, xfer, master); +- spi_statistics_add_transfer_stats(stats, xfer, master); ++ spi_statistics_add_transfer_stats(statm, xfer, ctlr); ++ spi_statistics_add_transfer_stats(stats, xfer, ctlr); + + if (xfer->tx_buf || xfer->rx_buf) { +- reinit_completion(&master->xfer_completion); ++ reinit_completion(&ctlr->xfer_completion); + +- ret = master->transfer_one(master, msg->spi, xfer); ++ ret = ctlr->transfer_one(ctlr, msg->spi, xfer); + if (ret < 0) { + SPI_STATISTICS_INCREMENT_FIELD(statm, + errors); +@@ -1009,7 +1008,7 @@ static int spi_transfer_one_message(struct spi_master *master, + if (ms > UINT_MAX) + ms = UINT_MAX; + +- ms = wait_for_completion_timeout(&master->xfer_completion, ++ ms = wait_for_completion_timeout(&ctlr->xfer_completion, + msecs_to_jiffies(ms)); + } + +@@ -1058,33 +1057,33 @@ static int spi_transfer_one_message(struct spi_master *master, + if (msg->status == -EINPROGRESS) + msg->status = ret; + +- if (msg->status && master->handle_err) +- master->handle_err(master, msg); ++ if (msg->status && ctlr->handle_err) ++ ctlr->handle_err(ctlr, msg); + +- spi_res_release(master, msg); ++ spi_res_release(ctlr, msg); + +- spi_finalize_current_message(master); ++ spi_finalize_current_message(ctlr); + + return ret; + } + + /** + * spi_finalize_current_transfer - report completion of a transfer +- * @master: the master reporting completion ++ * @ctlr: the controller reporting completion + * + * Called by SPI drivers using the core transfer_one_message() + * implementation to notify it that the current interrupt driven + * transfer has finished and the next one may be scheduled. + */ +-void spi_finalize_current_transfer(struct spi_master *master) ++void spi_finalize_current_transfer(struct spi_controller *ctlr) + { +- complete(&master->xfer_completion); ++ complete(&ctlr->xfer_completion); + } + EXPORT_SYMBOL_GPL(spi_finalize_current_transfer); + + /** + * __spi_pump_messages - function which processes spi message queue +- * @master: master to process queue for ++ * @ctlr: controller to process queue for + * @in_kthread: true if we are in the context of the message pump thread + * + * This function checks if there is any spi message in the queue that +@@ -1095,136 +1094,136 @@ void spi_finalize_current_transfer(struct spi_master *master) + * inside spi_sync(); the queue extraction handling at the top of the + * function should deal with this safely. + */ +-static void __spi_pump_messages(struct spi_master *master, bool in_kthread) ++static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) + { + unsigned long flags; + bool was_busy = false; + int ret; + + /* Lock queue */ +- spin_lock_irqsave(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); + + /* Make sure we are not already running a message */ +- if (master->cur_msg) { +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ if (ctlr->cur_msg) { ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return; + } + + /* If another context is idling the device then defer */ +- if (master->idling) { +- kthread_queue_work(&master->kworker, &master->pump_messages); +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ if (ctlr->idling) { ++ kthread_queue_work(&ctlr->kworker, &ctlr->pump_messages); ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return; + } + + /* Check if the queue is idle */ +- if (list_empty(&master->queue) || !master->running) { +- if (!master->busy) { +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ if (list_empty(&ctlr->queue) || !ctlr->running) { ++ if (!ctlr->busy) { ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return; + } + + /* Only do teardown in the thread */ + if (!in_kthread) { +- kthread_queue_work(&master->kworker, +- &master->pump_messages); +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ kthread_queue_work(&ctlr->kworker, ++ &ctlr->pump_messages); ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return; + } + +- master->busy = false; +- master->idling = true; +- spin_unlock_irqrestore(&master->queue_lock, flags); +- +- kfree(master->dummy_rx); +- master->dummy_rx = NULL; +- kfree(master->dummy_tx); +- master->dummy_tx = NULL; +- if (master->unprepare_transfer_hardware && +- master->unprepare_transfer_hardware(master)) +- dev_err(&master->dev, ++ ctlr->busy = false; ++ ctlr->idling = true; ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); ++ ++ kfree(ctlr->dummy_rx); ++ ctlr->dummy_rx = NULL; ++ kfree(ctlr->dummy_tx); ++ ctlr->dummy_tx = NULL; ++ if (ctlr->unprepare_transfer_hardware && ++ ctlr->unprepare_transfer_hardware(ctlr)) ++ dev_err(&ctlr->dev, + "failed to unprepare transfer hardware\n"); +- if (master->auto_runtime_pm) { +- pm_runtime_mark_last_busy(master->dev.parent); +- pm_runtime_put_autosuspend(master->dev.parent); ++ if (ctlr->auto_runtime_pm) { ++ pm_runtime_mark_last_busy(ctlr->dev.parent); ++ pm_runtime_put_autosuspend(ctlr->dev.parent); + } +- trace_spi_master_idle(master); ++ trace_spi_controller_idle(ctlr); + +- spin_lock_irqsave(&master->queue_lock, flags); +- master->idling = false; +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); ++ ctlr->idling = false; ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return; + } + + /* Extract head of queue */ +- master->cur_msg = +- list_first_entry(&master->queue, struct spi_message, queue); ++ ctlr->cur_msg = ++ list_first_entry(&ctlr->queue, struct spi_message, queue); + +- list_del_init(&master->cur_msg->queue); +- if (master->busy) ++ list_del_init(&ctlr->cur_msg->queue); ++ if (ctlr->busy) + was_busy = true; + else +- master->busy = true; +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ ctlr->busy = true; ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + +- mutex_lock(&master->io_mutex); ++ mutex_lock(&ctlr->io_mutex); + +- if (!was_busy && master->auto_runtime_pm) { +- ret = pm_runtime_get_sync(master->dev.parent); ++ if (!was_busy && ctlr->auto_runtime_pm) { ++ ret = pm_runtime_get_sync(ctlr->dev.parent); + if (ret < 0) { +- dev_err(&master->dev, "Failed to power device: %d\n", ++ dev_err(&ctlr->dev, "Failed to power device: %d\n", + ret); +- mutex_unlock(&master->io_mutex); ++ mutex_unlock(&ctlr->io_mutex); + return; + } + } + + if (!was_busy) +- trace_spi_master_busy(master); ++ trace_spi_controller_busy(ctlr); + +- if (!was_busy && master->prepare_transfer_hardware) { +- ret = master->prepare_transfer_hardware(master); ++ if (!was_busy && ctlr->prepare_transfer_hardware) { ++ ret = ctlr->prepare_transfer_hardware(ctlr); + if (ret) { +- dev_err(&master->dev, ++ dev_err(&ctlr->dev, + "failed to prepare transfer hardware\n"); + +- if (master->auto_runtime_pm) +- pm_runtime_put(master->dev.parent); +- mutex_unlock(&master->io_mutex); ++ if (ctlr->auto_runtime_pm) ++ pm_runtime_put(ctlr->dev.parent); ++ mutex_unlock(&ctlr->io_mutex); + return; + } + } + +- trace_spi_message_start(master->cur_msg); ++ trace_spi_message_start(ctlr->cur_msg); + +- if (master->prepare_message) { +- ret = master->prepare_message(master, master->cur_msg); ++ if (ctlr->prepare_message) { ++ ret = ctlr->prepare_message(ctlr, ctlr->cur_msg); + if (ret) { +- dev_err(&master->dev, +- "failed to prepare message: %d\n", ret); +- master->cur_msg->status = ret; +- spi_finalize_current_message(master); ++ dev_err(&ctlr->dev, "failed to prepare message: %d\n", ++ ret); ++ ctlr->cur_msg->status = ret; ++ spi_finalize_current_message(ctlr); + goto out; + } +- master->cur_msg_prepared = true; ++ ctlr->cur_msg_prepared = true; + } + +- ret = spi_map_msg(master, master->cur_msg); ++ ret = spi_map_msg(ctlr, ctlr->cur_msg); + if (ret) { +- master->cur_msg->status = ret; +- spi_finalize_current_message(master); ++ ctlr->cur_msg->status = ret; ++ spi_finalize_current_message(ctlr); + goto out; + } + +- ret = master->transfer_one_message(master, master->cur_msg); ++ ret = ctlr->transfer_one_message(ctlr, ctlr->cur_msg); + if (ret) { +- dev_err(&master->dev, ++ dev_err(&ctlr->dev, + "failed to transfer one message from queue\n"); + goto out; + } + + out: +- mutex_unlock(&master->io_mutex); ++ mutex_unlock(&ctlr->io_mutex); + + /* Prod the scheduler in case transfer_one() was busy waiting */ + if (!ret) +@@ -1233,44 +1232,43 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) + + /** + * spi_pump_messages - kthread work function which processes spi message queue +- * @work: pointer to kthread work struct contained in the master struct ++ * @work: pointer to kthread work struct contained in the controller struct + */ + static void spi_pump_messages(struct kthread_work *work) + { +- struct spi_master *master = +- container_of(work, struct spi_master, pump_messages); ++ struct spi_controller *ctlr = ++ container_of(work, struct spi_controller, pump_messages); + +- __spi_pump_messages(master, true); ++ __spi_pump_messages(ctlr, true); + } + +-static int spi_init_queue(struct spi_master *master) ++static int spi_init_queue(struct spi_controller *ctlr) + { + struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; + +- master->running = false; +- master->busy = false; ++ ctlr->running = false; ++ ctlr->busy = false; + +- kthread_init_worker(&master->kworker); +- master->kworker_task = kthread_run(kthread_worker_fn, +- &master->kworker, "%s", +- dev_name(&master->dev)); +- if (IS_ERR(master->kworker_task)) { +- dev_err(&master->dev, "failed to create message pump task\n"); +- return PTR_ERR(master->kworker_task); ++ kthread_init_worker(&ctlr->kworker); ++ ctlr->kworker_task = kthread_run(kthread_worker_fn, &ctlr->kworker, ++ "%s", dev_name(&ctlr->dev)); ++ if (IS_ERR(ctlr->kworker_task)) { ++ dev_err(&ctlr->dev, "failed to create message pump task\n"); ++ return PTR_ERR(ctlr->kworker_task); + } +- kthread_init_work(&master->pump_messages, spi_pump_messages); ++ kthread_init_work(&ctlr->pump_messages, spi_pump_messages); + + /* +- * Master config will indicate if this controller should run the ++ * Controller config will indicate if this controller should run the + * message pump with high (realtime) priority to reduce the transfer + * latency on the bus by minimising the delay between a transfer + * request and the scheduling of the message pump thread. Without this + * setting the message pump thread will remain at default priority. + */ +- if (master->rt) { +- dev_info(&master->dev, ++ if (ctlr->rt) { ++ dev_info(&ctlr->dev, + "will run message pump with realtime priority\n"); +- sched_setscheduler(master->kworker_task, SCHED_FIFO, ¶m); ++ sched_setscheduler(ctlr->kworker_task, SCHED_FIFO, ¶m); + } + + return 0; +@@ -1279,23 +1277,23 @@ static int spi_init_queue(struct spi_master *master) + /** + * spi_get_next_queued_message() - called by driver to check for queued + * messages +- * @master: the master to check for queued messages ++ * @ctlr: the controller to check for queued messages + * + * If there are more messages in the queue, the next message is returned from + * this call. + * + * Return: the next message in the queue, else NULL if the queue is empty. + */ +-struct spi_message *spi_get_next_queued_message(struct spi_master *master) ++struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr) + { + struct spi_message *next; + unsigned long flags; + + /* get a pointer to the next message, if any */ +- spin_lock_irqsave(&master->queue_lock, flags); +- next = list_first_entry_or_null(&master->queue, struct spi_message, ++ spin_lock_irqsave(&ctlr->queue_lock, flags); ++ next = list_first_entry_or_null(&ctlr->queue, struct spi_message, + queue); +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + + return next; + } +@@ -1303,36 +1301,36 @@ struct spi_message *spi_get_next_queued_message(struct spi_master *master) + + /** + * spi_finalize_current_message() - the current message is complete +- * @master: the master to return the message to ++ * @ctlr: the controller to return the message to + * + * Called by the driver to notify the core that the message in the front of the + * queue is complete and can be removed from the queue. + */ +-void spi_finalize_current_message(struct spi_master *master) ++void spi_finalize_current_message(struct spi_controller *ctlr) + { + struct spi_message *mesg; + unsigned long flags; + int ret; + +- spin_lock_irqsave(&master->queue_lock, flags); +- mesg = master->cur_msg; +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); ++ mesg = ctlr->cur_msg; ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + +- spi_unmap_msg(master, mesg); ++ spi_unmap_msg(ctlr, mesg); + +- if (master->cur_msg_prepared && master->unprepare_message) { +- ret = master->unprepare_message(master, mesg); ++ if (ctlr->cur_msg_prepared && ctlr->unprepare_message) { ++ ret = ctlr->unprepare_message(ctlr, mesg); + if (ret) { +- dev_err(&master->dev, +- "failed to unprepare message: %d\n", ret); ++ dev_err(&ctlr->dev, "failed to unprepare message: %d\n", ++ ret); + } + } + +- spin_lock_irqsave(&master->queue_lock, flags); +- master->cur_msg = NULL; +- master->cur_msg_prepared = false; +- kthread_queue_work(&master->kworker, &master->pump_messages); +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); ++ ctlr->cur_msg = NULL; ++ ctlr->cur_msg_prepared = false; ++ kthread_queue_work(&ctlr->kworker, &ctlr->pump_messages); ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + + trace_spi_message_done(mesg); + +@@ -1342,66 +1340,65 @@ void spi_finalize_current_message(struct spi_master *master) + } + EXPORT_SYMBOL_GPL(spi_finalize_current_message); + +-static int spi_start_queue(struct spi_master *master) ++static int spi_start_queue(struct spi_controller *ctlr) + { + unsigned long flags; + +- spin_lock_irqsave(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); + +- if (master->running || master->busy) { +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ if (ctlr->running || ctlr->busy) { ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return -EBUSY; + } + +- master->running = true; +- master->cur_msg = NULL; +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ ctlr->running = true; ++ ctlr->cur_msg = NULL; ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + +- kthread_queue_work(&master->kworker, &master->pump_messages); ++ kthread_queue_work(&ctlr->kworker, &ctlr->pump_messages); + + return 0; + } + +-static int spi_stop_queue(struct spi_master *master) ++static int spi_stop_queue(struct spi_controller *ctlr) + { + unsigned long flags; + unsigned limit = 500; + int ret = 0; + +- spin_lock_irqsave(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); + + /* + * This is a bit lame, but is optimized for the common execution path. +- * A wait_queue on the master->busy could be used, but then the common ++ * A wait_queue on the ctlr->busy could be used, but then the common + * execution path (pump_messages) would be required to call wake_up or + * friends on every SPI message. Do this instead. + */ +- while ((!list_empty(&master->queue) || master->busy) && limit--) { +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ while ((!list_empty(&ctlr->queue) || ctlr->busy) && limit--) { ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + usleep_range(10000, 11000); +- spin_lock_irqsave(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); + } + +- if (!list_empty(&master->queue) || master->busy) ++ if (!list_empty(&ctlr->queue) || ctlr->busy) + ret = -EBUSY; + else +- master->running = false; ++ ctlr->running = false; + +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + + if (ret) { +- dev_warn(&master->dev, +- "could not stop message queue\n"); ++ dev_warn(&ctlr->dev, "could not stop message queue\n"); + return ret; + } + return ret; + } + +-static int spi_destroy_queue(struct spi_master *master) ++static int spi_destroy_queue(struct spi_controller *ctlr) + { + int ret; + +- ret = spi_stop_queue(master); ++ ret = spi_stop_queue(ctlr); + + /* + * kthread_flush_worker will block until all work is done. +@@ -1410,12 +1407,12 @@ static int spi_destroy_queue(struct spi_master *master) + * return anyway. + */ + if (ret) { +- dev_err(&master->dev, "problem destroying queue\n"); ++ dev_err(&ctlr->dev, "problem destroying queue\n"); + return ret; + } + +- kthread_flush_worker(&master->kworker); +- kthread_stop(master->kworker_task); ++ kthread_flush_worker(&ctlr->kworker); ++ kthread_stop(ctlr->kworker_task); + + return 0; + } +@@ -1424,23 +1421,23 @@ static int __spi_queued_transfer(struct spi_device *spi, + struct spi_message *msg, + bool need_pump) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + unsigned long flags; + +- spin_lock_irqsave(&master->queue_lock, flags); ++ spin_lock_irqsave(&ctlr->queue_lock, flags); + +- if (!master->running) { +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ if (!ctlr->running) { ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return -ESHUTDOWN; + } + msg->actual_length = 0; + msg->status = -EINPROGRESS; + +- list_add_tail(&msg->queue, &master->queue); +- if (!master->busy && need_pump) +- kthread_queue_work(&master->kworker, &master->pump_messages); ++ list_add_tail(&msg->queue, &ctlr->queue); ++ if (!ctlr->busy && need_pump) ++ kthread_queue_work(&ctlr->kworker, &ctlr->pump_messages); + +- spin_unlock_irqrestore(&master->queue_lock, flags); ++ spin_unlock_irqrestore(&ctlr->queue_lock, flags); + return 0; + } + +@@ -1456,31 +1453,31 @@ static int spi_queued_transfer(struct spi_device *spi, struct spi_message *msg) + return __spi_queued_transfer(spi, msg, true); + } + +-static int spi_master_initialize_queue(struct spi_master *master) ++static int spi_controller_initialize_queue(struct spi_controller *ctlr) + { + int ret; + +- master->transfer = spi_queued_transfer; +- if (!master->transfer_one_message) +- master->transfer_one_message = spi_transfer_one_message; ++ ctlr->transfer = spi_queued_transfer; ++ if (!ctlr->transfer_one_message) ++ ctlr->transfer_one_message = spi_transfer_one_message; + + /* Initialize and start queue */ +- ret = spi_init_queue(master); ++ ret = spi_init_queue(ctlr); + if (ret) { +- dev_err(&master->dev, "problem initializing queue\n"); ++ dev_err(&ctlr->dev, "problem initializing queue\n"); + goto err_init_queue; + } +- master->queued = true; +- ret = spi_start_queue(master); ++ ctlr->queued = true; ++ ret = spi_start_queue(ctlr); + if (ret) { +- dev_err(&master->dev, "problem starting queue\n"); ++ dev_err(&ctlr->dev, "problem starting queue\n"); + goto err_start_queue; + } + + return 0; + + err_start_queue: +- spi_destroy_queue(master); ++ spi_destroy_queue(ctlr); + err_init_queue: + return ret; + } +@@ -1489,16 +1486,16 @@ static int spi_master_initialize_queue(struct spi_master *master) + + #if defined(CONFIG_OF) + static struct spi_device * +-of_register_spi_device(struct spi_master *master, struct device_node *nc) ++of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) + { + struct spi_device *spi; + int rc; + u32 value; + + /* Alloc an spi_device */ +- spi = spi_alloc_device(master); ++ spi = spi_alloc_device(ctlr); + if (!spi) { +- dev_err(&master->dev, "spi_device alloc error for %s\n", ++ dev_err(&ctlr->dev, "spi_device alloc error for %s\n", + nc->full_name); + rc = -ENOMEM; + goto err_out; +@@ -1508,7 +1505,7 @@ static int spi_master_initialize_queue(struct spi_master *master) + rc = of_modalias_node(nc, spi->modalias, + sizeof(spi->modalias)); + if (rc < 0) { +- dev_err(&master->dev, "cannot find modalias for %s\n", ++ dev_err(&ctlr->dev, "cannot find modalias for %s\n", + nc->full_name); + goto err_out; + } +@@ -1537,7 +1534,7 @@ static int spi_master_initialize_queue(struct spi_master *master) + spi->mode |= SPI_TX_QUAD; + break; + default: +- dev_warn(&master->dev, ++ dev_warn(&ctlr->dev, + "spi-tx-bus-width %d not supported\n", + value); + break; +@@ -1555,35 +1552,36 @@ static int spi_master_initialize_queue(struct spi_master *master) + spi->mode |= SPI_RX_QUAD; + break; + default: +- dev_warn(&master->dev, ++ dev_warn(&ctlr->dev, + "spi-rx-bus-width %d not supported\n", + value); + break; + } + } + +- if (spi_controller_is_slave(master)) { ++ if (spi_controller_is_slave(ctlr)) { + if (strcmp(nc->name, "slave")) { +- dev_err(&master->dev, "%s is not called 'slave'\n", ++ dev_err(&ctlr->dev, "%s is not called 'slave'\n", + nc->full_name); +- return -EINVAL; ++ rc = -EINVAL; ++ goto err_out; + } +- return 0; + } + + /* Device address */ + rc = of_property_read_u32(nc, "reg", &value); + if (rc) { +- dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", ++ dev_err(&ctlr->dev, "%s has no valid 'reg' property (%d)\n", + nc->full_name, rc); +- return rc; ++ goto err_out; + } + spi->chip_select = value; + + /* Device speed */ + rc = of_property_read_u32(nc, "spi-max-frequency", &value); + if (rc) { +- dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", ++ dev_err(&ctlr->dev, ++ "%s has no valid 'spi-max-frequency' property (%d)\n", + nc->full_name, rc); + goto err_out; + } +@@ -1596,7 +1594,7 @@ static int spi_master_initialize_queue(struct spi_master *master) + /* Register the new device */ + rc = spi_add_device(spi); + if (rc) { +- dev_err(&master->dev, "spi_device register error %s\n", ++ dev_err(&ctlr->dev, "spi_device register error %s\n", + nc->full_name); + goto err_out; + } +@@ -1610,39 +1608,40 @@ static int spi_master_initialize_queue(struct spi_master *master) + + /** + * of_register_spi_devices() - Register child devices onto the SPI bus +- * @master: Pointer to spi_master device ++ * @ctlr: Pointer to spi_controller device + * + * Registers an spi_device for each child node of controller node which + * represents a valid SPI slave. + */ +-static void of_register_spi_devices(struct spi_master *master) ++static void of_register_spi_devices(struct spi_controller *ctlr) + { + struct spi_device *spi; + struct device_node *nc; + +- if (!master->dev.of_node) ++ if (!ctlr->dev.of_node) + return; + +- for_each_available_child_of_node(master->dev.of_node, nc) { ++ for_each_available_child_of_node(ctlr->dev.of_node, nc) { + if (of_node_test_and_set_flag(nc, OF_POPULATED)) + continue; +- spi = of_register_spi_device(master, nc); ++ spi = of_register_spi_device(ctlr, nc); + if (IS_ERR(spi)) { +- dev_warn(&master->dev, "Failed to create SPI device for %s\n", +- nc->full_name); ++ dev_warn(&ctlr->dev, ++ "Failed to create SPI device for %s\n", ++ nc->full_name); + of_node_clear_flag(nc, OF_POPULATED); + } + } + } + #else +-static void of_register_spi_devices(struct spi_master *master) { } ++static void of_register_spi_devices(struct spi_controller *ctlr) { } + #endif + + #ifdef CONFIG_ACPI + static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) + { + struct spi_device *spi = data; +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + + if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { + struct acpi_resource_spi_serialbus *sb; +@@ -1656,8 +1655,8 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) + * 0 .. max - 1 so we need to ask the driver to + * translate between the two schemes. + */ +- if (master->fw_translate_cs) { +- int cs = master->fw_translate_cs(master, ++ if (ctlr->fw_translate_cs) { ++ int cs = ctlr->fw_translate_cs(ctlr, + sb->device_selection); + if (cs < 0) + return cs; +@@ -1686,7 +1685,7 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) + return 1; + } + +-static acpi_status acpi_register_spi_device(struct spi_master *master, ++static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, + struct acpi_device *adev) + { + struct list_head resource_list; +@@ -1697,9 +1696,9 @@ static acpi_status acpi_register_spi_device(struct spi_master *master, + acpi_device_enumerated(adev)) + return AE_OK; + +- spi = spi_alloc_device(master); ++ spi = spi_alloc_device(ctlr); + if (!spi) { +- dev_err(&master->dev, "failed to allocate SPI device for %s\n", ++ dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n", + dev_name(&adev->dev)); + return AE_NO_MEMORY; + } +@@ -1726,7 +1725,7 @@ static acpi_status acpi_register_spi_device(struct spi_master *master, + strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias)); + if (spi_add_device(spi)) { + adev->power.flags.ignore_parent = false; +- dev_err(&master->dev, "failed to add SPI device %s from ACPI\n", ++ dev_err(&ctlr->dev, "failed to add SPI device %s from ACPI\n", + dev_name(&adev->dev)); + spi_dev_put(spi); + } +@@ -1737,46 +1736,45 @@ static acpi_status acpi_register_spi_device(struct spi_master *master, + static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, + void *data, void **return_value) + { +- struct spi_master *master = data; ++ struct spi_controller *ctlr = data; + struct acpi_device *adev; + + if (acpi_bus_get_device(handle, &adev)) + return AE_OK; + +- return acpi_register_spi_device(master, adev); ++ return acpi_register_spi_device(ctlr, adev); + } + +-static void acpi_register_spi_devices(struct spi_master *master) ++static void acpi_register_spi_devices(struct spi_controller *ctlr) + { + acpi_status status; + acpi_handle handle; + +- handle = ACPI_HANDLE(master->dev.parent); ++ handle = ACPI_HANDLE(ctlr->dev.parent); + if (!handle) + return; + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, +- acpi_spi_add_device, NULL, +- master, NULL); ++ acpi_spi_add_device, NULL, ctlr, NULL); + if (ACPI_FAILURE(status)) +- dev_warn(&master->dev, "failed to enumerate SPI slaves\n"); ++ dev_warn(&ctlr->dev, "failed to enumerate SPI slaves\n"); + } + #else +-static inline void acpi_register_spi_devices(struct spi_master *master) {} ++static inline void acpi_register_spi_devices(struct spi_controller *ctlr) {} + #endif /* CONFIG_ACPI */ + +-static void spi_master_release(struct device *dev) ++static void spi_controller_release(struct device *dev) + { +- struct spi_master *master; ++ struct spi_controller *ctlr; + +- master = container_of(dev, struct spi_master, dev); +- kfree(master); ++ ctlr = container_of(dev, struct spi_controller, dev); ++ kfree(ctlr); + } + + static struct class spi_master_class = { + .name = "spi_master", + .owner = THIS_MODULE, +- .dev_release = spi_master_release, ++ .dev_release = spi_controller_release, + .dev_groups = spi_master_groups, + }; + +@@ -1788,10 +1786,10 @@ static void spi_master_release(struct device *dev) + */ + int spi_slave_abort(struct spi_device *spi) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + +- if (spi_controller_is_slave(master) && master->slave_abort) +- return master->slave_abort(master); ++ if (spi_controller_is_slave(ctlr) && ctlr->slave_abort) ++ return ctlr->slave_abort(ctlr); + + return -ENOTSUPP; + } +@@ -1805,7 +1803,8 @@ static int match_true(struct device *dev, void *data) + static ssize_t spi_slave_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +- struct spi_master *ctlr = container_of(dev, struct spi_master, dev); ++ struct spi_controller *ctlr = container_of(dev, struct spi_controller, ++ dev); + struct device *child; + + child = device_find_child(&ctlr->dev, NULL, match_true); +@@ -1817,7 +1816,8 @@ static ssize_t spi_slave_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) + { +- struct spi_master *ctlr = container_of(dev, struct spi_master, dev); ++ struct spi_controller *ctlr = container_of(dev, struct spi_controller, ++ dev); + struct spi_device *spi; + struct device *child; + char name[32]; +@@ -1864,7 +1864,7 @@ static ssize_t spi_slave_store(struct device *dev, + }; + + static const struct attribute_group *spi_slave_groups[] = { +- &spi_master_statistics_group, ++ &spi_controller_statistics_group, + &spi_slave_group, + NULL, + }; +@@ -1872,7 +1872,7 @@ static ssize_t spi_slave_store(struct device *dev, + static struct class spi_slave_class = { + .name = "spi_slave", + .owner = THIS_MODULE, +- .dev_release = spi_master_release, ++ .dev_release = spi_controller_release, + .dev_groups = spi_slave_groups, + }; + #else +@@ -1884,62 +1884,63 @@ static ssize_t spi_slave_store(struct device *dev, + * @dev: the controller, possibly using the platform_bus + * @size: how much zeroed driver-private data to allocate; the pointer to this + * memory is in the driver_data field of the returned device, +- * accessible with spi_master_get_devdata(). ++ * accessible with spi_controller_get_devdata(). + * @slave: flag indicating whether to allocate an SPI master (false) or SPI + * slave (true) controller + * Context: can sleep + * + * This call is used only by SPI controller drivers, which are the + * only ones directly touching chip registers. It's how they allocate +- * an spi_master structure, prior to calling spi_register_master(). ++ * an spi_controller structure, prior to calling spi_register_controller(). + * + * This must be called from context that can sleep. + * + * The caller is responsible for assigning the bus number and initializing the +- * controller's methods before calling spi_register_master(); and (after errors +- * adding the device) calling spi_master_put() to prevent a memory leak. ++ * controller's methods before calling spi_register_controller(); and (after ++ * errors adding the device) calling spi_controller_put() to prevent a memory ++ * leak. + * + * Return: the SPI controller structure on success, else NULL. + */ +-struct spi_master *__spi_alloc_controller(struct device *dev, +- unsigned int size, bool slave) ++struct spi_controller *__spi_alloc_controller(struct device *dev, ++ unsigned int size, bool slave) + { +- struct spi_master *master; ++ struct spi_controller *ctlr; + + if (!dev) + return NULL; + +- master = kzalloc(size + sizeof(*master), GFP_KERNEL); +- if (!master) ++ ctlr = kzalloc(size + sizeof(*ctlr), GFP_KERNEL); ++ if (!ctlr) + return NULL; + +- device_initialize(&master->dev); +- master->bus_num = -1; +- master->num_chipselect = 1; +- master->slave = slave; ++ device_initialize(&ctlr->dev); ++ ctlr->bus_num = -1; ++ ctlr->num_chipselect = 1; ++ ctlr->slave = slave; + if (IS_ENABLED(CONFIG_SPI_SLAVE) && slave) +- master->dev.class = &spi_slave_class; ++ ctlr->dev.class = &spi_slave_class; + else +- master->dev.class = &spi_master_class; +- master->dev.parent = dev; +- pm_suspend_ignore_children(&master->dev, true); +- spi_master_set_devdata(master, &master[1]); ++ ctlr->dev.class = &spi_master_class; ++ ctlr->dev.parent = dev; ++ pm_suspend_ignore_children(&ctlr->dev, true); ++ spi_controller_set_devdata(ctlr, &ctlr[1]); + +- return master; ++ return ctlr; + } + EXPORT_SYMBOL_GPL(__spi_alloc_controller); + + #ifdef CONFIG_OF +-static int of_spi_register_master(struct spi_master *master) ++static int of_spi_register_master(struct spi_controller *ctlr) + { + int nb, i, *cs; +- struct device_node *np = master->dev.of_node; ++ struct device_node *np = ctlr->dev.of_node; + + if (!np) + return 0; + + nb = of_gpio_named_count(np, "cs-gpios"); +- master->num_chipselect = max_t(int, nb, master->num_chipselect); ++ ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect); + + /* Return error only for an incorrectly formed cs-gpios property */ + if (nb == 0 || nb == -ENOENT) +@@ -1947,15 +1948,14 @@ static int of_spi_register_master(struct spi_master *master) + else if (nb < 0) + return nb; + +- cs = devm_kzalloc(&master->dev, +- sizeof(int) * master->num_chipselect, ++ cs = devm_kzalloc(&ctlr->dev, sizeof(int) * ctlr->num_chipselect, + GFP_KERNEL); +- master->cs_gpios = cs; ++ ctlr->cs_gpios = cs; + +- if (!master->cs_gpios) ++ if (!ctlr->cs_gpios) + return -ENOMEM; + +- for (i = 0; i < master->num_chipselect; i++) ++ for (i = 0; i < ctlr->num_chipselect; i++) + cs[i] = -ENOENT; + + for (i = 0; i < nb; i++) +@@ -1964,20 +1964,21 @@ static int of_spi_register_master(struct spi_master *master) + return 0; + } + #else +-static int of_spi_register_master(struct spi_master *master) ++static int of_spi_register_master(struct spi_controller *ctlr) + { + return 0; + } + #endif + + /** +- * spi_register_master - register SPI master controller +- * @master: initialized master, originally from spi_alloc_master() ++ * spi_register_controller - register SPI master or slave controller ++ * @ctlr: initialized master, originally from spi_alloc_master() or ++ * spi_alloc_slave() + * Context: can sleep + * +- * SPI master controllers connect to their drivers using some non-SPI bus, ++ * SPI controllers connect to their drivers using some non-SPI bus, + * such as the platform bus. The final stage of probe() in that code +- * includes calling spi_register_master() to hook up to this SPI bus glue. ++ * includes calling spi_register_controller() to hook up to this SPI bus glue. + * + * SPI controllers use board specific (often SOC specific) bus numbers, + * and board-specific addressing for SPI devices combines those numbers +@@ -1986,16 +1987,16 @@ static int of_spi_register_master(struct spi_master *master) + * chip is at which address. + * + * This must be called from context that can sleep. It returns zero on +- * success, else a negative error code (dropping the master's refcount). ++ * success, else a negative error code (dropping the controller's refcount). + * After a successful return, the caller is responsible for calling +- * spi_unregister_master(). ++ * spi_unregister_controller(). + * + * Return: zero on success, else a negative error code. + */ +-int spi_register_master(struct spi_master *master) ++int spi_register_controller(struct spi_controller *ctlr) + { + static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); +- struct device *dev = master->dev.parent; ++ struct device *dev = ctlr->dev.parent; + struct boardinfo *bi; + int status = -ENODEV; + int dynamic = 0; +@@ -2003,8 +2004,8 @@ int spi_register_master(struct spi_master *master) + if (!dev) + return -ENODEV; + +- if (!spi_controller_is_slave(master)) { +- status = of_spi_register_master(master); ++ if (!spi_controller_is_slave(ctlr)) { ++ status = of_spi_register_master(ctlr); + if (status) + return status; + } +@@ -2012,97 +2013,100 @@ int spi_register_master(struct spi_master *master) + /* even if it's just one always-selected device, there must + * be at least one chipselect + */ +- if (master->num_chipselect == 0) ++ if (ctlr->num_chipselect == 0) + return -EINVAL; + +- if ((master->bus_num < 0) && master->dev.of_node) +- master->bus_num = of_alias_get_id(master->dev.of_node, "spi"); ++ if ((ctlr->bus_num < 0) && ctlr->dev.of_node) ++ ctlr->bus_num = of_alias_get_id(ctlr->dev.of_node, "spi"); + + /* convention: dynamically assigned bus IDs count down from the max */ +- if (master->bus_num < 0) { ++ if (ctlr->bus_num < 0) { + /* FIXME switch to an IDR based scheme, something like + * I2C now uses, so we can't run out of "dynamic" IDs + */ +- master->bus_num = atomic_dec_return(&dyn_bus_id); ++ ctlr->bus_num = atomic_dec_return(&dyn_bus_id); + dynamic = 1; + } + +- INIT_LIST_HEAD(&master->queue); +- spin_lock_init(&master->queue_lock); +- spin_lock_init(&master->bus_lock_spinlock); +- mutex_init(&master->bus_lock_mutex); +- mutex_init(&master->io_mutex); +- master->bus_lock_flag = 0; +- init_completion(&master->xfer_completion); +- if (!master->max_dma_len) +- master->max_dma_len = INT_MAX; ++ INIT_LIST_HEAD(&ctlr->queue); ++ spin_lock_init(&ctlr->queue_lock); ++ spin_lock_init(&ctlr->bus_lock_spinlock); ++ mutex_init(&ctlr->bus_lock_mutex); ++ mutex_init(&ctlr->io_mutex); ++ ctlr->bus_lock_flag = 0; ++ init_completion(&ctlr->xfer_completion); ++ if (!ctlr->max_dma_len) ++ ctlr->max_dma_len = INT_MAX; + + /* register the device, then userspace will see it. + * registration fails if the bus ID is in use. + */ +- dev_set_name(&master->dev, "spi%u", master->bus_num); +- status = device_add(&master->dev); ++ dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); ++ status = device_add(&ctlr->dev); + if (status < 0) + goto done; + dev_dbg(dev, "registered %s %s%s\n", +- spi_controller_is_slave(master) ? "slave" : "master", +- dev_name(&master->dev), dynamic ? " (dynamic)" : ""); ++ spi_controller_is_slave(ctlr) ? "slave" : "master", ++ dev_name(&ctlr->dev), dynamic ? " (dynamic)" : ""); + + /* If we're using a queued driver, start the queue */ +- if (master->transfer) ++ if (ctlr->transfer) + dev_info(dev, "master is unqueued, this is deprecated\n"); + else { +- status = spi_master_initialize_queue(master); ++ status = spi_controller_initialize_queue(ctlr); + if (status) { +- device_del(&master->dev); ++ device_del(&ctlr->dev); + goto done; + } + } + /* add statistics */ +- spin_lock_init(&master->statistics.lock); ++ spin_lock_init(&ctlr->statistics.lock); + + mutex_lock(&board_lock); +- list_add_tail(&master->list, &spi_master_list); ++ list_add_tail(&ctlr->list, &spi_controller_list); + list_for_each_entry(bi, &board_list, list) +- spi_match_master_to_boardinfo(master, &bi->board_info); ++ spi_match_controller_to_boardinfo(ctlr, &bi->board_info); + mutex_unlock(&board_lock); + + /* Register devices from the device tree and ACPI */ +- of_register_spi_devices(master); +- acpi_register_spi_devices(master); ++ of_register_spi_devices(ctlr); ++ acpi_register_spi_devices(ctlr); + done: + return status; + } +-EXPORT_SYMBOL_GPL(spi_register_master); ++EXPORT_SYMBOL_GPL(spi_register_controller); + + static void devm_spi_unregister(struct device *dev, void *res) + { +- spi_unregister_master(*(struct spi_master **)res); ++ spi_unregister_controller(*(struct spi_master **)res); + } + + /** +- * dev_spi_register_master - register managed SPI master controller +- * @dev: device managing SPI master +- * @master: initialized master, originally from spi_alloc_master() ++ * devm_spi_register_controller - register managed SPI master or slave ++ * controller ++ * @dev: device managing SPI controller ++ * @ctlr: initialized controller, originally from spi_alloc_master() or ++ * spi_alloc_slave() + * Context: can sleep + * +- * Register a SPI device as with spi_register_master() which will ++ * Register a SPI device as with spi_register_controller() which will + * automatically be unregister + * + * Return: zero on success, else a negative error code. + */ +-int devm_spi_register_master(struct device *dev, struct spi_master *master) ++int devm_spi_register_controller(struct device *dev, ++ struct spi_controller *ctlr) + { +- struct spi_master **ptr; ++ struct spi_controller **ptr; + int ret; + + ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + +- ret = spi_register_master(master); ++ ret = spi_register_controller(ctlr); + if (!ret) { +- *ptr = master; ++ *ptr = ctlr; + devres_add(dev, ptr); + } else { + devres_free(ptr); +@@ -2110,7 +2114,7 @@ int devm_spi_register_master(struct device *dev, struct spi_master *master) + + return ret; + } +-EXPORT_SYMBOL_GPL(devm_spi_register_master); ++EXPORT_SYMBOL_GPL(devm_spi_register_controller); + + static int __unregister(struct device *dev, void *null) + { +@@ -2119,71 +2123,71 @@ static int __unregister(struct device *dev, void *null) + } + + /** +- * spi_unregister_master - unregister SPI master controller +- * @master: the master being unregistered ++ * spi_unregister_controller - unregister SPI master or slave controller ++ * @ctlr: the controller being unregistered + * Context: can sleep + * +- * This call is used only by SPI master controller drivers, which are the ++ * This call is used only by SPI controller drivers, which are the + * only ones directly touching chip registers. + * + * This must be called from context that can sleep. + */ +-void spi_unregister_master(struct spi_master *master) ++void spi_unregister_controller(struct spi_controller *ctlr) + { + int dummy; + +- if (master->queued) { +- if (spi_destroy_queue(master)) +- dev_err(&master->dev, "queue remove failed\n"); ++ if (ctlr->queued) { ++ if (spi_destroy_queue(ctlr)) ++ dev_err(&ctlr->dev, "queue remove failed\n"); + } + + mutex_lock(&board_lock); +- list_del(&master->list); ++ list_del(&ctlr->list); + mutex_unlock(&board_lock); + +- dummy = device_for_each_child(&master->dev, NULL, __unregister); +- device_unregister(&master->dev); ++ dummy = device_for_each_child(&ctlr->dev, NULL, __unregister); ++ device_unregister(&ctlr->dev); + } +-EXPORT_SYMBOL_GPL(spi_unregister_master); ++EXPORT_SYMBOL_GPL(spi_unregister_controller); + +-int spi_master_suspend(struct spi_master *master) ++int spi_controller_suspend(struct spi_controller *ctlr) + { + int ret; + +- /* Basically no-ops for non-queued masters */ +- if (!master->queued) ++ /* Basically no-ops for non-queued controllers */ ++ if (!ctlr->queued) + return 0; + +- ret = spi_stop_queue(master); ++ ret = spi_stop_queue(ctlr); + if (ret) +- dev_err(&master->dev, "queue stop failed\n"); ++ dev_err(&ctlr->dev, "queue stop failed\n"); + + return ret; + } +-EXPORT_SYMBOL_GPL(spi_master_suspend); ++EXPORT_SYMBOL_GPL(spi_controller_suspend); + +-int spi_master_resume(struct spi_master *master) ++int spi_controller_resume(struct spi_controller *ctlr) + { + int ret; + +- if (!master->queued) ++ if (!ctlr->queued) + return 0; + +- ret = spi_start_queue(master); ++ ret = spi_start_queue(ctlr); + if (ret) +- dev_err(&master->dev, "queue restart failed\n"); ++ dev_err(&ctlr->dev, "queue restart failed\n"); + + return ret; + } +-EXPORT_SYMBOL_GPL(spi_master_resume); ++EXPORT_SYMBOL_GPL(spi_controller_resume); + +-static int __spi_master_match(struct device *dev, const void *data) ++static int __spi_controller_match(struct device *dev, const void *data) + { +- struct spi_master *m; ++ struct spi_controller *ctlr; + const u16 *bus_num = data; + +- m = container_of(dev, struct spi_master, dev); +- return m->bus_num == *bus_num; ++ ctlr = container_of(dev, struct spi_controller, dev); ++ return ctlr->bus_num == *bus_num; + } + + /** +@@ -2193,22 +2197,22 @@ static int __spi_master_match(struct device *dev, const void *data) + * + * This call may be used with devices that are registered after + * arch init time. It returns a refcounted pointer to the relevant +- * spi_master (which the caller must release), or NULL if there is ++ * spi_controller (which the caller must release), or NULL if there is + * no such master registered. + * + * Return: the SPI master structure on success, else NULL. + */ +-struct spi_master *spi_busnum_to_master(u16 bus_num) ++struct spi_controller *spi_busnum_to_master(u16 bus_num) + { + struct device *dev; +- struct spi_master *master = NULL; ++ struct spi_controller *ctlr = NULL; + + dev = class_find_device(&spi_master_class, NULL, &bus_num, +- __spi_master_match); ++ __spi_controller_match); + if (dev) +- master = container_of(dev, struct spi_master, dev); ++ ctlr = container_of(dev, struct spi_controller, dev); + /* reference got in class_find_device */ +- return master; ++ return ctlr; + } + EXPORT_SYMBOL_GPL(spi_busnum_to_master); + +@@ -2228,7 +2232,7 @@ struct spi_master *spi_busnum_to_master(u16 bus_num) + * Return: the pointer to the allocated data + * + * This may get enhanced in the future to allocate from a memory pool +- * of the @spi_device or @spi_master to avoid repeated allocations. ++ * of the @spi_device or @spi_controller to avoid repeated allocations. + */ + void *spi_res_alloc(struct spi_device *spi, + spi_res_release_t release, +@@ -2280,11 +2284,10 @@ void spi_res_add(struct spi_message *message, void *res) + + /** + * spi_res_release - release all spi resources for this message +- * @master: the @spi_master ++ * @ctlr: the @spi_controller + * @message: the @spi_message + */ +-void spi_res_release(struct spi_master *master, +- struct spi_message *message) ++void spi_res_release(struct spi_controller *ctlr, struct spi_message *message) + { + struct spi_res *res; + +@@ -2293,7 +2296,7 @@ void spi_res_release(struct spi_master *master, + struct spi_res, entry); + + if (res->release) +- res->release(master, message, res->data); ++ res->release(ctlr, message, res->data); + + list_del(&res->entry); + +@@ -2306,7 +2309,7 @@ void spi_res_release(struct spi_master *master, + + /* Core methods for spi_message alterations */ + +-static void __spi_replace_transfers_release(struct spi_master *master, ++static void __spi_replace_transfers_release(struct spi_controller *ctlr, + struct spi_message *msg, + void *res) + { +@@ -2315,7 +2318,7 @@ static void __spi_replace_transfers_release(struct spi_master *master, + + /* call extra callback if requested */ + if (rxfer->release) +- rxfer->release(master, msg, res); ++ rxfer->release(ctlr, msg, res); + + /* insert replaced transfers back into the message */ + list_splice(&rxfer->replaced_transfers, rxfer->replaced_after); +@@ -2435,7 +2438,7 @@ struct spi_replaced_transfers *spi_replace_transfers( + } + EXPORT_SYMBOL_GPL(spi_replace_transfers); + +-static int __spi_split_transfer_maxsize(struct spi_master *master, ++static int __spi_split_transfer_maxsize(struct spi_controller *ctlr, + struct spi_message *msg, + struct spi_transfer **xferp, + size_t maxsize, +@@ -2497,7 +2500,7 @@ static int __spi_split_transfer_maxsize(struct spi_master *master, + *xferp = &xfers[count - 1]; + + /* increment statistics counters */ +- SPI_STATISTICS_INCREMENT_FIELD(&master->statistics, ++ SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, + transfers_split_maxsize); + SPI_STATISTICS_INCREMENT_FIELD(&msg->spi->statistics, + transfers_split_maxsize); +@@ -2509,14 +2512,14 @@ static int __spi_split_transfer_maxsize(struct spi_master *master, + * spi_split_tranfers_maxsize - split spi transfers into multiple transfers + * when an individual transfer exceeds a + * certain size +- * @master: the @spi_master for this transfer ++ * @ctlr: the @spi_controller for this transfer + * @msg: the @spi_message to transform + * @maxsize: the maximum when to apply this + * @gfp: GFP allocation flags + * + * Return: status of transformation + */ +-int spi_split_transfers_maxsize(struct spi_master *master, ++int spi_split_transfers_maxsize(struct spi_controller *ctlr, + struct spi_message *msg, + size_t maxsize, + gfp_t gfp) +@@ -2532,8 +2535,8 @@ int spi_split_transfers_maxsize(struct spi_master *master, + */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + if (xfer->len > maxsize) { +- ret = __spi_split_transfer_maxsize( +- master, msg, &xfer, maxsize, gfp); ++ ret = __spi_split_transfer_maxsize(ctlr, msg, &xfer, ++ maxsize, gfp); + if (ret) + return ret; + } +@@ -2545,18 +2548,18 @@ int spi_split_transfers_maxsize(struct spi_master *master, + + /*-------------------------------------------------------------------------*/ + +-/* Core methods for SPI master protocol drivers. Some of the ++/* Core methods for SPI controller protocol drivers. Some of the + * other core methods are currently defined as inline functions. + */ + +-static int __spi_validate_bits_per_word(struct spi_master *master, u8 bits_per_word) ++static int __spi_validate_bits_per_word(struct spi_controller *ctlr, ++ u8 bits_per_word) + { +- if (master->bits_per_word_mask) { ++ if (ctlr->bits_per_word_mask) { + /* Only 32 bits fit in the mask */ + if (bits_per_word > 32) + return -EINVAL; +- if (!(master->bits_per_word_mask & +- SPI_BPW_MASK(bits_per_word))) ++ if (!(ctlr->bits_per_word_mask & SPI_BPW_MASK(bits_per_word))) + return -EINVAL; + } + +@@ -2602,9 +2605,9 @@ int spi_setup(struct spi_device *spi) + (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD))) + return -EINVAL; + /* help drivers fail *cleanly* when they need options +- * that aren't supported with their current master ++ * that aren't supported with their current controller + */ +- bad_bits = spi->mode & ~spi->master->mode_bits; ++ bad_bits = spi->mode & ~spi->controller->mode_bits; + ugly_bits = bad_bits & + (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD); + if (ugly_bits) { +@@ -2623,15 +2626,16 @@ int spi_setup(struct spi_device *spi) + if (!spi->bits_per_word) + spi->bits_per_word = 8; + +- status = __spi_validate_bits_per_word(spi->master, spi->bits_per_word); ++ status = __spi_validate_bits_per_word(spi->controller, ++ spi->bits_per_word); + if (status) + return status; + + if (!spi->max_speed_hz) +- spi->max_speed_hz = spi->master->max_speed_hz; ++ spi->max_speed_hz = spi->controller->max_speed_hz; + +- if (spi->master->setup) +- status = spi->master->setup(spi); ++ if (spi->controller->setup) ++ status = spi->controller->setup(spi); + + spi_set_cs(spi, false); + +@@ -2650,7 +2654,7 @@ int spi_setup(struct spi_device *spi) + + static int __spi_validate(struct spi_device *spi, struct spi_message *message) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + struct spi_transfer *xfer; + int w_size; + +@@ -2662,16 +2666,16 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) + * either MOSI or MISO is missing. They can also be caused by + * software limitations. + */ +- if ((master->flags & SPI_MASTER_HALF_DUPLEX) +- || (spi->mode & SPI_3WIRE)) { +- unsigned flags = master->flags; ++ if ((ctlr->flags & SPI_CONTROLLER_HALF_DUPLEX) || ++ (spi->mode & SPI_3WIRE)) { ++ unsigned flags = ctlr->flags; + + list_for_each_entry(xfer, &message->transfers, transfer_list) { + if (xfer->rx_buf && xfer->tx_buf) + return -EINVAL; +- if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf) ++ if ((flags & SPI_CONTROLLER_NO_TX) && xfer->tx_buf) + return -EINVAL; +- if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf) ++ if ((flags & SPI_CONTROLLER_NO_RX) && xfer->rx_buf) + return -EINVAL; + } + } +@@ -2691,13 +2695,12 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) + if (!xfer->speed_hz) + xfer->speed_hz = spi->max_speed_hz; + if (!xfer->speed_hz) +- xfer->speed_hz = master->max_speed_hz; ++ xfer->speed_hz = ctlr->max_speed_hz; + +- if (master->max_speed_hz && +- xfer->speed_hz > master->max_speed_hz) +- xfer->speed_hz = master->max_speed_hz; ++ if (ctlr->max_speed_hz && xfer->speed_hz > ctlr->max_speed_hz) ++ xfer->speed_hz = ctlr->max_speed_hz; + +- if (__spi_validate_bits_per_word(master, xfer->bits_per_word)) ++ if (__spi_validate_bits_per_word(ctlr, xfer->bits_per_word)) + return -EINVAL; + + /* +@@ -2715,8 +2718,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) + if (xfer->len % w_size) + return -EINVAL; + +- if (xfer->speed_hz && master->min_speed_hz && +- xfer->speed_hz < master->min_speed_hz) ++ if (xfer->speed_hz && ctlr->min_speed_hz && ++ xfer->speed_hz < ctlr->min_speed_hz) + return -EINVAL; + + if (xfer->tx_buf && !xfer->tx_nbits) +@@ -2761,16 +2764,16 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) + + static int __spi_async(struct spi_device *spi, struct spi_message *message) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + + message->spi = spi; + +- SPI_STATISTICS_INCREMENT_FIELD(&master->statistics, spi_async); ++ SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, spi_async); + SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, spi_async); + + trace_spi_message_submit(message); + +- return master->transfer(spi, message); ++ return ctlr->transfer(spi, message); + } + + /** +@@ -2806,7 +2809,7 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) + */ + int spi_async(struct spi_device *spi, struct spi_message *message) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + int ret; + unsigned long flags; + +@@ -2814,14 +2817,14 @@ int spi_async(struct spi_device *spi, struct spi_message *message) + if (ret != 0) + return ret; + +- spin_lock_irqsave(&master->bus_lock_spinlock, flags); ++ spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); + +- if (master->bus_lock_flag) ++ if (ctlr->bus_lock_flag) + ret = -EBUSY; + else + ret = __spi_async(spi, message); + +- spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); ++ spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); + + return ret; + } +@@ -2860,7 +2863,7 @@ int spi_async(struct spi_device *spi, struct spi_message *message) + */ + int spi_async_locked(struct spi_device *spi, struct spi_message *message) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + int ret; + unsigned long flags; + +@@ -2868,11 +2871,11 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message) + if (ret != 0) + return ret; + +- spin_lock_irqsave(&master->bus_lock_spinlock, flags); ++ spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); + + ret = __spi_async(spi, message); + +- spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); ++ spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); + + return ret; + +@@ -2884,7 +2887,7 @@ int spi_flash_read(struct spi_device *spi, + struct spi_flash_read_message *msg) + + { +- struct spi_master *master = spi->master; ++ struct spi_controller *master = spi->controller; + struct device *rx_dev = NULL; + int ret; + +@@ -2938,7 +2941,7 @@ int spi_flash_read(struct spi_device *spi, + + /*-------------------------------------------------------------------------*/ + +-/* Utility methods for SPI master protocol drivers, layered on ++/* Utility methods for SPI protocol drivers, layered on + * top of the core. Some other utility methods are defined as + * inline functions. + */ +@@ -2952,7 +2955,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) + { + DECLARE_COMPLETION_ONSTACK(done); + int status; +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + unsigned long flags; + + status = __spi_validate(spi, message); +@@ -2963,7 +2966,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) + message->context = &done; + message->spi = spi; + +- SPI_STATISTICS_INCREMENT_FIELD(&master->statistics, spi_sync); ++ SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, spi_sync); + SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, spi_sync); + + /* If we're not using the legacy transfer method then we will +@@ -2971,14 +2974,14 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) + * This code would be less tricky if we could remove the + * support for driver implemented message queues. + */ +- if (master->transfer == spi_queued_transfer) { +- spin_lock_irqsave(&master->bus_lock_spinlock, flags); ++ if (ctlr->transfer == spi_queued_transfer) { ++ spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); + + trace_spi_message_submit(message); + + status = __spi_queued_transfer(spi, message, false); + +- spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); ++ spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); + } else { + status = spi_async_locked(spi, message); + } +@@ -2987,12 +2990,12 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) + /* Push out the messages in the calling context if we + * can. + */ +- if (master->transfer == spi_queued_transfer) { +- SPI_STATISTICS_INCREMENT_FIELD(&master->statistics, ++ if (ctlr->transfer == spi_queued_transfer) { ++ SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, + spi_sync_immediate); + SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, + spi_sync_immediate); +- __spi_pump_messages(master, false); ++ __spi_pump_messages(ctlr, false); + } + + wait_for_completion(&done); +@@ -3027,9 +3030,9 @@ int spi_sync(struct spi_device *spi, struct spi_message *message) + { + int ret; + +- mutex_lock(&spi->master->bus_lock_mutex); ++ mutex_lock(&spi->controller->bus_lock_mutex); + ret = __spi_sync(spi, message); +- mutex_unlock(&spi->master->bus_lock_mutex); ++ mutex_unlock(&spi->controller->bus_lock_mutex); + + return ret; + } +@@ -3059,7 +3062,7 @@ int spi_sync_locked(struct spi_device *spi, struct spi_message *message) + + /** + * spi_bus_lock - obtain a lock for exclusive SPI bus usage +- * @master: SPI bus master that should be locked for exclusive bus access ++ * @ctlr: SPI bus master that should be locked for exclusive bus access + * Context: can sleep + * + * This call may only be used from a context that may sleep. The sleep +@@ -3072,15 +3075,15 @@ int spi_sync_locked(struct spi_device *spi, struct spi_message *message) + * + * Return: always zero. + */ +-int spi_bus_lock(struct spi_master *master) ++int spi_bus_lock(struct spi_controller *ctlr) + { + unsigned long flags; + +- mutex_lock(&master->bus_lock_mutex); ++ mutex_lock(&ctlr->bus_lock_mutex); + +- spin_lock_irqsave(&master->bus_lock_spinlock, flags); +- master->bus_lock_flag = 1; +- spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); ++ spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); ++ ctlr->bus_lock_flag = 1; ++ spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); + + /* mutex remains locked until spi_bus_unlock is called */ + +@@ -3090,7 +3093,7 @@ int spi_bus_lock(struct spi_master *master) + + /** + * spi_bus_unlock - release the lock for exclusive SPI bus usage +- * @master: SPI bus master that was locked for exclusive bus access ++ * @ctlr: SPI bus master that was locked for exclusive bus access + * Context: can sleep + * + * This call may only be used from a context that may sleep. The sleep +@@ -3101,11 +3104,11 @@ int spi_bus_lock(struct spi_master *master) + * + * Return: always zero. + */ +-int spi_bus_unlock(struct spi_master *master) ++int spi_bus_unlock(struct spi_controller *ctlr) + { +- master->bus_lock_flag = 0; ++ ctlr->bus_lock_flag = 0; + +- mutex_unlock(&master->bus_lock_mutex); ++ mutex_unlock(&ctlr->bus_lock_mutex); + + return 0; + } +@@ -3207,48 +3210,48 @@ static struct spi_device *of_find_spi_device_by_node(struct device_node *node) + return dev ? to_spi_device(dev) : NULL; + } + +-static int __spi_of_master_match(struct device *dev, const void *data) ++static int __spi_of_controller_match(struct device *dev, const void *data) + { + return dev->of_node == data; + } + +-/* the spi masters are not using spi_bus, so we find it with another way */ +-static struct spi_master *of_find_spi_master_by_node(struct device_node *node) ++/* the spi controllers are not using spi_bus, so we find it with another way */ ++static struct spi_controller *of_find_spi_controller_by_node(struct device_node *node) + { + struct device *dev; + + dev = class_find_device(&spi_master_class, NULL, node, +- __spi_of_master_match); ++ __spi_of_controller_match); + if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) + dev = class_find_device(&spi_slave_class, NULL, node, +- __spi_of_master_match); ++ __spi_of_controller_match); + if (!dev) + return NULL; + + /* reference got in class_find_device */ +- return container_of(dev, struct spi_master, dev); ++ return container_of(dev, struct spi_controller, dev); + } + + static int of_spi_notify(struct notifier_block *nb, unsigned long action, + void *arg) + { + struct of_reconfig_data *rd = arg; +- struct spi_master *master; ++ struct spi_controller *ctlr; + struct spi_device *spi; + + switch (of_reconfig_get_state_change(action, arg)) { + case OF_RECONFIG_CHANGE_ADD: +- master = of_find_spi_master_by_node(rd->dn->parent); +- if (master == NULL) ++ ctlr = of_find_spi_controller_by_node(rd->dn->parent); ++ if (ctlr == NULL) + return NOTIFY_OK; /* not for us */ + + if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) { +- put_device(&master->dev); ++ put_device(&ctlr->dev); + return NOTIFY_OK; + } + +- spi = of_register_spi_device(master, rd->dn); +- put_device(&master->dev); ++ spi = of_register_spi_device(ctlr, rd->dn); ++ put_device(&ctlr->dev); + + if (IS_ERR(spi)) { + pr_err("%s: failed to create for '%s'\n", +@@ -3287,7 +3290,7 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action, + #endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ + + #if IS_ENABLED(CONFIG_ACPI) +-static int spi_acpi_master_match(struct device *dev, const void *data) ++static int spi_acpi_controller_match(struct device *dev, const void *data) + { + return ACPI_COMPANION(dev->parent) == data; + } +@@ -3297,19 +3300,19 @@ static int spi_acpi_device_match(struct device *dev, void *data) + return ACPI_COMPANION(dev) == data; + } + +-static struct spi_master *acpi_spi_find_master_by_adev(struct acpi_device *adev) ++static struct spi_controller *acpi_spi_find_controller_by_adev(struct acpi_device *adev) + { + struct device *dev; + + dev = class_find_device(&spi_master_class, NULL, adev, +- spi_acpi_master_match); ++ spi_acpi_controller_match); + if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) + dev = class_find_device(&spi_slave_class, NULL, adev, +- spi_acpi_master_match); ++ spi_acpi_controller_match); + if (!dev) + return NULL; + +- return container_of(dev, struct spi_master, dev); ++ return container_of(dev, struct spi_controller, dev); + } + + static struct spi_device *acpi_spi_find_device_by_adev(struct acpi_device *adev) +@@ -3325,17 +3328,17 @@ static int acpi_spi_notify(struct notifier_block *nb, unsigned long value, + void *arg) + { + struct acpi_device *adev = arg; +- struct spi_master *master; ++ struct spi_controller *ctlr; + struct spi_device *spi; + + switch (value) { + case ACPI_RECONFIG_DEVICE_ADD: +- master = acpi_spi_find_master_by_adev(adev->parent); +- if (!master) ++ ctlr = acpi_spi_find_controller_by_adev(adev->parent); ++ if (!ctlr) + break; + +- acpi_register_spi_device(master, adev); +- put_device(&master->dev); ++ acpi_register_spi_device(ctlr, adev); ++ put_device(&ctlr->dev); + break; + case ACPI_RECONFIG_DEVICE_REMOVE: + if (!acpi_device_enumerated(adev)) +diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h +index f9bbd33..920cdb7 100644 +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -23,7 +23,7 @@ + #include <linux/scatterlist.h> + + struct dma_chan; +-struct spi_master; ++struct spi_controller; + struct spi_transfer; + struct spi_flash_read_message; + +@@ -83,7 +83,7 @@ struct spi_statistics { + + void spi_statistics_add_transfer_stats(struct spi_statistics *stats, + struct spi_transfer *xfer, +- struct spi_master *master); ++ struct spi_controller *ctlr); + + #define SPI_STATISTICS_ADD_TO_FIELD(stats, field, count) \ + do { \ +@@ -97,13 +97,14 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats, + SPI_STATISTICS_ADD_TO_FIELD(stats, field, 1) + + /** +- * struct spi_device - Master side proxy for an SPI slave device ++ * struct spi_device - Controller side proxy for an SPI slave device + * @dev: Driver model representation of the device. +- * @master: SPI controller used with the device. ++ * @controller: SPI controller used with the device. ++ * @master: Copy of controller, for backwards compatibility. + * @max_speed_hz: Maximum clock rate to be used with this chip + * (on this board); may be changed by the device's driver. + * The spi_transfer.speed_hz can override this for each transfer. +- * @chip_select: Chipselect, distinguishing chips handled by @master. ++ * @chip_select: Chipselect, distinguishing chips handled by @controller. + * @mode: The spi mode defines how data is clocked out and in. + * This may be changed by the device's driver. + * The "active low" default for chipselect mode can be overridden +@@ -139,7 +140,8 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats, + */ + struct spi_device { + struct device dev; +- struct spi_master *master; ++ struct spi_controller *controller; ++ struct spi_controller *master; /* compatibility layer */ + u32 max_speed_hz; + u8 chip_select; + u8 bits_per_word; +@@ -197,7 +199,7 @@ static inline void spi_dev_put(struct spi_device *spi) + put_device(&spi->dev); + } + +-/* ctldata is for the bus_master driver's runtime state */ ++/* ctldata is for the bus_controller driver's runtime state */ + static inline void *spi_get_ctldata(struct spi_device *spi) + { + return spi->controller_state; +@@ -291,9 +293,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) + spi_unregister_driver) + + /** +- * struct spi_master - interface to SPI master controller ++ * struct spi_controller - interface to SPI master or slave controller + * @dev: device interface to this driver +- * @list: link with the global spi_master list ++ * @list: link with the global spi_controller list + * @bus_num: board-specific (and often SOC-specific) identifier for a + * given SPI controller. + * @num_chipselect: chipselects are used to distinguish individual +@@ -326,8 +328,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) + * the device whose settings are being modified. + * @transfer: adds a message to the controller's transfer queue. + * @cleanup: frees controller-specific state +- * @can_dma: determine whether this master supports DMA +- * @queued: whether this master is providing an internal message queue ++ * @can_dma: determine whether this controller supports DMA ++ * @queued: whether this controller is providing an internal message queue + * @kworker: thread struct for message pump + * @kworker_task: pointer to task for message pump kworker thread + * @pump_messages: work struct for scheduling work to the message pump +@@ -381,7 +383,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) + * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS + * number. Any individual value may be -ENOENT for CS lines that + * are not GPIOs (driven by the SPI controller itself). +- * @statistics: statistics for the spi_master ++ * @statistics: statistics for the spi_controller + * @dma_tx: DMA transmit channel + * @dma_rx: DMA receive channel + * @dummy_rx: dummy receive buffer for full-duplex devices +@@ -390,7 +392,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) + * what Linux expects, this optional hook can be used to translate + * between the two. + * +- * Each SPI master controller can communicate with one or more @spi_device ++ * Each SPI controller can communicate with one or more @spi_device + * children. These make a small bus, sharing MOSI, MISO and SCK signals + * but not chip select signals. Each device may be configured to use a + * different clock rate, since those shared signals are ignored unless +@@ -401,7 +403,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) + * an SPI slave device. For each such message it queues, it calls the + * message's completion function when the transaction completes. + */ +-struct spi_master { ++struct spi_controller { + struct device dev; + + struct list_head list; +@@ -439,11 +441,13 @@ struct spi_master { + + /* other constraints relevant to this driver */ + u16 flags; +-#define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ +-#define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */ +-#define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ +-#define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ +-#define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ ++#define SPI_CONTROLLER_HALF_DUPLEX BIT(0) /* can't do full duplex */ ++#define SPI_CONTROLLER_NO_RX BIT(1) /* can't do buffer read */ ++#define SPI_CONTROLLER_NO_TX BIT(2) /* can't do buffer write */ ++#define SPI_CONTROLLER_MUST_RX BIT(3) /* requires rx */ ++#define SPI_CONTROLLER_MUST_TX BIT(4) /* requires tx */ ++ ++#define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */ + + /* flag indicating this is an SPI slave controller */ + bool slave; +@@ -481,8 +485,8 @@ struct spi_master { + * any other request management + * + To a given spi_device, message queueing is pure fifo + * +- * + The master's main job is to process its message queue, +- * selecting a chip then transferring data ++ * + The controller's main job is to process its message queue, ++ * selecting a chip (for masters), then transferring data + * + If there are multiple spi_device children, the i/o queue + * arbitration algorithm is unspecified (round robin, fifo, + * priority, reservations, preemption, etc) +@@ -495,7 +499,7 @@ struct spi_master { + int (*transfer)(struct spi_device *spi, + struct spi_message *mesg); + +- /* called on release() to free memory provided by spi_master */ ++ /* called on release() to free memory provided by spi_controller */ + void (*cleanup)(struct spi_device *spi); + + /* +@@ -505,13 +509,13 @@ struct spi_master { + * not modify or store xfer and dma_tx and dma_rx must be set + * while the device is prepared. + */ +- bool (*can_dma)(struct spi_master *master, ++ bool (*can_dma)(struct spi_controller *ctlr, + struct spi_device *spi, + struct spi_transfer *xfer); + + /* + * These hooks are for drivers that want to use the generic +- * master transfer queueing mechanism. If these are used, the ++ * controller transfer queueing mechanism. If these are used, the + * transfer() function above must NOT be specified by the driver. + * Over time we expect SPI drivers to be phased over to this API. + */ +@@ -532,15 +536,15 @@ struct spi_master { + struct completion xfer_completion; + size_t max_dma_len; + +- int (*prepare_transfer_hardware)(struct spi_master *master); +- int (*transfer_one_message)(struct spi_master *master, ++ int (*prepare_transfer_hardware)(struct spi_controller *ctlr); ++ int (*transfer_one_message)(struct spi_controller *ctlr, + struct spi_message *mesg); +- int (*unprepare_transfer_hardware)(struct spi_master *master); +- int (*prepare_message)(struct spi_master *master, ++ int (*unprepare_transfer_hardware)(struct spi_controller *ctlr); ++ int (*prepare_message)(struct spi_controller *ctlr, + struct spi_message *message); +- int (*unprepare_message)(struct spi_master *master, ++ int (*unprepare_message)(struct spi_controller *ctlr, + struct spi_message *message); +- int (*slave_abort)(struct spi_master *spi); ++ int (*slave_abort)(struct spi_controller *ctlr); + int (*spi_flash_read)(struct spi_device *spi, + struct spi_flash_read_message *msg); + bool (*flash_read_supported)(struct spi_device *spi); +@@ -550,9 +554,9 @@ struct spi_master { + * of transfer_one_message() provied by the core. + */ + void (*set_cs)(struct spi_device *spi, bool enable); +- int (*transfer_one)(struct spi_master *master, struct spi_device *spi, ++ int (*transfer_one)(struct spi_controller *ctlr, struct spi_device *spi, + struct spi_transfer *transfer); +- void (*handle_err)(struct spi_master *master, ++ void (*handle_err)(struct spi_controller *ctlr, + struct spi_message *message); + + /* gpio chip select */ +@@ -569,58 +573,59 @@ struct spi_master { + void *dummy_rx; + void *dummy_tx; + +- int (*fw_translate_cs)(struct spi_master *master, unsigned cs); ++ int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs); + }; + +-static inline void *spi_master_get_devdata(struct spi_master *master) ++static inline void *spi_controller_get_devdata(struct spi_controller *ctlr) + { +- return dev_get_drvdata(&master->dev); ++ return dev_get_drvdata(&ctlr->dev); + } + +-static inline void spi_master_set_devdata(struct spi_master *master, void *data) ++static inline void spi_controller_set_devdata(struct spi_controller *ctlr, ++ void *data) + { +- dev_set_drvdata(&master->dev, data); ++ dev_set_drvdata(&ctlr->dev, data); + } + +-static inline struct spi_master *spi_master_get(struct spi_master *master) ++static inline struct spi_controller *spi_controller_get(struct spi_controller *ctlr) + { +- if (!master || !get_device(&master->dev)) ++ if (!ctlr || !get_device(&ctlr->dev)) + return NULL; +- return master; ++ return ctlr; + } + +-static inline void spi_master_put(struct spi_master *master) ++static inline void spi_controller_put(struct spi_controller *ctlr) + { +- if (master) +- put_device(&master->dev); ++ if (ctlr) ++ put_device(&ctlr->dev); + } + +-static inline bool spi_controller_is_slave(struct spi_master *ctlr) ++static inline bool spi_controller_is_slave(struct spi_controller *ctlr) + { + return IS_ENABLED(CONFIG_SPI_SLAVE) && ctlr->slave; + } + + /* PM calls that need to be issued by the driver */ +-extern int spi_master_suspend(struct spi_master *master); +-extern int spi_master_resume(struct spi_master *master); ++extern int spi_controller_suspend(struct spi_controller *ctlr); ++extern int spi_controller_resume(struct spi_controller *ctlr); + + /* Calls the driver make to interact with the message queue */ +-extern struct spi_message *spi_get_next_queued_message(struct spi_master *master); +-extern void spi_finalize_current_message(struct spi_master *master); +-extern void spi_finalize_current_transfer(struct spi_master *master); ++extern struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr); ++extern void spi_finalize_current_message(struct spi_controller *ctlr); ++extern void spi_finalize_current_transfer(struct spi_controller *ctlr); + +-/* the spi driver core manages memory for the spi_master classdev */ +-extern struct spi_master *__spi_alloc_controller(struct device *host, +- unsigned int size, bool slave); ++/* the spi driver core manages memory for the spi_controller classdev */ ++extern struct spi_controller *__spi_alloc_controller(struct device *host, ++ unsigned int size, bool slave); + +-static inline struct spi_master *spi_alloc_master(struct device *host, +- unsigned int size) ++static inline struct spi_controller *spi_alloc_master(struct device *host, ++ unsigned int size) + { + return __spi_alloc_controller(host, size, false); + } + +-static inline struct spi_master *spi_alloc_slave(struct device *host, +- unsigned int size) ++static inline struct spi_controller *spi_alloc_slave(struct device *host, ++ unsigned int size) + { + if (!IS_ENABLED(CONFIG_SPI_SLAVE)) + return NULL; +@@ -628,18 +633,18 @@ static inline struct spi_master *spi_alloc_slave(struct device *host, + return __spi_alloc_controller(host, size, true); + } + +-extern int spi_register_master(struct spi_master *master); +-extern int devm_spi_register_master(struct device *dev, +- struct spi_master *master); +-extern void spi_unregister_master(struct spi_master *master); ++extern int spi_register_controller(struct spi_controller *ctlr); ++extern int devm_spi_register_controller(struct device *dev, ++ struct spi_controller *ctlr); ++extern void spi_unregister_controller(struct spi_controller *ctlr); + +-extern struct spi_master *spi_busnum_to_master(u16 busnum); ++extern struct spi_controller *spi_busnum_to_master(u16 busnum); + + /* + * SPI resource management while processing a SPI message + */ + +-typedef void (*spi_res_release_t)(struct spi_master *master, ++typedef void (*spi_res_release_t)(struct spi_controller *ctlr, + struct spi_message *msg, + void *res); + +@@ -664,7 +669,7 @@ extern void *spi_res_alloc(struct spi_device *spi, + extern void spi_res_add(struct spi_message *message, void *res); + extern void spi_res_free(void *res); + +-extern void spi_res_release(struct spi_master *master, ++extern void spi_res_release(struct spi_controller *ctlr, + struct spi_message *message); + + /*---------------------------------------------------------------------------*/ +@@ -848,7 +853,7 @@ struct spi_message { + + /* for optional use by whatever driver currently owns the + * spi_message ... between calls to spi_async and then later +- * complete(), that's the spi_master controller driver. ++ * complete(), that's the spi_controller controller driver. + */ + struct list_head queue; + void *state; +@@ -937,21 +942,22 @@ extern int spi_async_locked(struct spi_device *spi, + static inline size_t + spi_max_message_size(struct spi_device *spi) + { +- struct spi_master *master = spi->master; +- if (!master->max_message_size) ++ struct spi_controller *ctlr = spi->controller; ++ ++ if (!ctlr->max_message_size) + return SIZE_MAX; +- return master->max_message_size(spi); ++ return ctlr->max_message_size(spi); + } + + static inline size_t + spi_max_transfer_size(struct spi_device *spi) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + size_t tr_max = SIZE_MAX; + size_t msg_max = spi_max_message_size(spi); + +- if (master->max_transfer_size) +- tr_max = master->max_transfer_size(spi); ++ if (ctlr->max_transfer_size) ++ tr_max = ctlr->max_transfer_size(spi); + + /* transfer size limit must not be greater than messsage size limit */ + return min(tr_max, msg_max); +@@ -962,7 +968,7 @@ extern int spi_async_locked(struct spi_device *spi, + /* SPI transfer replacement methods which make use of spi_res */ + + struct spi_replaced_transfers; +-typedef void (*spi_replaced_release_t)(struct spi_master *master, ++typedef void (*spi_replaced_release_t)(struct spi_controller *ctlr, + struct spi_message *msg, + struct spi_replaced_transfers *res); + /** +@@ -1006,7 +1012,7 @@ extern struct spi_replaced_transfers *spi_replace_transfers( + + /* SPI transfer transformation methods */ + +-extern int spi_split_transfers_maxsize(struct spi_master *master, ++extern int spi_split_transfers_maxsize(struct spi_controller *ctlr, + struct spi_message *msg, + size_t maxsize, + gfp_t gfp); +@@ -1020,8 +1026,8 @@ extern int spi_split_transfers_maxsize(struct spi_master *master, + + extern int spi_sync(struct spi_device *spi, struct spi_message *message); + extern int spi_sync_locked(struct spi_device *spi, struct spi_message *message); +-extern int spi_bus_lock(struct spi_master *master); +-extern int spi_bus_unlock(struct spi_master *master); ++extern int spi_bus_lock(struct spi_controller *ctlr); ++extern int spi_bus_unlock(struct spi_controller *ctlr); + + /** + * spi_sync_transfer - synchronous SPI data transfer +@@ -1206,9 +1212,9 @@ struct spi_flash_read_message { + /* SPI core interface for flash read support */ + static inline bool spi_flash_read_supported(struct spi_device *spi) + { +- return spi->master->spi_flash_read && +- (!spi->master->flash_read_supported || +- spi->master->flash_read_supported(spi)); ++ return spi->controller->spi_flash_read && ++ (!spi->controller->flash_read_supported || ++ spi->controller->flash_read_supported(spi)); + } + + int spi_flash_read(struct spi_device *spi, +@@ -1240,7 +1246,7 @@ int spi_flash_read(struct spi_device *spi, + * @irq: Initializes spi_device.irq; depends on how the board is wired. + * @max_speed_hz: Initializes spi_device.max_speed_hz; based on limits + * from the chip datasheet and board-specific signal quality issues. +- * @bus_num: Identifies which spi_master parents the spi_device; unused ++ * @bus_num: Identifies which spi_controller parents the spi_device; unused + * by spi_new_device(), and otherwise depends on board wiring. + * @chip_select: Initializes spi_device.chip_select; depends on how + * the board is wired. +@@ -1279,7 +1285,7 @@ struct spi_board_info { + + + /* bus_num is board specific and matches the bus_num of some +- * spi_master that will probably be registered later. ++ * spi_controller that will probably be registered later. + * + * chip_select reflects how this chip is wired to that master; + * it's less than num_chipselect. +@@ -1313,7 +1319,7 @@ struct spi_board_info { + /* If you're hotplugging an adapter with devices (parport, usb, etc) + * use spi_new_device() to describe each device. You can also call + * spi_unregister_device() to start making that device vanish, but +- * normally that would be handled by spi_unregister_master(). ++ * normally that would be handled by spi_unregister_controller(). + * + * You can also use spi_alloc_device() and spi_add_device() to use a two + * stage registration sequence for each spi_device. This gives the caller +@@ -1322,13 +1328,13 @@ struct spi_board_info { + * be defined using the board info. + */ + extern struct spi_device * +-spi_alloc_device(struct spi_master *master); ++spi_alloc_device(struct spi_controller *ctlr); + + extern int + spi_add_device(struct spi_device *spi); + + extern struct spi_device * +-spi_new_device(struct spi_master *, struct spi_board_info *); ++spi_new_device(struct spi_controller *, struct spi_board_info *); + + extern void spi_unregister_device(struct spi_device *spi); + +@@ -1336,9 +1342,32 @@ struct spi_board_info { + spi_get_device_id(const struct spi_device *sdev); + + static inline bool +-spi_transfer_is_last(struct spi_master *master, struct spi_transfer *xfer) ++spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer) + { +- return list_is_last(&xfer->transfer_list, &master->cur_msg->transfers); ++ return list_is_last(&xfer->transfer_list, &ctlr->cur_msg->transfers); + } + ++ ++/* Compatibility layer */ ++#define spi_master spi_controller ++ ++#define SPI_MASTER_HALF_DUPLEX SPI_CONTROLLER_HALF_DUPLEX ++#define SPI_MASTER_NO_RX SPI_CONTROLLER_NO_RX ++#define SPI_MASTER_NO_TX SPI_CONTROLLER_NO_TX ++#define SPI_MASTER_MUST_RX SPI_CONTROLLER_MUST_RX ++#define SPI_MASTER_MUST_TX SPI_CONTROLLER_MUST_TX ++ ++#define spi_master_get_devdata(_ctlr) spi_controller_get_devdata(_ctlr) ++#define spi_master_set_devdata(_ctlr, _data) \ ++ spi_controller_set_devdata(_ctlr, _data) ++#define spi_master_get(_ctlr) spi_controller_get(_ctlr) ++#define spi_master_put(_ctlr) spi_controller_put(_ctlr) ++#define spi_master_suspend(_ctlr) spi_controller_suspend(_ctlr) ++#define spi_master_resume(_ctlr) spi_controller_resume(_ctlr) ++ ++#define spi_register_master(_ctlr) spi_register_controller(_ctlr) ++#define devm_spi_register_master(_dev, _ctlr) \ ++ devm_spi_register_controller(_dev, _ctlr) ++#define spi_unregister_master(_ctlr) spi_unregister_controller(_ctlr) ++ + #endif /* __LINUX_SPI_H */ +diff --git a/include/trace/events/spi.h b/include/trace/events/spi.h +index 7e02c98..f9f702b 100644 +--- a/include/trace/events/spi.h ++++ b/include/trace/events/spi.h +@@ -7,37 +7,37 @@ + #include <linux/ktime.h> + #include <linux/tracepoint.h> + +-DECLARE_EVENT_CLASS(spi_master, ++DECLARE_EVENT_CLASS(spi_controller, + +- TP_PROTO(struct spi_master *master), ++ TP_PROTO(struct spi_controller *controller), + +- TP_ARGS(master), ++ TP_ARGS(controller), + + TP_STRUCT__entry( + __field( int, bus_num ) + ), + + TP_fast_assign( +- __entry->bus_num = master->bus_num; ++ __entry->bus_num = controller->bus_num; + ), + + TP_printk("spi%d", (int)__entry->bus_num) + + ); + +-DEFINE_EVENT(spi_master, spi_master_idle, ++DEFINE_EVENT(spi_controller, spi_controller_idle, + +- TP_PROTO(struct spi_master *master), ++ TP_PROTO(struct spi_controller *controller), + +- TP_ARGS(master) ++ TP_ARGS(controller) + + ); + +-DEFINE_EVENT(spi_master, spi_master_busy, ++DEFINE_EVENT(spi_controller, spi_controller_busy, + +- TP_PROTO(struct spi_master *master), ++ TP_PROTO(struct spi_controller *controller), + +- TP_ARGS(master) ++ TP_ARGS(controller) + + ); + +@@ -54,7 +54,7 @@ + ), + + TP_fast_assign( +- __entry->bus_num = msg->spi->master->bus_num; ++ __entry->bus_num = msg->spi->controller->bus_num; + __entry->chip_select = msg->spi->chip_select; + __entry->msg = msg; + ), +@@ -95,7 +95,7 @@ + ), + + TP_fast_assign( +- __entry->bus_num = msg->spi->master->bus_num; ++ __entry->bus_num = msg->spi->controller->bus_num; + __entry->chip_select = msg->spi->chip_select; + __entry->msg = msg; + __entry->frame = msg->frame_length; +@@ -122,7 +122,7 @@ + ), + + TP_fast_assign( +- __entry->bus_num = msg->spi->master->bus_num; ++ __entry->bus_num = msg->spi->controller->bus_num; + __entry->chip_select = msg->spi->chip_select; + __entry->xfer = xfer; + __entry->len = xfer->len; +-- +1.7.10.4 diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0090-pinctrl-sh-pfc-r8a7795-fix-ssi349_ctrl-name.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0090-pinctrl-sh-pfc-r8a7795-fix-ssi349_ctrl-name.patch new file mode 100644 index 0000000..0b4cd6f --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0090-pinctrl-sh-pfc-r8a7795-fix-ssi349_ctrl-name.patch @@ -0,0 +1,28 @@ +From defb4800e4b12760ac0479a7bcd71b0a3cf0aaa3 Mon Sep 17 00:00:00 2001 +From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> +Date: Tue, 30 Jan 2018 17:42:44 +0300 +Subject: [PATCH] pinctrl: sh-pfc: r8a7795: fix ssi349_ctrl name + +This fixes the ssi349_ctrl for r8a7795 SoC + +Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +index 3fc141a..f7dad4b 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +@@ -5066,7 +5066,7 @@ enum { + "ssi2_ctrl_a", + "ssi2_ctrl_b", + "ssi3_data", +- "ssi34_ctrl", ++ "ssi349_ctrl", + "ssi4_data", + "ssi4_ctrl", + "ssi5_data", +-- +1.9.1 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0106-media-rcar-imr-Add-RSE-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0106-media-rcar-imr-Add-RSE-support.patch new file mode 100644 index 0000000..1c8d800 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0106-media-rcar-imr-Add-RSE-support.patch @@ -0,0 +1,327 @@ +From a6fd88487f2dda6f8c5ec28230129478711206fb Mon Sep 17 00:00:00 2001 +From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com> +Date: Tue, 6 Feb 2018 13:38:34 +0300 +Subject: [PATCH] media: rcar-imr: Add RSE support + +This adds RSE support for V3H IMR + +Signed-off-by: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com> +--- + drivers/media/platform/rcar_imr.c | 143 +++++++++++++++++++++++++++++++ + include/uapi/linux/rcar-imr.h | 22 ++++- + 2 files changed, 165 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c +index 9b601da..7b16765 100644 +--- a/drivers/media/platform/rcar_imr.c ++++ b/drivers/media/platform/rcar_imr.c +@@ -17,6 +17,7 @@ + #include <linux/pm_runtime.h> + #include <linux/delay.h> + #include <linux/rcar-imr.h> ++#include <linux/of.h> + #include <media/v4l2-device.h> + #include <media/v4l2-ctrls.h> + #include <media/v4l2-fh.h> +@@ -38,6 +39,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-4)"); + * Local types definitions + ******************************************************************************/ + ++/* Number of RSE planes on V3H (non scaled, 1/2, 1/4, 1/8) */ ++#define RSE_PLANES_NUM 4 ++ + /* ...configuration data */ + struct imr_cfg { + /* ...display-list main program data */ +@@ -49,6 +53,21 @@ struct imr_cfg { + /* ...pointers to the source/destination planes */ + u32 *src_pa_ptr[2]; + u32 *dst_pa_ptr[2]; ++ /* ...pointers to the RSE destination planes */ ++ u32 *dstn_pa_ptr[RSE_PLANES_NUM]; ++ u32 *dstr_pa_ptr[RSE_PLANES_NUM]; ++ ++ /* ...offsets to RSE destination planes */ ++ u32 dstnr_offsets[IMR_EXTDST_NUM]; ++ ++ /* ...RSE logical right shift data */ ++ u32 *rscr_ptr; ++ u8 rscr_sc8, rscr_sc4, rscr_sc2; ++ ++ /* ...RSE destination stride values */ ++ u32 dstnr_strides[IMR_EXTDST_NUM]; ++ u32 *striden_ptr[RSE_PLANES_NUM]; ++ u32 *strider_ptr[RSE_PLANES_NUM]; + + /* ...subpixel destination coordinates space */ + int dst_subpixel; +@@ -96,6 +115,8 @@ struct imr_device { + struct v4l2_m2m_dev *m2m_dev; + struct device *alloc_dev; + ++ bool rse; ++ + /* ...do we need that counter really? framework counts fh structures for us - tbd */ + int refcount; + +@@ -219,6 +240,18 @@ struct imr_ctx { + + #define IMR_TPOR 0xF0 + ++#define IMR_RSCSR 0x204 ++#define IMR_RSCCR 0x208 ++#define IMR_RSCR_RSE 31 ++#define IMR_RSCR_SC8 25 ++#define IMR_RSCR_SC4 21 ++#define IMR_RSCR_SC2 17 ++ ++#define IMR_DSANRR0 0x210 ++#define IMR_DSTNRR0 0x214 ++#define IMR_DSARR0 0x218 ++#define IMR_DSTRR0 0x21C ++ + /******************************************************************************* + * Auxiliary helpers + ******************************************************************************/ +@@ -398,6 +431,7 @@ static int imr_queue_setup(struct vb2_queue *vq, + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_Y10: ++ case V4L2_PIX_FMT_Y12: + case V4L2_PIX_FMT_Y16: + sizes[0] = w * h * 2; + break; +@@ -750,6 +784,7 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg + int W = ctx->queue[1].fmt.width; + int H = ctx->queue[1].fmt.height; + u32 tricr = ctx->color & 0xFFFFFF; ++ int i; + + v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "setup %u*%u -> %u*%u mapping (type=%x)\n", w, h, W, H, type); + +@@ -775,6 +810,38 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg + *dl++ = IMR_OP_WTS(IMR_CMRCCR, 0xFFFF); + *dl++ = IMR_OP_WTS(IMR_CMRCCR2, 0xFFFF); + ++ if (type & IMR_MAP_RSE) { ++ /* ...enable RSE */ ++ *dl++ = IMR_OP_WTL(IMR_RSCCR, 1); ++ *dl++ = 0xffffffff; ++ *dl++ = IMR_OP_WTL(IMR_RSCSR, 1); ++ cfg->rscr_ptr = dl++; ++ ++ for (i = 0; i < RSE_PLANES_NUM; i++) { ++ /* ...set destination planes base address and strides */ ++ *dl++ = IMR_OP_WTL(IMR_DSANRR0 + i * 0x10, 4); ++ cfg->dstn_pa_ptr[i] = dl++; ++ cfg->striden_ptr[i] = dl++; ++ cfg->dstr_pa_ptr[i] = dl++; ++ cfg->strider_ptr[i] = dl++; ++ } ++ ++ cfg->rscr_sc8 = cfg->rscr_sc4 = cfg->rscr_sc2 = 0; ++ memset(cfg->dstnr_offsets, 0, sizeof(cfg->dstnr_offsets)); ++ memset(cfg->dstnr_strides, 0, sizeof(cfg->dstnr_strides)); ++ } else { ++ /* ...disable RSE */ ++ *dl++ = IMR_OP_WTL(IMR_RSCCR, 1); ++ *dl++ = 0xffffffff; ++ ++ for (i = 0; i < RSE_PLANES_NUM; i++) { ++ cfg->dstn_pa_ptr[i] = NULL; ++ cfg->striden_ptr[i] = NULL; ++ cfg->dstr_pa_ptr[i] = NULL; ++ cfg->strider_ptr[i] = NULL; ++ } ++ cfg->rscr_ptr = NULL; ++ } + /* ...set source/destination addresses of Y/UV plane */ + *dl++ = IMR_OP_WTL(IMR_DSAR, 2); + cfg->dst_pa_ptr[0] = dl++; +@@ -907,6 +974,12 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc) + + type = desc->type; + ++ /* ...check for RSE */ ++ if ((type & IMR_MAP_RSE) && !imr->rse) { ++ v4l2_err(&imr->v4l2_dev, "Rotator & Scaler extension not supported\n"); ++ return -EINVAL; ++ } ++ + /* ...mesh item size calculation */ + item_size = (type & IMR_MAP_LUCE ? 4 : 0) + (type & IMR_MAP_CLCE ? 4 : 0); + +@@ -1055,6 +1128,12 @@ static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc) + u32 dl_start_offset; + dma_addr_t dl_dma_addr; + ++ /* ...check RSE */ ++ if ((type & IMR_MAP_RSE) && !imr->rse) { ++ v4l2_err(&imr->v4l2_dev, "Rotator & Scaler extension not supported\n"); ++ return -EINVAL; ++ } ++ + /* ...calculate main routine length */ + dl_size = imr_dl_program_length(ctx); + if (!dl_size) { +@@ -1103,6 +1182,46 @@ static int imr_ioctl_color(struct imr_ctx *ctx, u32 color) + return 0; + } + ++static int imr_extdst_set(struct imr_ctx *ctx, u32 *extdst) ++{ ++ struct imr_device *imr = ctx->imr; ++ struct imr_cfg *cfg = ctx->cfg; ++ ++ if (!cfg) { ++ v4l2_err(&imr->v4l2_dev, "failed to set V3H extension dst buffers: No active confguration.\n"); ++ return -EINVAL; ++ } ++ ++ if (copy_from_user((void *) cfg->dstnr_offsets, (void __user *) extdst, sizeof(cfg->dstnr_offsets))) { ++ v4l2_err(&imr->v4l2_dev, "failed to read V3H extension dst buffers\n"); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static int imr_extstride_set(struct imr_ctx *ctx, struct imr_rse_param *param) ++{ ++ struct imr_device *imr = ctx->imr; ++ struct imr_cfg *cfg = ctx->cfg; ++ ++ if (!cfg) { ++ v4l2_err(&imr->v4l2_dev, "failed to set V3H extension buffers params: No active confguration.\n"); ++ return -EINVAL; ++ } ++ ++ cfg->rscr_sc8 = param->sc8; ++ cfg->rscr_sc4 = param->sc4; ++ cfg->rscr_sc2 = param->sc2; ++ ++ if (copy_from_user((void *) cfg->dstnr_strides, (void __user *) param->strides, sizeof(cfg->dstnr_strides))) { ++ v4l2_err(&imr->v4l2_dev, "failed to read V3H extension buffers strides\n"); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ + /******************************************************************************* + * V4L2 I/O controls + ******************************************************************************/ +@@ -1356,6 +1475,14 @@ static long imr_default(struct file *file, void *fh, bool valid_prio, unsigned i + /* ...set solid color code */ + return imr_ioctl_color(ctx, *(u32 *)arg); + ++ case VIDIOC_IMR_EXTDST: ++ /* ...set V3H extension dst buffers */ ++ return imr_extdst_set(ctx, *(u32 **)arg); ++ ++ case VIDIOC_IMR_EXTSTRIDE: ++ /* ...set V3H extension dst strides */ ++ return imr_extstride_set(ctx, (struct imr_rse_param *)arg); ++ + default: + return -ENOIOCTLCMD; + } +@@ -1579,6 +1706,7 @@ static void imr_device_run(void *priv) + struct vb2_v4l2_buffer *src_buf, *dst_buf; + u32 src_addr, dst_addr; + unsigned long flags; ++ int i; + + v4l2_dbg(3, debug, &imr->v4l2_dev, "run next job...\n"); + +@@ -1608,6 +1736,17 @@ static void imr_device_run(void *priv) + *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); + ++ for (i = 0; i < RSE_PLANES_NUM; i++) { ++ if (cfg->rscr_ptr) *cfg->rscr_ptr = (1 << IMR_RSCR_RSE) | (cfg->rscr_sc8 << IMR_RSCR_SC8) | ++ (cfg->rscr_sc4 << IMR_RSCR_SC4) |(cfg->rscr_sc2 << IMR_RSCR_SC2); ++ ++ if (cfg->dstn_pa_ptr[i]) *cfg->dstn_pa_ptr[i] = dst_addr + cfg->dstnr_offsets[i]; ++ if (cfg->dstr_pa_ptr[i]) *cfg->dstr_pa_ptr[i] = dst_addr + cfg->dstnr_offsets[i + RSE_PLANES_NUM]; ++ ++ if (cfg->striden_ptr[i]) *cfg->striden_ptr[i] = cfg->dstnr_strides[i]; ++ if (cfg->strider_ptr[i]) *cfg->strider_ptr[i] = cfg->dstnr_strides[i + RSE_PLANES_NUM]; ++ } ++ + /* ...adjust source/destination parameters of the UV-plane as needed */ + if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) { + *cfg->src_pa_ptr[1] = src_addr + ctx->queue[0].fmt.width * ctx->queue[0].fmt.height; +@@ -1776,6 +1915,7 @@ static int imr_probe(struct platform_device *pdev) + { + struct imr_device *imr; + struct resource *res; ++ struct device_node *np = pdev->dev.of_node; + int ret; + + imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL); +@@ -1786,6 +1926,9 @@ static int imr_probe(struct platform_device *pdev) + spin_lock_init(&imr->lock); + imr->dev = &pdev->dev; + ++ /* Check RSE support */ ++ imr->rse = of_property_read_bool(np, "rse"); ++ + /* ...memory-mapped registers */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { +diff --git a/include/uapi/linux/rcar-imr.h b/include/uapi/linux/rcar-imr.h +index 7b8ed0c..19fdbae 100644 +--- a/include/uapi/linux/rcar-imr.h ++++ b/include/uapi/linux/rcar-imr.h +@@ -25,8 +25,8 @@ struct imr_map_desc { + /* ...total size of the mesh structure */ + u32 size; + +- /* ...map-specific user-pointer */ +- void *data; ++ /* ...map-specific user-pointer */ ++ void *data; + + } __attribute__((packed)); + +@@ -54,6 +54,9 @@ struct imr_map_desc { + /* ...bilinear filtration enable flag */ + #define IMR_MAP_BFE (1 << 7) + ++/* ...extended functionality (rotation/scaling) enable flag */ ++#define IMR_MAP_RSE (1 << 21) ++ + /* ...source coordinate decimal point position bit index */ + #define __IMR_MAP_UVDPOR_SHIFT 8 + #define __IMR_MAP_UVDPOR(v) (((v) >> __IMR_MAP_UVDPOR_SHIFT) & 0x7) +@@ -88,11 +91,26 @@ struct imr_mesh { + } __attribute__((packed)); + + /******************************************************************************* ++ * V3H Extension destination data ++ ******************************************************************************/ ++/* ...number of V3H extension destination buffers (rotated/non-rotated, scaled 1/1, 1/2, 1/4, 1/8) */ ++#define IMR_EXTDST_NUM 8 ++ ++struct imr_rse_param { ++ /* ...logical right shift data */ ++ u8 sc8, sc4, sc2; ++ /* ...destination buffers stride */ ++ u32 *strides; ++}; ++ ++/******************************************************************************* + * Private IOCTL codes + ******************************************************************************/ + + #define VIDIOC_IMR_MESH _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct imr_map_desc) + #define VIDIOC_IMR_MESH_RAW _IOW('V', BASE_VIDIOC_PRIVATE + 1, struct imr_map_desc) + #define VIDIOC_IMR_COLOR _IOW('V', BASE_VIDIOC_PRIVATE + 2, u32) ++#define VIDIOC_IMR_EXTDST _IOW('V', BASE_VIDIOC_PRIVATE + 3, u32 *) ++#define VIDIOC_IMR_EXTSTRIDE _IOW('V', BASE_VIDIOC_PRIVATE + 4, struct imr_rse_param) + + #endif /* RCAR_IMR_USER_H */ +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0107-V3H-device-tree-Add-VIP-devices-IRQs.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0107-V3H-device-tree-Add-VIP-devices-IRQs.patch new file mode 100644 index 0000000..7198428 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0107-V3H-device-tree-Add-VIP-devices-IRQs.patch @@ -0,0 +1,189 @@ +From 2ef84c77a4c536dc1996c2e6ca2dc3cfa743fe7e Mon Sep 17 00:00:00 2001 +From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com> +Date: Fri, 9 Mar 2018 15:50:29 +0300 +Subject: [PATCH] V3H device tree: Add VIP devices IRQs. + +--- + arch/arm64/boot/dts/renesas/r8a7798.dtsi | 110 ++++++++++++++++++++++++++++--- + 1 file changed, 100 insertions(+), 10 deletions(-) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +index 6412a24..b8b0665 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7798.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +@@ -1627,72 +1627,162 @@ + rse; + }; + +- disp { ++ vip_disp_status { + compatible = "generic-uio"; + reg = <0 0xe7a00000 0 0x10000>; ++ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 101>; + power-domains = <&sysc R8A7798_PD_A3VIP>; + }; + +- umf { ++ vip_disp_error { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a00000 0 0x10000>; ++ interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 101>; ++ power-domains = <&sysc R8A7798_PD_A3VIP>; ++ }; ++ ++ vip_umf_status { + compatible = "generic-uio"; + reg = <0 0xe7a10000 0 0x10000>; ++ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 102>; + power-domains = <&sysc R8A7798_PD_A3VIP1>; + }; + +- smd_ps { ++ vip_umf_error { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a10000 0 0x10000>; ++ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 102>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ vip_smd_ps_status { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a20000 0 0x10000>; ++ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1102>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ vip_smd_ps_error { + compatible = "generic-uio"; + reg = <0 0xe7a20000 0 0x10000>; ++ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1102>; + power-domains = <&sysc R8A7798_PD_A3VIP1>; + }; + +- smd_est { ++ vip_smd_est_status { + compatible = "generic-uio"; + reg = <0 0xe7a30000 0 0x10000>; ++ interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1101>; + power-domains = <&sysc R8A7798_PD_A3VIP1>; + }; + +- smd_post { ++ vip_smd_est_error { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a30000 0 0x10000>; ++ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1101>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ vip_smd_post_status { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a40000 0 0x10000>; ++ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1100>; ++ power-domains = <&sysc R8A7798_PD_A3VIP1>; ++ }; ++ ++ vip_smd_post_error { + compatible = "generic-uio"; + reg = <0 0xe7a40000 0 0x10000>; ++ interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1100>; + power-domains = <&sysc R8A7798_PD_A3VIP1>; + }; + +- cle0 { ++ vip_cle0_status { + compatible = "generic-uio"; + reg = <0 0xe7a50000 0 0x10000>; ++ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1004>; + power-domains = <&sysc R8A7798_PD_A3VIP2>; + }; + +- cle1 { ++ vip_cle0_error { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a50000 0 0x10000>; ++ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1004>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ vip_cle1_status { + compatible = "generic-uio"; + reg = <0 0xe7a60000 0 0x10000>; ++ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1003>; + power-domains = <&sysc R8A7798_PD_A3VIP2>; + }; + +- cle2 { ++ vip_cle1_error { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a60000 0 0x10000>; ++ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1003>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ vip_cle2_status { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a70000 0 0x10000>; ++ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1002>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ vip_cle2_error { + compatible = "generic-uio"; + reg = <0 0xe7a70000 0 0x10000>; ++ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1002>; + power-domains = <&sysc R8A7798_PD_A3VIP2>; + }; + +- cle3 { ++ vip_cle3_status { + compatible = "generic-uio"; + reg = <0 0xe7a80000 0 0x10000>; ++ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1001>; + power-domains = <&sysc R8A7798_PD_A3VIP2>; + }; + +- cle4 { ++ vip_cle3_erorr { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a80000 0 0x10000>; ++ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1001>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ vip_cle4_status { ++ compatible = "generic-uio"; ++ reg = <0 0xe7a90000 0 0x10000>; ++ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 1000>; ++ power-domains = <&sysc R8A7798_PD_A3VIP2>; ++ }; ++ ++ vip_cle4_error { + compatible = "generic-uio"; + reg = <0 0xe7a90000 0 0x10000>; ++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1000>; + power-domains = <&sysc R8A7798_PD_A3VIP2>; + }; +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0108-can-mcp251x-add-reset-gpio-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0108-can-mcp251x-add-reset-gpio-support.patch new file mode 100644 index 0000000..646aa0c --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0108-can-mcp251x-add-reset-gpio-support.patch @@ -0,0 +1,72 @@ +From b69e3fdc91fbc88cc32eb6794872e1f058681b04 Mon Sep 17 00:00:00 2001 +From: Andrey Gusakov <andrey.gusakov@cogentembedded.com> +Date: Mon, 26 Mar 2018 13:51:49 +0300 +Subject: [PATCH] can: mcp251x: add reset gpio support + +Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com> +--- + drivers/net/can/spi/mcp251x.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c +index f3f05fe..ac78ce3 100644 +--- a/drivers/net/can/spi/mcp251x.c ++++ b/drivers/net/can/spi/mcp251x.c +@@ -71,6 +71,7 @@ + #include <linux/netdevice.h> + #include <linux/of.h> + #include <linux/of_device.h> ++#include <linux/of_gpio.h> + #include <linux/platform_device.h> + #include <linux/slab.h> + #include <linux/spi/spi.h> +@@ -270,6 +271,7 @@ struct mcp251x_priv { + struct regulator *power; + struct regulator *transceiver; + struct clk *clk; ++ struct gpio_desc *rst; + }; + + #define MCP251X_IS(_model) \ +@@ -1031,9 +1033,21 @@ static int mcp251x_can_probe(struct spi_device *spi) + struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev); + struct net_device *net; + struct mcp251x_priv *priv; ++ struct gpio_desc *reset_gpio; + struct clk *clk; + int freq, ret; + ++ reset_gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH); ++ if (IS_ERR(reset_gpio)) { ++ if (PTR_ERR(reset_gpio) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ dev_err(&spi->dev, "cannot get reset-gpios %ld\n", ++ PTR_ERR(reset_gpio)); ++ reset_gpio = NULL; ++ } else { ++ gpiod_set_value_cansleep(reset_gpio, 1); ++ } ++ + clk = devm_clk_get(&spi->dev, NULL); + if (IS_ERR(clk)) { + if (pdata) +@@ -1074,6 +1088,7 @@ static int mcp251x_can_probe(struct spi_device *spi) + priv->model = spi_get_device_id(spi)->driver_data; + priv->net = net; + priv->clk = clk; ++ priv->rst = reset_gpio; + + spi_set_drvdata(spi, priv); + +@@ -1185,6 +1200,8 @@ static int mcp251x_can_remove(struct spi_device *spi) + + mcp251x_power_enable(priv->power, 0); + ++ gpiod_set_value_cansleep(priv->rst, 0); ++ + if (!IS_ERR(priv->clk)) + clk_disable_unprepare(priv->clk); + +-- +1.9.1 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0109-ASoC-R-Car-fix-incorrect-behavior-with-PulseAudio.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0109-ASoC-R-Car-fix-incorrect-behavior-with-PulseAudio.patch new file mode 100644 index 0000000..89788bf --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0109-ASoC-R-Car-fix-incorrect-behavior-with-PulseAudio.patch @@ -0,0 +1,65 @@ +From 539d604c483df0a00033f207a2926b6048d99fbc Mon Sep 17 00:00:00 2001 +From: Andrey Gusakov <andrey.gusakov@cogentembedded.com> +Date: Fri, 30 Mar 2018 15:57:43 +0300 +Subject: [PATCH] ASoC: R-Car: fix incorrect behavior with PulseAudio + +io->hw_params is set for hw_constraint. And set to NULL in +rsnd_hw_params. But rule chacker can be called between +rsnd_hw_params and rsnd_soc_dai_trigger causing driver to +use io->hw_params instead of cached values. +Set io->hw_params = NULL in rsnd_soc_dai_trigger before actually +starting HW. + +Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com> +--- + sound/soc/sh/rcar/core.c | 8 ++++++++ + sound/soc/sh/rcar/ssi.c | 6 +++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 7e85aec..982f3d0 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -630,6 +630,14 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, + int ret; + unsigned long flags; + ++ /* ++ * hw_refine finished. remove hw_param from rdai ++ * see ++ * __rsnd_soc_hw_rule_rate() ++ * __rsnd_soc_hw_rule_channels() ++ */ ++ io->hw_params = NULL; ++ + spin_lock_irqsave(&priv->lock, flags); + + switch (cmd) { +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index fb5f7fd..8695647 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -240,7 +240,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); +- int chan = rsnd_runtime_channel_for_ssi(io); + int idx, ret; + unsigned int main_rate; + unsigned int rate = rsnd_io_is_play(io) ? +@@ -265,9 +264,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, + return 0; + } + +- main_rate = rsnd_ssi_clk_query(priv, rate, chan, &idx); ++ main_rate = rsnd_ssi_clk_query(priv, rate, ssi->chan, &idx); + if (!main_rate) { +- dev_err(dev, "unsupported clock rate\n"); ++ dev_err(dev, "unsupported clock rate: %dx%d\n", ++ rate, ssi->chan); + return -EIO; + } + +-- +1.9.1 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0110-Renesas-clk-Add-RPC-clock-source.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0110-Renesas-clk-Add-RPC-clock-source.patch new file mode 100644 index 0000000..37d08e9 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0110-Renesas-clk-Add-RPC-clock-source.patch @@ -0,0 +1,263 @@ +From b4acae6eda19307e0051763a532f522006a82d5c Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 10:37:04 +0300 +Subject: [PATCH 01/12] Renesas: clk: Add RPC clock source + +Add RPC clock source functionality + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/clk/renesas/rcar-gen3-cpg.c | 200 ++++++++++++++++++++++++++++++++++++ + drivers/clk/renesas/rcar-gen3-cpg.h | 4 + + 2 files changed, 204 insertions(+) + +diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c +index 99acba2..969e1b2 100644 +--- a/drivers/clk/renesas/rcar-gen3-cpg.c ++++ b/drivers/clk/renesas/rcar-gen3-cpg.c +@@ -599,6 +599,7 @@ static const struct clk_div_table cpg_sd01_div_table[] = { + { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 }, + }; + ++ + #define CPG_SD_STP_HCK BIT(9) + #define CPG_SD_STP_CK BIT(8) + +@@ -811,6 +812,202 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, + return clk; + } + ++/**************** RPCSCK ***********************************/ ++ ++ ++ ++struct rpc_clock { ++ struct clk_hw hw; ++ void __iomem *reg; ++ const struct clk_div_table *div_table; ++ unsigned int div_num; ++ unsigned int div_min; ++ unsigned int div_max; ++}; ++ ++static const struct clk_div_table cpg_rpc_div_table[] = { ++ { 0x11, 20 }, { 0x13, 40 }, { 0x15, 60 }, { 0x17, 80 }, ++ { 0x19, 24 }, { 0x1B, 48 }, { 0x1D, 72 }, { 0x1F, 96 }, ++}; ++ ++#define to_rpc_clock(_hw) container_of(_hw, struct rpc_clock, hw) ++ ++#define CPG_RPC_ENA_MASK (BIT(9) | BIT(8)) ++#define CPG_RPC_SCALE_MASK (0x1F) ++ ++ ++static int cpg_rpc_clock_endisable(void __iomem *reg, bool enable) ++{ ++ u32 val; ++ ++ val = readl(reg); ++ ++ if (enable) ++ val &= ~CPG_RPC_ENA_MASK; ++ else ++ val |= CPG_RPC_ENA_MASK; ++ ++ writel(val, reg); ++ return 0; ++}; ++ ++static int cpg_rpc_clock_enable(struct clk_hw *hw) ++{ ++ struct rpc_clock *clock = to_rpc_clock(hw); ++ ++ cpg_rpc_clock_endisable(clock->reg, true); ++ ++ return 0; ++} ++ ++static void cpg_rpc_clock_disable(struct clk_hw *hw) ++{ ++ struct rpc_clock *clock = to_rpc_clock(hw); ++ ++ cpg_rpc_clock_endisable(clock->reg, false); ++} ++ ++static int cpg_rpc_clock_is_enabled(struct clk_hw *hw) ++{ ++ struct rpc_clock *clock = to_rpc_clock(hw); ++ ++ return !(readl(clock->reg) & CPG_RPC_ENA_MASK); ++} ++ ++static unsigned long cpg_rpc_clock_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct rpc_clock *clock = to_rpc_clock(hw); ++ unsigned long rate = parent_rate; ++ u32 val, scale; ++ unsigned int i; ++ ++ val = readl(clock->reg); ++ ++ scale = val & CPG_RPC_SCALE_MASK; ++ for (i = 0; i < clock->div_num; i++) ++ if (scale == clock->div_table[i].val) ++ break; ++ ++ if (i >= clock->div_num) ++ return 0; ++ ++ return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); ++} ++ ++static unsigned int cpg_rpc_clock_calc_div(struct rpc_clock *clock, ++ unsigned long rate, ++ unsigned long parent_rate) ++{ ++ unsigned int div; ++ ++ if (!rate) ++ rate = 1; ++ ++ div = DIV_ROUND_CLOSEST(parent_rate, rate); ++ ++ return clamp_t(unsigned int, div, clock->div_min, clock->div_max); ++} ++ ++static long cpg_rpc_clock_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ struct rpc_clock *clock = to_rpc_clock(hw); ++ unsigned int div = cpg_rpc_clock_calc_div(clock, rate, *parent_rate); ++ ++ return DIV_ROUND_CLOSEST(*parent_rate, div); ++} ++ ++static int cpg_rpc_clock_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct rpc_clock *clock = to_rpc_clock(hw); ++ unsigned int div = cpg_rpc_clock_calc_div(clock, rate, parent_rate); ++ u32 val; ++ unsigned int i, nearest_i, nearest_div; ++ ++ ++ for (i = 0; i < clock->div_num; i++) ++ if (div == clock->div_table[i].div) ++ break; ++ ++ if (i >= clock->div_num) { ++ /* find nearest */ ++ nearest_div = -1; ++ nearest_i = clock->div_num; ++ for (i = 0; i < clock->div_num; i++) { ++ if (clock->div_table[i].div >= div && ++ clock->div_table[i].div <= nearest_div) { ++ nearest_i = i; ++ nearest_div = clock->div_table[i].div; ++ } ++ } ++ ++ i = nearest_i; ++ } ++ ++ if (i >= clock->div_num) ++ return -EINVAL; ++ ++ val = readl(clock->reg); ++ val &= ~CPG_RPC_SCALE_MASK; ++ val |= clock->div_table[i].val; ++ writel(val, clock->reg); ++ ++ return 0; ++} ++ ++static const struct clk_ops cpg_rpc_clock_ops = { ++ .enable = cpg_rpc_clock_enable, ++ .disable = cpg_rpc_clock_disable, ++ .is_enabled = cpg_rpc_clock_is_enabled, ++ .recalc_rate = cpg_rpc_clock_recalc_rate, ++ .round_rate = cpg_rpc_clock_round_rate, ++ .set_rate = cpg_rpc_clock_set_rate, ++}; ++ ++static struct clk * __init cpg_rpc_clk_register(const struct cpg_core_clk *core, ++ void __iomem *base, ++ const char *parent_name) ++{ ++ struct clk_init_data init; ++ struct rpc_clock *clock; ++ struct clk *clk; ++ unsigned int i; ++ ++ clock = kzalloc(sizeof(*clock), GFP_KERNEL); ++ if (!clock) ++ return ERR_PTR(-ENOMEM); ++ ++ init.name = core->name; ++ init.ops = &cpg_rpc_clock_ops; ++ init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; ++ init.parent_names = &parent_name; ++ init.num_parents = 1; ++ ++ clock->reg = base + core->offset; ++ clock->hw.init = &init; ++ clock->div_table = cpg_rpc_div_table; ++ clock->div_num = ARRAY_SIZE(cpg_rpc_div_table); ++ ++ clock->div_max = clock->div_table[0].div; ++ clock->div_min = clock->div_max; ++ for (i = 1; i < clock->div_num; i++) { ++ clock->div_max = max(clock->div_max, clock->div_table[i].div); ++ clock->div_min = min(clock->div_min, clock->div_table[i].div); ++ } ++ ++ clk = clk_register(NULL, &clock->hw); ++ if (IS_ERR(clk)) ++ kfree(clock); ++ ++ return clk; ++} ++ ++/***********************************************************/ ++ ++ ++ + + static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata; + static unsigned int cpg_clk_extalr __initdata; +@@ -943,6 +1140,9 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, + return cpg_zg_clk_register(core->name, __clk_get_name(parent), + base); + ++ case CLK_TYPE_GEN3_RPCSRC: ++ return cpg_rpc_clk_register(core, base, __clk_get_name(parent)); ++ + default: + return ERR_PTR(-EINVAL); + } +diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h +index 694bedc..636ef54 100644 +--- a/drivers/clk/renesas/rcar-gen3-cpg.h ++++ b/drivers/clk/renesas/rcar-gen3-cpg.h +@@ -27,6 +27,7 @@ enum rcar_gen3_clk_types { + CLK_TYPE_GEN3_ZG, + CLK_TYPE_GEN3_RINT, + CLK_TYPE_GEN3_OSC, ++ CLK_TYPE_GEN3_RPCSRC, + }; + + #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ +@@ -36,6 +37,9 @@ enum rcar_gen3_clk_types { + #define DEF_GEN3_SD0H(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD0H, _parent, .offset = _offset) + ++#define DEF_GEN3_RPCSRC(_name, _id, _parent, _offset) \ ++ DEF_BASE(_name, _id, CLK_TYPE_GEN3_RPCSRC, _parent, .offset = _offset) ++ + struct rcar_gen3_cpg_pll_config { + unsigned int extal_div; + unsigned int pll1_mult; +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0111-Renesas-r8a7798-Add-RPC-clock.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0111-Renesas-r8a7798-Add-RPC-clock.patch new file mode 100644 index 0000000..e0fb7d2 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0111-Renesas-r8a7798-Add-RPC-clock.patch @@ -0,0 +1,46 @@ +From 05ab83db0e0012674a0255fe37a51713a1601732 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 10:42:50 +0300 +Subject: [PATCH 02/12] Renesas: r8a7798: Add RPC clock + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/clk/renesas/r8a7798-cpg-mssr.c | 3 +++ + include/dt-bindings/clock/r8a7798-cpg-mssr.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/clk/renesas/r8a7798-cpg-mssr.c b/drivers/clk/renesas/r8a7798-cpg-mssr.c +index e407916..2614147 100644 +--- a/drivers/clk/renesas/r8a7798-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a7798-cpg-mssr.c +@@ -90,6 +90,8 @@ static const struct cpg_core_clk r8a7798_core_clks[] __initconst = { + + DEF_GEN3_SD("sd0", R8A7798_CLK_SD0, CLK_SDSRC, 0x0074), /* OK? */ + ++ DEF_GEN3_RPCSRC("rpcsrc", R8A7798_CLK_RPCSRC, CLK_PLL1, 0x0238), ++ + DEF_FIXED("cl", R8A7798_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A7798_CLK_CP, CLK_EXTAL, 2, 1), + +@@ -194,6 +196,7 @@ static const struct mssr_mod_clk r8a7798_mod_clks[] __initconst = { + DEF_MOD("gpio1", 911, R8A7798_CLK_CP), + DEF_MOD("gpio0", 912, R8A7798_CLK_CP), + DEF_MOD("can-fd", 914, R8A7798_CLK_S3D2), ++ DEF_MOD("rpc", 917, R8A7798_CLK_RPCSRC), + /* FIXME missing MSSR for i2c5; should it be 919 as in H3/M3? */ + /* DEF_MOD("i2c4", 919, R8A7798_CLK_S3D2), */ + DEF_MOD("i2c4", 927, R8A7798_CLK_S0D6), +diff --git a/include/dt-bindings/clock/r8a7798-cpg-mssr.h b/include/dt-bindings/clock/r8a7798-cpg-mssr.h +index 3d85730..821383d3 100644 +--- a/include/dt-bindings/clock/r8a7798-cpg-mssr.h ++++ b/include/dt-bindings/clock/r8a7798-cpg-mssr.h +@@ -52,5 +52,6 @@ + #define R8A7798_CLK_CPEX 36 + #define R8A7798_CLK_R 37 + #define R8A7798_CLK_OSC 38 ++#define R8A7798_CLK_RPCSRC 39 + + #endif /* __DT_BINDINGS_CLOCK_R8A7798_CPG_MSSR_H__ */ +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0112-Renesas-r8a7798-pinctrl-Add-RPC-pin-control.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0112-Renesas-r8a7798-pinctrl-Add-RPC-pin-control.patch new file mode 100644 index 0000000..5c91f56 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0112-Renesas-r8a7798-pinctrl-Add-RPC-pin-control.patch @@ -0,0 +1,119 @@ +From ba6a829c33809d780c40c3f60e97e8a9e2a99a92 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 10:48:44 +0300 +Subject: [PATCH 03/12] Renesas: r8a7798: pinctrl: Add RPC pin control + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7798.c | 74 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7798.c b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c +index 39aba74..f20afd1 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7798.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c +@@ -1472,6 +1472,60 @@ static const unsigned int scif_clk_b_mux[] = { + SCIF_CLK_B_MARK, + }; + ++/* - QSPI ------------------------------------------------------------------- */ ++static const unsigned int qspi0_ctrl_pins[] = { ++ /* QSPI0_SPCLK QSPI0_SSL */ ++ RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 0), ++}; ++static const unsigned int qspi0_ctrl_mux[] = { ++ QSPI0_SPCLK_MARK, QSPI0_SSL_MARK, ++}; ++ ++static const unsigned int qspi0_data2_pins[] = { ++ /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1 */ ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2), ++}; ++static const unsigned int qspi0_data2_mux[] = { ++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, ++}; ++ ++static const unsigned int qspi0_data4_pins[] = { ++ /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1, QSPI0_IO2, QSPI0_IO3 */ ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2), ++ RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 4), ++}; ++static const unsigned int qspi0_data4_mux[] = { ++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, ++ QSPI0_IO2_MARK, QSPI0_IO3_MARK ++}; ++ ++static const unsigned int qspi1_ctrl_pins[] = { ++ /* QSPI1_SPCLK QSPI1_SSL */ ++ RCAR_GP_PIN(5, 6), RCAR_GP_PIN(5, 11), ++}; ++static const unsigned int qspi1_ctrl_mux[] = { ++ QSPI1_SPCLK_MARK, QSPI1_SSL_MARK, ++}; ++ ++static const unsigned int qspi1_data2_pins[] = { ++ /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1 */ ++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8), ++}; ++static const unsigned int qspi1_data2_mux[] = { ++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, ++}; ++ ++static const unsigned int qspi1_data4_pins[] = { ++ /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1, QSPI1_IO2, QSPI1_IO3 */ ++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8), ++ RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10), ++}; ++static const unsigned int qspi1_data4_mux[] = { ++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, ++ QSPI1_IO2_MARK, QSPI1_IO3_MARK ++}; ++ ++ + /* - I2C -------------------------------------------------------------------- */ + static const unsigned int i2c0_pins[] = { + /* SDA0, SCL0 */ +@@ -2419,6 +2473,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(vin1_field), + SH_PFC_PIN_GROUP(vin1_clkenb), + SH_PFC_PIN_GROUP(vin1_clk), ++ SH_PFC_PIN_GROUP(qspi0_ctrl), ++ SH_PFC_PIN_GROUP(qspi0_data2), ++ SH_PFC_PIN_GROUP(qspi0_data4), ++ SH_PFC_PIN_GROUP(qspi1_ctrl), ++ SH_PFC_PIN_GROUP(qspi1_data2), ++ SH_PFC_PIN_GROUP(qspi1_data4), + }; + + static const char * const avb_groups[] = { +@@ -2683,6 +2743,18 @@ static const char * const vin1_groups[] = { + "vin1_clk", + }; + ++static const char * const qspi0_groups[] = { ++ "qspi0_ctrl", ++ "qspi0_data2", ++ "qspi0_data4", ++}; ++ ++static const char * const qspi1_groups[] = { ++ "qspi1_ctrl", ++ "qspi1_data2", ++ "qspi1_data4", ++}; ++ + static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(avb), + SH_PFC_FUNCTION(gether), +@@ -2719,6 +2791,8 @@ static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(tmu), + SH_PFC_FUNCTION(vin0), + SH_PFC_FUNCTION(vin1), ++ SH_PFC_FUNCTION(qspi0), ++ SH_PFC_FUNCTION(qspi1), + }; + + static const struct pinmux_cfg_reg pinmux_config_regs[] = { +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0113-Renesas-RPC-Add-RPC-driver.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0113-Renesas-RPC-Add-RPC-driver.patch new file mode 100644 index 0000000..86b2d6c --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0113-Renesas-RPC-Add-RPC-driver.patch @@ -0,0 +1,1483 @@ +From 931484f9bd4eb1741588dc1574080fa4534ac5dc Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 11:08:16 +0300 +Subject: [PATCH 04/12] Renesas: RPC: Add RPC driver + +This is initial commit. Driver supports single and dual mode. +Dual mode means that there are two spi-nor flashes connected. +Supports qspi flashes. + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/mtd/spi-nor/Kconfig | 8 + + drivers/mtd/spi-nor/Makefile | 1 + + drivers/mtd/spi-nor/renesas-rpc.c | 1429 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 1438 insertions(+) + create mode 100644 drivers/mtd/spi-nor/renesas-rpc.c + +diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig +index 4a682ee..298dc1d 100644 +--- a/drivers/mtd/spi-nor/Kconfig ++++ b/drivers/mtd/spi-nor/Kconfig +@@ -7,6 +7,14 @@ menuconfig MTD_SPI_NOR + + if MTD_SPI_NOR + ++ ++config SPI_RENESAS_RPC ++ tristate "Renesas RPC controller" ++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A7797 || ARCH_R8A7798 || COMPILE_TEST ++ help ++ QSPI driver for Renesas SPI Multi I/O Bus controller. This controller ++ supports normal, dual and quad spi for one or two SPI NOR Flashes. ++ + config MTD_MT81xx_NOR + tristate "Mediatek MT81xx SPI NOR flash controller" + depends on HAS_IOMEM +diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile +index 121695e..e99d775 100644 +--- a/drivers/mtd/spi-nor/Makefile ++++ b/drivers/mtd/spi-nor/Makefile +@@ -5,3 +5,4 @@ obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o + obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o + obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o + obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o ++obj-$(CONFIG_SPI_RENESAS_RPC) += renesas-rpc.o +diff --git a/drivers/mtd/spi-nor/renesas-rpc.c b/drivers/mtd/spi-nor/renesas-rpc.c +new file mode 100644 +index 0000000..1e93c98 +--- /dev/null ++++ b/drivers/mtd/spi-nor/renesas-rpc.c +@@ -0,0 +1,1429 @@ ++/* ++ * Renesas RPC driver ++ * ++ * Copyright (C) 2018, Cogent Embedded Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/interrupt.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++#include <linux/mtd/spi-nor.h> ++ ++ ++ ++#define CMNCR 0x0000 ++#define SSLDR 0x0004 ++#define DRCR 0x000C ++#define DRCMR 0x0010 ++#define DREAR 0x0014 ++#define DROPR 0x0018 ++#define DRENR 0x001C ++#define SMCR 0x0020 ++#define SMCMR 0x0024 ++#define SMADR 0x0028 ++#define SMOPR 0x002C ++#define SMENR 0x0030 ++#define SMRDR0 0x0038 ++#define SMRDR1 0x003C ++#define SMWDR0 0x0040 ++#define SMWDR1 0x0044 ++#define CMNSR 0x0048 ++#define DRDMCR 0x0058 ++#define DRDRENR 0x005C ++#define SMDMCR 0x0060 ++#define SMDRENR 0x0064 ++#define PHYCNT 0x007C ++#define PHYOFFSET1 0x0080 ++#define PHYOFFSET2 0x0084 ++#define PHYINT 0x0088 ++#define DIV_REG 0x00A8 ++ ++/* CMNCR */ ++#define CMNCR_BSZ_MASK (0x03) ++#define CMNCR_BSZ_4x1 (0x0) ++#define CMNCR_BSZ_8x1 (0x1) ++#define CMNCR_BSZ_4x2 (0x1) ++#define CMNCR_MD (0x1 << 31) ++#define CMNCR_MOIIO3_MASK (0x3 << 22) ++#define CMNCR_MOIIO3_HIZ (0x3 << 22) ++#define CMNCR_MOIIO2_MASK (0x3 << 20) ++#define CMNCR_MOIIO2_HIZ (0x3 << 20) ++#define CMNCR_MOIIO1_MASK (0x3 << 18) ++#define CMNCR_MOIIO1_HIZ (0x3 << 18) ++#define CMNCR_MOIIO0_MASK (0x3 << 16) ++#define CMNCR_MOIIO0_HIZ (0x3 << 16) ++#define CMNCR_IO0FV_MASK (0x3 << 8) ++#define CMNCR_IO0FV_HIZ (0x3 << 8) ++ ++ ++/* DRCR */ ++#define DRCR_RBURST_MASK (0x1f << 16) ++#define DRCR_RBURST(v) (((v) & 0x1f) << 16) ++#define DRCR_SSLE (0x1) ++#define DRCR_RBE (0x1 << 8) ++#define DRCR_RCF (0x1 << 9) ++#define DRCR_RBURST_32 (0x1f << 16) ++ ++ ++/* SMENR */ ++#define SMENR_CDB_MASK (0x03 << 30) ++#define SMENR_CDB(v) (((v) & 0x03) << 30) ++#define SMENR_CDB_1B (0) ++#define SMENR_CDB_2B (0x1 << 30) ++#define SMENR_CDB_4B (0x2 << 30) ++#define SMENR_OCDB_MASK (0x03 << 28) ++#define SMENR_OCDB_1B (0) ++#define SMENR_OCDB_2B (0x1 << 28) ++#define SMENR_OCDB_4B (0x2 << 28) ++#define SMENR_ADB_MASK (0x03 << 24) ++#define SMENR_ADB(v) (((v) & 0x03) << 24) ++#define SMENR_ADB_1B (0) ++#define SMENR_ADB_2B (0x1 << 24) ++#define SMENR_ADB_4B (0x2 << 24) ++#define SMENR_OPDB_MASK (0x03 << 20) ++#define SMENR_OPDB_1B (0) ++#define SMENR_OPDB_2B (0x1 << 20) ++#define SMENR_OPDB_4B (0x2 << 20) ++#define SMENR_SPIDB_MASK (0x03 << 16) ++#define SMENR_SPIDB(v) (((v) & 0x03) << 16) ++#define SMENR_SPIDB_1B (0) ++#define SMENR_SPIDB_2B (0x1 << 16) ++#define SMENR_SPIDB_4B (0x2 << 16) ++#define SMENR_OPDE_MASK (0xf << 4) ++#define SMENR_OPDE_DISABLE (0) ++#define SMENR_OPDE3 (0x8 << 4) ++#define SMENR_OPDE32 (0xC << 4) ++#define SMENR_OPDE321 (0xE << 4) ++#define SMENR_OPDE3210 (0xF << 4) ++#define SMENR_SPIDE_MASK (0x0F) ++#define SMENR_SPIDE_DISABLE (0) ++#define SMENR_SPIDE_8B (0x08) ++#define SMENR_SPIDE_16B (0x0C) ++#define SMENR_SPIDE_32B (0x0F) ++#define SMENR_DME (1<<15) ++#define SMENR_CDE (1<<14) ++#define SMENR_OCDE (1<<12) ++#define SMENR_ADE_MASK (0xf << 8) ++#define SMENR_ADE_DISABLE (0) ++#define SMENR_ADE_23_16 (0x4 << 8) ++#define SMENR_ADE_23_8 (0x6 << 8) ++#define SMENR_ADE_23_0 (0x7 << 8) ++#define SMENR_ADE_31_0 (0xf << 8) ++ ++ ++/* SMCMR */ ++#define SMCMR_CMD(cmd) (((cmd) & 0xff) << 16) ++#define SMCMR_CMD_MASK (0xff << 16) ++#define SMCMR_OCMD(cmd) (((cmd) & 0xff)) ++#define SMCMR_OCMD_MASK (0xff) ++ ++ ++/* SMDRENR */ ++#define SMDRENR_HYPE_MASK (0x7 << 12) ++#define SMDRENR_HYPE_SPI_FLASH (0x0) ++#define SMDRENR_ADDRE (0x1 << 8) ++#define SMDRENR_OPDRE (0x1 << 4) ++#define SMDRENR_SPIDRE (0x1) ++ ++/* PHYCNT */ ++#define PHYCNT_CAL (0x1 << 31) ++#define PHYCNT_OCTA_MASK (0x3 << 22) ++#define PHYCNT_EXDS (0x1 << 21) ++#define PHYCNT_OCT (0x1 << 20) ++#define PHYCNT_DDRCAL (0x1 << 19) ++#define PHYCNT_HS (0x1 << 18) ++#define PHYCNT_STREAM_MASK (0x7 << 15) ++#define PHYCNT_STREAM(o) (((o) & 0x7) << 15) ++#define PHYCNT_WBUF2 (0x1 << 4) ++#define PHYCNT_WBUF (0x1 << 2) ++#define PHYCNT_PHYMEM_MASK (0x3) ++ ++/* SMCR */ ++#define SMCR_SSLKP (0x1 << 8) ++#define SMCR_SPIRE (0x1 << 2) ++#define SMCR_SPIWE (0x1 << 1) ++#define SMCR_SPIE (0x1) ++ ++/* CMNSR */ ++#define CMNSR_TEND (0x1 << 0) ++ ++/* SSLDR */ ++#define SSLDR_SPNDL(v) (((v) & 0x7) << 16) ++#define SSLDR_SLNDL(v) ((((v) | 0x4) & 0x7) << 8) ++#define SSLDR_SCKDL(v) ((v) & 0x7) ++ ++/* DREAR */ ++#define DREAR_EAV_MASK (0xff << 16) ++#define DREAR_EAV(v) (((v) & 0xff) << 16) ++#define DREAR_EAC_MASK (0x7) ++#define DREAR_24B (0) ++#define DREAR_25B (1) ++ ++/* DRENR */ ++#define DRENR_CDB_MASK (0x03 << 30) ++#define DRENR_CDB(v) (((v) & 0x3) << 30) ++#define DRENR_CDB_1B (0) ++#define DRENR_CDB_2B (0x1 << 30) ++#define DRENR_CDB_4B (0x2 << 30) ++#define DRENR_OCDB_MASK (0x03 << 28) ++#define DRENR_OCDB_1B (0) ++#define DRENR_OCDB_2B (0x1 << 28) ++#define DRENR_OCDB_4B (0x2 << 28) ++#define DRENR_ADB_MASK (0x03 << 24) ++#define DRENR_ADB(v) (((v) & 0x3) << 24) ++#define DRENR_ADB_1B (0) ++#define DRENR_ADB_2B (0x1 << 24) ++#define DRENR_ADB_4B (0x2 << 24) ++#define DRENR_OPDB_MASK (0x03 << 20) ++#define DRENR_OPDB_1B (0) ++#define DRENR_OPDB_2B (0x1 << 20) ++#define DRENR_OPDB_4B (0x2 << 20) ++#define DRENR_DRDB_MASK (0x03 << 16) ++#define DRENR_DRDB(v) (((v) & 0x3) << 16) ++#define DRENR_DRDB_1B (0) ++#define DRENR_DRDB_2B (0x1 << 16) ++#define DRENR_DRDB_4B (0x2 << 16) ++#define DRENR_OPDE_MASK (0xf << 4) ++#define DRENR_OPDE_DISABLE (0) ++#define DRENR_OPDE3 (0x8 << 4) ++#define DRENR_OPDE32 (0xC << 4) ++#define DRENR_OPDE321 (0xE << 4) ++#define DRENR_OPDE3210 (0xF << 4) ++#define DRENR_DME (1<<15) ++#define DRENR_CDE (1<<14) ++#define DRENR_OCDE (1<<12) ++#define DRENR_ADE_MASK (0xf << 8) ++#define DRENR_ADE_DISABLE (0) ++#define DRENR_ADE_23_0 (0x7 << 8) ++#define DRENR_ADE_31_0 (0xf << 8) ++ ++/* DRCMR */ ++#define DRCMR_CMD(cmd) (((cmd) & 0xff) << 16) ++#define DRCMR_CMD_MASK (0xff << 16) ++#define DRCMR_OCMD(cmd) (((cmd) & 0xff)) ++#define DRCMR_OCMD_MASK (0xff) ++ ++/* DRCMR */ ++#define DRDMCR_DMCYC(v) ((v) & 0x1f) ++#define DRDMCR_DMCYC_MASK (0x1f) ++ ++/* SMDMCR */ ++#define SMDMCR_DMCYC(v) ((v) & 0x0f) ++#define SMDMCR_DMCYC_MASK (0x0f) ++ ++/* PHYOFFSET1 */ ++#define PHYOFFSET1_DDRTMG (1 << 28) ++ ++/* DIVREG */ ++#define DIVREG_RATIO_MASK (0x03) ++#define DIVREG_RATIO(v) ((v) & 0x03) ++#define DIVREG_RATIO_MAX (0x2) ++ ++ ++#define DEFAULT_TO (100) ++#define WRITE_BUF_SIZE (0x100) ++#define WRITE_BUF_ADR_MASK (0xff) ++ ++#define REPEAT_MAX (20) ++#define REPEAT_TIME (10) ++ ++ ++struct rpc_spi { ++ struct platform_device *pdev; ++ void __iomem *base; ++ void __iomem *read_area; ++ void __iomem *write_area; ++ struct clk *clk; ++ unsigned int irq; ++ struct spi_nor spi_nor; ++ ++#define MTD_QSPI_1x 0 ++#define MTD_QSPI_2x 1 ++ ++ u32 mtdtype; ++}; ++ ++ ++ ++/* IP block use it's own clock divigion register */ ++#define OWN_CLOCK_DIVIDER BIT(0) ++ ++ ++ ++static void regs_dump(struct rpc_spi *rpc) ++{ ++ static u32 regs[] = { ++ CMNCR, SSLDR, DRCR, DRCMR, DREAR, ++ DROPR, DRENR, SMCR, SMCMR, SMADR, ++ SMOPR, SMENR, SMRDR0, SMRDR1, SMWDR0, ++ SMWDR1, CMNSR, DRDMCR, DRDRENR, SMDMCR, ++ SMDRENR, PHYCNT, PHYOFFSET1, PHYOFFSET2, ++ PHYINT ++ }; ++ ++ static const char *const names[] = { ++ "CMNCR", "SSLDR", "DRCR", "DRCMR", "DREAR", ++ "DROPR", "DRENR", "SMCR", "SMCMR", "SMADR", ++ "SMOPR", "SMENR", "SMRDR0", "SMRDR1", "SMWDR0", ++ "SMWDR1", "CMNSR", "DRDMCR", "DRDRENR", "SMDMCR", ++ "SMDRENR", "PHYCNT", "PHYOFFSET1", "PHYOFFSET2", ++ "PHYINT" ++ }; ++ ++ int i; ++ ++ dev_dbg(&rpc->pdev->dev, "RPC regs dump:\n"); ++ for (i = 0; i < ARRAY_SIZE(regs); i++) ++ dev_dbg(&rpc->pdev->dev, "%s = 0x%08x\n", names[i], ++ readl(rpc->base + regs[i])); ++} ++ ++ ++ ++ ++ ++static u32 rpc_read(struct rpc_spi *rpc, unsigned int reg) ++{ ++ u32 val; ++ ++ val = readl(rpc->base + reg); ++ return val; ++} ++ ++static void rpc_write(struct rpc_spi *rpc, unsigned int reg, u32 val) ++{ ++ writel(val, rpc->base + reg); ++} ++ ++ ++static int rpc_wait(struct rpc_spi *rpc, u32 to) ++{ ++ u32 val; ++ int i; ++ ++ for (i = 0; i < to; i++) { ++ val = rpc_read(rpc, CMNSR); ++ val &= CMNSR_TEND; ++ if (val) ++ break; ++ ++ udelay(100); ++ } ++ ++ if (i == to) { ++ dev_err(&rpc->pdev->dev, "timeout waiting for operation end %d\n", ++ rpc_read(rpc, CMNSR)); ++ return -ETIMEDOUT; ++ } ++ ++ return 0; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++static int rpc_setup_clk_ratio(struct rpc_spi *rpc, u32 max_clk_rate) ++{ ++ unsigned long rate = clk_get_rate(rpc->clk); ++ u32 ratio; ++ u32 val; ++ ++ ratio = DIV_ROUND_UP(rate, max_clk_rate * 2) >> 1; ++ if (ratio > DIVREG_RATIO_MAX) ++ ratio = DIVREG_RATIO_MAX; ++ ++ val = rpc_read(rpc, DIV_REG); ++ val &= DIVREG_RATIO_MASK; ++ val |= DIVREG_RATIO(ratio); ++ rpc_write(rpc, DIV_REG, val); ++ ++ return 0; ++} ++ ++static int rpc_endisable_write_buf(struct rpc_spi *rpc, bool en) ++{ ++ u32 val; ++ ++ val = rpc_read(rpc, PHYCNT); ++ ++ if (en) ++ val |= PHYCNT_WBUF | PHYCNT_WBUF2; ++ else ++ val &= ~(PHYCNT_WBUF | PHYCNT_WBUF2); ++ ++ rpc_write(rpc, PHYCNT, val); ++ ++ return 0; ++} ++ ++ ++static int rpc_begin(struct rpc_spi *rpc, ++ bool rx, bool tx, bool last) ++{ ++ u32 val = SMCR_SPIE; ++ ++ if (rx) ++ val |= SMCR_SPIRE; ++ ++ if (tx) ++ val |= SMCR_SPIWE; ++ ++ if (!last) ++ val |= SMCR_SSLKP; ++ ++ rpc_write(rpc, SMCR, val); ++ ++ return 0; ++} ++ ++ ++static int rpc_setup_reg_mode(struct rpc_spi *rpc) ++{ ++ u32 val; ++ ++ rpc_wait(rpc, DEFAULT_TO); ++ ++ rpc_endisable_write_buf(rpc, false); ++ ++ /* ...setup manual mode */ ++ val = rpc_read(rpc, CMNCR); ++ val |= CMNCR_MD; ++ rpc_write(rpc, CMNCR, val); ++ ++ /* disable ddr */ ++ val = rpc_read(rpc, SMDRENR); ++ val &= ~(SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); ++ rpc_write(rpc, SMDRENR, val); ++ ++ /* enable 1bit command */ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_DME ++ | SMENR_OCDE | SMENR_SPIDB_MASK ++ | SMENR_ADE_MASK | SMENR_ADB_MASK ++ | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); ++ val |= SMENR_CDB_1B | SMENR_CDE | SMENR_SPIDE_32B; ++ rpc_write(rpc, SMENR, val); ++ ++ ++ return 0; ++} ++ ++static void rpc_flush_cache(struct rpc_spi *rpc) ++{ ++ u32 val; ++ ++ val = rpc_read(rpc, DRCR); ++ val |= DRCR_RCF; ++ ++ rpc_write(rpc, DRCR, val); ++} ++ ++ ++static int rpc_setup_ext_mode(struct rpc_spi *rpc) ++{ ++ u32 val; ++ u32 cmncr; ++ ++ rpc_wait(rpc, DEFAULT_TO); ++ ++ rpc_endisable_write_buf(rpc, false); ++ ++ /* ...setup ext mode */ ++ val = rpc_read(rpc, CMNCR); ++ cmncr = val; ++ val &= ~(CMNCR_MD); ++ rpc_write(rpc, CMNCR, val); ++ ++ /* ...enable burst and clear cache */ ++ val = rpc_read(rpc, DRCR); ++ val &= ~(DRCR_RBURST_MASK | DRCR_RBE | DRCR_SSLE); ++ val |= DRCR_RBURST(0x1f) | DRCR_RBE; ++ ++ if (cmncr & CMNCR_MD) ++ val |= DRCR_RCF; ++ ++ rpc_write(rpc, DRCR, val); ++ ++ return 0; ++} ++ ++ ++static int rpc_setup_data_size(struct rpc_spi *rpc, u32 size, bool copy) ++{ ++ u32 val; ++ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_SPIDE_MASK); ++ ++ if (rpc->mtdtype == MTD_QSPI_2x && !copy) ++ size >>= 1; ++ ++ switch (size) { ++ case 0: ++ break; ++ case 1: ++ val |= SMENR_SPIDE_8B; ++ break; ++ case 2: ++ val |= SMENR_SPIDE_16B; ++ break; ++ case 4: ++ val |= SMENR_SPIDE_32B; ++ break; ++ default: ++ dev_err(&rpc->pdev->dev, "Unsupported data width %d\n", size); ++ return -EINVAL; ++ } ++ rpc_write(rpc, SMENR, val); ++ ++ return 0; ++} ++ ++ ++static int rpc_setup_extmode_read_addr(struct rpc_spi *rpc, ++ int adr_width, loff_t adr) ++{ ++ u32 val; ++ u32 v; ++ ++ val = rpc_read(rpc, DREAR); ++ val &= ~(DREAR_EAV_MASK | DREAR_EAC_MASK); ++ ++ if (adr_width == 4) { ++ v = adr >> 25; ++ val |= DREAR_EAV(v) | DREAR_25B; ++ } ++ rpc_write(rpc, DREAR, val); ++ ++ val = rpc_read(rpc, DRENR); ++ val &= ~(DRENR_ADE_MASK); ++ if (adr_width == 4) ++ val |= DRENR_ADE_31_0; ++ else ++ val |= DRENR_ADE_23_0; ++ rpc_write(rpc, DRENR, val); ++ ++ return 0; ++} ++ ++ ++ ++#define NBITS_TO_VAL(v) ((v >> 1) & 3) ++static int rpc_setup_extmode_nbits(struct rpc_spi *rpc, int cnb, ++ int anb, int dnb) ++{ ++ u32 val; ++ ++ val = rpc_read(rpc, DRENR); ++ val &= ~(DRENR_CDB_MASK | DRENR_ADB_MASK | DRENR_DRDB_MASK); ++ val |= DRENR_CDB(NBITS_TO_VAL(cnb)) ++ | DRENR_ADB(NBITS_TO_VAL(anb)) ++ | DRENR_DRDB(NBITS_TO_VAL(dnb)); ++ rpc_write(rpc, DRENR, val); ++ ++ return 0; ++} ++ ++static int rpc_setup_writemode_nbits(struct rpc_spi *rpc, int cnb, ++ int anb, int dnb) ++{ ++ u32 val; ++ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_CDB_MASK | SMENR_ADB_MASK | SMENR_SPIDB_MASK); ++ val |= SMENR_CDB(NBITS_TO_VAL(cnb)) ++ | SMENR_ADB(NBITS_TO_VAL(anb)) ++ | SMENR_SPIDB(NBITS_TO_VAL(dnb)); ++ rpc_write(rpc, SMENR, val); ++ ++ return 0; ++} ++ ++static void rpc_setup_write_mode_command_and_adr(struct rpc_spi *rpc, ++ int adr_width, bool ena) ++{ ++ u32 val; ++ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_CDB_MASK | SMENR_CDE | SMENR_ADE_MASK); ++ ++ if (ena) { ++ /* enable 1bit command */ ++ val |= SMENR_CDB_1B | SMENR_CDE; ++ ++ if (adr_width == 4) ++ val |= SMENR_ADE_31_0; ++ else ++ val |= SMENR_ADE_23_0; ++ } ++ rpc_write(rpc, SMENR, val); ++} ++ ++static int rpc_setup_write_mode(struct rpc_spi *rpc) ++{ ++ u32 val; ++ ++ rpc_wait(rpc, DEFAULT_TO); ++ ++ rpc_endisable_write_buf(rpc, true); ++ ++ /* ...setup manual mode */ ++ val = rpc_read(rpc, CMNCR); ++ val |= CMNCR_MD; ++ rpc_write(rpc, CMNCR, val); ++ ++ /* disable ddr */ ++ val = rpc_read(rpc, SMDRENR); ++ val &= ~(SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); ++ rpc_write(rpc, SMDRENR, val); ++ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_OCDB_MASK | SMENR_DME | SMENR_OCDE | SMENR_SPIDB_MASK ++ | SMENR_ADB_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); ++ val |= SMENR_SPIDE_32B; ++ rpc_write(rpc, SMENR, val); ++ ++ return 0; ++} ++ ++static void rpc_read_manual_data(struct rpc_spi *rpc, u32 *pv0, u32 *pv1) ++{ ++ u32 val0, val1, rd0, rd1; ++ ++ val0 = rpc_read(rpc, SMRDR0); ++ val1 = rpc_read(rpc, SMRDR1); ++ ++ if (rpc->mtdtype == MTD_QSPI_2x) { ++ rd1 = (val0 & 0xff000000) | ((val0 << 8) & 0xff0000) | ++ ((val1 >> 16) & 0xff00) | ((val1 >> 8) & 0xff); ++ rd0 = ((val0 & 0xff0000) << 8) | ((val0 << 16) & 0xff0000) | ++ ((val1 >> 8) & 0xff00) | (val1 & 0xff); ++ } else ++ rd0 = val0; ++ ++ if (pv0) ++ *pv0 = rd0; ++ ++ if (pv1 && rpc->mtdtype == MTD_QSPI_2x) ++ *pv1 = rd1; ++} ++ ++ ++static int rpc_datalen2trancfersize(struct rpc_spi *rpc, int len, bool copy) ++{ ++ int sz = len; ++ ++ if (len >= 2) ++ sz = 2; ++ ++ if (len >= 4) ++ sz = 4; ++ ++ if (rpc->mtdtype == MTD_QSPI_2x ++ && len >= 8 && !copy) ++ sz = 8; ++ ++ return sz; ++} ++ ++static int __rpc_write_data2reg(struct rpc_spi *rpc, int off, ++ const u8 *buf, int sz) ++{ ++ const u32 *b32 = (const u32 *)buf; ++ const u16 *b16 = (const u16 *)buf; ++ ++ if (sz == 4) ++ rpc_write(rpc, off, *b32); ++ else if (sz == 2) ++ writew(*b16, rpc->base+off); ++ else if (sz == 1) ++ writeb(*buf, rpc->base+off); ++ else if (sz != 0) { ++ dev_err(&rpc->pdev->dev, "incorrect data size %d\n", sz); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#define __SETVAL(x) ((((x) & 0xff) << 8) | ((x) & 0xff)) ++static int rpc_write_data2reg(struct rpc_spi *rpc, const u8 *buf, ++ int sz, bool copy) ++{ ++ int i, ret; ++ u32 v = 0; ++ ++ if (rpc->mtdtype == MTD_QSPI_2x) { ++ if (copy) { ++ for (i = 0; i < sz && i < 2; i++) ++ v |= (__SETVAL(buf[i]) << 16*i); ++ ++ ret = __rpc_write_data2reg(rpc, ++ sz == 4 ? SMWDR1 : SMWDR0, ++ (u8 *)&v, ++ sz == 4 ? sz : sz * 2); ++ if (ret) ++ return ret; ++ ++ v = 0; ++ for (; i < sz; i++) ++ v |= (__SETVAL(buf[i]) << 16*i); ++ ++ ++ ret = __rpc_write_data2reg(rpc, ++ sz == 4 ? SMWDR0 : SMWDR1, ++ (u8 *)&v, ++ sz == 4 ? sz : sz * 2); ++ if (ret) ++ return ret; ++ ++ return 0; ++ } ++ ++ sz >>= 1; ++ ret = __rpc_write_data2reg(rpc, ++ sz == 4 ? SMWDR1 : SMWDR0, ++ buf, ++ sz == 4 ? sz : sz * 2); ++ if (ret) ++ return ret; ++ buf += sz; ++ ++ return __rpc_write_data2reg(rpc, ++ sz == 4 ? SMWDR0 : SMWDR1, ++ buf, sz == 4 ? sz : sz * 2); ++ } ++ ++ return __rpc_write_data2reg(rpc, SMWDR0, buf, sz); ++} ++ ++static ssize_t rpc_write_unaligned(struct spi_nor *nor, loff_t to, size_t len, ++ const u_char *buf, size_t fullen) ++{ ++ int ret = len, dsize; ++ struct rpc_spi *rpc = nor->priv; ++ bool copy = false, last; ++ loff_t _to; ++ ++ rpc_endisable_write_buf(rpc, false); ++ ++ while (len > 0) { ++ _to = to; ++ if (rpc->mtdtype == MTD_QSPI_2x) ++ _to >>= 1; ++ rpc_write(rpc, SMADR, _to); ++ dsize = rpc_datalen2trancfersize(rpc, len, copy); ++ ++ if (rpc_setup_data_size(rpc, dsize, copy)) ++ return -EINVAL; ++ ++ rpc_write_data2reg(rpc, buf, dsize, copy); ++ ++ last = (len <= dsize && fullen <= ret); ++ rpc_begin(rpc, false, true, last); ++ if (rpc_wait(rpc, DEFAULT_TO)) ++ return -ETIMEDOUT; ++ ++ /* ...disable command */ ++ rpc_setup_write_mode_command_and_adr(rpc, ++ nor->addr_width, false); ++ ++ buf += dsize; ++ len -= dsize; ++ to += dsize; ++ } ++ ++ return ret; ++} ++ ++ ++ ++ ++static ssize_t rpc_write_flash(struct spi_nor *nor, loff_t to, size_t len, ++ const u_char *buf) ++{ ++ ssize_t res = len, full = len; ++ u32 val; ++ u8 rval[2]; ++ struct rpc_spi *rpc = nor->priv; ++ loff_t bo; ++ loff_t offset; ++ loff_t _to; ++ bool is_rounded = false; ++ ++ /* ...len should be rounded to 2 bytes */ ++ if (rpc->mtdtype == MTD_QSPI_2x && (len & 1)) { ++ is_rounded = true; ++ len &= ~(1); ++ } ++ ++ bo = to & (WRITE_BUF_ADR_MASK); ++ ++ rpc_flush_cache(rpc); ++ rpc_setup_write_mode(rpc); ++ rpc_setup_write_mode_command_and_adr(rpc, nor->addr_width, true); ++ rpc_setup_writemode_nbits(rpc, 1, 1, 1); ++ ++ /* ...setup command */ ++ val = rpc_read(rpc, SMCMR); ++ val &= ~(SMCMR_CMD_MASK); ++ val |= SMCMR_CMD(nor->program_opcode); ++ rpc_write(rpc, SMCMR, val); ++ ++ offset = (to & (~WRITE_BUF_ADR_MASK)); ++ ++ /* ...write unaligned first bytes */ ++ if (bo) { ++ rpc_write_unaligned(nor, to, WRITE_BUF_SIZE - bo, buf, full); ++ rpc_setup_write_mode(rpc); ++ ++ len -= WRITE_BUF_SIZE - bo; ++ buf += WRITE_BUF_SIZE - bo; ++ to += WRITE_BUF_SIZE - bo; ++ full -= WRITE_BUF_SIZE - bo; ++ } ++ ++ /* Unfortunatly RPC does not write properly in write buf mode ++ * without transferring command. ++ * May be it is better just remove this code ++ */ ++ if (len >= WRITE_BUF_SIZE && !bo) { ++ _to = to; ++ if (rpc->mtdtype == MTD_QSPI_2x) ++ _to >>= 1; ++ rpc_write(rpc, SMADR, _to); ++ memcpy_toio(rpc->write_area, buf, WRITE_BUF_SIZE); ++ buf += WRITE_BUF_SIZE; ++ len -= WRITE_BUF_SIZE; ++ to += WRITE_BUF_SIZE; ++ full -= WRITE_BUF_SIZE; ++ ++ rpc_begin(rpc, false, true, full <= 0); ++ if (rpc_wait(rpc, DEFAULT_TO)) ++ return -ETIMEDOUT; ++ ++ rpc_setup_write_mode_command_and_adr(rpc, ++ nor->addr_width, false); ++ } ++ ++ if (len) { ++ rpc_write_unaligned(nor, to, len, buf, full); ++ buf += len; ++ to += len; ++ full -= len; ++ len = 0; ++ } ++ ++ if (is_rounded) { ++ rval[0] = *buf; ++ rval[1] = 0xFF; ++ rpc_write_unaligned(nor, to, 2, rval, full); ++ } ++ ++ rpc_flush_cache(rpc); ++ ++ return res; ++} ++ ++static inline unsigned int rpc_rx_nbits(struct spi_nor *nor) ++{ ++ switch (nor->flash_read) { ++ case SPI_NOR_DUAL: ++ return 2; ++ case SPI_NOR_QUAD: ++ return 4; ++ default: ++ return 0; ++ } ++} ++ ++ ++#if 0 ++//manual read ++static ssize_t rpc_read_flash(struct spi_nor *nor, loff_t from, size_t len, ++ u_char *buf) ++{ ++ ssize_t ret = len; ++ struct rpc_spi *rpc = nor->priv; ++ int adr_width = nor->addr_width; ++ int opcode_nbits = 1;//SPI_NBITS_SINGLE; ++ int addr_nbits = spi_nor_get_read_addr_nbits(nor->read_opcode); ++ int data_nbits = rpc_rx_nbits(nor); ++ int dummy = nor->read_dummy - 1; ++ u32 val, val2; ++ u32 *buf32; ++ int sz = 4; ++ int i, j; ++ loff_t adr = from; ++ ++ rpc_wait(rpc, DEFAULT_TO); ++ if (rpc->mtdtype == MTD_QSPI_2x) ++ sz <<= 1; ++ ++ /* ...setup manual mode */ ++ val = rpc_read(rpc, CMNCR); ++ val |= CMNCR_MD; ++ rpc_write(rpc, CMNCR, val); ++ ++ /*...setup dummy */ ++ val = rpc_read(rpc, SMDMCR); ++ val &= ~(SMDMCR_DMCYC_MASK); ++ val |= SMDMCR_DMCYC(dummy); ++ rpc_write(rpc, SMDMCR, val); ++ ++ /* disable ddr */ ++ val = rpc_read(rpc, SMDRENR); ++ val &= ~(SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); ++ rpc_write(rpc, SMDRENR, val); ++ ++ /* enable 1bit command */ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_DME ++ | SMENR_OCDE | SMENR_SPIDB_MASK ++ | SMENR_ADE_MASK | SMENR_ADB_MASK ++ | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); ++ val |= SMENR_CDB_1B | SMENR_ADB_4B | SMENR_SPIDB_4B ++ | SMENR_CDE | SMENR_ADE_31_0 | SMENR_DME | SMENR_SPIDE_32B; ++ rpc_write(rpc, SMENR, val); ++ ++ /* ...setup command */ ++ val = rpc_read(rpc, SMCMR); ++ val &= ~(SMCMR_CMD_MASK); ++ val |= SMCMR_CMD(nor->read_opcode); ++ rpc_write(rpc, SMCMR, val); ++ ++ buf32 = (u32 *)buf; ++ ++ while (len > 0) { ++ adr = from + ret - len; ++ ++ if (rpc->mtdtype == MTD_QSPI_2x) ++ adr >>= 1; ++ ++ rpc_write(rpc, SMADR, adr); ++ ++ rpc_begin(rpc, true, false, len <= sz); ++ if (rpc_wait(rpc, DEFAULT_TO)) ++ return -ETIMEDOUT; ++ ++ rpc_read_manual_data(rpc, &val, &val2); ++ ++ j = 0; ++ do { ++ if (len > 4) { ++ *buf32 = val; ++ buf32++; ++ len -= 4; ++ } else { ++ buf = (u8 *)buf32; ++ for (i = 0; i < len; i++) { ++ *buf = (val >> (8 * i)) & 0x000000ff; ++ buf++; ++ } ++ len = 0; ++ } ++ val = val2; ++ j++; ++ } while (j < 2 && rpc->mtdtype == MTD_QSPI_2x); ++ } ++ ++ return ret; ++} ++#else ++#define READ_ADR_MASK (BIT(26) - 1) ++static ssize_t rpc_read_flash(struct spi_nor *nor, loff_t from, size_t len, ++ u_char *buf) ++{ ++ u32 val; ++ struct rpc_spi *rpc = nor->priv; ++ int adr_width = nor->addr_width; ++ int opcode_nbits = 1; ++ int addr_nbits = spi_nor_get_read_addr_nbits(nor->read_opcode); ++ int data_nbits = rpc_rx_nbits(nor); ++ int dummy = nor->read_dummy - 1; ++ ssize_t ret = len; ++ ssize_t readlen; ++ loff_t _from; ++ ++ rpc_setup_ext_mode(rpc); ++ /* ...setup n bits */ ++ rpc_setup_extmode_nbits(rpc, opcode_nbits, addr_nbits, data_nbits); ++ ++ /* TODO: setup DDR */ ++ ++ /* ...setup command */ ++ val = rpc_read(rpc, DRCMR); ++ val &= ~(DRCMR_CMD_MASK); ++ val |= DRCMR_CMD(nor->read_opcode); ++ rpc_write(rpc, DRCMR, val); ++ ++ /* ...setup dummy cycles */ ++ val = rpc_read(rpc, DRDMCR); ++ val &= ~(DRDMCR_DMCYC_MASK); ++ val |= DRDMCR_DMCYC(dummy); ++ rpc_write(rpc, DRDMCR, val); ++ ++ /* ...setup read sequence */ ++ val = rpc_read(rpc, DRENR); ++ val |= DRENR_DME | DRENR_CDE; ++ rpc_write(rpc, DRENR, val); ++ ++ while (len > 0) { ++ /* ...setup address */ ++ rpc_setup_extmode_read_addr(rpc, adr_width, from); ++ /* ...use adr [25...0] */ ++ _from = from & READ_ADR_MASK; ++ ++ readlen = READ_ADR_MASK - _from + 1; ++ readlen = readlen > len ? len : readlen; ++ ++ memcpy_fromio(buf, rpc->read_area + _from, readlen); ++ buf += readlen; ++ from += readlen; ++ len -= readlen; ++ } ++ ++ return ret; ++} ++#endif ++ ++static int __rpc_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) ++{ ++ u32 val, val2; ++ u32 *buf32; ++ int i; ++ u32 mask = 0, type; ++ struct rpc_spi *rpc = nor->priv; ++ ++ type = rpc->mtdtype; ++ ++ rpc_setup_reg_mode(rpc); ++ val = rpc_read(rpc, SMCMR); ++ val &= ~(SMCMR_CMD_MASK); ++ val |= SMCMR_CMD(opcode); ++ rpc_write(rpc, SMCMR, val); ++ ++ rpc_begin(rpc, true, false, len <= 4); ++ if (rpc_wait(rpc, DEFAULT_TO)) ++ return -ETIMEDOUT; ++ ++ /* ...disable command */ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_CDE); ++ rpc_write(rpc, SMENR, val); ++ ++ buf32 = (u32 *)buf; ++ ++ while (len > 0) { ++ rpc_read_manual_data(rpc, &val, &val2); ++ ++ if (mask) { ++ dev_warn(&rpc->pdev->dev, ++ "Using mask workaround (0x%x)\n", mask); ++ val &= ~(mask); ++ val2 &= ~(mask); ++ } ++ ++ /* ... spi flashes should be the same */ ++ if (type == MTD_QSPI_2x && val != val2) { ++ /* clear cs */ ++ rpc_begin(rpc, true, false, true); ++ return -EAGAIN; ++ } ++ ++ if (len > 4) { ++ *buf32 = val; ++ buf32++; ++ len -= 4; ++ } else { ++ buf = (u8 *)buf32; ++ for (i = 0; i < len; i++) { ++ *buf = (val >> (8 * i)) & 0x000000ff; ++ buf++; ++ } ++ len = 0; ++ } ++ ++ if (!len) ++ break; ++ ++ mask = 0xff; ++ ++ rpc_begin(rpc, true, false, len <= 4); ++ if (rpc_wait(rpc, DEFAULT_TO)) ++ return -ETIMEDOUT; ++ ++ } ++ ++ return 0; ++} ++ ++ ++static int rpc_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) ++{ ++ int i, ret; ++ ++ /* A few read commands like read status can ++ * generate different answers. We repeat reading ++ * in that case ++ */ ++ for (i = 0; i < REPEAT_MAX; i++) { ++ ret = __rpc_read_reg(nor, opcode, buf, len); ++ if (!ret || ret != -EAGAIN) ++ break; ++ mdelay(REPEAT_TIME); ++ } ++ ++ return ret; ++} ++ ++ ++ ++static int rpc_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) ++{ ++ struct rpc_spi *rpc = nor->priv; ++ u32 val; ++ int dsize; ++ bool copy = true; ++ ++ rpc_setup_reg_mode(rpc); ++ ++ val = rpc_read(rpc, SMCMR); ++ val &= ~(SMCMR_CMD_MASK); ++ val |= SMCMR_CMD(opcode); ++ rpc_write(rpc, SMCMR, val); ++ ++ dsize = rpc_datalen2trancfersize(rpc, len, copy); ++ ++ if (rpc_setup_data_size(rpc, dsize, copy)) ++ return -EINVAL; ++ ++ if (rpc_write_data2reg(rpc, buf, dsize, copy)) ++ return -EINVAL; ++ buf += dsize; ++ len -= dsize; ++ rpc_begin(rpc, false, dsize > 0, len == 0); ++ ++ if (rpc_wait(rpc, DEFAULT_TO)) ++ return -ETIMEDOUT; ++ ++ /* ...disable command */ ++ val = rpc_read(rpc, SMENR); ++ val &= ~(SMENR_CDE); ++ rpc_write(rpc, SMENR, val); ++ ++ while (len > 0) { ++ dsize = rpc_datalen2trancfersize(rpc, len, copy); ++ if (rpc_setup_data_size(rpc, dsize, copy)) ++ return -EINVAL; ++ rpc_write_data2reg(rpc, buf, dsize, copy); ++ buf += dsize; ++ len -= dsize; ++ ++ rpc_begin(rpc, false, dsize, len == 0); ++ ++ if (rpc_wait(rpc, DEFAULT_TO)) ++ return -ETIMEDOUT; ++ ++ } ++ ++ return 0; ++} ++ ++ ++ ++/* hw init for spi-nor flashes */ ++static int rpc_hw_init_1x2x(struct rpc_spi *rpc) ++{ ++ u32 val; ++ ++ /* Exec calibration */ ++ val = rpc_read(rpc, PHYCNT); ++ val &= ~(PHYCNT_OCTA_MASK | PHYCNT_EXDS | PHYCNT_OCT ++ | PHYCNT_DDRCAL | PHYCNT_HS | PHYCNT_STREAM_MASK ++ | PHYCNT_WBUF2 | PHYCNT_WBUF | PHYCNT_PHYMEM_MASK); ++ val |= (PHYCNT_CAL) | PHYCNT_STREAM(6); ++ rpc_write(rpc, PHYCNT, val); ++ ++ /* disable rpc_* pins */ ++ val = rpc_read(rpc, PHYINT); ++ val &= ~((1<<24) | (7<<16)); ++ rpc_write(rpc, PHYINT, val); ++ ++ val = rpc_read(rpc, SMDRENR); ++ val &= ~(SMDRENR_HYPE_MASK); ++ val |= SMDRENR_HYPE_SPI_FLASH; ++ rpc_write(rpc, SMDRENR, val); ++ ++ val = rpc_read(rpc, CMNCR); ++ val &= ~(CMNCR_BSZ_MASK); ++ if (rpc->mtdtype != MTD_QSPI_1x) ++ val |= CMNCR_BSZ_4x2; ++ rpc_write(rpc, CMNCR, val); ++ ++ val = rpc_read(rpc, PHYOFFSET1); ++ val |= PHYOFFSET1_DDRTMG; ++ rpc_write(rpc, PHYOFFSET1, val); ++ ++ val = SSLDR_SPNDL(0) | SSLDR_SLNDL(4) | SSLDR_SCKDL(0); ++ rpc_write(rpc, SSLDR, val); ++ ++ return 0; ++} ++ ++ ++static int rpc_hw_init(struct rpc_spi *rpc) ++{ ++ switch (rpc->mtdtype) { ++ case MTD_QSPI_1x: ++ case MTD_QSPI_2x: ++ return rpc_hw_init_1x2x(rpc); ++ ++ default: ++ dev_err(&rpc->pdev->dev, "Unsupported connection mode\n"); ++ return -ENODEV; ++ } ++} ++ ++ ++static int rpc_erase_sector(struct spi_nor *nor, loff_t addr) ++{ ++ struct rpc_spi *rpc = nor->priv; ++ u8 buf[6]; ++ int i; ++ ++ if (rpc->mtdtype == MTD_QSPI_2x) ++ addr >>= 1; ++ ++ for (i = nor->addr_width - 1; i >= 0; i--) { ++ buf[i] = addr & 0xff; ++ addr >>= 8; ++ } ++ ++ return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width); ++} ++ ++ ++ ++ ++static const struct of_device_id rpc_of_match[] = { ++ { .compatible = "renesas,qspi-rpc-r8a7798" }, ++ { .compatible = "renesas,qspi-rpc-r8a7797", .data = (void *)OWN_CLOCK_DIVIDER }, ++ { }, ++}; ++ ++MODULE_DEVICE_TABLE(of, rpc_of_match); ++ ++ ++ ++static int rpc_spi_probe(struct platform_device *pdev) ++{ ++ struct device_node *flash_np; ++ struct spi_nor *nor; ++ struct rpc_spi *rpc; ++ struct resource *res; ++ enum read_mode mode = SPI_NOR_NORMAL; ++ u32 max_clk_rate = 50000000; ++ u32 property; ++ int ret; ++ int own_clk; ++ ++ ++ flash_np = of_get_next_available_child(pdev->dev.of_node, NULL); ++ if (!flash_np) { ++ dev_err(&pdev->dev, "no SPI flash device to configure\n"); ++ return -ENODEV; ++ } ++ ++ if (!of_property_read_u32(flash_np, "spi-rx-bus-width", &property)) { ++ switch (property) { ++ case 1: ++ break; ++ case 2: ++ mode = SPI_NOR_DUAL; ++ break; ++ case 4: ++ mode = SPI_NOR_QUAD; ++ break; ++ default: ++ dev_err(&pdev->dev, "unsupported rx-bus-width\n"); ++ return -EINVAL; ++ } ++ } ++ ++ of_property_read_u32(flash_np, "spi-max-frequency", &max_clk_rate); ++ own_clk = of_device_get_match_data(&pdev->dev); ++ ++ rpc = devm_kzalloc(&pdev->dev, sizeof(*rpc), GFP_KERNEL); ++ if (!rpc) ++ return -ENOMEM; ++ ++ rpc->pdev = pdev; ++ ++ /* ... setup nor hooks */ ++ nor = &rpc->spi_nor; ++ nor->dev = &pdev->dev; ++ spi_nor_set_flash_node(nor, flash_np); ++ nor->read = rpc_read_flash; ++ nor->write = rpc_write_flash; ++ nor->read_reg = rpc_read_reg; ++ nor->write_reg = rpc_write_reg; ++ nor->priv = rpc; ++ rpc->mtdtype = MTD_QSPI_1x; ++ if (of_find_property(pdev->dev.of_node, "dual", NULL)) { ++ rpc->mtdtype = MTD_QSPI_2x; ++ spi_nor_set_array_size(nor, 2); ++ } ++ if (rpc->mtdtype == MTD_QSPI_2x) ++ nor->erase = rpc_erase_sector; ++ ++ /* ...get memory */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ rpc->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(rpc->base)) { ++ dev_err(&pdev->dev, "cannot get resources\n"); ++ ret = PTR_ERR(rpc->base); ++ goto error; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ ++ rpc->read_area = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(rpc->base)) { ++ dev_err(&pdev->dev, "cannot get resources\n"); ++ ret = PTR_ERR(rpc->base); ++ goto error; ++ } ++ ++ /* ...get memory */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ rpc->write_area = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(rpc->base)) { ++ dev_err(&pdev->dev, "cannot get resources\n"); ++ ret = PTR_ERR(rpc->base); ++ goto error; ++ } ++ ++ /* ...get clk */ ++ rpc->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(rpc->clk)) { ++ dev_err(&pdev->dev, "cannot get clock\n"); ++ ret = PTR_ERR(rpc->clk); ++ goto error; ++ } ++ ++ /* ...set max clk rate */ ++ if (!own_clk) { ++ ret = clk_set_rate(rpc->clk, max_clk_rate); ++ if (ret) { ++ dev_err(&pdev->dev, "cannot set clock rate\n"); ++ goto error; ++ } ++ } ++ ++ /* ... enable clk */ ++ ret = clk_prepare_enable(rpc->clk); ++ if (ret) { ++ dev_err(&pdev->dev, "cannot prepare clock\n"); ++ goto error; ++ } ++ ++ /* ...init device */ ++ ret = rpc_hw_init(rpc); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "rpc_hw_init error.\n"); ++ goto error_clk_disable; ++ } ++ ++ /* ...set clk ratio */ ++ if (own_clk) { ++ ret = rpc_setup_clk_ratio(rpc, max_clk_rate); ++ if (ret) { ++ dev_err(&pdev->dev, "cannot set clock ratio\n"); ++ goto error; ++ } ++ } ++ ++ platform_set_drvdata(pdev, rpc); ++ ++ ret = spi_nor_scan(nor, NULL, mode); ++ if (ret) { ++ dev_err(&pdev->dev, "spi_nor_scan error.\n"); ++ goto error_clk_disable; ++ } ++ ++ ret = mtd_device_register(&nor->mtd, NULL, 0); ++ if (ret) { ++ dev_err(&pdev->dev, "mtd_device_register error.\n"); ++ goto error_clk_disable; ++ } ++ ++ dev_info(&pdev->dev, "probed as %s\n", ++ rpc->mtdtype == MTD_QSPI_1x ? "single" : "dual"); ++ ++ return 0; ++ ++ ++error_clk_disable: ++ clk_disable_unprepare(rpc->clk); ++error: ++ return ret; ++} ++ ++ ++ ++ ++static int rpc_spi_remove(struct platform_device *pdev) ++{ ++ struct rpc_spi *rpc = platform_get_drvdata(pdev); ++ ++ /* HW shutdown */ ++ clk_disable_unprepare(rpc->clk); ++ mtd_device_unregister(&rpc->spi_nor.mtd); ++ return 0; ++} ++ ++ ++ ++ ++ ++/* platform driver interface */ ++static struct platform_driver rpc_platform_driver = { ++ .probe = rpc_spi_probe, ++ .remove = rpc_spi_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "rpc", ++ .of_match_table = of_match_ptr(rpc_of_match), ++ }, ++}; ++ ++module_platform_driver(rpc_platform_driver); ++ ++ ++MODULE_ALIAS("rpc"); ++MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>"); ++MODULE_DESCRIPTION("Renesas RPC Driver"); ++MODULE_LICENSE("GPL"); +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0114-R8A7798-dtsi-Add-RPC-node-to-dtsi.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0114-R8A7798-dtsi-Add-RPC-node-to-dtsi.patch new file mode 100644 index 0000000..7169baa --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0114-R8A7798-dtsi-Add-RPC-node-to-dtsi.patch @@ -0,0 +1,35 @@ +From 80ebc1949eb5d7db33c60faa8537029fcf6379ba Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 11:14:26 +0300 +Subject: [PATCH 05/12] R8A7798: dtsi: Add RPC node to dtsi + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + arch/arm64/boot/dts/renesas/r8a7798.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +index e2b3404..fac60e6 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7798.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +@@ -1026,6 +1026,17 @@ + status = "disabled"; + }; + ++ qspi0: qspi@ee200000 { ++ compatible = "renesas,qspi-rpc-r8a7798"; ++ reg = <0 0xee200000 0 0x1f0>, ++ <0 0x08000000 0 0x04000000>, ++ <0 0xee208000 0 0x100>; ++ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 917>; ++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ + msiof0: spi@e6e90000 { + #address-cells = <1>; + #size-cells = <0>; +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0115-R8A7798-condor-dts-Add-qspi-flash.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0115-R8A7798-condor-dts-Add-qspi-flash.patch new file mode 100644 index 0000000..213421c --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0115-R8A7798-condor-dts-Add-qspi-flash.patch @@ -0,0 +1,98 @@ +From 45ac82977a015e6ec80a1fb119b26c5b5841b760 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 11:19:54 +0300 +Subject: [PATCH 06/12] R8A7798-condor: dts: Add qspi flash + +Add s25fs512 flash support + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + arch/arm64/boot/dts/renesas/r8a7798-condor.dts | 72 ++++++++++++++++++++++++++ + 1 file changed, 72 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7798-condor.dts b/arch/arm64/boot/dts/renesas/r8a7798-condor.dts +index cdd9844..81f984f1 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7798-condor.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7798-condor.dts +@@ -240,6 +240,78 @@ + groups = "tpu_to0"; + function = "tpu"; + }; ++ ++ qspi0_pins: qspi0 { ++ groups = "qspi0_ctrl", "qspi0_data4"; ++ function = "qspi0"; ++ }; ++ ++ qspi1_pins: qspi1 { ++ groups = "qspi1_ctrl", "qspi1_data4"; ++ function = "qspi1"; ++ }; ++}; ++ ++&qspi0 { ++ pinctrl-0 = <&qspi0_pins &qspi1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "spansion,s25fs512s", "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <50000000>; ++ spi-rx-bus-width = <4>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootparam@0 { ++ reg = <0x00000000 0x040000>; ++ read-only; ++ }; ++ cr7@00040000 { ++ reg = <0x00040000 0x080000>; ++ read-only; ++ }; ++ cert_header_sa3@000C0000 { ++ reg = <0x000C0000 0x080000>; ++ read-only; ++ }; ++ bl2@00140000 { ++ reg = <0x00140000 0x040000>; ++ read-only; ++ }; ++ cert_header_sa6@00180000 { ++ reg = <0x00180000 0x040000>; ++ read-only; ++ }; ++ bl31@001C0000 { ++ reg = <0x001C0000 0x460000>; ++ read-only; ++ }; ++ uboot@00640000 { ++ reg = <0x00640000 0x0C0000>; ++ read-only; ++ }; ++ uboot-env@00700000 { ++ reg = <0x00700000 0x040000>; ++ read-only; ++ }; ++ dtb@00740000 { ++ reg = <0x00740000 0x080000>; ++ }; ++ kernel@007C0000 { ++ reg = <0x007C0000 0x1400000>; ++ }; ++ user@01BC0000 { ++ reg = <0x01BC0000 0x2440000>; ++ }; ++ }; ++ }; + }; + + &scif0 { +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0116-spi-nor-Add-s25fs512-flash-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0116-spi-nor-Add-s25fs512-flash-support.patch new file mode 100644 index 0000000..7a3500b --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0116-spi-nor-Add-s25fs512-flash-support.patch @@ -0,0 +1,126 @@ +From 1b2a145d72c4202fc41b2af138b862a8be94b0f0 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 11:29:21 +0300 +Subject: [PATCH 07/12] spi-nor: Add s25fs512 flash support + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/mtd/spi-nor/spi-nor.c | 31 ++++++++++++++++++++++++++++--- + include/linux/mtd/spi-nor.h | 15 +++++++++++++++ + 2 files changed, 43 insertions(+), 3 deletions(-) + +diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c +index d0fc165..1855bbe 100644 +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -75,6 +75,7 @@ struct flash_info { + * bit. Must be used with + * SPI_NOR_HAS_LOCK. + */ ++#define SPANSION_S512FS_QUIRK BIT(10) + }; + + #define JEDEC_MFR(info) ((info)->id[0]) +@@ -222,8 +223,18 @@ static inline int spi_nor_sr_ready(struct spi_nor *nor) + int sr = read_sr(nor); + if (sr < 0) + return sr; +- else +- return !(sr & SR_WIP); ++ ++ if (nor->flags & SNOR_F_USE_CLSR && sr & (SR_E_ERR | SR_P_ERR)) { ++ if (sr & SR_E_ERR) ++ dev_err(nor->dev, "Erase Error occurred\n"); ++ else ++ dev_err(nor->dev, "Programming Error occurred\n"); ++ ++ nor->write_reg(nor, SPINOR_OP_CLSR, NULL, 0); ++ return -EIO; ++ } ++ ++ return !(sr & SR_WIP); + } + + static inline int spi_nor_fsr_ready(struct spi_nor *nor) +@@ -901,7 +912,21 @@ static const struct flash_info spi_nor_ids[] = { + { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, + { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ ++ { ++ "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPANSION_S512FS_QUIRK) ++ }, ++ { ++ "s25fs128s0", INFO6(0x012018, 0x4d0381, 256 * 1024, 64, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPANSION_S512FS_QUIRK) ++ }, ++ { ++ "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPANSION_S512FS_QUIRK) ++ }, ++ + { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, + { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, + { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, +diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h +index c425c7b..99f7b2a 100644 +--- a/include/linux/mtd/spi-nor.h ++++ b/include/linux/mtd/spi-nor.h +@@ -60,8 +60,10 @@ + #define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */ + #define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */ + #define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */ ++#define SPINOR_OP_READ4_1_4_4 0xec /* Read data bytes (Quad I/O SPI) */ + #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ + #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ ++#define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */ + + /* Used for SST flashes only. */ + #define SPINOR_OP_BP 0x02 /* Byte program */ +@@ -74,6 +76,7 @@ + + /* Used for Spansion flashes only. */ + #define SPINOR_OP_BRWR 0x17 /* Bank register write */ ++#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ + + /* Used for Micron flashes only. */ + #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ +@@ -88,6 +91,9 @@ + #define SR_BP2 BIT(4) /* Block protect 2 */ + #define SR_TB BIT(5) /* Top/Bottom protect */ + #define SR_SRWD BIT(7) /* SR write protect */ ++/* Spansion/Cypress specific status bits */ ++#define SR_E_ERR BIT(5) ++#define SR_P_ERR BIT(6) + + #define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ + +@@ -119,6 +125,7 @@ enum spi_nor_ops { + enum spi_nor_option_flags { + SNOR_F_USE_FSR = BIT(0), + SNOR_F_HAS_SR_TB = BIT(1), ++ SNOR_F_USE_CLSR = BIT(5), + }; + + /** +@@ -197,6 +204,14 @@ static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) + return mtd_get_of_node(&nor->mtd); + } + ++static inline int spi_nor_get_read_addr_nbits(u8 opcode) ++{ ++ if (opcode == SPINOR_OP_READ4_1_4_4) ++ return 4; ++ return 1; ++} ++ ++ + /** + * spi_nor_scan() - scan the SPI NOR + * @nor: the spi_nor structure +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0117-spi-nor-Add-flash-array-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0117-spi-nor-Add-flash-array-support.patch new file mode 100644 index 0000000..5003ae6 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0117-spi-nor-Add-flash-array-support.patch @@ -0,0 +1,89 @@ +From 0d10eb085d28a442b147e63383d1836cb3e62ae4 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Mon, 19 Mar 2018 11:32:58 +0300 +Subject: [PATCH 08/12] spi-nor: Add flash array support + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/mtd/spi-nor/spi-nor.c | 20 ++++++++++++++++++-- + include/linux/mtd/spi-nor.h | 12 ++++++++++++ + 2 files changed, 30 insertions(+), 2 deletions(-) + +diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c +index 1855bbe..3ced558 100644 +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -1338,6 +1338,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) + if (ret) + return ret; + ++ if (!nor->array_size) ++ nor->array_size = 1; ++ + if (name) + info = spi_nor_match_id(name); + /* Try to auto-detect if chip name wasn't specified or not found */ +@@ -1500,7 +1503,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) + /* Dedicated 4-byte command set */ + switch (nor->flash_read) { + case SPI_NOR_QUAD: +- nor->read_opcode = SPINOR_OP_READ4_1_1_4; ++ if (info->flags & SPANSION_S512FS_QUIRK) ++ nor->read_opcode = SPINOR_OP_READ4_1_4_4; ++ else ++ nor->read_opcode = SPINOR_OP_READ4_1_1_4; + break; + case SPI_NOR_DUAL: + nor->read_opcode = SPINOR_OP_READ4_1_1_2; +@@ -1528,7 +1534,17 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) + return -EINVAL; + } + +- nor->read_dummy = spi_nor_read_dummy_cycles(nor); ++ if (info->flags & SPANSION_S512FS_QUIRK) { ++ nor->read_dummy = 10; ++ nor->flags |= SNOR_F_USE_CLSR; ++ } else ++ nor->read_dummy = spi_nor_read_dummy_cycles(nor); ++ ++ /* recount parameters using array size */ ++ mtd->erasesize *= nor->array_size; ++ mtd->size *= nor->array_size; ++ nor->page_size *= nor->array_size; ++ mtd->writebufsize *= nor->array_size; + + dev_info(dev, "%s (%lld Kbytes)\n", info->name, + (long long)mtd->size >> 10); +diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h +index 99f7b2a..7216b09 100644 +--- a/include/linux/mtd/spi-nor.h ++++ b/include/linux/mtd/spi-nor.h +@@ -174,6 +174,7 @@ struct spi_nor { + bool sst_write_second; + u32 flags; + u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; ++ u8 array_size; + + int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); + void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops); +@@ -204,6 +205,17 @@ static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) + return mtd_get_of_node(&nor->mtd); + } + ++static inline void spi_nor_set_array_size(struct spi_nor *nor, ++ u8 size) ++{ ++ nor->array_size = size; ++} ++ ++static inline u8 spi_nor_get_array_size(struct spi_nor *nor) ++{ ++ return nor->array_size; ++} ++ + static inline int spi_nor_get_read_addr_nbits(u8 opcode) + { + if (opcode == SPINOR_OP_READ4_1_4_4) +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0118-r8a7797-clk-Add-rpc-clock.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0118-r8a7797-clk-Add-rpc-clock.patch new file mode 100644 index 0000000..7910790 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0118-r8a7797-clk-Add-rpc-clock.patch @@ -0,0 +1,45 @@ +From 730f3d906fa599bf76bb0b1fdf35b44a7cbdc2ed Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Thu, 22 Mar 2018 14:57:46 +0300 +Subject: [PATCH 09/12] r8a7797: clk: Add rpc clock + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/clk/renesas/r8a7797-cpg-mssr.c | 2 ++ + include/dt-bindings/clock/r8a7797-cpg-mssr.h | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/drivers/clk/renesas/r8a7797-cpg-mssr.c b/drivers/clk/renesas/r8a7797-cpg-mssr.c +index a3eed41..9763f6c 100644 +--- a/drivers/clk/renesas/r8a7797-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a7797-cpg-mssr.c +@@ -74,6 +74,7 @@ static const struct cpg_core_clk r8a7797_core_clks[] __initconst = { + DEF_FIXED("s2d1", R8A7797_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A7797_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A7797_CLK_S2D4, CLK_S2, 4, 1), ++ DEF_FIXED("rpcsrc", R8A7797_CLK_RPCSRC, CLK_PLL1_DIV2, 5, 1), + + DEF_GEN3_SD0H("sd0h", R8A7797_CLK_SD0H, CLK_PLL1_DIV4, 0x0074), + DEF_GEN3_SD0("sd0", R8A7797_CLK_SD0, CLK_PLL1_DIV4, 0x0074), +@@ -158,6 +159,7 @@ static const struct mssr_mod_clk r8a7797_mod_clks[] __initconst = { + DEF_MOD("i2c2", 929, R8A7797_CLK_S2D2), + DEF_MOD("i2c1", 930, R8A7797_CLK_S2D2), + DEF_MOD("i2c0", 931, R8A7797_CLK_S2D2), ++ DEF_MOD("rpc", 917, R8A7797_CLK_RPCSRC), + }; + + static const unsigned int r8a7797_crit_mod_clks[] __initconst = { +diff --git a/include/dt-bindings/clock/r8a7797-cpg-mssr.h b/include/dt-bindings/clock/r8a7797-cpg-mssr.h +index ae6b3af..c3bd0a7 100644 +--- a/include/dt-bindings/clock/r8a7797-cpg-mssr.h ++++ b/include/dt-bindings/clock/r8a7797-cpg-mssr.h +@@ -44,5 +44,6 @@ + #define R8A7797_CLK_CPEX 29 + #define R8A7797_CLK_R 30 + #define R8A7797_CLK_OSC 31 ++#define R8A7797_CLK_RPCSRC 32 + + #endif /* __DT_BINDINGS_CLOCK_R8A7797_CPG_MSSR_H__ */ +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0119-r8a7797-pinctrl-Add-qspi-pins.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0119-r8a7797-pinctrl-Add-qspi-pins.patch new file mode 100644 index 0000000..a0b4330 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0119-r8a7797-pinctrl-Add-qspi-pins.patch @@ -0,0 +1,118 @@ +From 441ae85fe3fec270ea1284a669cdd348a8432d85 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Thu, 22 Mar 2018 15:00:02 +0300 +Subject: [PATCH 10/12] r8a7797: pinctrl: Add qspi pins + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7797.c | 73 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7797.c b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c +index 6b83f44..4f451c4 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7797.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c +@@ -1143,6 +1143,59 @@ static const unsigned int scif_clk_b_mux[] = { + SCIF_CLK_B_MARK, + }; + ++/* - QSPI ------------------------------------------------------------------- */ ++static const unsigned int qspi0_ctrl_pins[] = { ++ /* QSPI0_SPCLK QSPI0_SSL */ ++ RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 0), ++}; ++static const unsigned int qspi0_ctrl_mux[] = { ++ QSPI0_SPCLK_MARK, QSPI0_SSL_MARK, ++}; ++ ++static const unsigned int qspi0_data2_pins[] = { ++ /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1 */ ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2), ++}; ++static const unsigned int qspi0_data2_mux[] = { ++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, ++}; ++ ++static const unsigned int qspi0_data4_pins[] = { ++ /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1, QSPI0_IO2, QSPI0_IO3 */ ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2), ++ RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 4), ++}; ++static const unsigned int qspi0_data4_mux[] = { ++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, ++ QSPI0_IO2_MARK, QSPI0_IO3_MARK ++}; ++ ++static const unsigned int qspi1_ctrl_pins[] = { ++ /* QSPI1_SPCLK QSPI1_SSL */ ++ RCAR_GP_PIN(5, 6), RCAR_GP_PIN(5, 11), ++}; ++static const unsigned int qspi1_ctrl_mux[] = { ++ QSPI1_SPCLK_MARK, QSPI1_SSL_MARK, ++}; ++ ++static const unsigned int qspi1_data2_pins[] = { ++ /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1 */ ++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8), ++}; ++static const unsigned int qspi1_data2_mux[] = { ++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, ++}; ++ ++static const unsigned int qspi1_data4_pins[] = { ++ /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1, QSPI1_IO2, QSPI1_IO3 */ ++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8), ++ RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10), ++}; ++static const unsigned int qspi1_data4_mux[] = { ++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, ++ QSPI1_IO2_MARK, QSPI1_IO3_MARK ++}; ++ + /* - I2C -------------------------------------------------------------------- */ + static const unsigned int i2c0_pins[] = { + /* SDA0, SCL0 */ +@@ -1971,6 +2024,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(vin1_field), + SH_PFC_PIN_GROUP(vin1_clkenb), + SH_PFC_PIN_GROUP(vin1_clk), ++ SH_PFC_PIN_GROUP(qspi0_ctrl), ++ SH_PFC_PIN_GROUP(qspi0_data2), ++ SH_PFC_PIN_GROUP(qspi0_data4), ++ SH_PFC_PIN_GROUP(qspi1_ctrl), ++ SH_PFC_PIN_GROUP(qspi1_data2), ++ SH_PFC_PIN_GROUP(qspi1_data4), + }; + + static const char * const avb0_groups[] = { +@@ -2201,6 +2260,18 @@ static const char * const vin1_groups[] = { + "vin1_clk", + }; + ++static const char * const qspi0_groups[] = { ++ "qspi0_ctrl", ++ "qspi0_data2", ++ "qspi0_data4", ++}; ++ ++static const char * const qspi1_groups[] = { ++ "qspi1_ctrl", ++ "qspi1_data2", ++ "qspi1_data4", ++}; ++ + #define POCCTRL0 0x380 + #define POCCTRL1 0x384 + #define PIN2POCCTRL0_SHIFT(a) ({ \ +@@ -2244,6 +2315,8 @@ static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(tmu), + SH_PFC_FUNCTION(vin0), + SH_PFC_FUNCTION(vin1), ++ SH_PFC_FUNCTION(qspi0), ++ SH_PFC_FUNCTION(qspi1), + }; + + static const struct pinmux_cfg_reg pinmux_config_regs[] = { +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0120-r8a7797-dtsi-Add-rpc-node.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0120-r8a7797-dtsi-Add-rpc-node.patch new file mode 100644 index 0000000..8d782ca --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0120-r8a7797-dtsi-Add-rpc-node.patch @@ -0,0 +1,35 @@ +From 847b14e65374563ec3ee1d06eec05b4004233e7d Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Thu, 22 Mar 2018 15:27:49 +0300 +Subject: [PATCH 11/12] r8a7797: dtsi: Add rpc node + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + arch/arm64/boot/dts/renesas/r8a7797.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi +index a5552d6..2beca53 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7797.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi +@@ -889,6 +889,17 @@ + status = "disabled"; + }; + ++ qspi0: qspi@ee200000 { ++ compatible = "renesas,qspi-rpc-r8a7797"; ++ reg = <0 0xee200000 0 0x1f0>, ++ <0 0x08000000 0 0x04000000>, ++ <0 0xee208000 0 0x100>; ++ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 917>; ++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; ++ status = "disabled"; ++ }; ++ + msiof0: spi@e6e90000 { + #address-cells = <1>; + #size-cells = <0>; +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-r8a7797-eagle-dts-Add-spi-flash-node.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-r8a7797-eagle-dts-Add-spi-flash-node.patch new file mode 100644 index 0000000..8dabedc --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-r8a7797-eagle-dts-Add-spi-flash-node.patch @@ -0,0 +1,96 @@ +From 0e884fcce89a6b15bd3971392b5641b48d1ad9ab Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Thu, 22 Mar 2018 15:31:48 +0300 +Subject: [PATCH 12/12] r8a7797-eagle: dts: Add spi flash node + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + arch/arm64/boot/dts/renesas/r8a7797-eagle.dts | 72 +++++++++++++++++++++++++++ + 1 file changed, 72 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts +index ce7a88e..c8150d9 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts +@@ -203,6 +203,78 @@ + groups = "du_rgb666", "du_sync", "du_clk_out_0", "du_disp"; + function = "du"; + }; ++ ++ qspi0_pins: qspi0 { ++ groups = "qspi0_ctrl", "qspi0_data4"; ++ function = "qspi0"; ++ }; ++ ++ qspi1_pins: qspi1 { ++ groups = "qspi1_ctrl", "qspi1_data4"; ++ function = "qspi1"; ++ }; ++}; ++ ++&qspi0 { ++ pinctrl-0 = <&qspi0_pins &qspi1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "spansion,s25fs512s", "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <50000000>; ++ spi-rx-bus-width = <4>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootparam@0 { ++ reg = <0x00000000 0x040000>; ++ read-only; ++ }; ++ cr7@00040000 { ++ reg = <0x00040000 0x080000>; ++ read-only; ++ }; ++ cert_header_sa3@000C0000 { ++ reg = <0x000C0000 0x080000>; ++ read-only; ++ }; ++ bl2@00140000 { ++ reg = <0x00140000 0x040000>; ++ read-only; ++ }; ++ cert_header_sa6@00180000 { ++ reg = <0x00180000 0x040000>; ++ read-only; ++ }; ++ bl31@001C0000 { ++ reg = <0x001C0000 0x460000>; ++ read-only; ++ }; ++ uboot@00640000 { ++ reg = <0x00640000 0x0C0000>; ++ read-only; ++ }; ++ uboot-env@00700000 { ++ reg = <0x00700000 0x040000>; ++ read-only; ++ }; ++ dtb@00740000 { ++ reg = <0x00740000 0x080000>; ++ }; ++ kernel@007C0000 { ++ reg = <0x007C0000 0x1400000>; ++ }; ++ user@01BC0000 { ++ reg = <0x01BC0000 0x2440000>; ++ }; ++ }; ++ }; + }; + + &scif0 { +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0122-r8a7797-v3msk-r8a7797-v3mzf-dts-Add-spi-flash-s25fs5.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0122-r8a7797-v3msk-r8a7797-v3mzf-dts-Add-spi-flash-s25fs5.patch new file mode 100644 index 0000000..07a55d5 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0122-r8a7797-v3msk-r8a7797-v3mzf-dts-Add-spi-flash-s25fs5.patch @@ -0,0 +1,172 @@ +From 22f31ca58e24e9c8b92361e0d1f57a59d1fdbf64 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Fri, 23 Mar 2018 16:32:07 +0300 +Subject: [PATCH] r8a7797-v3msk,r8a7797-v3mzf: dts: Add spi flash s25fs512 + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts | 68 +++++++++++++++++++++++++++ + arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts | 68 +++++++++++++++++++++++++++ + 2 files changed, 136 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts +index 33c6c0d..604475d 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts +@@ -213,6 +213,74 @@ + function = "mmc"; + power-source = <3300>; + }; ++ ++ qspi0_pins: qspi0 { ++ groups = "qspi0_ctrl", "qspi0_data4"; ++ function = "qspi0"; ++ }; ++ ++ qspi1_pins: qspi1 { ++ groups = "qspi1_ctrl", "qspi1_data4"; ++ function = "qspi1"; ++ }; ++}; ++ ++&qspi0 { ++ pinctrl-0 = <&qspi0_pins &qspi1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "spansion,s25fs512s", "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <50000000>; ++ spi-rx-bus-width = <4>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootparam@0 { ++ reg = <0x00000000 0x040000>; ++ read-only; ++ }; ++ cr7@00040000 { ++ reg = <0x00040000 0x080000>; ++ read-only; ++ }; ++ cert_header_sa3@000C0000 { ++ reg = <0x000C0000 0x080000>; ++ read-only; ++ }; ++ bl2@00140000 { ++ reg = <0x00140000 0x040000>; ++ read-only; ++ }; ++ cert_header_sa6@00180000 { ++ reg = <0x00180000 0x040000>; ++ read-only; ++ }; ++ bl31@001C0000 { ++ reg = <0x001C0000 0x460000>; ++ read-only; ++ }; ++ uboot@00640000 { ++ reg = <0x00640000 0x100000>; ++ read-only; ++ }; ++ dtb@00740000 { ++ reg = <0x00740000 0x080000>; ++ }; ++ kernel@007C0000 { ++ reg = <0x007C0000 0x1400000>; ++ }; ++ user@01BC0000 { ++ reg = <0x01BC0000 0x2440000>; ++ }; ++ }; ++ }; + }; + + &scif0 { +diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts +index 71d7bad..4a64881 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3mzf.dts +@@ -401,6 +401,74 @@ + function = "mmc"; + power-source = <3300>; + }; ++ ++ qspi0_pins: qspi0 { ++ groups = "qspi0_ctrl", "qspi0_data4"; ++ function = "qspi0"; ++ }; ++ ++ qspi1_pins: qspi1 { ++ groups = "qspi1_ctrl", "qspi1_data4"; ++ function = "qspi1"; ++ }; ++}; ++ ++&qspi0 { ++ pinctrl-0 = <&qspi0_pins &qspi1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "spansion,s25fs512s", "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <50000000>; ++ spi-rx-bus-width = <4>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootparam@0 { ++ reg = <0x00000000 0x040000>; ++ read-only; ++ }; ++ cr7@00040000 { ++ reg = <0x00040000 0x080000>; ++ read-only; ++ }; ++ cert_header_sa3@000C0000 { ++ reg = <0x000C0000 0x080000>; ++ read-only; ++ }; ++ bl2@00140000 { ++ reg = <0x00140000 0x040000>; ++ read-only; ++ }; ++ cert_header_sa6@00180000 { ++ reg = <0x00180000 0x040000>; ++ read-only; ++ }; ++ bl31@001C0000 { ++ reg = <0x001C0000 0x460000>; ++ read-only; ++ }; ++ uboot@00640000 { ++ reg = <0x00640000 0x100000>; ++ read-only; ++ }; ++ dtb@00740000 { ++ reg = <0x00740000 0x080000>; ++ }; ++ kernel@007C0000 { ++ reg = <0x007C0000 0x1400000>; ++ }; ++ user@01BC0000 { ++ reg = <0x01BC0000 0x2440000>; ++ }; ++ }; ++ }; + }; + + &scif0 { +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0123-V3HSK-dts-Add-qspi-node.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0123-V3HSK-dts-Add-qspi-node.patch new file mode 100644 index 0000000..4e39ed6 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0123-V3HSK-dts-Add-qspi-node.patch @@ -0,0 +1,101 @@ +From 2e5e9bce98281417fec62cb8af23c086c3d5b01a Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Thu, 5 Apr 2018 17:23:14 +0300 +Subject: [PATCH] V3HSK: dts: Add qspi node + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts | 73 +++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts +index bf8abe6..d863a95 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7798-v3hsk.dts +@@ -225,6 +225,17 @@ + groups = "tpu_to0"; + function = "tpu"; + }; ++ ++ ++ qspi0_pins: qspi0 { ++ groups = "qspi0_ctrl", "qspi0_data4"; ++ function = "qspi0"; ++ }; ++ ++ qspi1_pins: qspi1 { ++ groups = "qspi1_ctrl", "qspi1_data4"; ++ function = "qspi1"; ++ }; + }; + + &scif0 { +@@ -356,3 +367,65 @@ + max-speed = <1000>; + }; + }; ++ ++&qspi0 { ++ pinctrl-0 = <&qspi0_pins &qspi1_pins>; ++ pinctrl-names = "default"; ++ ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "spansion,s25fs512s", "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <50000000>; ++ spi-rx-bus-width = <4>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootparam@0 { ++ reg = <0x00000000 0x040000>; ++ read-only; ++ }; ++ cr7@00040000 { ++ reg = <0x00040000 0x080000>; ++ read-only; ++ }; ++ cert_header_sa3@000C0000 { ++ reg = <0x000C0000 0x080000>; ++ read-only; ++ }; ++ bl2@00140000 { ++ reg = <0x00140000 0x040000>; ++ read-only; ++ }; ++ cert_header_sa6@00180000 { ++ reg = <0x00180000 0x040000>; ++ read-only; ++ }; ++ bl31@001C0000 { ++ reg = <0x001C0000 0x460000>; ++ read-only; ++ }; ++ uboot@00640000 { ++ reg = <0x00640000 0x0C0000>; ++ read-only; ++ }; ++ uboot-env@00700000 { ++ reg = <0x00700000 0x040000>; ++ read-only; ++ }; ++ dtb@00740000 { ++ reg = <0x00740000 0x080000>; ++ }; ++ kernel@007C0000 { ++ reg = <0x007C0000 0x1400000>; ++ }; ++ user@01BC0000 { ++ reg = <0x01BC0000 0x2440000>; ++ }; ++ }; ++ }; ++}; +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0124-RPC-Hyperflash-Add-devicetree-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0124-RPC-Hyperflash-Add-devicetree-support.patch new file mode 100644 index 0000000..f347d47 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0124-RPC-Hyperflash-Add-devicetree-support.patch @@ -0,0 +1,219 @@ +From 466608ee2217ce02df6df977a35c4afa6ee1e350 Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Wed, 4 Apr 2018 12:29:47 +0300 +Subject: [PATCH 1/2] RPC: Hyperflash: Add devicetree support + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/mtd/rpc_hyperflash.c | 142 +++++++++++++++++++++++-------------------- + 1 file changed, 77 insertions(+), 65 deletions(-) + +diff --git a/drivers/mtd/rpc_hyperflash.c b/drivers/mtd/rpc_hyperflash.c +index cf4d56e..c15e520 100644 +--- a/drivers/mtd/rpc_hyperflash.c ++++ b/drivers/mtd/rpc_hyperflash.c +@@ -15,8 +15,10 @@ + #include <linux/mtd/mtd.h> + #include <linux/mtd/partitions.h> + #include <linux/of.h> ++#include <linux/clk.h> + #include <linux/rwsem.h> + #include <linux/slab.h> ++#include <linux/platform_device.h> + + /* RPC */ + #define RPC_BASE 0xEE200000 +@@ -156,10 +158,9 @@ + + struct rpc_info { + struct rw_semaphore lock; ++ struct clk *clk; + void __iomem *rpc_base; + void __iomem *flash_base; +- struct resource *rpc_res; +- struct resource *flash_res; + u32 flash_id; + struct mtd_info mtd; + }; +@@ -243,8 +244,6 @@ enum rpc_hf_size { + RPC_HF_SIZE_64BIT = RPC_SMENR_SPIDE(0xF), + }; + +-struct rpc_info *rpc_info; +- + static void rpc_hf_mode_man(struct rpc_info *info) + { + rpc_wait_tend(info); +@@ -861,8 +860,8 @@ static int rpc_hf_init_mtd(struct rpc_info *info) + rpc_hf_read_reg(info, 0x27 << 1, data, RPC_HF_SIZE_16BIT); + size = 1 << data[0]; + +- if (size > resource_size(info->flash_res)) +- size = resource_size(info->flash_res); ++ if (size > RPC_FLASH_SIZE) ++ size = RPC_FLASH_SIZE; + + if (size & (RPC_HF_ERASE_SIZE - 1)) { + retval = -EINVAL; +@@ -891,86 +890,99 @@ static int rpc_hf_init_mtd(struct rpc_info *info) + return retval; + } + +-static int rpc_flash_init(void) ++static int rpc_flash_probe(struct platform_device *pdev) + { +- struct rpc_info *info; ++ struct rpc_info *rpc; + struct resource *res; +- void __iomem *base; +- int retval = -ENODEV; +- +- if (!of_machine_is_compatible("renesas,r8a7795")) +- return -ENODEV; ++ int ret; + +- info = kzalloc(sizeof(*info), GFP_KERNEL); +- if (!info) ++ rpc = devm_kzalloc(&pdev->dev, sizeof(*rpc), GFP_KERNEL); ++ if (!rpc) + return -ENOMEM; + +- res = request_mem_region(RPC_BASE, RPC_SIZE, "RPC"); +- if (!res) +- goto out_info; ++ /* ...get memory */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ rpc->rpc_base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(rpc->rpc_base)) { ++ dev_err(&pdev->dev, "cannot get resources\n"); ++ ret = PTR_ERR(rpc->rpc_base); ++ goto error; ++ } + +- info->rpc_res = res; +- base = ioremap(res->start, resource_size(res)); +- if (!base) +- goto out_rpc_res; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ rpc->flash_base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(rpc->flash_base)) { ++ dev_err(&pdev->dev, "cannot get resources\n"); ++ ret = PTR_ERR(rpc->flash_base); ++ goto error; ++ } + +- info->rpc_base = base; +- res = request_mem_region(RPC_FLASH_BASE, RPC_FLASH_SIZE, "RPC-ext"); +- if (!res) +- goto out_rpc_base; ++ /* ...get clk */ ++ rpc->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(rpc->clk)) { ++ dev_err(&pdev->dev, "cannot get clock\n"); ++ ret = PTR_ERR(rpc->clk); ++ goto error; ++ } + +- info->flash_res = res; +- base = ioremap(res->start, resource_size(res)); +- if (!base) +- goto out_flash_res; ++ /* ... enable clk */ ++ ret = clk_prepare_enable(rpc->clk); ++ if (ret) { ++ dev_err(&pdev->dev, "cannot prepare clock\n"); ++ goto error; ++ } ++ ++ platform_set_drvdata(pdev, rpc); + +- info->flash_base = base; +- retval = rpc_hf_init_mtd(info); +- if (retval) +- goto out_flash_base; ++ mtd_set_of_node(&rpc->mtd, pdev->dev.of_node); ++ ret = rpc_hf_init_mtd(rpc); ++ if (ret) { ++ dev_err(&pdev->dev, "mtd device register error.\n"); ++ goto error_clk_disable; ++ } + +- pr_info("HyperFlash Id: %x\n", info->flash_id); ++ dev_info(&pdev->dev, "HyperFlash Id: %x\n", rpc->flash_id); + +- rpc_info = info; + return 0; + +-out_flash_base: +- iounmap(info->flash_base); +-out_flash_res: +- release_mem_region(info->flash_res->start, +- resource_size(info->flash_res)); +-out_rpc_base: +- iounmap(info->rpc_base); +-out_rpc_res: +- release_mem_region(info->rpc_res->start, +- resource_size(info->rpc_res)); +-out_info: +- kfree(info); +- return retval; ++ ++error_clk_disable: ++ clk_disable_unprepare(rpc->clk); ++error: ++ return ret; + } + +-static void rpc_flash_exit(void) ++static int rpc_flash_exit(struct platform_device *pdev) + { +- struct rpc_info *info = rpc_info; ++ struct rpc_info *rpc = platform_get_drvdata(pdev); ++ ++ /* HW shutdown */ ++ clk_disable_unprepare(rpc->clk); ++ mtd_device_unregister(&rpc->mtd); ++ return 0; ++} + +- if (!info) +- return; + +- rpc_info = NULL; ++static const struct of_device_id rpc_flash_of_match[] = { ++ { .compatible = "renesas,rpc-hyperflash-r8a7798" }, ++ { .compatible = "renesas,rpc-hyperflash-r8a7797" }, ++ { }, ++}; + +- mtd_device_unregister(&info->mtd); ++MODULE_DEVICE_TABLE(of, rpc_flash_of_match); + +- iounmap(info->flash_base); +- release_mem_region(info->flash_res->start, +- resource_size(info->flash_res)); +- iounmap(info->rpc_base); +- release_mem_region(info->rpc_res->start, +- resource_size(info->rpc_res)); +- kfree(info); +-} ++/* platform driver interface */ ++static struct platform_driver rpc_flash_platform_driver = { ++ .probe = rpc_flash_probe, ++ .remove = rpc_flash_exit, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "rpc", ++ .of_match_table = of_match_ptr(rpc_flash_of_match), ++ }, ++}; + +-module_init(rpc_flash_init); +-module_exit(rpc_flash_exit); ++module_platform_driver(rpc_flash_platform_driver); + + MODULE_LICENSE("GPL v2"); + MODULE_DESCRIPTION("Renesas RPC HyperFlash MTD driver"); +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0125-r8a7797-pinctrl-Add-pin-function-for-hyperflash.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0125-r8a7797-pinctrl-Add-pin-function-for-hyperflash.patch new file mode 100644 index 0000000..08bee0d --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0125-r8a7797-pinctrl-Add-pin-function-for-hyperflash.patch @@ -0,0 +1,70 @@ +From 4b5dc172d87cc8291ddb7377d3252b6777cf8d4b Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Wed, 4 Apr 2018 12:59:59 +0300 +Subject: [PATCH 2/2] r8a7797: pinctrl: Add pin function for hyperflash + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7797.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7797.c b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c +index 4f451c4..d989acd 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7797.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c +@@ -1196,6 +1196,25 @@ static const unsigned int qspi1_data4_mux[] = { + QSPI1_IO2_MARK, QSPI1_IO3_MARK + }; + ++static const unsigned int rpc_hyperflash_pins[] = { ++ RCAR_GP_PIN(5, 14), RCAR_GP_PIN(5, 12), ++ RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 7), ++ RCAR_GP_PIN(5, 8), RCAR_GP_PIN(5, 9), ++ RCAR_GP_PIN(5, 10), RCAR_GP_PIN(5, 6), ++ RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 4), ++ RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 2), ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 0) ++}; ++static const unsigned int rpc_hyperflash_mux[] = { ++ RPC_INT_N_MARK, RPC_RESET_N_MARK, ++ QSPI1_SSL_MARK, QSPI1_IO3_MARK, ++ QSPI1_IO2_MARK, QSPI1_MISO_IO1_MARK, ++ QSPI1_MOSI_IO0_MARK, QSPI1_SPCLK_MARK, ++ QSPI0_SSL_MARK, QSPI0_IO3_MARK, ++ QSPI0_IO2_MARK, QSPI0_MISO_IO1_MARK, ++ QSPI0_MOSI_IO0_MARK, QSPI0_SPCLK_MARK ++}; ++ + /* - I2C -------------------------------------------------------------------- */ + static const unsigned int i2c0_pins[] = { + /* SDA0, SCL0 */ +@@ -2030,6 +2049,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(qspi1_ctrl), + SH_PFC_PIN_GROUP(qspi1_data2), + SH_PFC_PIN_GROUP(qspi1_data4), ++ SH_PFC_PIN_GROUP(rpc_hyperflash), + }; + + static const char * const avb0_groups[] = { +@@ -2272,6 +2292,10 @@ static const char * const qspi1_groups[] = { + "qspi1_data4", + }; + ++static const char * const rpc_hyperflash_groups[] = { ++ "rpc_hyperflash", ++}; ++ + #define POCCTRL0 0x380 + #define POCCTRL1 0x384 + #define PIN2POCCTRL0_SHIFT(a) ({ \ +@@ -2317,6 +2341,7 @@ static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(vin1), + SH_PFC_FUNCTION(qspi0), + SH_PFC_FUNCTION(qspi1), ++ SH_PFC_FUNCTION(rpc_hyperflash), + }; + + static const struct pinmux_cfg_reg pinmux_config_regs[] = { +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0126-r8a7798-pinctrl-Add-pin-function-for-hyperflash.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0126-r8a7798-pinctrl-Add-pin-function-for-hyperflash.patch new file mode 100644 index 0000000..0babaa4 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0126-r8a7798-pinctrl-Add-pin-function-for-hyperflash.patch @@ -0,0 +1,69 @@ +From 6633820967dcedde29b2e0507b7583c08901a12f Mon Sep 17 00:00:00 2001 +From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +Date: Thu, 5 Apr 2018 18:32:59 +0300 +Subject: [PATCH] r8a7798: pinctrl: Add pin function for hyperflash + +Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7798.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7798.c b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c +index f20afd1..f6f159e 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7798.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c +@@ -1525,6 +1525,24 @@ static const unsigned int qspi1_data4_mux[] = { + QSPI1_IO2_MARK, QSPI1_IO3_MARK + }; + ++static const unsigned int rpc_hyperflash_pins[] = { ++ RCAR_GP_PIN(5, 14), RCAR_GP_PIN(5, 12), ++ RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 7), ++ RCAR_GP_PIN(5, 8), RCAR_GP_PIN(5, 9), ++ RCAR_GP_PIN(5, 10), RCAR_GP_PIN(5, 6), ++ RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 4), ++ RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 2), ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 0) ++}; ++static const unsigned int rpc_hyperflash_mux[] = { ++ RPC_INT_N_MARK, RPC_RESET_N_MARK, ++ QSPI1_SSL_MARK, QSPI1_IO3_MARK, ++ QSPI1_IO2_MARK, QSPI1_MISO_IO1_MARK, ++ QSPI1_MOSI_IO0_MARK, QSPI1_SPCLK_MARK, ++ QSPI0_SSL_MARK, QSPI0_IO3_MARK, ++ QSPI0_IO2_MARK, QSPI0_MISO_IO1_MARK, ++ QSPI0_MOSI_IO0_MARK, QSPI0_SPCLK_MARK ++}; + + /* - I2C -------------------------------------------------------------------- */ + static const unsigned int i2c0_pins[] = { +@@ -2479,6 +2497,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(qspi1_ctrl), + SH_PFC_PIN_GROUP(qspi1_data2), + SH_PFC_PIN_GROUP(qspi1_data4), ++ SH_PFC_PIN_GROUP(rpc_hyperflash), + }; + + static const char * const avb_groups[] = { +@@ -2755,6 +2774,10 @@ static const char * const qspi1_groups[] = { + "qspi1_data4", + }; + ++static const char * const rpc_hyperflash_groups[] = { ++ "rpc_hyperflash", ++}; ++ + static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(avb), + SH_PFC_FUNCTION(gether), +@@ -2793,6 +2816,7 @@ static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(vin1), + SH_PFC_FUNCTION(qspi0), + SH_PFC_FUNCTION(qspi1), ++ SH_PFC_FUNCTION(rpc_hyperflash), + }; + + static const struct pinmux_cfg_reg pinmux_config_regs[] = { +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-IMR-UIO-Driver-initial-version.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-IMR-UIO-Driver-initial-version.patch new file mode 100644 index 0000000..74d6c07 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-IMR-UIO-Driver-initial-version.patch @@ -0,0 +1,875 @@ +From 4a0e94fec7f69a717fc084fa168c2120998f076c Mon Sep 17 00:00:00 2001 +From: Toshiya Tamaki <toshiya.tamaki.ue@renesas.com> +Date: Thu, 1 Jun 2017 15:43:21 +0900 +Subject: [PATCH 1/2] IMR UIO Driver initial version + +Signed-off-by: Toshiya Tamaki <toshiya.tamaki.ue@renesas.com> +--- + .../devicetree/bindings/imr/renesas,imr.txt | 55 +++ + arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 24 +- + arch/arm64/boot/dts/renesas/r8a7795.dtsi | 24 +- + arch/arm64/boot/dts/renesas/r8a7796.dtsi | 16 + + arch/arm64/boot/dts/renesas/r8a7797.dtsi | 24 +- + arch/arm64/boot/dts/renesas/r8a7798.dtsi | 36 +- + drivers/clk/renesas/r8a7796-cpg-mssr.c | 2 + + drivers/uio/Kconfig | 8 + + drivers/uio/Makefile | 1 + + drivers/uio/uio_imr.c | 495 +++++++++++++++++++++ + 10 files changed, 631 insertions(+), 54 deletions(-) + create mode 100644 Documentation/devicetree/bindings/imr/renesas,imr.txt + create mode 100644 drivers/uio/uio_imr.c + +diff --git a/Documentation/devicetree/bindings/imr/renesas,imr.txt b/Documentation/devicetree/bindings/imr/renesas,imr.txt +new file mode 100644 +index 0000000..50ce539 +--- /dev/null ++++ b/Documentation/devicetree/bindings/imr/renesas,imr.txt +@@ -0,0 +1,55 @@ ++* Renesas Electronics IMR ++ ++This file provides information on what the device node for the IMR ++interface contains. ++ ++Required properties: ++- compatible: "renesas,imr-r8a7795" if the device is a part of R8A7795 SoC. ++ "renesas,imr-r8a7796" if the device is a part of R8A7796 SoC. ++ "renesas,imr-r8a7797" if the device is a part of R8A7797 SoC. ++ ++ When compatible with the generic version, nodes must list the ++ SoC-specific version corresponding to the platform first ++ followed by the generic version. ++ ++- reg: offset and length of (1) the register block and (2) the stream buffer. ++- interrupts: A list of interrupt-specifiers, one for each entry in ++ interrupt-names. ++ If interrupt-names is not present, an interrupt specifier ++ for a single muxed interrupt. ++- clocks: clock phandle and specifier pair. ++- power-domains: must contain a reference to the PM domain. ++ ++Example: ++ ++ imr0{ ++ compatible = "renesas,imr-r8a7797"; ++ reg = <0 0xfe860000 0 0x10000>; ++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 823>; ++ power-domains = <&sysc R8A7797_PD_A3VC>; ++ }; ++ ++ imr1{ ++ compatible = "renesas,imr-r8a7797"; ++ reg = <0 0xfe870000 0 0x10000>; ++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 822>; ++ power-domains = <&sysc R8A7797_PD_A3VC>; ++ }; ++ ++ imr2{ ++ compatible = "renesas,imr-r8a7797"; ++ reg = <0 0xfe880000 0 0x10000>; ++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 821>; ++ power-domains = <&sysc R8A7797_PD_A3VC>; ++ }; ++ ++ imr3{ ++ compatible = "renesas,imr-r8a7797"; ++ reg = <0 0xfe890000 0 0x10000>; ++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 820>; ++ power-domains = <&sysc R8A7797_PD_A3VC>; ++ }; +diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +index 13516e9..745493c 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +@@ -2899,33 +2899,33 @@ + power-domains = <&sysc R8A7795_PD_A3IR>; + }; + +- imrlx4_ch0: imr-lx4@fe860000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe860000 0 0x2000>; ++ imrlx4_ch0: imr0@fe860000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7795_PD_A3VC>; + }; + +- imrlx4_ch1: imr-lx4@fe870000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe870000 0 0x2000>; ++ imrlx4_ch1: imr1@fe870000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe870000 0 0x10000>; + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7795_PD_A3VC>; + }; + +- imrlx4_ch2: imr-lx4@fe880000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe880000 0 0x2000>; ++ imrlx4_ch2: imr2@fe880000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe880000 0 0x10000>; + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7795_PD_A3VC>; + }; + +- imrlx4_ch3: imr-lx4@fe890000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe890000 0 0x2000>; ++ imrlx4_ch3: imr3@fe890000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe890000 0 0x10000>; + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7795_PD_A3VC>; +diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi +index 565beb9..96e182a 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi +@@ -2895,33 +2895,33 @@ + power-domains = <&sysc R8A7795_PD_A3IR>; + }; + +- imrlx4_ch0: imr-lx4@fe860000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe860000 0 0x2000>; ++ imrlx4_ch0: imr0@fe860000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7795_PD_A3VC>; + }; + +- imrlx4_ch1: imr-lx4@fe870000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe870000 0 0x2000>; ++ imrlx4_ch1: imr1@fe870000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe870000 0 0x10000>; + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7795_PD_A3VC>; + }; + +- imrlx4_ch2: imr-lx4@fe880000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe880000 0 0x2000>; ++ imrlx4_ch2: imr2@fe880000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe880000 0 0x10000>; + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7795_PD_A3VC>; + }; + +- imrlx4_ch3: imr-lx4@fe890000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe890000 0 0x2000>; ++ imrlx4_ch3: imr3@fe890000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; ++ reg = <0 0xfe890000 0 0x10000>; + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7795_PD_A3VC>; +diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi +index bf37b8a..b747f0c 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi +@@ -1174,6 +1174,22 @@ + status = "disabled"; + }; + ++ imrlx4_ch0: imr0@fe860000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7796"; ++ reg = <0 0xfe860000 0 0x10000>; ++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 823>; ++ power-domains = <&sysc R8A7796_PD_A3VC>; ++ }; ++ ++ imrlx4_ch1: imr1@fe870000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7796"; ++ reg = <0 0xfe870000 0 0x10000>; ++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 822>; ++ power-domains = <&sysc R8A7796_PD_A3VC>; ++ }; ++ + can0: can@e6c30000 { + compatible = "renesas,can-r8a7796", + "renesas,rcar-gen3-can"; +diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi +index 2beca53..c878467 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7797.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi +@@ -1239,33 +1239,33 @@ + power-domains = <&sysc R8A7797_PD_A3IR>; + }; + +- imrlx4_ch0: imr-lx4@fe860000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe860000 0 0x2000>; ++ imrlx4_ch0: imr0@fe860000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797"; ++ reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; + }; + +- imrlx4_ch1: imr-lx4@fe870000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe870000 0 0x2000>; ++ imrlx4_ch1: imr1@fe870000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797"; ++ reg = <0 0xfe870000 0 0x10000>; + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; + }; + +- imrlx4_ch2: imr-lx4@fe880000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe880000 0 0x2000>; ++ imrlx4_ch2: imr2@fe880000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797"; ++ reg = <0 0xfe880000 0 0x10000>; + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; + }; + +- imrlx4_ch3: imr-lx4@fe890000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe890000 0 0x2000>; ++ imrlx4_ch3: imr3@fe890000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797"; ++ reg = <0 0xfe890000 0 0x10000>; + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; +diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +index 48ce2af..7bfd0483 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7798.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +@@ -1588,50 +1588,50 @@ + power-domains = <&sysc R8A7798_PD_A3IR>; + }; + +- imrlx4_ch0: imr-lx4@fe860000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe860000 0 0x2000>; ++ imrlx4_ch0: imr0@fe860000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798"; ++ reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; + }; + +- imrlx4_ch1: imr-lx4@fe870000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe870000 0 0x2000>; ++ imrlx4_ch1: imr1@fe870000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798"; ++ reg = <0 0xfe870000 0 0x10000>; + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; + }; + +- imrlx4_ch2: imr-lx4@fe880000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe880000 0 0x2000>; ++ imrlx4_ch2: imr2@fe880000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798"; ++ reg = <0 0xfe880000 0 0x10000>; + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; + }; + +- imrlx4_ch3: imr-lx4@fe890000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe890000 0 0x2000>; ++ imrlx4_ch3: imr3@fe890000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798"; ++ reg = <0 0xfe890000 0 0x10000>; + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; + }; + +- imrlx4_ch4: imr-lx4@fe8a0000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe8a0000 0 0x2000>; ++ imrlx4_ch4: imr4@fe8a0000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798"; ++ reg = <0 0xfe8a0000 0 0x10000>; + interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 707>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; + rse; + }; + +- imrlx4_ch5: imr-lx4@fe8b0000 { +- compatible = "renesas,imr-lx4"; +- reg = <0 0xfe8b0000 0 0x2000>; ++ imrlx4_ch5: imr5@fe8b0000 { ++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798"; ++ reg = <0 0xfe8b0000 0 0x10000>; + interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 706>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; +diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c +index e886d8a..e2ca77c 100644 +--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c +@@ -204,6 +204,8 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { + DEF_MOD("vin1", 810, R8A7796_CLK_S0D2), + DEF_MOD("vin0", 811, R8A7796_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A7796_CLK_S0D6), ++ DEF_MOD("imr1", 822, R8A7796_CLK_S2D1), ++ DEF_MOD("imr0", 823, R8A7796_CLK_S2D1), + DEF_MOD("imp", 824, R8A7796_CLK_S1D1), + DEF_MOD("gpio7", 905, R8A7796_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A7796_CLK_S3D4), +diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig +index 52c98ce..09d91ac 100644 +--- a/drivers/uio/Kconfig ++++ b/drivers/uio/Kconfig +@@ -155,4 +155,12 @@ config UIO_MF624 + + If you compile this as a module, it will be called uio_mf624. + ++config UIO_IMR ++ tristate "Renesas IMR support" ++ ++ help ++ Renesas IMR device driver. ++ This driver supports the following SoCs: ++ - R8A7795, R8A7796, R8A7797. ++ + endif +diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile +index 8560dad..3d29324 100644 +--- a/drivers/uio/Makefile ++++ b/drivers/uio/Makefile +@@ -9,3 +9,4 @@ obj-$(CONFIG_UIO_NETX) += uio_netx.o + obj-$(CONFIG_UIO_PRUSS) += uio_pruss.o + obj-$(CONFIG_UIO_MF624) += uio_mf624.o + obj-$(CONFIG_UIO_FSL_ELBC_GPCM) += uio_fsl_elbc_gpcm.o ++obj-$(CONFIG_UIO_IMR) += uio_imr.o +diff --git a/drivers/uio/uio_imr.c b/drivers/uio/uio_imr.c +new file mode 100644 +index 0000000..a64c65e +--- /dev/null ++++ b/drivers/uio/uio_imr.c +@@ -0,0 +1,495 @@ ++/*************************************************************************/ /* ++ IMR ++ ++ Copyright (C) 2015-2017 Renesas Electronics Corporation ++ ++ License Dual MIT/GPLv2 ++ ++ The contents of this file are subject to the MIT license as set out below. ++ ++ Permission is hereby granted, free of charge, to any person obtaining a copy ++ of this software and associated documentation files (the "Software"), to deal ++ in the Software without restriction, including without limitation the rights ++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ copies of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ ++ The above copyright notice and this permission notice shall be included in ++ all copies or substantial portions of the Software. ++ ++ Alternatively, the contents of this file may be used under the terms of ++ the GNU General Public License Version 2 ("GPL") in which case the provisions ++ of GPL are applicable instead of those above. ++ ++ If you wish to allow use of your version of this file only under the terms of ++ GPL, and not to allow others to use your version of this file under the terms ++ of the MIT license, indicate your decision by deleting the provisions above ++ and replace them with the notice and other provisions required by GPL as set ++ out in the file called "GPL-COPYING" included in this distribution. If you do ++ not delete the provisions above, a recipient may use your version of this file ++ under the terms of either the MIT license or GPL. ++ ++ This License is also included in this distribution in the file called ++ "MIT-COPYING". ++ ++ EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS ++ PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING ++ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR ++ PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR ++ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++ ++ GPLv2: ++ If you wish to use this file under the terms of GPL, following terms are ++ effective. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; version 2 of the License. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++*/ /*************************************************************************/ ++ ++/* PRQA S 292,2212,2214 EOF */ ++#include <linux/platform_device.h> ++#include <linux/uio_driver.h> ++#include <linux/interrupt.h> ++#include <linux/pm_runtime.h> ++#include <linux/slab.h> ++#include <linux/clk.h> ++#include <linux/io.h> ++#include <linux/module.h> ++ ++#include <linux/of.h> ++#include <linux/of_irq.h> ++ ++/* IMR uio driver name */ ++#define DRIVER_NAME "uio_imr" ++ ++/* IMR register definition */ ++#define IMR_REG_IMR_ADDRESS (0x018U) ++#define IMR_REG_IMR_BIT_BASE (0x3U << 3) ++#define IMR_REG_IMR_BIT_INT (0x1U << 2) ++#define IMR_REG_IMR_BIT_IER (0x1U << 1) ++#define IMR_REG_IMR_BIT_TRA (0x1U << 0) ++ ++/** ++ * struct uio_platdata - the uio platform data structure ++ * @uioinfo: UIO device capabilities ++ * @lock lock flag for irq. ++ * @flags: flags for request_irq. ++ * @pdev: IMR platform device data. ++ * @base_reg: IMR base register address. ++ * @clk: clock data. ++ * ++ * the uio platform data structure. ++ */ ++struct uio_platdata { ++ struct uio_info *uioinfo; ++ spinlock_t lock; ++ unsigned long flags; ++ struct platform_device *pdev; ++ void __iomem *base_reg; ++ struct clk *clock; ++}; ++ ++static void write_register(struct uio_platdata *priv, ++ u32 reg_offs, u32 data); ++static int uio_imr_open(struct uio_info *info, ++ __attribute__((unused)) struct inode *inode); ++static int uio_imr_release(struct uio_info *info, ++ __attribute__((unused)) struct inode *inode); ++static irqreturn_t uio_imr_handler(__attribute__((unused)) int irq, ++ struct uio_info *dev_info); ++static int uio_imr_irqcontrol(struct uio_info *info, s32 irq_on); ++static int uio_imr_probe(struct platform_device *pdev); ++static int uio_imr_remove(struct platform_device *pdev); ++static int uio_runtime_imr_nop(__attribute__((unused)) struct device *dev); ++ ++/** ++ * write_register() - register setting ++ * @priv: uio platform data. ++ * @reg_offs: register offset. ++ * @data: register value. ++ * ++ * register setting. ++ * ++ * ++ * Return: none ++ */ ++static void write_register(struct uio_platdata *priv, ++ u32 reg_offs, u32 data) ++{ ++ iowrite32(data, (u8 *)priv->base_reg + reg_offs); /* PRQA S 488 */ ++} ++ ++/** ++ * uio_imr_open() - open imr module ++ * @info: UIO device capabilities. ++ * @inode: inode. ++ * ++ * Open imr module. ++ * ++ * ++ * Return: 0 normal end. ++ */ ++/* PRQA S 3206 2 */ ++static int uio_imr_open(struct uio_info *info, ++ __attribute__((unused)) struct inode *inode) ++{ ++ struct uio_platdata *pdata = info->priv; ++ /* PRQA S 3200 1 */ ++ pr_debug("uio_imr_open enter. name=%s\n", pdata->uioinfo->name); ++ ++ /* Wait until the Runtime PM code has woken up the device */ ++ (void)pm_runtime_get_sync(&pdata->pdev->dev); ++ ++ return 0; ++} ++ ++/** ++ * uio_imr_release() - close imr module ++ * @info: UIO device capabilities. ++ * @inode: inode. ++ * ++ * Close imr module. ++ * ++ * ++ * Return: 0 normal end. ++ */ ++/* PRQA S 3206 2 */ ++static int uio_imr_release(struct uio_info *info, ++ __attribute__((unused)) struct inode *inode) ++{ ++ struct uio_platdata *pdata = info->priv; ++ ++ pr_debug("uio_imr_release enter\n"); /* PRQA S 3200 */ ++ ++ /* Tell the Runtime PM code that the device has become idle */ ++ (void)pm_runtime_put_sync(&pdata->pdev->dev); ++ ++ return 0; ++} ++ ++/** ++ * uio_imr_handler() - IMR interrupt handler ++ * @irq: irq No. ++ * @dev_info: UIO device capabilities. ++ * ++ * IMR interrupt handler. ++ * ++ * ++ * Return: IRQ_HANDLED normal end. ++ */ ++/* PRQA S 3206 1*/ ++static irqreturn_t uio_imr_handler(__attribute__((unused))int irq, ++ struct uio_info *dev_info) ++{ ++ struct uio_platdata *pdata = dev_info->priv; ++ ++ ++ pr_debug("uio_imr_handler enter\n"); /* PRQA S 3200 */ ++ ++ /* Mask interrupt */ ++ write_register(pdata, IMR_REG_IMR_ADDRESS, ++ IMR_REG_IMR_BIT_BASE | (IMR_REG_IMR_BIT_INT | ++ IMR_REG_IMR_BIT_IER | IMR_REG_IMR_BIT_TRA)); ++ ++ return IRQ_HANDLED; ++} ++ ++/** ++ * uio_imr_irqcontrol() - IMR irq controller ++ * @info: UIO device capabilities. ++ * @irq_on: irq enable/disable. ++ * ++ * IMR irq controller. Enable and disable the interrupt. ++ * ++ * ++ * Return: 0 normal end. ++ */ ++static int uio_imr_irqcontrol(struct uio_info *info, s32 irq_on) ++{ ++ struct uio_platdata *pdata = info->priv; ++ u64 flag; ++ ++ pr_debug("uio_imr_irqcontrol enter\n"); /* PRQA S 3200 */ ++ ++ spin_lock_irqsave(&pdata->lock, flag); ++ if (irq_on != 0) { ++ if (test_and_clear_bit(0, &pdata->flags) != 0) ++ enable_irq((u32)info->irq); ++ } else { ++ if (test_and_set_bit(0, &pdata->flags) == 0) ++ disable_irq((u32)info->irq); ++ } ++ spin_unlock_irqrestore(&pdata->lock, flag); ++ ++ return 0; ++} ++ ++/* PRQA S 1053,1041,605 10 */ ++static const struct of_device_id rcar_imr_dt_ids[] = { ++ { .compatible = "renesas,imr-r8a7795", .data = 0 }, ++ { .compatible = "renesas,imr-r8a7796", .data = 0 }, ++ { .compatible = "renesas,imr-r8a7797", .data = 0 }, ++ { .compatible = "renesas,imr-r8a7798", .data = 0 }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rcar_imr_dt_ids); /* PRQA S 605 */ ++ ++/** ++ * uio_imr_probe() - Initialize IMR module. ++ * @pdev: platform device data. ++ * ++ * Initialize IMR module. ++ * ++ * ++ * Return: 0 normal end. ++ * -EINVAL parameter error. ++ * -ENOMEM memory error. ++ * -ENODEV system error. ++ */ ++static int uio_imr_probe(struct platform_device *pdev) ++{ ++ struct uio_info *uioinfo_data = NULL; ++ struct uio_platdata *pdata; ++ struct uio_mem *uiomem; ++ int ret = 0; ++ unsigned int i; ++ struct resource *rsc; ++ unsigned int irq_l; ++ unsigned long remap_size; ++ ++ if (pdev == NULL) { ++ pr_err("missing pdev\n"); ++ ret = -EINVAL; ++ } else { ++ if (pdev->dev.of_node == NULL) { ++ dev_err(&pdev->dev, "missing pdev->dev.of_node\n"); ++ ret = -EINVAL; ++ } ++ } ++ ++ if (ret == 0) { ++ pr_debug("uio_imr_probe enter name = %s\n", /* PRQA S 3200 */ ++ pdev->dev.of_node->name); ++ ++ uioinfo_data = devm_kzalloc(&pdev->dev, ++ sizeof(*uioinfo_data), ++ GFP_KERNEL); ++ if (uioinfo_data == NULL) ++ ret = -ENOMEM; ++ } ++ ++ if (ret == 0) { ++ uioinfo_data->name = pdev->dev.of_node->name; ++ uioinfo_data->version = "0.1"; ++ ++ /* get irq number */ ++ irq_l = irq_of_parse_and_map(pdev->dev.of_node, 0); ++ if ((int)irq_l == -ENXIO) ++ uioinfo_data->irq = platform_get_irq(pdev, 0); ++ else ++ uioinfo_data->irq = (int)irq_l; ++ ++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); ++ if (pdata == NULL) ++ ret = -ENOMEM; ++ } ++ ++ if (ret == 0) { ++ pdata->uioinfo = uioinfo_data; ++ spin_lock_init(&pdata->lock); /* PRQA S 3200 */ ++ pdata->flags = 0; ++ pdata->pdev = pdev; ++ ++ uiomem = &uioinfo_data->mem[0]; ++ ++ for (i = 0; i < pdev->num_resources; ++i) { ++ /* PRQA S 491 1 */ ++ struct resource *r = &pdev->resource[i]; ++ ++ if (r->flags == IORESOURCE_IRQ) { ++ uioinfo_data->irq = (long)r->start; ++ } else if (r->flags != IORESOURCE_MEM) { ++ ; ++ } else { ++ if (uiomem >= ++ &uioinfo_data->mem[MAX_UIO_MAPS]) { ++ dev_warn(&pdev->dev, ++ "device has more than " ++ __stringify(MAX_UIO_MAPS) ++ " I/O memory resources.\n"); ++ break; ++ } ++ ++ uiomem->memtype = UIO_MEM_PHYS; ++ uiomem->addr = r->start; ++ uiomem->size = (r->end - r->start) + 1; ++ ++uiomem; /* PRQA S 489 */ ++ } ++ } ++ ++ while (uiomem < &uioinfo_data->mem[MAX_UIO_MAPS]) { ++ uiomem->size = 0; ++ ++uiomem; /* PRQA S 489 */ ++ } ++ ++ uioinfo_data->handler = &uio_imr_handler; ++ uioinfo_data->irqcontrol = &uio_imr_irqcontrol; ++ uioinfo_data->open = &uio_imr_open; ++ uioinfo_data->release = &uio_imr_release; ++ uioinfo_data->priv = pdata; ++ ++ pm_runtime_enable(&pdev->dev); ++ ++ ret = uio_register_device(&pdev->dev, pdata->uioinfo); ++ if (ret != 0) { ++ pm_runtime_disable(&pdev->dev); ++ dev_err(&pdev->dev, "could not register uio device\n"); ++ ret = -ENODEV; ++ } ++ } ++ ++ if (ret == 0) { ++ platform_set_drvdata(pdev, pdata); ++ pdata->clock = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(pdata->clock)) { ++ pm_runtime_disable(&pdev->dev); ++ dev_err(&pdev->dev, "could not get clock\n"); ++ ret = -ENODEV; ++ } else { ++ /* clock enable */ ++ (void)clk_prepare_enable(pdata->clock); ++ } ++ } ++ ++ if (ret == 0) { ++ rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (rsc == 0) { ++ pm_runtime_disable(&pdev->dev); ++ dev_err(&pdev->dev, "could not platform_get_resource\n"); ++ ret = -ENODEV; ++ } ++ } ++ ++ if (ret == 0) { ++ remap_size = (rsc->end - rsc->start) + 1; ++ if (!request_mem_region(rsc->start, ++ remap_size, ++ uioinfo_data->name)) { ++ dev_err(&pdev->dev, "could not request IO\n"); ++ pm_runtime_disable(&pdev->dev); ++ ret = -ENOMEM; ++ } ++ } ++ ++ if (ret == 0) { ++ /* IMR Register Adderss */ ++ pdata->base_reg = devm_ioremap_nocache(&pdev->dev, ++ rsc->start, ++ remap_size); ++ if (pdata->base_reg == NULL) { ++ release_mem_region(rsc->start, resource_size(rsc)); ++ dev_err(&pdev->dev, "could not remap IMR register\n"); ++ pm_runtime_disable(&pdev->dev); ++ ret = -ENOMEM; ++ } else { ++ /* PRQA S 3200 2 */ ++ pr_debug("IMR reg_base = %x size = %x\n", ++ (uint32_t)(rsc->start), (uint32_t)remap_size); ++ } ++ } ++ ++ return ret; ++} ++ ++/** ++ * uio_imr_remove() - release IMR module. ++ * @pdev: platform device data. ++ * ++ * release IMR module. ++ * ++ * ++ * Return: 0 normal end. ++ */ ++static int uio_imr_remove(struct platform_device *pdev) ++{ ++ struct resource *rsc; ++ struct uio_platdata *pdata = platform_get_drvdata(pdev); ++ ++ /* PRQA S 3200 1 */ ++ pr_debug("uio_imr_remove enter name = %s\n", pdata->uioinfo->name); ++ ++ clk_disable_unprepare(pdata->clock); ++ ++ uio_unregister_device(pdata->uioinfo); ++ ++ pm_runtime_disable(&pdev->dev); ++ ++ irq_dispose_mapping((u32)pdata->uioinfo->irq); ++ ++ pdata->uioinfo->handler = NULL; ++ pdata->uioinfo->irqcontrol = NULL; ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ if (pdata->base_reg != NULL) ++ devm_iounmap(&pdev->dev, pdata->base_reg); ++ ++ rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (rsc != 0) ++ release_mem_region(rsc->start, resource_size(rsc)); ++ ++ return 0; ++} ++ ++/** ++ * uio_runtime_imr_nop() - Runtime PM callback function. ++ * @dev: device data. ++ * ++ * Runtime PM callback function. ++ * ++ * ++ * Return: 0 normal end. ++ */ ++ /* PRQA S 3206 1 */ ++static int uio_runtime_imr_nop(__attribute__((unused)) struct device *dev) ++{ ++ pr_debug("uio_runtime_imr_nop enter\n"); /* PRQA S 3200 */ ++ return 0; ++} ++/* PRQA S 1053 4 */ ++static const struct dev_pm_ops uio_dev_pm_imr_ops = { ++ .runtime_suspend = &uio_runtime_imr_nop, ++ .runtime_resume = &uio_runtime_imr_nop, ++}; ++ ++static struct platform_driver uio_imr_platform_driver = { ++ .probe = &uio_imr_probe, ++ .remove = &uio_imr_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .pm = &uio_dev_pm_imr_ops, ++ .of_match_table = of_match_ptr(rcar_imr_dt_ids), ++ }, ++}; ++ ++module_platform_driver(uio_imr_platform_driver); ++ ++ ++MODULE_AUTHOR("Renesas Electronics Corporation"); ++MODULE_DESCRIPTION("Userspace I/O driver for IMR"); ++MODULE_LICENSE("Dual MIT/GPL"); ++MODULE_ALIAS("platform:" DRIVER_NAME); +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-rcar_imr-v4l2-driver-Fix-module-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-rcar_imr-v4l2-driver-Fix-module-support.patch new file mode 100644 index 0000000..f4ee6e2 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-rcar_imr-v4l2-driver-Fix-module-support.patch @@ -0,0 +1,321 @@ +From 772299b20e32fc3ff86de4a83845e8246d97bcbb Mon Sep 17 00:00:00 2001 +From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com> +Date: Mon, 9 Apr 2018 12:50:23 +0300 +Subject: [PATCH 2/2] rcar_imr v4l2 driver: Fix module support. + +--- + arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 8 +++++++ + arch/arm64/boot/dts/renesas/r8a7795.dtsi | 8 +++++++ + arch/arm64/boot/dts/renesas/r8a7796.dtsi | 6 ++++++ + arch/arm64/boot/dts/renesas/r8a7797.dtsi | 8 +++++++ + arch/arm64/boot/dts/renesas/r8a7798.dtsi | 10 +++++++++ + drivers/media/platform/rcar_imr.c | 32 +++++++++++++++++++++++++--- + 6 files changed, 69 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +index 745493c..f2769c2 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +@@ -2899,12 +2899,17 @@ + power-domains = <&sysc R8A7795_PD_A3IR>; + }; + ++ imr_v4l2_alloc: imr_alloc { ++ dma-coherent; ++ }; ++ + imrlx4_ch0: imr0@fe860000 { + compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; + reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch1: imr1@fe870000 { +@@ -2913,6 +2918,7 @@ + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch2: imr2@fe880000 { +@@ -2921,6 +2927,7 @@ + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch3: imr3@fe890000 { +@@ -2929,6 +2936,7 @@ + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi +index 96e182a..366ee5f 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi +@@ -2895,12 +2895,17 @@ + power-domains = <&sysc R8A7795_PD_A3IR>; + }; + ++ imr_v4l2_alloc: imr_alloc { ++ dma-coherent; ++ }; ++ + imrlx4_ch0: imr0@fe860000 { + compatible = "renesas,imr-lx4", "renesas,imr-r8a7795"; + reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch1: imr1@fe870000 { +@@ -2909,6 +2914,7 @@ + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch2: imr2@fe880000 { +@@ -2917,6 +2923,7 @@ + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch3: imr3@fe890000 { +@@ -2925,6 +2932,7 @@ + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7795_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi +index b747f0c..442f027 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi +@@ -1174,12 +1174,17 @@ + status = "disabled"; + }; + ++ imr_v4l2_alloc: imr_alloc { ++ dma-coherent; ++ }; ++ + imrlx4_ch0: imr0@fe860000 { + compatible = "renesas,imr-lx4", "renesas,imr-r8a7796"; + reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7796_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch1: imr1@fe870000 { +@@ -1188,6 +1193,7 @@ + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7796_PD_A3VC>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + can0: can@e6c30000 { +diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi +index c878467..16e73b4 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7797.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi +@@ -1239,12 +1239,17 @@ + power-domains = <&sysc R8A7797_PD_A3IR>; + }; + ++ imr_v4l2_alloc: imr_alloc { ++ dma-coherent; ++ }; ++ + imrlx4_ch0: imr0@fe860000 { + compatible = "renesas,imr-lx4", "renesas,imr-r8a7797"; + reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch1: imr1@fe870000 { +@@ -1253,6 +1258,7 @@ + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch2: imr2@fe880000 { +@@ -1261,6 +1267,7 @@ + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch3: imr3@fe890000 { +@@ -1269,6 +1276,7 @@ + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +index 7bfd0483..0742ec0 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7798.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi +@@ -1588,12 +1588,17 @@ + power-domains = <&sysc R8A7798_PD_A3IR>; + }; + ++ imr_v4l2_alloc: imr_alloc { ++ dma-coherent; ++ }; ++ + imrlx4_ch0: imr0@fe860000 { + compatible = "renesas,imr-lx4", "renesas,imr-r8a7798"; + reg = <0 0xfe860000 0 0x10000>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch1: imr1@fe870000 { +@@ -1602,6 +1607,7 @@ + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch2: imr2@fe880000 { +@@ -1610,6 +1616,7 @@ + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch3: imr3@fe890000 { +@@ -1618,6 +1625,7 @@ + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + }; + + imrlx4_ch4: imr4@fe8a0000 { +@@ -1626,6 +1634,7 @@ + interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 707>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + rse; + }; + +@@ -1635,6 +1644,7 @@ + interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 706>; + power-domains = <&sysc R8A7798_PD_ALWAYS_ON>; ++ alloc-dev = <&imr_v4l2_alloc>; + rse; + }; + +diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c +index 7b16765..3558211 100644 +--- a/drivers/media/platform/rcar_imr.c ++++ b/drivers/media/platform/rcar_imr.c +@@ -18,6 +18,7 @@ + #include <linux/delay.h> + #include <linux/rcar-imr.h> + #include <linux/of.h> ++#include <linux/of_device.h> + #include <media/v4l2-device.h> + #include <media/v4l2-ctrls.h> + #include <media/v4l2-fh.h> +@@ -1917,6 +1918,8 @@ static int imr_probe(struct platform_device *pdev) + struct resource *res; + struct device_node *np = pdev->dev.of_node; + int ret; ++ phandle *prop; ++ struct device_node *node; + + imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL); + if (!imr) +@@ -1989,10 +1992,15 @@ static int imr_probe(struct platform_device *pdev) + ret = PTR_ERR(adev); + goto m2m_init_rollback; + } ++ + adev->dma_mask = &adev->coherent_dma_mask; + adev->coherent_dma_mask = DMA_BIT_MASK(32); +- arch_setup_dma_ops(adev, 0, DMA_BIT_MASK(32) + 1, NULL, true); + imr->alloc_dev = adev; ++ prop = of_get_property(np, "alloc-dev", NULL); ++ if (prop) { ++ node = of_find_node_by_phandle(be32_to_cpup(prop)); ++ of_dma_configure(adev, node); ++ } + + strlcpy(imr->video_dev.name, dev_name(&pdev->dev), sizeof(imr->video_dev.name)); + imr->video_dev.fops = &imr_fops; +@@ -2032,7 +2040,6 @@ static int imr_remove(struct platform_device *pdev) + + //pm_runtime_disable(imr->v4l2_dev.dev); + video_unregister_device(&imr->video_dev); +- //device_destroy(imr->alloc_dev, MKDEV(0, 0)); + v4l2_m2m_release(imr->m2m_dev); + v4l2_device_unregister(&imr->v4l2_dev); + +@@ -2100,7 +2107,26 @@ static struct platform_driver imr_platform_driver = { + }, + }; + +-module_platform_driver(imr_platform_driver); ++static int __init imr_module_init(void) ++{ ++ return platform_driver_register(&imr_platform_driver); ++} ++ ++static int imr_device_destroy(struct device *dev, void *data) ++{ ++ device_destroy(imr_alloc_class, dev->devt); ++ return 0; ++} ++ ++static void __exit imr_module_exit(void) ++{ ++ class_for_each_device(imr_alloc_class, NULL, NULL, imr_device_destroy); ++ class_destroy(imr_alloc_class); ++ platform_driver_unregister(&imr_platform_driver); ++} ++ ++module_init(imr_module_init); ++module_exit(imr_module_exit); + + MODULE_ALIAS("imr"); + MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>"); +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0129-Add-cropping-handling-to-VSP-alpha-planes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0129-Add-cropping-handling-to-VSP-alpha-planes.patch new file mode 100644 index 0000000..d55b196 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0129-Add-cropping-handling-to-VSP-alpha-planes.patch @@ -0,0 +1,44 @@ +From 4b26e8c561541c68c5755660eaad355d9a9afc86 Mon Sep 17 00:00:00 2001 +From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com> +Date: Wed, 11 Apr 2018 05:11:21 -0700 +Subject: [PATCH] Add cropping handling to VSP alpha-planes + +--- + drivers/media/platform/vsp1/vsp1_dl.c | 2 +- + drivers/media/platform/vsp1/vsp1_rpf.c | 5 +++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c +index f9c6d09..d6314cd 100644 +--- a/drivers/media/platform/vsp1/vsp1_dl.c ++++ b/drivers/media/platform/vsp1/vsp1_dl.c +@@ -363,7 +363,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_list *dl, struct vsp1_rwpf *rpf) + dl->src_dst_addr[v_bot_index].addr = v_bot_addr; + + /* ...set alpha-plane address as needed */ +- dl->src_dst_addr[alpha_index].addr = rpf->mem.alpha; ++ dl->src_dst_addr[alpha_index].addr = rpf->mem.alpha + crop->top * width + crop->left; + } + + static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm) +diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c +index 2cce294..1f70186 100644 +--- a/drivers/media/platform/vsp1/vsp1_rpf.c ++++ b/drivers/media/platform/vsp1/vsp1_rpf.c +@@ -292,10 +292,11 @@ static void rpf_configure(struct vsp1_entity *entity, + + // ...setup alpha-plane as required + if (rpf->mem.alpha) { +- vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_AI, rpf->mem.alpha); ++ struct v4l2_rect *crop = vsp1_rwpf_get_crop(rpf, rpf->entity.config); ++ vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_AI, rpf->mem.alpha + crop->top * rpf->alpha_pitch + crop->left); + vsp1_rpf_write(rpf, dl, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_ASEL_8B_PLANE); + vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ASTRIDE, rpf->alpha_pitch); +- dev_dbg(vsp1->dev, "rpf#%d: setup alpha-plane: buffer=%pad, stride=%u\n", rpf->entity.index, &rpf->mem.alpha, rpf->alpha_pitch); ++ dev_dbg(vsp1->dev, "rpf#%d: setup alpha-plane: buffer=%pad, crop=%d,%d, stride=%u\n", rpf->entity.index, &rpf->mem.alpha, crop->left, crop->top, rpf->alpha_pitch); + goto out; + } + +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0130-Add-RAW-sensors-MBUS-formats.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0130-Add-RAW-sensors-MBUS-formats.patch new file mode 100644 index 0000000..3278fc2 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0130-Add-RAW-sensors-MBUS-formats.patch @@ -0,0 +1,36 @@ +From f977b84f5899093208f64b31731ea991579d6f8f Mon Sep 17 00:00:00 2001 +From: Vladimir Barinov <vladimir.barinov@cogentembedded.com> +Date: Fri, 13 Apr 2018 16:51:15 +0300 +Subject: [PATCH] Add RAW sensors MBUS formats. + +--- + drivers/media/platform/soc_camera/rcar_vin.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c +index 37f1a11..b4ea2de 100644 +--- a/drivers/media/platform/soc_camera/rcar_vin.c ++++ b/drivers/media/platform/soc_camera/rcar_vin.c +@@ -1074,6 +1074,9 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) + break; + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR12_1X12: ++ case MEDIA_BUS_FMT_SRGGB12_1X12: ++ case MEDIA_BUS_FMT_SGRBG12_1X12: ++ case MEDIA_BUS_FMT_SGRBG14_1X14: + vnmc |= VNMC_INF_RAW8 | VNMC_BPS; + break; + default: +@@ -2213,6 +2216,9 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR12_1X12: ++ case MEDIA_BUS_FMT_SRGGB12_1X12: ++ case MEDIA_BUS_FMT_SGRBG12_1X12: ++ case MEDIA_BUS_FMT_SGRBG14_1X14: + if (cam->extra_fmt) + break; + +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0131-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0131-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch new file mode 100644 index 0000000..8d7409a --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0131-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch @@ -0,0 +1,59 @@ +From e0807ef3f52f630dcfa694802273d63bbfd35f15 Mon Sep 17 00:00:00 2001 +From: Valentine Barshak <valentine.barshak@cogentembedded.com> +Date: Wed, 4 Apr 2018 18:48:27 +0300 +Subject: [PATCH] ARM64: dts: renesas: ulcb: Make AK4613 sound device name + consistent + +This makes AK4613 sound device name consistent throughout all +ULCB boards. This helps to avoid naming issues when pulseaudio +fails to start because the device has different names on +infotainment and starter boards. For example, "ak4613" +on Kingfisher vs "rsnd-dai.0-ak4613-hifi" on Starter Kit. +Pulseaudio is expecting "ak4613" name. + +Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com> +--- + arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts | 1 + + arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts | 1 + + arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts +index bffa775..124379d 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts +@@ -178,6 +178,7 @@ + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; ++ simple-audio-card,name = "ak4613"; + simple-audio-card,bitclock-master = <&sndcpu>; + simple-audio-card,frame-master = <&sndcpu>; + +diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts +index 76da9f2..4a94a68 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts +@@ -178,6 +178,7 @@ + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; ++ simple-audio-card,name = "ak4613"; + simple-audio-card,bitclock-master = <&sndcpu>; + simple-audio-card,frame-master = <&sndcpu>; + +diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts +index 7b58109..15c67ec 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts ++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts +@@ -159,6 +159,7 @@ + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; ++ simple-audio-card,name = "ak4613"; + simple-audio-card,bitclock-master = <&sndcpu>; + simple-audio-card,frame-master = <&sndcpu>; + +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg new file mode 100644 index 0000000..8efcbff --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg @@ -0,0 +1,33 @@ +CONFIG_ARCH_R8A7798=y +CONFIG_CAN=y +CONFIG_CAN_BCM=y +CONFIG_CAN_RAW=y +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_RCAR=y +CONFIG_CAN_RCAR_CANFD=y +CONFIG_DUMMY=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_VIDEO_ADV_DEBUG=y +CONFIG_VIDEO_RCAR_VIN_LEGACY=y +CONFIG_VIDEO_RCAR_CSI2_LEGACY=y +CONFIG_VIDEO_RCAR_ISP_LEGACY=y +# CONFIG_VIDEO_RCAR_VIN is not set +# CONFIG_VIDEO_RCAR_CSI2 is not set +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_SCALE_CROP=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_SOC_CAMERA_MAX9286=y +CONFIG_SOC_CAMERA_OV106XX=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_HID_MULTITOUCH=y +CONFIG_SERIAL_SH_SCI_DMA=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_SH_ETH=y +CONFIG_BLK_DEV_NVME=m +CONFIG_SATA_ACARD_AHCI=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg index 5b728fd..2b4cdc1 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg @@ -1,6 +1,5 @@ CONFIG_ARCH_R8A7797=y CONFIG_CAN=y -CONFIG_CAN_PEAK_USB=y CONFIG_CAN_BCM=y CONFIG_CAN_RAW=y CONFIG_CAN_DEV=y @@ -14,17 +13,22 @@ CONFIG_GPIO_PCA953X_IRQ=y CONFIG_VIDEO_ADV_DEBUG=y CONFIG_VIDEO_RCAR_VIN_LEGACY=y CONFIG_VIDEO_RCAR_CSI2_LEGACY=y +CONFIG_VIDEO_RCAR_ISP_LEGACY=y # CONFIG_VIDEO_RCAR_VIN is not set # CONFIG_VIDEO_RCAR_CSI2 is not set CONFIG_SOC_CAMERA=y CONFIG_SOC_CAMERA_SCALE_CROP=y CONFIG_SOC_CAMERA_PLATFORM=y -CONFIG_SOC_CAMERA_MAX9286_MAX9271=y +CONFIG_SOC_CAMERA_MAX9286=y CONFIG_SOC_CAMERA_OV106XX=y -CONFIG_VIDEO_RENESAS_IMR=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_UINPUT=y CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_HID_MULTITOUCH=y CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_UIO=y +CONFIG_MFD_DA9063=y +CONFIG_INPUT_DA9063_ONKEY=y +CONFIG_DA9063_WATCHDOG=y +CONFIG_REGULATOR_DA9063=y +CONFIG_RTC_DRV_DA9063=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg new file mode 100644 index 0000000..cc7f69e --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg @@ -0,0 +1,3 @@ +CONFIG_VIDEO_RENESAS_IMR=m +CONFIG_UIO=y +CONFIG_UIO_IMR=m diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/qspi.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/qspi.cfg new file mode 100644 index 0000000..9a1c695 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/qspi.cfg @@ -0,0 +1,3 @@ +CONFIG_SPI_RENESAS_RPC=y +CONFIG_MTD_BLOCK=y +CONFIG_JFFS2_FS=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg index a42b74c..4af8122 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg @@ -17,14 +17,13 @@ CONFIG_VIDEO_RCAR_CSI2_LEGACY=y CONFIG_SOC_CAMERA=y CONFIG_SOC_CAMERA_SCALE_CROP=y CONFIG_SOC_CAMERA_PLATFORM=y -CONFIG_SOC_CAMERA_MAX9286_MAX9271=y +CONFIG_SOC_CAMERA_MAX9286=y CONFIG_SOC_CAMERA_OV106XX=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_XHCI_RCAR=y CONFIG_MMC_SDHI_PRE_REQ=y CONFIG_MMC_SDHI_SEQ=y -CONFIG_VIDEO_RENESAS_IMR=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_HID_MULTITOUCH=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg index 0fd7e07..a821c24 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg @@ -1,11 +1,13 @@ CONFIG_CAN=y CONFIG_CAN_PEAK_USB=y +CONFIG_CAN_KVASER_USB=y CONFIG_CAN_BCM=y CONFIG_CAN_RAW=y CONFIG_CAN_DEV=y CONFIG_CAN_CALC_BITTIMING=y CONFIG_CAN_RCAR=y CONFIG_CAN_RCAR_CANFD=y +CONFIG_CAN_MCP251X=y CONFIG_DUMMY=y CONFIG_EXTRA_FIRMWARE="r8a779x_usb3_v2.dlmem r8a779x_usb3_v3.dlmem" CONFIG_EXTRA_FIRMWARE_DIR="firmware" @@ -26,9 +28,8 @@ CONFIG_VIDEO_RCAR_CSI2_LEGACY=y CONFIG_SOC_CAMERA=y CONFIG_SOC_CAMERA_SCALE_CROP=y CONFIG_SOC_CAMERA_PLATFORM=y -CONFIG_SOC_CAMERA_MAX9286_MAX9271=y -CONFIG_SOC_CAMERA_TI964_TI9X3=y -CONFIG_SOC_CAMERA_TI954_TI9X3=y +CONFIG_SOC_CAMERA_MAX9286=y +CONFIG_SOC_CAMERA_TI9X4=y CONFIG_SOC_CAMERA_OV106XX=y CONFIG_SOC_CAMERA_OV5647=y CONFIG_SOC_CAMERA_OV5642=y @@ -36,7 +37,6 @@ CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_XHCI_RCAR=y CONFIG_USB_ACM=y -CONFIG_VIDEO_RENESAS_IMR=y CONFIG_VIRTIO_RCAR_PCIE=y CONFIG_BT=y CONFIG_BT_BNEP=m @@ -77,4 +77,7 @@ CONFIG_PMBUS=y CONFIG_RTC_DRV_DS1307=y CONFIG_RTC_DRV_DS1307_HWMON=y CONFIG_SENSORS_LM63=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_RAID0=y CONFIG_MMC_SDHI_SEQ_WORKAROUND=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg new file mode 100644 index 0000000..c3cec9a --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg @@ -0,0 +1,42 @@ +CONFIG_ARCH_R8A7798=y +CONFIG_CAN=y +CONFIG_CAN_PEAK_USB=y +CONFIG_CAN_BCM=y +CONFIG_CAN_RAW=y +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_RCAR=y +CONFIG_CAN_RCAR_CANFD=y +CONFIG_DUMMY=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_GPIO_MAX732X=y +CONFIG_GPIO_MAX732X_IRQ=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_VIDEO_ADV_DEBUG=y +CONFIG_VIDEO_RCAR_VIN_LEGACY=y +CONFIG_VIDEO_RCAR_CSI2_LEGACY=y +CONFIG_VIDEO_RCAR_ISP_LEGACY=y +# CONFIG_VIDEO_RCAR_VIN is not set +# CONFIG_VIDEO_RCAR_CSI2 is not set +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_SCALE_CROP=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_SOC_CAMERA_MAX9286=y +CONFIG_SOC_CAMERA_TI9X4=y +CONFIG_SOC_CAMERA_OV106XX=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_HID_MULTITOUCH=y +CONFIG_SERIAL_SH_SCI_DMA=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_SPI_SLAVE=y +CONFIG_SPI_SLAVE_TIME=y +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y +CONFIG_SENSORS_LM63=y +CONFIG_RCAR_THERMAL=y +CONFIG_SH_ETH=y +CONFIG_BLK_DEV_NVME=m +CONFIG_SATA_ACARD_AHCI=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg index 34a385b..3af1cea 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg @@ -16,19 +16,23 @@ CONFIG_GPIO_PCA953X_IRQ=y CONFIG_VIDEO_ADV_DEBUG=y CONFIG_VIDEO_RCAR_VIN_LEGACY=y CONFIG_VIDEO_RCAR_CSI2_LEGACY=y +CONFIG_VIDEO_RCAR_ISP_LEGACY=y # CONFIG_VIDEO_RCAR_VIN is not set # CONFIG_VIDEO_RCAR_CSI2 is not set CONFIG_SOC_CAMERA=y CONFIG_SOC_CAMERA_SCALE_CROP=y CONFIG_SOC_CAMERA_PLATFORM=y -CONFIG_SOC_CAMERA_MAX9286_MAX9271=y -CONFIG_SOC_CAMERA_TI964_TI9X3=y -CONFIG_SOC_CAMERA_TI954_TI9X3=y +CONFIG_SOC_CAMERA_MAX9286=y +CONFIG_SOC_CAMERA_TI9X4=y CONFIG_SOC_CAMERA_OV106XX=y -CONFIG_VIDEO_RENESAS_IMR=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_UINPUT=y CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_HID_MULTITOUCH=y CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_UIO=y +CONFIG_SPI_SLAVE=y +CONFIG_SPI_SLAVE_TIME=y +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y +CONFIG_SENSORS_LM63=y +CONFIG_RCAR_THERMAL=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg new file mode 100644 index 0000000..bf4f35e --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg @@ -0,0 +1,24 @@ +CONFIG_ARCH_R8A7797=y +CONFIG_CAN=y +CONFIG_CAN_BCM=y +CONFIG_CAN_RAW=y +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_RCAR=y +CONFIG_CAN_RCAR_CANFD=y +CONFIG_DUMMY=y +CONFIG_VIDEO_ADV_DEBUG=y +CONFIG_VIDEO_RCAR_VIN_LEGACY=y +CONFIG_VIDEO_RCAR_CSI2_LEGACY=y +CONFIG_VIDEO_RCAR_ISP_LEGACY=y +# CONFIG_VIDEO_RCAR_VIN is not set +# CONFIG_VIDEO_RCAR_CSI2 is not set +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_SCALE_CROP=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_SOC_CAMERA_TI9X4=y +CONFIG_SOC_CAMERA_OV106XX=y +CONFIG_SERIAL_SH_SCI_DMA=y +CONFIG_SPI_SLAVE=y +CONFIG_SPI_SLAVE_TIME=y +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend index c4cad0f..e782c9f 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend @@ -2,6 +2,9 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" COMPATIBLE_MACHINE_eagle = "eagle" COMPATIBLE_MACHINE_v3msk = "v3msk" +COMPATIBLE_MACHINE_condor = "condor" +COMPATIBLE_MACHINE_v3mzf = "v3mzf" +COMPATIBLE_MACHINE_v3hsk = "v3hsk" BRANCH = "v4.9/rcar-3.5.9" SRCREV = "2c20c9881d53f1b5c7a3ebf55bb83ec15902d0d0" @@ -17,6 +20,8 @@ SRC_URI_remove = " \ SRC_URI_append = " \ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://hyperflash.cfg', '', d)} \ ${@base_conditional("SDHI_SEQ", "1", " file://sdhi_seq.cfg", "", d)} \ + file://qspi.cfg \ + file://imr.cfg \ file://0001-spi-sh-msiof-fixes.patch \ file://0002-spi-spidev-add-spi-gpio-into-spidev.patch \ file://0003-spi-spi-gpio-fix-CPOL-mode.patch \ @@ -50,7 +55,6 @@ SRC_URI_append = " \ file://0032-media-i2c-Add-ov5642-sensor.patch \ file://0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch \ file://0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch \ - file://0035-regulator-fixed-probe-after-i2c.patch \ file://0040-arm64-dts-renesas-add-ADAS-boards.patch \ file://0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch \ file://0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch \ @@ -61,9 +65,8 @@ SRC_URI_append = " \ ${@base_conditional("KF_ENABLE_MOST", "1", " file://0048-arm64-dts-renesas-ulcb-kf-enable-most.patch", "", d)} \ file://0049-clk-r8a779x-add-IMP-clock.patch \ file://0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch \ - ${@base_conditional("LVDSCAMERA_FIRST4_TYPE1", "1", " file://0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch", "", d)} \ - ${@base_conditional("LVDSCAMERA_SECOND4_TYPE1", "1", " file://0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch", "", d)} \ - ${@base_conditional("LVDSCAMERA_FIRST4_TYPE2", "1", " file://0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch", "", d)} \ + file://0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch \ + file://0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch \ file://0062-IIO-lsm9ds0-add-IMU-driver.patch \ file://0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch \ file://0064-ADV7511-limit-maximum-pixelclock.patch \ @@ -72,7 +75,7 @@ SRC_URI_append = " \ file://0068-drm-adv7511-use-smbus-to-retrieve-edid.patch \ file://0070-clk-clk-5p49x-add-5P49V5925-chip.patch \ file://0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch \ - file://0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch \ + file://0072-usb-hub-disable-autosuspend-for-SMSC-and-TI-hubs.patch \ file://0073-MOST-dim2-add-device-tree-support.patch \ file://0074-MOST-dim2-add-R-Car3-related-initialization.patch \ file://0075-MOST-core-fix-memory-allocation-at-arm64.patch \ @@ -81,14 +84,45 @@ SRC_URI_append = " \ file://0078-MOST-aim-fix-null-pointer-crash.patch \ file://0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch \ file://0082-gpio-pca953x-fix-interrupt-trigger.patch \ - file://0001-arm64-dts-renesas-preserve-drm-HDMI-connector-naming.patch \ - file://0001-arm64-dts-renesas-disable-r8a7796-hscif0-dma.patch \ -" - -SRC_URI_append_r8a7797 = " \ + file://0083-spi-Document-DT-bindings-for-SPI-controllers-in-slav.patch \ + file://0084-spi-core-Add-support-for-registering-SPI-slave-contr.patch \ + file://0085-spi-Document-SPI-slave-controller-support.patch \ + file://0086-spi-sh-msiof-Add-slave-mode-support.patch \ + file://0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch \ + file://0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch \ + file://0089-spi-Generalize-SPI-master-to-controller.patch \ + file://0090-pinctrl-sh-pfc-r8a7795-fix-ssi349_ctrl-name.patch \ file://0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch \ file://0104-media-vsp1-extend-DRM-VSP1-interface.patch \ file://0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch \ + file://0106-media-rcar-imr-Add-RSE-support.patch \ + file://0107-V3H-device-tree-Add-VIP-devices-IRQs.patch \ + file://0108-can-mcp251x-add-reset-gpio-support.patch \ + file://0109-ASoC-R-Car-fix-incorrect-behavior-with-PulseAudio.patch \ + file://0110-Renesas-clk-Add-RPC-clock-source.patch \ + file://0111-Renesas-r8a7798-Add-RPC-clock.patch \ + file://0112-Renesas-r8a7798-pinctrl-Add-RPC-pin-control.patch \ + file://0113-Renesas-RPC-Add-RPC-driver.patch \ + file://0114-R8A7798-dtsi-Add-RPC-node-to-dtsi.patch \ + file://0115-R8A7798-condor-dts-Add-qspi-flash.patch \ + file://0116-spi-nor-Add-s25fs512-flash-support.patch \ + file://0117-spi-nor-Add-flash-array-support.patch \ + file://0118-r8a7797-clk-Add-rpc-clock.patch \ + file://0119-r8a7797-pinctrl-Add-qspi-pins.patch \ + file://0120-r8a7797-dtsi-Add-rpc-node.patch \ + file://0121-r8a7797-eagle-dts-Add-spi-flash-node.patch \ + file://0122-r8a7797-v3msk-r8a7797-v3mzf-dts-Add-spi-flash-s25fs5.patch \ + file://0123-V3HSK-dts-Add-qspi-node.patch \ + file://0124-RPC-Hyperflash-Add-devicetree-support.patch \ + file://0125-r8a7797-pinctrl-Add-pin-function-for-hyperflash.patch \ + file://0126-r8a7798-pinctrl-Add-pin-function-for-hyperflash.patch \ + file://0127-IMR-UIO-Driver-initial-version.patch \ + file://0128-rcar_imr-v4l2-driver-Fix-module-support.patch \ + file://0129-Add-cropping-handling-to-VSP-alpha-planes.patch \ + file://0130-Add-RAW-sensors-MBUS-formats.patch \ + file://0131-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch \ + file://0001-arm64-dts-renesas-preserve-drm-HDMI-connector-naming.patch \ + file://0001-arm64-dts-renesas-disable-r8a7796-hscif0-dma.patch \ " SRC_URI_append_h3ulcb = " file://ulcb.cfg" @@ -96,6 +130,9 @@ SRC_URI_append_m3ulcb = " file://ulcb.cfg" SRC_URI_append_salvator-x = " file://salvator-x.cfg" SRC_URI_append_eagle = " file://eagle.cfg" SRC_URI_append_v3msk = " file://v3msk.cfg" +SRC_URI_append_condor = " file://condor.cfg" +SRC_URI_append_v3mzf = " file://v3mzf.cfg" +SRC_URI_append_v3hsk = " file://v3hsk.cfg" KERNEL_DEVICETREE_append_h3ulcb = " \ renesas/r8a7795-es1-h3ulcb-view.dtb \ @@ -126,13 +163,48 @@ KERNEL_DEVICETREE_append_salvator-x = " \ " KERNEL_DEVICETREE_append_eagle = " \ + renesas/r8a7797-es1-eagle.dtb \ + renesas/r8a7797-es1-eagle-function.dtb \ renesas/r8a7797-eagle.dtb \ renesas/r8a7797-eagle-function.dtb \ " KERNEL_DEVICETREE_append_v3msk = " \ + renesas/r8a7797-es1-v3msk.dtb \ + renesas/r8a7797-es1-v3msk-kf.dtb \ + renesas/r8a7797-es1-v3msk-vbm.dtb \ + renesas/r8a7797-es1-v3msk-vbm-v2.dtb \ + renesas/r8a7797-es1-v3msk-view.dtb \ renesas/r8a7797-v3msk.dtb \ renesas/r8a7797-v3msk-kf.dtb \ renesas/r8a7797-v3msk-vbm.dtb \ + renesas/r8a7797-v3msk-vbm-v2.dtb \ + renesas/r8a7797-v3msk-vbm-v2-isp.dtb \ renesas/r8a7797-v3msk-view.dtb \ " + +KERNEL_DEVICETREE_append_v3mzf = " \ + renesas/r8a7797-v3mzf.dtb \ +" + +KERNEL_DEVICETREE_append_condor = " \ + renesas/r8a7798-condor.dtb \ +" + +KERNEL_DEVICETREE_append_v3hsk = " \ + renesas/r8a7798-v3hsk.dtb \ + renesas/r8a7798-v3hsk-vbm.dtb \ + renesas/r8a7798-v3hsk-vbm-v2.dtb \ + renesas/r8a7798-v3hsk-vbm-v2-isp.dtb \ +" + +# Prefer V4L2 rcar_imr driver over UIO uio_imr +KERNEL_MODULE_AUTOLOAD += "rcar_imr" +KERNEL_MODULE_PROBECONF += "rcar_imr" +KERNEL_MODULE_PROBECONF += "uio_imr" +module_conf_uio_imr = 'blacklist uio_imr' + +# V3H VIP devices +KERNEL_MODULE_AUTOLOAD_append_r8a7798 += " uio_pdrv_genirq" +KERNEL_MODULE_PROBECONF_append_r8a7798 += " uio_pdrv_genirq" +module_conf_uio_pdrv_genirq_r8a7798 = 'options uio_pdrv_genirq of_id="generic-uio"' |