1diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig 2index ceaf87c4d..ea05aa4b4 100644 3--- a/arch/arm/Kconfig 4+++ b/arch/arm/Kconfig 5@@ -322,7 +322,7 @@ config ARCH_MULTIPLATFORM 6 select ARCH_SELECT_MEMORY_MODEL 7 select ARM_HAS_SG_CHAIN 8 select ARM_PATCH_PHYS_VIRT 9- select AUTO_ZRELADDR 10+ #select AUTO_ZRELADDR 11 select TIMER_OF 12 select COMMON_CLK 13 select GENERIC_CLOCKEVENTS 14@@ -650,6 +650,8 @@ source "arch/arm/mach-highbank/Kconfig" 15 16 source "arch/arm/mach-hisi/Kconfig" 17 18+source "arch/arm/mach-hibvt/Kconfig" 19+ 20 source "arch/arm/mach-imx/Kconfig" 21 22 source "arch/arm/mach-integrator/Kconfig" 23diff --git a/arch/arm/Makefile b/arch/arm/Makefile 24index cb7c6b02f..95308da9c 100644 25--- a/arch/arm/Makefile 26+++ b/arch/arm/Makefile 27@@ -182,6 +182,7 @@ machine-$(CONFIG_ARCH_FOOTBRIDGE) += footbridge 28 machine-$(CONFIG_ARCH_GEMINI) += gemini 29 machine-$(CONFIG_ARCH_HIGHBANK) += highbank 30 machine-$(CONFIG_ARCH_HISI) += hisi 31+machine-$(CONFIG_ARCH_HISI_BVT) += hibvt 32 machine-$(CONFIG_ARCH_INTEGRATOR) += integrator 33 machine-$(CONFIG_ARCH_IOP32X) += iop32x 34 machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx 35@@ -270,6 +271,10 @@ KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs)) 36 endif 37 endif 38 39+ifeq ($(CONFIG_ARCH_HISI_BVT),y) 40+KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs)) 41+endif 42+ 43 export TEXT_OFFSET GZFLAGS MMUEXT 44 45 core-y += arch/arm/ 46diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile 47index 0b3cd7a33..763d37e86 100644 48--- a/arch/arm/boot/Makefile 49+++ b/arch/arm/boot/Makefile 50@@ -16,6 +16,8 @@ OBJCOPYFLAGS :=-O binary -R .comment -S 51 ifneq ($(MACHINE),) 52 include $(MACHINE)/Makefile.boot 53 endif 54+include $(srctree)/arch/arm/mach-hibvt/Makefile.boot 55+include $(srctree)/arch/arm/boot/dts/Makefile 56 57 # Note: the following conditions must always be true: 58 # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) 59@@ -24,10 +26,12 @@ endif 60 ZRELADDR := $(zreladdr-y) 61 PARAMS_PHYS := $(params_phys-y) 62 INITRD_PHYS := $(initrd_phys-y) 63+DTB_OBJS ?= $(dtb-y) 64+DTB_OBJS_FULL := $(addprefix $(obj)/dts/,$(DTB_OBJS)) 65 66 export ZRELADDR INITRD_PHYS PARAMS_PHYS 67 68-targets := Image zImage xipImage bootpImage uImage 69+targets := Image zImage xipImage bootpImage uImage zImage-dtb 70 71 ifeq ($(CONFIG_XIP_KERNEL),y) 72 73@@ -66,6 +70,10 @@ $(obj)/compressed/vmlinux: $(obj)/Image FORCE 74 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE 75 $(call if_changed,objcopy) 76 77+$(obj)/zImage-dtb: $(obj)/zImage $(DTB_OBJS_FULL) FORCE 78+ @cat $(obj)/zImage $(DTB_OBJS_FULL) > $@ 79+ @$(kecho) ' Kernel: $@ is ready' 80+ 81 endif 82 83 ifneq ($(LOADADDR),) 84@@ -86,7 +94,7 @@ if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \ 85 false; \ 86 fi 87 88-$(obj)/uImage: $(obj)/zImage FORCE 89+$(obj)/uImage: $(obj)/zImage-dtb FORCE 90 @$(check_for_multiple_loadaddr) 91 $(call if_changed,uimage) 92 93diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile 94index ce66ffd5a..a84efd2d6 100644 95--- a/arch/arm/boot/dts/Makefile 96+++ b/arch/arm/boot/dts/Makefile 97@@ -239,6 +239,10 @@ dtb-$(CONFIG_ARCH_HISI) += \ 98 hi3519-demb.dtb 99 dtb-$(CONFIG_ARCH_HIX5HD2) += \ 100 hisi-x5hd2-dkb.dtb 101+ 102+dtb-$(CONFIG_ARCH_HI3516DV300) += \ 103+ hi3516dv300-demb.dtb 104+ 105 dtb-$(CONFIG_ARCH_INTEGRATOR) += \ 106 integratorap.dtb \ 107 integratorap-im-pd1.dtb \ 108@@ -1408,3 +1412,4 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ 109 aspeed-bmc-opp-zaius.dtb \ 110 aspeed-bmc-portwell-neptune.dtb \ 111 aspeed-bmc-quanta-q71l.dtb 112+ 113diff --git a/arch/arm/boot/dts/hi3516dv300-demb.dts b/arch/arm/boot/dts/hi3516dv300-demb.dts 114new file mode 100644 115index 000000000..bbe67651e 116--- /dev/null 117+++ b/arch/arm/boot/dts/hi3516dv300-demb.dts 118@@ -0,0 +1,270 @@ 119+/* 120+ * Copyright (c) 2013-2014 Linaro Ltd. 121+ * Copyright (c) 2015-2017 HiSilicon Technologies Co., Ltd. 122+ * 123+ * This program is free software; you can redistribute it and/or modify it 124+ * under the terms of the GNU General Public License as published by the 125+ * Free Software Foundation; either version 2 of the License, or (at your 126+ * option) any later version. 127+ * 128+ * This program is distributed in the hope that it will be useful, 129+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 130+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 131+ * GNU General Public License for more details. 132+ * 133+ * You should have received a copy of the GNU General Public License 134+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 135+ * 136+ */ 137+ 138+/dts-v1/; 139+#include "hi3516dv300.dtsi" 140+#include "autoconf.h" 141+ 142+/ { 143+ model = "Hisilicon HI3516DV300 DEMO Board"; 144+ compatible = "hisilicon,hi3516dv300"; 145+ 146+ memory { 147+ device_type = "memory"; 148+ reg = <0x82000000 0x20000000>; 149+ }; 150+ firmware { 151+ android { 152+ compatible = "android,firmware"; 153+ fstab { 154+ compatible = "android,fstab"; 155+ // delete for system as root 156+ /*system { 157+ compatible = "android,system"; 158+ dev = "/dev/block/platform/soc/f9830000.himciv200.MMC/by-name/system"; 159+ type = "ext4"; 160+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; 161+ fsmgr_flags = "wait"; 162+ };*/ 163+ vendor { 164+ compatible = "android,vendor"; 165+ //dev = "mmcblk0p4"; 166+ //dev = "/dev/block/by-name/vendor"; 167+ //dev = "/dev/block/platform/soc/100f0000.eMMC/by-name/vendor"; 168+ //dev = "/dev/block/platform/soc/10100000.eMMC/by-name/vendor"; 169+ dev = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor"; 170+ //dev = "/dev/block/platform/soc/100f0000.eMMC/mmcblk0p4"; 171+ //dev = "/dev/block/platform/soc/f9830000.himciv200.MMC/by-name/vendor"; 172+ type = "ext4"; 173+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; 174+ fsmgr_flags = "wait"; 175+ }; 176+ }; 177+ }; 178+ }; 179+}; 180+ 181+&uart0 { 182+ status = "okay"; 183+}; 184+#ifndef CONFIG_ARCH_HISI_BVT_AMP 185+&uart1 { 186+ status = "okay"; 187+}; 188+ 189+&i2c_bus0 { 190+ status = "okay"; 191+ clock-frequency = <100000>; 192+}; 193+ 194+&i2c_bus1 { 195+ status = "okay"; 196+ clock-frequency = <100000>; 197+}; 198+ 199+&i2c_bus2 { 200+ status = "okay"; 201+ clock-frequency = <100000>; 202+}; 203+ 204+&i2c_bus3 { 205+ status = "okay"; 206+ clock-frequency = <100000>; 207+}; 208+ 209+&i2c_bus4 { 210+ status = "okay"; 211+ clock-frequency = <100000>; 212+}; 213+ 214+&i2c_bus5 { 215+ status = "okay"; 216+ clock-frequency = <100000>; 217+}; 218+ 219+&i2c_bus6 { 220+ status = "okay"; 221+ clock-frequency = <100000>; 222+}; 223+ 224+&i2c_bus7 { 225+ status = "okay"; 226+ clock-frequency = <100000>; 227+}; 228+ 229+&spi_bus0{ 230+ status = "okay"; 231+ num-cs = <1>; 232+ 233+ spidev@0 { 234+ compatible = "rohm,dh2228fv"; 235+ reg = <0>; 236+ pl022,interface = <0>; 237+ pl022,com-mode = <0>; 238+ spi-max-frequency = <25000000>; 239+ }; 240+}; 241+&spi_bus1{ 242+ status = "okay"; 243+ num-cs = <2>; 244+ 245+ spidev@0 { 246+ compatible = "rohm,dh2228fv"; 247+ reg = <0>; 248+ pl022,interface = <0>; 249+ pl022,com-mode = <0>; 250+ spi-max-frequency = <25000000>; 251+ }; 252+ spidev@1 { 253+ compatible = "rohm,dh2228fv"; 254+ reg = <1>; 255+ pl022,interface = <0>; 256+ pl022,com-mode = <0>; 257+ spi-max-frequency = <25000000>; 258+ }; 259+}; 260+&spi_bus2{ 261+ status = "okay"; 262+ num-cs = <1>; 263+ 264+ spidev@0 { 265+ compatible = "rohm,dh2228fv"; 266+ reg = <0>; 267+ pl022,interface = <0>; 268+ pl022,com-mode = <0>; 269+ spi-max-frequency = <25000000>; 270+ }; 271+}; 272+#endif 273+ 274+&mdio0 { 275+ hisilicon,phy-reset-delays-us = <10000 20000 150000>; 276+ phy0: ethernet-phy@1 { 277+ reg = <1>; 278+ }; 279+}; 280+ 281+&hisi_femac0 { 282+ mac-address = [00 00 00 00 00 00]; 283+ phy-mode = "rmii"; 284+ phy-handle = <&phy0>; 285+ status = "okay"; 286+}; 287+ 288+&hisfc { 289+ hi_sfc { 290+ compatible = "jedec,spi-nor"; 291+ reg = <0>; 292+ spi-max-frequency = <160000000>; 293+ }; 294+}; 295+ 296+&hisnfc { 297+ hinand { 298+ compatible = "jedec,spi-nand"; 299+ reg = <0>; 300+ spi-max-frequency = <160000000>; 301+ }; 302+}; 303+ 304+&mmc0 { 305+#ifdef CONFIG_MTD 306+ status = "disabled"; 307+#else 308+ status = "okay"; 309+#endif 310+}; 311+ 312+&mmc1 { 313+ status = "okay"; 314+}; 315+ 316+&mmc2 { 317+ status = "okay"; 318+}; 319+ 320+&watchdog { 321+ status = "okay"; 322+}; 323+ 324+&pwm0 { 325+ status = "okay"; 326+}; 327+ 328+&pwm1 { 329+ status = "okay"; 330+}; 331+ 332+&hidmac { 333+ status = "disabled"; 334+}; 335+ 336+#ifdef CONFIG_HIEDMACV310 337+&hiedmacv310_0 { 338+ status = "okay"; 339+}; 340+#endif 341+ 342+&gpio_chip0 { 343+ status = "okay"; 344+}; 345+ 346+&gpio_chip1 { 347+ status = "okay"; 348+}; 349+ 350+&gpio_chip2 { 351+ status = "okay"; 352+}; 353+ 354+&gpio_chip3 { 355+ status = "okay"; 356+}; 357+ 358+&gpio_chip4 { 359+ status = "okay"; 360+}; 361+ 362+&gpio_chip5 { 363+ status = "okay"; 364+}; 365+ 366+&gpio_chip6 { 367+ status = "okay"; 368+}; 369+ 370+&gpio_chip7 { 371+ status = "okay"; 372+}; 373+ 374+&gpio_chip8 { 375+ status = "okay"; 376+}; 377+ 378+&gpio_chip9 { 379+ status = "okay"; 380+}; 381+ 382+&gpio_chip10 { 383+ status = "okay"; 384+}; 385+ 386+&gpio_chip11 { 387+ status = "okay"; 388+}; 389diff --git a/arch/arm/boot/dts/hi3516dv300.dtsi b/arch/arm/boot/dts/hi3516dv300.dtsi 390new file mode 100644 391index 000000000..c58f5b1ad 392--- /dev/null 393+++ b/arch/arm/boot/dts/hi3516dv300.dtsi 394@@ -0,0 +1,906 @@ 395+/* 396+ * Copyright (c) 2013-2014 Linaro Ltd. 397+ * Copyright (c) 2015-2017 HiSilicon Technologies Co., Ltd. 398+ * 399+ * This program is free software; you can redistribute it and/or modify it 400+ * under the terms of the GNU General Public License as published by the 401+ * Free Software Foundation; either version 2 of the License, or (at your 402+ * option) any later version. 403+ * 404+ * This program is distributed in the hope that it will be useful, 405+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 406+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 407+ * GNU General Public License for more details. 408+ * 409+ * You should have received a copy of the GNU General Public License 410+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 411+ * 412+ */ 413+#include "autoconf.h" 414+#include "skeleton.dtsi" 415+#include "clock/hi3516dv300-clock.h" 416+/ { 417+ aliases { 418+ serial0 = &uart0; 419+#ifndef CONFIG_ARCH_HISI_BVT_AMP 420+ i2c0 = &i2c_bus0; 421+ i2c1 = &i2c_bus1; 422+ i2c2 = &i2c_bus2; 423+ i2c3 = &i2c_bus3; 424+#endif 425+ i2c4 = &i2c_bus4; 426+ i2c5 = &i2c_bus5; 427+ i2c6 = &i2c_bus6; 428+ i2c7 = &i2c_bus7; 429+#ifndef CONFIG_ARCH_HISI_BVT_AMP 430+ spi0 = &spi_bus0; 431+ spi1 = &spi_bus1; 432+ spi2 = &spi_bus2; 433+#endif 434+ gpio0 = &gpio_chip0; 435+ gpio1 = &gpio_chip1; 436+ gpio2 = &gpio_chip2; 437+ gpio3 = &gpio_chip3; 438+ gpio4 = &gpio_chip4; 439+ gpio5 = &gpio_chip5; 440+ gpio6 = &gpio_chip6; 441+ gpio7 = &gpio_chip7; 442+ gpio8 = &gpio_chip8; 443+ gpio9 = &gpio_chip9; 444+ gpio10 = &gpio_chip10; 445+ gpio11 = &gpio_chip11; 446+ }; 447+ 448+ cpus { 449+ #address-cells = <1>; 450+ #size-cells = <0>; 451+ enable-method = "hisilicon,hi3516dv300"; 452+ 453+ cpu@0 { 454+ device_type = "cpu"; 455+ compatible = "arm,cortex-a7"; 456+ clock-frequency = <HI3516DV300_FIXED_1000M>; 457+ reg = <0>; 458+ }; 459+#ifndef CONFIG_ARCH_HISI_BVT_AMP 460+ cpu@1 { 461+ device_type = "cpu"; 462+ compatible = "arm,cortex-a7"; 463+ clock-frequency = <HI3516DV300_FIXED_1000M>; 464+ reg = <1>; 465+ }; 466+#endif 467+ }; 468+ 469+ clock: clock@12010000 { 470+ compatible = "hisilicon,hi3516dv300-clock"; 471+ #address-cells = <1>; 472+ #size-cells = <1>; 473+ #clock-cells = <1>; 474+ #reset-cells = <2>; 475+ reg = <0x12010000 0x1000>; 476+ }; 477+ 478+ gic: interrupt-controller@10300000 { 479+ compatible = "arm,cortex-a7-gic"; 480+ #interrupt-cells = <3>; 481+ #address-cells = <0>; 482+ interrupt-controller; 483+ /* gic dist base, gic cpu base , no virtual support */ 484+ reg = <0x10301000 0x1000>, <0x10302000 0x100>; 485+ }; 486+ 487+ syscounter { 488+ compatible = "arm,armv7-timer"; 489+ interrupt-parent = <&gic>; 490+ interrupts = <1 13 0xf08>, 491+ <1 14 0xf08>; 492+ clock-frequency = <50000000>; 493+ }; 494+ 495+ soc { 496+ #address-cells = <1>; 497+ #size-cells = <1>; 498+ compatible = "simple-bus"; 499+ interrupt-parent = <&gic>; 500+ ranges; 501+ 502+ clk_3m: clk_3m { 503+ compatible = "fixed-clock"; 504+ #clock-cells = <0>; 505+ clock-frequency = <3000000>; 506+ }; 507+ 508+ clk_apb: clk_apb { 509+ compatible = "fixed-clock"; 510+ #clock-cells = <0>; 511+ clock-frequency = <50000000>; 512+ }; 513+ 514+ pmu { 515+ compatible = "arm,cortex-a7-pmu"; 516+ interrupts = <0 54 4>; 517+ }; 518+#ifdef CONFIG_HIEDMACV310 519+ hiedmacv310_0: hiedma-controller@10060000 { 520+ compatible = "hisilicon,hiedmacv310"; 521+ reg = <0x10060000 0x1000>; 522+ interrupts = <0 28 4>; 523+ clocks = <&clock HI3516DV300_DMAC_CLK>, <&clock HI3516DV300_DMAC_AXICLK>; 524+ clock-names = "apb_pclk", "axi_aclk"; 525+ #clock-cells = <2>; 526+ resets = <&clock 0x194 0>; 527+ reset-names = "dma-reset"; 528+ dma-requests = <32>; 529+ dma-channels = <8>; 530+ devid = <0>; 531+ #dma-cells = <2>; 532+ status = "disabled"; 533+ }; 534+#endif 535+#ifdef CONFIG_HIEDMAC 536+ hiedmacv310_0: hiedma-controller@10060000 { 537+ compatible = "hisilicon,hiedmacv310_n"; 538+ reg = <0x10060000 0x1000>; 539+ interrupts = <0 28 4>; 540+ clocks = <&clock HI3516DV300_DMAC_CLK>, <&clock HI3516DV300_DMAC_AXICLK>; 541+ clock-names = "apb_pclk", "axi_aclk"; 542+ #clock-cells = <2>; 543+ resets = <&clock 0x194 0>; 544+ reset-names = "dma-reset"; 545+ dma-requests = <32>; 546+ dma-channels = <8>; 547+ devid = <0>; 548+ #dma-cells = <2>; 549+ status = "disabled"; 550+ }; 551+#endif 552+ 553+ sysctrl: system-controller@12020000 { 554+ compatible = "hisilicon,sysctrl"; 555+ reg = <0x12020000 0x1000>; 556+ reboot-offset = <0x4>; 557+ #clock-cells = <1>; 558+ }; 559+ 560+ amba { 561+ #address-cells = <1>; 562+ #size-cells = <1>; 563+ compatible = "arm,amba-bus"; 564+ ranges; 565+ 566+ timer@hisp804 { 567+ compatible = "hisilicon,hisp804"; 568+ /* timer0 & timer1 & timer2 */ 569+ reg = <0x12000000 0x20>, /* clocksource */ 570+ <0x12000020 0x20>, /* local timer for each cpu */ 571+ <0x12001000 0x20>; 572+ interrupts = <0 1 4>, /* irq of local timer */ 573+ <0 2 4>; 574+ clocks = <&clock HI3516DV300_FIXED_3M>, 575+ <&clock HI3516DV300_FIXED_3M>, 576+ <&clock HI3516DV300_FIXED_3M>; 577+ clock-names = "timer0", "timer1", "timer2"; 578+ }; 579+ 580+ dual_timer2: dual_timer@12002000 { 581+ compatible = "arm,sp804", "arm,primecell"; 582+ /* timer4 & timer5 */ 583+ interrupts = <0 3 4>; 584+ reg = <0x12002000 0x1000>; 585+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; 586+ clock-names = "timer20", "timer21", "apb_pclk"; 587+ status = "disabled"; 588+ }; 589+ 590+ watchdog: watchdog@12051000 { 591+ compatible = "arm,sp805-wdt", "arm,primecell"; 592+ arm,primecell-periphid = <0x00141805>; 593+ reg = <0x12051000 0x1000>; 594+ clocks = <&clk_3m>,<&clk_apb>; 595+ clock-names = "wdog_clk", "apb_pclk"; 596+ status = "disabled"; 597+ }; 598+ 599+ uart0: uart@120a0000 { 600+ compatible = "arm,pl011", "arm,primecell"; 601+ reg = <0x120a0000 0x1000>; 602+ interrupts = <0 6 4>; 603+ clocks = <&clock HI3516DV300_UART0_CLK>; 604+ clock-names = "apb_pclk"; 605+ status = "disabled"; 606+ }; 607+#ifndef CONFIG_ARCH_HISI_BVT_AMP 608+ uart1: uart@120a1000 { 609+ compatible = "arm,pl011", "arm,primecell"; 610+ reg = <0x120a1000 0x1000>; 611+ interrupts = <0 7 4>; 612+ clocks = <&clock HI3516DV300_UART1_CLK>; 613+ clock-names = "apb_pclk"; 614+#ifdef CONFIG_HIEDMACV310 615+ dmas = <&hiedmacv310_0 19 19>, <&hiedmacv310_0 18 18>; 616+ dma-names = "tx","rx"; 617+#endif 618+ status = "disabled"; 619+ }; 620+#endif 621+ uart2: uart@120a2000 { 622+ compatible = "arm,pl011", "arm,primecell"; 623+ reg = <0x120a2000 0x1000>; 624+ interrupts = <0 8 4>; 625+ clocks = <&clock HI3516DV300_UART2_CLK>; 626+ clock-names = "apb_pclk"; 627+#ifdef CONFIG_HIEDMACV310 628+ dmas = <&hiedmacv310_0 21 21>, <&hiedmacv310_0 20 20>; 629+ dma-names = "tx","rx"; 630+#endif 631+ status = "disabled"; 632+ }; 633+ 634+ uart3: uart@120a3000 { 635+ compatible = "arm,pl011", "arm,primecell"; 636+ reg = <0x120a3000 0x1000>; 637+ interrupts = <0 9 4>; 638+ clocks = <&clock HI3516DV300_UART3_CLK>; 639+ clock-names = "apb_pclk"; 640+#ifdef CONFIG_HIEDMACV310 641+ dmas = <&hiedmacv310_0 23 23>, <&hiedmacv310_0 22 22>; 642+ dma-names = "tx","rx"; 643+#endif 644+ status = "disabled"; 645+ }; 646+ 647+ uart4: uart@120a4000 { 648+ compatible = "arm,pl011", "arm,primecell"; 649+ reg = <0x120a4000 0x1000>; 650+ interrupts = <0 10 4>; 651+ clocks = <&clock HI3516DV300_UART4_CLK>; 652+ clock-names = "apb_pclk"; 653+#ifdef CONFIG_HIEDMACV310 654+ dmas = <&hiedmacv310_0 25 25>, <&hiedmacv310_0 24 24>; 655+ dma-names = "tx","rx"; 656+#endif 657+ status = "disabled"; 658+ }; 659+ 660+ }; 661+ 662+#ifndef CONFIG_ARCH_HISI_BVT_AMP 663+ i2c_bus0: i2c@120b0000 { 664+ compatible = "hisilicon,hibvt-i2c"; 665+ reg = <0x120b0000 0x1000>; 666+ clocks = <&clock HI3516DV300_I2C0_CLK>; 667+#ifdef CONFIG_HIEDMAC 668+ dmas = <&hiedmacv310_0 1 1>, <&hiedmacv310_0 0 0>; 669+ dma-names = "tx","rx"; 670+#endif 671+ status = "disabled"; 672+ }; 673+ 674+ i2c_bus1: i2c@120b1000 { 675+ compatible = "hisilicon,hibvt-i2c"; 676+ reg = <0x120b1000 0x1000>; 677+ clocks = <&clock HI3516DV300_I2C1_CLK>; 678+#ifdef CONFIG_HIEDMAC 679+ dmas = <&hiedmacv310_0 3 3>, <&hiedmacv310_0 2 2>; 680+ dma-names = "tx","rx"; 681+#endif 682+ status = "disabled"; 683+ }; 684+ 685+ i2c_bus2: i2c@120b2000 { 686+ compatible = "hisilicon,hibvt-i2c"; 687+ reg = <0x120b2000 0x1000>; 688+ clocks = <&clock HI3516DV300_I2C2_CLK>; 689+#ifdef CONFIG_HIEDMAC 690+ dmas = <&hiedmacv310_0 5 5>, <&hiedmacv310_0 4 4>; 691+ dma-names = "tx","rx"; 692+#endif 693+ status = "disabled"; 694+ }; 695+ 696+ i2c_bus3: i2c@120b3000 { 697+ compatible = "hisilicon,hibvt-i2c"; 698+ reg = <0x120b3000 0x1000>; 699+ clocks = <&clock HI3516DV300_I2C3_CLK>; 700+#ifdef CONFIG_HIEDMAC 701+ dmas = <&hiedmacv310_0 7 7>, <&hiedmacv310_0 6 6>; 702+ dma-names = "tx","rx"; 703+#endif 704+ status = "disabled"; 705+ }; 706+#endif 707+ i2c_bus4: i2c@120b4000 { 708+ compatible = "hisilicon,hibvt-i2c"; 709+ reg = <0x120b4000 0x1000>; 710+ clocks = <&clock HI3516DV300_I2C4_CLK>; 711+#ifdef CONFIG_HIEDMAC 712+ dmas = <&hiedmacv310_0 9 9>, <&hiedmacv310_0 8 8>; 713+ dma-names = "tx","rx"; 714+#endif 715+ status = "disabled"; 716+ }; 717+ i2c_bus5: i2c@120b5000 { 718+ compatible = "hisilicon,hibvt-i2c"; 719+ reg = <0x120b5000 0x1000>; 720+ clocks = <&clock HI3516DV300_I2C5_CLK>; 721+#ifdef CONFIG_HIEDMAC 722+ dmas = <&hiedmacv310_0 11 11>, <&hiedmacv310_0 10 10>; 723+ dma-names = "tx","rx"; 724+#endif 725+ status = "disabled"; 726+ }; 727+ 728+ i2c_bus6: i2c@120b6000 { 729+ compatible = "hisilicon,hibvt-i2c"; 730+ reg = <0x120b6000 0x1000>; 731+ clocks = <&clock HI3516DV300_I2C6_CLK>; 732+#ifdef CONFIG_HIEDMAC 733+ dmas = <&hiedmacv310_0 13 13>, <&hiedmacv310_0 12 12>; 734+ dma-names = "tx","rx"; 735+#endif 736+ status = "disabled"; 737+ }; 738+ 739+ i2c_bus7: i2c@120b7000 { 740+ compatible = "hisilicon,hibvt-i2c"; 741+ reg = <0x120b7000 0x1000>; 742+ clocks = <&clock HI3516DV300_I2C7_CLK>; 743+#ifdef CONFIG_HIEDMAC 744+ dmas = <&hiedmacv310_0 15 15>, <&hiedmacv310_0 14 14>; 745+ dma-names = "tx","rx"; 746+#endif 747+ status = "disabled"; 748+ }; 749+ 750+#ifndef CONFIG_ARCH_HISI_BVT_AMP 751+ spi_bus0: spi@120c0000 { 752+ compatible = "arm,pl022", "arm,primecell"; 753+ arm,primecell-periphid = <0x00800022>; 754+ reg = <0x120c0000 0x1000>; 755+ interrupts = <0 68 4>; 756+ clocks = <&clock HI3516DV300_SPI0_CLK>; 757+ clock-names = "apb_pclk"; 758+ #address-cells = <1>; 759+ #size-cells = <0>; 760+#ifdef CONFIG_HIEDMACV310 761+ dmas = <&hiedmacv310_0 27 27>, <&hiedmacv310_0 26 26>; 762+ dma-names = "tx","rx"; 763+#endif 764+ status = "disabled"; 765+ }; 766+ 767+ spi_bus1: spi@120c1000 { 768+ compatible = "arm,pl022", "arm,primecell"; 769+ arm,primecell-periphid = <0x00800022>; 770+ reg = <0x120c1000 0x1000>, <0x12030000 0x4>; 771+ interrupts = <0 69 4>; 772+ clocks = <&clock HI3516DV300_SPI1_CLK>; 773+ clock-names = "apb_pclk"; 774+ #address-cells = <1>; 775+ #size-cells = <0>; 776+ num-cs = <2>; 777+ hisi,spi_cs_sb = <2>; 778+ hisi,spi_cs_mask_bit = <0x4>;//0100 779+#ifdef CONFIG_HIEDMACV310 780+ dmas = <&hiedmacv310_0 29 29>, <&hiedmacv310_0 28 28>; 781+ dma-names = "tx","rx"; 782+#endif 783+ status = "disabled"; 784+ }; 785+ 786+ spi_bus2: spi@120c2000 { 787+ compatible = "arm,pl022", "arm,primecell"; 788+ arm,primecell-periphid = <0x00800022>; 789+ reg = <0x120c2000 0x1000>; 790+ interrupts = <0 70 4>; 791+ clocks = <&clock HI3516DV300_SPI2_CLK>; 792+ clock-names = "apb_pclk"; 793+ #address-cells = <1>; 794+ #size-cells = <0>; 795+#ifdef CONFIG_HIEDMACV310 796+ dmas = <&hiedmacv310_0 31 31>, <&hiedmacv310_0 30 30>; 797+ dma-names = "tx","rx"; 798+#endif 799+ status = "disabled"; 800+ }; 801+#endif 802+ 803+ ipcm: ipcm@045E0000 { 804+ compatible = "hisilicon,ipcm-interrupt"; 805+ interrupt-parent = <&gic>; 806+ interrupts = <0 10 4>; 807+ reg = <0x10300000 0x4000>; 808+ status = "okay"; 809+ }; 810+ 811+ mdio0: mdio@10011100 { 812+ compatible = "hisilicon,hisi-femac-mdio"; 813+ reg = <0x10011100 0x10>; 814+ clocks = <&clock HI3516DV300_ETH0_CLK>; 815+ clock-names = "mdio"; 816+ assigned-clocks = <&clock HI3516DV300_ETH0_CLK>; 817+ assigned-clock-rates = <54000000>; 818+ resets = <&clock 0x16c 3>; 819+ reset-names = "external-phy"; 820+ #address-cells = <1>; 821+ #size-cells = <0>; 822+ }; 823+ 824+ hisi_femac0: ethernet@10010000 { 825+ compatible = "hisilicon,hi3516dv300-femac", 826+ "hisilicon,hisi-femac-v2"; 827+ reg = <0x10010000 0x1000>,<0x10011300 0x200>; 828+ interrupts = <0 32 4>; 829+ clocks = <&clock HI3516DV300_ETH0_CLK>; 830+ resets = <&clock 0x16c 0>; 831+ reset-names = "mac"; 832+ }; 833+ 834+ fmc: flash-memory-controller@10000000 { 835+ compatible = "hisilicon,hisi-fmc"; 836+ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; 837+ reg-names = "control", "memory"; 838+ clocks = <&clock HI3516DV300_FMC_CLK>; 839+ max-dma-size = <0x2000>; 840+ #address-cells = <1>; 841+ #size-cells = <0>; 842+ 843+ hisfc:spi-nor@0 { 844+ compatible = "hisilicon,fmc-spi-nor"; 845+ assigned-clocks = <&clock HI3516DV300_FMC_CLK>; 846+ assigned-clock-rates = <24000000>; 847+ #address-cells = <1>; 848+ #size-cells = <0>; 849+ }; 850+ 851+ hisnfc:spi-nand@0 { 852+ compatible = "hisilicon,fmc-spi-nand"; 853+ assigned-clocks = <&clock HI3516DV300_FMC_CLK>; 854+ assigned-clock-rates = <24000000>; 855+ #address-cells = <1>; 856+ #size-cells = <0>; 857+ }; 858+ }; 859+ 860+ mmc0: himci.eMMC@0x10100000 { 861+ compatible = "hisilicon,hi3516dv300-himci"; 862+ reg = <0x10100000 0x1000>; 863+ interrupts = <0 64 4>; 864+ clocks = <&clock HI3516DV300_MMC0_CLK>; 865+ clock-names = "mmc_clk"; 866+ resets = <&clock 0x148 0>; 867+ reset-names = "mmc_reset"; 868+ max-frequency = <100000000>; 869+ bus-width = <4>; 870+ cap-mmc-highspeed; 871+ cap-mmc-hw-reset; 872+ devid = <0>; 873+ status = "disabled"; 874+ }; 875+ 876+ mmc1: himci.SD@0x100f0000 { 877+ compatible = "hisilicon,hi3516dv300-himci"; 878+ reg = <0x100f0000 0x1000>; 879+ interrupts = <0 30 4>; 880+ clocks = <&clock HI3516DV300_MMC1_CLK>; 881+ clock-names = "mmc_clk"; 882+ resets = <&clock 0x160 0>; 883+ reset-names = "mmc_reset"; 884+ max-frequency = <100000000>; 885+ bus-width = <4>; 886+ cap-sd-highspeed; 887+ sd-uhs-sdr12; 888+ sd-uhs-sdr25; 889+ sd-uhs-sdr50; 890+ sd-uhs-sdr104; 891+ full-pwr-cycle; 892+ devid = <1>; 893+ status = "disabled"; 894+ }; 895+ 896+ mmc2: himci.SD@0x10020000 { 897+ compatible = "hisilicon,hi3516dv300-himci"; 898+ reg = <0x10020000 0x1000>; 899+ interrupts = <0 31 4>; 900+ clocks = <&clock HI3516DV300_MMC2_CLK>; 901+ clock-names = "mmc_clk"; 902+ resets = <&clock 0x154 0>; 903+ reset-names = "mmc_reset"; 904+ max-frequency = <100000000>; 905+ bus-width = <4>; 906+ cap-sd-highspeed; 907+ cap-sdio-irq; 908+ full-pwr-cycle; 909+ devid = <2>; 910+ status = "disabled"; 911+ }; 912+ 913+ hidmac: hidma-controller@10060000 { 914+ compatible = "hisilicon,hisi-dmac"; 915+ reg = <0x10060000 0x1000>; 916+ interrupts = <0 28 4>; 917+ clocks = <&clock HI3516DV300_DMAC_CLK>; 918+ clock-names = "dmac_clk"; 919+ resets = <&clock 0xc8 4>; 920+ reset-names = "dma-reset"; 921+ #dma-cells = <2>; 922+ status = "disabled"; 923+ }; 924+ 925+ usb_phy: phy { 926+ compatible = "hisilicon,hisi-usb-phy"; 927+ reg = <0x12010000 0x1000>; 928+ #phy-cells = <0>; 929+ }; 930+ 931+#ifdef CONFIG_USB_DRD0_IN_HOST 932+ xhci_0@0x100e0000 { 933+ compatible = "generic-xhci"; 934+ reg = <0x100e0000 0x10000>; 935+ interrupts = <0 27 4>; 936+ usb2-lpm-disable; 937+ }; 938+#endif 939+#ifdef CONFIG_USB_DRD0_IN_DEVICE 940+ hidwc3_0@0x100e0000 { 941+ compatible = "snps,dwc3"; 942+ reg = <0x100e0000 0x10000>; 943+ interrupts = <0 27 4>; 944+ interrupt-names = "peripheral"; 945+ maximum-speed = "high-speed"; 946+ dr_mode = "otg"; 947+ }; 948+#endif 949+ gpio_chip0: gpio_chip@120d0000 { 950+ compatible = "arm,pl061", "arm,primecell"; 951+ reg = <0x120d0000 0x1000>; 952+ interrupts = <0 16 4>; 953+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 954+ clock-names = "apb_pclk"; 955+ #gpio-cells = <2>; 956+ status = "disabled"; 957+ }; 958+ 959+ gpio_chip1: gpio_chip@120d1000 { 960+ compatible = "arm,pl061", "arm,primecell"; 961+ reg = <0x120d1000 0x1000>; 962+ interrupts = <0 17 4>; 963+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 964+ clock-names = "apb_pclk"; 965+ #gpio-cells = <2>; 966+ status = "disabled"; 967+ }; 968+ 969+ gpio_chip2: gpio_chip@120d2000 { 970+ compatible = "arm,pl061", "arm,primecell"; 971+ reg = <0x120d2000 0x1000>; 972+ interrupts = <0 18 4>; 973+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 974+ clock-names = "apb_pclk"; 975+ #gpio-cells = <2>; 976+ status = "disabled"; 977+ }; 978+ 979+ gpio_chip3: gpio_chip@120d3000 { 980+ compatible = "arm,pl061", "arm,primecell"; 981+ reg = <0x120d3000 0x1000>; 982+ interrupts = <0 19 4>; 983+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 984+ clock-names = "apb_pclk"; 985+ #gpio-cells = <2>; 986+ status = "disabled"; 987+ }; 988+ 989+ gpio_chip4: gpio_chip@120d4000 { 990+ compatible = "arm,pl061", "arm,primecell"; 991+ reg = <0x120d4000 0x1000>; 992+ interrupts = <0 20 4>; 993+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 994+ clock-names = "apb_pclk"; 995+ #gpio-cells = <2>; 996+ status = "disabled"; 997+ }; 998+ 999+ gpio_chip5: gpio_chip@120d5000 { 1000+ compatible = "arm,pl061", "arm,primecell"; 1001+ reg = <0x120d5000 0x1000>; 1002+ interrupts = <0 21 4>; 1003+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 1004+ clock-names = "apb_pclk"; 1005+ #gpio-cells = <2>; 1006+ status = "disabled"; 1007+ }; 1008+ 1009+ gpio_chip6: gpio_chip@120d6000 { 1010+ compatible = "arm,pl061", "arm,primecell"; 1011+ reg = <0x120d6000 0x1000>; 1012+ interrupts = <0 22 4>; 1013+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 1014+ clock-names = "apb_pclk"; 1015+ #gpio-cells = <2>; 1016+ status = "disabled"; 1017+ }; 1018+ 1019+ gpio_chip7: gpio_chip@120d7000 { 1020+ compatible = "arm,pl061", "arm,primecell"; 1021+ reg = <0x120d7000 0x1000>; 1022+ interrupts = <0 23 4>; 1023+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 1024+ clock-names = "apb_pclk"; 1025+ #gpio-cells = <2>; 1026+ status = "disabled"; 1027+ }; 1028+ 1029+ gpio_chip8: gpio_chip@120d8000 { 1030+ compatible = "arm,pl061", "arm,primecell"; 1031+ reg = <0x120d8000 0x1000>; 1032+ interrupts = <0 24 4>; 1033+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 1034+ clock-names = "apb_pclk"; 1035+ #gpio-cells = <2>; 1036+ status = "disabled"; 1037+ }; 1038+ 1039+ gpio_chip9: gpio_chip@120d9000 { 1040+ compatible = "arm,pl061", "arm,primecell"; 1041+ reg = <0x120d9000 0x1000>; 1042+ interrupts = <0 25 4>; 1043+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 1044+ clock-names = "apb_pclk"; 1045+ #gpio-cells = <2>; 1046+ status = "disabled"; 1047+ }; 1048+ 1049+ gpio_chip10: gpio_chip@120da000 { 1050+ compatible = "arm,pl061", "arm,primecell"; 1051+ reg = <0x120da000 0x1000>; 1052+ interrupts = <0 26 4>; 1053+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 1054+ clock-names = "apb_pclk"; 1055+ #gpio-cells = <2>; 1056+ status = "disabled"; 1057+ }; 1058+ 1059+ gpio_chip11: gpio_chip@120db000 { 1060+ compatible = "arm,pl061", "arm,primecell"; 1061+ reg = <0x120db000 0x1000>; 1062+ interrupts = <0 80 4>; 1063+ clocks = <&clock HI3516DV300_SYSAPB_CLK>; 1064+ clock-names = "apb_pclk"; 1065+ #gpio-cells = <2>; 1066+ status = "disabled"; 1067+ }; 1068+ 1069+ cipher: cipher@0x100c0000 { 1070+ compatible = "hisilicon,hisi-cipher"; 1071+ reg = <0x100c0000 0x10000>; 1072+ reg-names = "cipher"; 1073+ interrupts = <0 71 4>, <0 72 4>, <0 71 4>, <0 72 4>; 1074+ interrupt-names = "cipher", "nonsec_cipher", "hash", "nonsec_hash"; 1075+ }; 1076+ 1077+ }; 1078+ 1079+ hidrm { 1080+ compatible = "hisilicon,hi-drm"; 1081+ }; 1082+ 1083+ media { 1084+ #address-cells = <1>; 1085+ #size-cells = <1>; 1086+ compatible = "simple-bus"; 1087+ interrupt-parent = <&gic>; 1088+ ranges; 1089+ 1090+ osal: osal { 1091+ compatible = "hisilicon,osal"; 1092+ }; 1093+ 1094+ sys_config: sys_config { 1095+ compatible = "hisilicon,sys_config"; 1096+ }; 1097+ 1098+ sys: sys@12010000 { 1099+ compatible = "hisilicon,hisi-sys"; 1100+ reg = <0x12010000 0x10000>, <0x12020000 0x8000>, 1101+ <0x12060000 0x10000>, <0x12030000 0x8000>; 1102+ reg-names = "crg", "sys", "ddr", "misc"; 1103+ }; 1104+ 1105+ mipi: mipi@113a0000 { 1106+ compatible = "hisilicon,hisi-mipi"; 1107+ reg = <0x113a0000 0x10000>; 1108+ reg-names = "mipi_rx"; 1109+ interrupts = <0 57 4>; 1110+ interrupt-names = "mipi_rx"; 1111+ }; 1112+ 1113+ mipi_tx: mipi_tx@11270000 { 1114+ compatible = "hisilicon,hisi-mipi_tx"; 1115+ reg = <0x11270000 0x10000>; 1116+ reg-names = "mipi_tx"; 1117+ interrupts = <0 63 4>; 1118+ interrupt-names = "mipi_tx"; 1119+ }; 1120+ 1121+ vi: vi@11300000 { 1122+ compatible = "hisilicon,hisi-vi"; 1123+ reg = <0x11300000 0xa0000>, <0x11000000 0x40000>; 1124+ reg-names = "VI_CAP0", "VI_PROC0"; 1125+ interrupts = <0 56 4>, <0 44 4>; 1126+ interrupt-names = "VI_CAP0", "VI_PROC0"; 1127+ }; 1128+ 1129+ isp: isp@11020000 { 1130+ compatible = "hisilicon,hisi-isp"; 1131+ reg = <0x11020000 0x20000>; 1132+ reg-names = "ISP"; 1133+ interrupts = <0 56 4>; 1134+ interrupt-names = "ISP"; 1135+ }; 1136+ 1137+ vpss: vpss@11040000 { 1138+ compatible = "hisilicon,hisi-vpss"; 1139+ reg = <0x11040000 0x10000>; 1140+ reg-names = "vpss0"; 1141+ interrupts = <0 43 4>; 1142+ interrupt-names = "vpss0"; 1143+ }; 1144+ 1145+ vgs: vgs@11240000 { 1146+ compatible = "hisilicon,hisi-vgs"; 1147+ reg = <0x11240000 0x10000>; 1148+ reg-names = "vgs0"; 1149+ interrupts = <0 38 4>; 1150+ interrupt-names = "vgs0"; 1151+ }; 1152+ 1153+ vo: vo@11440000 { 1154+ compatible = "hisilicon,hisi-vo"; 1155+ reg = <0x11440000 0x40000>; 1156+ reg-names = "vo"; 1157+ interrupts = <0 58 4>; 1158+ interrupt-names = "vo"; 1159+ }; 1160+ 1161+ hifb: hifb@11440000 { 1162+ compatible = "hisilicon,hisi-hifb"; 1163+ reg = <0x11440000 0x40000>, <0x12020000 0x8000>; 1164+ reg-names = "hifb", "sys"; 1165+ interrupts = <0 59 4>, <0 51 4>; 1166+ interrupt-names = "hifb", "hifb_soft"; 1167+ }; 1168+ 1169+ tde: tde@11210000 { 1170+ compatible = "hisilicon,hisi-tde"; 1171+ reg = <0x11210000 0x10000>; 1172+ reg-names = "tde"; 1173+ interrupts = <0 35 4>; 1174+ interrupt-names = "tde_osr_isr"; 1175+ }; 1176+ 1177+ gyro_dis: gyro { 1178+ compatible = "hisilicon,hisi-gyro-dis"; 1179+ }; 1180+ 1181+ gdc: gdc@11110000 { 1182+ compatible = "hisilicon,hisi-gdc"; 1183+ reg = <0x11110000 0x10000>, <0x11100000 0x10000>; 1184+ reg-names = "gdc", "nnie0"; 1185+ interrupts = <0 42 4>, <0 41 4>; 1186+ interrupt-names = "gdc", "nnie0"; 1187+ }; 1188+ 1189+ gzip: gzip@11200000 { 1190+ compatible = "hisilicon,hisi-gzip"; 1191+ reg = <0x11200000 0x10000>; 1192+ reg-names = "gzip"; 1193+ interrupts = <0 34 4>; 1194+ interrupt-names = "gzip"; 1195+ }; 1196+ 1197+ jpegd: jpegd@11260000 { 1198+ compatible = "hisilicon,hisi-jpegd"; 1199+ reg = <0x11260000 0x10000>; 1200+ reg-names = "jpegd"; 1201+ interrupts = <0 45 4>; 1202+ interrupt-names = "jpegd"; 1203+ }; 1204+ 1205+ vedu: vedu@11500000 { 1206+ compatible = "hisilicon,hisi-vedu"; 1207+ reg = <0x11500000 0x10000>, <0x11220000 0x10000>; 1208+ reg-names = "vedu0", "jpge"; 1209+ interrupts = <0 40 4>, <0 36 4>; 1210+ interrupt-names = "vedu0","jpge"; 1211+ }; 1212+ 1213+ venc: venc { 1214+ compatible = "hisilicon,hisi-venc"; 1215+ }; 1216+ 1217+ scd: scd@10030000 { 1218+ compatible = "hisilicon,hisi-scd"; 1219+ reg = <0x10030000 0x10000>; 1220+ reg-names = "scd"; 1221+ interrupts = <0 67 4>; 1222+ interrupt-names = "scd"; 1223+ }; 1224+ 1225+ hdmi: hdmi@11400000 { 1226+ compatible = "hisilicon,hisi-hdmi"; 1227+ reg = <0x11400000 0x30000>; 1228+ reg-names = "hdmi0"; 1229+ }; 1230+ 1231+ aiao: aiao@113b0000 { 1232+ compatible = "hisilicon,hisi-aiao"; 1233+ reg = <0x113b0000 0x10000>,<0x113c0000 0x10000>,<0x12010000 0x10000>; 1234+ reg-names = "aiao","acodec","crg"; 1235+ interrupts = <0 55 4>; 1236+ interrupt-names = "AIO"; 1237+ }; 1238+ 1239+ nnie: nnie@11100000 { 1240+ compatible = "hisilicon,hisi-nnie"; 1241+ reg = <0x11100000 0x10000>,<0x11110000 0x10000>; 1242+ reg-names = "nnie0","gdc"; 1243+ interrupts = <0 41 4>,<0 42 4>; 1244+ interrupt-names = "nnie0","gdc"; 1245+ }; 1246+ 1247+ ive: ive@11230000 { 1248+ compatible = "hisilicon,hisi-ive"; 1249+ reg = <0x11230000 0x10000>; 1250+ reg-names = "ive"; 1251+ interrupts = <0 37 4>; 1252+ interrupt-names = "ive"; 1253+ }; 1254+ 1255+ adc: adc@120e0000 { 1256+ compatible = "hisilicon,hisi-lsadc"; 1257+ reg = <0x120e0000 0x1000>; 1258+ interrupts = <0 65 4>; 1259+ resets = <&clock 0x1bc 2>; 1260+ reset-names = "lsadc-crg"; 1261+ status = "disabled"; 1262+ }; 1263+ ir: ir@120f0000 { 1264+ compatible = "hisilicon,hi_ir"; 1265+ reg = <0x120f0000 0x1000>; 1266+ interrupts = <0 75 4>; 1267+ }; 1268+ 1269+ rtc: rtc@12080000 { 1270+ compatible = "hisilicon,hi35xx-rtc"; 1271+ reg = <0x12080000 0x1000>; 1272+ interrupts = <0 5 4>; 1273+ }; 1274+ 1275+ wdg: wdg@12050000 { 1276+ compatible = "hisilicon,hi_wdg"; 1277+ reg = <0x12050000 0x1000>; 1278+ }; 1279+ pwm0: pwm@12070000 { 1280+ compatible = "hisilicon,pwm"; 1281+ reg = <0x12070000 0x20>; 1282+ clocks = <&clock HI3516DV300_PWM_CLK>; 1283+ resets = <&clock 0x1bc 6>; 1284+ }; 1285+ pwm1: pwm@12070020 { 1286+ compatible = "hisilicon,pwm"; 1287+ reg = <0x12070020 0x20>; 1288+ clocks = <&clock HI3516DV300_PWM_CLK>; 1289+ resets = <&clock 0x1bc 6>; 1290+ }; 1291+ 1292+ irq: irq@120f0000 { 1293+ compatible = "hisilicon,hi_irq"; 1294+ reg = <0x11240000 0x10000>,<0x11040000 0x10000>,<0x10030000 0x10000>,<0x113b0000 0x10000>,<0x113c0000 0x10000>,<0x12010000 0x10000>,<0x11500000 0x10000>, <0x11220000 0x10000>,<0x11440000 0x40000>,<0x11300000 0xa0000>, <0x11000000 0x40000>; 1295+ reg-names = "vgs", "vpss0", "scd", "aiao", "acodec", "crg", "vedu0", "jpge", "vo", "VI_CAP0", "VI_PROC0"; 1296+ interrupts = <0 67 4>,<0 26 4>,<0 56 4>, <0 44 4>,<0 43 4>,<0 38 4>,<0 58 4>,<0 40 4>,<0 36 4>,<0 37 4>,<0 41 4>,<0 42 4>,<0 56 4>,<0 45 4>,<0 55 4>; 1297+ interrupt-names = "scd","new", "VI_CAP0", "VI_PROC0","vpss0","vgs0", "vo", "vedu0", "jpge", "ive", "nnie0", "gdc", "ISP", "jpegd" ,"AIO"; 1298+ }; 1299+ }; 1300+}; 1301diff --git a/arch/arm/boot/dts/skeleton.dtsi b/arch/arm/boot/dts/skeleton.dtsi 1302new file mode 100644 1303index 000000000..34eda68d9 1304--- /dev/null 1305+++ b/arch/arm/boot/dts/skeleton.dtsi 1306@@ -0,0 +1,18 @@ 1307+// SPDX-License-Identifier: GPL-2.0 1308+/* 1309+ * This file is deprecated, and will be removed once existing users have been 1310+ * updated. New dts{,i} files should *not* include skeleton.dtsi, and should 1311+ * instead explicitly provide the below nodes only as required. 1312+ * 1313+ * Skeleton device tree; the bare minimum needed to boot; just include and 1314+ * add a compatible value. The bootloader will typically populate the memory 1315+ * node. 1316+ */ 1317+ 1318+/ { 1319+ #address-cells = <1>; 1320+ #size-cells = <1>; 1321+ chosen { }; 1322+ aliases { }; 1323+ memory { device_type = "memory"; reg = <0 0>; }; 1324+}; 1325diff --git a/arch/arm/configs/hi3516dv300_emmc_smp_defconfig b/arch/arm/configs/hi3516dv300_emmc_smp_defconfig 1326new file mode 100644 1327index 000000000..daeb1fa65 1328--- /dev/null 1329+++ b/arch/arm/configs/hi3516dv300_emmc_smp_defconfig 1330@@ -0,0 +1,3070 @@ 1331+# 1332+# Automatically generated file; DO NOT EDIT. 1333+# Linux/arm 4.19.90 Kernel Configuration 1334+# 1335+ 1336+# 1337+# Compiler: arm-himix410-linux-gcc (HC&C V1R3C00SPC200B041_20200707) 7.3.0 1338+# 1339+CONFIG_CC_IS_GCC=y 1340+CONFIG_GCC_VERSION=70300 1341+CONFIG_CLANG_VERSION=0 1342+CONFIG_CC_HAS_ASM_GOTO=y 1343+CONFIG_IRQ_WORK=y 1344+CONFIG_BUILDTIME_EXTABLE_SORT=y 1345+ 1346+# 1347+# General setup 1348+# 1349+CONFIG_INIT_ENV_ARG_LIMIT=32 1350+# CONFIG_COMPILE_TEST is not set 1351+CONFIG_LOCALVERSION="" 1352+# CONFIG_LOCALVERSION_AUTO is not set 1353+CONFIG_BUILD_SALT="" 1354+CONFIG_HAVE_KERNEL_GZIP=y 1355+CONFIG_HAVE_KERNEL_LZMA=y 1356+CONFIG_HAVE_KERNEL_XZ=y 1357+CONFIG_HAVE_KERNEL_LZO=y 1358+CONFIG_HAVE_KERNEL_LZ4=y 1359+CONFIG_KERNEL_GZIP=y 1360+# CONFIG_KERNEL_LZMA is not set 1361+# CONFIG_KERNEL_XZ is not set 1362+# CONFIG_KERNEL_LZO is not set 1363+# CONFIG_KERNEL_LZ4 is not set 1364+CONFIG_DEFAULT_HOSTNAME="(none)" 1365+# CONFIG_SWAP is not set 1366+CONFIG_SYSVIPC=y 1367+CONFIG_SYSVIPC_SYSCTL=y 1368+# CONFIG_POSIX_MQUEUE is not set 1369+CONFIG_CROSS_MEMORY_ATTACH=y 1370+CONFIG_USELIB=y 1371+# CONFIG_AUDIT is not set 1372+ 1373+# 1374+# IRQ subsystem 1375+# 1376+CONFIG_GENERIC_IRQ_PROBE=y 1377+CONFIG_GENERIC_IRQ_SHOW=y 1378+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y 1379+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y 1380+CONFIG_GENERIC_IRQ_MIGRATION=y 1381+CONFIG_HARDIRQS_SW_RESEND=y 1382+CONFIG_IRQ_DOMAIN=y 1383+CONFIG_IRQ_DOMAIN_HIERARCHY=y 1384+CONFIG_HANDLE_DOMAIN_IRQ=y 1385+CONFIG_IRQ_FORCED_THREADING=y 1386+CONFIG_SPARSE_IRQ=y 1387+# CONFIG_GENERIC_IRQ_DEBUGFS is not set 1388+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y 1389+CONFIG_ARCH_CLOCKSOURCE_DATA=y 1390+CONFIG_GENERIC_TIME_VSYSCALL=y 1391+CONFIG_GENERIC_CLOCKEVENTS=y 1392+CONFIG_ARCH_HAS_TICK_BROADCAST=y 1393+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y 1394+ 1395+# 1396+# Timers subsystem 1397+# 1398+CONFIG_HZ_PERIODIC=y 1399+# CONFIG_NO_HZ_IDLE is not set 1400+# CONFIG_NO_HZ_FULL is not set 1401+# CONFIG_NO_HZ is not set 1402+# CONFIG_HIGH_RES_TIMERS is not set 1403+CONFIG_PREEMPT_NONE=y 1404+# CONFIG_PREEMPT_VOLUNTARY is not set 1405+# CONFIG_PREEMPT is not set 1406+ 1407+# 1408+# CPU/Task time and stats accounting 1409+# 1410+CONFIG_TICK_CPU_ACCOUNTING=y 1411+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set 1412+# CONFIG_IRQ_TIME_ACCOUNTING is not set 1413+# CONFIG_BSD_PROCESS_ACCT is not set 1414+# CONFIG_TASKSTATS is not set 1415+CONFIG_CPU_ISOLATION=y 1416+ 1417+# 1418+# RCU Subsystem 1419+# 1420+CONFIG_TREE_RCU=y 1421+# CONFIG_RCU_EXPERT is not set 1422+CONFIG_SRCU=y 1423+CONFIG_TREE_SRCU=y 1424+CONFIG_RCU_STALL_COMMON=y 1425+CONFIG_RCU_NEED_SEGCBLIST=y 1426+# CONFIG_IKCONFIG is not set 1427+CONFIG_LOG_BUF_SHIFT=17 1428+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 1429+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 1430+CONFIG_GENERIC_SCHED_CLOCK=y 1431+CONFIG_CGROUPS=y 1432+# CONFIG_MEMCG is not set 1433+# CONFIG_BLK_CGROUP is not set 1434+CONFIG_CGROUP_SCHED=y 1435+CONFIG_FAIR_GROUP_SCHED=y 1436+# CONFIG_CFS_BANDWIDTH is not set 1437+# CONFIG_RT_GROUP_SCHED is not set 1438+# CONFIG_CGROUP_PIDS is not set 1439+# CONFIG_CGROUP_RDMA is not set 1440+# CONFIG_CGROUP_FREEZER is not set 1441+# CONFIG_CPUSETS is not set 1442+# CONFIG_CGROUP_DEVICE is not set 1443+# CONFIG_CGROUP_CPUACCT is not set 1444+# CONFIG_CGROUP_DEBUG is not set 1445+CONFIG_NAMESPACES=y 1446+CONFIG_UTS_NS=y 1447+CONFIG_IPC_NS=y 1448+# CONFIG_USER_NS is not set 1449+CONFIG_PID_NS=y 1450+CONFIG_NET_NS=y 1451+# CONFIG_CHECKPOINT_RESTORE is not set 1452+# CONFIG_SCHED_AUTOGROUP is not set 1453+# CONFIG_SYSFS_DEPRECATED is not set 1454+# CONFIG_RELAY is not set 1455+# CONFIG_BLK_DEV_INITRD is not set 1456+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y 1457+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 1458+CONFIG_SYSCTL=y 1459+CONFIG_ANON_INODES=y 1460+CONFIG_HAVE_UID16=y 1461+CONFIG_BPF=y 1462+# CONFIG_EXPERT is not set 1463+CONFIG_UID16=y 1464+CONFIG_MULTIUSER=y 1465+CONFIG_SYSFS_SYSCALL=y 1466+CONFIG_FHANDLE=y 1467+CONFIG_POSIX_TIMERS=y 1468+CONFIG_PRINTK=y 1469+CONFIG_PRINTK_NMI=y 1470+CONFIG_BUG=y 1471+CONFIG_ELF_CORE=y 1472+CONFIG_BASE_FULL=y 1473+CONFIG_FUTEX=y 1474+CONFIG_FUTEX_PI=y 1475+CONFIG_EPOLL=y 1476+CONFIG_SIGNALFD=y 1477+CONFIG_TIMERFD=y 1478+CONFIG_EVENTFD=y 1479+CONFIG_SHMEM=y 1480+CONFIG_AIO=y 1481+CONFIG_ADVISE_SYSCALLS=y 1482+CONFIG_MEMBARRIER=y 1483+CONFIG_KALLSYMS=y 1484+# CONFIG_KALLSYMS_ALL is not set 1485+CONFIG_KALLSYMS_BASE_RELATIVE=y 1486+# CONFIG_BPF_SYSCALL is not set 1487+# CONFIG_USERFAULTFD is not set 1488+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y 1489+CONFIG_RSEQ=y 1490+# CONFIG_EMBEDDED is not set 1491+CONFIG_HAVE_PERF_EVENTS=y 1492+CONFIG_PERF_USE_VMALLOC=y 1493+ 1494+# 1495+# Kernel Performance Events And Counters 1496+# 1497+# CONFIG_PERF_EVENTS is not set 1498+CONFIG_VM_EVENT_COUNTERS=y 1499+CONFIG_SLUB_DEBUG=y 1500+CONFIG_COMPAT_BRK=y 1501+# CONFIG_SLAB is not set 1502+CONFIG_SLUB=y 1503+CONFIG_SLAB_MERGE_DEFAULT=y 1504+# CONFIG_SLAB_FREELIST_RANDOM is not set 1505+# CONFIG_SLAB_FREELIST_HARDENED is not set 1506+CONFIG_SLUB_CPU_PARTIAL=y 1507+# CONFIG_PROFILING is not set 1508+CONFIG_ARM=y 1509+CONFIG_ARM_HAS_SG_CHAIN=y 1510+CONFIG_MIGHT_HAVE_PCI=y 1511+CONFIG_SYS_SUPPORTS_APM_EMULATION=y 1512+CONFIG_HAVE_PROC_CPU=y 1513+CONFIG_STACKTRACE_SUPPORT=y 1514+CONFIG_LOCKDEP_SUPPORT=y 1515+CONFIG_TRACE_IRQFLAGS_SUPPORT=y 1516+CONFIG_RWSEM_XCHGADD_ALGORITHM=y 1517+CONFIG_FIX_EARLYCON_MEM=y 1518+CONFIG_GENERIC_HWEIGHT=y 1519+CONFIG_GENERIC_CALIBRATE_DELAY=y 1520+CONFIG_ARCH_SUPPORTS_UPROBES=y 1521+CONFIG_ARM_PATCH_PHYS_VIRT=y 1522+CONFIG_GENERIC_BUG=y 1523+CONFIG_PGTABLE_LEVELS=2 1524+ 1525+# 1526+# System Type 1527+# 1528+CONFIG_MMU=y 1529+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 1530+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 1531+CONFIG_ARCH_MULTIPLATFORM=y 1532+# CONFIG_ARCH_EBSA110 is not set 1533+# CONFIG_ARCH_EP93XX is not set 1534+# CONFIG_ARCH_FOOTBRIDGE is not set 1535+# CONFIG_ARCH_NETX is not set 1536+# CONFIG_ARCH_IOP13XX is not set 1537+# CONFIG_ARCH_IOP32X is not set 1538+# CONFIG_ARCH_IOP33X is not set 1539+# CONFIG_ARCH_IXP4XX is not set 1540+# CONFIG_ARCH_DOVE is not set 1541+# CONFIG_ARCH_KS8695 is not set 1542+# CONFIG_ARCH_W90X900 is not set 1543+# CONFIG_ARCH_LPC32XX is not set 1544+# CONFIG_ARCH_PXA is not set 1545+# CONFIG_ARCH_RPC is not set 1546+# CONFIG_ARCH_SA1100 is not set 1547+# CONFIG_ARCH_S3C24XX is not set 1548+# CONFIG_ARCH_DAVINCI is not set 1549+# CONFIG_ARCH_OMAP1 is not set 1550+ 1551+# 1552+# Multiple platform selection 1553+# 1554+ 1555+# 1556+# CPU Core family selection 1557+# 1558+# CONFIG_ARCH_MULTI_V6 is not set 1559+CONFIG_ARCH_MULTI_V7=y 1560+CONFIG_ARCH_MULTI_V6_V7=y 1561+# CONFIG_ARCH_VIRT is not set 1562+# CONFIG_ARCH_ACTIONS is not set 1563+# CONFIG_ARCH_ALPINE is not set 1564+# CONFIG_ARCH_ARTPEC is not set 1565+# CONFIG_ARCH_AT91 is not set 1566+# CONFIG_ARCH_BCM is not set 1567+# CONFIG_ARCH_BERLIN is not set 1568+# CONFIG_ARCH_DIGICOLOR is not set 1569+# CONFIG_ARCH_EXYNOS is not set 1570+# CONFIG_ARCH_HIGHBANK is not set 1571+# CONFIG_ARCH_HISI is not set 1572+CONFIG_ARCH_HISI_BVT=y 1573+ 1574+# 1575+# Hisilicon BVT platform type 1576+# 1577+# CONFIG_ARCH_HI3521DV200 is not set 1578+# CONFIG_ARCH_HI3520DV500 is not set 1579+# CONFIG_ARCH_HI3516A is not set 1580+# CONFIG_ARCH_HI3516CV500 is not set 1581+CONFIG_ARCH_HI3516DV300=y 1582+# CONFIG_ARCH_HI3516EV200 is not set 1583+# CONFIG_ARCH_HI3516EV300 is not set 1584+# CONFIG_ARCH_HI3518EV300 is not set 1585+# CONFIG_ARCH_HI3516DV200 is not set 1586+# CONFIG_ARCH_HI3556V200 is not set 1587+# CONFIG_ARCH_HI3559V200 is not set 1588+# CONFIG_ARCH_HI3536DV100 is not set 1589+# CONFIG_ARCH_HI3521A is not set 1590+# CONFIG_ARCH_HI3531A is not set 1591+# CONFIG_ARCH_HI3556AV100 is not set 1592+# CONFIG_ARCH_HI3519AV100 is not set 1593+# CONFIG_ARCH_HI3568V100 is not set 1594+# CONFIG_ARCH_HISI_BVT_AMP is not set 1595+# CONFIG_HISI_MC is not set 1596+CONFIG_HI_ZRELADDR=0x80008000 1597+CONFIG_HI_PARAMS_PHYS=0x00000100 1598+CONFIG_HI_INITRD_PHYS=0x00800000 1599+# CONFIG_ARCH_MXC is not set 1600+# CONFIG_ARCH_KEYSTONE is not set 1601+# CONFIG_ARCH_MEDIATEK is not set 1602+# CONFIG_ARCH_MESON is not set 1603+# CONFIG_ARCH_MMP is not set 1604+# CONFIG_ARCH_MVEBU is not set 1605+# CONFIG_ARCH_NPCM is not set 1606+ 1607+# 1608+# TI OMAP/AM/DM/DRA Family 1609+# 1610+# CONFIG_ARCH_OMAP3 is not set 1611+# CONFIG_ARCH_OMAP4 is not set 1612+# CONFIG_SOC_OMAP5 is not set 1613+# CONFIG_SOC_AM33XX is not set 1614+# CONFIG_SOC_AM43XX is not set 1615+# CONFIG_SOC_DRA7XX is not set 1616+# CONFIG_ARCH_SIRF is not set 1617+# CONFIG_ARCH_QCOM is not set 1618+# CONFIG_ARCH_REALVIEW is not set 1619+# CONFIG_ARCH_ROCKCHIP is not set 1620+# CONFIG_ARCH_S5PV210 is not set 1621+# CONFIG_ARCH_RENESAS is not set 1622+# CONFIG_ARCH_SOCFPGA is not set 1623+# CONFIG_PLAT_SPEAR is not set 1624+# CONFIG_ARCH_STI is not set 1625+# CONFIG_ARCH_STM32 is not set 1626+# CONFIG_ARCH_SUNXI is not set 1627+# CONFIG_ARCH_TANGO is not set 1628+# CONFIG_ARCH_TEGRA is not set 1629+# CONFIG_ARCH_UNIPHIER is not set 1630+# CONFIG_ARCH_U8500 is not set 1631+# CONFIG_ARCH_VEXPRESS is not set 1632+# CONFIG_ARCH_WM8850 is not set 1633+# CONFIG_ARCH_ZX is not set 1634+# CONFIG_ARCH_ZYNQ is not set 1635+ 1636+# 1637+# Processor Type 1638+# 1639+CONFIG_CPU_V7=y 1640+CONFIG_CPU_THUMB_CAPABLE=y 1641+CONFIG_CPU_32v6K=y 1642+CONFIG_CPU_32v7=y 1643+CONFIG_CPU_ABRT_EV7=y 1644+CONFIG_CPU_PABRT_V7=y 1645+CONFIG_CPU_CACHE_V7=y 1646+CONFIG_CPU_CACHE_VIPT=y 1647+CONFIG_CPU_COPY_V6=y 1648+CONFIG_CPU_TLB_V7=y 1649+CONFIG_CPU_HAS_ASID=y 1650+CONFIG_CPU_CP15=y 1651+CONFIG_CPU_CP15_MMU=y 1652+ 1653+# 1654+# Processor Features 1655+# 1656+# CONFIG_ARM_LPAE is not set 1657+CONFIG_ARM_THUMB=y 1658+# CONFIG_ARM_THUMBEE is not set 1659+CONFIG_ARM_VIRT_EXT=y 1660+CONFIG_SWP_EMULATE=y 1661+# CONFIG_CPU_ICACHE_DISABLE is not set 1662+# CONFIG_CPU_BPREDICT_DISABLE is not set 1663+CONFIG_CPU_SPECTRE=y 1664+CONFIG_HARDEN_BRANCH_PREDICTOR=y 1665+CONFIG_KUSER_HELPERS=y 1666+CONFIG_VDSO=y 1667+CONFIG_MIGHT_HAVE_CACHE_L2X0=y 1668+# CONFIG_CACHE_L2X0 is not set 1669+CONFIG_ARM_L1_CACHE_SHIFT_6=y 1670+CONFIG_ARM_L1_CACHE_SHIFT=6 1671+CONFIG_ARM_DMA_MEM_BUFFERABLE=y 1672+CONFIG_DEBUG_ALIGN_RODATA=y 1673+# CONFIG_ARM_ERRATA_430973 is not set 1674+# CONFIG_ARM_ERRATA_643719 is not set 1675+# CONFIG_ARM_ERRATA_720789 is not set 1676+# CONFIG_ARM_ERRATA_754322 is not set 1677+# CONFIG_ARM_ERRATA_754327 is not set 1678+# CONFIG_ARM_ERRATA_764369 is not set 1679+# CONFIG_ARM_ERRATA_775420 is not set 1680+# CONFIG_ARM_ERRATA_798181 is not set 1681+# CONFIG_ARM_ERRATA_773022 is not set 1682+# CONFIG_ARM_ERRATA_818325_852422 is not set 1683+# CONFIG_ARM_ERRATA_821420 is not set 1684+# CONFIG_ARM_ERRATA_825619 is not set 1685+# CONFIG_ARM_ERRATA_852421 is not set 1686+# CONFIG_ARM_ERRATA_852423 is not set 1687+ 1688+# 1689+# Bus support 1690+# 1691+# CONFIG_PCI is not set 1692+ 1693+# 1694+# PCI Endpoint 1695+# 1696+# CONFIG_PCI_ENDPOINT is not set 1697+# CONFIG_PCCARD is not set 1698+ 1699+# 1700+# Kernel Features 1701+# 1702+CONFIG_HAVE_SMP=y 1703+CONFIG_SMP=y 1704+CONFIG_SMP_ON_UP=y 1705+CONFIG_ARM_CPU_TOPOLOGY=y 1706+# CONFIG_SCHED_MC is not set 1707+# CONFIG_SCHED_SMT is not set 1708+CONFIG_HAVE_ARM_ARCH_TIMER=y 1709+# CONFIG_MCPM is not set 1710+# CONFIG_BIG_LITTLE is not set 1711+CONFIG_VMSPLIT_3G=y 1712+# CONFIG_VMSPLIT_3G_OPT is not set 1713+# CONFIG_VMSPLIT_2G is not set 1714+# CONFIG_VMSPLIT_1G is not set 1715+CONFIG_PAGE_OFFSET=0xC0000000 1716+CONFIG_NR_CPUS=2 1717+CONFIG_HOTPLUG_CPU=y 1718+# CONFIG_ARM_PSCI is not set 1719+CONFIG_ARCH_NR_GPIO=0 1720+CONFIG_HZ_FIXED=0 1721+CONFIG_HZ_100=y 1722+# CONFIG_HZ_200 is not set 1723+# CONFIG_HZ_250 is not set 1724+# CONFIG_HZ_300 is not set 1725+# CONFIG_HZ_500 is not set 1726+# CONFIG_HZ_1000 is not set 1727+CONFIG_HZ=100 1728+# CONFIG_THUMB2_KERNEL is not set 1729+CONFIG_ARM_PATCH_IDIV=y 1730+CONFIG_AEABI=y 1731+CONFIG_OABI_COMPAT=y 1732+CONFIG_HAVE_ARCH_PFN_VALID=y 1733+CONFIG_HIGHMEM=y 1734+CONFIG_HIGHPTE=y 1735+CONFIG_CPU_SW_DOMAIN_PAN=y 1736+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y 1737+# CONFIG_ARM_MODULE_PLTS is not set 1738+CONFIG_FORCE_MAX_ZONEORDER=11 1739+CONFIG_ALIGNMENT_TRAP=y 1740+# CONFIG_UACCESS_WITH_MEMCPY is not set 1741+# CONFIG_SECCOMP is not set 1742+# CONFIG_PARAVIRT is not set 1743+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set 1744+# CONFIG_XEN is not set 1745+ 1746+# 1747+# Boot options 1748+# 1749+CONFIG_USE_OF=y 1750+CONFIG_ATAGS=y 1751+# CONFIG_DEPRECATED_PARAM_STRUCT is not set 1752+CONFIG_ZBOOT_ROM_TEXT=0 1753+CONFIG_ZBOOT_ROM_BSS=0 1754+CONFIG_ARM_APPENDED_DTB=y 1755+CONFIG_ARM_ATAG_DTB_COMPAT=y 1756+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y 1757+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set 1758+CONFIG_CMDLINE="" 1759+# CONFIG_KEXEC is not set 1760+# CONFIG_CRASH_DUMP is not set 1761+CONFIG_AUTO_ZRELADDR=y 1762+# CONFIG_EFI is not set 1763+ 1764+# 1765+# CPU Power Management 1766+# 1767+ 1768+# 1769+# CPU Frequency scaling 1770+# 1771+# CONFIG_CPU_FREQ is not set 1772+ 1773+# 1774+# CPU Idle 1775+# 1776+# CONFIG_CPU_IDLE is not set 1777+ 1778+# 1779+# Floating point emulation 1780+# 1781+ 1782+# 1783+# At least one emulation must be selected 1784+# 1785+# CONFIG_FPE_NWFPE is not set 1786+# CONFIG_FPE_FASTFPE is not set 1787+CONFIG_VFP=y 1788+CONFIG_VFPv3=y 1789+CONFIG_NEON=y 1790+CONFIG_KERNEL_MODE_NEON=y 1791+ 1792+# 1793+# Power management options 1794+# 1795+CONFIG_SUSPEND=y 1796+CONFIG_SUSPEND_FREEZER=y 1797+CONFIG_PM_SLEEP=y 1798+CONFIG_PM_SLEEP_SMP=y 1799+# CONFIG_PM_AUTOSLEEP is not set 1800+# CONFIG_PM_WAKELOCKS is not set 1801+CONFIG_PM=y 1802+# CONFIG_PM_DEBUG is not set 1803+# CONFIG_APM_EMULATION is not set 1804+CONFIG_PM_CLK=y 1805+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set 1806+CONFIG_CPU_PM=y 1807+CONFIG_ARCH_SUSPEND_POSSIBLE=y 1808+CONFIG_ARM_CPU_SUSPEND=y 1809+CONFIG_ARCH_HIBERNATION_POSSIBLE=y 1810+ 1811+# 1812+# Firmware Drivers 1813+# 1814+# CONFIG_FW_CFG_SYSFS is not set 1815+CONFIG_HAVE_ARM_SMCCC=y 1816+# CONFIG_GOOGLE_FIRMWARE is not set 1817+ 1818+# 1819+# Tegra firmware driver 1820+# 1821+# CONFIG_ARM_CRYPTO is not set 1822+# CONFIG_VIRTUALIZATION is not set 1823+ 1824+# 1825+# General architecture-dependent options 1826+# 1827+CONFIG_HAVE_OPROFILE=y 1828+# CONFIG_KPROBES is not set 1829+# CONFIG_JUMP_LABEL is not set 1830+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y 1831+CONFIG_ARCH_USE_BUILTIN_BSWAP=y 1832+CONFIG_HAVE_KPROBES=y 1833+CONFIG_HAVE_KRETPROBES=y 1834+CONFIG_HAVE_OPTPROBES=y 1835+CONFIG_HAVE_NMI=y 1836+CONFIG_HAVE_ARCH_TRACEHOOK=y 1837+CONFIG_HAVE_DMA_CONTIGUOUS=y 1838+CONFIG_GENERIC_SMP_IDLE_THREAD=y 1839+CONFIG_GENERIC_IDLE_POLL_SETUP=y 1840+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y 1841+CONFIG_ARCH_HAS_SET_MEMORY=y 1842+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y 1843+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y 1844+CONFIG_HAVE_RSEQ=y 1845+CONFIG_HAVE_CLK=y 1846+CONFIG_HAVE_PERF_REGS=y 1847+CONFIG_HAVE_PERF_USER_STACK_DUMP=y 1848+CONFIG_HAVE_ARCH_JUMP_LABEL=y 1849+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y 1850+CONFIG_HAVE_STACKPROTECTOR=y 1851+CONFIG_CC_HAS_STACKPROTECTOR_NONE=y 1852+CONFIG_STACKPROTECTOR=y 1853+CONFIG_STACKPROTECTOR_STRONG=y 1854+CONFIG_HAVE_CONTEXT_TRACKING=y 1855+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y 1856+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y 1857+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y 1858+CONFIG_MODULES_USE_ELF_REL=y 1859+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y 1860+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y 1861+CONFIG_HAVE_EXIT_THREAD=y 1862+CONFIG_ARCH_MMAP_RND_BITS=8 1863+CONFIG_CLONE_BACKWARDS=y 1864+CONFIG_OLD_SIGSUSPEND3=y 1865+CONFIG_OLD_SIGACTION=y 1866+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y 1867+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y 1868+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y 1869+CONFIG_STRICT_KERNEL_RWX=y 1870+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y 1871+CONFIG_STRICT_MODULE_RWX=y 1872+CONFIG_ARCH_HAS_PHYS_TO_DMA=y 1873+CONFIG_REFCOUNT_FULL=y 1874+ 1875+# 1876+# GCOV-based kernel profiling 1877+# 1878+# CONFIG_GCOV_KERNEL is not set 1879+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y 1880+CONFIG_PLUGIN_HOSTCC="" 1881+CONFIG_HAVE_GCC_PLUGINS=y 1882+CONFIG_RT_MUTEXES=y 1883+CONFIG_BASE_SMALL=0 1884+CONFIG_MODULES=y 1885+CONFIG_MODULE_FORCE_LOAD=y 1886+CONFIG_MODULE_UNLOAD=y 1887+CONFIG_MODULE_FORCE_UNLOAD=y 1888+# CONFIG_MODVERSIONS is not set 1889+# CONFIG_MODULE_SRCVERSION_ALL is not set 1890+# CONFIG_MODULE_SIG is not set 1891+# CONFIG_MODULE_COMPRESS is not set 1892+# CONFIG_TRIM_UNUSED_KSYMS is not set 1893+CONFIG_BLOCK=y 1894+CONFIG_LBDAF=y 1895+CONFIG_BLK_SCSI_REQUEST=y 1896+CONFIG_BLK_DEV_BSG=y 1897+# CONFIG_BLK_DEV_BSGLIB is not set 1898+# CONFIG_BLK_DEV_INTEGRITY is not set 1899+# CONFIG_BLK_DEV_ZONED is not set 1900+CONFIG_BLK_CMDLINE_PARSER=y 1901+# CONFIG_BLK_WBT is not set 1902+# CONFIG_BLK_DEBUG_FS is not set 1903+# CONFIG_BLK_SED_OPAL is not set 1904+ 1905+# 1906+# Partition Types 1907+# 1908+CONFIG_PARTITION_ADVANCED=y 1909+# CONFIG_ACORN_PARTITION is not set 1910+# CONFIG_AIX_PARTITION is not set 1911+# CONFIG_OSF_PARTITION is not set 1912+# CONFIG_AMIGA_PARTITION is not set 1913+# CONFIG_ATARI_PARTITION is not set 1914+# CONFIG_MAC_PARTITION is not set 1915+CONFIG_MSDOS_PARTITION=y 1916+# CONFIG_BSD_DISKLABEL is not set 1917+# CONFIG_MINIX_SUBPARTITION is not set 1918+# CONFIG_SOLARIS_X86_PARTITION is not set 1919+# CONFIG_UNIXWARE_DISKLABEL is not set 1920+# CONFIG_LDM_PARTITION is not set 1921+# CONFIG_SGI_PARTITION is not set 1922+# CONFIG_ULTRIX_PARTITION is not set 1923+# CONFIG_SUN_PARTITION is not set 1924+# CONFIG_KARMA_PARTITION is not set 1925+CONFIG_EFI_PARTITION=y 1926+# CONFIG_SYSV68_PARTITION is not set 1927+CONFIG_CMDLINE_PARTITION=y 1928+ 1929+# 1930+# IO Schedulers 1931+# 1932+CONFIG_IOSCHED_NOOP=y 1933+# CONFIG_IOSCHED_DEADLINE is not set 1934+CONFIG_IOSCHED_CFQ=y 1935+CONFIG_DEFAULT_CFQ=y 1936+# CONFIG_DEFAULT_NOOP is not set 1937+CONFIG_DEFAULT_IOSCHED="cfq" 1938+CONFIG_MQ_IOSCHED_DEADLINE=y 1939+CONFIG_MQ_IOSCHED_KYBER=y 1940+# CONFIG_IOSCHED_BFQ is not set 1941+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y 1942+CONFIG_INLINE_READ_UNLOCK=y 1943+CONFIG_INLINE_READ_UNLOCK_IRQ=y 1944+CONFIG_INLINE_WRITE_UNLOCK=y 1945+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y 1946+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y 1947+CONFIG_MUTEX_SPIN_ON_OWNER=y 1948+CONFIG_RWSEM_SPIN_ON_OWNER=y 1949+CONFIG_LOCK_SPIN_ON_OWNER=y 1950+CONFIG_FREEZER=y 1951+ 1952+# 1953+# Executable file formats 1954+# 1955+CONFIG_BINFMT_ELF=y 1956+# CONFIG_BINFMT_ELF_FDPIC is not set 1957+CONFIG_ELFCORE=y 1958+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y 1959+CONFIG_BINFMT_SCRIPT=y 1960+# CONFIG_BINFMT_FLAT is not set 1961+# CONFIG_BINFMT_MISC is not set 1962+CONFIG_COREDUMP=y 1963+ 1964+# 1965+# Memory Management options 1966+# 1967+CONFIG_FLATMEM=y 1968+CONFIG_FLAT_NODE_MEM_MAP=y 1969+CONFIG_HAVE_MEMBLOCK=y 1970+CONFIG_NO_BOOTMEM=y 1971+CONFIG_MEMORY_ISOLATION=y 1972+CONFIG_SPLIT_PTLOCK_CPUS=4 1973+CONFIG_COMPACTION=y 1974+CONFIG_MIGRATION=y 1975+CONFIG_BOUNCE=y 1976+# CONFIG_KSM is not set 1977+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 1978+# CONFIG_CLEANCACHE is not set 1979+CONFIG_CMA=y 1980+CONFIG_CMA_DEBUG=y 1981+# CONFIG_CMA_DEBUGFS is not set 1982+CONFIG_CMA_AREAS=7 1983+# CONFIG_ZPOOL is not set 1984+# CONFIG_ZBUD is not set 1985+# CONFIG_ZSMALLOC is not set 1986+CONFIG_GENERIC_EARLY_IOREMAP=y 1987+# CONFIG_IDLE_PAGE_TRACKING is not set 1988+CONFIG_FRAME_VECTOR=y 1989+# CONFIG_PERCPU_STATS is not set 1990+# CONFIG_GUP_BENCHMARK is not set 1991+CONFIG_NET=y 1992+ 1993+# 1994+# Networking options 1995+# 1996+CONFIG_PACKET=y 1997+# CONFIG_PACKET_DIAG is not set 1998+CONFIG_UNIX=y 1999+# CONFIG_UNIX_DIAG is not set 2000+# CONFIG_TLS is not set 2001+CONFIG_XFRM=y 2002+# CONFIG_XFRM_USER is not set 2003+# CONFIG_XFRM_INTERFACE is not set 2004+# CONFIG_XFRM_SUB_POLICY is not set 2005+# CONFIG_XFRM_MIGRATE is not set 2006+# CONFIG_XFRM_STATISTICS is not set 2007+# CONFIG_NET_KEY is not set 2008+CONFIG_INET=y 2009+# CONFIG_IP_MULTICAST is not set 2010+# CONFIG_IP_ADVANCED_ROUTER is not set 2011+CONFIG_IP_PNP=y 2012+CONFIG_IP_PNP_DHCP=y 2013+# CONFIG_IP_PNP_BOOTP is not set 2014+# CONFIG_IP_PNP_RARP is not set 2015+# CONFIG_NET_IPIP is not set 2016+# CONFIG_NET_IPGRE_DEMUX is not set 2017+# CONFIG_SYN_COOKIES is not set 2018+# CONFIG_NET_IPVTI is not set 2019+# CONFIG_NET_FOU is not set 2020+# CONFIG_INET_AH is not set 2021+# CONFIG_INET_ESP is not set 2022+# CONFIG_INET_IPCOMP is not set 2023+CONFIG_INET_XFRM_MODE_TRANSPORT=y 2024+CONFIG_INET_XFRM_MODE_TUNNEL=y 2025+CONFIG_INET_XFRM_MODE_BEET=y 2026+CONFIG_INET_DIAG=y 2027+CONFIG_INET_TCP_DIAG=y 2028+# CONFIG_INET_UDP_DIAG is not set 2029+# CONFIG_INET_RAW_DIAG is not set 2030+# CONFIG_INET_DIAG_DESTROY is not set 2031+# CONFIG_TCP_CONG_ADVANCED is not set 2032+CONFIG_TCP_CONG_CUBIC=y 2033+CONFIG_DEFAULT_TCP_CONG="cubic" 2034+# CONFIG_TCP_MD5SIG is not set 2035+CONFIG_IPV6=y 2036+# CONFIG_IPV6_ROUTER_PREF is not set 2037+# CONFIG_IPV6_OPTIMISTIC_DAD is not set 2038+# CONFIG_INET6_AH is not set 2039+# CONFIG_INET6_ESP is not set 2040+# CONFIG_INET6_IPCOMP is not set 2041+# CONFIG_IPV6_MIP6 is not set 2042+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set 2043+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set 2044+# CONFIG_INET6_XFRM_MODE_BEET is not set 2045+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 2046+# CONFIG_IPV6_SIT is not set 2047+# CONFIG_IPV6_TUNNEL is not set 2048+# CONFIG_IPV6_MULTIPLE_TABLES is not set 2049+# CONFIG_IPV6_MROUTE is not set 2050+# CONFIG_IPV6_SEG6_LWTUNNEL is not set 2051+# CONFIG_IPV6_SEG6_HMAC is not set 2052+# CONFIG_NETWORK_SECMARK is not set 2053+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set 2054+# CONFIG_NETFILTER is not set 2055+# CONFIG_BPFILTER is not set 2056+# CONFIG_IP_DCCP is not set 2057+# CONFIG_IP_SCTP is not set 2058+# CONFIG_RDS is not set 2059+# CONFIG_TIPC is not set 2060+# CONFIG_ATM is not set 2061+# CONFIG_L2TP is not set 2062+# CONFIG_BRIDGE is not set 2063+CONFIG_HAVE_NET_DSA=y 2064+# CONFIG_NET_DSA is not set 2065+CONFIG_VLAN_8021Q=y 2066+# CONFIG_VLAN_8021Q_GVRP is not set 2067+# CONFIG_VLAN_8021Q_MVRP is not set 2068+# CONFIG_DECNET is not set 2069+# CONFIG_LLC2 is not set 2070+# CONFIG_ATALK is not set 2071+# CONFIG_X25 is not set 2072+# CONFIG_LAPB is not set 2073+# CONFIG_PHONET is not set 2074+# CONFIG_6LOWPAN is not set 2075+# CONFIG_IEEE802154 is not set 2076+# CONFIG_NET_SCHED is not set 2077+# CONFIG_DCB is not set 2078+CONFIG_DNS_RESOLVER=y 2079+# CONFIG_BATMAN_ADV is not set 2080+# CONFIG_OPENVSWITCH is not set 2081+# CONFIG_VSOCKETS is not set 2082+# CONFIG_NETLINK_DIAG is not set 2083+# CONFIG_MPLS is not set 2084+# CONFIG_NET_NSH is not set 2085+# CONFIG_HSR is not set 2086+# CONFIG_NET_SWITCHDEV is not set 2087+# CONFIG_NET_L3_MASTER_DEV is not set 2088+# CONFIG_NET_NCSI is not set 2089+CONFIG_RPS=y 2090+CONFIG_RFS_ACCEL=y 2091+CONFIG_XPS=y 2092+# CONFIG_CGROUP_NET_PRIO is not set 2093+# CONFIG_CGROUP_NET_CLASSID is not set 2094+CONFIG_NET_RX_BUSY_POLL=y 2095+CONFIG_BQL=y 2096+# CONFIG_BPF_JIT is not set 2097+CONFIG_NET_FLOW_LIMIT=y 2098+ 2099+# 2100+# Network testing 2101+# 2102+# CONFIG_NET_PKTGEN is not set 2103+# CONFIG_HAMRADIO is not set 2104+# CONFIG_CAN is not set 2105+# CONFIG_BT is not set 2106+# CONFIG_AF_RXRPC is not set 2107+# CONFIG_AF_KCM is not set 2108+CONFIG_WIRELESS=y 2109+# CONFIG_CFG80211 is not set 2110+ 2111+# 2112+# CFG80211 needs to be enabled for MAC80211 2113+# 2114+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 2115+# CONFIG_WIMAX is not set 2116+# CONFIG_RFKILL is not set 2117+# CONFIG_NET_9P is not set 2118+# CONFIG_CAIF is not set 2119+# CONFIG_CEPH_LIB is not set 2120+# CONFIG_NFC is not set 2121+# CONFIG_PSAMPLE is not set 2122+# CONFIG_NET_IFE is not set 2123+# CONFIG_LWTUNNEL is not set 2124+CONFIG_GRO_CELLS=y 2125+# CONFIG_NET_DEVLINK is not set 2126+CONFIG_MAY_USE_DEVLINK=y 2127+# CONFIG_FAILOVER is not set 2128+CONFIG_HAVE_EBPF_JIT=y 2129+ 2130+# 2131+# Device Drivers 2132+# 2133+CONFIG_ARM_AMBA=y 2134+ 2135+# 2136+# Generic Driver Options 2137+# 2138+CONFIG_UEVENT_HELPER=y 2139+CONFIG_UEVENT_HELPER_PATH="" 2140+CONFIG_DEVTMPFS=y 2141+CONFIG_DEVTMPFS_MOUNT=y 2142+CONFIG_STANDALONE=y 2143+CONFIG_PREVENT_FIRMWARE_BUILD=y 2144+ 2145+# 2146+# Firmware loader 2147+# 2148+CONFIG_FW_LOADER=y 2149+CONFIG_EXTRA_FIRMWARE="" 2150+# CONFIG_FW_LOADER_USER_HELPER is not set 2151+CONFIG_ALLOW_DEV_COREDUMP=y 2152+# CONFIG_DEBUG_DRIVER is not set 2153+# CONFIG_DEBUG_DEVRES is not set 2154+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set 2155+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set 2156+CONFIG_GENERIC_CPU_AUTOPROBE=y 2157+CONFIG_REGMAP=y 2158+CONFIG_REGMAP_I2C=y 2159+CONFIG_REGMAP_SPI=y 2160+CONFIG_REGMAP_MMIO=y 2161+CONFIG_DMA_SHARED_BUFFER=y 2162+# CONFIG_DMA_FENCE_TRACE is not set 2163+CONFIG_DMA_CMA=y 2164+ 2165+# 2166+# Default contiguous memory area size: 2167+# 2168+CONFIG_CMA_SIZE_MBYTES=16 2169+CONFIG_CMA_SIZE_SEL_MBYTES=y 2170+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set 2171+# CONFIG_CMA_SIZE_SEL_MIN is not set 2172+# CONFIG_CMA_SIZE_SEL_MAX is not set 2173+CONFIG_CMA_ALIGNMENT=8 2174+CONFIG_GENERIC_ARCH_TOPOLOGY=y 2175+ 2176+# 2177+# Bus devices 2178+# 2179+# CONFIG_BRCMSTB_GISB_ARB is not set 2180+# CONFIG_SIMPLE_PM_BUS is not set 2181+# CONFIG_VEXPRESS_CONFIG is not set 2182+# CONFIG_CONNECTOR is not set 2183+# CONFIG_GNSS is not set 2184+# CONFIG_MTD is not set 2185+CONFIG_DTC=y 2186+CONFIG_OF=y 2187+# CONFIG_OF_UNITTEST is not set 2188+CONFIG_OF_FLATTREE=y 2189+CONFIG_OF_EARLY_FLATTREE=y 2190+CONFIG_OF_KOBJ=y 2191+CONFIG_OF_ADDRESS=y 2192+CONFIG_OF_IRQ=y 2193+CONFIG_OF_NET=y 2194+CONFIG_OF_MDIO=y 2195+CONFIG_OF_RESERVED_MEM=y 2196+# CONFIG_OF_OVERLAY is not set 2197+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y 2198+# CONFIG_PARPORT is not set 2199+CONFIG_BLK_DEV=y 2200+# CONFIG_BLK_DEV_NULL_BLK is not set 2201+# CONFIG_BLK_DEV_LOOP is not set 2202+# CONFIG_BLK_DEV_DRBD is not set 2203+# CONFIG_BLK_DEV_NBD is not set 2204+CONFIG_BLK_DEV_RAM=y 2205+CONFIG_BLK_DEV_RAM_COUNT=16 2206+CONFIG_BLK_DEV_RAM_SIZE=65536 2207+# CONFIG_CDROM_PKTCDVD is not set 2208+# CONFIG_ATA_OVER_ETH is not set 2209+# CONFIG_BLK_DEV_RBD is not set 2210+ 2211+# 2212+# NVME Support 2213+# 2214+# CONFIG_NVME_FC is not set 2215+# CONFIG_NVME_TARGET is not set 2216+ 2217+# 2218+# Misc devices 2219+# 2220+# CONFIG_AD525X_DPOT is not set 2221+# CONFIG_DUMMY_IRQ is not set 2222+# CONFIG_ICS932S401 is not set 2223+# CONFIG_ENCLOSURE_SERVICES is not set 2224+# CONFIG_APDS9802ALS is not set 2225+# CONFIG_ISL29003 is not set 2226+# CONFIG_ISL29020 is not set 2227+# CONFIG_SENSORS_TSL2550 is not set 2228+# CONFIG_SENSORS_BH1770 is not set 2229+# CONFIG_SENSORS_APDS990X is not set 2230+# CONFIG_HMC6352 is not set 2231+# CONFIG_DS1682 is not set 2232+# CONFIG_USB_SWITCH_FSA9480 is not set 2233+# CONFIG_LATTICE_ECP3_CONFIG is not set 2234+# CONFIG_SRAM is not set 2235+# CONFIG_C2PORT is not set 2236+ 2237+# 2238+# EEPROM support 2239+# 2240+# CONFIG_EEPROM_AT24 is not set 2241+# CONFIG_EEPROM_AT25 is not set 2242+# CONFIG_EEPROM_LEGACY is not set 2243+# CONFIG_EEPROM_MAX6875 is not set 2244+# CONFIG_EEPROM_93CX6 is not set 2245+# CONFIG_EEPROM_93XX46 is not set 2246+# CONFIG_EEPROM_IDT_89HPESX is not set 2247+ 2248+# 2249+# Texas Instruments shared transport line discipline 2250+# 2251+# CONFIG_TI_ST is not set 2252+# CONFIG_SENSORS_LIS3_SPI is not set 2253+# CONFIG_SENSORS_LIS3_I2C is not set 2254+# CONFIG_ALTERA_STAPL is not set 2255+ 2256+# 2257+# Intel MIC & related support 2258+# 2259+ 2260+# 2261+# Intel MIC Bus Driver 2262+# 2263+ 2264+# 2265+# SCIF Bus Driver 2266+# 2267+ 2268+# 2269+# VOP Bus Driver 2270+# 2271+ 2272+# 2273+# Intel MIC Host Driver 2274+# 2275+ 2276+# 2277+# Intel MIC Card Driver 2278+# 2279+ 2280+# 2281+# SCIF Driver 2282+# 2283+ 2284+# 2285+# Intel MIC Coprocessor State Management (COSM) Drivers 2286+# 2287+ 2288+# 2289+# VOP Driver 2290+# 2291+# CONFIG_ECHO is not set 2292+# CONFIG_MISC_RTSX_USB is not set 2293+ 2294+# 2295+# SCSI device support 2296+# 2297+CONFIG_SCSI_MOD=y 2298+# CONFIG_RAID_ATTRS is not set 2299+CONFIG_SCSI=y 2300+CONFIG_SCSI_DMA=y 2301+# CONFIG_SCSI_MQ_DEFAULT is not set 2302+CONFIG_SCSI_PROC_FS=y 2303+ 2304+# 2305+# SCSI support type (disk, tape, CD-ROM) 2306+# 2307+CONFIG_BLK_DEV_SD=y 2308+# CONFIG_CHR_DEV_ST is not set 2309+# CONFIG_CHR_DEV_OSST is not set 2310+# CONFIG_BLK_DEV_SR is not set 2311+# CONFIG_CHR_DEV_SG is not set 2312+# CONFIG_CHR_DEV_SCH is not set 2313+# CONFIG_SCSI_CONSTANTS is not set 2314+# CONFIG_SCSI_LOGGING is not set 2315+# CONFIG_SCSI_SCAN_ASYNC is not set 2316+ 2317+# 2318+# SCSI Transports 2319+# 2320+# CONFIG_SCSI_SPI_ATTRS is not set 2321+# CONFIG_SCSI_FC_ATTRS is not set 2322+# CONFIG_SCSI_ISCSI_ATTRS is not set 2323+# CONFIG_SCSI_SAS_ATTRS is not set 2324+# CONFIG_SCSI_SAS_LIBSAS is not set 2325+# CONFIG_SCSI_SRP_ATTRS is not set 2326+CONFIG_SCSI_LOWLEVEL=y 2327+# CONFIG_ISCSI_TCP is not set 2328+# CONFIG_ISCSI_BOOT_SYSFS is not set 2329+# CONFIG_SCSI_UFSHCD is not set 2330+# CONFIG_SCSI_DEBUG is not set 2331+# CONFIG_SCSI_DH is not set 2332+# CONFIG_SCSI_OSD_INITIATOR is not set 2333+# CONFIG_ATA is not set 2334+# CONFIG_MD is not set 2335+# CONFIG_TARGET_CORE is not set 2336+CONFIG_NETDEVICES=y 2337+CONFIG_MII=y 2338+CONFIG_NET_CORE=y 2339+# CONFIG_BONDING is not set 2340+# CONFIG_DUMMY is not set 2341+# CONFIG_EQUALIZER is not set 2342+# CONFIG_NET_TEAM is not set 2343+# CONFIG_MACVLAN is not set 2344+# CONFIG_VXLAN is not set 2345+# CONFIG_GENEVE is not set 2346+# CONFIG_GTP is not set 2347+# CONFIG_MACSEC is not set 2348+# CONFIG_NETCONSOLE is not set 2349+# CONFIG_TUN is not set 2350+# CONFIG_TUN_VNET_CROSS_LE is not set 2351+# CONFIG_VETH is not set 2352+# CONFIG_NLMON is not set 2353+ 2354+# 2355+# CAIF transport drivers 2356+# 2357+ 2358+# 2359+# Distributed Switch Architecture drivers 2360+# 2361+CONFIG_ETHERNET=y 2362+CONFIG_NET_VENDOR_ALACRITECH=y 2363+# CONFIG_ALTERA_TSE is not set 2364+# CONFIG_NET_VENDOR_AMAZON is not set 2365+CONFIG_NET_VENDOR_AQUANTIA=y 2366+# CONFIG_NET_VENDOR_ARC is not set 2367+# CONFIG_NET_VENDOR_AURORA is not set 2368+# CONFIG_NET_VENDOR_BROADCOM is not set 2369+CONFIG_NET_VENDOR_CADENCE=y 2370+# CONFIG_MACB is not set 2371+CONFIG_NET_VENDOR_CAVIUM=y 2372+# CONFIG_NET_VENDOR_CIRRUS is not set 2373+CONFIG_NET_VENDOR_CORTINA=y 2374+# CONFIG_GEMINI_ETHERNET is not set 2375+# CONFIG_DM9000 is not set 2376+# CONFIG_DNET is not set 2377+# CONFIG_NET_VENDOR_EZCHIP is not set 2378+# CONFIG_NET_VENDOR_FARADAY is not set 2379+CONFIG_NET_VENDOR_HISILICON=y 2380+# CONFIG_HIX5HD2_GMAC is not set 2381+CONFIG_HISI_FEMAC=y 2382+# CONFIG_HIP04_ETH is not set 2383+# CONFIG_HNS is not set 2384+# CONFIG_HNS_DSAF is not set 2385+# CONFIG_HNS_ENET is not set 2386+# CONFIG_HIETH_GMAC is not set 2387+CONFIG_NET_VENDOR_HUAWEI=y 2388+# CONFIG_NET_VENDOR_INTEL is not set 2389+# CONFIG_NET_VENDOR_MARVELL is not set 2390+CONFIG_NET_VENDOR_MELLANOX=y 2391+# CONFIG_MLXSW_CORE is not set 2392+# CONFIG_MLXFW is not set 2393+# CONFIG_NET_VENDOR_MICREL is not set 2394+# CONFIG_NET_VENDOR_MICROCHIP is not set 2395+CONFIG_NET_VENDOR_MICROSEMI=y 2396+# CONFIG_NET_VENDOR_NATSEMI is not set 2397+# CONFIG_NET_VENDOR_NETRONOME is not set 2398+CONFIG_NET_VENDOR_NI=y 2399+# CONFIG_ETHOC is not set 2400+# CONFIG_NET_VENDOR_QUALCOMM is not set 2401+# CONFIG_NET_VENDOR_RENESAS is not set 2402+# CONFIG_NET_VENDOR_ROCKER is not set 2403+# CONFIG_NET_VENDOR_SAMSUNG is not set 2404+# CONFIG_NET_VENDOR_SEEQ is not set 2405+CONFIG_NET_VENDOR_SOLARFLARE=y 2406+# CONFIG_NET_VENDOR_SMSC is not set 2407+CONFIG_NET_VENDOR_SOCIONEXT=y 2408+# CONFIG_NET_VENDOR_STMICRO is not set 2409+# CONFIG_NET_VENDOR_SYNOPSYS is not set 2410+# CONFIG_NET_VENDOR_VIA is not set 2411+# CONFIG_NET_VENDOR_WIZNET is not set 2412+CONFIG_MDIO_DEVICE=y 2413+CONFIG_MDIO_BUS=y 2414+# CONFIG_MDIO_BCM_UNIMAC is not set 2415+# CONFIG_MDIO_BITBANG is not set 2416+# CONFIG_MDIO_BUS_MUX_GPIO is not set 2417+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set 2418+CONFIG_MDIO_HISI_FEMAC=y 2419+# CONFIG_MDIO_HISI_GEMAC is not set 2420+# CONFIG_MDIO_MSCC_MIIM is not set 2421+CONFIG_PHYLIB=y 2422+CONFIG_SWPHY=y 2423+ 2424+# 2425+# MII PHY device drivers 2426+# 2427+# CONFIG_AMD_PHY is not set 2428+# CONFIG_AQUANTIA_PHY is not set 2429+# CONFIG_AX88796B_PHY is not set 2430+# CONFIG_AT803X_PHY is not set 2431+# CONFIG_BCM7XXX_PHY is not set 2432+# CONFIG_BCM87XX_PHY is not set 2433+# CONFIG_BROADCOM_PHY is not set 2434+# CONFIG_CICADA_PHY is not set 2435+# CONFIG_CORTINA_PHY is not set 2436+# CONFIG_DAVICOM_PHY is not set 2437+# CONFIG_DP83822_PHY is not set 2438+# CONFIG_DP83TC811_PHY is not set 2439+# CONFIG_DP83848_PHY is not set 2440+# CONFIG_DP83867_PHY is not set 2441+CONFIG_FIXED_PHY=y 2442+# CONFIG_ICPLUS_PHY is not set 2443+# CONFIG_INTEL_XWAY_PHY is not set 2444+# CONFIG_LSI_ET1011C_PHY is not set 2445+# CONFIG_LXT_PHY is not set 2446+# CONFIG_MARVELL_PHY is not set 2447+# CONFIG_MARVELL_10G_PHY is not set 2448+# CONFIG_MICREL_PHY is not set 2449+# CONFIG_MICROCHIP_PHY is not set 2450+# CONFIG_MICROCHIP_T1_PHY is not set 2451+# CONFIG_MICROSEMI_PHY is not set 2452+# CONFIG_NATIONAL_PHY is not set 2453+# CONFIG_QSEMI_PHY is not set 2454+# CONFIG_REALTEK_PHY is not set 2455+# CONFIG_RENESAS_PHY is not set 2456+# CONFIG_ROCKCHIP_PHY is not set 2457+# CONFIG_SMSC_PHY is not set 2458+# CONFIG_STE10XP is not set 2459+# CONFIG_TERANETICS_PHY is not set 2460+# CONFIG_VITESSE_PHY is not set 2461+# CONFIG_XILINX_GMII2RGMII is not set 2462+# CONFIG_MICREL_KS8995MA is not set 2463+# CONFIG_PPP is not set 2464+# CONFIG_SLIP is not set 2465+CONFIG_USB_NET_DRIVERS=y 2466+# CONFIG_USB_CATC is not set 2467+# CONFIG_USB_KAWETH is not set 2468+# CONFIG_USB_PEGASUS is not set 2469+# CONFIG_USB_RTL8150 is not set 2470+CONFIG_USB_RTL8152=y 2471+# CONFIG_USB_LAN78XX is not set 2472+# CONFIG_USB_USBNET is not set 2473+# CONFIG_USB_IPHETH is not set 2474+CONFIG_WLAN=y 2475+CONFIG_WLAN_VENDOR_ADMTEK=y 2476+CONFIG_WLAN_VENDOR_ATH=y 2477+# CONFIG_ATH_DEBUG is not set 2478+CONFIG_WLAN_VENDOR_ATMEL=y 2479+CONFIG_WLAN_VENDOR_BROADCOM=y 2480+CONFIG_WLAN_VENDOR_CISCO=y 2481+CONFIG_WLAN_VENDOR_INTEL=y 2482+CONFIG_WLAN_VENDOR_INTERSIL=y 2483+# CONFIG_HOSTAP is not set 2484+CONFIG_WLAN_VENDOR_MARVELL=y 2485+CONFIG_WLAN_VENDOR_MEDIATEK=y 2486+CONFIG_WLAN_VENDOR_RALINK=y 2487+CONFIG_WLAN_VENDOR_REALTEK=y 2488+CONFIG_WLAN_VENDOR_RSI=y 2489+CONFIG_WLAN_VENDOR_ST=y 2490+CONFIG_WLAN_VENDOR_TI=y 2491+CONFIG_WLAN_VENDOR_ZYDAS=y 2492+CONFIG_WLAN_VENDOR_QUANTENNA=y 2493+ 2494+# 2495+# Enable WiMAX (Networking options) to see the WiMAX drivers 2496+# 2497+# CONFIG_WAN is not set 2498+# CONFIG_NETDEVSIM is not set 2499+# CONFIG_NET_FAILOVER is not set 2500+# CONFIG_ISDN is not set 2501+ 2502+# 2503+# Input device support 2504+# 2505+CONFIG_INPUT=y 2506+CONFIG_INPUT_FF_MEMLESS=y 2507+# CONFIG_INPUT_POLLDEV is not set 2508+# CONFIG_INPUT_SPARSEKMAP is not set 2509+# CONFIG_INPUT_MATRIXKMAP is not set 2510+ 2511+# 2512+# Userland interfaces 2513+# 2514+CONFIG_INPUT_MOUSEDEV=y 2515+CONFIG_INPUT_MOUSEDEV_PSAUX=y 2516+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 2517+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 2518+CONFIG_INPUT_JOYDEV=y 2519+CONFIG_INPUT_EVDEV=y 2520+# CONFIG_INPUT_EVBUG is not set 2521+ 2522+# 2523+# Input Device Drivers 2524+# 2525+CONFIG_INPUT_KEYBOARD=y 2526+# CONFIG_KEYBOARD_ADP5588 is not set 2527+# CONFIG_KEYBOARD_ADP5589 is not set 2528+CONFIG_KEYBOARD_ATKBD=y 2529+# CONFIG_KEYBOARD_QT1070 is not set 2530+# CONFIG_KEYBOARD_QT2160 is not set 2531+# CONFIG_KEYBOARD_DLINK_DIR685 is not set 2532+# CONFIG_KEYBOARD_LKKBD is not set 2533+# CONFIG_KEYBOARD_GPIO is not set 2534+# CONFIG_KEYBOARD_GPIO_POLLED is not set 2535+# CONFIG_KEYBOARD_TCA6416 is not set 2536+# CONFIG_KEYBOARD_TCA8418 is not set 2537+# CONFIG_KEYBOARD_MATRIX is not set 2538+# CONFIG_KEYBOARD_LM8333 is not set 2539+# CONFIG_KEYBOARD_MAX7359 is not set 2540+# CONFIG_KEYBOARD_MCS is not set 2541+# CONFIG_KEYBOARD_MPR121 is not set 2542+# CONFIG_KEYBOARD_NEWTON is not set 2543+# CONFIG_KEYBOARD_OPENCORES is not set 2544+# CONFIG_KEYBOARD_SAMSUNG is not set 2545+# CONFIG_KEYBOARD_STOWAWAY is not set 2546+# CONFIG_KEYBOARD_SUNKBD is not set 2547+# CONFIG_KEYBOARD_OMAP4 is not set 2548+# CONFIG_KEYBOARD_XTKBD is not set 2549+# CONFIG_KEYBOARD_CAP11XX is not set 2550+# CONFIG_KEYBOARD_BCM is not set 2551+CONFIG_INPUT_MOUSE=y 2552+CONFIG_MOUSE_PS2=y 2553+CONFIG_MOUSE_PS2_ALPS=y 2554+CONFIG_MOUSE_PS2_BYD=y 2555+CONFIG_MOUSE_PS2_LOGIPS2PP=y 2556+CONFIG_MOUSE_PS2_SYNAPTICS=y 2557+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y 2558+CONFIG_MOUSE_PS2_CYPRESS=y 2559+CONFIG_MOUSE_PS2_TRACKPOINT=y 2560+# CONFIG_MOUSE_PS2_ELANTECH is not set 2561+# CONFIG_MOUSE_PS2_SENTELIC is not set 2562+# CONFIG_MOUSE_PS2_TOUCHKIT is not set 2563+CONFIG_MOUSE_PS2_FOCALTECH=y 2564+CONFIG_MOUSE_PS2_SMBUS=y 2565+# CONFIG_MOUSE_SERIAL is not set 2566+# CONFIG_MOUSE_APPLETOUCH is not set 2567+# CONFIG_MOUSE_BCM5974 is not set 2568+# CONFIG_MOUSE_CYAPA is not set 2569+# CONFIG_MOUSE_ELAN_I2C is not set 2570+# CONFIG_MOUSE_VSXXXAA is not set 2571+# CONFIG_MOUSE_GPIO is not set 2572+# CONFIG_MOUSE_SYNAPTICS_I2C is not set 2573+# CONFIG_MOUSE_SYNAPTICS_USB is not set 2574+CONFIG_INPUT_JOYSTICK=y 2575+# CONFIG_JOYSTICK_ANALOG is not set 2576+# CONFIG_JOYSTICK_A3D is not set 2577+# CONFIG_JOYSTICK_ADI is not set 2578+# CONFIG_JOYSTICK_COBRA is not set 2579+# CONFIG_JOYSTICK_GF2K is not set 2580+# CONFIG_JOYSTICK_GRIP is not set 2581+# CONFIG_JOYSTICK_GRIP_MP is not set 2582+# CONFIG_JOYSTICK_GUILLEMOT is not set 2583+# CONFIG_JOYSTICK_INTERACT is not set 2584+# CONFIG_JOYSTICK_SIDEWINDER is not set 2585+# CONFIG_JOYSTICK_TMDC is not set 2586+# CONFIG_JOYSTICK_IFORCE is not set 2587+# CONFIG_JOYSTICK_WARRIOR is not set 2588+# CONFIG_JOYSTICK_MAGELLAN is not set 2589+# CONFIG_JOYSTICK_SPACEORB is not set 2590+# CONFIG_JOYSTICK_SPACEBALL is not set 2591+# CONFIG_JOYSTICK_STINGER is not set 2592+# CONFIG_JOYSTICK_TWIDJOY is not set 2593+# CONFIG_JOYSTICK_ZHENHUA is not set 2594+# CONFIG_JOYSTICK_AS5011 is not set 2595+# CONFIG_JOYSTICK_JOYDUMP is not set 2596+CONFIG_JOYSTICK_XPAD=y 2597+CONFIG_JOYSTICK_XPAD_FF=y 2598+# CONFIG_JOYSTICK_PSXPAD_SPI is not set 2599+# CONFIG_JOYSTICK_PXRC is not set 2600+# CONFIG_INPUT_TABLET is not set 2601+# CONFIG_INPUT_TOUCHSCREEN is not set 2602+# CONFIG_INPUT_MISC is not set 2603+# CONFIG_RMI4_CORE is not set 2604+ 2605+# 2606+# Hardware I/O ports 2607+# 2608+CONFIG_SERIO=y 2609+CONFIG_SERIO_SERPORT=y 2610+# CONFIG_SERIO_AMBAKMI is not set 2611+CONFIG_SERIO_LIBPS2=y 2612+# CONFIG_SERIO_RAW is not set 2613+# CONFIG_SERIO_ALTERA_PS2 is not set 2614+# CONFIG_SERIO_PS2MULT is not set 2615+# CONFIG_SERIO_ARC_PS2 is not set 2616+# CONFIG_SERIO_APBPS2 is not set 2617+# CONFIG_SERIO_GPIO_PS2 is not set 2618+# CONFIG_USERIO is not set 2619+# CONFIG_GAMEPORT is not set 2620+ 2621+# 2622+# Character devices 2623+# 2624+CONFIG_TTY=y 2625+CONFIG_VT=y 2626+CONFIG_CONSOLE_TRANSLATIONS=y 2627+CONFIG_VT_CONSOLE=y 2628+CONFIG_VT_CONSOLE_SLEEP=y 2629+CONFIG_HW_CONSOLE=y 2630+# CONFIG_VT_HW_CONSOLE_BINDING is not set 2631+CONFIG_UNIX98_PTYS=y 2632+# CONFIG_LEGACY_PTYS is not set 2633+# CONFIG_SERIAL_NONSTANDARD is not set 2634+# CONFIG_N_GSM is not set 2635+# CONFIG_TRACE_SINK is not set 2636+CONFIG_LDISC_AUTOLOAD=y 2637+CONFIG_DEVMEM=y 2638+CONFIG_DEVKMEM=y 2639+ 2640+# 2641+# Serial drivers 2642+# 2643+CONFIG_SERIAL_EARLYCON=y 2644+# CONFIG_SERIAL_8250 is not set 2645+ 2646+# 2647+# Non-8250 serial port support 2648+# 2649+# CONFIG_SERIAL_AMBA_PL010 is not set 2650+CONFIG_SERIAL_AMBA_PL011=y 2651+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y 2652+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set 2653+# CONFIG_SERIAL_MAX3100 is not set 2654+# CONFIG_SERIAL_MAX310X is not set 2655+# CONFIG_SERIAL_UARTLITE is not set 2656+CONFIG_SERIAL_CORE=y 2657+CONFIG_SERIAL_CORE_CONSOLE=y 2658+# CONFIG_SERIAL_SCCNXP is not set 2659+# CONFIG_SERIAL_SC16IS7XX is not set 2660+# CONFIG_SERIAL_BCM63XX is not set 2661+# CONFIG_SERIAL_ALTERA_JTAGUART is not set 2662+# CONFIG_SERIAL_ALTERA_UART is not set 2663+# CONFIG_SERIAL_IFX6X60 is not set 2664+# CONFIG_SERIAL_XILINX_PS_UART is not set 2665+# CONFIG_SERIAL_ARC is not set 2666+# CONFIG_SERIAL_FSL_LPUART is not set 2667+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set 2668+# CONFIG_SERIAL_ST_ASC is not set 2669+# CONFIG_SERIAL_DEV_BUS is not set 2670+# CONFIG_HVC_DCC is not set 2671+# CONFIG_IPMI_HANDLER is not set 2672+# CONFIG_HW_RANDOM is not set 2673+# CONFIG_RAW_DRIVER is not set 2674+# CONFIG_TCG_TPM is not set 2675+# CONFIG_XILLYBUS is not set 2676+ 2677+# 2678+# I2C support 2679+# 2680+CONFIG_I2C=y 2681+CONFIG_I2C_BOARDINFO=y 2682+# CONFIG_I2C_COMPAT is not set 2683+CONFIG_I2C_CHARDEV=y 2684+CONFIG_I2C_MUX=y 2685+ 2686+# 2687+# Multiplexer I2C Chip support 2688+# 2689+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set 2690+# CONFIG_I2C_MUX_GPIO is not set 2691+# CONFIG_I2C_MUX_GPMUX is not set 2692+# CONFIG_I2C_MUX_LTC4306 is not set 2693+# CONFIG_I2C_MUX_PCA9541 is not set 2694+# CONFIG_I2C_MUX_PCA954x is not set 2695+# CONFIG_I2C_MUX_PINCTRL is not set 2696+# CONFIG_I2C_MUX_REG is not set 2697+# CONFIG_I2C_DEMUX_PINCTRL is not set 2698+# CONFIG_I2C_MUX_MLXCPLD is not set 2699+# CONFIG_I2C_HELPER_AUTO is not set 2700+# CONFIG_I2C_SMBUS is not set 2701+ 2702+# 2703+# I2C Algorithms 2704+# 2705+# CONFIG_I2C_ALGOBIT is not set 2706+# CONFIG_I2C_ALGOPCF is not set 2707+# CONFIG_I2C_ALGOPCA is not set 2708+ 2709+# 2710+# I2C Hardware Bus support 2711+# 2712+ 2713+# 2714+# I2C system bus drivers (mostly embedded / system-on-chip) 2715+# 2716+# CONFIG_I2C_CBUS_GPIO is not set 2717+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set 2718+# CONFIG_I2C_EMEV2 is not set 2719+# CONFIG_I2C_GPIO is not set 2720+CONFIG_I2C_HIBVT=y 2721+# CONFIG_I2C_NOMADIK is not set 2722+# CONFIG_I2C_OCORES is not set 2723+# CONFIG_I2C_PCA_PLATFORM is not set 2724+# CONFIG_I2C_RK3X is not set 2725+# CONFIG_I2C_SIMTEC is not set 2726+# CONFIG_I2C_XILINX is not set 2727+ 2728+# 2729+# External I2C/SMBus adapter drivers 2730+# 2731+# CONFIG_I2C_DIOLAN_U2C is not set 2732+# CONFIG_I2C_PARPORT_LIGHT is not set 2733+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set 2734+# CONFIG_I2C_TAOS_EVM is not set 2735+# CONFIG_I2C_TINY_USB is not set 2736+ 2737+# 2738+# Other I2C/SMBus bus drivers 2739+# 2740+CONFIG_DMA_MSG_MIN_LEN=5 2741+CONFIG_DMA_MSG_MAX_LEN=4090 2742+# CONFIG_I2C_STUB is not set 2743+# CONFIG_I2C_SLAVE is not set 2744+# CONFIG_I2C_DEBUG_CORE is not set 2745+# CONFIG_I2C_DEBUG_ALGO is not set 2746+# CONFIG_I2C_DEBUG_BUS is not set 2747+CONFIG_SPI=y 2748+# CONFIG_SPI_DEBUG is not set 2749+CONFIG_SPI_MASTER=y 2750+# CONFIG_SPI_MEM is not set 2751+ 2752+# 2753+# SPI Master Controller Drivers 2754+# 2755+# CONFIG_SPI_ALTERA is not set 2756+# CONFIG_SPI_AXI_SPI_ENGINE is not set 2757+# CONFIG_SPI_BITBANG is not set 2758+# CONFIG_SPI_CADENCE is not set 2759+# CONFIG_SPI_DESIGNWARE is not set 2760+# CONFIG_SPI_GPIO is not set 2761+# CONFIG_SPI_FSL_SPI is not set 2762+# CONFIG_SPI_OC_TINY is not set 2763+CONFIG_SPI_PL022=y 2764+# CONFIG_SPI_ROCKCHIP is not set 2765+# CONFIG_SPI_SC18IS602 is not set 2766+# CONFIG_SPI_XCOMM is not set 2767+# CONFIG_SPI_XILINX is not set 2768+# CONFIG_SPI_ZYNQMP_GQSPI is not set 2769+ 2770+# 2771+# SPI Protocol Masters 2772+# 2773+CONFIG_SPI_SPIDEV=y 2774+# CONFIG_SPI_LOOPBACK_TEST is not set 2775+# CONFIG_SPI_TLE62X0 is not set 2776+# CONFIG_SPI_SLAVE is not set 2777+# CONFIG_SPMI is not set 2778+# CONFIG_HSI is not set 2779+# CONFIG_PPS is not set 2780+ 2781+# 2782+# PTP clock support 2783+# 2784+# CONFIG_PTP_1588_CLOCK is not set 2785+ 2786+# 2787+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. 2788+# 2789+CONFIG_PINCTRL=y 2790+# CONFIG_DEBUG_PINCTRL is not set 2791+# CONFIG_PINCTRL_AMD is not set 2792+# CONFIG_PINCTRL_MCP23S08 is not set 2793+# CONFIG_PINCTRL_SINGLE is not set 2794+# CONFIG_PINCTRL_SX150X is not set 2795+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y 2796+CONFIG_GPIOLIB=y 2797+CONFIG_GPIOLIB_FASTPATH_LIMIT=512 2798+CONFIG_OF_GPIO=y 2799+CONFIG_GPIOLIB_IRQCHIP=y 2800+# CONFIG_DEBUG_GPIO is not set 2801+CONFIG_GPIO_SYSFS=y 2802+CONFIG_GPIO_GENERIC=y 2803+ 2804+# 2805+# Memory mapped GPIO drivers 2806+# 2807+# CONFIG_GPIO_74XX_MMIO is not set 2808+# CONFIG_GPIO_ALTERA is not set 2809+# CONFIG_GPIO_DWAPB is not set 2810+# CONFIG_GPIO_FTGPIO010 is not set 2811+CONFIG_GPIO_GENERIC_PLATFORM=y 2812+# CONFIG_GPIO_GRGPIO is not set 2813+# CONFIG_GPIO_HLWD is not set 2814+# CONFIG_GPIO_MB86S7X is not set 2815+# CONFIG_GPIO_MOCKUP is not set 2816+# CONFIG_GPIO_MPC8XXX is not set 2817+CONFIG_GPIO_PL061=y 2818+# CONFIG_GPIO_SYSCON is not set 2819+# CONFIG_GPIO_XILINX is not set 2820+# CONFIG_GPIO_ZEVIO is not set 2821+ 2822+# 2823+# I2C GPIO expanders 2824+# 2825+# CONFIG_GPIO_ADP5588 is not set 2826+# CONFIG_GPIO_ADNP is not set 2827+# CONFIG_GPIO_MAX7300 is not set 2828+# CONFIG_GPIO_MAX732X is not set 2829+# CONFIG_GPIO_PCA953X is not set 2830+# CONFIG_GPIO_PCF857X is not set 2831+# CONFIG_GPIO_TPIC2810 is not set 2832+ 2833+# 2834+# MFD GPIO expanders 2835+# 2836+# CONFIG_HTC_EGPIO is not set 2837+ 2838+# 2839+# SPI GPIO expanders 2840+# 2841+# CONFIG_GPIO_74X164 is not set 2842+# CONFIG_GPIO_MAX3191X is not set 2843+# CONFIG_GPIO_MAX7301 is not set 2844+# CONFIG_GPIO_MC33880 is not set 2845+# CONFIG_GPIO_PISOSR is not set 2846+# CONFIG_GPIO_XRA1403 is not set 2847+ 2848+# 2849+# USB GPIO expanders 2850+# 2851+# CONFIG_W1 is not set 2852+# CONFIG_POWER_AVS is not set 2853+CONFIG_POWER_RESET=y 2854+# CONFIG_POWER_RESET_BRCMKONA is not set 2855+# CONFIG_POWER_RESET_BRCMSTB is not set 2856+# CONFIG_POWER_RESET_GPIO is not set 2857+# CONFIG_POWER_RESET_GPIO_RESTART is not set 2858+CONFIG_POWER_RESET_HISI=y 2859+# CONFIG_POWER_RESET_LTC2952 is not set 2860+# CONFIG_POWER_RESET_RESTART is not set 2861+# CONFIG_POWER_RESET_VERSATILE is not set 2862+CONFIG_POWER_RESET_SYSCON=y 2863+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set 2864+# CONFIG_SYSCON_REBOOT_MODE is not set 2865+CONFIG_POWER_SUPPLY=y 2866+# CONFIG_POWER_SUPPLY_DEBUG is not set 2867+# CONFIG_PDA_POWER is not set 2868+# CONFIG_TEST_POWER is not set 2869+# CONFIG_CHARGER_ADP5061 is not set 2870+# CONFIG_BATTERY_DS2780 is not set 2871+# CONFIG_BATTERY_DS2781 is not set 2872+# CONFIG_BATTERY_DS2782 is not set 2873+# CONFIG_BATTERY_SBS is not set 2874+# CONFIG_CHARGER_SBS is not set 2875+# CONFIG_MANAGER_SBS is not set 2876+# CONFIG_BATTERY_BQ27XXX is not set 2877+# CONFIG_BATTERY_MAX17040 is not set 2878+# CONFIG_BATTERY_MAX17042 is not set 2879+# CONFIG_CHARGER_MAX8903 is not set 2880+# CONFIG_CHARGER_LP8727 is not set 2881+# CONFIG_CHARGER_GPIO is not set 2882+# CONFIG_CHARGER_LTC3651 is not set 2883+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set 2884+# CONFIG_CHARGER_BQ2415X is not set 2885+# CONFIG_CHARGER_BQ24257 is not set 2886+# CONFIG_CHARGER_BQ24735 is not set 2887+# CONFIG_CHARGER_BQ25890 is not set 2888+# CONFIG_CHARGER_SMB347 is not set 2889+# CONFIG_BATTERY_GAUGE_LTC2941 is not set 2890+# CONFIG_CHARGER_RT9455 is not set 2891+# CONFIG_HWMON is not set 2892+# CONFIG_THERMAL is not set 2893+# CONFIG_WATCHDOG is not set 2894+CONFIG_SSB_POSSIBLE=y 2895+# CONFIG_SSB is not set 2896+CONFIG_BCMA_POSSIBLE=y 2897+# CONFIG_BCMA is not set 2898+ 2899+# 2900+# Multifunction device drivers 2901+# 2902+CONFIG_MFD_CORE=y 2903+# CONFIG_MFD_ACT8945A is not set 2904+# CONFIG_MFD_AS3711 is not set 2905+# CONFIG_MFD_AS3722 is not set 2906+# CONFIG_PMIC_ADP5520 is not set 2907+# CONFIG_MFD_AAT2870_CORE is not set 2908+# CONFIG_MFD_ATMEL_FLEXCOM is not set 2909+# CONFIG_MFD_ATMEL_HLCDC is not set 2910+# CONFIG_MFD_BCM590XX is not set 2911+# CONFIG_MFD_BD9571MWV is not set 2912+# CONFIG_MFD_AXP20X_I2C is not set 2913+# CONFIG_MFD_CROS_EC is not set 2914+# CONFIG_MFD_MADERA is not set 2915+# CONFIG_MFD_ASIC3 is not set 2916+# CONFIG_PMIC_DA903X is not set 2917+# CONFIG_MFD_DA9052_SPI is not set 2918+# CONFIG_MFD_DA9052_I2C is not set 2919+# CONFIG_MFD_DA9055 is not set 2920+# CONFIG_MFD_DA9062 is not set 2921+# CONFIG_MFD_DA9063 is not set 2922+# CONFIG_MFD_DA9150 is not set 2923+# CONFIG_MFD_DLN2 is not set 2924+# CONFIG_MFD_MC13XXX_SPI is not set 2925+# CONFIG_MFD_MC13XXX_I2C is not set 2926+# CONFIG_MFD_HI6421_PMIC is not set 2927+CONFIG_MFD_HISI_FMC=y 2928+# CONFIG_HTC_PASIC3 is not set 2929+# CONFIG_HTC_I2CPLD is not set 2930+# CONFIG_MFD_KEMPLD is not set 2931+# CONFIG_MFD_88PM800 is not set 2932+# CONFIG_MFD_88PM805 is not set 2933+# CONFIG_MFD_88PM860X is not set 2934+# CONFIG_MFD_MAX14577 is not set 2935+# CONFIG_MFD_MAX77620 is not set 2936+# CONFIG_MFD_MAX77686 is not set 2937+# CONFIG_MFD_MAX77693 is not set 2938+# CONFIG_MFD_MAX77843 is not set 2939+# CONFIG_MFD_MAX8907 is not set 2940+# CONFIG_MFD_MAX8925 is not set 2941+# CONFIG_MFD_MAX8997 is not set 2942+# CONFIG_MFD_MAX8998 is not set 2943+# CONFIG_MFD_MT6397 is not set 2944+# CONFIG_MFD_MENF21BMC is not set 2945+# CONFIG_EZX_PCAP is not set 2946+# CONFIG_MFD_CPCAP is not set 2947+# CONFIG_MFD_VIPERBOARD is not set 2948+# CONFIG_MFD_RETU is not set 2949+# CONFIG_MFD_PCF50633 is not set 2950+# CONFIG_MFD_PM8XXX is not set 2951+# CONFIG_MFD_RT5033 is not set 2952+# CONFIG_MFD_RC5T583 is not set 2953+# CONFIG_MFD_RK808 is not set 2954+# CONFIG_MFD_RN5T618 is not set 2955+# CONFIG_MFD_SEC_CORE is not set 2956+# CONFIG_MFD_SI476X_CORE is not set 2957+# CONFIG_MFD_SM501 is not set 2958+# CONFIG_MFD_SKY81452 is not set 2959+# CONFIG_MFD_SMSC is not set 2960+# CONFIG_ABX500_CORE is not set 2961+# CONFIG_MFD_STMPE is not set 2962+CONFIG_MFD_SYSCON=y 2963+# CONFIG_MFD_TI_AM335X_TSCADC is not set 2964+# CONFIG_MFD_LP3943 is not set 2965+# CONFIG_MFD_LP8788 is not set 2966+# CONFIG_MFD_TI_LMU is not set 2967+# CONFIG_MFD_PALMAS is not set 2968+# CONFIG_TPS6105X is not set 2969+# CONFIG_TPS65010 is not set 2970+# CONFIG_TPS6507X is not set 2971+# CONFIG_MFD_TPS65086 is not set 2972+# CONFIG_MFD_TPS65090 is not set 2973+# CONFIG_MFD_TPS65217 is not set 2974+# CONFIG_MFD_TI_LP873X is not set 2975+# CONFIG_MFD_TI_LP87565 is not set 2976+# CONFIG_MFD_TPS65218 is not set 2977+# CONFIG_MFD_TPS6586X is not set 2978+# CONFIG_MFD_TPS65910 is not set 2979+# CONFIG_MFD_TPS65912_I2C is not set 2980+# CONFIG_MFD_TPS65912_SPI is not set 2981+# CONFIG_MFD_TPS80031 is not set 2982+# CONFIG_TWL4030_CORE is not set 2983+# CONFIG_TWL6040_CORE is not set 2984+# CONFIG_MFD_WL1273_CORE is not set 2985+# CONFIG_MFD_LM3533 is not set 2986+# CONFIG_MFD_TC3589X is not set 2987+# CONFIG_MFD_T7L66XB is not set 2988+# CONFIG_MFD_TC6387XB is not set 2989+# CONFIG_MFD_TC6393XB is not set 2990+# CONFIG_MFD_ARIZONA_I2C is not set 2991+# CONFIG_MFD_ARIZONA_SPI is not set 2992+# CONFIG_MFD_WM8400 is not set 2993+# CONFIG_MFD_WM831X_I2C is not set 2994+# CONFIG_MFD_WM831X_SPI is not set 2995+# CONFIG_MFD_WM8350_I2C is not set 2996+# CONFIG_MFD_WM8994 is not set 2997+# CONFIG_MFD_ROHM_BD718XX is not set 2998+# CONFIG_REGULATOR is not set 2999+# CONFIG_RC_CORE is not set 3000+CONFIG_MEDIA_SUPPORT=y 3001+ 3002+# 3003+# Multimedia core support 3004+# 3005+CONFIG_MEDIA_CAMERA_SUPPORT=y 3006+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set 3007+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set 3008+# CONFIG_MEDIA_RADIO_SUPPORT is not set 3009+# CONFIG_MEDIA_SDR_SUPPORT is not set 3010+# CONFIG_MEDIA_CEC_SUPPORT is not set 3011+# CONFIG_MEDIA_CONTROLLER is not set 3012+CONFIG_VIDEO_DEV=y 3013+CONFIG_VIDEO_V4L2=y 3014+# CONFIG_VIDEO_ADV_DEBUG is not set 3015+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set 3016+ 3017+# 3018+# Media drivers 3019+# 3020+CONFIG_MEDIA_USB_SUPPORT=y 3021+ 3022+# 3023+# Webcam devices 3024+# 3025+CONFIG_USB_VIDEO_CLASS=y 3026+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y 3027+CONFIG_USB_GSPCA=m 3028+# CONFIG_USB_M5602 is not set 3029+# CONFIG_USB_STV06XX is not set 3030+# CONFIG_USB_GL860 is not set 3031+# CONFIG_USB_GSPCA_BENQ is not set 3032+# CONFIG_USB_GSPCA_CONEX is not set 3033+# CONFIG_USB_GSPCA_CPIA1 is not set 3034+# CONFIG_USB_GSPCA_DTCS033 is not set 3035+# CONFIG_USB_GSPCA_ETOMS is not set 3036+# CONFIG_USB_GSPCA_FINEPIX is not set 3037+# CONFIG_USB_GSPCA_JEILINJ is not set 3038+# CONFIG_USB_GSPCA_JL2005BCD is not set 3039+# CONFIG_USB_GSPCA_KINECT is not set 3040+# CONFIG_USB_GSPCA_KONICA is not set 3041+# CONFIG_USB_GSPCA_MARS is not set 3042+# CONFIG_USB_GSPCA_MR97310A is not set 3043+# CONFIG_USB_GSPCA_NW80X is not set 3044+# CONFIG_USB_GSPCA_OV519 is not set 3045+# CONFIG_USB_GSPCA_OV534 is not set 3046+# CONFIG_USB_GSPCA_OV534_9 is not set 3047+# CONFIG_USB_GSPCA_PAC207 is not set 3048+# CONFIG_USB_GSPCA_PAC7302 is not set 3049+# CONFIG_USB_GSPCA_PAC7311 is not set 3050+# CONFIG_USB_GSPCA_SE401 is not set 3051+# CONFIG_USB_GSPCA_SN9C2028 is not set 3052+# CONFIG_USB_GSPCA_SN9C20X is not set 3053+# CONFIG_USB_GSPCA_SONIXB is not set 3054+# CONFIG_USB_GSPCA_SONIXJ is not set 3055+# CONFIG_USB_GSPCA_SPCA500 is not set 3056+# CONFIG_USB_GSPCA_SPCA501 is not set 3057+# CONFIG_USB_GSPCA_SPCA505 is not set 3058+# CONFIG_USB_GSPCA_SPCA506 is not set 3059+# CONFIG_USB_GSPCA_SPCA508 is not set 3060+# CONFIG_USB_GSPCA_SPCA561 is not set 3061+# CONFIG_USB_GSPCA_SPCA1528 is not set 3062+# CONFIG_USB_GSPCA_SQ905 is not set 3063+# CONFIG_USB_GSPCA_SQ905C is not set 3064+# CONFIG_USB_GSPCA_SQ930X is not set 3065+# CONFIG_USB_GSPCA_STK014 is not set 3066+# CONFIG_USB_GSPCA_STK1135 is not set 3067+# CONFIG_USB_GSPCA_STV0680 is not set 3068+# CONFIG_USB_GSPCA_SUNPLUS is not set 3069+# CONFIG_USB_GSPCA_T613 is not set 3070+# CONFIG_USB_GSPCA_TOPRO is not set 3071+# CONFIG_USB_GSPCA_TOUPTEK is not set 3072+# CONFIG_USB_GSPCA_TV8532 is not set 3073+# CONFIG_USB_GSPCA_VC032X is not set 3074+# CONFIG_USB_GSPCA_VICAM is not set 3075+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set 3076+# CONFIG_USB_GSPCA_ZC3XX is not set 3077+# CONFIG_USB_PWC is not set 3078+# CONFIG_VIDEO_CPIA2 is not set 3079+# CONFIG_USB_ZR364XX is not set 3080+# CONFIG_USB_STKWEBCAM is not set 3081+# CONFIG_USB_S2255 is not set 3082+# CONFIG_VIDEO_USBTV is not set 3083+ 3084+# 3085+# Webcam, TV (analog/digital) USB devices 3086+# 3087+# CONFIG_VIDEO_EM28XX is not set 3088+# CONFIG_V4L_PLATFORM_DRIVERS is not set 3089+# CONFIG_V4L_MEM2MEM_DRIVERS is not set 3090+# CONFIG_V4L_TEST_DRIVERS is not set 3091+ 3092+# 3093+# Supported MMC/SDIO adapters 3094+# 3095+# CONFIG_CYPRESS_FIRMWARE is not set 3096+CONFIG_VIDEOBUF2_CORE=y 3097+CONFIG_VIDEOBUF2_V4L2=y 3098+CONFIG_VIDEOBUF2_MEMOPS=y 3099+CONFIG_VIDEOBUF2_VMALLOC=y 3100+ 3101+# 3102+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) 3103+# 3104+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y 3105+ 3106+# 3107+# Audio decoders, processors and mixers 3108+# 3109+ 3110+# 3111+# RDS decoders 3112+# 3113+ 3114+# 3115+# Video decoders 3116+# 3117+ 3118+# 3119+# Video and audio decoders 3120+# 3121+ 3122+# 3123+# Video encoders 3124+# 3125+ 3126+# 3127+# Camera sensor devices 3128+# 3129+ 3130+# 3131+# Flash devices 3132+# 3133+ 3134+# 3135+# Video improvement chips 3136+# 3137+ 3138+# 3139+# Audio/Video compression chips 3140+# 3141+ 3142+# 3143+# SDR tuner chips 3144+# 3145+ 3146+# 3147+# Miscellaneous helper chips 3148+# 3149+ 3150+# 3151+# Sensors used on soc_camera driver 3152+# 3153+ 3154+# 3155+# Media SPI Adapters 3156+# 3157+ 3158+# 3159+# Tools to develop new frontends 3160+# 3161+ 3162+# 3163+# Graphics support 3164+# 3165+# CONFIG_IMX_IPUV3_CORE is not set 3166+# CONFIG_DRM is not set 3167+# CONFIG_DRM_DP_CEC is not set 3168+ 3169+# 3170+# ACP (Audio CoProcessor) Configuration 3171+# 3172+ 3173+# 3174+# AMD Library routines 3175+# 3176+ 3177+# 3178+# Frame buffer Devices 3179+# 3180+CONFIG_FB_CMDLINE=y 3181+CONFIG_FB_NOTIFY=y 3182+CONFIG_FB=y 3183+# CONFIG_FIRMWARE_EDID is not set 3184+# CONFIG_FB_FOREIGN_ENDIAN is not set 3185+# CONFIG_FB_MODE_HELPERS is not set 3186+# CONFIG_FB_TILEBLITTING is not set 3187+ 3188+# 3189+# Frame buffer hardware drivers 3190+# 3191+# CONFIG_FB_ARMCLCD is not set 3192+# CONFIG_FB_OPENCORES is not set 3193+# CONFIG_FB_S1D13XXX is not set 3194+# CONFIG_FB_SMSCUFX is not set 3195+# CONFIG_FB_UDL is not set 3196+# CONFIG_FB_IBM_GXT4500 is not set 3197+# CONFIG_FB_VIRTUAL is not set 3198+# CONFIG_FB_METRONOME is not set 3199+# CONFIG_FB_BROADSHEET is not set 3200+# CONFIG_FB_SIMPLE is not set 3201+# CONFIG_FB_SSD1307 is not set 3202+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 3203+ 3204+# 3205+# Console display driver support 3206+# 3207+CONFIG_DUMMY_CONSOLE=y 3208+# CONFIG_FRAMEBUFFER_CONSOLE is not set 3209+# CONFIG_LOGO is not set 3210+CONFIG_SOUND=y 3211+CONFIG_SND=y 3212+CONFIG_SND_TIMER=y 3213+CONFIG_SND_PCM=y 3214+# CONFIG_SND_OSSEMUL is not set 3215+CONFIG_SND_PCM_TIMER=y 3216+# CONFIG_SND_DYNAMIC_MINORS is not set 3217+CONFIG_SND_SUPPORT_OLD_API=y 3218+CONFIG_SND_PROC_FS=y 3219+CONFIG_SND_VERBOSE_PROCFS=y 3220+# CONFIG_SND_VERBOSE_PRINTK is not set 3221+# CONFIG_SND_DEBUG is not set 3222+# CONFIG_SND_SEQUENCER is not set 3223+CONFIG_SND_DRIVERS=y 3224+# CONFIG_SND_DUMMY is not set 3225+# CONFIG_SND_ALOOP is not set 3226+# CONFIG_SND_MTPAV is not set 3227+# CONFIG_SND_SERIAL_U16550 is not set 3228+# CONFIG_SND_MPU401 is not set 3229+ 3230+# 3231+# HD-Audio 3232+# 3233+CONFIG_SND_HDA_PREALLOC_SIZE=64 3234+CONFIG_SND_ARM=y 3235+# CONFIG_SND_ARMAACI is not set 3236+CONFIG_SND_SPI=y 3237+CONFIG_SND_USB=y 3238+# CONFIG_SND_USB_AUDIO is not set 3239+# CONFIG_SND_USB_UA101 is not set 3240+# CONFIG_SND_USB_CAIAQ is not set 3241+# CONFIG_SND_USB_6FIRE is not set 3242+# CONFIG_SND_USB_HIFACE is not set 3243+# CONFIG_SND_BCD2000 is not set 3244+# CONFIG_SND_USB_POD is not set 3245+# CONFIG_SND_USB_PODHD is not set 3246+# CONFIG_SND_USB_TONEPORT is not set 3247+# CONFIG_SND_USB_VARIAX is not set 3248+# CONFIG_SND_SOC is not set 3249+ 3250+# 3251+# HID support 3252+# 3253+CONFIG_HID=y 3254+# CONFIG_HID_BATTERY_STRENGTH is not set 3255+# CONFIG_HIDRAW is not set 3256+# CONFIG_UHID is not set 3257+CONFIG_HID_GENERIC=y 3258+ 3259+# 3260+# Special HID drivers 3261+# 3262+CONFIG_HID_A4TECH=y 3263+# CONFIG_HID_ACCUTOUCH is not set 3264+# CONFIG_HID_ACRUX is not set 3265+CONFIG_HID_APPLE=y 3266+# CONFIG_HID_APPLEIR is not set 3267+# CONFIG_HID_AUREAL is not set 3268+CONFIG_HID_BELKIN=y 3269+# CONFIG_HID_BETOP_FF is not set 3270+CONFIG_HID_CHERRY=y 3271+CONFIG_HID_CHICONY=y 3272+# CONFIG_HID_COUGAR is not set 3273+# CONFIG_HID_PRODIKEYS is not set 3274+# CONFIG_HID_CMEDIA is not set 3275+CONFIG_HID_CYPRESS=y 3276+# CONFIG_HID_DRAGONRISE is not set 3277+# CONFIG_HID_EMS_FF is not set 3278+# CONFIG_HID_ELECOM is not set 3279+# CONFIG_HID_ELO is not set 3280+CONFIG_HID_EZKEY=y 3281+# CONFIG_HID_GEMBIRD is not set 3282+# CONFIG_HID_GFRM is not set 3283+# CONFIG_HID_HOLTEK is not set 3284+# CONFIG_HID_KEYTOUCH is not set 3285+# CONFIG_HID_KYE is not set 3286+# CONFIG_HID_UCLOGIC is not set 3287+# CONFIG_HID_WALTOP is not set 3288+# CONFIG_HID_GYRATION is not set 3289+# CONFIG_HID_ICADE is not set 3290+CONFIG_HID_ITE=y 3291+# CONFIG_HID_JABRA is not set 3292+# CONFIG_HID_TWINHAN is not set 3293+CONFIG_HID_KENSINGTON=y 3294+# CONFIG_HID_LCPOWER is not set 3295+# CONFIG_HID_LENOVO is not set 3296+CONFIG_HID_LOGITECH=y 3297+# CONFIG_HID_LOGITECH_HIDPP is not set 3298+# CONFIG_LOGITECH_FF is not set 3299+# CONFIG_LOGIRUMBLEPAD2_FF is not set 3300+# CONFIG_LOGIG940_FF is not set 3301+# CONFIG_LOGIWHEELS_FF is not set 3302+# CONFIG_HID_MAGICMOUSE is not set 3303+# CONFIG_HID_MAYFLASH is not set 3304+CONFIG_HID_REDRAGON=y 3305+CONFIG_HID_MICROSOFT=y 3306+CONFIG_HID_MONTEREY=y 3307+# CONFIG_HID_MULTITOUCH is not set 3308+# CONFIG_HID_NTI is not set 3309+# CONFIG_HID_NTRIG is not set 3310+# CONFIG_HID_ORTEK is not set 3311+# CONFIG_HID_PANTHERLORD is not set 3312+# CONFIG_HID_PENMOUNT is not set 3313+# CONFIG_HID_PETALYNX is not set 3314+# CONFIG_HID_PICOLCD is not set 3315+# CONFIG_HID_PLANTRONICS is not set 3316+# CONFIG_HID_PRIMAX is not set 3317+# CONFIG_HID_RETRODE is not set 3318+# CONFIG_HID_ROCCAT is not set 3319+# CONFIG_HID_SAITEK is not set 3320+# CONFIG_HID_SAMSUNG is not set 3321+# CONFIG_HID_SPEEDLINK is not set 3322+# CONFIG_HID_STEAM is not set 3323+# CONFIG_HID_STEELSERIES is not set 3324+# CONFIG_HID_SUNPLUS is not set 3325+# CONFIG_HID_RMI is not set 3326+# CONFIG_HID_GREENASIA is not set 3327+# CONFIG_HID_SMARTJOYPLUS is not set 3328+# CONFIG_HID_TIVO is not set 3329+# CONFIG_HID_TOPSEED is not set 3330+# CONFIG_HID_THRUSTMASTER is not set 3331+# CONFIG_HID_UDRAW_PS3 is not set 3332+# CONFIG_HID_WACOM is not set 3333+# CONFIG_HID_XINMO is not set 3334+# CONFIG_HID_ZEROPLUS is not set 3335+# CONFIG_HID_ZYDACRON is not set 3336+# CONFIG_HID_SENSOR_HUB is not set 3337+# CONFIG_HID_ALPS is not set 3338+ 3339+# 3340+# USB HID support 3341+# 3342+CONFIG_USB_HID=y 3343+# CONFIG_HID_PID is not set 3344+# CONFIG_USB_HIDDEV is not set 3345+ 3346+# 3347+# I2C HID support 3348+# 3349+# CONFIG_I2C_HID is not set 3350+CONFIG_USB_OHCI_LITTLE_ENDIAN=y 3351+CONFIG_USB_SUPPORT=y 3352+CONFIG_USB_COMMON=y 3353+CONFIG_USB_ARCH_HAS_HCD=y 3354+CONFIG_USB=y 3355+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set 3356+ 3357+# 3358+# Miscellaneous USB options 3359+# 3360+CONFIG_USB_DEFAULT_PERSIST=y 3361+# CONFIG_USB_DYNAMIC_MINORS is not set 3362+# CONFIG_USB_OTG is not set 3363+# CONFIG_USB_OTG_WHITELIST is not set 3364+# CONFIG_USB_MON is not set 3365+# CONFIG_USB_WUSB_CBAF is not set 3366+ 3367+# 3368+# USB Host Controller Drivers 3369+# 3370+# CONFIG_USB_C67X00_HCD is not set 3371+CONFIG_USB_XHCI_HCD=y 3372+# CONFIG_USB_XHCI_DBGCAP is not set 3373+CONFIG_USB_XHCI_PLATFORM=y 3374+# CONFIG_USB_EHCI_HCD is not set 3375+# CONFIG_USB_OXU210HP_HCD is not set 3376+# CONFIG_USB_ISP116X_HCD is not set 3377+# CONFIG_USB_FOTG210_HCD is not set 3378+# CONFIG_USB_MAX3421_HCD is not set 3379+# CONFIG_USB_OHCI_HCD is not set 3380+# CONFIG_USB_SL811_HCD is not set 3381+# CONFIG_USB_R8A66597_HCD is not set 3382+# CONFIG_USB_HCD_TEST_MODE is not set 3383+ 3384+# 3385+# USB Device Class drivers 3386+# 3387+# CONFIG_USB_ACM is not set 3388+# CONFIG_USB_PRINTER is not set 3389+# CONFIG_USB_WDM is not set 3390+# CONFIG_USB_TMC is not set 3391+ 3392+# 3393+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may 3394+# 3395+ 3396+# 3397+# also be needed; see USB_STORAGE Help for more info 3398+# 3399+CONFIG_USB_STORAGE=y 3400+# CONFIG_USB_STORAGE_DEBUG is not set 3401+# CONFIG_USB_STORAGE_REALTEK is not set 3402+# CONFIG_USB_STORAGE_DATAFAB is not set 3403+# CONFIG_USB_STORAGE_FREECOM is not set 3404+# CONFIG_USB_STORAGE_ISD200 is not set 3405+# CONFIG_USB_STORAGE_USBAT is not set 3406+# CONFIG_USB_STORAGE_SDDR09 is not set 3407+# CONFIG_USB_STORAGE_SDDR55 is not set 3408+# CONFIG_USB_STORAGE_JUMPSHOT is not set 3409+# CONFIG_USB_STORAGE_ALAUDA is not set 3410+# CONFIG_USB_STORAGE_ONETOUCH is not set 3411+# CONFIG_USB_STORAGE_KARMA is not set 3412+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set 3413+# CONFIG_USB_STORAGE_ENE_UB6250 is not set 3414+# CONFIG_USB_UAS is not set 3415+ 3416+# 3417+# USB Imaging devices 3418+# 3419+# CONFIG_USB_MDC800 is not set 3420+# CONFIG_USB_MICROTEK is not set 3421+# CONFIG_USBIP_CORE is not set 3422+# CONFIG_USB_MUSB_HDRC is not set 3423+CONFIG_USB_DWC3=y 3424+# CONFIG_USB_DWC3_HOST is not set 3425+CONFIG_USB_DWC3_GADGET=y 3426+ 3427+# 3428+# Platform Glue Driver Support 3429+# 3430+# CONFIG_USB_DWC3_OF_SIMPLE is not set 3431+# CONFIG_USB_DWC2 is not set 3432+# CONFIG_USB_CHIPIDEA is not set 3433+# CONFIG_USB_ISP1760 is not set 3434+ 3435+# 3436+# USB port drivers 3437+# 3438+# CONFIG_USB_SERIAL is not set 3439+ 3440+# 3441+# USB Miscellaneous drivers 3442+# 3443+# CONFIG_USB_EMI62 is not set 3444+# CONFIG_USB_EMI26 is not set 3445+# CONFIG_USB_ADUTUX is not set 3446+# CONFIG_USB_SEVSEG is not set 3447+# CONFIG_USB_LEGOTOWER is not set 3448+# CONFIG_USB_LCD is not set 3449+# CONFIG_USB_CYPRESS_CY7C63 is not set 3450+# CONFIG_USB_CYTHERM is not set 3451+# CONFIG_USB_IDMOUSE is not set 3452+# CONFIG_USB_FTDI_ELAN is not set 3453+# CONFIG_USB_APPLEDISPLAY is not set 3454+# CONFIG_USB_LD is not set 3455+# CONFIG_USB_TRANCEVIBRATOR is not set 3456+# CONFIG_USB_IOWARRIOR is not set 3457+# CONFIG_USB_TEST is not set 3458+# CONFIG_USB_EHSET_TEST_FIXTURE is not set 3459+# CONFIG_USB_ISIGHTFW is not set 3460+# CONFIG_USB_YUREX is not set 3461+# CONFIG_USB_EZUSB_FX2 is not set 3462+# CONFIG_USB_HUB_USB251XB is not set 3463+# CONFIG_USB_HSIC_USB3503 is not set 3464+# CONFIG_USB_HSIC_USB4604 is not set 3465+# CONFIG_USB_LINK_LAYER_TEST is not set 3466+ 3467+# 3468+# USB Physical Layer drivers 3469+# 3470+# CONFIG_NOP_USB_XCEIV is not set 3471+# CONFIG_USB_GPIO_VBUS is not set 3472+# CONFIG_USB_ISP1301 is not set 3473+# CONFIG_USB_ULPI is not set 3474+CONFIG_USB_GADGET=y 3475+# CONFIG_USB_GADGET_DEBUG is not set 3476+# CONFIG_USB_GADGET_DEBUG_FILES is not set 3477+# CONFIG_USB_GADGET_DEBUG_FS is not set 3478+CONFIG_USB_GADGET_VBUS_DRAW=2 3479+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 3480+# CONFIG_U_SERIAL_CONSOLE is not set 3481+ 3482+# 3483+# USB Peripheral Controller 3484+# 3485+# CONFIG_USB_FUSB300 is not set 3486+# CONFIG_USB_FOTG210_UDC is not set 3487+# CONFIG_USB_GR_UDC is not set 3488+# CONFIG_USB_R8A66597 is not set 3489+# CONFIG_USB_PXA27X is not set 3490+# CONFIG_USB_MV_UDC is not set 3491+# CONFIG_USB_MV_U3D is not set 3492+# CONFIG_USB_SNP_UDC_PLAT is not set 3493+# CONFIG_USB_M66592 is not set 3494+# CONFIG_USB_BDC_UDC is not set 3495+# CONFIG_USB_NET2272 is not set 3496+# CONFIG_USB_GADGET_XILINX is not set 3497+# CONFIG_USB_DUMMY_HCD is not set 3498+CONFIG_USB_LIBCOMPOSITE=y 3499+CONFIG_USB_F_ACM=y 3500+CONFIG_USB_U_SERIAL=y 3501+CONFIG_USB_U_ETHER=y 3502+CONFIG_USB_U_AUDIO=y 3503+CONFIG_USB_F_RNDIS=y 3504+CONFIG_USB_F_MASS_STORAGE=y 3505+CONFIG_USB_F_UAC1=y 3506+CONFIG_USB_F_UVC=y 3507+CONFIG_USB_CONFIGFS=y 3508+# CONFIG_USB_CONFIGFS_SERIAL is not set 3509+CONFIG_USB_CONFIGFS_ACM=y 3510+# CONFIG_USB_CONFIGFS_OBEX is not set 3511+# CONFIG_USB_CONFIGFS_NCM is not set 3512+# CONFIG_USB_CONFIGFS_ECM is not set 3513+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set 3514+CONFIG_USB_CONFIGFS_RNDIS=y 3515+# CONFIG_USB_CONFIGFS_EEM is not set 3516+CONFIG_USB_CONFIGFS_MASS_STORAGE=y 3517+# CONFIG_USB_CONFIGFS_F_LB_SS is not set 3518+# CONFIG_USB_CONFIGFS_F_FS is not set 3519+CONFIG_USB_CONFIGFS_F_UAC1=y 3520+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set 3521+# CONFIG_USB_CONFIGFS_F_UAC2 is not set 3522+# CONFIG_USB_CONFIGFS_F_MIDI is not set 3523+# CONFIG_USB_CONFIGFS_F_HID is not set 3524+CONFIG_USB_CONFIGFS_F_UVC=y 3525+# CONFIG_USB_CONFIGFS_F_PRINTER is not set 3526+# CONFIG_TYPEC is not set 3527+# CONFIG_USB_ROLE_SWITCH is not set 3528+# CONFIG_USB_ULPI_BUS is not set 3529+# CONFIG_UWB is not set 3530+CONFIG_MMC=y 3531+CONFIG_PWRSEQ_EMMC=y 3532+CONFIG_PWRSEQ_SIMPLE=y 3533+CONFIG_MMC_BLOCK=y 3534+CONFIG_MMC_BLOCK_MINORS=8 3535+# CONFIG_SDIO_UART is not set 3536+# CONFIG_MMC_TEST is not set 3537+ 3538+# 3539+# MMC/SD/SDIO Host Controller Drivers 3540+# 3541+# CONFIG_MMC_DEBUG is not set 3542+# CONFIG_MMC_ARMMMCI is not set 3543+# CONFIG_MMC_SDHCI is not set 3544+# CONFIG_MMC_SPI is not set 3545+# CONFIG_MMC_DW is not set 3546+# CONFIG_MMC_VUB300 is not set 3547+# CONFIG_MMC_USHC is not set 3548+# CONFIG_MMC_USDHI6ROL0 is not set 3549+# CONFIG_MMC_CQHCI is not set 3550+# CONFIG_MMC_MTK is not set 3551+# CONFIG_MMC_CQ_HCI is not set 3552+CONFIG_HIMCI=y 3553+CONFIG_SEND_AUTO_STOP=y 3554+# CONFIG_MEMSTICK is not set 3555+# CONFIG_NEW_LEDS is not set 3556+# CONFIG_ACCESSIBILITY is not set 3557+# CONFIG_INFINIBAND is not set 3558+CONFIG_EDAC_ATOMIC_SCRUB=y 3559+CONFIG_EDAC_SUPPORT=y 3560+CONFIG_RTC_LIB=y 3561+CONFIG_RTC_CLASS=y 3562+CONFIG_RTC_HCTOSYS=y 3563+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" 3564+CONFIG_RTC_SYSTOHC=y 3565+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" 3566+# CONFIG_RTC_DEBUG is not set 3567+CONFIG_RTC_NVMEM=y 3568+ 3569+# 3570+# RTC interfaces 3571+# 3572+CONFIG_RTC_INTF_SYSFS=y 3573+CONFIG_RTC_INTF_PROC=y 3574+CONFIG_RTC_INTF_DEV=y 3575+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set 3576+# CONFIG_RTC_DRV_TEST is not set 3577+ 3578+# 3579+# I2C RTC drivers 3580+# 3581+# CONFIG_RTC_DRV_ABB5ZES3 is not set 3582+# CONFIG_RTC_DRV_ABX80X is not set 3583+# CONFIG_RTC_DRV_DS1307 is not set 3584+# CONFIG_RTC_DRV_DS1374 is not set 3585+# CONFIG_RTC_DRV_DS1672 is not set 3586+# CONFIG_RTC_DRV_HYM8563 is not set 3587+# CONFIG_RTC_DRV_MAX6900 is not set 3588+# CONFIG_RTC_DRV_RS5C372 is not set 3589+# CONFIG_RTC_DRV_ISL1208 is not set 3590+# CONFIG_RTC_DRV_ISL12022 is not set 3591+# CONFIG_RTC_DRV_ISL12026 is not set 3592+# CONFIG_RTC_DRV_X1205 is not set 3593+# CONFIG_RTC_DRV_PCF8523 is not set 3594+# CONFIG_RTC_DRV_PCF85063 is not set 3595+# CONFIG_RTC_DRV_PCF85363 is not set 3596+# CONFIG_RTC_DRV_PCF8563 is not set 3597+# CONFIG_RTC_DRV_PCF8583 is not set 3598+# CONFIG_RTC_DRV_M41T80 is not set 3599+# CONFIG_RTC_DRV_BQ32K is not set 3600+# CONFIG_RTC_DRV_S35390A is not set 3601+# CONFIG_RTC_DRV_FM3130 is not set 3602+# CONFIG_RTC_DRV_RX8010 is not set 3603+# CONFIG_RTC_DRV_RX8581 is not set 3604+# CONFIG_RTC_DRV_RX8025 is not set 3605+# CONFIG_RTC_DRV_EM3027 is not set 3606+# CONFIG_RTC_DRV_RV8803 is not set 3607+ 3608+# 3609+# SPI RTC drivers 3610+# 3611+# CONFIG_RTC_DRV_M41T93 is not set 3612+# CONFIG_RTC_DRV_M41T94 is not set 3613+# CONFIG_RTC_DRV_DS1302 is not set 3614+# CONFIG_RTC_DRV_DS1305 is not set 3615+# CONFIG_RTC_DRV_DS1343 is not set 3616+# CONFIG_RTC_DRV_DS1347 is not set 3617+# CONFIG_RTC_DRV_DS1390 is not set 3618+# CONFIG_RTC_DRV_MAX6916 is not set 3619+# CONFIG_RTC_DRV_R9701 is not set 3620+# CONFIG_RTC_DRV_RX4581 is not set 3621+# CONFIG_RTC_DRV_RX6110 is not set 3622+# CONFIG_RTC_DRV_RS5C348 is not set 3623+# CONFIG_RTC_DRV_MAX6902 is not set 3624+# CONFIG_RTC_DRV_PCF2123 is not set 3625+# CONFIG_RTC_DRV_MCP795 is not set 3626+CONFIG_RTC_I2C_AND_SPI=y 3627+ 3628+# 3629+# SPI and I2C RTC drivers 3630+# 3631+# CONFIG_RTC_DRV_DS3232 is not set 3632+# CONFIG_RTC_DRV_PCF2127 is not set 3633+# CONFIG_RTC_DRV_RV3029C2 is not set 3634+ 3635+# 3636+# Platform RTC drivers 3637+# 3638+CONFIG_RTC_DRV_HIBVT=y 3639+# CONFIG_RTC_DRV_CMOS is not set 3640+# CONFIG_RTC_DRV_DS1286 is not set 3641+# CONFIG_RTC_DRV_DS1511 is not set 3642+# CONFIG_RTC_DRV_DS1553 is not set 3643+# CONFIG_RTC_DRV_DS1685_FAMILY is not set 3644+# CONFIG_RTC_DRV_DS1742 is not set 3645+# CONFIG_RTC_DRV_DS2404 is not set 3646+# CONFIG_RTC_DRV_STK17TA8 is not set 3647+# CONFIG_RTC_DRV_M48T86 is not set 3648+# CONFIG_RTC_DRV_M48T35 is not set 3649+# CONFIG_RTC_DRV_M48T59 is not set 3650+# CONFIG_RTC_DRV_MSM6242 is not set 3651+# CONFIG_RTC_DRV_BQ4802 is not set 3652+# CONFIG_RTC_DRV_RP5C01 is not set 3653+# CONFIG_RTC_DRV_V3020 is not set 3654+# CONFIG_RTC_DRV_ZYNQMP is not set 3655+ 3656+# 3657+# on-CPU RTC drivers 3658+# 3659+# CONFIG_RTC_DRV_PL030 is not set 3660+# CONFIG_RTC_DRV_PL031 is not set 3661+# CONFIG_RTC_DRV_FTRTC010 is not set 3662+# CONFIG_RTC_DRV_SNVS is not set 3663+# CONFIG_RTC_DRV_R7301 is not set 3664+ 3665+# 3666+# HID Sensor RTC drivers 3667+# 3668+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set 3669+# CONFIG_DMADEVICES is not set 3670+ 3671+# 3672+# DMABUF options 3673+# 3674+# CONFIG_SYNC_FILE is not set 3675+# CONFIG_AUXDISPLAY is not set 3676+# CONFIG_UIO is not set 3677+# CONFIG_VIRT_DRIVERS is not set 3678+CONFIG_VIRTIO_MENU=y 3679+# CONFIG_VIRTIO_MMIO is not set 3680+ 3681+# 3682+# Microsoft Hyper-V guest support 3683+# 3684+# CONFIG_STAGING is not set 3685+# CONFIG_GOLDFISH is not set 3686+# CONFIG_CHROME_PLATFORMS is not set 3687+# CONFIG_MELLANOX_PLATFORM is not set 3688+CONFIG_CLKDEV_LOOKUP=y 3689+CONFIG_HAVE_CLK_PREPARE=y 3690+CONFIG_COMMON_CLK=y 3691+ 3692+# 3693+# Common Clock Framework 3694+# 3695+# CONFIG_CLK_HSDK is not set 3696+# CONFIG_COMMON_CLK_MAX9485 is not set 3697+# CONFIG_COMMON_CLK_SI5351 is not set 3698+# CONFIG_COMMON_CLK_SI514 is not set 3699+# CONFIG_COMMON_CLK_SI544 is not set 3700+# CONFIG_COMMON_CLK_SI570 is not set 3701+# CONFIG_COMMON_CLK_CDCE706 is not set 3702+# CONFIG_COMMON_CLK_CDCE925 is not set 3703+# CONFIG_COMMON_CLK_CS2000_CP is not set 3704+# CONFIG_CLK_QORIQ is not set 3705+# CONFIG_COMMON_CLK_VC5 is not set 3706+CONFIG_COMMON_CLK_HI3516DV300=y 3707+CONFIG_RESET_HISI=y 3708+# CONFIG_HWSPINLOCK is not set 3709+ 3710+# 3711+# Clock Source drivers 3712+# 3713+CONFIG_TIMER_OF=y 3714+CONFIG_TIMER_PROBE=y 3715+CONFIG_CLKSRC_MMIO=y 3716+CONFIG_ARM_ARCH_TIMER=y 3717+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y 3718+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set 3719+CONFIG_ARM_TIMER_SP804=y 3720+# CONFIG_TIMER_HISP804 is not set 3721+# CONFIG_MAILBOX is not set 3722+# CONFIG_IOMMU_SUPPORT is not set 3723+ 3724+# 3725+# Remoteproc drivers 3726+# 3727+# CONFIG_REMOTEPROC is not set 3728+ 3729+# 3730+# Rpmsg drivers 3731+# 3732+# CONFIG_RPMSG_VIRTIO is not set 3733+ 3734+# 3735+# SOC (System On Chip) specific Drivers 3736+# 3737+ 3738+# 3739+# Amlogic SoC drivers 3740+# 3741+ 3742+# 3743+# Broadcom SoC drivers 3744+# 3745+# CONFIG_SOC_BRCMSTB is not set 3746+ 3747+# 3748+# NXP/Freescale QorIQ SoC drivers 3749+# 3750+ 3751+# 3752+# i.MX SoC drivers 3753+# 3754+ 3755+# 3756+# Qualcomm SoC drivers 3757+# 3758+# CONFIG_SOC_TI is not set 3759+ 3760+# 3761+# Xilinx SoC drivers 3762+# 3763+# CONFIG_XILINX_VCU is not set 3764+# CONFIG_PM_DEVFREQ is not set 3765+# CONFIG_EXTCON is not set 3766+# CONFIG_MEMORY is not set 3767+# CONFIG_IIO is not set 3768+# CONFIG_PWM is not set 3769+ 3770+# 3771+# IRQ chip support 3772+# 3773+CONFIG_IRQCHIP=y 3774+CONFIG_ARM_GIC=y 3775+CONFIG_ARM_GIC_MAX_NR=1 3776+# CONFIG_IPACK_BUS is not set 3777+CONFIG_RESET_CONTROLLER=y 3778+# CONFIG_RESET_TI_SYSCON is not set 3779+# CONFIG_FMC is not set 3780+ 3781+# 3782+# PHY Subsystem 3783+# 3784+CONFIG_GENERIC_PHY=y 3785+# CONFIG_BCM_KONA_USB2_PHY is not set 3786+# CONFIG_PHY_PXA_28NM_HSIC is not set 3787+# CONFIG_PHY_PXA_28NM_USB2 is not set 3788+# CONFIG_PHY_MAPPHONE_MDM6600 is not set 3789+CONFIG_HI_USB_PHY=y 3790+CONFIG_PHY_HISI_USB2=y 3791+CONFIG_HIBVT_USB_PHY=y 3792+CONFIG_USB_MODE_OPTION=y 3793+CONFIG_USB_DRD0_IN_HOST=y 3794+# CONFIG_POWERCAP is not set 3795+# CONFIG_MCB is not set 3796+# CONFIG_RAS is not set 3797+# CONFIG_DAX is not set 3798+CONFIG_NVMEM=y 3799+ 3800+# 3801+# HW tracing support 3802+# 3803+# CONFIG_STM is not set 3804+# CONFIG_INTEL_TH is not set 3805+# CONFIG_FPGA is not set 3806+# CONFIG_FSI is not set 3807+# CONFIG_TEE is not set 3808+# CONFIG_SIOX is not set 3809+# CONFIG_SLIMBUS is not set 3810+# CONFIG_HI_DMAC is not set 3811+# CONFIG_HIEDMAC is not set 3812+ 3813+# 3814+# Hisilicon driver support 3815+# 3816+# CONFIG_CMA_MEM_SHARED is not set 3817+# CONFIG_CMA_ADVANCE_SHARE is not set 3818+ 3819+# 3820+# File systems 3821+# 3822+CONFIG_DCACHE_WORD_ACCESS=y 3823+CONFIG_FS_IOMAP=y 3824+# CONFIG_EXT2_FS is not set 3825+# CONFIG_EXT3_FS is not set 3826+CONFIG_EXT4_FS=y 3827+CONFIG_EXT4_USE_FOR_EXT2=y 3828+# CONFIG_EXT4_FS_POSIX_ACL is not set 3829+# CONFIG_EXT4_FS_SECURITY is not set 3830+# CONFIG_EXT4_ENCRYPTION is not set 3831+# CONFIG_EXT4_DEBUG is not set 3832+CONFIG_JBD2=y 3833+# CONFIG_JBD2_DEBUG is not set 3834+CONFIG_FS_MBCACHE=y 3835+CONFIG_REISERFS_FS=m 3836+CONFIG_REISERFS_CHECK=y 3837+CONFIG_REISERFS_PROC_INFO=y 3838+CONFIG_REISERFS_FS_XATTR=y 3839+CONFIG_REISERFS_FS_POSIX_ACL=y 3840+CONFIG_REISERFS_FS_SECURITY=y 3841+CONFIG_JFS_FS=m 3842+CONFIG_JFS_POSIX_ACL=y 3843+CONFIG_JFS_SECURITY=y 3844+CONFIG_JFS_DEBUG=y 3845+CONFIG_JFS_STATISTICS=y 3846+CONFIG_XFS_FS=m 3847+CONFIG_XFS_QUOTA=y 3848+CONFIG_XFS_POSIX_ACL=y 3849+CONFIG_XFS_RT=y 3850+# CONFIG_XFS_ONLINE_SCRUB is not set 3851+# CONFIG_XFS_WARN is not set 3852+# CONFIG_XFS_DEBUG is not set 3853+# CONFIG_GFS2_FS is not set 3854+# CONFIG_OCFS2_FS is not set 3855+# CONFIG_BTRFS_FS is not set 3856+# CONFIG_NILFS2_FS is not set 3857+# CONFIG_F2FS_FS is not set 3858+CONFIG_FS_POSIX_ACL=y 3859+CONFIG_EXPORTFS=y 3860+# CONFIG_EXPORTFS_BLOCK_OPS is not set 3861+CONFIG_FILE_LOCKING=y 3862+CONFIG_MANDATORY_FILE_LOCKING=y 3863+# CONFIG_FS_ENCRYPTION is not set 3864+CONFIG_FSNOTIFY=y 3865+CONFIG_DNOTIFY=y 3866+CONFIG_INOTIFY_USER=y 3867+# CONFIG_FANOTIFY is not set 3868+# CONFIG_QUOTA is not set 3869+# CONFIG_QUOTA_NETLINK_INTERFACE is not set 3870+CONFIG_QUOTACTL=y 3871+# CONFIG_AUTOFS4_FS is not set 3872+# CONFIG_AUTOFS_FS is not set 3873+# CONFIG_FUSE_FS is not set 3874+# CONFIG_OVERLAY_FS is not set 3875+ 3876+# 3877+# Caches 3878+# 3879+# CONFIG_FSCACHE is not set 3880+ 3881+# 3882+# CD-ROM/DVD Filesystems 3883+# 3884+# CONFIG_ISO9660_FS is not set 3885+# CONFIG_UDF_FS is not set 3886+ 3887+# 3888+# DOS/FAT/NT Filesystems 3889+# 3890+CONFIG_FAT_FS=y 3891+CONFIG_MSDOS_FS=y 3892+CONFIG_VFAT_FS=y 3893+CONFIG_FAT_DEFAULT_CODEPAGE=437 3894+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" 3895+# CONFIG_FAT_DEFAULT_UTF8 is not set 3896+# CONFIG_NTFS_FS is not set 3897+ 3898+# 3899+# Pseudo filesystems 3900+# 3901+CONFIG_PROC_FS=y 3902+CONFIG_PROC_SYSCTL=y 3903+CONFIG_PROC_PAGE_MONITOR=y 3904+# CONFIG_PROC_CHILDREN is not set 3905+CONFIG_KERNFS=y 3906+CONFIG_SYSFS=y 3907+CONFIG_TMPFS=y 3908+# CONFIG_TMPFS_POSIX_ACL is not set 3909+# CONFIG_TMPFS_XATTR is not set 3910+CONFIG_MEMFD_CREATE=y 3911+CONFIG_CONFIGFS_FS=y 3912+CONFIG_MISC_FILESYSTEMS=y 3913+# CONFIG_ORANGEFS_FS is not set 3914+# CONFIG_ADFS_FS is not set 3915+# CONFIG_AFFS_FS is not set 3916+# CONFIG_ECRYPT_FS is not set 3917+# CONFIG_HFS_FS is not set 3918+# CONFIG_HFSPLUS_FS is not set 3919+# CONFIG_BEFS_FS is not set 3920+# CONFIG_BFS_FS is not set 3921+# CONFIG_EFS_FS is not set 3922+CONFIG_CRAMFS=y 3923+CONFIG_CRAMFS_BLOCKDEV=y 3924+# CONFIG_SQUASHFS is not set 3925+# CONFIG_VXFS_FS is not set 3926+# CONFIG_MINIX_FS is not set 3927+# CONFIG_OMFS_FS is not set 3928+# CONFIG_HPFS_FS is not set 3929+# CONFIG_QNX4FS_FS is not set 3930+# CONFIG_QNX6FS_FS is not set 3931+# CONFIG_ROMFS_FS is not set 3932+# CONFIG_PSTORE is not set 3933+# CONFIG_SYSV_FS is not set 3934+# CONFIG_UFS_FS is not set 3935+CONFIG_NETWORK_FILESYSTEMS=y 3936+CONFIG_NFS_FS=y 3937+CONFIG_NFS_V2=y 3938+CONFIG_NFS_V3=y 3939+CONFIG_NFS_V3_ACL=y 3940+CONFIG_NFS_V4=y 3941+# CONFIG_NFS_SWAP is not set 3942+# CONFIG_NFS_V4_1 is not set 3943+# CONFIG_ROOT_NFS is not set 3944+# CONFIG_NFS_USE_LEGACY_DNS is not set 3945+CONFIG_NFS_USE_KERNEL_DNS=y 3946+# CONFIG_NFSD is not set 3947+CONFIG_GRACE_PERIOD=y 3948+CONFIG_LOCKD=y 3949+CONFIG_LOCKD_V4=y 3950+CONFIG_NFS_ACL_SUPPORT=y 3951+CONFIG_NFS_COMMON=y 3952+CONFIG_SUNRPC=y 3953+CONFIG_SUNRPC_GSS=y 3954+# CONFIG_SUNRPC_DEBUG is not set 3955+# CONFIG_CEPH_FS is not set 3956+# CONFIG_CIFS is not set 3957+# CONFIG_CODA_FS is not set 3958+# CONFIG_AFS_FS is not set 3959+CONFIG_NLS=y 3960+CONFIG_NLS_DEFAULT="iso8859-1" 3961+CONFIG_NLS_CODEPAGE_437=y 3962+CONFIG_NLS_CODEPAGE_737=m 3963+CONFIG_NLS_CODEPAGE_775=m 3964+CONFIG_NLS_CODEPAGE_850=m 3965+CONFIG_NLS_CODEPAGE_852=m 3966+CONFIG_NLS_CODEPAGE_855=m 3967+CONFIG_NLS_CODEPAGE_857=m 3968+CONFIG_NLS_CODEPAGE_860=m 3969+CONFIG_NLS_CODEPAGE_861=m 3970+CONFIG_NLS_CODEPAGE_862=m 3971+CONFIG_NLS_CODEPAGE_863=m 3972+CONFIG_NLS_CODEPAGE_864=m 3973+CONFIG_NLS_CODEPAGE_865=m 3974+CONFIG_NLS_CODEPAGE_866=m 3975+CONFIG_NLS_CODEPAGE_869=m 3976+CONFIG_NLS_CODEPAGE_936=y 3977+CONFIG_NLS_CODEPAGE_950=m 3978+CONFIG_NLS_CODEPAGE_932=m 3979+CONFIG_NLS_CODEPAGE_949=m 3980+CONFIG_NLS_CODEPAGE_874=m 3981+CONFIG_NLS_ISO8859_8=m 3982+CONFIG_NLS_CODEPAGE_1250=m 3983+CONFIG_NLS_CODEPAGE_1251=m 3984+CONFIG_NLS_ASCII=y 3985+CONFIG_NLS_ISO8859_1=y 3986+CONFIG_NLS_ISO8859_2=m 3987+CONFIG_NLS_ISO8859_3=m 3988+CONFIG_NLS_ISO8859_4=m 3989+CONFIG_NLS_ISO8859_5=m 3990+CONFIG_NLS_ISO8859_6=m 3991+CONFIG_NLS_ISO8859_7=m 3992+CONFIG_NLS_ISO8859_9=m 3993+CONFIG_NLS_ISO8859_13=m 3994+CONFIG_NLS_ISO8859_14=m 3995+CONFIG_NLS_ISO8859_15=m 3996+CONFIG_NLS_KOI8_R=m 3997+CONFIG_NLS_KOI8_U=m 3998+# CONFIG_NLS_MAC_ROMAN is not set 3999+# CONFIG_NLS_MAC_CELTIC is not set 4000+# CONFIG_NLS_MAC_CENTEURO is not set 4001+# CONFIG_NLS_MAC_CROATIAN is not set 4002+# CONFIG_NLS_MAC_CYRILLIC is not set 4003+# CONFIG_NLS_MAC_GAELIC is not set 4004+# CONFIG_NLS_MAC_GREEK is not set 4005+# CONFIG_NLS_MAC_ICELAND is not set 4006+# CONFIG_NLS_MAC_INUIT is not set 4007+# CONFIG_NLS_MAC_ROMANIAN is not set 4008+# CONFIG_NLS_MAC_TURKISH is not set 4009+CONFIG_NLS_UTF8=y 4010+# CONFIG_DLM is not set 4011+ 4012+# 4013+# Security options 4014+# 4015+CONFIG_KEYS=y 4016+# CONFIG_PERSISTENT_KEYRINGS is not set 4017+# CONFIG_BIG_KEYS is not set 4018+# CONFIG_ENCRYPTED_KEYS is not set 4019+# CONFIG_KEY_DH_OPERATIONS is not set 4020+# CONFIG_SECURITY_DMESG_RESTRICT is not set 4021+# CONFIG_SECURITY is not set 4022+# CONFIG_SECURITYFS is not set 4023+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y 4024+# CONFIG_HARDENED_USERCOPY is not set 4025+# CONFIG_FORTIFY_SOURCE is not set 4026+# CONFIG_STATIC_USERMODEHELPER is not set 4027+CONFIG_DEFAULT_SECURITY_DAC=y 4028+CONFIG_DEFAULT_SECURITY="" 4029+CONFIG_CRYPTO=y 4030+ 4031+# 4032+# Crypto core or helper 4033+# 4034+CONFIG_CRYPTO_ALGAPI=y 4035+CONFIG_CRYPTO_ALGAPI2=y 4036+CONFIG_CRYPTO_AEAD=m 4037+CONFIG_CRYPTO_AEAD2=y 4038+CONFIG_CRYPTO_BLKCIPHER2=y 4039+CONFIG_CRYPTO_HASH=y 4040+CONFIG_CRYPTO_HASH2=y 4041+CONFIG_CRYPTO_RNG=y 4042+CONFIG_CRYPTO_RNG2=y 4043+CONFIG_CRYPTO_RNG_DEFAULT=m 4044+CONFIG_CRYPTO_AKCIPHER2=y 4045+CONFIG_CRYPTO_KPP2=y 4046+CONFIG_CRYPTO_ACOMP2=y 4047+# CONFIG_CRYPTO_RSA is not set 4048+# CONFIG_CRYPTO_DH is not set 4049+# CONFIG_CRYPTO_ECDH is not set 4050+CONFIG_CRYPTO_MANAGER=m 4051+CONFIG_CRYPTO_MANAGER2=y 4052+# CONFIG_CRYPTO_USER is not set 4053+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y 4054+# CONFIG_CRYPTO_GF128MUL is not set 4055+CONFIG_CRYPTO_NULL=m 4056+CONFIG_CRYPTO_NULL2=y 4057+# CONFIG_CRYPTO_PCRYPT is not set 4058+CONFIG_CRYPTO_WORKQUEUE=y 4059+# CONFIG_CRYPTO_CRYPTD is not set 4060+# CONFIG_CRYPTO_MCRYPTD is not set 4061+# CONFIG_CRYPTO_AUTHENC is not set 4062+# CONFIG_CRYPTO_TEST is not set 4063+ 4064+# 4065+# Authenticated Encryption with Associated Data 4066+# 4067+# CONFIG_CRYPTO_CCM is not set 4068+# CONFIG_CRYPTO_GCM is not set 4069+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set 4070+# CONFIG_CRYPTO_AEGIS128 is not set 4071+# CONFIG_CRYPTO_AEGIS128L is not set 4072+# CONFIG_CRYPTO_AEGIS256 is not set 4073+# CONFIG_CRYPTO_MORUS640 is not set 4074+# CONFIG_CRYPTO_MORUS1280 is not set 4075+# CONFIG_CRYPTO_SEQIV is not set 4076+CONFIG_CRYPTO_ECHAINIV=m 4077+ 4078+# 4079+# Block modes 4080+# 4081+# CONFIG_CRYPTO_CBC is not set 4082+# CONFIG_CRYPTO_CFB is not set 4083+# CONFIG_CRYPTO_CTR is not set 4084+# CONFIG_CRYPTO_CTS is not set 4085+# CONFIG_CRYPTO_ECB is not set 4086+# CONFIG_CRYPTO_LRW is not set 4087+# CONFIG_CRYPTO_PCBC is not set 4088+# CONFIG_CRYPTO_XTS is not set 4089+# CONFIG_CRYPTO_KEYWRAP is not set 4090+ 4091+# 4092+# Hash modes 4093+# 4094+# CONFIG_CRYPTO_CMAC is not set 4095+CONFIG_CRYPTO_HMAC=m 4096+# CONFIG_CRYPTO_XCBC is not set 4097+# CONFIG_CRYPTO_VMAC is not set 4098+ 4099+# 4100+# Digest 4101+# 4102+CONFIG_CRYPTO_CRC32C=y 4103+# CONFIG_CRYPTO_CRC32 is not set 4104+# CONFIG_CRYPTO_CRCT10DIF is not set 4105+# CONFIG_CRYPTO_GHASH is not set 4106+# CONFIG_CRYPTO_POLY1305 is not set 4107+# CONFIG_CRYPTO_MD4 is not set 4108+# CONFIG_CRYPTO_MD5 is not set 4109+# CONFIG_CRYPTO_MICHAEL_MIC is not set 4110+# CONFIG_CRYPTO_RMD128 is not set 4111+# CONFIG_CRYPTO_RMD160 is not set 4112+# CONFIG_CRYPTO_RMD256 is not set 4113+# CONFIG_CRYPTO_RMD320 is not set 4114+# CONFIG_CRYPTO_SHA1 is not set 4115+CONFIG_CRYPTO_SHA256=m 4116+# CONFIG_CRYPTO_SHA512 is not set 4117+# CONFIG_CRYPTO_SHA3 is not set 4118+# CONFIG_CRYPTO_SM3 is not set 4119+# CONFIG_CRYPTO_TGR192 is not set 4120+# CONFIG_CRYPTO_WP512 is not set 4121+ 4122+# 4123+# Ciphers 4124+# 4125+CONFIG_CRYPTO_AES=y 4126+# CONFIG_CRYPTO_AES_TI is not set 4127+# CONFIG_CRYPTO_ANUBIS is not set 4128+# CONFIG_CRYPTO_ARC4 is not set 4129+# CONFIG_CRYPTO_BLOWFISH is not set 4130+# CONFIG_CRYPTO_CAMELLIA is not set 4131+# CONFIG_CRYPTO_CAST5 is not set 4132+# CONFIG_CRYPTO_CAST6 is not set 4133+# CONFIG_CRYPTO_DES is not set 4134+# CONFIG_CRYPTO_FCRYPT is not set 4135+# CONFIG_CRYPTO_KHAZAD is not set 4136+# CONFIG_CRYPTO_SALSA20 is not set 4137+# CONFIG_CRYPTO_CHACHA20 is not set 4138+# CONFIG_CRYPTO_SEED is not set 4139+# CONFIG_CRYPTO_SERPENT is not set 4140+# CONFIG_CRYPTO_SM4 is not set 4141+# CONFIG_CRYPTO_TEA is not set 4142+# CONFIG_CRYPTO_TWOFISH is not set 4143+ 4144+# 4145+# Compression 4146+# 4147+# CONFIG_CRYPTO_DEFLATE is not set 4148+# CONFIG_CRYPTO_LZO is not set 4149+# CONFIG_CRYPTO_842 is not set 4150+# CONFIG_CRYPTO_LZ4 is not set 4151+# CONFIG_CRYPTO_LZ4HC is not set 4152+# CONFIG_CRYPTO_ZSTD is not set 4153+ 4154+# 4155+# Random Number Generation 4156+# 4157+CONFIG_CRYPTO_ANSI_CPRNG=y 4158+CONFIG_CRYPTO_DRBG_MENU=m 4159+CONFIG_CRYPTO_DRBG_HMAC=y 4160+# CONFIG_CRYPTO_DRBG_HASH is not set 4161+CONFIG_CRYPTO_DRBG=m 4162+CONFIG_CRYPTO_JITTERENTROPY=m 4163+# CONFIG_CRYPTO_USER_API_HASH is not set 4164+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set 4165+# CONFIG_CRYPTO_USER_API_RNG is not set 4166+# CONFIG_CRYPTO_USER_API_AEAD is not set 4167+CONFIG_CRYPTO_HW=y 4168+# CONFIG_CRYPTO_DEV_CCREE is not set 4169+# CONFIG_ASYMMETRIC_KEY_TYPE is not set 4170+ 4171+# 4172+# Certificates for signature checking 4173+# 4174+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set 4175+ 4176+# 4177+# Library routines 4178+# 4179+CONFIG_BITREVERSE=y 4180+CONFIG_HAVE_ARCH_BITREVERSE=y 4181+CONFIG_RATIONAL=y 4182+CONFIG_GENERIC_STRNCPY_FROM_USER=y 4183+CONFIG_GENERIC_STRNLEN_USER=y 4184+CONFIG_GENERIC_NET_UTILS=y 4185+CONFIG_GENERIC_PCI_IOMAP=y 4186+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y 4187+# CONFIG_CRC_CCITT is not set 4188+CONFIG_CRC16=y 4189+# CONFIG_CRC_T10DIF is not set 4190+# CONFIG_CRC_ITU_T is not set 4191+CONFIG_CRC32=y 4192+# CONFIG_CRC32_SELFTEST is not set 4193+CONFIG_CRC32_SLICEBY8=y 4194+# CONFIG_CRC32_SLICEBY4 is not set 4195+# CONFIG_CRC32_SARWATE is not set 4196+# CONFIG_CRC32_BIT is not set 4197+# CONFIG_CRC64 is not set 4198+# CONFIG_CRC4 is not set 4199+# CONFIG_CRC7 is not set 4200+CONFIG_LIBCRC32C=m 4201+# CONFIG_CRC8 is not set 4202+# CONFIG_RANDOM32_SELFTEST is not set 4203+CONFIG_ZLIB_INFLATE=y 4204+CONFIG_XZ_DEC=y 4205+CONFIG_XZ_DEC_X86=y 4206+CONFIG_XZ_DEC_POWERPC=y 4207+CONFIG_XZ_DEC_IA64=y 4208+CONFIG_XZ_DEC_ARM=y 4209+CONFIG_XZ_DEC_ARMTHUMB=y 4210+CONFIG_XZ_DEC_SPARC=y 4211+CONFIG_XZ_DEC_BCJ=y 4212+# CONFIG_XZ_DEC_TEST is not set 4213+CONFIG_GENERIC_ALLOCATOR=y 4214+CONFIG_ASSOCIATIVE_ARRAY=y 4215+CONFIG_HAS_IOMEM=y 4216+CONFIG_HAS_IOPORT_MAP=y 4217+CONFIG_HAS_DMA=y 4218+CONFIG_NEED_DMA_MAP_STATE=y 4219+CONFIG_HAVE_GENERIC_DMA_COHERENT=y 4220+CONFIG_SGL_ALLOC=y 4221+CONFIG_CPU_RMAP=y 4222+CONFIG_DQL=y 4223+CONFIG_NLATTR=y 4224+# CONFIG_CORDIC is not set 4225+# CONFIG_DDR is not set 4226+# CONFIG_IRQ_POLL is not set 4227+CONFIG_LIBFDT=y 4228+CONFIG_OID_REGISTRY=y 4229+CONFIG_SG_POOL=y 4230+CONFIG_ARCH_HAS_SG_CHAIN=y 4231+CONFIG_SBITMAP=y 4232+# CONFIG_STRING_SELFTEST is not set 4233+ 4234+# 4235+# Kernel hacking 4236+# 4237+ 4238+# 4239+# printk and dmesg options 4240+# 4241+# CONFIG_PRINTK_TIME is not set 4242+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 4243+CONFIG_CONSOLE_LOGLEVEL_QUIET=4 4244+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 4245+# CONFIG_BOOT_PRINTK_DELAY is not set 4246+# CONFIG_DYNAMIC_DEBUG is not set 4247+ 4248+# 4249+# Compile-time checks and compiler options 4250+# 4251+# CONFIG_DEBUG_INFO is not set 4252+CONFIG_ENABLE_MUST_CHECK=y 4253+CONFIG_FRAME_WARN=1024 4254+# CONFIG_STRIP_ASM_SYMS is not set 4255+# CONFIG_READABLE_ASM is not set 4256+# CONFIG_UNUSED_SYMBOLS is not set 4257+# CONFIG_PAGE_OWNER is not set 4258+# CONFIG_DEBUG_FS is not set 4259+# CONFIG_HEADERS_CHECK is not set 4260+# CONFIG_DEBUG_SECTION_MISMATCH is not set 4261+CONFIG_SECTION_MISMATCH_WARN_ONLY=y 4262+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set 4263+# CONFIG_MAGIC_SYSRQ is not set 4264+CONFIG_DEBUG_KERNEL=y 4265+ 4266+# 4267+# Memory Debugging 4268+# 4269+# CONFIG_PAGE_EXTENSION is not set 4270+# CONFIG_DEBUG_PAGEALLOC is not set 4271+# CONFIG_PAGE_POISONING is not set 4272+# CONFIG_DEBUG_RODATA_TEST is not set 4273+# CONFIG_DEBUG_OBJECTS is not set 4274+# CONFIG_SLUB_DEBUG_ON is not set 4275+# CONFIG_SLUB_STATS is not set 4276+CONFIG_HAVE_DEBUG_KMEMLEAK=y 4277+# CONFIG_DEBUG_KMEMLEAK is not set 4278+# CONFIG_DEBUG_STACK_USAGE is not set 4279+# CONFIG_DEBUG_VM is not set 4280+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y 4281+# CONFIG_DEBUG_VIRTUAL is not set 4282+CONFIG_DEBUG_MEMORY_INIT=y 4283+# CONFIG_DEBUG_PER_CPU_MAPS is not set 4284+# CONFIG_DEBUG_HIGHMEM is not set 4285+CONFIG_ARCH_HAS_KCOV=y 4286+CONFIG_CC_HAS_SANCOV_TRACE_PC=y 4287+# CONFIG_KCOV is not set 4288+# CONFIG_DEBUG_SHIRQ is not set 4289+ 4290+# 4291+# Debug Lockups and Hangs 4292+# 4293+# CONFIG_SOFTLOCKUP_DETECTOR is not set 4294+# CONFIG_DETECT_HUNG_TASK is not set 4295+# CONFIG_WQ_WATCHDOG is not set 4296+# CONFIG_PANIC_ON_OOPS is not set 4297+CONFIG_PANIC_ON_OOPS_VALUE=0 4298+CONFIG_PANIC_TIMEOUT=0 4299+CONFIG_SCHED_DEBUG=y 4300+# CONFIG_SCHEDSTATS is not set 4301+# CONFIG_SCHED_STACK_END_CHECK is not set 4302+# CONFIG_DEBUG_TIMEKEEPING is not set 4303+ 4304+# 4305+# Lock Debugging (spinlocks, mutexes, etc...) 4306+# 4307+CONFIG_LOCK_DEBUGGING_SUPPORT=y 4308+# CONFIG_PROVE_LOCKING is not set 4309+# CONFIG_LOCK_STAT is not set 4310+# CONFIG_DEBUG_RT_MUTEXES is not set 4311+# CONFIG_DEBUG_SPINLOCK is not set 4312+# CONFIG_DEBUG_MUTEXES is not set 4313+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set 4314+# CONFIG_DEBUG_RWSEMS is not set 4315+# CONFIG_DEBUG_LOCK_ALLOC is not set 4316+# CONFIG_DEBUG_ATOMIC_SLEEP is not set 4317+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 4318+# CONFIG_LOCK_TORTURE_TEST is not set 4319+# CONFIG_WW_MUTEX_SELFTEST is not set 4320+CONFIG_STACKTRACE=y 4321+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set 4322+# CONFIG_DEBUG_KOBJECT is not set 4323+CONFIG_DEBUG_BUGVERBOSE=y 4324+# CONFIG_DEBUG_LIST is not set 4325+# CONFIG_DEBUG_PI_LIST is not set 4326+# CONFIG_DEBUG_SG is not set 4327+# CONFIG_DEBUG_NOTIFIERS is not set 4328+# CONFIG_DEBUG_CREDENTIALS is not set 4329+ 4330+# 4331+# RCU Debugging 4332+# 4333+# CONFIG_RCU_PERF_TEST is not set 4334+# CONFIG_RCU_TORTURE_TEST is not set 4335+CONFIG_RCU_CPU_STALL_TIMEOUT=60 4336+# CONFIG_RCU_TRACE is not set 4337+# CONFIG_RCU_EQS_DEBUG is not set 4338+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set 4339+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set 4340+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set 4341+# CONFIG_NOTIFIER_ERROR_INJECTION is not set 4342+# CONFIG_FAULT_INJECTION is not set 4343+# CONFIG_LATENCYTOP is not set 4344+CONFIG_HAVE_FUNCTION_TRACER=y 4345+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y 4346+CONFIG_HAVE_DYNAMIC_FTRACE=y 4347+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y 4348+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y 4349+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y 4350+CONFIG_HAVE_C_RECORDMCOUNT=y 4351+CONFIG_TRACING_SUPPORT=y 4352+# CONFIG_FTRACE is not set 4353+# CONFIG_DMA_API_DEBUG is not set 4354+CONFIG_RUNTIME_TESTING_MENU=y 4355+# CONFIG_LKDTM is not set 4356+# CONFIG_TEST_LIST_SORT is not set 4357+# CONFIG_TEST_SORT is not set 4358+# CONFIG_BACKTRACE_SELF_TEST is not set 4359+# CONFIG_RBTREE_TEST is not set 4360+# CONFIG_INTERVAL_TREE_TEST is not set 4361+# CONFIG_PERCPU_TEST is not set 4362+# CONFIG_ATOMIC64_SELFTEST is not set 4363+# CONFIG_TEST_HEXDUMP is not set 4364+# CONFIG_TEST_STRING_HELPERS is not set 4365+# CONFIG_TEST_KSTRTOX is not set 4366+# CONFIG_TEST_PRINTF is not set 4367+# CONFIG_TEST_BITMAP is not set 4368+# CONFIG_TEST_BITFIELD is not set 4369+# CONFIG_TEST_UUID is not set 4370+# CONFIG_TEST_OVERFLOW is not set 4371+# CONFIG_TEST_RHASHTABLE is not set 4372+# CONFIG_TEST_HASH is not set 4373+# CONFIG_TEST_IDA is not set 4374+# CONFIG_TEST_LKM is not set 4375+# CONFIG_TEST_USER_COPY is not set 4376+# CONFIG_TEST_BPF is not set 4377+# CONFIG_FIND_BIT_BENCHMARK is not set 4378+# CONFIG_TEST_FIRMWARE is not set 4379+# CONFIG_TEST_SYSCTL is not set 4380+# CONFIG_TEST_UDELAY is not set 4381+# CONFIG_TEST_STATIC_KEYS is not set 4382+# CONFIG_TEST_KMOD is not set 4383+# CONFIG_MEMTEST is not set 4384+# CONFIG_BUG_ON_DATA_CORRUPTION is not set 4385+# CONFIG_SAMPLES is not set 4386+CONFIG_HAVE_ARCH_KGDB=y 4387+# CONFIG_KGDB is not set 4388+# CONFIG_UBSAN is not set 4389+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y 4390+CONFIG_STRICT_DEVMEM=y 4391+# CONFIG_IO_STRICT_DEVMEM is not set 4392+# CONFIG_ARM_PTDUMP_DEBUGFS is not set 4393+# CONFIG_DEBUG_WX is not set 4394+CONFIG_ARM_UNWIND=y 4395+# CONFIG_DEBUG_USER is not set 4396+# CONFIG_DEBUG_LL is not set 4397+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" 4398+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" 4399+# CONFIG_PID_IN_CONTEXTIDR is not set 4400+# CONFIG_CORESIGHT is not set 4401diff --git a/arch/arm/configs/hi3516dv300_emmc_smp_hos_l2_defconfig b/arch/arm/configs/hi3516dv300_emmc_smp_hos_l2_defconfig 4402new file mode 100644 4403index 000000000..364f69865 4404--- /dev/null 4405+++ b/arch/arm/configs/hi3516dv300_emmc_smp_hos_l2_defconfig 4406@@ -0,0 +1,3135 @@ 4407+# 4408+# Automatically generated file; DO NOT EDIT. 4409+# Linux/arm 4.19.41 Kernel Configuration 4410+# 4411+ 4412+# 4413+# Compiler: arm-himix400-linux-gcc (HC&C V1R3C00SPC200B041_20200707) 7.3.0 4414+# 4415+CONFIG_CC_IS_GCC=y 4416+CONFIG_GCC_VERSION=70300 4417+CONFIG_CLANG_VERSION=0 4418+CONFIG_CC_HAS_ASM_GOTO=y 4419+CONFIG_IRQ_WORK=y 4420+CONFIG_BUILDTIME_EXTABLE_SORT=y 4421+ 4422+# 4423+# General setup 4424+# 4425+CONFIG_INIT_ENV_ARG_LIMIT=32 4426+# CONFIG_COMPILE_TEST is not set 4427+CONFIG_LOCALVERSION="" 4428+# CONFIG_LOCALVERSION_AUTO is not set 4429+CONFIG_BUILD_SALT="" 4430+CONFIG_HAVE_KERNEL_GZIP=y 4431+CONFIG_HAVE_KERNEL_LZMA=y 4432+CONFIG_HAVE_KERNEL_XZ=y 4433+CONFIG_HAVE_KERNEL_LZO=y 4434+CONFIG_HAVE_KERNEL_LZ4=y 4435+CONFIG_KERNEL_GZIP=y 4436+# CONFIG_KERNEL_LZMA is not set 4437+# CONFIG_KERNEL_XZ is not set 4438+# CONFIG_KERNEL_LZO is not set 4439+# CONFIG_KERNEL_LZ4 is not set 4440+CONFIG_DEFAULT_HOSTNAME="(none)" 4441+# CONFIG_SWAP is not set 4442+CONFIG_SYSVIPC=y 4443+CONFIG_SYSVIPC_SYSCTL=y 4444+# CONFIG_POSIX_MQUEUE is not set 4445+CONFIG_CROSS_MEMORY_ATTACH=y 4446+CONFIG_USELIB=y 4447+CONFIG_AUDIT=y 4448+ 4449+# 4450+# IRQ subsystem 4451+# 4452+CONFIG_GENERIC_IRQ_PROBE=y 4453+CONFIG_GENERIC_IRQ_SHOW=y 4454+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y 4455+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y 4456+CONFIG_GENERIC_IRQ_MIGRATION=y 4457+CONFIG_HARDIRQS_SW_RESEND=y 4458+CONFIG_IRQ_DOMAIN=y 4459+CONFIG_IRQ_DOMAIN_HIERARCHY=y 4460+CONFIG_HANDLE_DOMAIN_IRQ=y 4461+CONFIG_IRQ_FORCED_THREADING=y 4462+CONFIG_SPARSE_IRQ=y 4463+# CONFIG_GENERIC_IRQ_DEBUGFS is not set 4464+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y 4465+CONFIG_ARCH_CLOCKSOURCE_DATA=y 4466+CONFIG_GENERIC_TIME_VSYSCALL=y 4467+CONFIG_GENERIC_CLOCKEVENTS=y 4468+CONFIG_ARCH_HAS_TICK_BROADCAST=y 4469+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y 4470+ 4471+#HDF 4472+CONFIG_DRIVERS_HDF=y 4473+CONFIG_DRIVERS_HDF_PLATFORM=y 4474+CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI=y 4475+CONFIG_DRIVERS_HDF_PLATFORM_MIPI_CSI=y 4476+CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y 4477+CONFIG_DRIVERS_HDF_PLATFORM_I2C=y 4478+CONFIG_DRIVERS_HDF_PLATFORM_WATCHDOG=y 4479+CONFIG_DRIVERS_HDF_PLATFORM_PWM=y 4480+CONFIG_DRIVERS_HDF_PLATFORM_UART=y 4481+CONFIG_DRIVERS_HDF_PLATFORM_SPI=y 4482+CONFIG_DRIVERS_HDF_PLATFORM_RTC=y 4483+CONFIG_DRIVERS_HDF_DISP=y 4484+# CONFIG_DRIVERS_HDF_LCD_ST7789 is not set 4485+CONFIG_DRIVERS_HDF_LCD_ICN9700=y 4486+CONFIG_DRIVERS_HDF_INPUT=y 4487+CONFIG_DRIVERS_HDF_TP_5P5_GT911=y 4488+CONFIG_DRIVERS_HDF_TP_2P35_FT6236=y 4489+CONFIG_DRIVERS_HDF_WIFI=y 4490+CONFIG_DRIVERS_HI3881=y 4491+CONFIG_DRIVERS_HDF_USB_PNP_NOTIFY=y 4492+CONFIG_DRIVERS_HDF_SENSOR=y 4493+# CONFIG_DRIVERS_HDF_SENSOR_ACCEL is not set 4494+# CONFIG_DRIVERS_HDF_SENSOR_GYRO is not set 4495+CONFIG_DRIVERS_HDF_TEST=y 4496+CONFIG_DRIVERS_HDF_USB_F_GENERIC=y 4497+CONFIG_DRIVERS_HDF_USB_PNP_NOTIFY=y 4498+# 4499+# Timers subsystem 4500+# 4501+CONFIG_HZ_PERIODIC=y 4502+# CONFIG_NO_HZ_IDLE is not set 4503+# CONFIG_NO_HZ_FULL is not set 4504+# CONFIG_NO_HZ is not set 4505+# CONFIG_HIGH_RES_TIMERS is not set 4506+CONFIG_PREEMPT_NONE=y 4507+# CONFIG_PREEMPT_VOLUNTARY is not set 4508+# CONFIG_PREEMPT is not set 4509+ 4510+# 4511+# CPU/Task time and stats accounting 4512+# 4513+CONFIG_TICK_CPU_ACCOUNTING=y 4514+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set 4515+# CONFIG_IRQ_TIME_ACCOUNTING is not set 4516+# CONFIG_BSD_PROCESS_ACCT is not set 4517+# CONFIG_TASKSTATS is not set 4518+CONFIG_CPU_ISOLATION=y 4519+ 4520+# 4521+# RCU Subsystem 4522+# 4523+CONFIG_TREE_RCU=y 4524+# CONFIG_RCU_EXPERT is not set 4525+CONFIG_SRCU=y 4526+CONFIG_TREE_SRCU=y 4527+CONFIG_RCU_STALL_COMMON=y 4528+CONFIG_RCU_NEED_SEGCBLIST=y 4529+# CONFIG_IKCONFIG is not set 4530+CONFIG_LOG_BUF_SHIFT=17 4531+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 4532+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 4533+CONFIG_GENERIC_SCHED_CLOCK=y 4534+CONFIG_CGROUPS=y 4535+# CONFIG_MEMCG is not set 4536+# CONFIG_BLK_CGROUP is not set 4537+CONFIG_CGROUP_SCHED=y 4538+CONFIG_FAIR_GROUP_SCHED=y 4539+# CONFIG_CFS_BANDWIDTH is not set 4540+# CONFIG_RT_GROUP_SCHED is not set 4541+# CONFIG_CGROUP_PIDS is not set 4542+# CONFIG_CGROUP_RDMA is not set 4543+# CONFIG_CGROUP_FREEZER is not set 4544+# CONFIG_CPUSETS is not set 4545+# CONFIG_CGROUP_DEVICE is not set 4546+# CONFIG_CGROUP_CPUACCT is not set 4547+# CONFIG_CGROUP_DEBUG is not set 4548+CONFIG_NAMESPACES=y 4549+CONFIG_UTS_NS=y 4550+CONFIG_IPC_NS=y 4551+# CONFIG_USER_NS is not set 4552+CONFIG_PID_NS=y 4553+CONFIG_NET_NS=y 4554+# CONFIG_CHECKPOINT_RESTORE is not set 4555+# CONFIG_SCHED_AUTOGROUP is not set 4556+# CONFIG_SYSFS_DEPRECATED is not set 4557+# CONFIG_RELAY is not set 4558+# CONFIG_BLK_DEV_INITRD is not set 4559+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y 4560+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 4561+CONFIG_SYSCTL=y 4562+CONFIG_ANON_INODES=y 4563+CONFIG_HAVE_UID16=y 4564+CONFIG_BPF=y 4565+# CONFIG_EXPERT is not set 4566+CONFIG_UID16=y 4567+CONFIG_MULTIUSER=y 4568+CONFIG_SYSFS_SYSCALL=y 4569+CONFIG_FHANDLE=y 4570+CONFIG_POSIX_TIMERS=y 4571+CONFIG_PRINTK=y 4572+CONFIG_PRINTK_NMI=y 4573+CONFIG_BUG=y 4574+CONFIG_ELF_CORE=y 4575+CONFIG_BASE_FULL=y 4576+CONFIG_FUTEX=y 4577+CONFIG_FUTEX_PI=y 4578+CONFIG_EPOLL=y 4579+CONFIG_SIGNALFD=y 4580+CONFIG_TIMERFD=y 4581+CONFIG_EVENTFD=y 4582+CONFIG_SHMEM=y 4583+CONFIG_AIO=y 4584+CONFIG_ADVISE_SYSCALLS=y 4585+CONFIG_MEMBARRIER=y 4586+CONFIG_KALLSYMS=y 4587+# CONFIG_KALLSYMS_ALL is not set 4588+CONFIG_KALLSYMS_BASE_RELATIVE=y 4589+# CONFIG_BPF_SYSCALL is not set 4590+# CONFIG_USERFAULTFD is not set 4591+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y 4592+CONFIG_RSEQ=y 4593+# CONFIG_EMBEDDED is not set 4594+CONFIG_HAVE_PERF_EVENTS=y 4595+CONFIG_PERF_USE_VMALLOC=y 4596+ 4597+# 4598+# Kernel Performance Events And Counters 4599+# 4600+# CONFIG_PERF_EVENTS is not set 4601+CONFIG_VM_EVENT_COUNTERS=y 4602+CONFIG_SLUB_DEBUG=y 4603+CONFIG_COMPAT_BRK=y 4604+# CONFIG_SLAB is not set 4605+CONFIG_SLUB=y 4606+CONFIG_SLAB_MERGE_DEFAULT=y 4607+# CONFIG_SLAB_FREELIST_RANDOM is not set 4608+# CONFIG_SLAB_FREELIST_HARDENED is not set 4609+CONFIG_SLUB_CPU_PARTIAL=y 4610+# CONFIG_PROFILING is not set 4611+CONFIG_ARM=y 4612+CONFIG_ARM_HAS_SG_CHAIN=y 4613+CONFIG_MIGHT_HAVE_PCI=y 4614+CONFIG_SYS_SUPPORTS_APM_EMULATION=y 4615+CONFIG_HAVE_PROC_CPU=y 4616+CONFIG_STACKTRACE_SUPPORT=y 4617+CONFIG_LOCKDEP_SUPPORT=y 4618+CONFIG_TRACE_IRQFLAGS_SUPPORT=y 4619+CONFIG_RWSEM_XCHGADD_ALGORITHM=y 4620+CONFIG_FIX_EARLYCON_MEM=y 4621+CONFIG_GENERIC_HWEIGHT=y 4622+CONFIG_GENERIC_CALIBRATE_DELAY=y 4623+CONFIG_ARCH_SUPPORTS_UPROBES=y 4624+CONFIG_ARM_PATCH_PHYS_VIRT=y 4625+CONFIG_GENERIC_BUG=y 4626+CONFIG_PGTABLE_LEVELS=2 4627+ 4628+# 4629+# System Type 4630+# 4631+CONFIG_MMU=y 4632+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 4633+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 4634+CONFIG_ARCH_MULTIPLATFORM=y 4635+# CONFIG_ARCH_EBSA110 is not set 4636+# CONFIG_ARCH_EP93XX is not set 4637+# CONFIG_ARCH_FOOTBRIDGE is not set 4638+# CONFIG_ARCH_NETX is not set 4639+# CONFIG_ARCH_IOP13XX is not set 4640+# CONFIG_ARCH_IOP32X is not set 4641+# CONFIG_ARCH_IOP33X is not set 4642+# CONFIG_ARCH_IXP4XX is not set 4643+# CONFIG_ARCH_DOVE is not set 4644+# CONFIG_ARCH_KS8695 is not set 4645+# CONFIG_ARCH_W90X900 is not set 4646+# CONFIG_ARCH_LPC32XX is not set 4647+# CONFIG_ARCH_PXA is not set 4648+# CONFIG_ARCH_RPC is not set 4649+# CONFIG_ARCH_SA1100 is not set 4650+# CONFIG_ARCH_S3C24XX is not set 4651+# CONFIG_ARCH_DAVINCI is not set 4652+# CONFIG_ARCH_OMAP1 is not set 4653+ 4654+# 4655+# Multiple platform selection 4656+# 4657+ 4658+# 4659+# CPU Core family selection 4660+# 4661+# CONFIG_ARCH_MULTI_V6 is not set 4662+CONFIG_ARCH_MULTI_V7=y 4663+CONFIG_ARCH_MULTI_V6_V7=y 4664+# CONFIG_ARCH_VIRT is not set 4665+# CONFIG_ARCH_ACTIONS is not set 4666+# CONFIG_ARCH_ALPINE is not set 4667+# CONFIG_ARCH_ARTPEC is not set 4668+# CONFIG_ARCH_AT91 is not set 4669+# CONFIG_ARCH_BCM is not set 4670+# CONFIG_ARCH_BERLIN is not set 4671+# CONFIG_ARCH_DIGICOLOR is not set 4672+# CONFIG_ARCH_EXYNOS is not set 4673+# CONFIG_ARCH_HIGHBANK is not set 4674+# CONFIG_ARCH_HISI is not set 4675+CONFIG_ARCH_HISI_BVT=y 4676+ 4677+# 4678+# Hisilicon BVT platform type 4679+# 4680+# CONFIG_ARCH_HI3521DV200 is not set 4681+# CONFIG_ARCH_HI3520DV500 is not set 4682+# CONFIG_ARCH_HI3516A is not set 4683+# CONFIG_ARCH_HI3516CV500 is not set 4684+CONFIG_ARCH_HI3516DV300=y 4685+# CONFIG_ARCH_HI3516EV200 is not set 4686+# CONFIG_ARCH_HI3516EV300 is not set 4687+# CONFIG_ARCH_HI3518EV300 is not set 4688+# CONFIG_ARCH_HI3516DV200 is not set 4689+# CONFIG_ARCH_HI3556V200 is not set 4690+# CONFIG_ARCH_HI3559V200 is not set 4691+# CONFIG_ARCH_HI3536DV100 is not set 4692+# CONFIG_ARCH_HI3521A is not set 4693+# CONFIG_ARCH_HI3531A is not set 4694+# CONFIG_ARCH_HI3556AV100 is not set 4695+# CONFIG_ARCH_HI3519AV100 is not set 4696+# CONFIG_ARCH_HI3568V100 is not set 4697+# CONFIG_ARCH_HISI_BVT_AMP is not set 4698+# CONFIG_HISI_MC is not set 4699+CONFIG_HI_ZRELADDR=0x80008000 4700+CONFIG_HI_PARAMS_PHYS=0x00000100 4701+CONFIG_HI_INITRD_PHYS=0x00800000 4702+# CONFIG_ARCH_MXC is not set 4703+# CONFIG_ARCH_KEYSTONE is not set 4704+# CONFIG_ARCH_MEDIATEK is not set 4705+# CONFIG_ARCH_MESON is not set 4706+# CONFIG_ARCH_MMP is not set 4707+# CONFIG_ARCH_MVEBU is not set 4708+# CONFIG_ARCH_NPCM is not set 4709+ 4710+# 4711+# TI OMAP/AM/DM/DRA Family 4712+# 4713+# CONFIG_ARCH_OMAP3 is not set 4714+# CONFIG_ARCH_OMAP4 is not set 4715+# CONFIG_SOC_OMAP5 is not set 4716+# CONFIG_SOC_AM33XX is not set 4717+# CONFIG_SOC_AM43XX is not set 4718+# CONFIG_SOC_DRA7XX is not set 4719+# CONFIG_ARCH_SIRF is not set 4720+# CONFIG_ARCH_QCOM is not set 4721+# CONFIG_ARCH_REALVIEW is not set 4722+# CONFIG_ARCH_ROCKCHIP is not set 4723+# CONFIG_ARCH_S5PV210 is not set 4724+# CONFIG_ARCH_RENESAS is not set 4725+# CONFIG_ARCH_SOCFPGA is not set 4726+# CONFIG_PLAT_SPEAR is not set 4727+# CONFIG_ARCH_STI is not set 4728+# CONFIG_ARCH_STM32 is not set 4729+# CONFIG_ARCH_SUNXI is not set 4730+# CONFIG_ARCH_TANGO is not set 4731+# CONFIG_ARCH_TEGRA is not set 4732+# CONFIG_ARCH_UNIPHIER is not set 4733+# CONFIG_ARCH_U8500 is not set 4734+# CONFIG_ARCH_VEXPRESS is not set 4735+# CONFIG_ARCH_WM8850 is not set 4736+# CONFIG_ARCH_ZX is not set 4737+# CONFIG_ARCH_ZYNQ is not set 4738+ 4739+# 4740+# Processor Type 4741+# 4742+CONFIG_CPU_V7=y 4743+CONFIG_CPU_THUMB_CAPABLE=y 4744+CONFIG_CPU_32v6K=y 4745+CONFIG_CPU_32v7=y 4746+CONFIG_CPU_ABRT_EV7=y 4747+CONFIG_CPU_PABRT_V7=y 4748+CONFIG_CPU_CACHE_V7=y 4749+CONFIG_CPU_CACHE_VIPT=y 4750+CONFIG_CPU_COPY_V6=y 4751+CONFIG_CPU_TLB_V7=y 4752+CONFIG_CPU_HAS_ASID=y 4753+CONFIG_CPU_CP15=y 4754+CONFIG_CPU_CP15_MMU=y 4755+ 4756+# 4757+# Processor Features 4758+# 4759+# CONFIG_ARM_LPAE is not set 4760+CONFIG_ARM_THUMB=y 4761+# CONFIG_ARM_THUMBEE is not set 4762+CONFIG_ARM_VIRT_EXT=y 4763+CONFIG_SWP_EMULATE=y 4764+# CONFIG_CPU_ICACHE_DISABLE is not set 4765+# CONFIG_CPU_BPREDICT_DISABLE is not set 4766+CONFIG_CPU_SPECTRE=y 4767+CONFIG_HARDEN_BRANCH_PREDICTOR=y 4768+CONFIG_KUSER_HELPERS=y 4769+CONFIG_VDSO=y 4770+CONFIG_MIGHT_HAVE_CACHE_L2X0=y 4771+# CONFIG_CACHE_L2X0 is not set 4772+CONFIG_ARM_L1_CACHE_SHIFT_6=y 4773+CONFIG_ARM_L1_CACHE_SHIFT=6 4774+CONFIG_ARM_DMA_MEM_BUFFERABLE=y 4775+CONFIG_DEBUG_ALIGN_RODATA=y 4776+# CONFIG_ARM_ERRATA_430973 is not set 4777+# CONFIG_ARM_ERRATA_643719 is not set 4778+# CONFIG_ARM_ERRATA_720789 is not set 4779+# CONFIG_ARM_ERRATA_754322 is not set 4780+# CONFIG_ARM_ERRATA_754327 is not set 4781+# CONFIG_ARM_ERRATA_764369 is not set 4782+# CONFIG_ARM_ERRATA_775420 is not set 4783+# CONFIG_ARM_ERRATA_798181 is not set 4784+# CONFIG_ARM_ERRATA_773022 is not set 4785+# CONFIG_ARM_ERRATA_818325_852422 is not set 4786+# CONFIG_ARM_ERRATA_821420 is not set 4787+# CONFIG_ARM_ERRATA_825619 is not set 4788+# CONFIG_ARM_ERRATA_852421 is not set 4789+# CONFIG_ARM_ERRATA_852423 is not set 4790+ 4791+# 4792+# Bus support 4793+# 4794+# CONFIG_PCI is not set 4795+ 4796+# 4797+# PCI Endpoint 4798+# 4799+# CONFIG_PCI_ENDPOINT is not set 4800+# CONFIG_PCCARD is not set 4801+ 4802+# 4803+# Kernel Features 4804+# 4805+CONFIG_HAVE_SMP=y 4806+CONFIG_SMP=y 4807+CONFIG_SMP_ON_UP=y 4808+CONFIG_ARM_CPU_TOPOLOGY=y 4809+# CONFIG_SCHED_MC is not set 4810+# CONFIG_SCHED_SMT is not set 4811+CONFIG_HAVE_ARM_ARCH_TIMER=y 4812+# CONFIG_MCPM is not set 4813+# CONFIG_BIG_LITTLE is not set 4814+CONFIG_VMSPLIT_3G=y 4815+# CONFIG_VMSPLIT_3G_OPT is not set 4816+# CONFIG_VMSPLIT_2G is not set 4817+# CONFIG_VMSPLIT_1G is not set 4818+CONFIG_PAGE_OFFSET=0xC0000000 4819+CONFIG_NR_CPUS=2 4820+CONFIG_HOTPLUG_CPU=y 4821+# CONFIG_ARM_PSCI is not set 4822+CONFIG_ARCH_NR_GPIO=0 4823+CONFIG_HZ_FIXED=0 4824+CONFIG_HZ_100=y 4825+# CONFIG_HZ_200 is not set 4826+# CONFIG_HZ_250 is not set 4827+# CONFIG_HZ_300 is not set 4828+# CONFIG_HZ_500 is not set 4829+# CONFIG_HZ_1000 is not set 4830+CONFIG_HZ=100 4831+# CONFIG_THUMB2_KERNEL is not set 4832+CONFIG_ARM_PATCH_IDIV=y 4833+CONFIG_AEABI=y 4834+CONFIG_OABI_COMPAT=y 4835+CONFIG_HAVE_ARCH_PFN_VALID=y 4836+CONFIG_HIGHMEM=y 4837+CONFIG_HIGHPTE=y 4838+CONFIG_CPU_SW_DOMAIN_PAN=y 4839+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y 4840+# CONFIG_ARM_MODULE_PLTS is not set 4841+CONFIG_FORCE_MAX_ZONEORDER=11 4842+CONFIG_ALIGNMENT_TRAP=y 4843+# CONFIG_UACCESS_WITH_MEMCPY is not set 4844+# CONFIG_SECCOMP is not set 4845+# CONFIG_PARAVIRT is not set 4846+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set 4847+# CONFIG_XEN is not set 4848+ 4849+# 4850+# Boot options 4851+# 4852+CONFIG_USE_OF=y 4853+CONFIG_ATAGS=y 4854+# CONFIG_DEPRECATED_PARAM_STRUCT is not set 4855+CONFIG_ZBOOT_ROM_TEXT=0 4856+CONFIG_ZBOOT_ROM_BSS=0 4857+CONFIG_ARM_APPENDED_DTB=y 4858+CONFIG_ARM_ATAG_DTB_COMPAT=y 4859+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y 4860+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set 4861+CONFIG_CMDLINE="" 4862+# CONFIG_KEXEC is not set 4863+# CONFIG_CRASH_DUMP is not set 4864+CONFIG_AUTO_ZRELADDR=y 4865+# CONFIG_EFI is not set 4866+ 4867+# 4868+# CPU Power Management 4869+# 4870+ 4871+# 4872+# CPU Frequency scaling 4873+# 4874+# CONFIG_CPU_FREQ is not set 4875+ 4876+# 4877+# CPU Idle 4878+# 4879+# CONFIG_CPU_IDLE is not set 4880+ 4881+# 4882+# Floating point emulation 4883+# 4884+ 4885+# 4886+# At least one emulation must be selected 4887+# 4888+# CONFIG_FPE_NWFPE is not set 4889+# CONFIG_FPE_FASTFPE is not set 4890+CONFIG_VFP=y 4891+CONFIG_VFPv3=y 4892+CONFIG_NEON=y 4893+CONFIG_KERNEL_MODE_NEON=y 4894+ 4895+# 4896+# Power management options 4897+# 4898+CONFIG_SUSPEND=y 4899+CONFIG_SUSPEND_FREEZER=y 4900+CONFIG_PM_SLEEP=y 4901+CONFIG_PM_SLEEP_SMP=y 4902+# CONFIG_PM_AUTOSLEEP is not set 4903+CONFIG_PM_WAKELOCKS=y 4904+CONFIG_PM_WAKELOCKS_GC=y 4905+CONFIG_PM=y 4906+# CONFIG_PM_DEBUG is not set 4907+# CONFIG_APM_EMULATION is not set 4908+CONFIG_PM_CLK=y 4909+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set 4910+CONFIG_CPU_PM=y 4911+CONFIG_ARCH_SUSPEND_POSSIBLE=y 4912+CONFIG_ARM_CPU_SUSPEND=y 4913+CONFIG_ARCH_HIBERNATION_POSSIBLE=y 4914+ 4915+# 4916+# Firmware Drivers 4917+# 4918+# CONFIG_FW_CFG_SYSFS is not set 4919+CONFIG_HAVE_ARM_SMCCC=y 4920+# CONFIG_GOOGLE_FIRMWARE is not set 4921+ 4922+# 4923+# Tegra firmware driver 4924+# 4925+# CONFIG_ARM_CRYPTO is not set 4926+# CONFIG_VIRTUALIZATION is not set 4927+ 4928+# 4929+# General architecture-dependent options 4930+# 4931+CONFIG_HAVE_OPROFILE=y 4932+# CONFIG_KPROBES is not set 4933+# CONFIG_JUMP_LABEL is not set 4934+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y 4935+CONFIG_ARCH_USE_BUILTIN_BSWAP=y 4936+CONFIG_HAVE_KPROBES=y 4937+CONFIG_HAVE_KRETPROBES=y 4938+CONFIG_HAVE_OPTPROBES=y 4939+CONFIG_HAVE_NMI=y 4940+CONFIG_HAVE_ARCH_TRACEHOOK=y 4941+CONFIG_HAVE_DMA_CONTIGUOUS=y 4942+CONFIG_GENERIC_SMP_IDLE_THREAD=y 4943+CONFIG_GENERIC_IDLE_POLL_SETUP=y 4944+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y 4945+CONFIG_ARCH_HAS_SET_MEMORY=y 4946+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y 4947+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y 4948+CONFIG_HAVE_RSEQ=y 4949+CONFIG_HAVE_CLK=y 4950+CONFIG_HAVE_PERF_REGS=y 4951+CONFIG_HAVE_PERF_USER_STACK_DUMP=y 4952+CONFIG_HAVE_ARCH_JUMP_LABEL=y 4953+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y 4954+CONFIG_HAVE_STACKPROTECTOR=y 4955+CONFIG_CC_HAS_STACKPROTECTOR_NONE=y 4956+CONFIG_STACKPROTECTOR=y 4957+CONFIG_STACKPROTECTOR_STRONG=y 4958+CONFIG_HAVE_CONTEXT_TRACKING=y 4959+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y 4960+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y 4961+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y 4962+CONFIG_MODULES_USE_ELF_REL=y 4963+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y 4964+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y 4965+CONFIG_HAVE_EXIT_THREAD=y 4966+CONFIG_ARCH_MMAP_RND_BITS=8 4967+CONFIG_CLONE_BACKWARDS=y 4968+CONFIG_OLD_SIGSUSPEND3=y 4969+CONFIG_OLD_SIGACTION=y 4970+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y 4971+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y 4972+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y 4973+CONFIG_STRICT_KERNEL_RWX=y 4974+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y 4975+CONFIG_STRICT_MODULE_RWX=y 4976+CONFIG_ARCH_HAS_PHYS_TO_DMA=y 4977+CONFIG_REFCOUNT_FULL=y 4978+ 4979+# 4980+# GCOV-based kernel profiling 4981+# 4982+# CONFIG_GCOV_KERNEL is not set 4983+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y 4984+CONFIG_PLUGIN_HOSTCC="" 4985+CONFIG_HAVE_GCC_PLUGINS=y 4986+CONFIG_RT_MUTEXES=y 4987+CONFIG_BASE_SMALL=0 4988+CONFIG_MODULES=y 4989+CONFIG_MODULE_FORCE_LOAD=y 4990+CONFIG_MODULE_UNLOAD=y 4991+CONFIG_MODULE_FORCE_UNLOAD=y 4992+# CONFIG_MODVERSIONS is not set 4993+# CONFIG_MODULE_SRCVERSION_ALL is not set 4994+# CONFIG_MODULE_SIG is not set 4995+# CONFIG_MODULE_COMPRESS is not set 4996+# CONFIG_TRIM_UNUSED_KSYMS is not set 4997+CONFIG_BLOCK=y 4998+CONFIG_LBDAF=y 4999+CONFIG_BLK_SCSI_REQUEST=y 5000+CONFIG_BLK_DEV_BSG=y 5001+# CONFIG_BLK_DEV_BSGLIB is not set 5002+# CONFIG_BLK_DEV_INTEGRITY is not set 5003+# CONFIG_BLK_DEV_ZONED is not set 5004+CONFIG_BLK_CMDLINE_PARSER=y 5005+# CONFIG_BLK_WBT is not set 5006+# CONFIG_BLK_DEBUG_FS is not set 5007+# CONFIG_BLK_SED_OPAL is not set 5008+ 5009+# 5010+# Partition Types 5011+# 5012+CONFIG_PARTITION_ADVANCED=y 5013+# CONFIG_ACORN_PARTITION is not set 5014+# CONFIG_AIX_PARTITION is not set 5015+# CONFIG_OSF_PARTITION is not set 5016+# CONFIG_AMIGA_PARTITION is not set 5017+# CONFIG_ATARI_PARTITION is not set 5018+# CONFIG_MAC_PARTITION is not set 5019+CONFIG_MSDOS_PARTITION=y 5020+# CONFIG_BSD_DISKLABEL is not set 5021+# CONFIG_MINIX_SUBPARTITION is not set 5022+# CONFIG_SOLARIS_X86_PARTITION is not set 5023+# CONFIG_UNIXWARE_DISKLABEL is not set 5024+# CONFIG_LDM_PARTITION is not set 5025+# CONFIG_SGI_PARTITION is not set 5026+# CONFIG_ULTRIX_PARTITION is not set 5027+# CONFIG_SUN_PARTITION is not set 5028+# CONFIG_KARMA_PARTITION is not set 5029+CONFIG_EFI_PARTITION=y 5030+# CONFIG_SYSV68_PARTITION is not set 5031+CONFIG_CMDLINE_PARTITION=y 5032+ 5033+# 5034+# IO Schedulers 5035+# 5036+CONFIG_IOSCHED_NOOP=y 5037+CONFIG_IOSCHED_DEADLINE=y 5038+CONFIG_IOSCHED_CFQ=y 5039+# CONFIG_DEFAULT_DEADLINE is not set 5040+CONFIG_DEFAULT_CFQ=y 5041+# CONFIG_DEFAULT_NOOP is not set 5042+CONFIG_DEFAULT_IOSCHED="cfq" 5043+CONFIG_MQ_IOSCHED_DEADLINE=y 5044+CONFIG_MQ_IOSCHED_KYBER=y 5045+# CONFIG_IOSCHED_BFQ is not set 5046+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y 5047+CONFIG_INLINE_READ_UNLOCK=y 5048+CONFIG_INLINE_READ_UNLOCK_IRQ=y 5049+CONFIG_INLINE_WRITE_UNLOCK=y 5050+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y 5051+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y 5052+CONFIG_MUTEX_SPIN_ON_OWNER=y 5053+CONFIG_RWSEM_SPIN_ON_OWNER=y 5054+CONFIG_LOCK_SPIN_ON_OWNER=y 5055+CONFIG_FREEZER=y 5056+ 5057+# 5058+# Executable file formats 5059+# 5060+CONFIG_BINFMT_ELF=y 5061+# CONFIG_BINFMT_ELF_FDPIC is not set 5062+CONFIG_ELFCORE=y 5063+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y 5064+CONFIG_BINFMT_SCRIPT=y 5065+# CONFIG_BINFMT_FLAT is not set 5066+# CONFIG_BINFMT_MISC is not set 5067+CONFIG_COREDUMP=y 5068+ 5069+# 5070+# Memory Management options 5071+# 5072+CONFIG_FLATMEM=y 5073+CONFIG_FLAT_NODE_MEM_MAP=y 5074+CONFIG_HAVE_MEMBLOCK=y 5075+CONFIG_NO_BOOTMEM=y 5076+CONFIG_MEMORY_ISOLATION=y 5077+CONFIG_SPLIT_PTLOCK_CPUS=4 5078+CONFIG_COMPACTION=y 5079+CONFIG_MIGRATION=y 5080+CONFIG_BOUNCE=y 5081+# CONFIG_KSM is not set 5082+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 5083+# CONFIG_CLEANCACHE is not set 5084+CONFIG_CMA=y 5085+CONFIG_CMA_DEBUG=y 5086+# CONFIG_CMA_DEBUGFS is not set 5087+CONFIG_CMA_AREAS=7 5088+# CONFIG_ZPOOL is not set 5089+# CONFIG_ZBUD is not set 5090+# CONFIG_ZSMALLOC is not set 5091+CONFIG_GENERIC_EARLY_IOREMAP=y 5092+# CONFIG_IDLE_PAGE_TRACKING is not set 5093+CONFIG_FRAME_VECTOR=y 5094+# CONFIG_PERCPU_STATS is not set 5095+# CONFIG_GUP_BENCHMARK is not set 5096+CONFIG_NET=y 5097+ 5098+# 5099+# Networking options 5100+# 5101+CONFIG_PACKET=y 5102+# CONFIG_PACKET_DIAG is not set 5103+CONFIG_UNIX=y 5104+# CONFIG_UNIX_DIAG is not set 5105+# CONFIG_TLS is not set 5106+CONFIG_XFRM=y 5107+# CONFIG_XFRM_USER is not set 5108+# CONFIG_XFRM_INTERFACE is not set 5109+# CONFIG_XFRM_SUB_POLICY is not set 5110+# CONFIG_XFRM_MIGRATE is not set 5111+# CONFIG_XFRM_STATISTICS is not set 5112+# CONFIG_NET_KEY is not set 5113+CONFIG_INET=y 5114+# CONFIG_IP_MULTICAST is not set 5115+# CONFIG_IP_ADVANCED_ROUTER is not set 5116+CONFIG_IP_PNP=y 5117+CONFIG_IP_PNP_DHCP=y 5118+# CONFIG_IP_PNP_BOOTP is not set 5119+# CONFIG_IP_PNP_RARP is not set 5120+# CONFIG_NET_IPIP is not set 5121+# CONFIG_NET_IPGRE_DEMUX is not set 5122+# CONFIG_SYN_COOKIES is not set 5123+# CONFIG_NET_IPVTI is not set 5124+# CONFIG_NET_FOU is not set 5125+# CONFIG_INET_AH is not set 5126+# CONFIG_INET_ESP is not set 5127+# CONFIG_INET_IPCOMP is not set 5128+CONFIG_INET_XFRM_MODE_TRANSPORT=y 5129+CONFIG_INET_XFRM_MODE_TUNNEL=y 5130+CONFIG_INET_XFRM_MODE_BEET=y 5131+CONFIG_INET_DIAG=y 5132+CONFIG_INET_TCP_DIAG=y 5133+# CONFIG_INET_UDP_DIAG is not set 5134+# CONFIG_INET_RAW_DIAG is not set 5135+# CONFIG_INET_DIAG_DESTROY is not set 5136+# CONFIG_TCP_CONG_ADVANCED is not set 5137+CONFIG_TCP_CONG_CUBIC=y 5138+CONFIG_DEFAULT_TCP_CONG="cubic" 5139+# CONFIG_TCP_MD5SIG is not set 5140+CONFIG_IPV6=y 5141+# CONFIG_IPV6_ROUTER_PREF is not set 5142+# CONFIG_IPV6_OPTIMISTIC_DAD is not set 5143+# CONFIG_INET6_AH is not set 5144+# CONFIG_INET6_ESP is not set 5145+# CONFIG_INET6_IPCOMP is not set 5146+# CONFIG_IPV6_MIP6 is not set 5147+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set 5148+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set 5149+# CONFIG_INET6_XFRM_MODE_BEET is not set 5150+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 5151+# CONFIG_IPV6_SIT is not set 5152+# CONFIG_IPV6_TUNNEL is not set 5153+# CONFIG_IPV6_MULTIPLE_TABLES is not set 5154+# CONFIG_IPV6_MROUTE is not set 5155+# CONFIG_IPV6_SEG6_LWTUNNEL is not set 5156+# CONFIG_IPV6_SEG6_HMAC is not set 5157+# CONFIG_NETLABEL is not set 5158+CONFIG_NETWORK_SECMARK=y 5159+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set 5160+# CONFIG_NETFILTER is not set 5161+# CONFIG_BPFILTER is not set 5162+# CONFIG_IP_DCCP is not set 5163+# CONFIG_IP_SCTP is not set 5164+# CONFIG_RDS is not set 5165+# CONFIG_TIPC is not set 5166+# CONFIG_ATM is not set 5167+# CONFIG_L2TP is not set 5168+# CONFIG_BRIDGE is not set 5169+CONFIG_HAVE_NET_DSA=y 5170+# CONFIG_NET_DSA is not set 5171+CONFIG_VLAN_8021Q=y 5172+# CONFIG_VLAN_8021Q_GVRP is not set 5173+# CONFIG_VLAN_8021Q_MVRP is not set 5174+# CONFIG_DECNET is not set 5175+# CONFIG_LLC2 is not set 5176+# CONFIG_ATALK is not set 5177+# CONFIG_X25 is not set 5178+# CONFIG_LAPB is not set 5179+# CONFIG_PHONET is not set 5180+# CONFIG_6LOWPAN is not set 5181+# CONFIG_IEEE802154 is not set 5182+# CONFIG_NET_SCHED is not set 5183+# CONFIG_DCB is not set 5184+CONFIG_DNS_RESOLVER=y 5185+# CONFIG_BATMAN_ADV is not set 5186+# CONFIG_OPENVSWITCH is not set 5187+# CONFIG_VSOCKETS is not set 5188+# CONFIG_NETLINK_DIAG is not set 5189+# CONFIG_MPLS is not set 5190+# CONFIG_NET_NSH is not set 5191+# CONFIG_HSR is not set 5192+# CONFIG_NET_SWITCHDEV is not set 5193+# CONFIG_NET_L3_MASTER_DEV is not set 5194+# CONFIG_NET_NCSI is not set 5195+CONFIG_RPS=y 5196+CONFIG_RFS_ACCEL=y 5197+CONFIG_XPS=y 5198+# CONFIG_CGROUP_NET_PRIO is not set 5199+# CONFIG_CGROUP_NET_CLASSID is not set 5200+CONFIG_NET_RX_BUSY_POLL=y 5201+CONFIG_BQL=y 5202+# CONFIG_BPF_JIT is not set 5203+CONFIG_NET_FLOW_LIMIT=y 5204+ 5205+# 5206+# Network testing 5207+# 5208+# CONFIG_NET_PKTGEN is not set 5209+# CONFIG_HAMRADIO is not set 5210+# CONFIG_CAN is not set 5211+# CONFIG_BT is not set 5212+# CONFIG_AF_RXRPC is not set 5213+# CONFIG_AF_KCM is not set 5214+CONFIG_WIRELESS=y 5215+# CONFIG_CFG80211 is not set 5216+ 5217+# 5218+# CFG80211 needs to be enabled for MAC80211 5219+# 5220+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 5221+# CONFIG_WIMAX is not set 5222+# CONFIG_RFKILL is not set 5223+# CONFIG_NET_9P is not set 5224+# CONFIG_CAIF is not set 5225+# CONFIG_CEPH_LIB is not set 5226+# CONFIG_NFC is not set 5227+# CONFIG_PSAMPLE is not set 5228+# CONFIG_NET_IFE is not set 5229+# CONFIG_LWTUNNEL is not set 5230+CONFIG_GRO_CELLS=y 5231+# CONFIG_NET_DEVLINK is not set 5232+CONFIG_MAY_USE_DEVLINK=y 5233+# CONFIG_FAILOVER is not set 5234+CONFIG_HAVE_EBPF_JIT=y 5235+ 5236+# 5237+# Device Drivers 5238+# 5239+CONFIG_ARM_AMBA=y 5240+ 5241+# 5242+# Generic Driver Options 5243+# 5244+CONFIG_UEVENT_HELPER=y 5245+CONFIG_UEVENT_HELPER_PATH="" 5246+CONFIG_DEVTMPFS=y 5247+CONFIG_DEVTMPFS_MOUNT=y 5248+CONFIG_STANDALONE=y 5249+CONFIG_PREVENT_FIRMWARE_BUILD=y 5250+ 5251+# 5252+# Firmware loader 5253+# 5254+CONFIG_FW_LOADER=y 5255+CONFIG_EXTRA_FIRMWARE="" 5256+# CONFIG_FW_LOADER_USER_HELPER is not set 5257+CONFIG_ALLOW_DEV_COREDUMP=y 5258+# CONFIG_DEBUG_DRIVER is not set 5259+# CONFIG_DEBUG_DEVRES is not set 5260+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set 5261+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set 5262+CONFIG_GENERIC_CPU_AUTOPROBE=y 5263+CONFIG_REGMAP=y 5264+CONFIG_REGMAP_I2C=y 5265+CONFIG_REGMAP_SPI=y 5266+CONFIG_REGMAP_MMIO=y 5267+CONFIG_DMA_SHARED_BUFFER=y 5268+# CONFIG_DMA_FENCE_TRACE is not set 5269+CONFIG_DMA_CMA=y 5270+ 5271+# 5272+# Default contiguous memory area size: 5273+# 5274+CONFIG_CMA_SIZE_MBYTES=64 5275+CONFIG_CMA_SIZE_SEL_MBYTES=y 5276+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set 5277+# CONFIG_CMA_SIZE_SEL_MIN is not set 5278+# CONFIG_CMA_SIZE_SEL_MAX is not set 5279+CONFIG_CMA_ALIGNMENT=8 5280+CONFIG_GENERIC_ARCH_TOPOLOGY=y 5281+ 5282+# 5283+# Bus devices 5284+# 5285+# CONFIG_BRCMSTB_GISB_ARB is not set 5286+# CONFIG_SIMPLE_PM_BUS is not set 5287+# CONFIG_VEXPRESS_CONFIG is not set 5288+# CONFIG_CONNECTOR is not set 5289+# CONFIG_GNSS is not set 5290+# CONFIG_MTD is not set 5291+CONFIG_DTC=y 5292+CONFIG_OF=y 5293+# CONFIG_OF_UNITTEST is not set 5294+CONFIG_OF_FLATTREE=y 5295+CONFIG_OF_EARLY_FLATTREE=y 5296+CONFIG_OF_KOBJ=y 5297+CONFIG_OF_ADDRESS=y 5298+CONFIG_OF_IRQ=y 5299+CONFIG_OF_NET=y 5300+CONFIG_OF_MDIO=y 5301+CONFIG_OF_RESERVED_MEM=y 5302+# CONFIG_OF_OVERLAY is not set 5303+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y 5304+# CONFIG_PARPORT is not set 5305+CONFIG_BLK_DEV=y 5306+# CONFIG_BLK_DEV_NULL_BLK is not set 5307+# CONFIG_BLK_DEV_LOOP is not set 5308+# CONFIG_BLK_DEV_DRBD is not set 5309+# CONFIG_BLK_DEV_NBD is not set 5310+CONFIG_BLK_DEV_RAM=y 5311+CONFIG_BLK_DEV_RAM_COUNT=16 5312+CONFIG_BLK_DEV_RAM_SIZE=65536 5313+# CONFIG_CDROM_PKTCDVD is not set 5314+# CONFIG_ATA_OVER_ETH is not set 5315+# CONFIG_BLK_DEV_RBD is not set 5316+ 5317+# 5318+# NVME Support 5319+# 5320+# CONFIG_NVME_FC is not set 5321+# CONFIG_NVME_TARGET is not set 5322+ 5323+# 5324+# Misc devices 5325+# 5326+# CONFIG_AD525X_DPOT is not set 5327+# CONFIG_DUMMY_IRQ is not set 5328+# CONFIG_ICS932S401 is not set 5329+# CONFIG_ENCLOSURE_SERVICES is not set 5330+# CONFIG_APDS9802ALS is not set 5331+# CONFIG_ISL29003 is not set 5332+# CONFIG_ISL29020 is not set 5333+# CONFIG_SENSORS_TSL2550 is not set 5334+# CONFIG_SENSORS_BH1770 is not set 5335+# CONFIG_SENSORS_APDS990X is not set 5336+# CONFIG_HMC6352 is not set 5337+# CONFIG_DS1682 is not set 5338+# CONFIG_USB_SWITCH_FSA9480 is not set 5339+# CONFIG_LATTICE_ECP3_CONFIG is not set 5340+# CONFIG_SRAM is not set 5341+# CONFIG_C2PORT is not set 5342+ 5343+# 5344+# EEPROM support 5345+# 5346+# CONFIG_EEPROM_AT24 is not set 5347+# CONFIG_EEPROM_AT25 is not set 5348+# CONFIG_EEPROM_LEGACY is not set 5349+# CONFIG_EEPROM_MAX6875 is not set 5350+# CONFIG_EEPROM_93CX6 is not set 5351+# CONFIG_EEPROM_93XX46 is not set 5352+# CONFIG_EEPROM_IDT_89HPESX is not set 5353+ 5354+# 5355+# Texas Instruments shared transport line discipline 5356+# 5357+# CONFIG_TI_ST is not set 5358+# CONFIG_SENSORS_LIS3_SPI is not set 5359+# CONFIG_SENSORS_LIS3_I2C is not set 5360+# CONFIG_ALTERA_STAPL is not set 5361+ 5362+# 5363+# Intel MIC & related support 5364+# 5365+ 5366+# 5367+# Intel MIC Bus Driver 5368+# 5369+ 5370+# 5371+# SCIF Bus Driver 5372+# 5373+ 5374+# 5375+# VOP Bus Driver 5376+# 5377+ 5378+# 5379+# Intel MIC Host Driver 5380+# 5381+ 5382+# 5383+# Intel MIC Card Driver 5384+# 5385+ 5386+# 5387+# SCIF Driver 5388+# 5389+ 5390+# 5391+# Intel MIC Coprocessor State Management (COSM) Drivers 5392+# 5393+ 5394+# 5395+# VOP Driver 5396+# 5397+# CONFIG_ECHO is not set 5398+# CONFIG_MISC_RTSX_USB is not set 5399+ 5400+# 5401+# SCSI device support 5402+# 5403+CONFIG_SCSI_MOD=y 5404+# CONFIG_RAID_ATTRS is not set 5405+CONFIG_SCSI=y 5406+CONFIG_SCSI_DMA=y 5407+# CONFIG_SCSI_MQ_DEFAULT is not set 5408+CONFIG_SCSI_PROC_FS=y 5409+ 5410+# 5411+# SCSI support type (disk, tape, CD-ROM) 5412+# 5413+CONFIG_BLK_DEV_SD=y 5414+# CONFIG_CHR_DEV_ST is not set 5415+# CONFIG_CHR_DEV_OSST is not set 5416+# CONFIG_BLK_DEV_SR is not set 5417+# CONFIG_CHR_DEV_SG is not set 5418+# CONFIG_CHR_DEV_SCH is not set 5419+# CONFIG_SCSI_CONSTANTS is not set 5420+# CONFIG_SCSI_LOGGING is not set 5421+# CONFIG_SCSI_SCAN_ASYNC is not set 5422+ 5423+# 5424+# SCSI Transports 5425+# 5426+# CONFIG_SCSI_SPI_ATTRS is not set 5427+# CONFIG_SCSI_FC_ATTRS is not set 5428+# CONFIG_SCSI_ISCSI_ATTRS is not set 5429+# CONFIG_SCSI_SAS_ATTRS is not set 5430+# CONFIG_SCSI_SAS_LIBSAS is not set 5431+# CONFIG_SCSI_SRP_ATTRS is not set 5432+CONFIG_SCSI_LOWLEVEL=y 5433+# CONFIG_ISCSI_TCP is not set 5434+# CONFIG_ISCSI_BOOT_SYSFS is not set 5435+# CONFIG_SCSI_UFSHCD is not set 5436+# CONFIG_SCSI_DEBUG is not set 5437+# CONFIG_SCSI_DH is not set 5438+# CONFIG_SCSI_OSD_INITIATOR is not set 5439+# CONFIG_ATA is not set 5440+# CONFIG_MD is not set 5441+# CONFIG_TARGET_CORE is not set 5442+CONFIG_NETDEVICES=y 5443+CONFIG_MII=y 5444+CONFIG_NET_CORE=y 5445+# CONFIG_BONDING is not set 5446+# CONFIG_DUMMY is not set 5447+# CONFIG_EQUALIZER is not set 5448+# CONFIG_NET_TEAM is not set 5449+# CONFIG_MACVLAN is not set 5450+# CONFIG_VXLAN is not set 5451+# CONFIG_GENEVE is not set 5452+# CONFIG_GTP is not set 5453+# CONFIG_MACSEC is not set 5454+# CONFIG_NETCONSOLE is not set 5455+# CONFIG_TUN is not set 5456+# CONFIG_TUN_VNET_CROSS_LE is not set 5457+# CONFIG_VETH is not set 5458+# CONFIG_NLMON is not set 5459+ 5460+# 5461+# CAIF transport drivers 5462+# 5463+ 5464+# 5465+# Distributed Switch Architecture drivers 5466+# 5467+CONFIG_ETHERNET=y 5468+CONFIG_NET_VENDOR_ALACRITECH=y 5469+# CONFIG_ALTERA_TSE is not set 5470+# CONFIG_NET_VENDOR_AMAZON is not set 5471+CONFIG_NET_VENDOR_AQUANTIA=y 5472+# CONFIG_NET_VENDOR_ARC is not set 5473+# CONFIG_NET_VENDOR_AURORA is not set 5474+# CONFIG_NET_VENDOR_BROADCOM is not set 5475+CONFIG_NET_VENDOR_CADENCE=y 5476+# CONFIG_MACB is not set 5477+CONFIG_NET_VENDOR_CAVIUM=y 5478+# CONFIG_NET_VENDOR_CIRRUS is not set 5479+CONFIG_NET_VENDOR_CORTINA=y 5480+# CONFIG_GEMINI_ETHERNET is not set 5481+# CONFIG_DM9000 is not set 5482+# CONFIG_DNET is not set 5483+# CONFIG_NET_VENDOR_EZCHIP is not set 5484+# CONFIG_NET_VENDOR_FARADAY is not set 5485+CONFIG_NET_VENDOR_HISILICON=y 5486+# CONFIG_HIX5HD2_GMAC is not set 5487+CONFIG_HISI_FEMAC=y 5488+# CONFIG_HIP04_ETH is not set 5489+# CONFIG_HNS is not set 5490+# CONFIG_HNS_DSAF is not set 5491+# CONFIG_HNS_ENET is not set 5492+# CONFIG_HIETH_GMAC is not set 5493+CONFIG_NET_VENDOR_HUAWEI=y 5494+# CONFIG_NET_VENDOR_INTEL is not set 5495+# CONFIG_NET_VENDOR_MARVELL is not set 5496+CONFIG_NET_VENDOR_MELLANOX=y 5497+# CONFIG_MLXSW_CORE is not set 5498+# CONFIG_MLXFW is not set 5499+# CONFIG_NET_VENDOR_MICREL is not set 5500+# CONFIG_NET_VENDOR_MICROCHIP is not set 5501+CONFIG_NET_VENDOR_MICROSEMI=y 5502+# CONFIG_NET_VENDOR_NATSEMI is not set 5503+# CONFIG_NET_VENDOR_NETRONOME is not set 5504+CONFIG_NET_VENDOR_NI=y 5505+# CONFIG_ETHOC is not set 5506+# CONFIG_NET_VENDOR_QUALCOMM is not set 5507+# CONFIG_NET_VENDOR_RENESAS is not set 5508+# CONFIG_NET_VENDOR_ROCKER is not set 5509+# CONFIG_NET_VENDOR_SAMSUNG is not set 5510+# CONFIG_NET_VENDOR_SEEQ is not set 5511+CONFIG_NET_VENDOR_SOLARFLARE=y 5512+# CONFIG_NET_VENDOR_SMSC is not set 5513+CONFIG_NET_VENDOR_SOCIONEXT=y 5514+# CONFIG_NET_VENDOR_STMICRO is not set 5515+# CONFIG_NET_VENDOR_SYNOPSYS is not set 5516+# CONFIG_NET_VENDOR_VIA is not set 5517+# CONFIG_NET_VENDOR_WIZNET is not set 5518+CONFIG_MDIO_DEVICE=y 5519+CONFIG_MDIO_BUS=y 5520+# CONFIG_MDIO_BCM_UNIMAC is not set 5521+# CONFIG_MDIO_BITBANG is not set 5522+# CONFIG_MDIO_BUS_MUX_GPIO is not set 5523+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set 5524+CONFIG_MDIO_HISI_FEMAC=y 5525+# CONFIG_MDIO_HISI_GEMAC is not set 5526+# CONFIG_MDIO_MSCC_MIIM is not set 5527+CONFIG_PHYLIB=y 5528+CONFIG_SWPHY=y 5529+ 5530+# 5531+# MII PHY device drivers 5532+# 5533+# CONFIG_AMD_PHY is not set 5534+# CONFIG_AQUANTIA_PHY is not set 5535+# CONFIG_ASIX_PHY is not set 5536+# CONFIG_AT803X_PHY is not set 5537+# CONFIG_BCM7XXX_PHY is not set 5538+# CONFIG_BCM87XX_PHY is not set 5539+# CONFIG_BROADCOM_PHY is not set 5540+# CONFIG_CICADA_PHY is not set 5541+# CONFIG_CORTINA_PHY is not set 5542+# CONFIG_DAVICOM_PHY is not set 5543+# CONFIG_DP83822_PHY is not set 5544+# CONFIG_DP83TC811_PHY is not set 5545+# CONFIG_DP83848_PHY is not set 5546+# CONFIG_DP83867_PHY is not set 5547+CONFIG_FIXED_PHY=y 5548+# CONFIG_ICPLUS_PHY is not set 5549+# CONFIG_INTEL_XWAY_PHY is not set 5550+# CONFIG_LSI_ET1011C_PHY is not set 5551+# CONFIG_LXT_PHY is not set 5552+# CONFIG_MARVELL_PHY is not set 5553+# CONFIG_MARVELL_10G_PHY is not set 5554+# CONFIG_MICREL_PHY is not set 5555+# CONFIG_MICROCHIP_PHY is not set 5556+# CONFIG_MICROCHIP_T1_PHY is not set 5557+# CONFIG_MICROSEMI_PHY is not set 5558+# CONFIG_NATIONAL_PHY is not set 5559+# CONFIG_QSEMI_PHY is not set 5560+# CONFIG_REALTEK_PHY is not set 5561+# CONFIG_RENESAS_PHY is not set 5562+# CONFIG_ROCKCHIP_PHY is not set 5563+# CONFIG_SMSC_PHY is not set 5564+# CONFIG_STE10XP is not set 5565+# CONFIG_TERANETICS_PHY is not set 5566+# CONFIG_VITESSE_PHY is not set 5567+# CONFIG_XILINX_GMII2RGMII is not set 5568+# CONFIG_MICREL_KS8995MA is not set 5569+# CONFIG_PPP is not set 5570+# CONFIG_SLIP is not set 5571+CONFIG_USB_NET_DRIVERS=y 5572+# CONFIG_USB_CATC is not set 5573+# CONFIG_USB_KAWETH is not set 5574+# CONFIG_USB_PEGASUS is not set 5575+# CONFIG_USB_RTL8150 is not set 5576+CONFIG_USB_RTL8152=y 5577+# CONFIG_USB_LAN78XX is not set 5578+# CONFIG_USB_USBNET is not set 5579+# CONFIG_USB_IPHETH is not set 5580+CONFIG_WLAN=y 5581+CONFIG_WLAN_VENDOR_ADMTEK=y 5582+CONFIG_WLAN_VENDOR_ATH=y 5583+# CONFIG_ATH_DEBUG is not set 5584+CONFIG_WLAN_VENDOR_ATMEL=y 5585+CONFIG_WLAN_VENDOR_BROADCOM=y 5586+CONFIG_WLAN_VENDOR_CISCO=y 5587+CONFIG_WLAN_VENDOR_INTEL=y 5588+CONFIG_WLAN_VENDOR_INTERSIL=y 5589+# CONFIG_HOSTAP is not set 5590+CONFIG_WLAN_VENDOR_MARVELL=y 5591+CONFIG_WLAN_VENDOR_MEDIATEK=y 5592+CONFIG_WLAN_VENDOR_RALINK=y 5593+CONFIG_WLAN_VENDOR_REALTEK=y 5594+CONFIG_WLAN_VENDOR_RSI=y 5595+CONFIG_WLAN_VENDOR_ST=y 5596+CONFIG_WLAN_VENDOR_TI=y 5597+CONFIG_WLAN_VENDOR_ZYDAS=y 5598+CONFIG_WLAN_VENDOR_QUANTENNA=y 5599+ 5600+# 5601+# Enable WiMAX (Networking options) to see the WiMAX drivers 5602+# 5603+# CONFIG_WAN is not set 5604+# CONFIG_NETDEVSIM is not set 5605+# CONFIG_NET_FAILOVER is not set 5606+# CONFIG_ISDN is not set 5607+ 5608+# 5609+# Input device support 5610+# 5611+CONFIG_INPUT=y 5612+CONFIG_INPUT_FF_MEMLESS=y 5613+# CONFIG_INPUT_POLLDEV is not set 5614+# CONFIG_INPUT_SPARSEKMAP is not set 5615+# CONFIG_INPUT_MATRIXKMAP is not set 5616+ 5617+# 5618+# Userland interfaces 5619+# 5620+CONFIG_INPUT_MOUSEDEV=y 5621+CONFIG_INPUT_MOUSEDEV_PSAUX=y 5622+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 5623+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 5624+CONFIG_INPUT_JOYDEV=y 5625+CONFIG_INPUT_EVDEV=y 5626+# CONFIG_INPUT_EVBUG is not set 5627+ 5628+# 5629+# Input Device Drivers 5630+# 5631+CONFIG_INPUT_KEYBOARD=y 5632+# CONFIG_KEYBOARD_ADP5588 is not set 5633+# CONFIG_KEYBOARD_ADP5589 is not set 5634+CONFIG_KEYBOARD_ATKBD=y 5635+# CONFIG_KEYBOARD_QT1070 is not set 5636+# CONFIG_KEYBOARD_QT2160 is not set 5637+# CONFIG_KEYBOARD_DLINK_DIR685 is not set 5638+# CONFIG_KEYBOARD_LKKBD is not set 5639+# CONFIG_KEYBOARD_GPIO is not set 5640+# CONFIG_KEYBOARD_GPIO_POLLED is not set 5641+# CONFIG_KEYBOARD_TCA6416 is not set 5642+# CONFIG_KEYBOARD_TCA8418 is not set 5643+# CONFIG_KEYBOARD_MATRIX is not set 5644+# CONFIG_KEYBOARD_LM8333 is not set 5645+# CONFIG_KEYBOARD_MAX7359 is not set 5646+# CONFIG_KEYBOARD_MCS is not set 5647+# CONFIG_KEYBOARD_MPR121 is not set 5648+# CONFIG_KEYBOARD_NEWTON is not set 5649+# CONFIG_KEYBOARD_OPENCORES is not set 5650+# CONFIG_KEYBOARD_SAMSUNG is not set 5651+# CONFIG_KEYBOARD_STOWAWAY is not set 5652+# CONFIG_KEYBOARD_SUNKBD is not set 5653+# CONFIG_KEYBOARD_OMAP4 is not set 5654+# CONFIG_KEYBOARD_XTKBD is not set 5655+# CONFIG_KEYBOARD_CAP11XX is not set 5656+# CONFIG_KEYBOARD_BCM is not set 5657+CONFIG_INPUT_MOUSE=y 5658+CONFIG_MOUSE_PS2=y 5659+CONFIG_MOUSE_PS2_ALPS=y 5660+CONFIG_MOUSE_PS2_BYD=y 5661+CONFIG_MOUSE_PS2_LOGIPS2PP=y 5662+CONFIG_MOUSE_PS2_SYNAPTICS=y 5663+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y 5664+CONFIG_MOUSE_PS2_CYPRESS=y 5665+CONFIG_MOUSE_PS2_TRACKPOINT=y 5666+# CONFIG_MOUSE_PS2_ELANTECH is not set 5667+# CONFIG_MOUSE_PS2_SENTELIC is not set 5668+# CONFIG_MOUSE_PS2_TOUCHKIT is not set 5669+CONFIG_MOUSE_PS2_FOCALTECH=y 5670+CONFIG_MOUSE_PS2_SMBUS=y 5671+# CONFIG_MOUSE_SERIAL is not set 5672+# CONFIG_MOUSE_APPLETOUCH is not set 5673+# CONFIG_MOUSE_BCM5974 is not set 5674+# CONFIG_MOUSE_CYAPA is not set 5675+# CONFIG_MOUSE_ELAN_I2C is not set 5676+# CONFIG_MOUSE_VSXXXAA is not set 5677+# CONFIG_MOUSE_GPIO is not set 5678+# CONFIG_MOUSE_SYNAPTICS_I2C is not set 5679+# CONFIG_MOUSE_SYNAPTICS_USB is not set 5680+CONFIG_INPUT_JOYSTICK=y 5681+# CONFIG_JOYSTICK_ANALOG is not set 5682+# CONFIG_JOYSTICK_A3D is not set 5683+# CONFIG_JOYSTICK_ADI is not set 5684+# CONFIG_JOYSTICK_COBRA is not set 5685+# CONFIG_JOYSTICK_GF2K is not set 5686+# CONFIG_JOYSTICK_GRIP is not set 5687+# CONFIG_JOYSTICK_GRIP_MP is not set 5688+# CONFIG_JOYSTICK_GUILLEMOT is not set 5689+# CONFIG_JOYSTICK_INTERACT is not set 5690+# CONFIG_JOYSTICK_SIDEWINDER is not set 5691+# CONFIG_JOYSTICK_TMDC is not set 5692+# CONFIG_JOYSTICK_IFORCE is not set 5693+# CONFIG_JOYSTICK_WARRIOR is not set 5694+# CONFIG_JOYSTICK_MAGELLAN is not set 5695+# CONFIG_JOYSTICK_SPACEORB is not set 5696+# CONFIG_JOYSTICK_SPACEBALL is not set 5697+# CONFIG_JOYSTICK_STINGER is not set 5698+# CONFIG_JOYSTICK_TWIDJOY is not set 5699+# CONFIG_JOYSTICK_ZHENHUA is not set 5700+# CONFIG_JOYSTICK_AS5011 is not set 5701+# CONFIG_JOYSTICK_JOYDUMP is not set 5702+CONFIG_JOYSTICK_XPAD=y 5703+CONFIG_JOYSTICK_XPAD_FF=y 5704+# CONFIG_JOYSTICK_PSXPAD_SPI is not set 5705+# CONFIG_JOYSTICK_PXRC is not set 5706+# CONFIG_INPUT_TABLET is not set 5707+# CONFIG_INPUT_TOUCHSCREEN is not set 5708+CONFIG_INPUT_MISC=y 5709+# CONFIG_RMI4_CORE is not set 5710+CONFIG_INPUT_UINPUT=y 5711+ 5712+# 5713+# Hardware I/O ports 5714+# 5715+CONFIG_SERIO=y 5716+CONFIG_SERIO_SERPORT=y 5717+# CONFIG_SERIO_AMBAKMI is not set 5718+CONFIG_SERIO_LIBPS2=y 5719+# CONFIG_SERIO_RAW is not set 5720+# CONFIG_SERIO_ALTERA_PS2 is not set 5721+# CONFIG_SERIO_PS2MULT is not set 5722+# CONFIG_SERIO_ARC_PS2 is not set 5723+# CONFIG_SERIO_APBPS2 is not set 5724+# CONFIG_SERIO_GPIO_PS2 is not set 5725+# CONFIG_USERIO is not set 5726+# CONFIG_GAMEPORT is not set 5727+ 5728+# 5729+# Character devices 5730+# 5731+CONFIG_TTY=y 5732+CONFIG_VT=y 5733+CONFIG_CONSOLE_TRANSLATIONS=y 5734+CONFIG_VT_CONSOLE=y 5735+CONFIG_VT_CONSOLE_SLEEP=y 5736+CONFIG_HW_CONSOLE=y 5737+# CONFIG_VT_HW_CONSOLE_BINDING is not set 5738+CONFIG_UNIX98_PTYS=y 5739+# CONFIG_LEGACY_PTYS is not set 5740+# CONFIG_SERIAL_NONSTANDARD is not set 5741+# CONFIG_N_GSM is not set 5742+# CONFIG_TRACE_SINK is not set 5743+CONFIG_LDISC_AUTOLOAD=y 5744+CONFIG_DEVMEM=y 5745+CONFIG_DEVKMEM=y 5746+ 5747+# 5748+# Serial drivers 5749+# 5750+CONFIG_SERIAL_EARLYCON=y 5751+# CONFIG_SERIAL_8250 is not set 5752+ 5753+# 5754+# Non-8250 serial port support 5755+# 5756+# CONFIG_SERIAL_AMBA_PL010 is not set 5757+CONFIG_SERIAL_AMBA_PL011=y 5758+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y 5759+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set 5760+# CONFIG_SERIAL_MAX3100 is not set 5761+# CONFIG_SERIAL_MAX310X is not set 5762+# CONFIG_SERIAL_UARTLITE is not set 5763+CONFIG_SERIAL_CORE=y 5764+CONFIG_SERIAL_CORE_CONSOLE=y 5765+# CONFIG_SERIAL_SCCNXP is not set 5766+# CONFIG_SERIAL_SC16IS7XX is not set 5767+# CONFIG_SERIAL_BCM63XX is not set 5768+# CONFIG_SERIAL_ALTERA_JTAGUART is not set 5769+# CONFIG_SERIAL_ALTERA_UART is not set 5770+# CONFIG_SERIAL_IFX6X60 is not set 5771+# CONFIG_SERIAL_XILINX_PS_UART is not set 5772+# CONFIG_SERIAL_ARC is not set 5773+# CONFIG_SERIAL_FSL_LPUART is not set 5774+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set 5775+# CONFIG_SERIAL_ST_ASC is not set 5776+# CONFIG_SERIAL_DEV_BUS is not set 5777+# CONFIG_HVC_DCC is not set 5778+# CONFIG_IPMI_HANDLER is not set 5779+# CONFIG_HW_RANDOM is not set 5780+# CONFIG_RAW_DRIVER is not set 5781+# CONFIG_TCG_TPM is not set 5782+# CONFIG_XILLYBUS is not set 5783+ 5784+# 5785+# I2C support 5786+# 5787+CONFIG_I2C=y 5788+CONFIG_I2C_BOARDINFO=y 5789+# CONFIG_I2C_COMPAT is not set 5790+CONFIG_I2C_CHARDEV=y 5791+CONFIG_I2C_MUX=y 5792+ 5793+# 5794+# Multiplexer I2C Chip support 5795+# 5796+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set 5797+# CONFIG_I2C_MUX_GPIO is not set 5798+# CONFIG_I2C_MUX_GPMUX is not set 5799+# CONFIG_I2C_MUX_LTC4306 is not set 5800+# CONFIG_I2C_MUX_PCA9541 is not set 5801+# CONFIG_I2C_MUX_PCA954x is not set 5802+# CONFIG_I2C_MUX_PINCTRL is not set 5803+# CONFIG_I2C_MUX_REG is not set 5804+# CONFIG_I2C_DEMUX_PINCTRL is not set 5805+# CONFIG_I2C_MUX_MLXCPLD is not set 5806+# CONFIG_I2C_HELPER_AUTO is not set 5807+# CONFIG_I2C_SMBUS is not set 5808+ 5809+# 5810+# I2C Algorithms 5811+# 5812+CONFIG_I2C_ALGOBIT=y 5813+# CONFIG_I2C_ALGOPCF is not set 5814+# CONFIG_I2C_ALGOPCA is not set 5815+ 5816+# 5817+# I2C Hardware Bus support 5818+# 5819+ 5820+# 5821+# I2C system bus drivers (mostly embedded / system-on-chip) 5822+# 5823+# CONFIG_I2C_CBUS_GPIO is not set 5824+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set 5825+# CONFIG_I2C_EMEV2 is not set 5826+# CONFIG_I2C_GPIO is not set 5827+CONFIG_I2C_HIBVT=y 5828+# CONFIG_I2C_NOMADIK is not set 5829+# CONFIG_I2C_OCORES is not set 5830+# CONFIG_I2C_PCA_PLATFORM is not set 5831+# CONFIG_I2C_RK3X is not set 5832+# CONFIG_I2C_SIMTEC is not set 5833+# CONFIG_I2C_XILINX is not set 5834+ 5835+# 5836+# External I2C/SMBus adapter drivers 5837+# 5838+# CONFIG_I2C_DIOLAN_U2C is not set 5839+# CONFIG_I2C_PARPORT_LIGHT is not set 5840+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set 5841+# CONFIG_I2C_TAOS_EVM is not set 5842+# CONFIG_I2C_TINY_USB is not set 5843+ 5844+# 5845+# Other I2C/SMBus bus drivers 5846+# 5847+CONFIG_DMA_MSG_MIN_LEN=5 5848+CONFIG_DMA_MSG_MAX_LEN=4090 5849+# CONFIG_I2C_STUB is not set 5850+# CONFIG_I2C_SLAVE is not set 5851+# CONFIG_I2C_DEBUG_CORE is not set 5852+# CONFIG_I2C_DEBUG_ALGO is not set 5853+# CONFIG_I2C_DEBUG_BUS is not set 5854+CONFIG_SPI=y 5855+# CONFIG_SPI_DEBUG is not set 5856+CONFIG_SPI_MASTER=y 5857+# CONFIG_SPI_MEM is not set 5858+ 5859+# 5860+# SPI Master Controller Drivers 5861+# 5862+# CONFIG_SPI_ALTERA is not set 5863+# CONFIG_SPI_AXI_SPI_ENGINE is not set 5864+# CONFIG_SPI_BITBANG is not set 5865+# CONFIG_SPI_CADENCE is not set 5866+# CONFIG_SPI_DESIGNWARE is not set 5867+# CONFIG_SPI_GPIO is not set 5868+# CONFIG_SPI_FSL_SPI is not set 5869+# CONFIG_SPI_OC_TINY is not set 5870+CONFIG_SPI_PL022=y 5871+# CONFIG_SPI_ROCKCHIP is not set 5872+# CONFIG_SPI_SC18IS602 is not set 5873+# CONFIG_SPI_XCOMM is not set 5874+# CONFIG_SPI_XILINX is not set 5875+# CONFIG_SPI_ZYNQMP_GQSPI is not set 5876+ 5877+# 5878+# SPI Protocol Masters 5879+# 5880+CONFIG_SPI_SPIDEV=y 5881+# CONFIG_SPI_LOOPBACK_TEST is not set 5882+# CONFIG_SPI_TLE62X0 is not set 5883+# CONFIG_SPI_SLAVE is not set 5884+# CONFIG_SPMI is not set 5885+# CONFIG_HSI is not set 5886+# CONFIG_PPS is not set 5887+ 5888+# 5889+# PTP clock support 5890+# 5891+# CONFIG_PTP_1588_CLOCK is not set 5892+ 5893+# 5894+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. 5895+# 5896+CONFIG_PINCTRL=y 5897+# CONFIG_DEBUG_PINCTRL is not set 5898+# CONFIG_PINCTRL_AMD is not set 5899+# CONFIG_PINCTRL_MCP23S08 is not set 5900+# CONFIG_PINCTRL_SINGLE is not set 5901+# CONFIG_PINCTRL_SX150X is not set 5902+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y 5903+CONFIG_GPIOLIB=y 5904+CONFIG_GPIOLIB_FASTPATH_LIMIT=512 5905+CONFIG_OF_GPIO=y 5906+CONFIG_GPIOLIB_IRQCHIP=y 5907+# CONFIG_DEBUG_GPIO is not set 5908+CONFIG_GPIO_SYSFS=y 5909+CONFIG_GPIO_GENERIC=y 5910+ 5911+# 5912+# Memory mapped GPIO drivers 5913+# 5914+# CONFIG_GPIO_74XX_MMIO is not set 5915+# CONFIG_GPIO_ALTERA is not set 5916+# CONFIG_GPIO_DWAPB is not set 5917+# CONFIG_GPIO_FTGPIO010 is not set 5918+CONFIG_GPIO_GENERIC_PLATFORM=y 5919+# CONFIG_GPIO_GRGPIO is not set 5920+# CONFIG_GPIO_HLWD is not set 5921+# CONFIG_GPIO_MB86S7X is not set 5922+# CONFIG_GPIO_MOCKUP is not set 5923+# CONFIG_GPIO_MPC8XXX is not set 5924+CONFIG_GPIO_PL061=y 5925+# CONFIG_GPIO_SYSCON is not set 5926+# CONFIG_GPIO_XILINX is not set 5927+# CONFIG_GPIO_ZEVIO is not set 5928+ 5929+# 5930+# I2C GPIO expanders 5931+# 5932+# CONFIG_GPIO_ADP5588 is not set 5933+# CONFIG_GPIO_ADNP is not set 5934+# CONFIG_GPIO_MAX7300 is not set 5935+# CONFIG_GPIO_MAX732X is not set 5936+# CONFIG_GPIO_PCA953X is not set 5937+# CONFIG_GPIO_PCF857X is not set 5938+# CONFIG_GPIO_TPIC2810 is not set 5939+ 5940+# 5941+# MFD GPIO expanders 5942+# 5943+# CONFIG_HTC_EGPIO is not set 5944+ 5945+# 5946+# SPI GPIO expanders 5947+# 5948+# CONFIG_GPIO_74X164 is not set 5949+# CONFIG_GPIO_MAX3191X is not set 5950+# CONFIG_GPIO_MAX7301 is not set 5951+# CONFIG_GPIO_MC33880 is not set 5952+# CONFIG_GPIO_PISOSR is not set 5953+# CONFIG_GPIO_XRA1403 is not set 5954+ 5955+# 5956+# USB GPIO expanders 5957+# 5958+# CONFIG_W1 is not set 5959+# CONFIG_POWER_AVS is not set 5960+CONFIG_POWER_RESET=y 5961+# CONFIG_POWER_RESET_BRCMKONA is not set 5962+# CONFIG_POWER_RESET_BRCMSTB is not set 5963+# CONFIG_POWER_RESET_GPIO is not set 5964+# CONFIG_POWER_RESET_GPIO_RESTART is not set 5965+CONFIG_POWER_RESET_HISI=y 5966+# CONFIG_POWER_RESET_LTC2952 is not set 5967+# CONFIG_POWER_RESET_RESTART is not set 5968+# CONFIG_POWER_RESET_VERSATILE is not set 5969+CONFIG_POWER_RESET_SYSCON=y 5970+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set 5971+# CONFIG_SYSCON_REBOOT_MODE is not set 5972+CONFIG_POWER_SUPPLY=y 5973+# CONFIG_POWER_SUPPLY_DEBUG is not set 5974+# CONFIG_PDA_POWER is not set 5975+# CONFIG_TEST_POWER is not set 5976+# CONFIG_CHARGER_ADP5061 is not set 5977+# CONFIG_BATTERY_DS2780 is not set 5978+# CONFIG_BATTERY_DS2781 is not set 5979+# CONFIG_BATTERY_DS2782 is not set 5980+# CONFIG_BATTERY_SBS is not set 5981+# CONFIG_CHARGER_SBS is not set 5982+# CONFIG_MANAGER_SBS is not set 5983+# CONFIG_BATTERY_BQ27XXX is not set 5984+# CONFIG_BATTERY_MAX17040 is not set 5985+# CONFIG_BATTERY_MAX17042 is not set 5986+# CONFIG_CHARGER_MAX8903 is not set 5987+# CONFIG_CHARGER_LP8727 is not set 5988+# CONFIG_CHARGER_GPIO is not set 5989+# CONFIG_CHARGER_LTC3651 is not set 5990+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set 5991+# CONFIG_CHARGER_BQ2415X is not set 5992+# CONFIG_CHARGER_BQ24257 is not set 5993+# CONFIG_CHARGER_BQ24735 is not set 5994+# CONFIG_CHARGER_BQ25890 is not set 5995+# CONFIG_CHARGER_SMB347 is not set 5996+# CONFIG_BATTERY_GAUGE_LTC2941 is not set 5997+# CONFIG_CHARGER_RT9455 is not set 5998+# CONFIG_HWMON is not set 5999+# CONFIG_THERMAL is not set 6000+# CONFIG_WATCHDOG is not set 6001+CONFIG_SSB_POSSIBLE=y 6002+# CONFIG_SSB is not set 6003+CONFIG_BCMA_POSSIBLE=y 6004+# CONFIG_BCMA is not set 6005+ 6006+# 6007+# Multifunction device drivers 6008+# 6009+CONFIG_MFD_CORE=y 6010+# CONFIG_MFD_ACT8945A is not set 6011+# CONFIG_MFD_AS3711 is not set 6012+# CONFIG_MFD_AS3722 is not set 6013+# CONFIG_PMIC_ADP5520 is not set 6014+# CONFIG_MFD_AAT2870_CORE is not set 6015+# CONFIG_MFD_ATMEL_FLEXCOM is not set 6016+# CONFIG_MFD_ATMEL_HLCDC is not set 6017+# CONFIG_MFD_BCM590XX is not set 6018+# CONFIG_MFD_BD9571MWV is not set 6019+# CONFIG_MFD_AXP20X_I2C is not set 6020+# CONFIG_MFD_CROS_EC is not set 6021+# CONFIG_MFD_MADERA is not set 6022+# CONFIG_MFD_ASIC3 is not set 6023+# CONFIG_PMIC_DA903X is not set 6024+# CONFIG_MFD_DA9052_SPI is not set 6025+# CONFIG_MFD_DA9052_I2C is not set 6026+# CONFIG_MFD_DA9055 is not set 6027+# CONFIG_MFD_DA9062 is not set 6028+# CONFIG_MFD_DA9063 is not set 6029+# CONFIG_MFD_DA9150 is not set 6030+# CONFIG_MFD_DLN2 is not set 6031+# CONFIG_MFD_MC13XXX_SPI is not set 6032+# CONFIG_MFD_MC13XXX_I2C is not set 6033+# CONFIG_MFD_HI6421_PMIC is not set 6034+CONFIG_MFD_HISI_FMC=y 6035+# CONFIG_HTC_PASIC3 is not set 6036+# CONFIG_HTC_I2CPLD is not set 6037+# CONFIG_MFD_KEMPLD is not set 6038+# CONFIG_MFD_88PM800 is not set 6039+# CONFIG_MFD_88PM805 is not set 6040+# CONFIG_MFD_88PM860X is not set 6041+# CONFIG_MFD_MAX14577 is not set 6042+# CONFIG_MFD_MAX77620 is not set 6043+# CONFIG_MFD_MAX77686 is not set 6044+# CONFIG_MFD_MAX77693 is not set 6045+# CONFIG_MFD_MAX77843 is not set 6046+# CONFIG_MFD_MAX8907 is not set 6047+# CONFIG_MFD_MAX8925 is not set 6048+# CONFIG_MFD_MAX8997 is not set 6049+# CONFIG_MFD_MAX8998 is not set 6050+# CONFIG_MFD_MT6397 is not set 6051+# CONFIG_MFD_MENF21BMC is not set 6052+# CONFIG_EZX_PCAP is not set 6053+# CONFIG_MFD_CPCAP is not set 6054+# CONFIG_MFD_VIPERBOARD is not set 6055+# CONFIG_MFD_RETU is not set 6056+# CONFIG_MFD_PCF50633 is not set 6057+# CONFIG_MFD_PM8XXX is not set 6058+# CONFIG_MFD_RT5033 is not set 6059+# CONFIG_MFD_RC5T583 is not set 6060+# CONFIG_MFD_RK808 is not set 6061+# CONFIG_MFD_RN5T618 is not set 6062+# CONFIG_MFD_SEC_CORE is not set 6063+# CONFIG_MFD_SI476X_CORE is not set 6064+# CONFIG_MFD_SM501 is not set 6065+# CONFIG_MFD_SKY81452 is not set 6066+# CONFIG_MFD_SMSC is not set 6067+# CONFIG_ABX500_CORE is not set 6068+# CONFIG_MFD_STMPE is not set 6069+CONFIG_MFD_SYSCON=y 6070+# CONFIG_MFD_TI_AM335X_TSCADC is not set 6071+# CONFIG_MFD_LP3943 is not set 6072+# CONFIG_MFD_LP8788 is not set 6073+# CONFIG_MFD_TI_LMU is not set 6074+# CONFIG_MFD_PALMAS is not set 6075+# CONFIG_TPS6105X is not set 6076+# CONFIG_TPS65010 is not set 6077+# CONFIG_TPS6507X is not set 6078+# CONFIG_MFD_TPS65086 is not set 6079+# CONFIG_MFD_TPS65090 is not set 6080+# CONFIG_MFD_TPS65217 is not set 6081+# CONFIG_MFD_TI_LP873X is not set 6082+# CONFIG_MFD_TI_LP87565 is not set 6083+# CONFIG_MFD_TPS65218 is not set 6084+# CONFIG_MFD_TPS6586X is not set 6085+# CONFIG_MFD_TPS65910 is not set 6086+# CONFIG_MFD_TPS65912_I2C is not set 6087+# CONFIG_MFD_TPS65912_SPI is not set 6088+# CONFIG_MFD_TPS80031 is not set 6089+# CONFIG_TWL4030_CORE is not set 6090+# CONFIG_TWL6040_CORE is not set 6091+# CONFIG_MFD_WL1273_CORE is not set 6092+# CONFIG_MFD_LM3533 is not set 6093+# CONFIG_MFD_TC3589X is not set 6094+# CONFIG_MFD_T7L66XB is not set 6095+# CONFIG_MFD_TC6387XB is not set 6096+# CONFIG_MFD_TC6393XB is not set 6097+# CONFIG_MFD_ARIZONA_I2C is not set 6098+# CONFIG_MFD_ARIZONA_SPI is not set 6099+# CONFIG_MFD_WM8400 is not set 6100+# CONFIG_MFD_WM831X_I2C is not set 6101+# CONFIG_MFD_WM831X_SPI is not set 6102+# CONFIG_MFD_WM8350_I2C is not set 6103+# CONFIG_MFD_WM8994 is not set 6104+# CONFIG_MFD_ROHM_BD718XX is not set 6105+# CONFIG_REGULATOR is not set 6106+# CONFIG_RC_CORE is not set 6107+CONFIG_MEDIA_SUPPORT=y 6108+ 6109+# 6110+# Multimedia core support 6111+# 6112+CONFIG_MEDIA_CAMERA_SUPPORT=y 6113+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set 6114+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set 6115+# CONFIG_MEDIA_RADIO_SUPPORT is not set 6116+# CONFIG_MEDIA_SDR_SUPPORT is not set 6117+# CONFIG_MEDIA_CEC_SUPPORT is not set 6118+# CONFIG_MEDIA_CONTROLLER is not set 6119+CONFIG_VIDEO_DEV=y 6120+CONFIG_VIDEO_V4L2=y 6121+# CONFIG_VIDEO_ADV_DEBUG is not set 6122+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set 6123+ 6124+# 6125+# Media drivers 6126+# 6127+CONFIG_MEDIA_USB_SUPPORT=y 6128+ 6129+# 6130+# Webcam devices 6131+# 6132+CONFIG_USB_VIDEO_CLASS=y 6133+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y 6134+CONFIG_USB_GSPCA=m 6135+# CONFIG_USB_M5602 is not set 6136+# CONFIG_USB_STV06XX is not set 6137+# CONFIG_USB_GL860 is not set 6138+# CONFIG_USB_GSPCA_BENQ is not set 6139+# CONFIG_USB_GSPCA_CONEX is not set 6140+# CONFIG_USB_GSPCA_CPIA1 is not set 6141+# CONFIG_USB_GSPCA_DTCS033 is not set 6142+# CONFIG_USB_GSPCA_ETOMS is not set 6143+# CONFIG_USB_GSPCA_FINEPIX is not set 6144+# CONFIG_USB_GSPCA_JEILINJ is not set 6145+# CONFIG_USB_GSPCA_JL2005BCD is not set 6146+# CONFIG_USB_GSPCA_KINECT is not set 6147+# CONFIG_USB_GSPCA_KONICA is not set 6148+# CONFIG_USB_GSPCA_MARS is not set 6149+# CONFIG_USB_GSPCA_MR97310A is not set 6150+# CONFIG_USB_GSPCA_NW80X is not set 6151+# CONFIG_USB_GSPCA_OV519 is not set 6152+# CONFIG_USB_GSPCA_OV534 is not set 6153+# CONFIG_USB_GSPCA_OV534_9 is not set 6154+# CONFIG_USB_GSPCA_PAC207 is not set 6155+# CONFIG_USB_GSPCA_PAC7302 is not set 6156+# CONFIG_USB_GSPCA_PAC7311 is not set 6157+# CONFIG_USB_GSPCA_SE401 is not set 6158+# CONFIG_USB_GSPCA_SN9C2028 is not set 6159+# CONFIG_USB_GSPCA_SN9C20X is not set 6160+# CONFIG_USB_GSPCA_SONIXB is not set 6161+# CONFIG_USB_GSPCA_SONIXJ is not set 6162+# CONFIG_USB_GSPCA_SPCA500 is not set 6163+# CONFIG_USB_GSPCA_SPCA501 is not set 6164+# CONFIG_USB_GSPCA_SPCA505 is not set 6165+# CONFIG_USB_GSPCA_SPCA506 is not set 6166+# CONFIG_USB_GSPCA_SPCA508 is not set 6167+# CONFIG_USB_GSPCA_SPCA561 is not set 6168+# CONFIG_USB_GSPCA_SPCA1528 is not set 6169+# CONFIG_USB_GSPCA_SQ905 is not set 6170+# CONFIG_USB_GSPCA_SQ905C is not set 6171+# CONFIG_USB_GSPCA_SQ930X is not set 6172+# CONFIG_USB_GSPCA_STK014 is not set 6173+# CONFIG_USB_GSPCA_STK1135 is not set 6174+# CONFIG_USB_GSPCA_STV0680 is not set 6175+# CONFIG_USB_GSPCA_SUNPLUS is not set 6176+# CONFIG_USB_GSPCA_T613 is not set 6177+# CONFIG_USB_GSPCA_TOPRO is not set 6178+# CONFIG_USB_GSPCA_TOUPTEK is not set 6179+# CONFIG_USB_GSPCA_TV8532 is not set 6180+# CONFIG_USB_GSPCA_VC032X is not set 6181+# CONFIG_USB_GSPCA_VICAM is not set 6182+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set 6183+# CONFIG_USB_GSPCA_ZC3XX is not set 6184+# CONFIG_USB_PWC is not set 6185+# CONFIG_VIDEO_CPIA2 is not set 6186+# CONFIG_USB_ZR364XX is not set 6187+# CONFIG_USB_STKWEBCAM is not set 6188+# CONFIG_USB_S2255 is not set 6189+# CONFIG_VIDEO_USBTV is not set 6190+ 6191+# 6192+# Webcam, TV (analog/digital) USB devices 6193+# 6194+# CONFIG_VIDEO_EM28XX is not set 6195+# CONFIG_V4L_PLATFORM_DRIVERS is not set 6196+# CONFIG_V4L_MEM2MEM_DRIVERS is not set 6197+# CONFIG_V4L_TEST_DRIVERS is not set 6198+ 6199+# 6200+# Supported MMC/SDIO adapters 6201+# 6202+# CONFIG_CYPRESS_FIRMWARE is not set 6203+CONFIG_VIDEOBUF2_CORE=y 6204+CONFIG_VIDEOBUF2_V4L2=y 6205+CONFIG_VIDEOBUF2_MEMOPS=y 6206+CONFIG_VIDEOBUF2_VMALLOC=y 6207+ 6208+# 6209+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) 6210+# 6211+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y 6212+ 6213+# 6214+# Audio decoders, processors and mixers 6215+# 6216+ 6217+# 6218+# RDS decoders 6219+# 6220+ 6221+# 6222+# Video decoders 6223+# 6224+ 6225+# 6226+# Video and audio decoders 6227+# 6228+ 6229+# 6230+# Video encoders 6231+# 6232+ 6233+# 6234+# Camera sensor devices 6235+# 6236+ 6237+# 6238+# Flash devices 6239+# 6240+ 6241+# 6242+# Video improvement chips 6243+# 6244+ 6245+# 6246+# Audio/Video compression chips 6247+# 6248+ 6249+# 6250+# SDR tuner chips 6251+# 6252+ 6253+# 6254+# Miscellaneous helper chips 6255+# 6256+ 6257+# 6258+# Sensors used on soc_camera driver 6259+# 6260+ 6261+# 6262+# Media SPI Adapters 6263+# 6264+ 6265+# 6266+# Tools to develop new frontends 6267+# 6268+ 6269+# 6270+# Graphics support 6271+# 6272+# CONFIG_IMX_IPUV3_CORE is not set 6273+CONFIG_DRM=y 6274+# CONFIG_DRM_DP_AUX_CHARDEV is not set 6275+# CONFIG_DRM_DEBUG_MM is not set 6276+# CONFIG_DRM_DEBUG_SELFTEST is not set 6277+CONFIG_DRM_KMS_HELPER=y 6278+# CONFIG_DRM_FBDEV_EMULATION is not set 6279+# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set 6280+# CONFIG_DRM_DP_CEC is not set 6281+CONFIG_DRM_GEM_CMA_HELPER=y 6282+ 6283+# 6284+# I2C encoder or helper chips 6285+# 6286+# CONFIG_DRM_I2C_CH7006 is not set 6287+# CONFIG_DRM_I2C_SIL164 is not set 6288+# CONFIG_DRM_I2C_NXP_TDA998X is not set 6289+# CONFIG_DRM_I2C_NXP_TDA9950 is not set 6290+# CONFIG_DRM_HDLCD is not set 6291+# CONFIG_DRM_MALI_DISPLAY is not set 6292+ 6293+# 6294+# ACP (Audio CoProcessor) Configuration 6295+# 6296+ 6297+# 6298+# AMD Library routines 6299+# 6300+# CONFIG_DRM_VGEM is not set 6301+# CONFIG_DRM_VKMS is not set 6302+# CONFIG_DRM_EXYNOS is not set 6303+# CONFIG_DRM_UDL is not set 6304+# CONFIG_DRM_ARMADA is not set 6305+# CONFIG_DRM_RCAR_DW_HDMI is not set 6306+# CONFIG_DRM_RCAR_LVDS is not set 6307+# CONFIG_DRM_OMAP is not set 6308+# CONFIG_DRM_TILCDC is not set 6309+# CONFIG_DRM_FSL_DCU is not set 6310+# CONFIG_DRM_STM is not set 6311+CONFIG_DRM_PANEL=y 6312+ 6313+# 6314+# Display Panels 6315+# 6316+# CONFIG_DRM_PANEL_ARM_VERSATILE is not set 6317+# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set 6318+# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set 6319+# CONFIG_DRM_PANEL_LG_LG4573 is not set 6320+# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set 6321+CONFIG_DRM_BRIDGE=y 6322+CONFIG_DRM_PANEL_BRIDGE=y 6323+ 6324+# 6325+# Display Interface Bridges 6326+# 6327+# CONFIG_DRM_ANALOGIX_ANX78XX is not set 6328+# CONFIG_DRM_CDNS_DSI is not set 6329+# CONFIG_DRM_DUMB_VGA_DAC is not set 6330+# CONFIG_DRM_LVDS_ENCODER is not set 6331+# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set 6332+# CONFIG_DRM_NXP_PTN3460 is not set 6333+# CONFIG_DRM_PARADE_PS8622 is not set 6334+# CONFIG_DRM_SIL_SII8620 is not set 6335+# CONFIG_DRM_SII902X is not set 6336+# CONFIG_DRM_SII9234 is not set 6337+# CONFIG_DRM_THINE_THC63LVD1024 is not set 6338+# CONFIG_DRM_TOSHIBA_TC358767 is not set 6339+# CONFIG_DRM_TI_TFP410 is not set 6340+# CONFIG_DRM_I2C_ADV7511 is not set 6341+# CONFIG_DRM_STI is not set 6342+# CONFIG_DRM_ARCPGU is not set 6343+CONFIG_DRM_HISI_HISMART=y 6344+# CONFIG_DRM_MXSFB is not set 6345+# CONFIG_DRM_TINYDRM is not set 6346+# CONFIG_DRM_PL111 is not set 6347+# CONFIG_DRM_TVE200 is not set 6348+# CONFIG_DRM_LEGACY is not set 6349+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y 6350+ 6351+# 6352+# Frame buffer Devices 6353+# 6354+CONFIG_FB_CMDLINE=y 6355+CONFIG_FB_NOTIFY=y 6356+CONFIG_FB=y 6357+# CONFIG_FIRMWARE_EDID is not set 6358+# CONFIG_FB_FOREIGN_ENDIAN is not set 6359+# CONFIG_FB_MODE_HELPERS is not set 6360+# CONFIG_FB_TILEBLITTING is not set 6361+ 6362+# 6363+# Frame buffer hardware drivers 6364+# 6365+# CONFIG_FB_ARMCLCD is not set 6366+# CONFIG_FB_OPENCORES is not set 6367+# CONFIG_FB_S1D13XXX is not set 6368+# CONFIG_FB_SMSCUFX is not set 6369+# CONFIG_FB_UDL is not set 6370+# CONFIG_FB_IBM_GXT4500 is not set 6371+# CONFIG_FB_VIRTUAL is not set 6372+# CONFIG_FB_METRONOME is not set 6373+# CONFIG_FB_BROADSHEET is not set 6374+# CONFIG_FB_SIMPLE is not set 6375+# CONFIG_FB_SSD1307 is not set 6376+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 6377+CONFIG_HDMI=y 6378+ 6379+# 6380+# Console display driver support 6381+# 6382+CONFIG_DUMMY_CONSOLE=y 6383+# CONFIG_FRAMEBUFFER_CONSOLE is not set 6384+# CONFIG_LOGO is not set 6385+CONFIG_SOUND=y 6386+CONFIG_SND=y 6387+CONFIG_SND_TIMER=y 6388+CONFIG_SND_PCM=y 6389+# CONFIG_SND_OSSEMUL is not set 6390+CONFIG_SND_PCM_TIMER=y 6391+# CONFIG_SND_DYNAMIC_MINORS is not set 6392+CONFIG_SND_SUPPORT_OLD_API=y 6393+CONFIG_SND_PROC_FS=y 6394+CONFIG_SND_VERBOSE_PROCFS=y 6395+# CONFIG_SND_VERBOSE_PRINTK is not set 6396+# CONFIG_SND_DEBUG is not set 6397+# CONFIG_SND_SEQUENCER is not set 6398+CONFIG_SND_DRIVERS=y 6399+# CONFIG_SND_DUMMY is not set 6400+# CONFIG_SND_ALOOP is not set 6401+# CONFIG_SND_MTPAV is not set 6402+# CONFIG_SND_SERIAL_U16550 is not set 6403+# CONFIG_SND_MPU401 is not set 6404+ 6405+# 6406+# HD-Audio 6407+# 6408+CONFIG_SND_HDA_PREALLOC_SIZE=64 6409+CONFIG_SND_ARM=y 6410+# CONFIG_SND_ARMAACI is not set 6411+CONFIG_SND_SPI=y 6412+CONFIG_SND_USB=y 6413+# CONFIG_SND_USB_AUDIO is not set 6414+# CONFIG_SND_USB_UA101 is not set 6415+# CONFIG_SND_USB_CAIAQ is not set 6416+# CONFIG_SND_USB_6FIRE is not set 6417+# CONFIG_SND_USB_HIFACE is not set 6418+# CONFIG_SND_BCD2000 is not set 6419+# CONFIG_SND_USB_POD is not set 6420+# CONFIG_SND_USB_PODHD is not set 6421+# CONFIG_SND_USB_TONEPORT is not set 6422+# CONFIG_SND_USB_VARIAX is not set 6423+# CONFIG_SND_SOC is not set 6424+ 6425+# 6426+# HID support 6427+# 6428+# CONFIG_HID is not set 6429+ 6430+# 6431+# USB HID support 6432+# 6433+CONFIG_USB_HID=y 6434+# CONFIG_HID_PID is not set 6435+ 6436+# 6437+# I2C HID support 6438+# 6439+# CONFIG_I2C_HID is not set 6440+CONFIG_USB_OHCI_LITTLE_ENDIAN=y 6441+CONFIG_USB_SUPPORT=y 6442+CONFIG_USB_COMMON=y 6443+CONFIG_USB_ARCH_HAS_HCD=y 6444+CONFIG_USB=y 6445+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set 6446+ 6447+# 6448+# Miscellaneous USB options 6449+# 6450+CONFIG_USB_DEFAULT_PERSIST=y 6451+# CONFIG_USB_DYNAMIC_MINORS is not set 6452+# CONFIG_USB_OTG is not set 6453+# CONFIG_USB_OTG_WHITELIST is not set 6454+# CONFIG_USB_MON is not set 6455+# CONFIG_USB_WUSB_CBAF is not set 6456+ 6457+# 6458+# USB Host Controller Drivers 6459+# 6460+# CONFIG_USB_C67X00_HCD is not set 6461+CONFIG_USB_XHCI_HCD=y 6462+# CONFIG_USB_XHCI_DBGCAP is not set 6463+CONFIG_USB_XHCI_PLATFORM=y 6464+# CONFIG_USB_EHCI_HCD is not set 6465+# CONFIG_USB_OXU210HP_HCD is not set 6466+# CONFIG_USB_ISP116X_HCD is not set 6467+# CONFIG_USB_FOTG210_HCD is not set 6468+# CONFIG_USB_MAX3421_HCD is not set 6469+# CONFIG_USB_OHCI_HCD is not set 6470+# CONFIG_USB_SL811_HCD is not set 6471+# CONFIG_USB_R8A66597_HCD is not set 6472+# CONFIG_USB_HCD_TEST_MODE is not set 6473+ 6474+# 6475+# USB Device Class drivers 6476+# 6477+# CONFIG_USB_ACM is not set 6478+# CONFIG_USB_PRINTER is not set 6479+# CONFIG_USB_WDM is not set 6480+# CONFIG_USB_TMC is not set 6481+ 6482+# 6483+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may 6484+# 6485+ 6486+# 6487+# also be needed; see USB_STORAGE Help for more info 6488+# 6489+CONFIG_USB_STORAGE=y 6490+# CONFIG_USB_STORAGE_DEBUG is not set 6491+# CONFIG_USB_STORAGE_REALTEK is not set 6492+# CONFIG_USB_STORAGE_DATAFAB is not set 6493+# CONFIG_USB_STORAGE_FREECOM is not set 6494+# CONFIG_USB_STORAGE_ISD200 is not set 6495+# CONFIG_USB_STORAGE_USBAT is not set 6496+# CONFIG_USB_STORAGE_SDDR09 is not set 6497+# CONFIG_USB_STORAGE_SDDR55 is not set 6498+# CONFIG_USB_STORAGE_JUMPSHOT is not set 6499+# CONFIG_USB_STORAGE_ALAUDA is not set 6500+# CONFIG_USB_STORAGE_ONETOUCH is not set 6501+# CONFIG_USB_STORAGE_KARMA is not set 6502+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set 6503+# CONFIG_USB_STORAGE_ENE_UB6250 is not set 6504+# CONFIG_USB_UAS is not set 6505+ 6506+# 6507+# USB Imaging devices 6508+# 6509+# CONFIG_USB_MDC800 is not set 6510+# CONFIG_USB_MICROTEK is not set 6511+# CONFIG_USBIP_CORE is not set 6512+# CONFIG_USB_MUSB_HDRC is not set 6513+CONFIG_USB_DWC3=y 6514+# CONFIG_USB_DWC3_HOST is not set 6515+CONFIG_USB_DWC3_GADGET=y 6516+ 6517+# 6518+# Platform Glue Driver Support 6519+# 6520+# CONFIG_USB_DWC3_OF_SIMPLE is not set 6521+# CONFIG_USB_DWC2 is not set 6522+# CONFIG_USB_CHIPIDEA is not set 6523+# CONFIG_USB_ISP1760 is not set 6524+ 6525+# 6526+# USB port drivers 6527+# 6528+# CONFIG_USB_SERIAL is not set 6529+ 6530+# 6531+# USB Miscellaneous drivers 6532+# 6533+# CONFIG_USB_EMI62 is not set 6534+# CONFIG_USB_EMI26 is not set 6535+# CONFIG_USB_ADUTUX is not set 6536+# CONFIG_USB_SEVSEG is not set 6537+# CONFIG_USB_RIO500 is not set 6538+# CONFIG_USB_LEGOTOWER is not set 6539+# CONFIG_USB_LCD is not set 6540+# CONFIG_USB_CYPRESS_CY7C63 is not set 6541+# CONFIG_USB_CYTHERM is not set 6542+# CONFIG_USB_IDMOUSE is not set 6543+# CONFIG_USB_FTDI_ELAN is not set 6544+# CONFIG_USB_APPLEDISPLAY is not set 6545+# CONFIG_USB_LD is not set 6546+# CONFIG_USB_TRANCEVIBRATOR is not set 6547+# CONFIG_USB_IOWARRIOR is not set 6548+# CONFIG_USB_TEST is not set 6549+# CONFIG_USB_EHSET_TEST_FIXTURE is not set 6550+# CONFIG_USB_ISIGHTFW is not set 6551+# CONFIG_USB_YUREX is not set 6552+# CONFIG_USB_EZUSB_FX2 is not set 6553+# CONFIG_USB_HUB_USB251XB is not set 6554+# CONFIG_USB_HSIC_USB3503 is not set 6555+# CONFIG_USB_HSIC_USB4604 is not set 6556+# CONFIG_USB_LINK_LAYER_TEST is not set 6557+ 6558+# 6559+# USB Physical Layer drivers 6560+# 6561+# CONFIG_NOP_USB_XCEIV is not set 6562+# CONFIG_USB_GPIO_VBUS is not set 6563+# CONFIG_USB_ISP1301 is not set 6564+# CONFIG_USB_ULPI is not set 6565+CONFIG_USB_GADGET=y 6566+# CONFIG_USB_GADGET_DEBUG is not set 6567+# CONFIG_USB_GADGET_DEBUG_FILES is not set 6568+# CONFIG_USB_GADGET_DEBUG_FS is not set 6569+CONFIG_USB_GADGET_VBUS_DRAW=2 6570+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 6571+# CONFIG_U_SERIAL_CONSOLE is not set 6572+ 6573+# 6574+# USB Peripheral Controller 6575+# 6576+# CONFIG_USB_FUSB300 is not set 6577+# CONFIG_USB_FOTG210_UDC is not set 6578+# CONFIG_USB_GR_UDC is not set 6579+# CONFIG_USB_R8A66597 is not set 6580+# CONFIG_USB_PXA27X is not set 6581+# CONFIG_USB_MV_UDC is not set 6582+# CONFIG_USB_MV_U3D is not set 6583+# CONFIG_USB_SNP_UDC_PLAT is not set 6584+# CONFIG_USB_M66592 is not set 6585+# CONFIG_USB_BDC_UDC is not set 6586+# CONFIG_USB_NET2272 is not set 6587+# CONFIG_USB_GADGET_XILINX is not set 6588+# CONFIG_USB_DUMMY_HCD is not set 6589+CONFIG_USB_LIBCOMPOSITE=y 6590+CONFIG_USB_F_ACM=y 6591+CONFIG_USB_U_SERIAL=y 6592+CONFIG_USB_U_ETHER=y 6593+CONFIG_USB_U_AUDIO=y 6594+CONFIG_USB_F_RNDIS=y 6595+CONFIG_USB_F_MASS_STORAGE=y 6596+CONFIG_USB_F_FS=y 6597+CONFIG_USB_F_UAC1=y 6598+CONFIG_USB_F_UVC=y 6599+CONFIG_USB_CONFIGFS=y 6600+# CONFIG_USB_CONFIGFS_SERIAL is not set 6601+CONFIG_USB_CONFIGFS_ACM=y 6602+# CONFIG_USB_CONFIGFS_OBEX is not set 6603+# CONFIG_USB_CONFIGFS_NCM is not set 6604+# CONFIG_USB_CONFIGFS_ECM is not set 6605+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set 6606+CONFIG_USB_CONFIGFS_RNDIS=y 6607+# CONFIG_USB_CONFIGFS_EEM is not set 6608+CONFIG_USB_CONFIGFS_MASS_STORAGE=y 6609+# CONFIG_USB_CONFIGFS_F_LB_SS is not set 6610+CONFIG_USB_CONFIGFS_F_FS=y 6611+CONFIG_USB_CONFIGFS_F_UAC1=y 6612+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set 6613+# CONFIG_USB_CONFIGFS_F_UAC2 is not set 6614+# CONFIG_USB_CONFIGFS_F_MIDI is not set 6615+# CONFIG_USB_CONFIGFS_F_HID is not set 6616+CONFIG_USB_CONFIGFS_F_UVC=y 6617+# CONFIG_USB_CONFIGFS_F_PRINTER is not set 6618+CONFIG_TYPEC=y 6619+# CONFIG_TYPEC_TCPM is not set 6620+# CONFIG_TYPEC_UCSI is not set 6621+# CONFIG_TYPEC_TPS6598X is not set 6622+ 6623+# 6624+# USB Type-C Multiplexer/DeMultiplexer Switch support 6625+# 6626+# CONFIG_TYPEC_MUX_PI3USB30532 is not set 6627+ 6628+# 6629+# USB Type-C Alternate Mode drivers 6630+# 6631+# CONFIG_TYPEC_DP_ALTMODE is not set 6632+# CONFIG_USB_ROLE_SWITCH is not set 6633+# CONFIG_USB_ULPI_BUS is not set 6634+# CONFIG_UWB is not set 6635+CONFIG_MMC=y 6636+CONFIG_PWRSEQ_EMMC=y 6637+CONFIG_PWRSEQ_SIMPLE=y 6638+CONFIG_MMC_BLOCK=y 6639+CONFIG_MMC_BLOCK_MINORS=8 6640+# CONFIG_SDIO_UART is not set 6641+# CONFIG_MMC_TEST is not set 6642+ 6643+# 6644+# MMC/SD/SDIO Host Controller Drivers 6645+# 6646+# CONFIG_MMC_DEBUG is not set 6647+# CONFIG_MMC_ARMMMCI is not set 6648+# CONFIG_MMC_SDHCI is not set 6649+# CONFIG_MMC_SPI is not set 6650+# CONFIG_MMC_DW is not set 6651+# CONFIG_MMC_VUB300 is not set 6652+# CONFIG_MMC_USHC is not set 6653+# CONFIG_MMC_USDHI6ROL0 is not set 6654+# CONFIG_MMC_CQHCI is not set 6655+# CONFIG_MMC_MTK is not set 6656+# CONFIG_MMC_CQ_HCI is not set 6657+CONFIG_HIMCI=y 6658+CONFIG_SEND_AUTO_STOP=y 6659+# CONFIG_MEMSTICK is not set 6660+# CONFIG_NEW_LEDS is not set 6661+# CONFIG_ACCESSIBILITY is not set 6662+# CONFIG_INFINIBAND is not set 6663+CONFIG_EDAC_ATOMIC_SCRUB=y 6664+CONFIG_EDAC_SUPPORT=y 6665+CONFIG_RTC_LIB=y 6666+CONFIG_RTC_CLASS=y 6667+CONFIG_RTC_HCTOSYS=y 6668+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" 6669+CONFIG_RTC_SYSTOHC=y 6670+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" 6671+# CONFIG_RTC_DEBUG is not set 6672+CONFIG_RTC_NVMEM=y 6673+ 6674+# 6675+# RTC interfaces 6676+# 6677+CONFIG_RTC_INTF_SYSFS=y 6678+CONFIG_RTC_INTF_PROC=y 6679+CONFIG_RTC_INTF_DEV=y 6680+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set 6681+# CONFIG_RTC_DRV_TEST is not set 6682+ 6683+# 6684+# I2C RTC drivers 6685+# 6686+# CONFIG_RTC_DRV_ABB5ZES3 is not set 6687+# CONFIG_RTC_DRV_ABX80X is not set 6688+# CONFIG_RTC_DRV_DS1307 is not set 6689+# CONFIG_RTC_DRV_DS1374 is not set 6690+# CONFIG_RTC_DRV_DS1672 is not set 6691+# CONFIG_RTC_DRV_HYM8563 is not set 6692+# CONFIG_RTC_DRV_MAX6900 is not set 6693+# CONFIG_RTC_DRV_RS5C372 is not set 6694+# CONFIG_RTC_DRV_ISL1208 is not set 6695+# CONFIG_RTC_DRV_ISL12022 is not set 6696+# CONFIG_RTC_DRV_ISL12026 is not set 6697+# CONFIG_RTC_DRV_X1205 is not set 6698+# CONFIG_RTC_DRV_PCF8523 is not set 6699+# CONFIG_RTC_DRV_PCF85063 is not set 6700+# CONFIG_RTC_DRV_PCF85363 is not set 6701+# CONFIG_RTC_DRV_PCF8563 is not set 6702+# CONFIG_RTC_DRV_PCF8583 is not set 6703+# CONFIG_RTC_DRV_M41T80 is not set 6704+# CONFIG_RTC_DRV_BQ32K is not set 6705+# CONFIG_RTC_DRV_S35390A is not set 6706+# CONFIG_RTC_DRV_FM3130 is not set 6707+# CONFIG_RTC_DRV_RX8010 is not set 6708+# CONFIG_RTC_DRV_RX8581 is not set 6709+# CONFIG_RTC_DRV_RX8025 is not set 6710+# CONFIG_RTC_DRV_EM3027 is not set 6711+# CONFIG_RTC_DRV_RV8803 is not set 6712+ 6713+# 6714+# SPI RTC drivers 6715+# 6716+# CONFIG_RTC_DRV_M41T93 is not set 6717+# CONFIG_RTC_DRV_M41T94 is not set 6718+# CONFIG_RTC_DRV_DS1302 is not set 6719+# CONFIG_RTC_DRV_DS1305 is not set 6720+# CONFIG_RTC_DRV_DS1343 is not set 6721+# CONFIG_RTC_DRV_DS1347 is not set 6722+# CONFIG_RTC_DRV_DS1390 is not set 6723+# CONFIG_RTC_DRV_MAX6916 is not set 6724+# CONFIG_RTC_DRV_R9701 is not set 6725+# CONFIG_RTC_DRV_RX4581 is not set 6726+# CONFIG_RTC_DRV_RX6110 is not set 6727+# CONFIG_RTC_DRV_RS5C348 is not set 6728+# CONFIG_RTC_DRV_MAX6902 is not set 6729+# CONFIG_RTC_DRV_PCF2123 is not set 6730+# CONFIG_RTC_DRV_MCP795 is not set 6731+CONFIG_RTC_I2C_AND_SPI=y 6732+ 6733+# 6734+# SPI and I2C RTC drivers 6735+# 6736+# CONFIG_RTC_DRV_DS3232 is not set 6737+# CONFIG_RTC_DRV_PCF2127 is not set 6738+# CONFIG_RTC_DRV_RV3029C2 is not set 6739+ 6740+# 6741+# Platform RTC drivers 6742+# 6743+CONFIG_RTC_DRV_HIBVT=y 6744+# CONFIG_RTC_DRV_CMOS is not set 6745+# CONFIG_RTC_DRV_DS1286 is not set 6746+# CONFIG_RTC_DRV_DS1511 is not set 6747+# CONFIG_RTC_DRV_DS1553 is not set 6748+# CONFIG_RTC_DRV_DS1685_FAMILY is not set 6749+# CONFIG_RTC_DRV_DS1742 is not set 6750+# CONFIG_RTC_DRV_DS2404 is not set 6751+# CONFIG_RTC_DRV_STK17TA8 is not set 6752+# CONFIG_RTC_DRV_M48T86 is not set 6753+# CONFIG_RTC_DRV_M48T35 is not set 6754+# CONFIG_RTC_DRV_M48T59 is not set 6755+# CONFIG_RTC_DRV_MSM6242 is not set 6756+# CONFIG_RTC_DRV_BQ4802 is not set 6757+# CONFIG_RTC_DRV_RP5C01 is not set 6758+# CONFIG_RTC_DRV_V3020 is not set 6759+# CONFIG_RTC_DRV_ZYNQMP is not set 6760+ 6761+# 6762+# on-CPU RTC drivers 6763+# 6764+# CONFIG_RTC_DRV_PL030 is not set 6765+# CONFIG_RTC_DRV_PL031 is not set 6766+# CONFIG_RTC_DRV_FTRTC010 is not set 6767+# CONFIG_RTC_DRV_SNVS is not set 6768+# CONFIG_RTC_DRV_R7301 is not set 6769+ 6770+# 6771+# HID Sensor RTC drivers 6772+# 6773+# CONFIG_DMADEVICES is not set 6774+ 6775+# 6776+# DMABUF options 6777+# 6778+CONFIG_SYNC_FILE=y 6779+# CONFIG_SW_SYNC is not set 6780+# CONFIG_AUXDISPLAY is not set 6781+# CONFIG_UIO is not set 6782+# CONFIG_VIRT_DRIVERS is not set 6783+CONFIG_VIRTIO_MENU=y 6784+# CONFIG_VIRTIO_MMIO is not set 6785+ 6786+# 6787+# Microsoft Hyper-V guest support 6788+# 6789+# CONFIG_STAGING is not set 6790+# CONFIG_GOLDFISH is not set 6791+# CONFIG_CHROME_PLATFORMS is not set 6792+# CONFIG_MELLANOX_PLATFORM is not set 6793+CONFIG_CLKDEV_LOOKUP=y 6794+CONFIG_HAVE_CLK_PREPARE=y 6795+CONFIG_COMMON_CLK=y 6796+ 6797+# 6798+# Common Clock Framework 6799+# 6800+# CONFIG_CLK_HSDK is not set 6801+# CONFIG_COMMON_CLK_MAX9485 is not set 6802+# CONFIG_COMMON_CLK_SI5351 is not set 6803+# CONFIG_COMMON_CLK_SI514 is not set 6804+# CONFIG_COMMON_CLK_SI544 is not set 6805+# CONFIG_COMMON_CLK_SI570 is not set 6806+# CONFIG_COMMON_CLK_CDCE706 is not set 6807+# CONFIG_COMMON_CLK_CDCE925 is not set 6808+# CONFIG_COMMON_CLK_CS2000_CP is not set 6809+# CONFIG_CLK_QORIQ is not set 6810+# CONFIG_COMMON_CLK_VC5 is not set 6811+CONFIG_COMMON_CLK_HI3516DV300=y 6812+CONFIG_RESET_HISI=y 6813+CONFIG_STAGING=y 6814+# CONFIG_HWSPINLOCK is not set 6815+# 6816+# Android 6817+# 6818+CONFIG_ANDROID=y 6819+CONFIG_ANDROID_BINDER_IPC=y 6820+CONFIG_ANDROID_BINDER_DEVICES=binder,hwbinder,vndbinder 6821+CONFIG_ASHMEM=y 6822+CONFIG_ANDROID_LOW_MEMORY_KILLER=y 6823+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y 6824+# CONFIG_ANDROID_VSOC is not set 6825+CONFIG_ION=y 6826+CONFIG_ION_TEST=y 6827+# CONFIG_ION_DUMMY is not set 6828+CONFIG_ION_HICAMERA=y 6829+CONFIG_ION_OF=y 6830+# CONFIG_FIQ_DEBUGGER is not set 6831+# CONFIG_FIQ_WATCHDOG is not set 6832+# CONFIG_STAGING_BOARD is not set 6833+# CONFIG_LTE_GDM724X is not set 6834+# CONFIG_MTD_SPINAND_MT29F is not set 6835+# CONFIG_LNET is not set 6836+# CONFIG_DGNC is not set 6837+# CONFIG_GS_FPGABOOT is not set 6838+# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set 6839+# CONFIG_FB_TFT is not set 6840+# CONFIG_FSL_MC_BUS is not set 6841+# CONFIG_MOST is not set 6842+# CONFIG_KS7010 is not set 6843+# CONFIG_GREYBUS is not set 6844+# CONFIG_GOLDFISH is not set 6845+# CONFIG_CHROME_PLATFORMS is not set 6846+CONFIG_CLKDEV_LOOKUP=y 6847+CONFIG_HAVE_CLK_PREPARE=y 6848+CONFIG_COMMON_CLK=y 6849+# 6850+# Clock Source drivers 6851+# 6852+CONFIG_TIMER_OF=y 6853+CONFIG_TIMER_PROBE=y 6854+CONFIG_CLKSRC_MMIO=y 6855+CONFIG_ARM_ARCH_TIMER=y 6856+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y 6857+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set 6858+CONFIG_ARM_TIMER_SP804=y 6859+# CONFIG_TIMER_HISP804 is not set 6860+# CONFIG_MAILBOX is not set 6861+# CONFIG_IOMMU_SUPPORT is not set 6862+ 6863+# 6864+# Remoteproc drivers 6865+# 6866+# CONFIG_REMOTEPROC is not set 6867+ 6868+# 6869+# Rpmsg drivers 6870+# 6871+# CONFIG_RPMSG_VIRTIO is not set 6872+# CONFIG_SOUNDWIRE is not set 6873+ 6874+# 6875+# SOC (System On Chip) specific Drivers 6876+# 6877+ 6878+# 6879+# Amlogic SoC drivers 6880+# 6881+ 6882+# 6883+# Broadcom SoC drivers 6884+# 6885+# CONFIG_SOC_BRCMSTB is not set 6886+ 6887+# 6888+# NXP/Freescale QorIQ SoC drivers 6889+# 6890+ 6891+# 6892+# i.MX SoC drivers 6893+# 6894+ 6895+# 6896+# Qualcomm SoC drivers 6897+# 6898+# CONFIG_SOC_TI is not set 6899+ 6900+# 6901+# Xilinx SoC drivers 6902+# 6903+# CONFIG_XILINX_VCU is not set 6904+# CONFIG_PM_DEVFREQ is not set 6905+# CONFIG_EXTCON is not set 6906+# CONFIG_MEMORY is not set 6907+# CONFIG_IIO is not set 6908+CONFIG_PWM=y 6909+CONFIG_PWM_HI35XX=y 6910+ 6911+# 6912+# IRQ chip support 6913+# 6914+CONFIG_IRQCHIP=y 6915+CONFIG_ARM_GIC=y 6916+CONFIG_ARM_GIC_MAX_NR=1 6917+# CONFIG_IPACK_BUS is not set 6918+CONFIG_RESET_CONTROLLER=y 6919+# CONFIG_RESET_TI_SYSCON is not set 6920+# CONFIG_FMC is not set 6921+ 6922+# 6923+# PHY Subsystem 6924+# 6925+CONFIG_GENERIC_PHY=y 6926+# CONFIG_BCM_KONA_USB2_PHY is not set 6927+# CONFIG_PHY_PXA_28NM_HSIC is not set 6928+# CONFIG_PHY_PXA_28NM_USB2 is not set 6929+# CONFIG_PHY_MAPPHONE_MDM6600 is not set 6930+CONFIG_HI_USB_PHY=y 6931+CONFIG_PHY_HISI_USB2=y 6932+CONFIG_HIBVT_USB_PHY=y 6933+CONFIG_USB_MODE_OPTION=y 6934+CONFIG_USB_DRD0_IN_HOST=y 6935+CONFIG_USB_DRD0_IN_DEVICE=y 6936+# CONFIG_POWERCAP is not set 6937+# CONFIG_MCB is not set 6938+# CONFIG_RAS is not set 6939+# CONFIG_DAX is not set 6940+CONFIG_NVMEM=y 6941+ 6942+# 6943+# HW tracing support 6944+# 6945+# CONFIG_STM is not set 6946+# CONFIG_INTEL_TH is not set 6947+# CONFIG_FPGA is not set 6948+# CONFIG_FSI is not set 6949+# CONFIG_TEE is not set 6950+# CONFIG_SIOX is not set 6951+# CONFIG_SLIMBUS is not set 6952+# CONFIG_HI_DMAC is not set 6953+# CONFIG_HIEDMAC is not set 6954+ 6955+# 6956+# Hisilicon driver support 6957+# 6958+# CONFIG_CMA_MEM_SHARED is not set 6959+# CONFIG_CMA_ADVANCE_SHARE is not set 6960+# 6961+# File systems 6962+# 6963+CONFIG_DCACHE_WORD_ACCESS=y 6964+CONFIG_FS_IOMAP=y 6965+# CONFIG_EXT2_FS is not set 6966+# CONFIG_EXT3_FS is not set 6967+CONFIG_EXT4_FS=y 6968+CONFIG_EXT4_USE_FOR_EXT2=y 6969+CONFIG_EXT4_FS_POSIX_ACL=y 6970+CONFIG_EXT4_FS_SECURITY=y 6971+# CONFIG_EXT4_ENCRYPTION is not set 6972+# CONFIG_EXT4_DEBUG is not set 6973+CONFIG_JBD2=y 6974+# CONFIG_JBD2_DEBUG is not set 6975+CONFIG_FS_MBCACHE=y 6976+CONFIG_REISERFS_FS=m 6977+CONFIG_REISERFS_CHECK=y 6978+CONFIG_REISERFS_PROC_INFO=y 6979+CONFIG_REISERFS_FS_XATTR=y 6980+CONFIG_REISERFS_FS_POSIX_ACL=y 6981+CONFIG_REISERFS_FS_SECURITY=y 6982+CONFIG_JFS_FS=m 6983+CONFIG_JFS_POSIX_ACL=y 6984+CONFIG_JFS_SECURITY=y 6985+CONFIG_JFS_DEBUG=y 6986+CONFIG_JFS_STATISTICS=y 6987+CONFIG_XFS_FS=m 6988+CONFIG_XFS_QUOTA=y 6989+CONFIG_XFS_POSIX_ACL=y 6990+CONFIG_XFS_RT=y 6991+# CONFIG_XFS_ONLINE_SCRUB is not set 6992+# CONFIG_XFS_WARN is not set 6993+# CONFIG_XFS_DEBUG is not set 6994+# CONFIG_GFS2_FS is not set 6995+# CONFIG_OCFS2_FS is not set 6996+# CONFIG_BTRFS_FS is not set 6997+# CONFIG_NILFS2_FS is not set 6998+# CONFIG_F2FS_FS is not set 6999+CONFIG_FS_POSIX_ACL=y 7000+CONFIG_EXPORTFS=y 7001+# CONFIG_EXPORTFS_BLOCK_OPS is not set 7002+CONFIG_FILE_LOCKING=y 7003+CONFIG_MANDATORY_FILE_LOCKING=y 7004+# CONFIG_FS_ENCRYPTION is not set 7005+CONFIG_FSNOTIFY=y 7006+CONFIG_DNOTIFY=y 7007+CONFIG_INOTIFY_USER=y 7008+# CONFIG_FANOTIFY is not set 7009+# CONFIG_QUOTA is not set 7010+# CONFIG_QUOTA_NETLINK_INTERFACE is not set 7011+CONFIG_QUOTACTL=y 7012+# CONFIG_AUTOFS4_FS is not set 7013+# CONFIG_AUTOFS_FS is not set 7014+# CONFIG_FUSE_FS is not set 7015+# CONFIG_OVERLAY_FS is not set 7016+ 7017+# 7018+# Caches 7019+# 7020+# CONFIG_FSCACHE is not set 7021+ 7022+# 7023+# CD-ROM/DVD Filesystems 7024+# 7025+# CONFIG_ISO9660_FS is not set 7026+# CONFIG_UDF_FS is not set 7027+ 7028+# 7029+# DOS/FAT/NT Filesystems 7030+# 7031+CONFIG_FAT_FS=y 7032+CONFIG_MSDOS_FS=y 7033+CONFIG_VFAT_FS=y 7034+CONFIG_FAT_DEFAULT_CODEPAGE=437 7035+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" 7036+# CONFIG_FAT_DEFAULT_UTF8 is not set 7037+# CONFIG_NTFS_FS is not set 7038+ 7039+# 7040+# Pseudo filesystems 7041+# 7042+CONFIG_PROC_FS=y 7043+CONFIG_PROC_SYSCTL=y 7044+CONFIG_PROC_PAGE_MONITOR=y 7045+# CONFIG_PROC_CHILDREN is not set 7046+CONFIG_KERNFS=y 7047+CONFIG_SYSFS=y 7048+CONFIG_TMPFS=y 7049+# CONFIG_TMPFS_POSIX_ACL is not set 7050+# CONFIG_TMPFS_XATTR is not set 7051+CONFIG_MEMFD_CREATE=y 7052+CONFIG_CONFIGFS_FS=y 7053+CONFIG_MISC_FILESYSTEMS=y 7054+# CONFIG_ORANGEFS_FS is not set 7055+# CONFIG_ADFS_FS is not set 7056+# CONFIG_AFFS_FS is not set 7057+# CONFIG_ECRYPT_FS is not set 7058+# CONFIG_HFS_FS is not set 7059+# CONFIG_HFSPLUS_FS is not set 7060+# CONFIG_BEFS_FS is not set 7061+# CONFIG_BFS_FS is not set 7062+# CONFIG_EFS_FS is not set 7063+CONFIG_CRAMFS=y 7064+CONFIG_CRAMFS_BLOCKDEV=y 7065+# CONFIG_SQUASHFS is not set 7066+# CONFIG_VXFS_FS is not set 7067+# CONFIG_MINIX_FS is not set 7068+# CONFIG_OMFS_FS is not set 7069+# CONFIG_HPFS_FS is not set 7070+# CONFIG_QNX4FS_FS is not set 7071+# CONFIG_QNX6FS_FS is not set 7072+# CONFIG_ROMFS_FS is not set 7073+# CONFIG_PSTORE is not set 7074+# CONFIG_SYSV_FS is not set 7075+# CONFIG_UFS_FS is not set 7076+CONFIG_NETWORK_FILESYSTEMS=y 7077+CONFIG_NFS_FS=y 7078+CONFIG_NFS_V2=y 7079+CONFIG_NFS_V3=y 7080+CONFIG_NFS_V3_ACL=y 7081+CONFIG_NFS_V4=y 7082+# CONFIG_NFS_SWAP is not set 7083+# CONFIG_NFS_V4_1 is not set 7084+# CONFIG_ROOT_NFS is not set 7085+# CONFIG_NFS_USE_LEGACY_DNS is not set 7086+CONFIG_NFS_USE_KERNEL_DNS=y 7087+# CONFIG_NFSD is not set 7088+CONFIG_GRACE_PERIOD=y 7089+CONFIG_LOCKD=y 7090+CONFIG_LOCKD_V4=y 7091+CONFIG_NFS_ACL_SUPPORT=y 7092+CONFIG_NFS_COMMON=y 7093+CONFIG_SUNRPC=y 7094+CONFIG_SUNRPC_GSS=y 7095+# CONFIG_SUNRPC_DEBUG is not set 7096+# CONFIG_CEPH_FS is not set 7097+# CONFIG_CIFS is not set 7098+# CONFIG_CODA_FS is not set 7099+# CONFIG_AFS_FS is not set 7100+CONFIG_NLS=y 7101+CONFIG_NLS_DEFAULT="iso8859-1" 7102+CONFIG_NLS_CODEPAGE_437=y 7103+CONFIG_NLS_CODEPAGE_737=m 7104+CONFIG_NLS_CODEPAGE_775=m 7105+CONFIG_NLS_CODEPAGE_850=m 7106+CONFIG_NLS_CODEPAGE_852=m 7107+CONFIG_NLS_CODEPAGE_855=m 7108+CONFIG_NLS_CODEPAGE_857=m 7109+CONFIG_NLS_CODEPAGE_860=m 7110+CONFIG_NLS_CODEPAGE_861=m 7111+CONFIG_NLS_CODEPAGE_862=m 7112+CONFIG_NLS_CODEPAGE_863=m 7113+CONFIG_NLS_CODEPAGE_864=m 7114+CONFIG_NLS_CODEPAGE_865=m 7115+CONFIG_NLS_CODEPAGE_866=m 7116+CONFIG_NLS_CODEPAGE_869=m 7117+CONFIG_NLS_CODEPAGE_936=y 7118+CONFIG_NLS_CODEPAGE_950=m 7119+CONFIG_NLS_CODEPAGE_932=m 7120+CONFIG_NLS_CODEPAGE_949=m 7121+CONFIG_NLS_CODEPAGE_874=m 7122+CONFIG_NLS_ISO8859_8=m 7123+CONFIG_NLS_CODEPAGE_1250=m 7124+CONFIG_NLS_CODEPAGE_1251=m 7125+CONFIG_NLS_ASCII=y 7126+CONFIG_NLS_ISO8859_1=y 7127+CONFIG_NLS_ISO8859_2=m 7128+CONFIG_NLS_ISO8859_3=m 7129+CONFIG_NLS_ISO8859_4=m 7130+CONFIG_NLS_ISO8859_5=m 7131+CONFIG_NLS_ISO8859_6=m 7132+CONFIG_NLS_ISO8859_7=m 7133+CONFIG_NLS_ISO8859_9=m 7134+CONFIG_NLS_ISO8859_13=m 7135+CONFIG_NLS_ISO8859_14=m 7136+CONFIG_NLS_ISO8859_15=m 7137+CONFIG_NLS_KOI8_R=m 7138+CONFIG_NLS_KOI8_U=m 7139+# CONFIG_NLS_MAC_ROMAN is not set 7140+# CONFIG_NLS_MAC_CELTIC is not set 7141+# CONFIG_NLS_MAC_CENTEURO is not set 7142+# CONFIG_NLS_MAC_CROATIAN is not set 7143+# CONFIG_NLS_MAC_CYRILLIC is not set 7144+# CONFIG_NLS_MAC_GAELIC is not set 7145+# CONFIG_NLS_MAC_GREEK is not set 7146+# CONFIG_NLS_MAC_ICELAND is not set 7147+# CONFIG_NLS_MAC_INUIT is not set 7148+# CONFIG_NLS_MAC_ROMANIAN is not set 7149+# CONFIG_NLS_MAC_TURKISH is not set 7150+CONFIG_NLS_UTF8=y 7151+# CONFIG_DLM is not set 7152+ 7153+# 7154+# Security options 7155+# 7156+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y 7157+CONFIG_SECURITY=y 7158+CONFIG_SECURITYFS=y 7159+CONFIG_SECURITY_NETWORK=y 7160+#CONFIG_PAGE_TABLE_ISOLATION=y 7161+#CONFIG_SECURITY_INFINIBAND=y 7162+#CONFIG_SECURITY_NETWORK_XFRM=y 7163+#CONFIG_SECURITY_PATH=y 7164+CONFIG_SECURITY_SELINUX=y 7165+CONFIG_SECURITY_SELINUX_BOOTPARAM=y 7166+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 7167+# CONFIG_SECURITY_SELINUX_DISABLE is not set 7168+CONFIG_SECURITY_SELINUX_DEVELOP=y 7169+CONFIG_SECURITY_SELINUX_AVC_STATS=y 7170+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 7171+CONFIG_DEFAULT_SECURITY_SELINUX=y 7172+CONFIG_DEFAULT_SECURITY="selinux" 7173+#CONFIG_SECURITY_SMACK=y 7174+# CONFIG_SECURITY_SMACK_BRINGUP is not set 7175+#CONFIG_SECURITY_SMACK_NETFILTER=y 7176+#CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y 7177+#CONFIG_SECURITY_TOMOYO=y 7178+#CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 7179+#CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 7180+#CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set 7181+#CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" 7182+#CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" 7183+CONFIG_SECURITY_APPARMOR=y 7184+CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 7185+CONFIG_SECURITY_APPARMOR_HASH=y 7186+CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y 7187+# CONFIG_SECURITY_APPARMOR_DEBUG is not set 7188+# CONFIG_SECURITY_LOADPIN is not set 7189+# CONFIG_SECURITY_YAMA=y 7190+ 7191+CONFIG_CRYPTO=y 7192+ 7193+# 7194+# Crypto core or helper 7195+# 7196+CONFIG_CRYPTO_ALGAPI=y 7197+CONFIG_CRYPTO_ALGAPI2=y 7198+CONFIG_CRYPTO_AEAD=m 7199+CONFIG_CRYPTO_AEAD2=y 7200+CONFIG_CRYPTO_BLKCIPHER2=y 7201+CONFIG_CRYPTO_HASH=y 7202+CONFIG_CRYPTO_HASH2=y 7203+CONFIG_CRYPTO_RNG=y 7204+CONFIG_CRYPTO_RNG2=y 7205+CONFIG_CRYPTO_RNG_DEFAULT=m 7206+CONFIG_CRYPTO_AKCIPHER2=y 7207+CONFIG_CRYPTO_KPP2=y 7208+CONFIG_CRYPTO_ACOMP2=y 7209+# CONFIG_CRYPTO_RSA is not set 7210+# CONFIG_CRYPTO_DH is not set 7211+# CONFIG_CRYPTO_ECDH is not set 7212+CONFIG_CRYPTO_MANAGER=m 7213+CONFIG_CRYPTO_MANAGER2=y 7214+# CONFIG_CRYPTO_USER is not set 7215+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y 7216+# CONFIG_CRYPTO_GF128MUL is not set 7217+CONFIG_CRYPTO_NULL=m 7218+CONFIG_CRYPTO_NULL2=y 7219+# CONFIG_CRYPTO_PCRYPT is not set 7220+CONFIG_CRYPTO_WORKQUEUE=y 7221+# CONFIG_CRYPTO_CRYPTD is not set 7222+# CONFIG_CRYPTO_MCRYPTD is not set 7223+# CONFIG_CRYPTO_AUTHENC is not set 7224+# CONFIG_CRYPTO_TEST is not set 7225+ 7226+# 7227+# Authenticated Encryption with Associated Data 7228+# 7229+# CONFIG_CRYPTO_CCM is not set 7230+# CONFIG_CRYPTO_GCM is not set 7231+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set 7232+# CONFIG_CRYPTO_AEGIS128 is not set 7233+# CONFIG_CRYPTO_AEGIS128L is not set 7234+# CONFIG_CRYPTO_AEGIS256 is not set 7235+# CONFIG_CRYPTO_MORUS640 is not set 7236+# CONFIG_CRYPTO_MORUS1280 is not set 7237+# CONFIG_CRYPTO_SEQIV is not set 7238+CONFIG_CRYPTO_ECHAINIV=m 7239+ 7240+# 7241+# Block modes 7242+# 7243+# CONFIG_CRYPTO_CBC is not set 7244+# CONFIG_CRYPTO_CFB is not set 7245+# CONFIG_CRYPTO_CTR is not set 7246+# CONFIG_CRYPTO_CTS is not set 7247+# CONFIG_CRYPTO_ECB is not set 7248+# CONFIG_CRYPTO_LRW is not set 7249+# CONFIG_CRYPTO_PCBC is not set 7250+# CONFIG_CRYPTO_XTS is not set 7251+# CONFIG_CRYPTO_KEYWRAP is not set 7252+ 7253+# 7254+# Hash modes 7255+# 7256+# CONFIG_CRYPTO_CMAC is not set 7257+CONFIG_CRYPTO_HMAC=m 7258+# CONFIG_CRYPTO_XCBC is not set 7259+# CONFIG_CRYPTO_VMAC is not set 7260+ 7261+# 7262+# Digest 7263+# 7264+CONFIG_CRYPTO_CRC32C=y 7265+# CONFIG_CRYPTO_CRC32 is not set 7266+# CONFIG_CRYPTO_CRCT10DIF is not set 7267+# CONFIG_CRYPTO_GHASH is not set 7268+# CONFIG_CRYPTO_POLY1305 is not set 7269+# CONFIG_CRYPTO_MD4 is not set 7270+# CONFIG_CRYPTO_MD5 is not set 7271+# CONFIG_CRYPTO_MICHAEL_MIC is not set 7272+# CONFIG_CRYPTO_RMD128 is not set 7273+# CONFIG_CRYPTO_RMD160 is not set 7274+# CONFIG_CRYPTO_RMD256 is not set 7275+# CONFIG_CRYPTO_RMD320 is not set 7276+CONFIG_CRYPTO_SHA1=y 7277+CONFIG_CRYPTO_SHA256=m 7278+# CONFIG_CRYPTO_SHA512 is not set 7279+# CONFIG_CRYPTO_SHA3 is not set 7280+# CONFIG_CRYPTO_SM3 is not set 7281+# CONFIG_CRYPTO_TGR192 is not set 7282+# CONFIG_CRYPTO_WP512 is not set 7283+ 7284+# 7285+# Ciphers 7286+# 7287+CONFIG_CRYPTO_AES=y 7288+# CONFIG_CRYPTO_AES_TI is not set 7289+# CONFIG_CRYPTO_ANUBIS is not set 7290+# CONFIG_CRYPTO_ARC4 is not set 7291+# CONFIG_CRYPTO_BLOWFISH is not set 7292+# CONFIG_CRYPTO_CAMELLIA is not set 7293+# CONFIG_CRYPTO_CAST5 is not set 7294+# CONFIG_CRYPTO_CAST6 is not set 7295+# CONFIG_CRYPTO_DES is not set 7296+# CONFIG_CRYPTO_FCRYPT is not set 7297+# CONFIG_CRYPTO_KHAZAD is not set 7298+# CONFIG_CRYPTO_SALSA20 is not set 7299+# CONFIG_CRYPTO_CHACHA20 is not set 7300+# CONFIG_CRYPTO_SEED is not set 7301+# CONFIG_CRYPTO_SERPENT is not set 7302+# CONFIG_CRYPTO_SM4 is not set 7303+# CONFIG_CRYPTO_TEA is not set 7304+# CONFIG_CRYPTO_TWOFISH is not set 7305+ 7306+# 7307+# Compression 7308+# 7309+# CONFIG_CRYPTO_DEFLATE is not set 7310+# CONFIG_CRYPTO_LZO is not set 7311+# CONFIG_CRYPTO_842 is not set 7312+# CONFIG_CRYPTO_LZ4 is not set 7313+# CONFIG_CRYPTO_LZ4HC is not set 7314+# CONFIG_CRYPTO_ZSTD is not set 7315+ 7316+# 7317+# Random Number Generation 7318+# 7319+CONFIG_CRYPTO_ANSI_CPRNG=y 7320+CONFIG_CRYPTO_DRBG_MENU=m 7321+CONFIG_CRYPTO_DRBG_HMAC=y 7322+# CONFIG_CRYPTO_DRBG_HASH is not set 7323+CONFIG_CRYPTO_DRBG=m 7324+CONFIG_CRYPTO_JITTERENTROPY=m 7325+# CONFIG_CRYPTO_USER_API_HASH is not set 7326+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set 7327+# CONFIG_CRYPTO_USER_API_RNG is not set 7328+# CONFIG_CRYPTO_USER_API_AEAD is not set 7329+CONFIG_CRYPTO_HW=y 7330+# CONFIG_CRYPTO_DEV_CCREE is not set 7331+# CONFIG_ASYMMETRIC_KEY_TYPE is not set 7332+ 7333+# 7334+# Certificates for signature checking 7335+# 7336+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set 7337+ 7338+# 7339+# Library routines 7340+# 7341+CONFIG_BITREVERSE=y 7342+CONFIG_HAVE_ARCH_BITREVERSE=y 7343+CONFIG_RATIONAL=y 7344+CONFIG_GENERIC_STRNCPY_FROM_USER=y 7345+CONFIG_GENERIC_STRNLEN_USER=y 7346+CONFIG_GENERIC_NET_UTILS=y 7347+CONFIG_GENERIC_PCI_IOMAP=y 7348+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y 7349+# CONFIG_CRC_CCITT is not set 7350+CONFIG_CRC16=y 7351+# CONFIG_CRC_T10DIF is not set 7352+# CONFIG_CRC_ITU_T is not set 7353+CONFIG_CRC32=y 7354+# CONFIG_CRC32_SELFTEST is not set 7355+CONFIG_CRC32_SLICEBY8=y 7356+# CONFIG_CRC32_SLICEBY4 is not set 7357+# CONFIG_CRC32_SARWATE is not set 7358+# CONFIG_CRC32_BIT is not set 7359+# CONFIG_CRC64 is not set 7360+# CONFIG_CRC4 is not set 7361+# CONFIG_CRC7 is not set 7362+CONFIG_LIBCRC32C=m 7363+# CONFIG_CRC8 is not set 7364+CONFIG_AUDIT_GENERIC=y 7365+# CONFIG_RANDOM32_SELFTEST is not set 7366+CONFIG_ZLIB_INFLATE=y 7367+CONFIG_XZ_DEC=y 7368+CONFIG_XZ_DEC_X86=y 7369+CONFIG_XZ_DEC_POWERPC=y 7370+CONFIG_XZ_DEC_IA64=y 7371+CONFIG_XZ_DEC_ARM=y 7372+CONFIG_XZ_DEC_ARMTHUMB=y 7373+CONFIG_XZ_DEC_SPARC=y 7374+CONFIG_XZ_DEC_BCJ=y 7375+# CONFIG_XZ_DEC_TEST is not set 7376+CONFIG_GENERIC_ALLOCATOR=y 7377+CONFIG_ASSOCIATIVE_ARRAY=y 7378+CONFIG_HAS_IOMEM=y 7379+CONFIG_HAS_IOPORT_MAP=y 7380+CONFIG_HAS_DMA=y 7381+CONFIG_NEED_DMA_MAP_STATE=y 7382+CONFIG_HAVE_GENERIC_DMA_COHERENT=y 7383+CONFIG_SGL_ALLOC=y 7384+CONFIG_CPU_RMAP=y 7385+CONFIG_DQL=y 7386+CONFIG_NLATTR=y 7387+# CONFIG_CORDIC is not set 7388+# CONFIG_DDR is not set 7389+# CONFIG_IRQ_POLL is not set 7390+CONFIG_LIBFDT=y 7391+CONFIG_OID_REGISTRY=y 7392+CONFIG_SG_POOL=y 7393+CONFIG_ARCH_HAS_SG_CHAIN=y 7394+CONFIG_SBITMAP=y 7395+# CONFIG_STRING_SELFTEST is not set 7396+ 7397+# 7398+# Kernel hacking 7399+# 7400+ 7401+# 7402+# printk and dmesg options 7403+# 7404+# CONFIG_PRINTK_TIME is not set 7405+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 7406+CONFIG_CONSOLE_LOGLEVEL_QUIET=4 7407+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 7408+# CONFIG_BOOT_PRINTK_DELAY is not set 7409+# CONFIG_DYNAMIC_DEBUG is not set 7410+ 7411+# 7412+# Compile-time checks and compiler options 7413+# 7414+# CONFIG_DEBUG_INFO is not set 7415+CONFIG_ENABLE_MUST_CHECK=y 7416+CONFIG_FRAME_WARN=1024 7417+# CONFIG_STRIP_ASM_SYMS is not set 7418+# CONFIG_READABLE_ASM is not set 7419+# CONFIG_UNUSED_SYMBOLS is not set 7420+# CONFIG_PAGE_OWNER is not set 7421+CONFIG_DEBUG_FS=y 7422+# CONFIG_HEADERS_CHECK is not set 7423+# CONFIG_DEBUG_SECTION_MISMATCH is not set 7424+CONFIG_SECTION_MISMATCH_WARN_ONLY=y 7425+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set 7426+# CONFIG_MAGIC_SYSRQ is not set 7427+CONFIG_DEBUG_KERNEL=y 7428+ 7429+# 7430+# Memory Debugging 7431+# 7432+# CONFIG_PAGE_EXTENSION is not set 7433+# CONFIG_DEBUG_PAGEALLOC is not set 7434+# CONFIG_PAGE_POISONING is not set 7435+# CONFIG_DEBUG_RODATA_TEST is not set 7436+# CONFIG_DEBUG_OBJECTS is not set 7437+# CONFIG_SLUB_DEBUG_ON is not set 7438+# CONFIG_SLUB_STATS is not set 7439+CONFIG_HAVE_DEBUG_KMEMLEAK=y 7440+# CONFIG_DEBUG_KMEMLEAK is not set 7441+# CONFIG_DEBUG_STACK_USAGE is not set 7442+# CONFIG_DEBUG_VM is not set 7443+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y 7444+# CONFIG_DEBUG_VIRTUAL is not set 7445+CONFIG_DEBUG_MEMORY_INIT=y 7446+# CONFIG_DEBUG_PER_CPU_MAPS is not set 7447+# CONFIG_DEBUG_HIGHMEM is not set 7448+CONFIG_ARCH_HAS_KCOV=y 7449+CONFIG_CC_HAS_SANCOV_TRACE_PC=y 7450+# CONFIG_KCOV is not set 7451+# CONFIG_DEBUG_SHIRQ is not set 7452+ 7453+# 7454+# Debug Lockups and Hangs 7455+# 7456+# CONFIG_SOFTLOCKUP_DETECTOR is not set 7457+# CONFIG_DETECT_HUNG_TASK is not set 7458+# CONFIG_WQ_WATCHDOG is not set 7459+# CONFIG_PANIC_ON_OOPS is not set 7460+CONFIG_PANIC_ON_OOPS_VALUE=0 7461+CONFIG_PANIC_TIMEOUT=0 7462+CONFIG_SCHED_DEBUG=y 7463+# CONFIG_SCHEDSTATS is not set 7464+# CONFIG_SCHED_STACK_END_CHECK is not set 7465+# CONFIG_DEBUG_TIMEKEEPING is not set 7466+ 7467+# 7468+# Lock Debugging (spinlocks, mutexes, etc...) 7469+# 7470+CONFIG_LOCK_DEBUGGING_SUPPORT=y 7471+# CONFIG_PROVE_LOCKING is not set 7472+# CONFIG_LOCK_STAT is not set 7473+# CONFIG_DEBUG_RT_MUTEXES is not set 7474+# CONFIG_DEBUG_SPINLOCK is not set 7475+# CONFIG_DEBUG_MUTEXES is not set 7476+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set 7477+# CONFIG_DEBUG_RWSEMS is not set 7478+# CONFIG_DEBUG_LOCK_ALLOC is not set 7479+# CONFIG_DEBUG_ATOMIC_SLEEP is not set 7480+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 7481+# CONFIG_LOCK_TORTURE_TEST is not set 7482+# CONFIG_WW_MUTEX_SELFTEST is not set 7483+CONFIG_STACKTRACE=y 7484+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set 7485+# CONFIG_DEBUG_KOBJECT is not set 7486+CONFIG_DEBUG_BUGVERBOSE=y 7487+# CONFIG_DEBUG_LIST is not set 7488+# CONFIG_DEBUG_PI_LIST is not set 7489+# CONFIG_DEBUG_SG is not set 7490+# CONFIG_DEBUG_NOTIFIERS is not set 7491+# CONFIG_DEBUG_CREDENTIALS is not set 7492+ 7493+# 7494+# RCU Debugging 7495+# 7496+# CONFIG_RCU_PERF_TEST is not set 7497+# CONFIG_RCU_TORTURE_TEST is not set 7498+CONFIG_RCU_CPU_STALL_TIMEOUT=60 7499+# CONFIG_RCU_TRACE is not set 7500+# CONFIG_RCU_EQS_DEBUG is not set 7501+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set 7502+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set 7503+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set 7504+# CONFIG_NOTIFIER_ERROR_INJECTION is not set 7505+# CONFIG_FAULT_INJECTION is not set 7506+# CONFIG_LATENCYTOP is not set 7507+CONFIG_HAVE_FUNCTION_TRACER=y 7508+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y 7509+CONFIG_HAVE_DYNAMIC_FTRACE=y 7510+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y 7511+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y 7512+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y 7513+CONFIG_HAVE_C_RECORDMCOUNT=y 7514+CONFIG_TRACING_SUPPORT=y 7515+# CONFIG_FTRACE is not set 7516+# CONFIG_DMA_API_DEBUG is not set 7517+CONFIG_RUNTIME_TESTING_MENU=y 7518+# CONFIG_LKDTM is not set 7519+# CONFIG_TEST_LIST_SORT is not set 7520+# CONFIG_TEST_SORT is not set 7521+# CONFIG_BACKTRACE_SELF_TEST is not set 7522+# CONFIG_RBTREE_TEST is not set 7523+# CONFIG_INTERVAL_TREE_TEST is not set 7524+# CONFIG_PERCPU_TEST is not set 7525+# CONFIG_ATOMIC64_SELFTEST is not set 7526+# CONFIG_TEST_HEXDUMP is not set 7527+# CONFIG_TEST_STRING_HELPERS is not set 7528+# CONFIG_TEST_KSTRTOX is not set 7529+# CONFIG_TEST_PRINTF is not set 7530+# CONFIG_TEST_BITMAP is not set 7531+# CONFIG_TEST_BITFIELD is not set 7532+# CONFIG_TEST_UUID is not set 7533+# CONFIG_TEST_OVERFLOW is not set 7534+# CONFIG_TEST_RHASHTABLE is not set 7535+# CONFIG_TEST_HASH is not set 7536+# CONFIG_TEST_IDA is not set 7537+# CONFIG_TEST_LKM is not set 7538+# CONFIG_TEST_USER_COPY is not set 7539+# CONFIG_TEST_BPF is not set 7540+# CONFIG_FIND_BIT_BENCHMARK is not set 7541+# CONFIG_TEST_FIRMWARE is not set 7542diff --git a/arch/arm/configs/hi3516dv300_smp_defconfig b/arch/arm/configs/hi3516dv300_smp_defconfig 7543new file mode 100644 7544index 000000000..109c06652 7545--- /dev/null 7546+++ b/arch/arm/configs/hi3516dv300_smp_defconfig 7547@@ -0,0 +1,3189 @@ 7548+# 7549+# Automatically generated file; DO NOT EDIT. 7550+# Linux/arm 4.19.90 Kernel Configuration 7551+# 7552+ 7553+# 7554+# Compiler: arm-himix410-linux-gcc (HC&C V1R3C00SPC200B041_20200707) 7.3.0 7555+# 7556+CONFIG_CC_IS_GCC=y 7557+CONFIG_GCC_VERSION=70300 7558+CONFIG_CLANG_VERSION=0 7559+CONFIG_CC_HAS_ASM_GOTO=y 7560+CONFIG_IRQ_WORK=y 7561+CONFIG_BUILDTIME_EXTABLE_SORT=y 7562+ 7563+# 7564+# General setup 7565+# 7566+CONFIG_INIT_ENV_ARG_LIMIT=32 7567+# CONFIG_COMPILE_TEST is not set 7568+CONFIG_LOCALVERSION="" 7569+# CONFIG_LOCALVERSION_AUTO is not set 7570+CONFIG_BUILD_SALT="" 7571+CONFIG_HAVE_KERNEL_GZIP=y 7572+CONFIG_HAVE_KERNEL_LZMA=y 7573+CONFIG_HAVE_KERNEL_XZ=y 7574+CONFIG_HAVE_KERNEL_LZO=y 7575+CONFIG_HAVE_KERNEL_LZ4=y 7576+CONFIG_KERNEL_GZIP=y 7577+# CONFIG_KERNEL_LZMA is not set 7578+# CONFIG_KERNEL_XZ is not set 7579+# CONFIG_KERNEL_LZO is not set 7580+# CONFIG_KERNEL_LZ4 is not set 7581+CONFIG_DEFAULT_HOSTNAME="(none)" 7582+# CONFIG_SWAP is not set 7583+CONFIG_SYSVIPC=y 7584+CONFIG_SYSVIPC_SYSCTL=y 7585+# CONFIG_POSIX_MQUEUE is not set 7586+CONFIG_CROSS_MEMORY_ATTACH=y 7587+CONFIG_USELIB=y 7588+# CONFIG_AUDIT is not set 7589+ 7590+# 7591+# IRQ subsystem 7592+# 7593+CONFIG_GENERIC_IRQ_PROBE=y 7594+CONFIG_GENERIC_IRQ_SHOW=y 7595+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y 7596+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y 7597+CONFIG_GENERIC_IRQ_MIGRATION=y 7598+CONFIG_HARDIRQS_SW_RESEND=y 7599+CONFIG_IRQ_DOMAIN=y 7600+CONFIG_IRQ_DOMAIN_HIERARCHY=y 7601+CONFIG_HANDLE_DOMAIN_IRQ=y 7602+CONFIG_IRQ_FORCED_THREADING=y 7603+CONFIG_SPARSE_IRQ=y 7604+# CONFIG_GENERIC_IRQ_DEBUGFS is not set 7605+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y 7606+CONFIG_ARCH_CLOCKSOURCE_DATA=y 7607+CONFIG_GENERIC_TIME_VSYSCALL=y 7608+CONFIG_GENERIC_CLOCKEVENTS=y 7609+CONFIG_ARCH_HAS_TICK_BROADCAST=y 7610+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y 7611+ 7612+# 7613+# Timers subsystem 7614+# 7615+CONFIG_HZ_PERIODIC=y 7616+# CONFIG_NO_HZ_IDLE is not set 7617+# CONFIG_NO_HZ_FULL is not set 7618+# CONFIG_NO_HZ is not set 7619+# CONFIG_HIGH_RES_TIMERS is not set 7620+CONFIG_PREEMPT_NONE=y 7621+# CONFIG_PREEMPT_VOLUNTARY is not set 7622+# CONFIG_PREEMPT is not set 7623+ 7624+# 7625+# CPU/Task time and stats accounting 7626+# 7627+CONFIG_TICK_CPU_ACCOUNTING=y 7628+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set 7629+# CONFIG_IRQ_TIME_ACCOUNTING is not set 7630+# CONFIG_BSD_PROCESS_ACCT is not set 7631+# CONFIG_TASKSTATS is not set 7632+CONFIG_CPU_ISOLATION=y 7633+ 7634+# 7635+# RCU Subsystem 7636+# 7637+CONFIG_TREE_RCU=y 7638+# CONFIG_RCU_EXPERT is not set 7639+CONFIG_SRCU=y 7640+CONFIG_TREE_SRCU=y 7641+CONFIG_RCU_STALL_COMMON=y 7642+CONFIG_RCU_NEED_SEGCBLIST=y 7643+# CONFIG_IKCONFIG is not set 7644+CONFIG_LOG_BUF_SHIFT=17 7645+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 7646+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 7647+CONFIG_GENERIC_SCHED_CLOCK=y 7648+CONFIG_CGROUPS=y 7649+# CONFIG_MEMCG is not set 7650+# CONFIG_BLK_CGROUP is not set 7651+CONFIG_CGROUP_SCHED=y 7652+CONFIG_FAIR_GROUP_SCHED=y 7653+# CONFIG_CFS_BANDWIDTH is not set 7654+# CONFIG_RT_GROUP_SCHED is not set 7655+# CONFIG_CGROUP_PIDS is not set 7656+# CONFIG_CGROUP_RDMA is not set 7657+# CONFIG_CGROUP_FREEZER is not set 7658+# CONFIG_CPUSETS is not set 7659+# CONFIG_CGROUP_DEVICE is not set 7660+# CONFIG_CGROUP_CPUACCT is not set 7661+# CONFIG_CGROUP_DEBUG is not set 7662+CONFIG_NAMESPACES=y 7663+CONFIG_UTS_NS=y 7664+CONFIG_IPC_NS=y 7665+# CONFIG_USER_NS is not set 7666+CONFIG_PID_NS=y 7667+CONFIG_NET_NS=y 7668+# CONFIG_CHECKPOINT_RESTORE is not set 7669+# CONFIG_SCHED_AUTOGROUP is not set 7670+# CONFIG_SYSFS_DEPRECATED is not set 7671+# CONFIG_RELAY is not set 7672+# CONFIG_BLK_DEV_INITRD is not set 7673+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y 7674+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 7675+CONFIG_SYSCTL=y 7676+CONFIG_ANON_INODES=y 7677+CONFIG_HAVE_UID16=y 7678+CONFIG_BPF=y 7679+# CONFIG_EXPERT is not set 7680+CONFIG_UID16=y 7681+CONFIG_MULTIUSER=y 7682+CONFIG_SYSFS_SYSCALL=y 7683+CONFIG_FHANDLE=y 7684+CONFIG_POSIX_TIMERS=y 7685+CONFIG_PRINTK=y 7686+CONFIG_PRINTK_NMI=y 7687+CONFIG_BUG=y 7688+CONFIG_ELF_CORE=y 7689+CONFIG_BASE_FULL=y 7690+CONFIG_FUTEX=y 7691+CONFIG_FUTEX_PI=y 7692+CONFIG_EPOLL=y 7693+CONFIG_SIGNALFD=y 7694+CONFIG_TIMERFD=y 7695+CONFIG_EVENTFD=y 7696+CONFIG_SHMEM=y 7697+CONFIG_AIO=y 7698+CONFIG_ADVISE_SYSCALLS=y 7699+CONFIG_MEMBARRIER=y 7700+CONFIG_KALLSYMS=y 7701+# CONFIG_KALLSYMS_ALL is not set 7702+CONFIG_KALLSYMS_BASE_RELATIVE=y 7703+# CONFIG_BPF_SYSCALL is not set 7704+# CONFIG_USERFAULTFD is not set 7705+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y 7706+CONFIG_RSEQ=y 7707+# CONFIG_EMBEDDED is not set 7708+CONFIG_HAVE_PERF_EVENTS=y 7709+CONFIG_PERF_USE_VMALLOC=y 7710+ 7711+# 7712+# Kernel Performance Events And Counters 7713+# 7714+# CONFIG_PERF_EVENTS is not set 7715+CONFIG_VM_EVENT_COUNTERS=y 7716+CONFIG_SLUB_DEBUG=y 7717+CONFIG_COMPAT_BRK=y 7718+# CONFIG_SLAB is not set 7719+CONFIG_SLUB=y 7720+CONFIG_SLAB_MERGE_DEFAULT=y 7721+# CONFIG_SLAB_FREELIST_RANDOM is not set 7722+# CONFIG_SLAB_FREELIST_HARDENED is not set 7723+CONFIG_SLUB_CPU_PARTIAL=y 7724+# CONFIG_PROFILING is not set 7725+CONFIG_ARM=y 7726+CONFIG_ARM_HAS_SG_CHAIN=y 7727+CONFIG_MIGHT_HAVE_PCI=y 7728+CONFIG_SYS_SUPPORTS_APM_EMULATION=y 7729+CONFIG_HAVE_PROC_CPU=y 7730+CONFIG_STACKTRACE_SUPPORT=y 7731+CONFIG_LOCKDEP_SUPPORT=y 7732+CONFIG_TRACE_IRQFLAGS_SUPPORT=y 7733+CONFIG_RWSEM_XCHGADD_ALGORITHM=y 7734+CONFIG_FIX_EARLYCON_MEM=y 7735+CONFIG_GENERIC_HWEIGHT=y 7736+CONFIG_GENERIC_CALIBRATE_DELAY=y 7737+CONFIG_ARCH_SUPPORTS_UPROBES=y 7738+CONFIG_ARM_PATCH_PHYS_VIRT=y 7739+CONFIG_GENERIC_BUG=y 7740+CONFIG_PGTABLE_LEVELS=2 7741+ 7742+# 7743+# System Type 7744+# 7745+CONFIG_MMU=y 7746+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 7747+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 7748+CONFIG_ARCH_MULTIPLATFORM=y 7749+# CONFIG_ARCH_EBSA110 is not set 7750+# CONFIG_ARCH_EP93XX is not set 7751+# CONFIG_ARCH_FOOTBRIDGE is not set 7752+# CONFIG_ARCH_NETX is not set 7753+# CONFIG_ARCH_IOP13XX is not set 7754+# CONFIG_ARCH_IOP32X is not set 7755+# CONFIG_ARCH_IOP33X is not set 7756+# CONFIG_ARCH_IXP4XX is not set 7757+# CONFIG_ARCH_DOVE is not set 7758+# CONFIG_ARCH_KS8695 is not set 7759+# CONFIG_ARCH_W90X900 is not set 7760+# CONFIG_ARCH_LPC32XX is not set 7761+# CONFIG_ARCH_PXA is not set 7762+# CONFIG_ARCH_RPC is not set 7763+# CONFIG_ARCH_SA1100 is not set 7764+# CONFIG_ARCH_S3C24XX is not set 7765+# CONFIG_ARCH_DAVINCI is not set 7766+# CONFIG_ARCH_OMAP1 is not set 7767+ 7768+# 7769+# Multiple platform selection 7770+# 7771+ 7772+# 7773+# CPU Core family selection 7774+# 7775+# CONFIG_ARCH_MULTI_V6 is not set 7776+CONFIG_ARCH_MULTI_V7=y 7777+CONFIG_ARCH_MULTI_V6_V7=y 7778+# CONFIG_ARCH_VIRT is not set 7779+# CONFIG_ARCH_ACTIONS is not set 7780+# CONFIG_ARCH_ALPINE is not set 7781+# CONFIG_ARCH_ARTPEC is not set 7782+# CONFIG_ARCH_AT91 is not set 7783+# CONFIG_ARCH_BCM is not set 7784+# CONFIG_ARCH_BERLIN is not set 7785+# CONFIG_ARCH_DIGICOLOR is not set 7786+# CONFIG_ARCH_EXYNOS is not set 7787+# CONFIG_ARCH_HIGHBANK is not set 7788+# CONFIG_ARCH_HISI is not set 7789+CONFIG_ARCH_HISI_BVT=y 7790+ 7791+# 7792+# Hisilicon BVT platform type 7793+# 7794+# CONFIG_ARCH_HI3521DV200 is not set 7795+# CONFIG_ARCH_HI3520DV500 is not set 7796+# CONFIG_ARCH_HI3516A is not set 7797+# CONFIG_ARCH_HI3516CV500 is not set 7798+CONFIG_ARCH_HI3516DV300=y 7799+# CONFIG_ARCH_HI3516EV200 is not set 7800+# CONFIG_ARCH_HI3516EV300 is not set 7801+# CONFIG_ARCH_HI3518EV300 is not set 7802+# CONFIG_ARCH_HI3516DV200 is not set 7803+# CONFIG_ARCH_HI3556V200 is not set 7804+# CONFIG_ARCH_HI3559V200 is not set 7805+# CONFIG_ARCH_HI3536DV100 is not set 7806+# CONFIG_ARCH_HI3521A is not set 7807+# CONFIG_ARCH_HI3531A is not set 7808+# CONFIG_ARCH_HI3556AV100 is not set 7809+# CONFIG_ARCH_HI3519AV100 is not set 7810+# CONFIG_ARCH_HI3568V100 is not set 7811+# CONFIG_ARCH_HISI_BVT_AMP is not set 7812+# CONFIG_HISI_MC is not set 7813+CONFIG_HI_ZRELADDR=0x80008000 7814+CONFIG_HI_PARAMS_PHYS=0x00000100 7815+CONFIG_HI_INITRD_PHYS=0x00800000 7816+# CONFIG_ARCH_MXC is not set 7817+# CONFIG_ARCH_KEYSTONE is not set 7818+# CONFIG_ARCH_MEDIATEK is not set 7819+# CONFIG_ARCH_MESON is not set 7820+# CONFIG_ARCH_MMP is not set 7821+# CONFIG_ARCH_MVEBU is not set 7822+# CONFIG_ARCH_NPCM is not set 7823+ 7824+# 7825+# TI OMAP/AM/DM/DRA Family 7826+# 7827+# CONFIG_ARCH_OMAP3 is not set 7828+# CONFIG_ARCH_OMAP4 is not set 7829+# CONFIG_SOC_OMAP5 is not set 7830+# CONFIG_SOC_AM33XX is not set 7831+# CONFIG_SOC_AM43XX is not set 7832+# CONFIG_SOC_DRA7XX is not set 7833+# CONFIG_ARCH_SIRF is not set 7834+# CONFIG_ARCH_QCOM is not set 7835+# CONFIG_ARCH_REALVIEW is not set 7836+# CONFIG_ARCH_ROCKCHIP is not set 7837+# CONFIG_ARCH_S5PV210 is not set 7838+# CONFIG_ARCH_RENESAS is not set 7839+# CONFIG_ARCH_SOCFPGA is not set 7840+# CONFIG_PLAT_SPEAR is not set 7841+# CONFIG_ARCH_STI is not set 7842+# CONFIG_ARCH_STM32 is not set 7843+# CONFIG_ARCH_SUNXI is not set 7844+# CONFIG_ARCH_TANGO is not set 7845+# CONFIG_ARCH_TEGRA is not set 7846+# CONFIG_ARCH_UNIPHIER is not set 7847+# CONFIG_ARCH_U8500 is not set 7848+# CONFIG_ARCH_VEXPRESS is not set 7849+# CONFIG_ARCH_WM8850 is not set 7850+# CONFIG_ARCH_ZX is not set 7851+# CONFIG_ARCH_ZYNQ is not set 7852+ 7853+# 7854+# Processor Type 7855+# 7856+CONFIG_CPU_V7=y 7857+CONFIG_CPU_THUMB_CAPABLE=y 7858+CONFIG_CPU_32v6K=y 7859+CONFIG_CPU_32v7=y 7860+CONFIG_CPU_ABRT_EV7=y 7861+CONFIG_CPU_PABRT_V7=y 7862+CONFIG_CPU_CACHE_V7=y 7863+CONFIG_CPU_CACHE_VIPT=y 7864+CONFIG_CPU_COPY_V6=y 7865+CONFIG_CPU_TLB_V7=y 7866+CONFIG_CPU_HAS_ASID=y 7867+CONFIG_CPU_CP15=y 7868+CONFIG_CPU_CP15_MMU=y 7869+ 7870+# 7871+# Processor Features 7872+# 7873+# CONFIG_ARM_LPAE is not set 7874+CONFIG_ARM_THUMB=y 7875+# CONFIG_ARM_THUMBEE is not set 7876+CONFIG_ARM_VIRT_EXT=y 7877+CONFIG_SWP_EMULATE=y 7878+# CONFIG_CPU_ICACHE_DISABLE is not set 7879+# CONFIG_CPU_BPREDICT_DISABLE is not set 7880+CONFIG_CPU_SPECTRE=y 7881+CONFIG_HARDEN_BRANCH_PREDICTOR=y 7882+CONFIG_KUSER_HELPERS=y 7883+CONFIG_VDSO=y 7884+CONFIG_MIGHT_HAVE_CACHE_L2X0=y 7885+# CONFIG_CACHE_L2X0 is not set 7886+CONFIG_ARM_L1_CACHE_SHIFT_6=y 7887+CONFIG_ARM_L1_CACHE_SHIFT=6 7888+CONFIG_ARM_DMA_MEM_BUFFERABLE=y 7889+CONFIG_DEBUG_ALIGN_RODATA=y 7890+# CONFIG_ARM_ERRATA_430973 is not set 7891+# CONFIG_ARM_ERRATA_643719 is not set 7892+# CONFIG_ARM_ERRATA_720789 is not set 7893+# CONFIG_ARM_ERRATA_754322 is not set 7894+# CONFIG_ARM_ERRATA_754327 is not set 7895+# CONFIG_ARM_ERRATA_764369 is not set 7896+# CONFIG_ARM_ERRATA_775420 is not set 7897+# CONFIG_ARM_ERRATA_798181 is not set 7898+# CONFIG_ARM_ERRATA_773022 is not set 7899+# CONFIG_ARM_ERRATA_818325_852422 is not set 7900+# CONFIG_ARM_ERRATA_821420 is not set 7901+# CONFIG_ARM_ERRATA_825619 is not set 7902+# CONFIG_ARM_ERRATA_852421 is not set 7903+# CONFIG_ARM_ERRATA_852423 is not set 7904+ 7905+# 7906+# Bus support 7907+# 7908+# CONFIG_PCI is not set 7909+ 7910+# 7911+# PCI Endpoint 7912+# 7913+# CONFIG_PCI_ENDPOINT is not set 7914+# CONFIG_PCCARD is not set 7915+ 7916+# 7917+# Kernel Features 7918+# 7919+CONFIG_HAVE_SMP=y 7920+CONFIG_SMP=y 7921+CONFIG_SMP_ON_UP=y 7922+CONFIG_ARM_CPU_TOPOLOGY=y 7923+# CONFIG_SCHED_MC is not set 7924+# CONFIG_SCHED_SMT is not set 7925+CONFIG_HAVE_ARM_ARCH_TIMER=y 7926+# CONFIG_MCPM is not set 7927+# CONFIG_BIG_LITTLE is not set 7928+CONFIG_VMSPLIT_3G=y 7929+# CONFIG_VMSPLIT_3G_OPT is not set 7930+# CONFIG_VMSPLIT_2G is not set 7931+# CONFIG_VMSPLIT_1G is not set 7932+CONFIG_PAGE_OFFSET=0xC0000000 7933+CONFIG_NR_CPUS=2 7934+CONFIG_HOTPLUG_CPU=y 7935+# CONFIG_ARM_PSCI is not set 7936+CONFIG_ARCH_NR_GPIO=0 7937+CONFIG_HZ_FIXED=0 7938+CONFIG_HZ_100=y 7939+# CONFIG_HZ_200 is not set 7940+# CONFIG_HZ_250 is not set 7941+# CONFIG_HZ_300 is not set 7942+# CONFIG_HZ_500 is not set 7943+# CONFIG_HZ_1000 is not set 7944+CONFIG_HZ=100 7945+# CONFIG_THUMB2_KERNEL is not set 7946+CONFIG_ARM_PATCH_IDIV=y 7947+CONFIG_AEABI=y 7948+CONFIG_OABI_COMPAT=y 7949+CONFIG_HAVE_ARCH_PFN_VALID=y 7950+CONFIG_HIGHMEM=y 7951+CONFIG_HIGHPTE=y 7952+CONFIG_CPU_SW_DOMAIN_PAN=y 7953+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y 7954+# CONFIG_ARM_MODULE_PLTS is not set 7955+CONFIG_FORCE_MAX_ZONEORDER=11 7956+CONFIG_ALIGNMENT_TRAP=y 7957+# CONFIG_UACCESS_WITH_MEMCPY is not set 7958+# CONFIG_SECCOMP is not set 7959+# CONFIG_PARAVIRT is not set 7960+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set 7961+# CONFIG_XEN is not set 7962+ 7963+# 7964+# Boot options 7965+# 7966+CONFIG_USE_OF=y 7967+CONFIG_ATAGS=y 7968+# CONFIG_DEPRECATED_PARAM_STRUCT is not set 7969+CONFIG_ZBOOT_ROM_TEXT=0 7970+CONFIG_ZBOOT_ROM_BSS=0 7971+CONFIG_ARM_APPENDED_DTB=y 7972+CONFIG_ARM_ATAG_DTB_COMPAT=y 7973+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y 7974+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set 7975+CONFIG_CMDLINE="" 7976+# CONFIG_KEXEC is not set 7977+# CONFIG_CRASH_DUMP is not set 7978+CONFIG_AUTO_ZRELADDR=y 7979+# CONFIG_EFI is not set 7980+ 7981+# 7982+# CPU Power Management 7983+# 7984+ 7985+# 7986+# CPU Frequency scaling 7987+# 7988+# CONFIG_CPU_FREQ is not set 7989+ 7990+# 7991+# CPU Idle 7992+# 7993+# CONFIG_CPU_IDLE is not set 7994+ 7995+# 7996+# Floating point emulation 7997+# 7998+ 7999+# 8000+# At least one emulation must be selected 8001+# 8002+# CONFIG_FPE_NWFPE is not set 8003+# CONFIG_FPE_FASTFPE is not set 8004+CONFIG_VFP=y 8005+CONFIG_VFPv3=y 8006+CONFIG_NEON=y 8007+CONFIG_KERNEL_MODE_NEON=y 8008+ 8009+# 8010+# Power management options 8011+# 8012+CONFIG_SUSPEND=y 8013+CONFIG_SUSPEND_FREEZER=y 8014+CONFIG_PM_SLEEP=y 8015+CONFIG_PM_SLEEP_SMP=y 8016+# CONFIG_PM_AUTOSLEEP is not set 8017+# CONFIG_PM_WAKELOCKS is not set 8018+CONFIG_PM=y 8019+# CONFIG_PM_DEBUG is not set 8020+# CONFIG_APM_EMULATION is not set 8021+CONFIG_PM_CLK=y 8022+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set 8023+CONFIG_CPU_PM=y 8024+CONFIG_ARCH_SUSPEND_POSSIBLE=y 8025+CONFIG_ARM_CPU_SUSPEND=y 8026+CONFIG_ARCH_HIBERNATION_POSSIBLE=y 8027+ 8028+# 8029+# Firmware Drivers 8030+# 8031+# CONFIG_FW_CFG_SYSFS is not set 8032+CONFIG_HAVE_ARM_SMCCC=y 8033+# CONFIG_GOOGLE_FIRMWARE is not set 8034+ 8035+# 8036+# Tegra firmware driver 8037+# 8038+# CONFIG_ARM_CRYPTO is not set 8039+# CONFIG_VIRTUALIZATION is not set 8040+ 8041+# 8042+# General architecture-dependent options 8043+# 8044+CONFIG_HAVE_OPROFILE=y 8045+# CONFIG_KPROBES is not set 8046+# CONFIG_JUMP_LABEL is not set 8047+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y 8048+CONFIG_ARCH_USE_BUILTIN_BSWAP=y 8049+CONFIG_HAVE_KPROBES=y 8050+CONFIG_HAVE_KRETPROBES=y 8051+CONFIG_HAVE_OPTPROBES=y 8052+CONFIG_HAVE_NMI=y 8053+CONFIG_HAVE_ARCH_TRACEHOOK=y 8054+CONFIG_HAVE_DMA_CONTIGUOUS=y 8055+CONFIG_GENERIC_SMP_IDLE_THREAD=y 8056+CONFIG_GENERIC_IDLE_POLL_SETUP=y 8057+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y 8058+CONFIG_ARCH_HAS_SET_MEMORY=y 8059+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y 8060+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y 8061+CONFIG_HAVE_RSEQ=y 8062+CONFIG_HAVE_CLK=y 8063+CONFIG_HAVE_PERF_REGS=y 8064+CONFIG_HAVE_PERF_USER_STACK_DUMP=y 8065+CONFIG_HAVE_ARCH_JUMP_LABEL=y 8066+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y 8067+CONFIG_HAVE_STACKPROTECTOR=y 8068+CONFIG_CC_HAS_STACKPROTECTOR_NONE=y 8069+CONFIG_STACKPROTECTOR=y 8070+CONFIG_STACKPROTECTOR_STRONG=y 8071+CONFIG_HAVE_CONTEXT_TRACKING=y 8072+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y 8073+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y 8074+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y 8075+CONFIG_MODULES_USE_ELF_REL=y 8076+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y 8077+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y 8078+CONFIG_HAVE_EXIT_THREAD=y 8079+CONFIG_ARCH_MMAP_RND_BITS=8 8080+CONFIG_CLONE_BACKWARDS=y 8081+CONFIG_OLD_SIGSUSPEND3=y 8082+CONFIG_OLD_SIGACTION=y 8083+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y 8084+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y 8085+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y 8086+CONFIG_STRICT_KERNEL_RWX=y 8087+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y 8088+CONFIG_STRICT_MODULE_RWX=y 8089+CONFIG_ARCH_HAS_PHYS_TO_DMA=y 8090+CONFIG_REFCOUNT_FULL=y 8091+ 8092+# 8093+# GCOV-based kernel profiling 8094+# 8095+# CONFIG_GCOV_KERNEL is not set 8096+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y 8097+CONFIG_PLUGIN_HOSTCC="" 8098+CONFIG_HAVE_GCC_PLUGINS=y 8099+CONFIG_RT_MUTEXES=y 8100+CONFIG_BASE_SMALL=0 8101+CONFIG_MODULES=y 8102+CONFIG_MODULE_FORCE_LOAD=y 8103+CONFIG_MODULE_UNLOAD=y 8104+CONFIG_MODULE_FORCE_UNLOAD=y 8105+# CONFIG_MODVERSIONS is not set 8106+# CONFIG_MODULE_SRCVERSION_ALL is not set 8107+# CONFIG_MODULE_SIG is not set 8108+# CONFIG_MODULE_COMPRESS is not set 8109+# CONFIG_TRIM_UNUSED_KSYMS is not set 8110+CONFIG_BLOCK=y 8111+CONFIG_LBDAF=y 8112+CONFIG_BLK_SCSI_REQUEST=y 8113+CONFIG_BLK_DEV_BSG=y 8114+# CONFIG_BLK_DEV_BSGLIB is not set 8115+# CONFIG_BLK_DEV_INTEGRITY is not set 8116+# CONFIG_BLK_DEV_ZONED is not set 8117+CONFIG_BLK_CMDLINE_PARSER=y 8118+# CONFIG_BLK_WBT is not set 8119+# CONFIG_BLK_DEBUG_FS is not set 8120+# CONFIG_BLK_SED_OPAL is not set 8121+ 8122+# 8123+# Partition Types 8124+# 8125+CONFIG_PARTITION_ADVANCED=y 8126+# CONFIG_ACORN_PARTITION is not set 8127+# CONFIG_AIX_PARTITION is not set 8128+# CONFIG_OSF_PARTITION is not set 8129+# CONFIG_AMIGA_PARTITION is not set 8130+# CONFIG_ATARI_PARTITION is not set 8131+# CONFIG_MAC_PARTITION is not set 8132+CONFIG_MSDOS_PARTITION=y 8133+# CONFIG_BSD_DISKLABEL is not set 8134+# CONFIG_MINIX_SUBPARTITION is not set 8135+# CONFIG_SOLARIS_X86_PARTITION is not set 8136+# CONFIG_UNIXWARE_DISKLABEL is not set 8137+# CONFIG_LDM_PARTITION is not set 8138+# CONFIG_SGI_PARTITION is not set 8139+# CONFIG_ULTRIX_PARTITION is not set 8140+# CONFIG_SUN_PARTITION is not set 8141+# CONFIG_KARMA_PARTITION is not set 8142+CONFIG_EFI_PARTITION=y 8143+# CONFIG_SYSV68_PARTITION is not set 8144+CONFIG_CMDLINE_PARTITION=y 8145+ 8146+# 8147+# IO Schedulers 8148+# 8149+CONFIG_IOSCHED_NOOP=y 8150+# CONFIG_IOSCHED_DEADLINE is not set 8151+CONFIG_IOSCHED_CFQ=y 8152+CONFIG_DEFAULT_CFQ=y 8153+# CONFIG_DEFAULT_NOOP is not set 8154+CONFIG_DEFAULT_IOSCHED="cfq" 8155+CONFIG_MQ_IOSCHED_DEADLINE=y 8156+CONFIG_MQ_IOSCHED_KYBER=y 8157+# CONFIG_IOSCHED_BFQ is not set 8158+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y 8159+CONFIG_INLINE_READ_UNLOCK=y 8160+CONFIG_INLINE_READ_UNLOCK_IRQ=y 8161+CONFIG_INLINE_WRITE_UNLOCK=y 8162+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y 8163+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y 8164+CONFIG_MUTEX_SPIN_ON_OWNER=y 8165+CONFIG_RWSEM_SPIN_ON_OWNER=y 8166+CONFIG_LOCK_SPIN_ON_OWNER=y 8167+CONFIG_FREEZER=y 8168+ 8169+# 8170+# Executable file formats 8171+# 8172+CONFIG_BINFMT_ELF=y 8173+# CONFIG_BINFMT_ELF_FDPIC is not set 8174+CONFIG_ELFCORE=y 8175+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y 8176+CONFIG_BINFMT_SCRIPT=y 8177+# CONFIG_BINFMT_FLAT is not set 8178+# CONFIG_BINFMT_MISC is not set 8179+CONFIG_COREDUMP=y 8180+ 8181+# 8182+# Memory Management options 8183+# 8184+CONFIG_FLATMEM=y 8185+CONFIG_FLAT_NODE_MEM_MAP=y 8186+CONFIG_HAVE_MEMBLOCK=y 8187+CONFIG_NO_BOOTMEM=y 8188+CONFIG_MEMORY_ISOLATION=y 8189+CONFIG_SPLIT_PTLOCK_CPUS=4 8190+CONFIG_COMPACTION=y 8191+CONFIG_MIGRATION=y 8192+CONFIG_BOUNCE=y 8193+# CONFIG_KSM is not set 8194+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 8195+# CONFIG_CLEANCACHE is not set 8196+CONFIG_CMA=y 8197+CONFIG_CMA_DEBUG=y 8198+# CONFIG_CMA_DEBUGFS is not set 8199+CONFIG_CMA_AREAS=7 8200+# CONFIG_ZPOOL is not set 8201+# CONFIG_ZBUD is not set 8202+# CONFIG_ZSMALLOC is not set 8203+CONFIG_GENERIC_EARLY_IOREMAP=y 8204+# CONFIG_IDLE_PAGE_TRACKING is not set 8205+CONFIG_FRAME_VECTOR=y 8206+# CONFIG_PERCPU_STATS is not set 8207+# CONFIG_GUP_BENCHMARK is not set 8208+CONFIG_NET=y 8209+ 8210+# 8211+# Networking options 8212+# 8213+CONFIG_PACKET=y 8214+# CONFIG_PACKET_DIAG is not set 8215+CONFIG_UNIX=y 8216+# CONFIG_UNIX_DIAG is not set 8217+# CONFIG_TLS is not set 8218+CONFIG_XFRM=y 8219+# CONFIG_XFRM_USER is not set 8220+# CONFIG_XFRM_INTERFACE is not set 8221+# CONFIG_XFRM_SUB_POLICY is not set 8222+# CONFIG_XFRM_MIGRATE is not set 8223+# CONFIG_XFRM_STATISTICS is not set 8224+# CONFIG_NET_KEY is not set 8225+CONFIG_INET=y 8226+# CONFIG_IP_MULTICAST is not set 8227+# CONFIG_IP_ADVANCED_ROUTER is not set 8228+CONFIG_IP_PNP=y 8229+CONFIG_IP_PNP_DHCP=y 8230+# CONFIG_IP_PNP_BOOTP is not set 8231+# CONFIG_IP_PNP_RARP is not set 8232+# CONFIG_NET_IPIP is not set 8233+# CONFIG_NET_IPGRE_DEMUX is not set 8234+# CONFIG_SYN_COOKIES is not set 8235+# CONFIG_NET_IPVTI is not set 8236+# CONFIG_NET_FOU is not set 8237+# CONFIG_INET_AH is not set 8238+# CONFIG_INET_ESP is not set 8239+# CONFIG_INET_IPCOMP is not set 8240+CONFIG_INET_XFRM_MODE_TRANSPORT=y 8241+CONFIG_INET_XFRM_MODE_TUNNEL=y 8242+CONFIG_INET_XFRM_MODE_BEET=y 8243+CONFIG_INET_DIAG=y 8244+CONFIG_INET_TCP_DIAG=y 8245+# CONFIG_INET_UDP_DIAG is not set 8246+# CONFIG_INET_RAW_DIAG is not set 8247+# CONFIG_INET_DIAG_DESTROY is not set 8248+# CONFIG_TCP_CONG_ADVANCED is not set 8249+CONFIG_TCP_CONG_CUBIC=y 8250+CONFIG_DEFAULT_TCP_CONG="cubic" 8251+# CONFIG_TCP_MD5SIG is not set 8252+CONFIG_IPV6=y 8253+# CONFIG_IPV6_ROUTER_PREF is not set 8254+# CONFIG_IPV6_OPTIMISTIC_DAD is not set 8255+# CONFIG_INET6_AH is not set 8256+# CONFIG_INET6_ESP is not set 8257+# CONFIG_INET6_IPCOMP is not set 8258+# CONFIG_IPV6_MIP6 is not set 8259+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set 8260+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set 8261+# CONFIG_INET6_XFRM_MODE_BEET is not set 8262+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 8263+# CONFIG_IPV6_SIT is not set 8264+# CONFIG_IPV6_TUNNEL is not set 8265+# CONFIG_IPV6_MULTIPLE_TABLES is not set 8266+# CONFIG_IPV6_MROUTE is not set 8267+# CONFIG_IPV6_SEG6_LWTUNNEL is not set 8268+# CONFIG_IPV6_SEG6_HMAC is not set 8269+# CONFIG_NETWORK_SECMARK is not set 8270+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set 8271+# CONFIG_NETFILTER is not set 8272+# CONFIG_BPFILTER is not set 8273+# CONFIG_IP_DCCP is not set 8274+# CONFIG_IP_SCTP is not set 8275+# CONFIG_RDS is not set 8276+# CONFIG_TIPC is not set 8277+# CONFIG_ATM is not set 8278+# CONFIG_L2TP is not set 8279+# CONFIG_BRIDGE is not set 8280+CONFIG_HAVE_NET_DSA=y 8281+# CONFIG_NET_DSA is not set 8282+CONFIG_VLAN_8021Q=y 8283+# CONFIG_VLAN_8021Q_GVRP is not set 8284+# CONFIG_VLAN_8021Q_MVRP is not set 8285+# CONFIG_DECNET is not set 8286+# CONFIG_LLC2 is not set 8287+# CONFIG_ATALK is not set 8288+# CONFIG_X25 is not set 8289+# CONFIG_LAPB is not set 8290+# CONFIG_PHONET is not set 8291+# CONFIG_6LOWPAN is not set 8292+# CONFIG_IEEE802154 is not set 8293+# CONFIG_NET_SCHED is not set 8294+# CONFIG_DCB is not set 8295+CONFIG_DNS_RESOLVER=y 8296+# CONFIG_BATMAN_ADV is not set 8297+# CONFIG_OPENVSWITCH is not set 8298+# CONFIG_VSOCKETS is not set 8299+# CONFIG_NETLINK_DIAG is not set 8300+# CONFIG_MPLS is not set 8301+# CONFIG_NET_NSH is not set 8302+# CONFIG_HSR is not set 8303+# CONFIG_NET_SWITCHDEV is not set 8304+# CONFIG_NET_L3_MASTER_DEV is not set 8305+# CONFIG_NET_NCSI is not set 8306+CONFIG_RPS=y 8307+CONFIG_RFS_ACCEL=y 8308+CONFIG_XPS=y 8309+# CONFIG_CGROUP_NET_PRIO is not set 8310+# CONFIG_CGROUP_NET_CLASSID is not set 8311+CONFIG_NET_RX_BUSY_POLL=y 8312+CONFIG_BQL=y 8313+# CONFIG_BPF_JIT is not set 8314+CONFIG_NET_FLOW_LIMIT=y 8315+ 8316+# 8317+# Network testing 8318+# 8319+# CONFIG_NET_PKTGEN is not set 8320+# CONFIG_HAMRADIO is not set 8321+# CONFIG_CAN is not set 8322+# CONFIG_BT is not set 8323+# CONFIG_AF_RXRPC is not set 8324+# CONFIG_AF_KCM is not set 8325+CONFIG_WIRELESS=y 8326+# CONFIG_CFG80211 is not set 8327+ 8328+# 8329+# CFG80211 needs to be enabled for MAC80211 8330+# 8331+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 8332+# CONFIG_WIMAX is not set 8333+# CONFIG_RFKILL is not set 8334+# CONFIG_NET_9P is not set 8335+# CONFIG_CAIF is not set 8336+# CONFIG_CEPH_LIB is not set 8337+# CONFIG_NFC is not set 8338+# CONFIG_PSAMPLE is not set 8339+# CONFIG_NET_IFE is not set 8340+# CONFIG_LWTUNNEL is not set 8341+CONFIG_GRO_CELLS=y 8342+# CONFIG_NET_DEVLINK is not set 8343+CONFIG_MAY_USE_DEVLINK=y 8344+# CONFIG_FAILOVER is not set 8345+CONFIG_HAVE_EBPF_JIT=y 8346+ 8347+# 8348+# Device Drivers 8349+# 8350+CONFIG_ARM_AMBA=y 8351+ 8352+# 8353+# Generic Driver Options 8354+# 8355+CONFIG_UEVENT_HELPER=y 8356+CONFIG_UEVENT_HELPER_PATH="" 8357+CONFIG_DEVTMPFS=y 8358+CONFIG_DEVTMPFS_MOUNT=y 8359+CONFIG_STANDALONE=y 8360+CONFIG_PREVENT_FIRMWARE_BUILD=y 8361+ 8362+# 8363+# Firmware loader 8364+# 8365+CONFIG_FW_LOADER=y 8366+CONFIG_EXTRA_FIRMWARE="" 8367+# CONFIG_FW_LOADER_USER_HELPER is not set 8368+CONFIG_ALLOW_DEV_COREDUMP=y 8369+# CONFIG_DEBUG_DRIVER is not set 8370+# CONFIG_DEBUG_DEVRES is not set 8371+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set 8372+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set 8373+CONFIG_GENERIC_CPU_AUTOPROBE=y 8374+CONFIG_REGMAP=y 8375+CONFIG_REGMAP_I2C=y 8376+CONFIG_REGMAP_SPI=y 8377+CONFIG_REGMAP_MMIO=y 8378+CONFIG_DMA_SHARED_BUFFER=y 8379+# CONFIG_DMA_FENCE_TRACE is not set 8380+CONFIG_DMA_CMA=y 8381+ 8382+# 8383+# Default contiguous memory area size: 8384+# 8385+CONFIG_CMA_SIZE_MBYTES=16 8386+CONFIG_CMA_SIZE_SEL_MBYTES=y 8387+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set 8388+# CONFIG_CMA_SIZE_SEL_MIN is not set 8389+# CONFIG_CMA_SIZE_SEL_MAX is not set 8390+CONFIG_CMA_ALIGNMENT=8 8391+CONFIG_GENERIC_ARCH_TOPOLOGY=y 8392+ 8393+# 8394+# Bus devices 8395+# 8396+# CONFIG_BRCMSTB_GISB_ARB is not set 8397+# CONFIG_SIMPLE_PM_BUS is not set 8398+# CONFIG_VEXPRESS_CONFIG is not set 8399+# CONFIG_CONNECTOR is not set 8400+# CONFIG_GNSS is not set 8401+CONFIG_MTD=y 8402+# CONFIG_MTD_TESTS is not set 8403+# CONFIG_MTD_REDBOOT_PARTS is not set 8404+CONFIG_MTD_CMDLINE_PARTS=y 8405+# CONFIG_MTD_AFS_PARTS is not set 8406+CONFIG_MTD_OF_PARTS=y 8407+# CONFIG_MTD_AR7_PARTS is not set 8408+ 8409+# 8410+# Partition parsers 8411+# 8412+ 8413+# 8414+# User Modules And Translation Layers 8415+# 8416+CONFIG_MTD_BLKDEVS=y 8417+CONFIG_MTD_BLOCK=y 8418+# CONFIG_FTL is not set 8419+# CONFIG_NFTL is not set 8420+# CONFIG_INFTL is not set 8421+# CONFIG_RFD_FTL is not set 8422+# CONFIG_SSFDC is not set 8423+# CONFIG_SM_FTL is not set 8424+# CONFIG_MTD_OOPS is not set 8425+# CONFIG_MTD_PARTITIONED_MASTER is not set 8426+ 8427+# 8428+# RAM/ROM/Flash chip drivers 8429+# 8430+# CONFIG_MTD_CFI is not set 8431+# CONFIG_MTD_JEDECPROBE is not set 8432+CONFIG_MTD_MAP_BANK_WIDTH_1=y 8433+CONFIG_MTD_MAP_BANK_WIDTH_2=y 8434+CONFIG_MTD_MAP_BANK_WIDTH_4=y 8435+CONFIG_MTD_CFI_I1=y 8436+CONFIG_MTD_CFI_I2=y 8437+# CONFIG_MTD_RAM is not set 8438+# CONFIG_MTD_ROM is not set 8439+# CONFIG_MTD_ABSENT is not set 8440+ 8441+# 8442+# Mapping drivers for chip access 8443+# 8444+# CONFIG_MTD_COMPLEX_MAPPINGS is not set 8445+# CONFIG_MTD_PLATRAM is not set 8446+ 8447+# 8448+# Self-contained MTD device drivers 8449+# 8450+# CONFIG_MTD_DATAFLASH is not set 8451+# CONFIG_MTD_M25P80 is not set 8452+# CONFIG_MTD_MCHP23K256 is not set 8453+# CONFIG_MTD_SST25L is not set 8454+# CONFIG_MTD_SLRAM is not set 8455+# CONFIG_MTD_PHRAM is not set 8456+# CONFIG_MTD_MTDRAM is not set 8457+# CONFIG_MTD_BLOCK2MTD is not set 8458+ 8459+# 8460+# Disk-On-Chip Device Drivers 8461+# 8462+# CONFIG_MTD_DOCG3 is not set 8463+# CONFIG_MTD_ONENAND is not set 8464+CONFIG_MTD_SPI_NAND_HISI_BVT=y 8465+# CONFIG_HISI_NAND_ECC_STATUS_REPORT is not set 8466+# CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 is not set 8467+CONFIG_MTD_NAND_ECC=y 8468+# CONFIG_MTD_NAND_ECC_SMC is not set 8469+CONFIG_MTD_NAND=y 8470+# CONFIG_MTD_NAND_ECC_BCH is not set 8471+# CONFIG_MTD_NAND_DENALI_DT is not set 8472+# CONFIG_MTD_NAND_GPIO is not set 8473+# CONFIG_MTD_NAND_DISKONCHIP is not set 8474+# CONFIG_MTD_NAND_DOCG4 is not set 8475+# CONFIG_MTD_NAND_NANDSIM is not set 8476+# CONFIG_MTD_NAND_BRCMNAND is not set 8477+# CONFIG_MTD_NAND_PLATFORM is not set 8478+CONFIG_MTD_SPI_NAND_HIFMC100=y 8479+# CONFIG_MTD_SPI_NAND is not set 8480+ 8481+# 8482+# LPDDR & LPDDR2 PCM memory drivers 8483+# 8484+# CONFIG_MTD_LPDDR is not set 8485+# CONFIG_MTD_LPDDR2_NVM is not set 8486+CONFIG_MTD_SPI_NOR=y 8487+# CONFIG_MTD_MT81xx_NOR is not set 8488+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set 8489+# CONFIG_SPI_CADENCE_QUADSPI is not set 8490+CONFIG_SPI_HISI_SFC=y 8491+# CONFIG_MTD_SPI_IDS is not set 8492+# CONFIG_CLOSE_SPI_8PIN_4IO is not set 8493+CONFIG_HISI_SPI_BLOCK_PROTECT=y 8494+CONFIG_MTD_UBI=y 8495+CONFIG_MTD_UBI_WL_THRESHOLD=4096 8496+CONFIG_MTD_UBI_BEB_LIMIT=20 8497+# CONFIG_MTD_UBI_FASTMAP is not set 8498+# CONFIG_MTD_UBI_GLUEBI is not set 8499+# CONFIG_MTD_UBI_BLOCK is not set 8500+CONFIG_DTC=y 8501+CONFIG_OF=y 8502+# CONFIG_OF_UNITTEST is not set 8503+CONFIG_OF_FLATTREE=y 8504+CONFIG_OF_EARLY_FLATTREE=y 8505+CONFIG_OF_KOBJ=y 8506+CONFIG_OF_ADDRESS=y 8507+CONFIG_OF_IRQ=y 8508+CONFIG_OF_NET=y 8509+CONFIG_OF_MDIO=y 8510+CONFIG_OF_RESERVED_MEM=y 8511+# CONFIG_OF_OVERLAY is not set 8512+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y 8513+# CONFIG_PARPORT is not set 8514+CONFIG_BLK_DEV=y 8515+# CONFIG_BLK_DEV_NULL_BLK is not set 8516+# CONFIG_BLK_DEV_LOOP is not set 8517+# CONFIG_BLK_DEV_DRBD is not set 8518+# CONFIG_BLK_DEV_NBD is not set 8519+CONFIG_BLK_DEV_RAM=y 8520+CONFIG_BLK_DEV_RAM_COUNT=16 8521+CONFIG_BLK_DEV_RAM_SIZE=65536 8522+# CONFIG_CDROM_PKTCDVD is not set 8523+# CONFIG_ATA_OVER_ETH is not set 8524+# CONFIG_BLK_DEV_RBD is not set 8525+ 8526+# 8527+# NVME Support 8528+# 8529+# CONFIG_NVME_FC is not set 8530+# CONFIG_NVME_TARGET is not set 8531+ 8532+# 8533+# Misc devices 8534+# 8535+# CONFIG_AD525X_DPOT is not set 8536+# CONFIG_DUMMY_IRQ is not set 8537+# CONFIG_ICS932S401 is not set 8538+# CONFIG_ENCLOSURE_SERVICES is not set 8539+# CONFIG_APDS9802ALS is not set 8540+# CONFIG_ISL29003 is not set 8541+# CONFIG_ISL29020 is not set 8542+# CONFIG_SENSORS_TSL2550 is not set 8543+# CONFIG_SENSORS_BH1770 is not set 8544+# CONFIG_SENSORS_APDS990X is not set 8545+# CONFIG_HMC6352 is not set 8546+# CONFIG_DS1682 is not set 8547+# CONFIG_USB_SWITCH_FSA9480 is not set 8548+# CONFIG_LATTICE_ECP3_CONFIG is not set 8549+# CONFIG_SRAM is not set 8550+# CONFIG_C2PORT is not set 8551+ 8552+# 8553+# EEPROM support 8554+# 8555+# CONFIG_EEPROM_AT24 is not set 8556+# CONFIG_EEPROM_AT25 is not set 8557+# CONFIG_EEPROM_LEGACY is not set 8558+# CONFIG_EEPROM_MAX6875 is not set 8559+# CONFIG_EEPROM_93CX6 is not set 8560+# CONFIG_EEPROM_93XX46 is not set 8561+# CONFIG_EEPROM_IDT_89HPESX is not set 8562+ 8563+# 8564+# Texas Instruments shared transport line discipline 8565+# 8566+# CONFIG_TI_ST is not set 8567+# CONFIG_SENSORS_LIS3_SPI is not set 8568+# CONFIG_SENSORS_LIS3_I2C is not set 8569+# CONFIG_ALTERA_STAPL is not set 8570+ 8571+# 8572+# Intel MIC & related support 8573+# 8574+ 8575+# 8576+# Intel MIC Bus Driver 8577+# 8578+ 8579+# 8580+# SCIF Bus Driver 8581+# 8582+ 8583+# 8584+# VOP Bus Driver 8585+# 8586+ 8587+# 8588+# Intel MIC Host Driver 8589+# 8590+ 8591+# 8592+# Intel MIC Card Driver 8593+# 8594+ 8595+# 8596+# SCIF Driver 8597+# 8598+ 8599+# 8600+# Intel MIC Coprocessor State Management (COSM) Drivers 8601+# 8602+ 8603+# 8604+# VOP Driver 8605+# 8606+# CONFIG_ECHO is not set 8607+# CONFIG_MISC_RTSX_USB is not set 8608+ 8609+# 8610+# SCSI device support 8611+# 8612+CONFIG_SCSI_MOD=y 8613+# CONFIG_RAID_ATTRS is not set 8614+CONFIG_SCSI=y 8615+CONFIG_SCSI_DMA=y 8616+# CONFIG_SCSI_MQ_DEFAULT is not set 8617+CONFIG_SCSI_PROC_FS=y 8618+ 8619+# 8620+# SCSI support type (disk, tape, CD-ROM) 8621+# 8622+CONFIG_BLK_DEV_SD=y 8623+# CONFIG_CHR_DEV_ST is not set 8624+# CONFIG_CHR_DEV_OSST is not set 8625+# CONFIG_BLK_DEV_SR is not set 8626+# CONFIG_CHR_DEV_SG is not set 8627+# CONFIG_CHR_DEV_SCH is not set 8628+# CONFIG_SCSI_CONSTANTS is not set 8629+# CONFIG_SCSI_LOGGING is not set 8630+# CONFIG_SCSI_SCAN_ASYNC is not set 8631+ 8632+# 8633+# SCSI Transports 8634+# 8635+# CONFIG_SCSI_SPI_ATTRS is not set 8636+# CONFIG_SCSI_FC_ATTRS is not set 8637+# CONFIG_SCSI_ISCSI_ATTRS is not set 8638+# CONFIG_SCSI_SAS_ATTRS is not set 8639+# CONFIG_SCSI_SAS_LIBSAS is not set 8640+# CONFIG_SCSI_SRP_ATTRS is not set 8641+CONFIG_SCSI_LOWLEVEL=y 8642+# CONFIG_ISCSI_TCP is not set 8643+# CONFIG_ISCSI_BOOT_SYSFS is not set 8644+# CONFIG_SCSI_UFSHCD is not set 8645+# CONFIG_SCSI_DEBUG is not set 8646+# CONFIG_SCSI_DH is not set 8647+# CONFIG_SCSI_OSD_INITIATOR is not set 8648+# CONFIG_ATA is not set 8649+# CONFIG_MD is not set 8650+# CONFIG_TARGET_CORE is not set 8651+CONFIG_NETDEVICES=y 8652+CONFIG_MII=y 8653+CONFIG_NET_CORE=y 8654+# CONFIG_BONDING is not set 8655+# CONFIG_DUMMY is not set 8656+# CONFIG_EQUALIZER is not set 8657+# CONFIG_NET_TEAM is not set 8658+# CONFIG_MACVLAN is not set 8659+# CONFIG_VXLAN is not set 8660+# CONFIG_GENEVE is not set 8661+# CONFIG_GTP is not set 8662+# CONFIG_MACSEC is not set 8663+# CONFIG_NETCONSOLE is not set 8664+# CONFIG_TUN is not set 8665+# CONFIG_TUN_VNET_CROSS_LE is not set 8666+# CONFIG_VETH is not set 8667+# CONFIG_NLMON is not set 8668+ 8669+# 8670+# CAIF transport drivers 8671+# 8672+ 8673+# 8674+# Distributed Switch Architecture drivers 8675+# 8676+CONFIG_ETHERNET=y 8677+CONFIG_NET_VENDOR_ALACRITECH=y 8678+# CONFIG_ALTERA_TSE is not set 8679+# CONFIG_NET_VENDOR_AMAZON is not set 8680+CONFIG_NET_VENDOR_AQUANTIA=y 8681+# CONFIG_NET_VENDOR_ARC is not set 8682+# CONFIG_NET_VENDOR_AURORA is not set 8683+# CONFIG_NET_VENDOR_BROADCOM is not set 8684+CONFIG_NET_VENDOR_CADENCE=y 8685+# CONFIG_MACB is not set 8686+CONFIG_NET_VENDOR_CAVIUM=y 8687+# CONFIG_NET_VENDOR_CIRRUS is not set 8688+CONFIG_NET_VENDOR_CORTINA=y 8689+# CONFIG_GEMINI_ETHERNET is not set 8690+# CONFIG_DM9000 is not set 8691+# CONFIG_DNET is not set 8692+# CONFIG_NET_VENDOR_EZCHIP is not set 8693+# CONFIG_NET_VENDOR_FARADAY is not set 8694+CONFIG_NET_VENDOR_HISILICON=y 8695+# CONFIG_HIX5HD2_GMAC is not set 8696+CONFIG_HISI_FEMAC=y 8697+# CONFIG_HIP04_ETH is not set 8698+# CONFIG_HNS is not set 8699+# CONFIG_HNS_DSAF is not set 8700+# CONFIG_HNS_ENET is not set 8701+# CONFIG_HIETH_GMAC is not set 8702+CONFIG_NET_VENDOR_HUAWEI=y 8703+# CONFIG_NET_VENDOR_INTEL is not set 8704+# CONFIG_NET_VENDOR_MARVELL is not set 8705+CONFIG_NET_VENDOR_MELLANOX=y 8706+# CONFIG_MLXSW_CORE is not set 8707+# CONFIG_MLXFW is not set 8708+# CONFIG_NET_VENDOR_MICREL is not set 8709+# CONFIG_NET_VENDOR_MICROCHIP is not set 8710+CONFIG_NET_VENDOR_MICROSEMI=y 8711+# CONFIG_NET_VENDOR_NATSEMI is not set 8712+# CONFIG_NET_VENDOR_NETRONOME is not set 8713+CONFIG_NET_VENDOR_NI=y 8714+# CONFIG_ETHOC is not set 8715+# CONFIG_NET_VENDOR_QUALCOMM is not set 8716+# CONFIG_NET_VENDOR_RENESAS is not set 8717+# CONFIG_NET_VENDOR_ROCKER is not set 8718+# CONFIG_NET_VENDOR_SAMSUNG is not set 8719+# CONFIG_NET_VENDOR_SEEQ is not set 8720+CONFIG_NET_VENDOR_SOLARFLARE=y 8721+# CONFIG_NET_VENDOR_SMSC is not set 8722+CONFIG_NET_VENDOR_SOCIONEXT=y 8723+# CONFIG_NET_VENDOR_STMICRO is not set 8724+# CONFIG_NET_VENDOR_SYNOPSYS is not set 8725+# CONFIG_NET_VENDOR_VIA is not set 8726+# CONFIG_NET_VENDOR_WIZNET is not set 8727+CONFIG_MDIO_DEVICE=y 8728+CONFIG_MDIO_BUS=y 8729+# CONFIG_MDIO_BCM_UNIMAC is not set 8730+# CONFIG_MDIO_BITBANG is not set 8731+# CONFIG_MDIO_BUS_MUX_GPIO is not set 8732+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set 8733+CONFIG_MDIO_HISI_FEMAC=y 8734+# CONFIG_MDIO_HISI_GEMAC is not set 8735+# CONFIG_MDIO_MSCC_MIIM is not set 8736+CONFIG_PHYLIB=y 8737+CONFIG_SWPHY=y 8738+ 8739+# 8740+# MII PHY device drivers 8741+# 8742+# CONFIG_AMD_PHY is not set 8743+# CONFIG_AQUANTIA_PHY is not set 8744+# CONFIG_AX88796B_PHY is not set 8745+# CONFIG_AT803X_PHY is not set 8746+# CONFIG_BCM7XXX_PHY is not set 8747+# CONFIG_BCM87XX_PHY is not set 8748+# CONFIG_BROADCOM_PHY is not set 8749+# CONFIG_CICADA_PHY is not set 8750+# CONFIG_CORTINA_PHY is not set 8751+# CONFIG_DAVICOM_PHY is not set 8752+# CONFIG_DP83822_PHY is not set 8753+# CONFIG_DP83TC811_PHY is not set 8754+# CONFIG_DP83848_PHY is not set 8755+# CONFIG_DP83867_PHY is not set 8756+CONFIG_FIXED_PHY=y 8757+# CONFIG_ICPLUS_PHY is not set 8758+# CONFIG_INTEL_XWAY_PHY is not set 8759+# CONFIG_LSI_ET1011C_PHY is not set 8760+# CONFIG_LXT_PHY is not set 8761+# CONFIG_MARVELL_PHY is not set 8762+# CONFIG_MARVELL_10G_PHY is not set 8763+# CONFIG_MICREL_PHY is not set 8764+# CONFIG_MICROCHIP_PHY is not set 8765+# CONFIG_MICROCHIP_T1_PHY is not set 8766+# CONFIG_MICROSEMI_PHY is not set 8767+# CONFIG_NATIONAL_PHY is not set 8768+# CONFIG_QSEMI_PHY is not set 8769+# CONFIG_REALTEK_PHY is not set 8770+# CONFIG_RENESAS_PHY is not set 8771+# CONFIG_ROCKCHIP_PHY is not set 8772+# CONFIG_SMSC_PHY is not set 8773+# CONFIG_STE10XP is not set 8774+# CONFIG_TERANETICS_PHY is not set 8775+# CONFIG_VITESSE_PHY is not set 8776+# CONFIG_XILINX_GMII2RGMII is not set 8777+# CONFIG_MICREL_KS8995MA is not set 8778+# CONFIG_PPP is not set 8779+# CONFIG_SLIP is not set 8780+CONFIG_USB_NET_DRIVERS=y 8781+# CONFIG_USB_CATC is not set 8782+# CONFIG_USB_KAWETH is not set 8783+# CONFIG_USB_PEGASUS is not set 8784+# CONFIG_USB_RTL8150 is not set 8785+CONFIG_USB_RTL8152=y 8786+# CONFIG_USB_LAN78XX is not set 8787+# CONFIG_USB_USBNET is not set 8788+# CONFIG_USB_IPHETH is not set 8789+CONFIG_WLAN=y 8790+CONFIG_WLAN_VENDOR_ADMTEK=y 8791+CONFIG_WLAN_VENDOR_ATH=y 8792+# CONFIG_ATH_DEBUG is not set 8793+CONFIG_WLAN_VENDOR_ATMEL=y 8794+CONFIG_WLAN_VENDOR_BROADCOM=y 8795+CONFIG_WLAN_VENDOR_CISCO=y 8796+CONFIG_WLAN_VENDOR_INTEL=y 8797+CONFIG_WLAN_VENDOR_INTERSIL=y 8798+# CONFIG_HOSTAP is not set 8799+CONFIG_WLAN_VENDOR_MARVELL=y 8800+CONFIG_WLAN_VENDOR_MEDIATEK=y 8801+CONFIG_WLAN_VENDOR_RALINK=y 8802+CONFIG_WLAN_VENDOR_REALTEK=y 8803+CONFIG_WLAN_VENDOR_RSI=y 8804+CONFIG_WLAN_VENDOR_ST=y 8805+CONFIG_WLAN_VENDOR_TI=y 8806+CONFIG_WLAN_VENDOR_ZYDAS=y 8807+CONFIG_WLAN_VENDOR_QUANTENNA=y 8808+ 8809+# 8810+# Enable WiMAX (Networking options) to see the WiMAX drivers 8811+# 8812+# CONFIG_WAN is not set 8813+# CONFIG_NETDEVSIM is not set 8814+# CONFIG_NET_FAILOVER is not set 8815+# CONFIG_ISDN is not set 8816+ 8817+# 8818+# Input device support 8819+# 8820+CONFIG_INPUT=y 8821+CONFIG_INPUT_FF_MEMLESS=y 8822+# CONFIG_INPUT_POLLDEV is not set 8823+# CONFIG_INPUT_SPARSEKMAP is not set 8824+# CONFIG_INPUT_MATRIXKMAP is not set 8825+ 8826+# 8827+# Userland interfaces 8828+# 8829+CONFIG_INPUT_MOUSEDEV=y 8830+CONFIG_INPUT_MOUSEDEV_PSAUX=y 8831+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 8832+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 8833+CONFIG_INPUT_JOYDEV=y 8834+CONFIG_INPUT_EVDEV=y 8835+# CONFIG_INPUT_EVBUG is not set 8836+ 8837+# 8838+# Input Device Drivers 8839+# 8840+CONFIG_INPUT_KEYBOARD=y 8841+# CONFIG_KEYBOARD_ADP5588 is not set 8842+# CONFIG_KEYBOARD_ADP5589 is not set 8843+CONFIG_KEYBOARD_ATKBD=y 8844+# CONFIG_KEYBOARD_QT1070 is not set 8845+# CONFIG_KEYBOARD_QT2160 is not set 8846+# CONFIG_KEYBOARD_DLINK_DIR685 is not set 8847+# CONFIG_KEYBOARD_LKKBD is not set 8848+# CONFIG_KEYBOARD_GPIO is not set 8849+# CONFIG_KEYBOARD_GPIO_POLLED is not set 8850+# CONFIG_KEYBOARD_TCA6416 is not set 8851+# CONFIG_KEYBOARD_TCA8418 is not set 8852+# CONFIG_KEYBOARD_MATRIX is not set 8853+# CONFIG_KEYBOARD_LM8333 is not set 8854+# CONFIG_KEYBOARD_MAX7359 is not set 8855+# CONFIG_KEYBOARD_MCS is not set 8856+# CONFIG_KEYBOARD_MPR121 is not set 8857+# CONFIG_KEYBOARD_NEWTON is not set 8858+# CONFIG_KEYBOARD_OPENCORES is not set 8859+# CONFIG_KEYBOARD_SAMSUNG is not set 8860+# CONFIG_KEYBOARD_STOWAWAY is not set 8861+# CONFIG_KEYBOARD_SUNKBD is not set 8862+# CONFIG_KEYBOARD_OMAP4 is not set 8863+# CONFIG_KEYBOARD_XTKBD is not set 8864+# CONFIG_KEYBOARD_CAP11XX is not set 8865+# CONFIG_KEYBOARD_BCM is not set 8866+CONFIG_INPUT_MOUSE=y 8867+CONFIG_MOUSE_PS2=y 8868+CONFIG_MOUSE_PS2_ALPS=y 8869+CONFIG_MOUSE_PS2_BYD=y 8870+CONFIG_MOUSE_PS2_LOGIPS2PP=y 8871+CONFIG_MOUSE_PS2_SYNAPTICS=y 8872+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y 8873+CONFIG_MOUSE_PS2_CYPRESS=y 8874+CONFIG_MOUSE_PS2_TRACKPOINT=y 8875+# CONFIG_MOUSE_PS2_ELANTECH is not set 8876+# CONFIG_MOUSE_PS2_SENTELIC is not set 8877+# CONFIG_MOUSE_PS2_TOUCHKIT is not set 8878+CONFIG_MOUSE_PS2_FOCALTECH=y 8879+CONFIG_MOUSE_PS2_SMBUS=y 8880+# CONFIG_MOUSE_SERIAL is not set 8881+# CONFIG_MOUSE_APPLETOUCH is not set 8882+# CONFIG_MOUSE_BCM5974 is not set 8883+# CONFIG_MOUSE_CYAPA is not set 8884+# CONFIG_MOUSE_ELAN_I2C is not set 8885+# CONFIG_MOUSE_VSXXXAA is not set 8886+# CONFIG_MOUSE_GPIO is not set 8887+# CONFIG_MOUSE_SYNAPTICS_I2C is not set 8888+# CONFIG_MOUSE_SYNAPTICS_USB is not set 8889+CONFIG_INPUT_JOYSTICK=y 8890+# CONFIG_JOYSTICK_ANALOG is not set 8891+# CONFIG_JOYSTICK_A3D is not set 8892+# CONFIG_JOYSTICK_ADI is not set 8893+# CONFIG_JOYSTICK_COBRA is not set 8894+# CONFIG_JOYSTICK_GF2K is not set 8895+# CONFIG_JOYSTICK_GRIP is not set 8896+# CONFIG_JOYSTICK_GRIP_MP is not set 8897+# CONFIG_JOYSTICK_GUILLEMOT is not set 8898+# CONFIG_JOYSTICK_INTERACT is not set 8899+# CONFIG_JOYSTICK_SIDEWINDER is not set 8900+# CONFIG_JOYSTICK_TMDC is not set 8901+# CONFIG_JOYSTICK_IFORCE is not set 8902+# CONFIG_JOYSTICK_WARRIOR is not set 8903+# CONFIG_JOYSTICK_MAGELLAN is not set 8904+# CONFIG_JOYSTICK_SPACEORB is not set 8905+# CONFIG_JOYSTICK_SPACEBALL is not set 8906+# CONFIG_JOYSTICK_STINGER is not set 8907+# CONFIG_JOYSTICK_TWIDJOY is not set 8908+# CONFIG_JOYSTICK_ZHENHUA is not set 8909+# CONFIG_JOYSTICK_AS5011 is not set 8910+# CONFIG_JOYSTICK_JOYDUMP is not set 8911+CONFIG_JOYSTICK_XPAD=y 8912+CONFIG_JOYSTICK_XPAD_FF=y 8913+# CONFIG_JOYSTICK_PSXPAD_SPI is not set 8914+# CONFIG_JOYSTICK_PXRC is not set 8915+# CONFIG_INPUT_TABLET is not set 8916+# CONFIG_INPUT_TOUCHSCREEN is not set 8917+# CONFIG_INPUT_MISC is not set 8918+# CONFIG_RMI4_CORE is not set 8919+ 8920+# 8921+# Hardware I/O ports 8922+# 8923+CONFIG_SERIO=y 8924+CONFIG_SERIO_SERPORT=y 8925+# CONFIG_SERIO_AMBAKMI is not set 8926+CONFIG_SERIO_LIBPS2=y 8927+# CONFIG_SERIO_RAW is not set 8928+# CONFIG_SERIO_ALTERA_PS2 is not set 8929+# CONFIG_SERIO_PS2MULT is not set 8930+# CONFIG_SERIO_ARC_PS2 is not set 8931+# CONFIG_SERIO_APBPS2 is not set 8932+# CONFIG_SERIO_GPIO_PS2 is not set 8933+# CONFIG_USERIO is not set 8934+# CONFIG_GAMEPORT is not set 8935+ 8936+# 8937+# Character devices 8938+# 8939+CONFIG_TTY=y 8940+CONFIG_VT=y 8941+CONFIG_CONSOLE_TRANSLATIONS=y 8942+CONFIG_VT_CONSOLE=y 8943+CONFIG_VT_CONSOLE_SLEEP=y 8944+CONFIG_HW_CONSOLE=y 8945+# CONFIG_VT_HW_CONSOLE_BINDING is not set 8946+CONFIG_UNIX98_PTYS=y 8947+# CONFIG_LEGACY_PTYS is not set 8948+# CONFIG_SERIAL_NONSTANDARD is not set 8949+# CONFIG_N_GSM is not set 8950+# CONFIG_TRACE_SINK is not set 8951+CONFIG_LDISC_AUTOLOAD=y 8952+CONFIG_DEVMEM=y 8953+CONFIG_DEVKMEM=y 8954+ 8955+# 8956+# Serial drivers 8957+# 8958+CONFIG_SERIAL_EARLYCON=y 8959+# CONFIG_SERIAL_8250 is not set 8960+ 8961+# 8962+# Non-8250 serial port support 8963+# 8964+# CONFIG_SERIAL_AMBA_PL010 is not set 8965+CONFIG_SERIAL_AMBA_PL011=y 8966+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y 8967+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set 8968+# CONFIG_SERIAL_MAX3100 is not set 8969+# CONFIG_SERIAL_MAX310X is not set 8970+# CONFIG_SERIAL_UARTLITE is not set 8971+CONFIG_SERIAL_CORE=y 8972+CONFIG_SERIAL_CORE_CONSOLE=y 8973+# CONFIG_SERIAL_SCCNXP is not set 8974+# CONFIG_SERIAL_SC16IS7XX is not set 8975+# CONFIG_SERIAL_BCM63XX is not set 8976+# CONFIG_SERIAL_ALTERA_JTAGUART is not set 8977+# CONFIG_SERIAL_ALTERA_UART is not set 8978+# CONFIG_SERIAL_IFX6X60 is not set 8979+# CONFIG_SERIAL_XILINX_PS_UART is not set 8980+# CONFIG_SERIAL_ARC is not set 8981+# CONFIG_SERIAL_FSL_LPUART is not set 8982+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set 8983+# CONFIG_SERIAL_ST_ASC is not set 8984+# CONFIG_SERIAL_DEV_BUS is not set 8985+# CONFIG_HVC_DCC is not set 8986+# CONFIG_IPMI_HANDLER is not set 8987+# CONFIG_HW_RANDOM is not set 8988+# CONFIG_RAW_DRIVER is not set 8989+# CONFIG_TCG_TPM is not set 8990+# CONFIG_XILLYBUS is not set 8991+ 8992+# 8993+# I2C support 8994+# 8995+CONFIG_I2C=y 8996+CONFIG_I2C_BOARDINFO=y 8997+# CONFIG_I2C_COMPAT is not set 8998+CONFIG_I2C_CHARDEV=y 8999+CONFIG_I2C_MUX=y 9000+ 9001+# 9002+# Multiplexer I2C Chip support 9003+# 9004+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set 9005+# CONFIG_I2C_MUX_GPIO is not set 9006+# CONFIG_I2C_MUX_GPMUX is not set 9007+# CONFIG_I2C_MUX_LTC4306 is not set 9008+# CONFIG_I2C_MUX_PCA9541 is not set 9009+# CONFIG_I2C_MUX_PCA954x is not set 9010+# CONFIG_I2C_MUX_PINCTRL is not set 9011+# CONFIG_I2C_MUX_REG is not set 9012+# CONFIG_I2C_DEMUX_PINCTRL is not set 9013+# CONFIG_I2C_MUX_MLXCPLD is not set 9014+# CONFIG_I2C_HELPER_AUTO is not set 9015+# CONFIG_I2C_SMBUS is not set 9016+ 9017+# 9018+# I2C Algorithms 9019+# 9020+# CONFIG_I2C_ALGOBIT is not set 9021+# CONFIG_I2C_ALGOPCF is not set 9022+# CONFIG_I2C_ALGOPCA is not set 9023+ 9024+# 9025+# I2C Hardware Bus support 9026+# 9027+ 9028+# 9029+# I2C system bus drivers (mostly embedded / system-on-chip) 9030+# 9031+# CONFIG_I2C_CBUS_GPIO is not set 9032+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set 9033+# CONFIG_I2C_EMEV2 is not set 9034+# CONFIG_I2C_GPIO is not set 9035+CONFIG_I2C_HIBVT=y 9036+# CONFIG_I2C_NOMADIK is not set 9037+# CONFIG_I2C_OCORES is not set 9038+# CONFIG_I2C_PCA_PLATFORM is not set 9039+# CONFIG_I2C_RK3X is not set 9040+# CONFIG_I2C_SIMTEC is not set 9041+# CONFIG_I2C_XILINX is not set 9042+ 9043+# 9044+# External I2C/SMBus adapter drivers 9045+# 9046+# CONFIG_I2C_DIOLAN_U2C is not set 9047+# CONFIG_I2C_PARPORT_LIGHT is not set 9048+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set 9049+# CONFIG_I2C_TAOS_EVM is not set 9050+# CONFIG_I2C_TINY_USB is not set 9051+ 9052+# 9053+# Other I2C/SMBus bus drivers 9054+# 9055+CONFIG_DMA_MSG_MIN_LEN=5 9056+CONFIG_DMA_MSG_MAX_LEN=4090 9057+# CONFIG_I2C_STUB is not set 9058+# CONFIG_I2C_SLAVE is not set 9059+# CONFIG_I2C_DEBUG_CORE is not set 9060+# CONFIG_I2C_DEBUG_ALGO is not set 9061+# CONFIG_I2C_DEBUG_BUS is not set 9062+CONFIG_SPI=y 9063+# CONFIG_SPI_DEBUG is not set 9064+CONFIG_SPI_MASTER=y 9065+# CONFIG_SPI_MEM is not set 9066+ 9067+# 9068+# SPI Master Controller Drivers 9069+# 9070+# CONFIG_SPI_ALTERA is not set 9071+# CONFIG_SPI_AXI_SPI_ENGINE is not set 9072+# CONFIG_SPI_BITBANG is not set 9073+# CONFIG_SPI_CADENCE is not set 9074+# CONFIG_SPI_DESIGNWARE is not set 9075+# CONFIG_SPI_GPIO is not set 9076+# CONFIG_SPI_FSL_SPI is not set 9077+# CONFIG_SPI_OC_TINY is not set 9078+CONFIG_SPI_PL022=y 9079+# CONFIG_SPI_ROCKCHIP is not set 9080+# CONFIG_SPI_SC18IS602 is not set 9081+# CONFIG_SPI_XCOMM is not set 9082+# CONFIG_SPI_XILINX is not set 9083+# CONFIG_SPI_ZYNQMP_GQSPI is not set 9084+ 9085+# 9086+# SPI Protocol Masters 9087+# 9088+CONFIG_SPI_SPIDEV=y 9089+# CONFIG_SPI_LOOPBACK_TEST is not set 9090+# CONFIG_SPI_TLE62X0 is not set 9091+# CONFIG_SPI_SLAVE is not set 9092+# CONFIG_SPMI is not set 9093+# CONFIG_HSI is not set 9094+# CONFIG_PPS is not set 9095+ 9096+# 9097+# PTP clock support 9098+# 9099+# CONFIG_PTP_1588_CLOCK is not set 9100+ 9101+# 9102+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. 9103+# 9104+CONFIG_PINCTRL=y 9105+# CONFIG_DEBUG_PINCTRL is not set 9106+# CONFIG_PINCTRL_AMD is not set 9107+# CONFIG_PINCTRL_MCP23S08 is not set 9108+# CONFIG_PINCTRL_SINGLE is not set 9109+# CONFIG_PINCTRL_SX150X is not set 9110+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y 9111+CONFIG_GPIOLIB=y 9112+CONFIG_GPIOLIB_FASTPATH_LIMIT=512 9113+CONFIG_OF_GPIO=y 9114+CONFIG_GPIOLIB_IRQCHIP=y 9115+# CONFIG_DEBUG_GPIO is not set 9116+CONFIG_GPIO_SYSFS=y 9117+CONFIG_GPIO_GENERIC=y 9118+ 9119+# 9120+# Memory mapped GPIO drivers 9121+# 9122+# CONFIG_GPIO_74XX_MMIO is not set 9123+# CONFIG_GPIO_ALTERA is not set 9124+# CONFIG_GPIO_DWAPB is not set 9125+# CONFIG_GPIO_FTGPIO010 is not set 9126+CONFIG_GPIO_GENERIC_PLATFORM=y 9127+# CONFIG_GPIO_GRGPIO is not set 9128+# CONFIG_GPIO_HLWD is not set 9129+# CONFIG_GPIO_MB86S7X is not set 9130+# CONFIG_GPIO_MOCKUP is not set 9131+# CONFIG_GPIO_MPC8XXX is not set 9132+CONFIG_GPIO_PL061=y 9133+# CONFIG_GPIO_SYSCON is not set 9134+# CONFIG_GPIO_XILINX is not set 9135+# CONFIG_GPIO_ZEVIO is not set 9136+ 9137+# 9138+# I2C GPIO expanders 9139+# 9140+# CONFIG_GPIO_ADP5588 is not set 9141+# CONFIG_GPIO_ADNP is not set 9142+# CONFIG_GPIO_MAX7300 is not set 9143+# CONFIG_GPIO_MAX732X is not set 9144+# CONFIG_GPIO_PCA953X is not set 9145+# CONFIG_GPIO_PCF857X is not set 9146+# CONFIG_GPIO_TPIC2810 is not set 9147+ 9148+# 9149+# MFD GPIO expanders 9150+# 9151+# CONFIG_HTC_EGPIO is not set 9152+ 9153+# 9154+# SPI GPIO expanders 9155+# 9156+# CONFIG_GPIO_74X164 is not set 9157+# CONFIG_GPIO_MAX3191X is not set 9158+# CONFIG_GPIO_MAX7301 is not set 9159+# CONFIG_GPIO_MC33880 is not set 9160+# CONFIG_GPIO_PISOSR is not set 9161+# CONFIG_GPIO_XRA1403 is not set 9162+ 9163+# 9164+# USB GPIO expanders 9165+# 9166+# CONFIG_W1 is not set 9167+# CONFIG_POWER_AVS is not set 9168+CONFIG_POWER_RESET=y 9169+# CONFIG_POWER_RESET_BRCMKONA is not set 9170+# CONFIG_POWER_RESET_BRCMSTB is not set 9171+# CONFIG_POWER_RESET_GPIO is not set 9172+# CONFIG_POWER_RESET_GPIO_RESTART is not set 9173+CONFIG_POWER_RESET_HISI=y 9174+# CONFIG_POWER_RESET_LTC2952 is not set 9175+# CONFIG_POWER_RESET_RESTART is not set 9176+# CONFIG_POWER_RESET_VERSATILE is not set 9177+CONFIG_POWER_RESET_SYSCON=y 9178+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set 9179+# CONFIG_SYSCON_REBOOT_MODE is not set 9180+CONFIG_POWER_SUPPLY=y 9181+# CONFIG_POWER_SUPPLY_DEBUG is not set 9182+# CONFIG_PDA_POWER is not set 9183+# CONFIG_TEST_POWER is not set 9184+# CONFIG_CHARGER_ADP5061 is not set 9185+# CONFIG_BATTERY_DS2780 is not set 9186+# CONFIG_BATTERY_DS2781 is not set 9187+# CONFIG_BATTERY_DS2782 is not set 9188+# CONFIG_BATTERY_SBS is not set 9189+# CONFIG_CHARGER_SBS is not set 9190+# CONFIG_MANAGER_SBS is not set 9191+# CONFIG_BATTERY_BQ27XXX is not set 9192+# CONFIG_BATTERY_MAX17040 is not set 9193+# CONFIG_BATTERY_MAX17042 is not set 9194+# CONFIG_CHARGER_MAX8903 is not set 9195+# CONFIG_CHARGER_LP8727 is not set 9196+# CONFIG_CHARGER_GPIO is not set 9197+# CONFIG_CHARGER_LTC3651 is not set 9198+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set 9199+# CONFIG_CHARGER_BQ2415X is not set 9200+# CONFIG_CHARGER_BQ24257 is not set 9201+# CONFIG_CHARGER_BQ24735 is not set 9202+# CONFIG_CHARGER_BQ25890 is not set 9203+# CONFIG_CHARGER_SMB347 is not set 9204+# CONFIG_BATTERY_GAUGE_LTC2941 is not set 9205+# CONFIG_CHARGER_RT9455 is not set 9206+# CONFIG_HWMON is not set 9207+# CONFIG_THERMAL is not set 9208+# CONFIG_WATCHDOG is not set 9209+CONFIG_SSB_POSSIBLE=y 9210+# CONFIG_SSB is not set 9211+CONFIG_BCMA_POSSIBLE=y 9212+# CONFIG_BCMA is not set 9213+ 9214+# 9215+# Multifunction device drivers 9216+# 9217+CONFIG_MFD_CORE=y 9218+# CONFIG_MFD_ACT8945A is not set 9219+# CONFIG_MFD_AS3711 is not set 9220+# CONFIG_MFD_AS3722 is not set 9221+# CONFIG_PMIC_ADP5520 is not set 9222+# CONFIG_MFD_AAT2870_CORE is not set 9223+# CONFIG_MFD_ATMEL_FLEXCOM is not set 9224+# CONFIG_MFD_ATMEL_HLCDC is not set 9225+# CONFIG_MFD_BCM590XX is not set 9226+# CONFIG_MFD_BD9571MWV is not set 9227+# CONFIG_MFD_AXP20X_I2C is not set 9228+# CONFIG_MFD_CROS_EC is not set 9229+# CONFIG_MFD_MADERA is not set 9230+# CONFIG_MFD_ASIC3 is not set 9231+# CONFIG_PMIC_DA903X is not set 9232+# CONFIG_MFD_DA9052_SPI is not set 9233+# CONFIG_MFD_DA9052_I2C is not set 9234+# CONFIG_MFD_DA9055 is not set 9235+# CONFIG_MFD_DA9062 is not set 9236+# CONFIG_MFD_DA9063 is not set 9237+# CONFIG_MFD_DA9150 is not set 9238+# CONFIG_MFD_DLN2 is not set 9239+# CONFIG_MFD_MC13XXX_SPI is not set 9240+# CONFIG_MFD_MC13XXX_I2C is not set 9241+# CONFIG_MFD_HI6421_PMIC is not set 9242+CONFIG_MFD_HISI_FMC=y 9243+# CONFIG_HTC_PASIC3 is not set 9244+# CONFIG_HTC_I2CPLD is not set 9245+# CONFIG_MFD_KEMPLD is not set 9246+# CONFIG_MFD_88PM800 is not set 9247+# CONFIG_MFD_88PM805 is not set 9248+# CONFIG_MFD_88PM860X is not set 9249+# CONFIG_MFD_MAX14577 is not set 9250+# CONFIG_MFD_MAX77620 is not set 9251+# CONFIG_MFD_MAX77686 is not set 9252+# CONFIG_MFD_MAX77693 is not set 9253+# CONFIG_MFD_MAX77843 is not set 9254+# CONFIG_MFD_MAX8907 is not set 9255+# CONFIG_MFD_MAX8925 is not set 9256+# CONFIG_MFD_MAX8997 is not set 9257+# CONFIG_MFD_MAX8998 is not set 9258+# CONFIG_MFD_MT6397 is not set 9259+# CONFIG_MFD_MENF21BMC is not set 9260+# CONFIG_EZX_PCAP is not set 9261+# CONFIG_MFD_CPCAP is not set 9262+# CONFIG_MFD_VIPERBOARD is not set 9263+# CONFIG_MFD_RETU is not set 9264+# CONFIG_MFD_PCF50633 is not set 9265+# CONFIG_MFD_PM8XXX is not set 9266+# CONFIG_MFD_RT5033 is not set 9267+# CONFIG_MFD_RC5T583 is not set 9268+# CONFIG_MFD_RK808 is not set 9269+# CONFIG_MFD_RN5T618 is not set 9270+# CONFIG_MFD_SEC_CORE is not set 9271+# CONFIG_MFD_SI476X_CORE is not set 9272+# CONFIG_MFD_SM501 is not set 9273+# CONFIG_MFD_SKY81452 is not set 9274+# CONFIG_MFD_SMSC is not set 9275+# CONFIG_ABX500_CORE is not set 9276+# CONFIG_MFD_STMPE is not set 9277+CONFIG_MFD_SYSCON=y 9278+# CONFIG_MFD_TI_AM335X_TSCADC is not set 9279+# CONFIG_MFD_LP3943 is not set 9280+# CONFIG_MFD_LP8788 is not set 9281+# CONFIG_MFD_TI_LMU is not set 9282+# CONFIG_MFD_PALMAS is not set 9283+# CONFIG_TPS6105X is not set 9284+# CONFIG_TPS65010 is not set 9285+# CONFIG_TPS6507X is not set 9286+# CONFIG_MFD_TPS65086 is not set 9287+# CONFIG_MFD_TPS65090 is not set 9288+# CONFIG_MFD_TPS65217 is not set 9289+# CONFIG_MFD_TI_LP873X is not set 9290+# CONFIG_MFD_TI_LP87565 is not set 9291+# CONFIG_MFD_TPS65218 is not set 9292+# CONFIG_MFD_TPS6586X is not set 9293+# CONFIG_MFD_TPS65910 is not set 9294+# CONFIG_MFD_TPS65912_I2C is not set 9295+# CONFIG_MFD_TPS65912_SPI is not set 9296+# CONFIG_MFD_TPS80031 is not set 9297+# CONFIG_TWL4030_CORE is not set 9298+# CONFIG_TWL6040_CORE is not set 9299+# CONFIG_MFD_WL1273_CORE is not set 9300+# CONFIG_MFD_LM3533 is not set 9301+# CONFIG_MFD_TC3589X is not set 9302+# CONFIG_MFD_T7L66XB is not set 9303+# CONFIG_MFD_TC6387XB is not set 9304+# CONFIG_MFD_TC6393XB is not set 9305+# CONFIG_MFD_ARIZONA_I2C is not set 9306+# CONFIG_MFD_ARIZONA_SPI is not set 9307+# CONFIG_MFD_WM8400 is not set 9308+# CONFIG_MFD_WM831X_I2C is not set 9309+# CONFIG_MFD_WM831X_SPI is not set 9310+# CONFIG_MFD_WM8350_I2C is not set 9311+# CONFIG_MFD_WM8994 is not set 9312+# CONFIG_MFD_ROHM_BD718XX is not set 9313+# CONFIG_REGULATOR is not set 9314+# CONFIG_RC_CORE is not set 9315+CONFIG_MEDIA_SUPPORT=y 9316+ 9317+# 9318+# Multimedia core support 9319+# 9320+CONFIG_MEDIA_CAMERA_SUPPORT=y 9321+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set 9322+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set 9323+# CONFIG_MEDIA_RADIO_SUPPORT is not set 9324+# CONFIG_MEDIA_SDR_SUPPORT is not set 9325+# CONFIG_MEDIA_CEC_SUPPORT is not set 9326+# CONFIG_MEDIA_CONTROLLER is not set 9327+CONFIG_VIDEO_DEV=y 9328+CONFIG_VIDEO_V4L2=y 9329+# CONFIG_VIDEO_ADV_DEBUG is not set 9330+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set 9331+ 9332+# 9333+# Media drivers 9334+# 9335+CONFIG_MEDIA_USB_SUPPORT=y 9336+ 9337+# 9338+# Webcam devices 9339+# 9340+CONFIG_USB_VIDEO_CLASS=y 9341+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y 9342+CONFIG_USB_GSPCA=m 9343+# CONFIG_USB_M5602 is not set 9344+# CONFIG_USB_STV06XX is not set 9345+# CONFIG_USB_GL860 is not set 9346+# CONFIG_USB_GSPCA_BENQ is not set 9347+# CONFIG_USB_GSPCA_CONEX is not set 9348+# CONFIG_USB_GSPCA_CPIA1 is not set 9349+# CONFIG_USB_GSPCA_DTCS033 is not set 9350+# CONFIG_USB_GSPCA_ETOMS is not set 9351+# CONFIG_USB_GSPCA_FINEPIX is not set 9352+# CONFIG_USB_GSPCA_JEILINJ is not set 9353+# CONFIG_USB_GSPCA_JL2005BCD is not set 9354+# CONFIG_USB_GSPCA_KINECT is not set 9355+# CONFIG_USB_GSPCA_KONICA is not set 9356+# CONFIG_USB_GSPCA_MARS is not set 9357+# CONFIG_USB_GSPCA_MR97310A is not set 9358+# CONFIG_USB_GSPCA_NW80X is not set 9359+# CONFIG_USB_GSPCA_OV519 is not set 9360+# CONFIG_USB_GSPCA_OV534 is not set 9361+# CONFIG_USB_GSPCA_OV534_9 is not set 9362+# CONFIG_USB_GSPCA_PAC207 is not set 9363+# CONFIG_USB_GSPCA_PAC7302 is not set 9364+# CONFIG_USB_GSPCA_PAC7311 is not set 9365+# CONFIG_USB_GSPCA_SE401 is not set 9366+# CONFIG_USB_GSPCA_SN9C2028 is not set 9367+# CONFIG_USB_GSPCA_SN9C20X is not set 9368+# CONFIG_USB_GSPCA_SONIXB is not set 9369+# CONFIG_USB_GSPCA_SONIXJ is not set 9370+# CONFIG_USB_GSPCA_SPCA500 is not set 9371+# CONFIG_USB_GSPCA_SPCA501 is not set 9372+# CONFIG_USB_GSPCA_SPCA505 is not set 9373+# CONFIG_USB_GSPCA_SPCA506 is not set 9374+# CONFIG_USB_GSPCA_SPCA508 is not set 9375+# CONFIG_USB_GSPCA_SPCA561 is not set 9376+# CONFIG_USB_GSPCA_SPCA1528 is not set 9377+# CONFIG_USB_GSPCA_SQ905 is not set 9378+# CONFIG_USB_GSPCA_SQ905C is not set 9379+# CONFIG_USB_GSPCA_SQ930X is not set 9380+# CONFIG_USB_GSPCA_STK014 is not set 9381+# CONFIG_USB_GSPCA_STK1135 is not set 9382+# CONFIG_USB_GSPCA_STV0680 is not set 9383+# CONFIG_USB_GSPCA_SUNPLUS is not set 9384+# CONFIG_USB_GSPCA_T613 is not set 9385+# CONFIG_USB_GSPCA_TOPRO is not set 9386+# CONFIG_USB_GSPCA_TOUPTEK is not set 9387+# CONFIG_USB_GSPCA_TV8532 is not set 9388+# CONFIG_USB_GSPCA_VC032X is not set 9389+# CONFIG_USB_GSPCA_VICAM is not set 9390+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set 9391+# CONFIG_USB_GSPCA_ZC3XX is not set 9392+# CONFIG_USB_PWC is not set 9393+# CONFIG_VIDEO_CPIA2 is not set 9394+# CONFIG_USB_ZR364XX is not set 9395+# CONFIG_USB_STKWEBCAM is not set 9396+# CONFIG_USB_S2255 is not set 9397+# CONFIG_VIDEO_USBTV is not set 9398+ 9399+# 9400+# Webcam, TV (analog/digital) USB devices 9401+# 9402+# CONFIG_VIDEO_EM28XX is not set 9403+# CONFIG_V4L_PLATFORM_DRIVERS is not set 9404+# CONFIG_V4L_MEM2MEM_DRIVERS is not set 9405+# CONFIG_V4L_TEST_DRIVERS is not set 9406+ 9407+# 9408+# Supported MMC/SDIO adapters 9409+# 9410+# CONFIG_CYPRESS_FIRMWARE is not set 9411+CONFIG_VIDEOBUF2_CORE=y 9412+CONFIG_VIDEOBUF2_V4L2=y 9413+CONFIG_VIDEOBUF2_MEMOPS=y 9414+CONFIG_VIDEOBUF2_VMALLOC=y 9415+ 9416+# 9417+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) 9418+# 9419+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y 9420+ 9421+# 9422+# Audio decoders, processors and mixers 9423+# 9424+ 9425+# 9426+# RDS decoders 9427+# 9428+ 9429+# 9430+# Video decoders 9431+# 9432+ 9433+# 9434+# Video and audio decoders 9435+# 9436+ 9437+# 9438+# Video encoders 9439+# 9440+ 9441+# 9442+# Camera sensor devices 9443+# 9444+ 9445+# 9446+# Flash devices 9447+# 9448+ 9449+# 9450+# Video improvement chips 9451+# 9452+ 9453+# 9454+# Audio/Video compression chips 9455+# 9456+ 9457+# 9458+# SDR tuner chips 9459+# 9460+ 9461+# 9462+# Miscellaneous helper chips 9463+# 9464+ 9465+# 9466+# Sensors used on soc_camera driver 9467+# 9468+ 9469+# 9470+# Media SPI Adapters 9471+# 9472+ 9473+# 9474+# Tools to develop new frontends 9475+# 9476+ 9477+# 9478+# Graphics support 9479+# 9480+# CONFIG_IMX_IPUV3_CORE is not set 9481+# CONFIG_DRM is not set 9482+# CONFIG_DRM_DP_CEC is not set 9483+ 9484+# 9485+# ACP (Audio CoProcessor) Configuration 9486+# 9487+ 9488+# 9489+# AMD Library routines 9490+# 9491+ 9492+# 9493+# Frame buffer Devices 9494+# 9495+CONFIG_FB_CMDLINE=y 9496+CONFIG_FB_NOTIFY=y 9497+CONFIG_FB=y 9498+# CONFIG_FIRMWARE_EDID is not set 9499+# CONFIG_FB_FOREIGN_ENDIAN is not set 9500+# CONFIG_FB_MODE_HELPERS is not set 9501+# CONFIG_FB_TILEBLITTING is not set 9502+ 9503+# 9504+# Frame buffer hardware drivers 9505+# 9506+# CONFIG_FB_ARMCLCD is not set 9507+# CONFIG_FB_OPENCORES is not set 9508+# CONFIG_FB_S1D13XXX is not set 9509+# CONFIG_FB_SMSCUFX is not set 9510+# CONFIG_FB_UDL is not set 9511+# CONFIG_FB_IBM_GXT4500 is not set 9512+# CONFIG_FB_VIRTUAL is not set 9513+# CONFIG_FB_METRONOME is not set 9514+# CONFIG_FB_BROADSHEET is not set 9515+# CONFIG_FB_SIMPLE is not set 9516+# CONFIG_FB_SSD1307 is not set 9517+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 9518+ 9519+# 9520+# Console display driver support 9521+# 9522+CONFIG_DUMMY_CONSOLE=y 9523+# CONFIG_FRAMEBUFFER_CONSOLE is not set 9524+# CONFIG_LOGO is not set 9525+CONFIG_SOUND=y 9526+CONFIG_SND=y 9527+CONFIG_SND_TIMER=y 9528+CONFIG_SND_PCM=y 9529+# CONFIG_SND_OSSEMUL is not set 9530+CONFIG_SND_PCM_TIMER=y 9531+# CONFIG_SND_DYNAMIC_MINORS is not set 9532+CONFIG_SND_SUPPORT_OLD_API=y 9533+CONFIG_SND_PROC_FS=y 9534+CONFIG_SND_VERBOSE_PROCFS=y 9535+# CONFIG_SND_VERBOSE_PRINTK is not set 9536+# CONFIG_SND_DEBUG is not set 9537+# CONFIG_SND_SEQUENCER is not set 9538+CONFIG_SND_DRIVERS=y 9539+# CONFIG_SND_DUMMY is not set 9540+# CONFIG_SND_ALOOP is not set 9541+# CONFIG_SND_MTPAV is not set 9542+# CONFIG_SND_SERIAL_U16550 is not set 9543+# CONFIG_SND_MPU401 is not set 9544+ 9545+# 9546+# HD-Audio 9547+# 9548+CONFIG_SND_HDA_PREALLOC_SIZE=64 9549+CONFIG_SND_ARM=y 9550+# CONFIG_SND_ARMAACI is not set 9551+CONFIG_SND_SPI=y 9552+CONFIG_SND_USB=y 9553+# CONFIG_SND_USB_AUDIO is not set 9554+# CONFIG_SND_USB_UA101 is not set 9555+# CONFIG_SND_USB_CAIAQ is not set 9556+# CONFIG_SND_USB_6FIRE is not set 9557+# CONFIG_SND_USB_HIFACE is not set 9558+# CONFIG_SND_BCD2000 is not set 9559+# CONFIG_SND_USB_POD is not set 9560+# CONFIG_SND_USB_PODHD is not set 9561+# CONFIG_SND_USB_TONEPORT is not set 9562+# CONFIG_SND_USB_VARIAX is not set 9563+# CONFIG_SND_SOC is not set 9564+ 9565+# 9566+# HID support 9567+# 9568+CONFIG_HID=y 9569+# CONFIG_HID_BATTERY_STRENGTH is not set 9570+# CONFIG_HIDRAW is not set 9571+# CONFIG_UHID is not set 9572+CONFIG_HID_GENERIC=y 9573+ 9574+# 9575+# Special HID drivers 9576+# 9577+CONFIG_HID_A4TECH=y 9578+# CONFIG_HID_ACCUTOUCH is not set 9579+# CONFIG_HID_ACRUX is not set 9580+CONFIG_HID_APPLE=y 9581+# CONFIG_HID_APPLEIR is not set 9582+# CONFIG_HID_AUREAL is not set 9583+CONFIG_HID_BELKIN=y 9584+# CONFIG_HID_BETOP_FF is not set 9585+CONFIG_HID_CHERRY=y 9586+CONFIG_HID_CHICONY=y 9587+# CONFIG_HID_COUGAR is not set 9588+# CONFIG_HID_PRODIKEYS is not set 9589+# CONFIG_HID_CMEDIA is not set 9590+CONFIG_HID_CYPRESS=y 9591+# CONFIG_HID_DRAGONRISE is not set 9592+# CONFIG_HID_EMS_FF is not set 9593+# CONFIG_HID_ELECOM is not set 9594+# CONFIG_HID_ELO is not set 9595+CONFIG_HID_EZKEY=y 9596+# CONFIG_HID_GEMBIRD is not set 9597+# CONFIG_HID_GFRM is not set 9598+# CONFIG_HID_HOLTEK is not set 9599+# CONFIG_HID_KEYTOUCH is not set 9600+# CONFIG_HID_KYE is not set 9601+# CONFIG_HID_UCLOGIC is not set 9602+# CONFIG_HID_WALTOP is not set 9603+# CONFIG_HID_GYRATION is not set 9604+# CONFIG_HID_ICADE is not set 9605+CONFIG_HID_ITE=y 9606+# CONFIG_HID_JABRA is not set 9607+# CONFIG_HID_TWINHAN is not set 9608+CONFIG_HID_KENSINGTON=y 9609+# CONFIG_HID_LCPOWER is not set 9610+# CONFIG_HID_LENOVO is not set 9611+CONFIG_HID_LOGITECH=y 9612+# CONFIG_HID_LOGITECH_HIDPP is not set 9613+# CONFIG_LOGITECH_FF is not set 9614+# CONFIG_LOGIRUMBLEPAD2_FF is not set 9615+# CONFIG_LOGIG940_FF is not set 9616+# CONFIG_LOGIWHEELS_FF is not set 9617+# CONFIG_HID_MAGICMOUSE is not set 9618+# CONFIG_HID_MAYFLASH is not set 9619+CONFIG_HID_REDRAGON=y 9620+CONFIG_HID_MICROSOFT=y 9621+CONFIG_HID_MONTEREY=y 9622+# CONFIG_HID_MULTITOUCH is not set 9623+# CONFIG_HID_NTI is not set 9624+# CONFIG_HID_NTRIG is not set 9625+# CONFIG_HID_ORTEK is not set 9626+# CONFIG_HID_PANTHERLORD is not set 9627+# CONFIG_HID_PENMOUNT is not set 9628+# CONFIG_HID_PETALYNX is not set 9629+# CONFIG_HID_PICOLCD is not set 9630+# CONFIG_HID_PLANTRONICS is not set 9631+# CONFIG_HID_PRIMAX is not set 9632+# CONFIG_HID_RETRODE is not set 9633+# CONFIG_HID_ROCCAT is not set 9634+# CONFIG_HID_SAITEK is not set 9635+# CONFIG_HID_SAMSUNG is not set 9636+# CONFIG_HID_SPEEDLINK is not set 9637+# CONFIG_HID_STEAM is not set 9638+# CONFIG_HID_STEELSERIES is not set 9639+# CONFIG_HID_SUNPLUS is not set 9640+# CONFIG_HID_RMI is not set 9641+# CONFIG_HID_GREENASIA is not set 9642+# CONFIG_HID_SMARTJOYPLUS is not set 9643+# CONFIG_HID_TIVO is not set 9644+# CONFIG_HID_TOPSEED is not set 9645+# CONFIG_HID_THRUSTMASTER is not set 9646+# CONFIG_HID_UDRAW_PS3 is not set 9647+# CONFIG_HID_WACOM is not set 9648+# CONFIG_HID_XINMO is not set 9649+# CONFIG_HID_ZEROPLUS is not set 9650+# CONFIG_HID_ZYDACRON is not set 9651+# CONFIG_HID_SENSOR_HUB is not set 9652+# CONFIG_HID_ALPS is not set 9653+ 9654+# 9655+# USB HID support 9656+# 9657+CONFIG_USB_HID=y 9658+# CONFIG_HID_PID is not set 9659+# CONFIG_USB_HIDDEV is not set 9660+ 9661+# 9662+# I2C HID support 9663+# 9664+# CONFIG_I2C_HID is not set 9665+CONFIG_USB_OHCI_LITTLE_ENDIAN=y 9666+CONFIG_USB_SUPPORT=y 9667+CONFIG_USB_COMMON=y 9668+CONFIG_USB_ARCH_HAS_HCD=y 9669+CONFIG_USB=y 9670+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set 9671+ 9672+# 9673+# Miscellaneous USB options 9674+# 9675+CONFIG_USB_DEFAULT_PERSIST=y 9676+# CONFIG_USB_DYNAMIC_MINORS is not set 9677+# CONFIG_USB_OTG is not set 9678+# CONFIG_USB_OTG_WHITELIST is not set 9679+# CONFIG_USB_MON is not set 9680+# CONFIG_USB_WUSB_CBAF is not set 9681+ 9682+# 9683+# USB Host Controller Drivers 9684+# 9685+# CONFIG_USB_C67X00_HCD is not set 9686+CONFIG_USB_XHCI_HCD=y 9687+# CONFIG_USB_XHCI_DBGCAP is not set 9688+CONFIG_USB_XHCI_PLATFORM=y 9689+# CONFIG_USB_EHCI_HCD is not set 9690+# CONFIG_USB_OXU210HP_HCD is not set 9691+# CONFIG_USB_ISP116X_HCD is not set 9692+# CONFIG_USB_FOTG210_HCD is not set 9693+# CONFIG_USB_MAX3421_HCD is not set 9694+# CONFIG_USB_OHCI_HCD is not set 9695+# CONFIG_USB_SL811_HCD is not set 9696+# CONFIG_USB_R8A66597_HCD is not set 9697+# CONFIG_USB_HCD_TEST_MODE is not set 9698+ 9699+# 9700+# USB Device Class drivers 9701+# 9702+# CONFIG_USB_ACM is not set 9703+# CONFIG_USB_PRINTER is not set 9704+# CONFIG_USB_WDM is not set 9705+# CONFIG_USB_TMC is not set 9706+ 9707+# 9708+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may 9709+# 9710+ 9711+# 9712+# also be needed; see USB_STORAGE Help for more info 9713+# 9714+CONFIG_USB_STORAGE=y 9715+# CONFIG_USB_STORAGE_DEBUG is not set 9716+# CONFIG_USB_STORAGE_REALTEK is not set 9717+# CONFIG_USB_STORAGE_DATAFAB is not set 9718+# CONFIG_USB_STORAGE_FREECOM is not set 9719+# CONFIG_USB_STORAGE_ISD200 is not set 9720+# CONFIG_USB_STORAGE_USBAT is not set 9721+# CONFIG_USB_STORAGE_SDDR09 is not set 9722+# CONFIG_USB_STORAGE_SDDR55 is not set 9723+# CONFIG_USB_STORAGE_JUMPSHOT is not set 9724+# CONFIG_USB_STORAGE_ALAUDA is not set 9725+# CONFIG_USB_STORAGE_ONETOUCH is not set 9726+# CONFIG_USB_STORAGE_KARMA is not set 9727+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set 9728+# CONFIG_USB_STORAGE_ENE_UB6250 is not set 9729+# CONFIG_USB_UAS is not set 9730+ 9731+# 9732+# USB Imaging devices 9733+# 9734+# CONFIG_USB_MDC800 is not set 9735+# CONFIG_USB_MICROTEK is not set 9736+# CONFIG_USBIP_CORE is not set 9737+# CONFIG_USB_MUSB_HDRC is not set 9738+CONFIG_USB_DWC3=y 9739+# CONFIG_USB_DWC3_HOST is not set 9740+CONFIG_USB_DWC3_GADGET=y 9741+ 9742+# 9743+# Platform Glue Driver Support 9744+# 9745+# CONFIG_USB_DWC3_OF_SIMPLE is not set 9746+# CONFIG_USB_DWC2 is not set 9747+# CONFIG_USB_CHIPIDEA is not set 9748+# CONFIG_USB_ISP1760 is not set 9749+ 9750+# 9751+# USB port drivers 9752+# 9753+# CONFIG_USB_SERIAL is not set 9754+ 9755+# 9756+# USB Miscellaneous drivers 9757+# 9758+# CONFIG_USB_EMI62 is not set 9759+# CONFIG_USB_EMI26 is not set 9760+# CONFIG_USB_ADUTUX is not set 9761+# CONFIG_USB_SEVSEG is not set 9762+# CONFIG_USB_LEGOTOWER is not set 9763+# CONFIG_USB_LCD is not set 9764+# CONFIG_USB_CYPRESS_CY7C63 is not set 9765+# CONFIG_USB_CYTHERM is not set 9766+# CONFIG_USB_IDMOUSE is not set 9767+# CONFIG_USB_FTDI_ELAN is not set 9768+# CONFIG_USB_APPLEDISPLAY is not set 9769+# CONFIG_USB_LD is not set 9770+# CONFIG_USB_TRANCEVIBRATOR is not set 9771+# CONFIG_USB_IOWARRIOR is not set 9772+# CONFIG_USB_TEST is not set 9773+# CONFIG_USB_EHSET_TEST_FIXTURE is not set 9774+# CONFIG_USB_ISIGHTFW is not set 9775+# CONFIG_USB_YUREX is not set 9776+# CONFIG_USB_EZUSB_FX2 is not set 9777+# CONFIG_USB_HUB_USB251XB is not set 9778+# CONFIG_USB_HSIC_USB3503 is not set 9779+# CONFIG_USB_HSIC_USB4604 is not set 9780+# CONFIG_USB_LINK_LAYER_TEST is not set 9781+ 9782+# 9783+# USB Physical Layer drivers 9784+# 9785+# CONFIG_NOP_USB_XCEIV is not set 9786+# CONFIG_USB_GPIO_VBUS is not set 9787+# CONFIG_USB_ISP1301 is not set 9788+# CONFIG_USB_ULPI is not set 9789+CONFIG_USB_GADGET=y 9790+# CONFIG_USB_GADGET_DEBUG is not set 9791+# CONFIG_USB_GADGET_DEBUG_FILES is not set 9792+# CONFIG_USB_GADGET_DEBUG_FS is not set 9793+CONFIG_USB_GADGET_VBUS_DRAW=2 9794+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 9795+# CONFIG_U_SERIAL_CONSOLE is not set 9796+ 9797+# 9798+# USB Peripheral Controller 9799+# 9800+# CONFIG_USB_FUSB300 is not set 9801+# CONFIG_USB_FOTG210_UDC is not set 9802+# CONFIG_USB_GR_UDC is not set 9803+# CONFIG_USB_R8A66597 is not set 9804+# CONFIG_USB_PXA27X is not set 9805+# CONFIG_USB_MV_UDC is not set 9806+# CONFIG_USB_MV_U3D is not set 9807+# CONFIG_USB_SNP_UDC_PLAT is not set 9808+# CONFIG_USB_M66592 is not set 9809+# CONFIG_USB_BDC_UDC is not set 9810+# CONFIG_USB_NET2272 is not set 9811+# CONFIG_USB_GADGET_XILINX is not set 9812+# CONFIG_USB_DUMMY_HCD is not set 9813+CONFIG_USB_LIBCOMPOSITE=y 9814+CONFIG_USB_F_ACM=y 9815+CONFIG_USB_U_SERIAL=y 9816+CONFIG_USB_U_ETHER=y 9817+CONFIG_USB_U_AUDIO=y 9818+CONFIG_USB_F_RNDIS=y 9819+CONFIG_USB_F_MASS_STORAGE=y 9820+CONFIG_USB_F_UAC1=y 9821+CONFIG_USB_F_UVC=y 9822+CONFIG_USB_CONFIGFS=y 9823+# CONFIG_USB_CONFIGFS_SERIAL is not set 9824+CONFIG_USB_CONFIGFS_ACM=y 9825+# CONFIG_USB_CONFIGFS_OBEX is not set 9826+# CONFIG_USB_CONFIGFS_NCM is not set 9827+# CONFIG_USB_CONFIGFS_ECM is not set 9828+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set 9829+CONFIG_USB_CONFIGFS_RNDIS=y 9830+# CONFIG_USB_CONFIGFS_EEM is not set 9831+CONFIG_USB_CONFIGFS_MASS_STORAGE=y 9832+# CONFIG_USB_CONFIGFS_F_LB_SS is not set 9833+# CONFIG_USB_CONFIGFS_F_FS is not set 9834+CONFIG_USB_CONFIGFS_F_UAC1=y 9835+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set 9836+# CONFIG_USB_CONFIGFS_F_UAC2 is not set 9837+# CONFIG_USB_CONFIGFS_F_MIDI is not set 9838+# CONFIG_USB_CONFIGFS_F_HID is not set 9839+CONFIG_USB_CONFIGFS_F_UVC=y 9840+# CONFIG_USB_CONFIGFS_F_PRINTER is not set 9841+# CONFIG_TYPEC is not set 9842+# CONFIG_USB_ROLE_SWITCH is not set 9843+# CONFIG_USB_ULPI_BUS is not set 9844+# CONFIG_UWB is not set 9845+CONFIG_MMC=y 9846+CONFIG_PWRSEQ_EMMC=y 9847+CONFIG_PWRSEQ_SIMPLE=y 9848+CONFIG_MMC_BLOCK=y 9849+CONFIG_MMC_BLOCK_MINORS=8 9850+# CONFIG_SDIO_UART is not set 9851+# CONFIG_MMC_TEST is not set 9852+ 9853+# 9854+# MMC/SD/SDIO Host Controller Drivers 9855+# 9856+# CONFIG_MMC_DEBUG is not set 9857+# CONFIG_MMC_ARMMMCI is not set 9858+# CONFIG_MMC_SDHCI is not set 9859+# CONFIG_MMC_SPI is not set 9860+# CONFIG_MMC_DW is not set 9861+# CONFIG_MMC_VUB300 is not set 9862+# CONFIG_MMC_USHC is not set 9863+# CONFIG_MMC_USDHI6ROL0 is not set 9864+# CONFIG_MMC_CQHCI is not set 9865+# CONFIG_MMC_MTK is not set 9866+# CONFIG_MMC_CQ_HCI is not set 9867+CONFIG_HIMCI=y 9868+CONFIG_SEND_AUTO_STOP=y 9869+# CONFIG_MEMSTICK is not set 9870+# CONFIG_NEW_LEDS is not set 9871+# CONFIG_ACCESSIBILITY is not set 9872+# CONFIG_INFINIBAND is not set 9873+CONFIG_EDAC_ATOMIC_SCRUB=y 9874+CONFIG_EDAC_SUPPORT=y 9875+CONFIG_RTC_LIB=y 9876+CONFIG_RTC_CLASS=y 9877+CONFIG_RTC_HCTOSYS=y 9878+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" 9879+CONFIG_RTC_SYSTOHC=y 9880+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" 9881+# CONFIG_RTC_DEBUG is not set 9882+CONFIG_RTC_NVMEM=y 9883+ 9884+# 9885+# RTC interfaces 9886+# 9887+CONFIG_RTC_INTF_SYSFS=y 9888+CONFIG_RTC_INTF_PROC=y 9889+CONFIG_RTC_INTF_DEV=y 9890+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set 9891+# CONFIG_RTC_DRV_TEST is not set 9892+ 9893+# 9894+# I2C RTC drivers 9895+# 9896+# CONFIG_RTC_DRV_ABB5ZES3 is not set 9897+# CONFIG_RTC_DRV_ABX80X is not set 9898+# CONFIG_RTC_DRV_DS1307 is not set 9899+# CONFIG_RTC_DRV_DS1374 is not set 9900+# CONFIG_RTC_DRV_DS1672 is not set 9901+# CONFIG_RTC_DRV_HYM8563 is not set 9902+# CONFIG_RTC_DRV_MAX6900 is not set 9903+# CONFIG_RTC_DRV_RS5C372 is not set 9904+# CONFIG_RTC_DRV_ISL1208 is not set 9905+# CONFIG_RTC_DRV_ISL12022 is not set 9906+# CONFIG_RTC_DRV_ISL12026 is not set 9907+# CONFIG_RTC_DRV_X1205 is not set 9908+# CONFIG_RTC_DRV_PCF8523 is not set 9909+# CONFIG_RTC_DRV_PCF85063 is not set 9910+# CONFIG_RTC_DRV_PCF85363 is not set 9911+# CONFIG_RTC_DRV_PCF8563 is not set 9912+# CONFIG_RTC_DRV_PCF8583 is not set 9913+# CONFIG_RTC_DRV_M41T80 is not set 9914+# CONFIG_RTC_DRV_BQ32K is not set 9915+# CONFIG_RTC_DRV_S35390A is not set 9916+# CONFIG_RTC_DRV_FM3130 is not set 9917+# CONFIG_RTC_DRV_RX8010 is not set 9918+# CONFIG_RTC_DRV_RX8581 is not set 9919+# CONFIG_RTC_DRV_RX8025 is not set 9920+# CONFIG_RTC_DRV_EM3027 is not set 9921+# CONFIG_RTC_DRV_RV8803 is not set 9922+ 9923+# 9924+# SPI RTC drivers 9925+# 9926+# CONFIG_RTC_DRV_M41T93 is not set 9927+# CONFIG_RTC_DRV_M41T94 is not set 9928+# CONFIG_RTC_DRV_DS1302 is not set 9929+# CONFIG_RTC_DRV_DS1305 is not set 9930+# CONFIG_RTC_DRV_DS1343 is not set 9931+# CONFIG_RTC_DRV_DS1347 is not set 9932+# CONFIG_RTC_DRV_DS1390 is not set 9933+# CONFIG_RTC_DRV_MAX6916 is not set 9934+# CONFIG_RTC_DRV_R9701 is not set 9935+# CONFIG_RTC_DRV_RX4581 is not set 9936+# CONFIG_RTC_DRV_RX6110 is not set 9937+# CONFIG_RTC_DRV_RS5C348 is not set 9938+# CONFIG_RTC_DRV_MAX6902 is not set 9939+# CONFIG_RTC_DRV_PCF2123 is not set 9940+# CONFIG_RTC_DRV_MCP795 is not set 9941+CONFIG_RTC_I2C_AND_SPI=y 9942+ 9943+# 9944+# SPI and I2C RTC drivers 9945+# 9946+# CONFIG_RTC_DRV_DS3232 is not set 9947+# CONFIG_RTC_DRV_PCF2127 is not set 9948+# CONFIG_RTC_DRV_RV3029C2 is not set 9949+ 9950+# 9951+# Platform RTC drivers 9952+# 9953+CONFIG_RTC_DRV_HIBVT=y 9954+# CONFIG_RTC_DRV_CMOS is not set 9955+# CONFIG_RTC_DRV_DS1286 is not set 9956+# CONFIG_RTC_DRV_DS1511 is not set 9957+# CONFIG_RTC_DRV_DS1553 is not set 9958+# CONFIG_RTC_DRV_DS1685_FAMILY is not set 9959+# CONFIG_RTC_DRV_DS1742 is not set 9960+# CONFIG_RTC_DRV_DS2404 is not set 9961+# CONFIG_RTC_DRV_STK17TA8 is not set 9962+# CONFIG_RTC_DRV_M48T86 is not set 9963+# CONFIG_RTC_DRV_M48T35 is not set 9964+# CONFIG_RTC_DRV_M48T59 is not set 9965+# CONFIG_RTC_DRV_MSM6242 is not set 9966+# CONFIG_RTC_DRV_BQ4802 is not set 9967+# CONFIG_RTC_DRV_RP5C01 is not set 9968+# CONFIG_RTC_DRV_V3020 is not set 9969+# CONFIG_RTC_DRV_ZYNQMP is not set 9970+ 9971+# 9972+# on-CPU RTC drivers 9973+# 9974+# CONFIG_RTC_DRV_PL030 is not set 9975+# CONFIG_RTC_DRV_PL031 is not set 9976+# CONFIG_RTC_DRV_FTRTC010 is not set 9977+# CONFIG_RTC_DRV_SNVS is not set 9978+# CONFIG_RTC_DRV_R7301 is not set 9979+ 9980+# 9981+# HID Sensor RTC drivers 9982+# 9983+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set 9984+# CONFIG_DMADEVICES is not set 9985+ 9986+# 9987+# DMABUF options 9988+# 9989+# CONFIG_SYNC_FILE is not set 9990+# CONFIG_AUXDISPLAY is not set 9991+# CONFIG_UIO is not set 9992+# CONFIG_VIRT_DRIVERS is not set 9993+CONFIG_VIRTIO_MENU=y 9994+# CONFIG_VIRTIO_MMIO is not set 9995+ 9996+# 9997+# Microsoft Hyper-V guest support 9998+# 9999+# CONFIG_STAGING is not set 10000+# CONFIG_GOLDFISH is not set 10001+# CONFIG_CHROME_PLATFORMS is not set 10002+# CONFIG_MELLANOX_PLATFORM is not set 10003+CONFIG_CLKDEV_LOOKUP=y 10004+CONFIG_HAVE_CLK_PREPARE=y 10005+CONFIG_COMMON_CLK=y 10006+ 10007+# 10008+# Common Clock Framework 10009+# 10010+# CONFIG_CLK_HSDK is not set 10011+# CONFIG_COMMON_CLK_MAX9485 is not set 10012+# CONFIG_COMMON_CLK_SI5351 is not set 10013+# CONFIG_COMMON_CLK_SI514 is not set 10014+# CONFIG_COMMON_CLK_SI544 is not set 10015+# CONFIG_COMMON_CLK_SI570 is not set 10016+# CONFIG_COMMON_CLK_CDCE706 is not set 10017+# CONFIG_COMMON_CLK_CDCE925 is not set 10018+# CONFIG_COMMON_CLK_CS2000_CP is not set 10019+# CONFIG_CLK_QORIQ is not set 10020+# CONFIG_COMMON_CLK_VC5 is not set 10021+CONFIG_COMMON_CLK_HI3516DV300=y 10022+CONFIG_RESET_HISI=y 10023+# CONFIG_HWSPINLOCK is not set 10024+ 10025+# 10026+# Clock Source drivers 10027+# 10028+CONFIG_TIMER_OF=y 10029+CONFIG_TIMER_PROBE=y 10030+CONFIG_CLKSRC_MMIO=y 10031+CONFIG_ARM_ARCH_TIMER=y 10032+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y 10033+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set 10034+CONFIG_ARM_TIMER_SP804=y 10035+# CONFIG_TIMER_HISP804 is not set 10036+# CONFIG_MAILBOX is not set 10037+# CONFIG_IOMMU_SUPPORT is not set 10038+ 10039+# 10040+# Remoteproc drivers 10041+# 10042+# CONFIG_REMOTEPROC is not set 10043+ 10044+# 10045+# Rpmsg drivers 10046+# 10047+# CONFIG_RPMSG_VIRTIO is not set 10048+ 10049+# 10050+# SOC (System On Chip) specific Drivers 10051+# 10052+ 10053+# 10054+# Amlogic SoC drivers 10055+# 10056+ 10057+# 10058+# Broadcom SoC drivers 10059+# 10060+# CONFIG_SOC_BRCMSTB is not set 10061+ 10062+# 10063+# NXP/Freescale QorIQ SoC drivers 10064+# 10065+ 10066+# 10067+# i.MX SoC drivers 10068+# 10069+ 10070+# 10071+# Qualcomm SoC drivers 10072+# 10073+# CONFIG_SOC_TI is not set 10074+ 10075+# 10076+# Xilinx SoC drivers 10077+# 10078+# CONFIG_XILINX_VCU is not set 10079+# CONFIG_PM_DEVFREQ is not set 10080+# CONFIG_EXTCON is not set 10081+# CONFIG_MEMORY is not set 10082+# CONFIG_IIO is not set 10083+# CONFIG_PWM is not set 10084+ 10085+# 10086+# IRQ chip support 10087+# 10088+CONFIG_IRQCHIP=y 10089+CONFIG_ARM_GIC=y 10090+CONFIG_ARM_GIC_MAX_NR=1 10091+# CONFIG_IPACK_BUS is not set 10092+CONFIG_RESET_CONTROLLER=y 10093+# CONFIG_RESET_TI_SYSCON is not set 10094+# CONFIG_FMC is not set 10095+ 10096+# 10097+# PHY Subsystem 10098+# 10099+CONFIG_GENERIC_PHY=y 10100+# CONFIG_BCM_KONA_USB2_PHY is not set 10101+# CONFIG_PHY_PXA_28NM_HSIC is not set 10102+# CONFIG_PHY_PXA_28NM_USB2 is not set 10103+# CONFIG_PHY_MAPPHONE_MDM6600 is not set 10104+CONFIG_HI_USB_PHY=y 10105+CONFIG_PHY_HISI_USB2=y 10106+CONFIG_HIBVT_USB_PHY=y 10107+CONFIG_USB_MODE_OPTION=y 10108+CONFIG_USB_DRD0_IN_HOST=y 10109+# CONFIG_POWERCAP is not set 10110+# CONFIG_MCB is not set 10111+# CONFIG_RAS is not set 10112+# CONFIG_DAX is not set 10113+CONFIG_NVMEM=y 10114+ 10115+# 10116+# HW tracing support 10117+# 10118+# CONFIG_STM is not set 10119+# CONFIG_INTEL_TH is not set 10120+# CONFIG_FPGA is not set 10121+# CONFIG_FSI is not set 10122+# CONFIG_TEE is not set 10123+# CONFIG_SIOX is not set 10124+# CONFIG_SLIMBUS is not set 10125+# CONFIG_HI_DMAC is not set 10126+# CONFIG_HIEDMAC is not set 10127+ 10128+# 10129+# Hisilicon driver support 10130+# 10131+# CONFIG_CMA_MEM_SHARED is not set 10132+# CONFIG_CMA_ADVANCE_SHARE is not set 10133+ 10134+# 10135+# File systems 10136+# 10137+CONFIG_DCACHE_WORD_ACCESS=y 10138+CONFIG_FS_IOMAP=y 10139+# CONFIG_EXT2_FS is not set 10140+# CONFIG_EXT3_FS is not set 10141+CONFIG_EXT4_FS=y 10142+CONFIG_EXT4_USE_FOR_EXT2=y 10143+# CONFIG_EXT4_FS_POSIX_ACL is not set 10144+# CONFIG_EXT4_FS_SECURITY is not set 10145+# CONFIG_EXT4_ENCRYPTION is not set 10146+# CONFIG_EXT4_DEBUG is not set 10147+CONFIG_JBD2=y 10148+# CONFIG_JBD2_DEBUG is not set 10149+CONFIG_FS_MBCACHE=y 10150+CONFIG_REISERFS_FS=m 10151+CONFIG_REISERFS_CHECK=y 10152+CONFIG_REISERFS_PROC_INFO=y 10153+CONFIG_REISERFS_FS_XATTR=y 10154+CONFIG_REISERFS_FS_POSIX_ACL=y 10155+CONFIG_REISERFS_FS_SECURITY=y 10156+CONFIG_JFS_FS=m 10157+CONFIG_JFS_POSIX_ACL=y 10158+CONFIG_JFS_SECURITY=y 10159+CONFIG_JFS_DEBUG=y 10160+CONFIG_JFS_STATISTICS=y 10161+CONFIG_XFS_FS=m 10162+CONFIG_XFS_QUOTA=y 10163+CONFIG_XFS_POSIX_ACL=y 10164+CONFIG_XFS_RT=y 10165+# CONFIG_XFS_ONLINE_SCRUB is not set 10166+# CONFIG_XFS_WARN is not set 10167+# CONFIG_XFS_DEBUG is not set 10168+# CONFIG_GFS2_FS is not set 10169+# CONFIG_OCFS2_FS is not set 10170+# CONFIG_BTRFS_FS is not set 10171+# CONFIG_NILFS2_FS is not set 10172+# CONFIG_F2FS_FS is not set 10173+CONFIG_FS_POSIX_ACL=y 10174+CONFIG_EXPORTFS=y 10175+# CONFIG_EXPORTFS_BLOCK_OPS is not set 10176+CONFIG_FILE_LOCKING=y 10177+CONFIG_MANDATORY_FILE_LOCKING=y 10178+# CONFIG_FS_ENCRYPTION is not set 10179+CONFIG_FSNOTIFY=y 10180+CONFIG_DNOTIFY=y 10181+CONFIG_INOTIFY_USER=y 10182+# CONFIG_FANOTIFY is not set 10183+# CONFIG_QUOTA is not set 10184+# CONFIG_QUOTA_NETLINK_INTERFACE is not set 10185+CONFIG_QUOTACTL=y 10186+# CONFIG_AUTOFS4_FS is not set 10187+# CONFIG_AUTOFS_FS is not set 10188+# CONFIG_FUSE_FS is not set 10189+# CONFIG_OVERLAY_FS is not set 10190+ 10191+# 10192+# Caches 10193+# 10194+# CONFIG_FSCACHE is not set 10195+ 10196+# 10197+# CD-ROM/DVD Filesystems 10198+# 10199+# CONFIG_ISO9660_FS is not set 10200+# CONFIG_UDF_FS is not set 10201+ 10202+# 10203+# DOS/FAT/NT Filesystems 10204+# 10205+CONFIG_FAT_FS=y 10206+CONFIG_MSDOS_FS=y 10207+CONFIG_VFAT_FS=y 10208+CONFIG_FAT_DEFAULT_CODEPAGE=437 10209+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" 10210+# CONFIG_FAT_DEFAULT_UTF8 is not set 10211+# CONFIG_NTFS_FS is not set 10212+ 10213+# 10214+# Pseudo filesystems 10215+# 10216+CONFIG_PROC_FS=y 10217+CONFIG_PROC_SYSCTL=y 10218+CONFIG_PROC_PAGE_MONITOR=y 10219+# CONFIG_PROC_CHILDREN is not set 10220+CONFIG_KERNFS=y 10221+CONFIG_SYSFS=y 10222+CONFIG_TMPFS=y 10223+# CONFIG_TMPFS_POSIX_ACL is not set 10224+# CONFIG_TMPFS_XATTR is not set 10225+CONFIG_MEMFD_CREATE=y 10226+CONFIG_CONFIGFS_FS=y 10227+CONFIG_MISC_FILESYSTEMS=y 10228+# CONFIG_ORANGEFS_FS is not set 10229+# CONFIG_ADFS_FS is not set 10230+# CONFIG_AFFS_FS is not set 10231+# CONFIG_ECRYPT_FS is not set 10232+# CONFIG_HFS_FS is not set 10233+# CONFIG_HFSPLUS_FS is not set 10234+# CONFIG_BEFS_FS is not set 10235+# CONFIG_BFS_FS is not set 10236+# CONFIG_EFS_FS is not set 10237+CONFIG_JFFS2_FS=y 10238+CONFIG_JFFS2_FS_DEBUG=0 10239+CONFIG_JFFS2_FS_WRITEBUFFER=y 10240+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set 10241+# CONFIG_JFFS2_SUMMARY is not set 10242+# CONFIG_JFFS2_FS_XATTR is not set 10243+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 10244+CONFIG_JFFS2_ZLIB=y 10245+CONFIG_JFFS2_RTIME=y 10246+CONFIG_UBIFS_FS=y 10247+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set 10248+CONFIG_UBIFS_FS_LZO=y 10249+CONFIG_UBIFS_FS_ZLIB=y 10250+# CONFIG_UBIFS_ATIME_SUPPORT is not set 10251+CONFIG_UBIFS_FS_XATTR=y 10252+# CONFIG_UBIFS_FS_ENCRYPTION is not set 10253+CONFIG_UBIFS_FS_SECURITY=y 10254+CONFIG_CRAMFS=y 10255+CONFIG_CRAMFS_BLOCKDEV=y 10256+# CONFIG_CRAMFS_MTD is not set 10257+# CONFIG_SQUASHFS is not set 10258+# CONFIG_VXFS_FS is not set 10259+# CONFIG_MINIX_FS is not set 10260+# CONFIG_OMFS_FS is not set 10261+# CONFIG_HPFS_FS is not set 10262+# CONFIG_QNX4FS_FS is not set 10263+# CONFIG_QNX6FS_FS is not set 10264+# CONFIG_ROMFS_FS is not set 10265+# CONFIG_PSTORE is not set 10266+# CONFIG_SYSV_FS is not set 10267+# CONFIG_UFS_FS is not set 10268+CONFIG_NETWORK_FILESYSTEMS=y 10269+CONFIG_NFS_FS=y 10270+CONFIG_NFS_V2=y 10271+CONFIG_NFS_V3=y 10272+CONFIG_NFS_V3_ACL=y 10273+CONFIG_NFS_V4=y 10274+# CONFIG_NFS_SWAP is not set 10275+# CONFIG_NFS_V4_1 is not set 10276+# CONFIG_ROOT_NFS is not set 10277+# CONFIG_NFS_USE_LEGACY_DNS is not set 10278+CONFIG_NFS_USE_KERNEL_DNS=y 10279+# CONFIG_NFSD is not set 10280+CONFIG_GRACE_PERIOD=y 10281+CONFIG_LOCKD=y 10282+CONFIG_LOCKD_V4=y 10283+CONFIG_NFS_ACL_SUPPORT=y 10284+CONFIG_NFS_COMMON=y 10285+CONFIG_SUNRPC=y 10286+CONFIG_SUNRPC_GSS=y 10287+# CONFIG_SUNRPC_DEBUG is not set 10288+# CONFIG_CEPH_FS is not set 10289+# CONFIG_CIFS is not set 10290+# CONFIG_CODA_FS is not set 10291+# CONFIG_AFS_FS is not set 10292+CONFIG_NLS=y 10293+CONFIG_NLS_DEFAULT="iso8859-1" 10294+CONFIG_NLS_CODEPAGE_437=y 10295+CONFIG_NLS_CODEPAGE_737=m 10296+CONFIG_NLS_CODEPAGE_775=m 10297+CONFIG_NLS_CODEPAGE_850=m 10298+CONFIG_NLS_CODEPAGE_852=m 10299+CONFIG_NLS_CODEPAGE_855=m 10300+CONFIG_NLS_CODEPAGE_857=m 10301+CONFIG_NLS_CODEPAGE_860=m 10302+CONFIG_NLS_CODEPAGE_861=m 10303+CONFIG_NLS_CODEPAGE_862=m 10304+CONFIG_NLS_CODEPAGE_863=m 10305+CONFIG_NLS_CODEPAGE_864=m 10306+CONFIG_NLS_CODEPAGE_865=m 10307+CONFIG_NLS_CODEPAGE_866=m 10308+CONFIG_NLS_CODEPAGE_869=m 10309+CONFIG_NLS_CODEPAGE_936=y 10310+CONFIG_NLS_CODEPAGE_950=m 10311+CONFIG_NLS_CODEPAGE_932=m 10312+CONFIG_NLS_CODEPAGE_949=m 10313+CONFIG_NLS_CODEPAGE_874=m 10314+CONFIG_NLS_ISO8859_8=m 10315+CONFIG_NLS_CODEPAGE_1250=m 10316+CONFIG_NLS_CODEPAGE_1251=m 10317+CONFIG_NLS_ASCII=y 10318+CONFIG_NLS_ISO8859_1=y 10319+CONFIG_NLS_ISO8859_2=m 10320+CONFIG_NLS_ISO8859_3=m 10321+CONFIG_NLS_ISO8859_4=m 10322+CONFIG_NLS_ISO8859_5=m 10323+CONFIG_NLS_ISO8859_6=m 10324+CONFIG_NLS_ISO8859_7=m 10325+CONFIG_NLS_ISO8859_9=m 10326+CONFIG_NLS_ISO8859_13=m 10327+CONFIG_NLS_ISO8859_14=m 10328+CONFIG_NLS_ISO8859_15=m 10329+CONFIG_NLS_KOI8_R=m 10330+CONFIG_NLS_KOI8_U=m 10331+# CONFIG_NLS_MAC_ROMAN is not set 10332+# CONFIG_NLS_MAC_CELTIC is not set 10333+# CONFIG_NLS_MAC_CENTEURO is not set 10334+# CONFIG_NLS_MAC_CROATIAN is not set 10335+# CONFIG_NLS_MAC_CYRILLIC is not set 10336+# CONFIG_NLS_MAC_GAELIC is not set 10337+# CONFIG_NLS_MAC_GREEK is not set 10338+# CONFIG_NLS_MAC_ICELAND is not set 10339+# CONFIG_NLS_MAC_INUIT is not set 10340+# CONFIG_NLS_MAC_ROMANIAN is not set 10341+# CONFIG_NLS_MAC_TURKISH is not set 10342+CONFIG_NLS_UTF8=y 10343+# CONFIG_DLM is not set 10344+ 10345+# 10346+# Security options 10347+# 10348+CONFIG_KEYS=y 10349+# CONFIG_PERSISTENT_KEYRINGS is not set 10350+# CONFIG_BIG_KEYS is not set 10351+# CONFIG_ENCRYPTED_KEYS is not set 10352+# CONFIG_KEY_DH_OPERATIONS is not set 10353+# CONFIG_SECURITY_DMESG_RESTRICT is not set 10354+# CONFIG_SECURITY is not set 10355+# CONFIG_SECURITYFS is not set 10356+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y 10357+# CONFIG_HARDENED_USERCOPY is not set 10358+# CONFIG_FORTIFY_SOURCE is not set 10359+# CONFIG_STATIC_USERMODEHELPER is not set 10360+CONFIG_DEFAULT_SECURITY_DAC=y 10361+CONFIG_DEFAULT_SECURITY="" 10362+CONFIG_CRYPTO=y 10363+ 10364+# 10365+# Crypto core or helper 10366+# 10367+CONFIG_CRYPTO_ALGAPI=y 10368+CONFIG_CRYPTO_ALGAPI2=y 10369+CONFIG_CRYPTO_AEAD=m 10370+CONFIG_CRYPTO_AEAD2=y 10371+CONFIG_CRYPTO_BLKCIPHER2=y 10372+CONFIG_CRYPTO_HASH=y 10373+CONFIG_CRYPTO_HASH2=y 10374+CONFIG_CRYPTO_RNG=y 10375+CONFIG_CRYPTO_RNG2=y 10376+CONFIG_CRYPTO_RNG_DEFAULT=m 10377+CONFIG_CRYPTO_AKCIPHER2=y 10378+CONFIG_CRYPTO_KPP2=y 10379+CONFIG_CRYPTO_ACOMP2=y 10380+# CONFIG_CRYPTO_RSA is not set 10381+# CONFIG_CRYPTO_DH is not set 10382+# CONFIG_CRYPTO_ECDH is not set 10383+CONFIG_CRYPTO_MANAGER=m 10384+CONFIG_CRYPTO_MANAGER2=y 10385+# CONFIG_CRYPTO_USER is not set 10386+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y 10387+# CONFIG_CRYPTO_GF128MUL is not set 10388+CONFIG_CRYPTO_NULL=m 10389+CONFIG_CRYPTO_NULL2=y 10390+# CONFIG_CRYPTO_PCRYPT is not set 10391+CONFIG_CRYPTO_WORKQUEUE=y 10392+# CONFIG_CRYPTO_CRYPTD is not set 10393+# CONFIG_CRYPTO_MCRYPTD is not set 10394+# CONFIG_CRYPTO_AUTHENC is not set 10395+# CONFIG_CRYPTO_TEST is not set 10396+ 10397+# 10398+# Authenticated Encryption with Associated Data 10399+# 10400+# CONFIG_CRYPTO_CCM is not set 10401+# CONFIG_CRYPTO_GCM is not set 10402+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set 10403+# CONFIG_CRYPTO_AEGIS128 is not set 10404+# CONFIG_CRYPTO_AEGIS128L is not set 10405+# CONFIG_CRYPTO_AEGIS256 is not set 10406+# CONFIG_CRYPTO_MORUS640 is not set 10407+# CONFIG_CRYPTO_MORUS1280 is not set 10408+# CONFIG_CRYPTO_SEQIV is not set 10409+CONFIG_CRYPTO_ECHAINIV=m 10410+ 10411+# 10412+# Block modes 10413+# 10414+# CONFIG_CRYPTO_CBC is not set 10415+# CONFIG_CRYPTO_CFB is not set 10416+# CONFIG_CRYPTO_CTR is not set 10417+# CONFIG_CRYPTO_CTS is not set 10418+# CONFIG_CRYPTO_ECB is not set 10419+# CONFIG_CRYPTO_LRW is not set 10420+# CONFIG_CRYPTO_PCBC is not set 10421+# CONFIG_CRYPTO_XTS is not set 10422+# CONFIG_CRYPTO_KEYWRAP is not set 10423+ 10424+# 10425+# Hash modes 10426+# 10427+# CONFIG_CRYPTO_CMAC is not set 10428+CONFIG_CRYPTO_HMAC=m 10429+# CONFIG_CRYPTO_XCBC is not set 10430+# CONFIG_CRYPTO_VMAC is not set 10431+ 10432+# 10433+# Digest 10434+# 10435+CONFIG_CRYPTO_CRC32C=y 10436+# CONFIG_CRYPTO_CRC32 is not set 10437+# CONFIG_CRYPTO_CRCT10DIF is not set 10438+# CONFIG_CRYPTO_GHASH is not set 10439+# CONFIG_CRYPTO_POLY1305 is not set 10440+# CONFIG_CRYPTO_MD4 is not set 10441+# CONFIG_CRYPTO_MD5 is not set 10442+# CONFIG_CRYPTO_MICHAEL_MIC is not set 10443+# CONFIG_CRYPTO_RMD128 is not set 10444+# CONFIG_CRYPTO_RMD160 is not set 10445+# CONFIG_CRYPTO_RMD256 is not set 10446+# CONFIG_CRYPTO_RMD320 is not set 10447+# CONFIG_CRYPTO_SHA1 is not set 10448+CONFIG_CRYPTO_SHA256=m 10449+# CONFIG_CRYPTO_SHA512 is not set 10450+# CONFIG_CRYPTO_SHA3 is not set 10451+# CONFIG_CRYPTO_SM3 is not set 10452+# CONFIG_CRYPTO_TGR192 is not set 10453+# CONFIG_CRYPTO_WP512 is not set 10454+ 10455+# 10456+# Ciphers 10457+# 10458+CONFIG_CRYPTO_AES=y 10459+# CONFIG_CRYPTO_AES_TI is not set 10460+# CONFIG_CRYPTO_ANUBIS is not set 10461+# CONFIG_CRYPTO_ARC4 is not set 10462+# CONFIG_CRYPTO_BLOWFISH is not set 10463+# CONFIG_CRYPTO_CAMELLIA is not set 10464+# CONFIG_CRYPTO_CAST5 is not set 10465+# CONFIG_CRYPTO_CAST6 is not set 10466+# CONFIG_CRYPTO_DES is not set 10467+# CONFIG_CRYPTO_FCRYPT is not set 10468+# CONFIG_CRYPTO_KHAZAD is not set 10469+# CONFIG_CRYPTO_SALSA20 is not set 10470+# CONFIG_CRYPTO_CHACHA20 is not set 10471+# CONFIG_CRYPTO_SEED is not set 10472+# CONFIG_CRYPTO_SERPENT is not set 10473+# CONFIG_CRYPTO_SM4 is not set 10474+# CONFIG_CRYPTO_TEA is not set 10475+# CONFIG_CRYPTO_TWOFISH is not set 10476+ 10477+# 10478+# Compression 10479+# 10480+CONFIG_CRYPTO_DEFLATE=y 10481+CONFIG_CRYPTO_LZO=y 10482+# CONFIG_CRYPTO_842 is not set 10483+# CONFIG_CRYPTO_LZ4 is not set 10484+# CONFIG_CRYPTO_LZ4HC is not set 10485+# CONFIG_CRYPTO_ZSTD is not set 10486+ 10487+# 10488+# Random Number Generation 10489+# 10490+CONFIG_CRYPTO_ANSI_CPRNG=y 10491+CONFIG_CRYPTO_DRBG_MENU=m 10492+CONFIG_CRYPTO_DRBG_HMAC=y 10493+# CONFIG_CRYPTO_DRBG_HASH is not set 10494+CONFIG_CRYPTO_DRBG=m 10495+CONFIG_CRYPTO_JITTERENTROPY=m 10496+# CONFIG_CRYPTO_USER_API_HASH is not set 10497+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set 10498+# CONFIG_CRYPTO_USER_API_RNG is not set 10499+# CONFIG_CRYPTO_USER_API_AEAD is not set 10500+CONFIG_CRYPTO_HW=y 10501+# CONFIG_CRYPTO_DEV_CCREE is not set 10502+# CONFIG_ASYMMETRIC_KEY_TYPE is not set 10503+ 10504+# 10505+# Certificates for signature checking 10506+# 10507+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set 10508+ 10509+# 10510+# Library routines 10511+# 10512+CONFIG_BITREVERSE=y 10513+CONFIG_HAVE_ARCH_BITREVERSE=y 10514+CONFIG_RATIONAL=y 10515+CONFIG_GENERIC_STRNCPY_FROM_USER=y 10516+CONFIG_GENERIC_STRNLEN_USER=y 10517+CONFIG_GENERIC_NET_UTILS=y 10518+CONFIG_GENERIC_PCI_IOMAP=y 10519+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y 10520+# CONFIG_CRC_CCITT is not set 10521+CONFIG_CRC16=y 10522+# CONFIG_CRC_T10DIF is not set 10523+# CONFIG_CRC_ITU_T is not set 10524+CONFIG_CRC32=y 10525+# CONFIG_CRC32_SELFTEST is not set 10526+CONFIG_CRC32_SLICEBY8=y 10527+# CONFIG_CRC32_SLICEBY4 is not set 10528+# CONFIG_CRC32_SARWATE is not set 10529+# CONFIG_CRC32_BIT is not set 10530+# CONFIG_CRC64 is not set 10531+# CONFIG_CRC4 is not set 10532+# CONFIG_CRC7 is not set 10533+CONFIG_LIBCRC32C=m 10534+# CONFIG_CRC8 is not set 10535+# CONFIG_RANDOM32_SELFTEST is not set 10536+CONFIG_ZLIB_INFLATE=y 10537+CONFIG_ZLIB_DEFLATE=y 10538+CONFIG_LZO_COMPRESS=y 10539+CONFIG_LZO_DECOMPRESS=y 10540+CONFIG_XZ_DEC=y 10541+CONFIG_XZ_DEC_X86=y 10542+CONFIG_XZ_DEC_POWERPC=y 10543+CONFIG_XZ_DEC_IA64=y 10544+CONFIG_XZ_DEC_ARM=y 10545+CONFIG_XZ_DEC_ARMTHUMB=y 10546+CONFIG_XZ_DEC_SPARC=y 10547+CONFIG_XZ_DEC_BCJ=y 10548+# CONFIG_XZ_DEC_TEST is not set 10549+CONFIG_GENERIC_ALLOCATOR=y 10550+CONFIG_ASSOCIATIVE_ARRAY=y 10551+CONFIG_HAS_IOMEM=y 10552+CONFIG_HAS_IOPORT_MAP=y 10553+CONFIG_HAS_DMA=y 10554+CONFIG_NEED_DMA_MAP_STATE=y 10555+CONFIG_HAVE_GENERIC_DMA_COHERENT=y 10556+CONFIG_SGL_ALLOC=y 10557+CONFIG_CPU_RMAP=y 10558+CONFIG_DQL=y 10559+CONFIG_NLATTR=y 10560+# CONFIG_CORDIC is not set 10561+# CONFIG_DDR is not set 10562+# CONFIG_IRQ_POLL is not set 10563+CONFIG_LIBFDT=y 10564+CONFIG_OID_REGISTRY=y 10565+CONFIG_SG_POOL=y 10566+CONFIG_ARCH_HAS_SG_CHAIN=y 10567+CONFIG_SBITMAP=y 10568+# CONFIG_STRING_SELFTEST is not set 10569+ 10570+# 10571+# Kernel hacking 10572+# 10573+ 10574+# 10575+# printk and dmesg options 10576+# 10577+# CONFIG_PRINTK_TIME is not set 10578+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 10579+CONFIG_CONSOLE_LOGLEVEL_QUIET=4 10580+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 10581+# CONFIG_BOOT_PRINTK_DELAY is not set 10582+# CONFIG_DYNAMIC_DEBUG is not set 10583+ 10584+# 10585+# Compile-time checks and compiler options 10586+# 10587+# CONFIG_DEBUG_INFO is not set 10588+CONFIG_ENABLE_MUST_CHECK=y 10589+CONFIG_FRAME_WARN=1024 10590+# CONFIG_STRIP_ASM_SYMS is not set 10591+# CONFIG_READABLE_ASM is not set 10592+# CONFIG_UNUSED_SYMBOLS is not set 10593+# CONFIG_PAGE_OWNER is not set 10594+# CONFIG_DEBUG_FS is not set 10595+# CONFIG_HEADERS_CHECK is not set 10596+# CONFIG_DEBUG_SECTION_MISMATCH is not set 10597+CONFIG_SECTION_MISMATCH_WARN_ONLY=y 10598+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set 10599+# CONFIG_MAGIC_SYSRQ is not set 10600+CONFIG_DEBUG_KERNEL=y 10601+ 10602+# 10603+# Memory Debugging 10604+# 10605+# CONFIG_PAGE_EXTENSION is not set 10606+# CONFIG_DEBUG_PAGEALLOC is not set 10607+# CONFIG_PAGE_POISONING is not set 10608+# CONFIG_DEBUG_RODATA_TEST is not set 10609+# CONFIG_DEBUG_OBJECTS is not set 10610+# CONFIG_SLUB_DEBUG_ON is not set 10611+# CONFIG_SLUB_STATS is not set 10612+CONFIG_HAVE_DEBUG_KMEMLEAK=y 10613+# CONFIG_DEBUG_KMEMLEAK is not set 10614+# CONFIG_DEBUG_STACK_USAGE is not set 10615+# CONFIG_DEBUG_VM is not set 10616+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y 10617+# CONFIG_DEBUG_VIRTUAL is not set 10618+CONFIG_DEBUG_MEMORY_INIT=y 10619+# CONFIG_DEBUG_PER_CPU_MAPS is not set 10620+# CONFIG_DEBUG_HIGHMEM is not set 10621+CONFIG_ARCH_HAS_KCOV=y 10622+CONFIG_CC_HAS_SANCOV_TRACE_PC=y 10623+# CONFIG_KCOV is not set 10624+# CONFIG_DEBUG_SHIRQ is not set 10625+ 10626+# 10627+# Debug Lockups and Hangs 10628+# 10629+# CONFIG_SOFTLOCKUP_DETECTOR is not set 10630+# CONFIG_DETECT_HUNG_TASK is not set 10631+# CONFIG_WQ_WATCHDOG is not set 10632+# CONFIG_PANIC_ON_OOPS is not set 10633+CONFIG_PANIC_ON_OOPS_VALUE=0 10634+CONFIG_PANIC_TIMEOUT=0 10635+CONFIG_SCHED_DEBUG=y 10636+# CONFIG_SCHEDSTATS is not set 10637+# CONFIG_SCHED_STACK_END_CHECK is not set 10638+# CONFIG_DEBUG_TIMEKEEPING is not set 10639+ 10640+# 10641+# Lock Debugging (spinlocks, mutexes, etc...) 10642+# 10643+CONFIG_LOCK_DEBUGGING_SUPPORT=y 10644+# CONFIG_PROVE_LOCKING is not set 10645+# CONFIG_LOCK_STAT is not set 10646+# CONFIG_DEBUG_RT_MUTEXES is not set 10647+# CONFIG_DEBUG_SPINLOCK is not set 10648+# CONFIG_DEBUG_MUTEXES is not set 10649+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set 10650+# CONFIG_DEBUG_RWSEMS is not set 10651+# CONFIG_DEBUG_LOCK_ALLOC is not set 10652+# CONFIG_DEBUG_ATOMIC_SLEEP is not set 10653+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 10654+# CONFIG_LOCK_TORTURE_TEST is not set 10655+# CONFIG_WW_MUTEX_SELFTEST is not set 10656+CONFIG_STACKTRACE=y 10657+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set 10658+# CONFIG_DEBUG_KOBJECT is not set 10659+CONFIG_DEBUG_BUGVERBOSE=y 10660+# CONFIG_DEBUG_LIST is not set 10661+# CONFIG_DEBUG_PI_LIST is not set 10662+# CONFIG_DEBUG_SG is not set 10663+# CONFIG_DEBUG_NOTIFIERS is not set 10664+# CONFIG_DEBUG_CREDENTIALS is not set 10665+ 10666+# 10667+# RCU Debugging 10668+# 10669+# CONFIG_RCU_PERF_TEST is not set 10670+# CONFIG_RCU_TORTURE_TEST is not set 10671+CONFIG_RCU_CPU_STALL_TIMEOUT=60 10672+# CONFIG_RCU_TRACE is not set 10673+# CONFIG_RCU_EQS_DEBUG is not set 10674+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set 10675+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set 10676+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set 10677+# CONFIG_NOTIFIER_ERROR_INJECTION is not set 10678+# CONFIG_FAULT_INJECTION is not set 10679+# CONFIG_LATENCYTOP is not set 10680+CONFIG_HAVE_FUNCTION_TRACER=y 10681+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y 10682+CONFIG_HAVE_DYNAMIC_FTRACE=y 10683+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y 10684+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y 10685+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y 10686+CONFIG_HAVE_C_RECORDMCOUNT=y 10687+CONFIG_TRACING_SUPPORT=y 10688+# CONFIG_FTRACE is not set 10689+# CONFIG_DMA_API_DEBUG is not set 10690+CONFIG_RUNTIME_TESTING_MENU=y 10691+# CONFIG_LKDTM is not set 10692+# CONFIG_TEST_LIST_SORT is not set 10693+# CONFIG_TEST_SORT is not set 10694+# CONFIG_BACKTRACE_SELF_TEST is not set 10695+# CONFIG_RBTREE_TEST is not set 10696+# CONFIG_INTERVAL_TREE_TEST is not set 10697+# CONFIG_PERCPU_TEST is not set 10698+# CONFIG_ATOMIC64_SELFTEST is not set 10699+# CONFIG_TEST_HEXDUMP is not set 10700+# CONFIG_TEST_STRING_HELPERS is not set 10701+# CONFIG_TEST_KSTRTOX is not set 10702+# CONFIG_TEST_PRINTF is not set 10703+# CONFIG_TEST_BITMAP is not set 10704+# CONFIG_TEST_BITFIELD is not set 10705+# CONFIG_TEST_UUID is not set 10706+# CONFIG_TEST_OVERFLOW is not set 10707+# CONFIG_TEST_RHASHTABLE is not set 10708+# CONFIG_TEST_HASH is not set 10709+# CONFIG_TEST_IDA is not set 10710+# CONFIG_TEST_LKM is not set 10711+# CONFIG_TEST_USER_COPY is not set 10712+# CONFIG_TEST_BPF is not set 10713+# CONFIG_FIND_BIT_BENCHMARK is not set 10714+# CONFIG_TEST_FIRMWARE is not set 10715+# CONFIG_TEST_SYSCTL is not set 10716+# CONFIG_TEST_UDELAY is not set 10717+# CONFIG_TEST_STATIC_KEYS is not set 10718+# CONFIG_TEST_KMOD is not set 10719+# CONFIG_MEMTEST is not set 10720+# CONFIG_BUG_ON_DATA_CORRUPTION is not set 10721+# CONFIG_SAMPLES is not set 10722+CONFIG_HAVE_ARCH_KGDB=y 10723+# CONFIG_KGDB is not set 10724+# CONFIG_UBSAN is not set 10725+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y 10726+CONFIG_STRICT_DEVMEM=y 10727+# CONFIG_IO_STRICT_DEVMEM is not set 10728+# CONFIG_ARM_PTDUMP_DEBUGFS is not set 10729+# CONFIG_DEBUG_WX is not set 10730+CONFIG_ARM_UNWIND=y 10731+# CONFIG_DEBUG_USER is not set 10732+# CONFIG_DEBUG_LL is not set 10733+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" 10734+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" 10735+# CONFIG_PID_IN_CONTEXTIDR is not set 10736+# CONFIG_CORESIGHT is not set 10737diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h 10738index ea9bd0889..dbe96664b 100644 10739--- a/arch/arm/include/asm/mach/pci.h 10740+++ b/arch/arm/include/asm/mach/pci.h 10741@@ -9,6 +9,7 @@ 10742 #define __ASM_MACH_PCI_H 10743 10744 #include <linux/ioport.h> 10745+#include <linux/msi.h> 10746 10747 struct pci_sys_data; 10748 struct pci_ops; 10749@@ -16,7 +17,25 @@ struct pci_bus; 10750 struct pci_host_bridge; 10751 struct device; 10752 10753+#ifdef CONFIG_PCI_MSI 10754+#define HISI_PCI_MSI_NR (8 * 32) 10755+struct hisi_msi { 10756+ struct msi_controller chip; 10757+ DECLARE_BITMAP(used, HISI_PCI_MSI_NR); 10758+ struct irq_domain *domain; 10759+ unsigned long pages; 10760+ struct mutex lock; 10761+ int irq; 10762+}; 10763+#endif 10764 struct hw_pci { 10765+#ifdef CONFIG_PCI_DOMAINS 10766+ int domain; 10767+#endif 10768+#ifdef CONFIG_PCI_MSI 10769+ struct hisi_msi msi; 10770+#endif 10771+ struct device *dev; 10772 struct pci_ops *ops; 10773 int nr_controllers; 10774 void **private_data; 10775@@ -26,12 +45,17 @@ struct hw_pci { 10776 void (*postinit)(void); 10777 u8 (*swizzle)(struct pci_dev *dev, u8 *pin); 10778 int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); 10779+ void (*add_bus)(struct pci_bus *bus); 10780+ void (*remove_bus)(struct pci_bus *bus); 10781 }; 10782 10783 /* 10784 * Per-controller structure 10785 */ 10786 struct pci_sys_data { 10787+#ifdef CONFIG_PCI_DOMAINS 10788+ int domain; 10789+#endif 10790 struct list_head node; 10791 int busnr; /* primary bus number */ 10792 u64 mem_offset; /* bus->cpu memory mapping offset */ 10793diff --git a/arch/arm/include/asm/vdso/gettimeofday.h b/arch/arm/include/asm/vdso/gettimeofday.h 10794index 2134cbd54..6f078fedb 100644 10795--- a/arch/arm/include/asm/vdso/gettimeofday.h 10796+++ b/arch/arm/include/asm/vdso/gettimeofday.h 10797@@ -109,14 +109,14 @@ static __always_inline int clock_getres32_fallback( 10798 10799 static inline bool arm_vdso_hres_capable(void) 10800 { 10801- return IS_ENABLED(CONFIG_ARM_ARCH_TIMER); 10802+ return 0; 10803 } 10804 #define __arch_vdso_hres_capable arm_vdso_hres_capable 10805 10806 static __always_inline u64 __arch_get_hw_counter(int clock_mode, 10807 const struct vdso_data *vd) 10808 { 10809-#ifdef CONFIG_ARM_ARCH_TIMER 10810+#if defined (CONFIG_ARM_ARCH_TIMER) && defined(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS) 10811 u64 cycle_now; 10812 10813 /* 10814diff --git a/arch/arm/mach-hibvt/Kconfig b/arch/arm/mach-hibvt/Kconfig 10815new file mode 100644 10816index 000000000..89bedcb95 10817--- /dev/null 10818+++ b/arch/arm/mach-hibvt/Kconfig 10819@@ -0,0 +1,269 @@ 10820+config ARCH_HISI_BVT 10821+ bool "Hisilicon BVT SoC Support" 10822+ select ARM_AMBA 10823+ select ARM_GIC if ARCH_MULTI_V7 10824+ select ARM_VIC if ARCH_MULTI_V5 10825+ select ARM_TIMER_SP804 10826+ select POWER_RESET 10827+ select POWER_SUPPLY 10828+ 10829+if ARCH_HISI_BVT 10830+ 10831+menu "Hisilicon BVT platform type" 10832+ 10833+config ARCH_HI3521DV200 10834+ bool "Hisilicon Hi3521DV200 Cortex-A7 family" 10835+ depends on ARCH_MULTI_V7 10836+ select HAVE_ARM_ARCH_TIMER 10837+ select PINCTRL 10838+ select POWER_RESET_HISI 10839+ help 10840+ Support for Hisilicon Hi3521DV200 Soc family. 10841+ 10842+config ARCH_HI3520DV500 10843+ bool "Hisilicon Hi3520DV500 Cortex-A7 family" 10844+ depends on ARCH_MULTI_V7 10845+ select HAVE_ARM_ARCH_TIMER 10846+ select PINCTRL 10847+ select POWER_RESET_HISI 10848+ help 10849+ Support for Hisilicon Hi3520DV500 Soc family. 10850+ 10851+config ARCH_HI3516A 10852+ bool "Hisilicon Hi3516A Cortex-A7(Single) family" 10853+ depends on ARCH_MULTI_V7 10854+ select HAVE_ARM_ARCH_TIMER 10855+ select ARM_GIC 10856+ select ARCH_HAS_RESET_CONTROLLER 10857+ select RESET_CONTROLLER 10858+ help 10859+ Support for Hisilicon Hi3516A Soc family. 10860+ 10861+config ARCH_HI3516CV500 10862+ bool "Hisilicon Hi3516CV500 Cortex-A7 family" 10863+ depends on ARCH_MULTI_V7 10864+ select HAVE_ARM_ARCH_TIMER 10865+ select PINCTRL 10866+ select POWER_RESET_HISI 10867+ help 10868+ Support for Hisilicon Hi3516CV500 Soc family. 10869+ 10870+config ARCH_HI3516DV300 10871+ bool "Hisilicon Hi3516DV300 Cortex-A7 family" 10872+ depends on ARCH_MULTI_V7 10873+ select HAVE_ARM_ARCH_TIMER 10874+ select PINCTRL 10875+ select POWER_RESET_HISI 10876+ help 10877+ Support for Hisilicon Hi3516DV300 Soc family. 10878+ 10879+config ARCH_HI3516EV200 10880+ bool "Hisilicon Hi3516EV200 Cortex-A7 family" 10881+ depends on ARCH_MULTI_V7 10882+ select HAVE_ARM_ARCH_TIMER 10883+ select PINCTRL 10884+ select POWER_RESET_HISI 10885+ help 10886+ Support for Hisilicon Hi3516EV200 Soc family. 10887+ 10888+config ARCH_HI3516EV300 10889+ bool "Hisilicon Hi3516EV300 Cortex-A7 family" 10890+ depends on ARCH_MULTI_V7 10891+ select HAVE_ARM_ARCH_TIMER 10892+ select PINCTRL 10893+ select POWER_RESET_HISI 10894+ help 10895+ Support for Hisilicon Hi3516EV300 Soc family. 10896+ 10897+config ARCH_HI3518EV300 10898+ bool "Hisilicon Hi3518EV300 Cortex-A7 family" 10899+ depends on ARCH_MULTI_V7 10900+ select HAVE_ARM_ARCH_TIMER 10901+ select PINCTRL 10902+ select POWER_RESET_HISI 10903+ help 10904+ Support for Hisilicon Hi3518EV300 Soc family. 10905+ 10906+config ARCH_HI3516DV200 10907+ bool "Hisilicon Hi3516DV200 Cortex-A7 family" 10908+ depends on ARCH_MULTI_V7 10909+ select HAVE_ARM_ARCH_TIMER 10910+ select PINCTRL 10911+ select POWER_RESET_HISI 10912+ help 10913+ Support for Hisilicon Hi3516DV200 Soc family. 10914+config ARCH_HI3556V200 10915+ bool "Hisilicon Hi3556V200 Cortex-A7 family" 10916+ depends on ARCH_MULTI_V7 10917+ select HAVE_ARM_ARCH_TIMER 10918+ select PINCTRL 10919+ select POWER_RESET_HISI 10920+ help 10921+ Support for Hisilicon Hi3556V200 Soc family. 10922+ 10923+config ARCH_HI3559V200 10924+ bool "Hisilicon Hi3559V200 Cortex-A7 family" 10925+ depends on ARCH_MULTI_V7 10926+ select HAVE_ARM_ARCH_TIMER 10927+ select PINCTRL 10928+ select POWER_RESET_HISI 10929+ help 10930+ Support for Hisilicon Hi3559V200 Soc family. 10931+ 10932+config ARCH_HI3518EV20X 10933+ bool "Hisilicon Hi3518ev20x ARM926T(Single) family" 10934+ depends on ARCH_MULTI_V5 10935+ select PINCTRL 10936+ select PINCTRL_SINGLE 10937+ help 10938+ Support for Hisilicon Hi3518ev20x Soc family. 10939+ 10940+config ARCH_HI3536DV100 10941+ bool "Hisilicon Hi3536DV100 Cortex-A7(Single) family" 10942+ depends on ARCH_MULTI_V7 10943+ select HAVE_ARM_ARCH_TIMER 10944+ select PINCTRL 10945+ help 10946+ Support for Hisilicon Hi3536DV100 Soc family. 10947+ 10948+config ARCH_HI3521A 10949+ bool "Hisilicon Hi3521A A7(Single) family" 10950+ depends on ARCH_MULTI_V7 10951+ select HAVE_ARM_ARCH_TIMER 10952+ select ARM_GIC 10953+ select PINCTRL 10954+ select PINCTRL_SINGLE 10955+ help 10956+ Support for Hisilicon Hi3521a Soc family. 10957+ 10958+config ARCH_HI3531A 10959+ bool "Hisilicon Hi3531A A9 family" if ARCH_MULTI_V7 10960+ select HAVE_ARM_ARCH_TIMER 10961+ select ARM_GIC 10962+ select CACHE_L2X0 10963+ select PINCTRL 10964+ select PINCTRL_SINGLE 10965+ select HAVE_ARM_SCU if SMP 10966+ select NEED_MACH_IO_H if PCI 10967+ help 10968+ Support for Hisilicon Hi3531a Soc family. 10969+ 10970+config ARCH_HI3556AV100 10971+ bool "Hisilicon Hi3556AV100 Cortex-a53 family" if ARCH_MULTI_V7 10972+ select HAVE_ARM_ARCH_TIMER 10973+ select ARM_CCI 10974+ select ARCH_HAS_RESET_CONTROLLER 10975+ select RESET_CONTROLLER 10976+ select PMC if SMP 10977+ help 10978+ Support for Hisilicon Hi3556AV100 Soc family 10979+if ARCH_HI3556AV100 10980+ 10981+config PMC 10982+ bool 10983+ depends on ARCH_HI3556AV100 10984+ help 10985+ support power control for Hi3556AV100 Cortex-a53 10986+ 10987+endif 10988+ 10989+config ARCH_HI3519AV100 10990+ bool "Hisilicon Hi3519AV100 Cortex-a53 family" if ARCH_MULTI_V7 10991+ select HAVE_ARM_ARCH_TIMER 10992+ select ARM_CCI 10993+ select ARM_GIC 10994+ select ARCH_HAS_RESET_CONTROLLER 10995+ select RESET_CONTROLLER 10996+ select NEED_MACH_IO_H if PCI 10997+ select PMC if SMP 10998+ help 10999+ Support for Hisilicon Hi3519AV100 Soc family 11000+if ARCH_HI3519AV100 11001+ 11002+config PMC 11003+ bool 11004+ depends on ARCH_HI3519AV100 11005+ help 11006+ support power control for Hi3519AV100 Cortex-a53 11007+ 11008+endif 11009+ 11010+config ARCH_HI3568V100 11011+ bool "Hisilicon Hi3568V100 Cortex-a53 family" if ARCH_MULTI_V7 11012+ select HAVE_ARM_ARCH_TIMER 11013+ select ARM_CCI 11014+ select ARM_GIC 11015+ select ARCH_HAS_RESET_CONTROLLER 11016+ select RESET_CONTROLLER 11017+ select NEED_MACH_IO_H if PCI 11018+ select PMC if SMP 11019+ help 11020+ Support for Hisilicon Hi3568V100 Soc family 11021+if ARCH_HI3568V100 11022+ 11023+config PMC 11024+ bool 11025+ depends on ARCH_HI3568V100 11026+ help 11027+ support power control for Hi3568V100 Cortex-a53 11028+ 11029+endif 11030+ 11031+config ARCH_HISI_BVT_AMP 11032+ bool "Hisilicon AMP solution support" 11033+ depends on ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3516CV500 || ARCH_HI3516DV300 || ARCH_HI3556V200 || ARCH_HI3559V200 || ARCH_HI3562V100 || ARCH_HI3566V100 || ARCH_HI3568V100 11034+ help 11035+ support for Hisilicon AMP solution 11036+ 11037+config HISI_MC 11038+ bool "Hisilicon mc platform solution" 11039+ default n 11040+ help 11041+ support for Hisilicon mc platform solution 11042+ 11043+config AMP_ZRELADDR 11044+ hex 'amp zreladdr' 11045+ depends on ARCH_HISI_BVT_AMP 11046+ default "0x32008000" if ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100 11047+ default "0x82008000" if ARCH_HI3516CV500 || ARCH_HI3516DV300 || ARCH_HI3556V200 || ARCH_HI3559V200 || ARCH_HI3562V100 || ARCH_HI3566V100 11048+ default "0x42008000" if ARCH_HI3516EV200 || ARCH_HI3516EV300 || ARCH_HI3518EV300 || ARCH_HI3516DV200 11049+config HI_ZRELADDR 11050+ hex 'zreladdr' 11051+ default "0x40008000" if ARCH_HI3521DV200 11052+ default "0x40008000" if ARCH_HI3520DV500 11053+ default "0x80008000" if ARCH_HI3516CV500 11054+ default "0x80008000" if ARCH_HI3516DV300 11055+ default "0x80008000" if ARCH_HI3556V200 11056+ default "0x80008000" if ARCH_HI3559V200 11057+ default "0x80008000" if ARCH_HI3562V100 11058+ default "0x80008000" if ARCH_HI3566V100 11059+ default "0x80008000" if ARCH_HI3516A 11060+ default "0x80008000" if ARCH_HI3518EV20X 11061+ default "0x80008000" if ARCH_HI3536DV100 11062+ default "0x80008000" if ARCH_HI3521A 11063+ default "0x40008000" if ARCH_HI3531A 11064+ default "0x40008000" if ARCH_HI3516EV200 || ARCH_HI3516EV300 || ARCH_HI3518EV300 || ARCH_HI3516DV200 11065+ default "0x22008000" if ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100 11066+ 11067+config HI_PARAMS_PHYS 11068+ hex 'params_phys' 11069+ default "0x00000100" 11070+ 11071+config HI_INITRD_PHYS 11072+ hex 'initrd_phys' 11073+ default "0x00800000" 11074+ 11075+endmenu 11076+ 11077+if ARCH_HI3516DV300 11078+ 11079+config BLACKBOX_HI3516DV300 11080+ bool "Support BlackBox saving fault logs with pstore for hi3516dv300" 11081+ depends on PSTORE_BLACKBOX 11082+ depends on BLACKBOX_STORAGE_BY_PSTORE_BLK 11083+ help 11084+ Save fault logs with pstore for Hi3516DV300 when oops or panic occurs. 11085+ 11086+endif 11087+ 11088+endif 11089diff --git a/arch/arm/mach-hibvt/Makefile b/arch/arm/mach-hibvt/Makefile 11090new file mode 100644 11091index 000000000..8c4802fd1 11092--- /dev/null 11093+++ b/arch/arm/mach-hibvt/Makefile 11094@@ -0,0 +1,34 @@ 11095+# 11096+# Makefile for Hisilicon processors family 11097+# 11098+ 11099+obj-$(CONFIG_ARCH_HI3521DV200) += mach-hi3521dv200.o 11100+obj-$(CONFIG_ARCH_HI3520DV500) += mach-hi3521dv200.o 11101+obj-$(CONFIG_ARCH_HI3516A) += mach-hi3516a.o 11102+obj-$(CONFIG_ARCH_HI3516CV500) += mach-hi3516cv500.o 11103+obj-$(CONFIG_ARCH_HI3516EV200) += mach-hi3516ev200.o 11104+obj-$(CONFIG_ARCH_HI3516EV300) += mach-hi3516ev300.o 11105+obj-$(CONFIG_ARCH_HI3518EV300) += mach-hi3518ev300.o 11106+obj-$(CONFIG_ARCH_HI3516DV200) += mach-hi3516dv200.o 11107+obj-$(CONFIG_ARCH_HI3516DV300) += mach-hi3516dv300.o 11108+obj-$(CONFIG_ARCH_HI3556V200) += mach-hi3556v200.o 11109+obj-$(CONFIG_ARCH_HI3559V200) += mach-hi3559v200.o 11110+obj-$(CONFIG_ARCH_HI3562V100) += mach-hi3559v200.o 11111+obj-$(CONFIG_ARCH_HI3566V100) += mach-hi3559v200.o 11112+obj-$(CONFIG_ARCH_HI3518EV20X) += mach-hi3518ev20x.o 11113+obj-$(CONFIG_ARCH_HI3536DV100) += mach-hi3536dv100.o 11114+obj-$(CONFIG_ARCH_HI3521A) += mach-hi3521a.o 11115+obj-$(CONFIG_ARCH_HI3531A) += mach-hi3531a.o 11116+obj-$(CONFIG_ARCH_HI3556AV100) += mach-hi3556av100.o 11117+obj-$(CONFIG_ARCH_HI3519AV100) += mach-hi3519av100.o 11118+obj-$(CONFIG_ARCH_HI3568V100) += mach-hi3519av100.o 11119+ 11120+ 11121+obj-$(CONFIG_SMP) += platsmp.o 11122+ 11123+ifdef CONFIG_BLACKBOX_HI3516DV300 11124+ 11125+obj-$(CONFIG_BLACKBOX_STORAGE_BY_PSTORE_BLK) += system_adapter.o 11126+obj-$(CONFIG_BLACKBOX_STORAGE_BY_MEMORY) += system_adapter_by_memory.o 11127+ 11128+endif 11129diff --git a/arch/arm/mach-hibvt/Makefile.boot b/arch/arm/mach-hibvt/Makefile.boot 11130new file mode 100644 11131index 000000000..8c8b30077 11132--- /dev/null 11133+++ b/arch/arm/mach-hibvt/Makefile.boot 11134@@ -0,0 +1,7 @@ 11135+ifeq ($(CONFIG_ARCH_HISI_BVT_AMP), y) 11136+zreladdr-$(CONFIG_ARCH_HISI_BVT) := $(CONFIG_AMP_ZRELADDR) 11137+else 11138+zreladdr-$(CONFIG_ARCH_HISI_BVT) := $(CONFIG_HI_ZRELADDR) 11139+endif 11140+params_phys-$(CONFIG_ARCH_HISI_BVT) := $(CONFIG_HI_PARAMS_PHYS) 11141+initrd_phys-$(CONFIG_ARCH_HISI_BVT) := $(CONFIG_HI_INITRD_PHYS) 11142diff --git a/arch/arm/mach-hibvt/include/mach/hi3516dv300_io.h b/arch/arm/mach-hibvt/include/mach/hi3516dv300_io.h 11143new file mode 100644 11144index 000000000..72ab47e83 11145--- /dev/null 11146+++ b/arch/arm/mach-hibvt/include/mach/hi3516dv300_io.h 11147@@ -0,0 +1,26 @@ 11148+#ifndef __HI3516DV300_IO_H 11149+#define __HI3516DV300_IO_H 11150+ 11151+/* 11152+ * phy: 0x20000000 ~ 0x20700000 11153+ * vir: 0xFE100000 ~ 0xFE800000 11154+ */ 11155+#define HI3516DV300_IOCH2_PHYS 0x20000000 11156+#define IO_OFFSET_HIGH 0xDE100000 11157+#define HI3516DV300_IOCH2_VIRT (HI3516DV300_IOCH2_PHYS + IO_OFFSET_HIGH) 11158+#define HI3516DV300_IOCH2_SIZE 0x700000 11159+ 11160+/* phy: 0x10000000 ~ 0x100E0000 11161+ * vir: 0xFE000000 ~ 0xFE0E0000 11162+ */ 11163+#define HI3516DV300_IOCH1_PHYS 0x10000000 11164+#define IO_OFFSET_LOW 0xEE000000 11165+#define HI3516DV300_IOCH1_VIRT (HI3516DV300_IOCH1_PHYS + IO_OFFSET_LOW) 11166+#define HI3516DV300_IOCH1_SIZE 0xE0000 11167+ 11168+#define IO_ADDRESS(x) ((x) >= HI3516DV300_IOCH2_PHYS ? (x) + IO_OFFSET_HIGH \ 11169+ : (x) + IO_OFFSET_LOW) 11170+ 11171+#define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n)) 11172+ 11173+#endif 11174diff --git a/arch/arm/mach-hibvt/include/mach/hi3516dv300_platform.h b/arch/arm/mach-hibvt/include/mach/hi3516dv300_platform.h 11175new file mode 100644 11176index 000000000..94c48064b 11177--- /dev/null 11178+++ b/arch/arm/mach-hibvt/include/mach/hi3516dv300_platform.h 11179@@ -0,0 +1,4 @@ 11180+#ifndef __HI3516DV300_CHIP_REGS_H__ 11181+#define __HI3516DV300_CHIP_REGS_H__ 11182+ 11183+#endif /* End of __HI3516DV300_CHIP_REGS_H__ */ 11184diff --git a/arch/arm/mach-hibvt/include/mach/io.h b/arch/arm/mach-hibvt/include/mach/io.h 11185new file mode 100644 11186index 000000000..b5fd58c7b 11187--- /dev/null 11188+++ b/arch/arm/mach-hibvt/include/mach/io.h 11189@@ -0,0 +1,52 @@ 11190+#ifndef __ASM_ARM_ARCH_IO_H 11191+#define __ASM_ARM_ARCH_IO_H 11192+ 11193+#ifdef CONFIG_ARCH_HI3516A 11194+#include <mach/hi3516a_io.h> 11195+#endif 11196+ 11197+#ifdef CONFIG_ARCH_HI3518EV20X 11198+#include <mach/hi3518ev20x_io.h> 11199+#endif 11200+ 11201+#ifdef CONFIG_ARCH_HI3536DV100 11202+#include <mach/hi3536dv100_io.h> 11203+#endif 11204+ 11205+#ifdef CONFIG_ARCH_HI3521A 11206+#include <mach/hi3521a_io.h> 11207+#endif 11208+ 11209+#ifdef CONFIG_ARCH_HI3531A 11210+#include <mach/hi3531a_io.h> 11211+#endif 11212+ 11213+#ifdef CONFIG_ARCH_HI3516CV500 11214+#include <mach/hi3516cv500_io.h> 11215+#endif 11216+ 11217+#ifdef CONFIG_ARCH_HI3516DV300 11218+#include <mach/hi3516dv300_io.h> 11219+#endif 11220+ 11221+#ifdef CONFIG_ARCH_HI3556V200 11222+#include <mach/hi3556v200_io.h> 11223+#endif 11224+ 11225+#ifdef CONFIG_ARCH_HI3559V200 11226+#include <mach/hi3559v200_io.h> 11227+#endif 11228+ 11229+#ifdef CONFIG_ARCH_HI3562V100 11230+#include <mach/hi3559v200_io.h> 11231+#endif 11232+ 11233+#ifdef CONFIG_ARCH_HI3566V100 11234+#include <mach/hi3559v200_io.h> 11235+#endif 11236+ 11237+#ifdef CONFIG_ARCH_HI3519AV100 11238+#include <mach/hi3519av100_io.h> 11239+#endif 11240+ 11241+#endif 11242diff --git a/arch/arm/mach-hibvt/include/mach/platform.h b/arch/arm/mach-hibvt/include/mach/platform.h 11243new file mode 100644 11244index 000000000..5e41d2696 11245--- /dev/null 11246+++ b/arch/arm/mach-hibvt/include/mach/platform.h 11247@@ -0,0 +1,52 @@ 11248+#ifndef __HISI_PLATFORM_H__ 11249+#define __HISI_PLATFORM_H__ 11250+ 11251+#ifdef CONFIG_ARCH_HI3536DV100 11252+#include <mach/hi3536dv100_platform.h> 11253+#endif 11254+ 11255+#ifdef CONFIG_ARCH_HI3521A 11256+#include <mach/hi3521a_platform.h> 11257+#endif 11258+ 11259+#ifdef CONFIG_ARCH_HI3531A 11260+#include <mach/hi3531a_platform.h> 11261+#endif 11262+ 11263+#ifdef CONFIG_ARCH_HI3516DV300 11264+#include <mach/hi3516dv300_platform.h> 11265+#endif 11266+ 11267+#ifdef CONFIG_ARCH_HI3516CV500 11268+#include <mach/hi3516cv500_platform.h> 11269+#endif 11270+ 11271+#ifdef CONFIG_ARCH_HI3556V200 11272+#include <mach/hi3556v200_platform.h> 11273+#endif 11274+ 11275+#ifdef CONFIG_ARCH_HI3559V200 11276+#include <mach/hi3559v200_platform.h> 11277+#endif 11278+ 11279+#ifdef CONFIG_ARCH_HI3562V100 11280+#include <mach/hi3559v200_platform.h> 11281+#endif 11282+ 11283+#ifdef CONFIG_ARCH_HI3566V100 11284+#include <mach/hi3559v200_platform.h> 11285+#endif 11286+ 11287+#ifdef CONFIG_ARCH_HI3556AV100 11288+#include <mach/hi3556av100_platform.h> 11289+#endif 11290+ 11291+#ifdef CONFIG_ARCH_HI3519AV100 11292+#include <mach/hi3519av100_platform.h> 11293+#endif 11294+ 11295+#ifdef CONFIG_ARCH_HI3568V100 11296+#include <mach/hi3519av100_platform.h> 11297+#endif 11298+ 11299+#endif /* End of __HISI_PLATFORM_H__ */ 11300diff --git a/arch/arm/mach-hibvt/mach-common.h b/arch/arm/mach-hibvt/mach-common.h 11301new file mode 100644 11302index 000000000..f5edadb0f 11303--- /dev/null 11304+++ b/arch/arm/mach-hibvt/mach-common.h 11305@@ -0,0 +1,9 @@ 11306+#ifndef __SMP_COMMON_H 11307+#define __SMP_COMMON_H 11308+ 11309+#ifdef CONFIG_SMP 11310+void hi35xx_set_cpu(unsigned int cpu, bool enable); 11311+void __init hi35xx_smp_prepare_cpus(unsigned int max_cpus); 11312+int hi35xx_boot_secondary(unsigned int cpu, struct task_struct *idle); 11313+#endif /* CONFIG_SMP */ 11314+#endif /* __SMP_COMMON_H */ 11315diff --git a/arch/arm/mach-hibvt/mach-hi3516dv300.c b/arch/arm/mach-hibvt/mach-hi3516dv300.c 11316new file mode 100644 11317index 000000000..3061683bb 11318--- /dev/null 11319+++ b/arch/arm/mach-hibvt/mach-hi3516dv300.c 11320@@ -0,0 +1,68 @@ 11321+/* 11322+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 11323+ * 11324+ * This program is free software; you can redistribute it and/or modify 11325+ * it under the terms of the GNU General Public License as published by 11326+ * the Free Software Foundation; either version 2 of the License, or 11327+ * (at your option) any later version. 11328+ * 11329+ * This program is distributed in the hope that it will be useful, 11330+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 11331+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11332+ * GNU General Public License for more details. 11333+ * 11334+ * You should have received a copy of the GNU General Public License 11335+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 11336+ * 11337+*/ 11338+ 11339+#include <linux/of_address.h> 11340+#include <asm/smp_scu.h> 11341+ 11342+#include "mach-common.h" 11343+ 11344+#ifdef CONFIG_SMP 11345+ 11346+#define REG_CPU_SRST_CRG 0x78 11347+#define CPU1_SRST_REQ BIT(2) 11348+#define DBG1_SRST_REQ BIT(4) 11349+ 11350+void hi35xx_set_cpu(unsigned int cpu, bool enable) 11351+{ 11352+ struct device_node *np = NULL; 11353+ unsigned int regval; 11354+ void __iomem *crg_base; 11355+ 11356+ np = of_find_compatible_node(NULL, NULL, "hisilicon,hi3516dv300-clock"); 11357+ if (!np) { 11358+ pr_err("failed to find hisilicon clock node\n"); 11359+ return; 11360+ } 11361+ 11362+ crg_base = of_iomap(np, 0); 11363+ if (!crg_base) { 11364+ pr_err("failed to map address\n"); 11365+ return; 11366+ } 11367+ 11368+ if (enable) { 11369+ /* clear the slave cpu reset */ 11370+ regval = readl(crg_base + REG_CPU_SRST_CRG); 11371+ regval &= ~CPU1_SRST_REQ; 11372+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); 11373+ } else { 11374+ regval = readl(crg_base + REG_CPU_SRST_CRG); 11375+ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); 11376+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); 11377+ } 11378+ iounmap(crg_base); 11379+} 11380+ 11381+static const struct smp_operations hi35xx_smp_ops __initconst = { 11382+ .smp_prepare_cpus = hi35xx_smp_prepare_cpus, 11383+ .smp_boot_secondary = hi35xx_boot_secondary, 11384+}; 11385+ 11386+CPU_METHOD_OF_DECLARE(hi3516dv300_smp, "hisilicon,hi3516dv300", 11387+ &hi35xx_smp_ops); 11388+#endif /* CONFIG_SMP */ 11389diff --git a/arch/arm/mach-hibvt/platsmp.c b/arch/arm/mach-hibvt/platsmp.c 11390new file mode 100644 11391index 000000000..a73be20b1 11392--- /dev/null 11393+++ b/arch/arm/mach-hibvt/platsmp.c 11394@@ -0,0 +1,62 @@ 11395+/* 11396+ * Copyright (c) 2013 Linaro Ltd. 11397+ * Copyright (c) 2013 Hisilicon Limited. 11398+ * Based on arch/arm/mach-vexpress/platsmp.c, Copyright (C) 2002 ARM Ltd. 11399+ * 11400+ * This program is free software; you can redistribute it and/or modify it 11401+ * under the terms and conditions of the GNU General Public License, 11402+ * version 2, as published by the Free Software Foundation. 11403+ */ 11404+ 11405+#include <linux/io.h> 11406+#include <linux/smp.h> 11407+#include <asm/smp_scu.h> 11408+ 11409+#include "mach-common.h" 11410+ 11411+#define HI35XX_BOOT_ADDRESS 0x00000000 11412+ 11413+void __init hi35xx_smp_prepare_cpus(unsigned int max_cpus) 11414+{ 11415+ unsigned long base = 0; 11416+ void __iomem *scu_base = NULL; 11417+ 11418+ if (scu_a9_has_base()) { 11419+ base = scu_a9_get_base(); 11420+ scu_base = ioremap(base, PAGE_SIZE); 11421+ if (!scu_base) { 11422+ pr_err("ioremap(scu_base) failed\n"); 11423+ return; 11424+ } 11425+ 11426+ scu_enable(scu_base); 11427+ iounmap(scu_base); 11428+ } 11429+} 11430+ 11431+void hi35xx_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr) 11432+{ 11433+ void __iomem *virt; 11434+ 11435+ virt = ioremap(start_addr, PAGE_SIZE); 11436+ if (!virt) { 11437+ pr_err("ioremap(start_addr) failed\n"); 11438+ return; 11439+ } 11440+ 11441+ writel_relaxed(0xe51ff004, virt); /* ldr pc, [rc, #-4] */ 11442+ writel_relaxed(jump_addr, virt + 4); /* pc jump phy address */ 11443+ iounmap(virt); 11444+} 11445+ 11446+int hi35xx_boot_secondary(unsigned int cpu, struct task_struct *idle) 11447+{ 11448+ phys_addr_t jumpaddr; 11449+ 11450+ jumpaddr = virt_to_phys(secondary_startup); 11451+ hi35xx_set_scu_boot_addr(HI35XX_BOOT_ADDRESS, jumpaddr); 11452+ hi35xx_set_cpu(cpu, true); 11453+ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 11454+ return 0; 11455+} 11456+ 11457diff --git a/arch/arm/mach-hibvt/system_adapter.c b/arch/arm/mach-hibvt/system_adapter.c 11458new file mode 100644 11459index 000000000..58fe574b3 11460--- /dev/null 11461+++ b/arch/arm/mach-hibvt/system_adapter.c 11462@@ -0,0 +1,340 @@ 11463+// SPDX-License-Identifier: GPL-2.0 11464+/* 11465+ * Copyright (C) 2021 Huawei Technologies Co., Ltd. All rights reserved. 11466+ */ 11467+ 11468+#include <asm/cacheflush.h> 11469+#include <linux/blackbox.h> 11470+#include <linux/kmsg_dump.h> 11471+#include <linux/semaphore.h> 11472+#include <linux/slab.h> 11473+#include <linux/module.h> 11474+#include <linux/stacktrace.h> 11475+#include <linux/reboot.h> 11476+#include <linux/vmalloc.h> 11477+#include <linux/ctype.h> 11478+#include <linux/blackbox_common.h> 11479+#include <linux/blackbox_storage.h> 11480+ 11481+/* ---- local macroes ---- */ 11482+#define BOOTLOADER_LOG_NAME "fastboot_log" 11483+#define KERNEL_LOG_NAME "last_kmsg" 11484+#define SIZE_1K 1024 11485+#define KERNEL_LOG_MAX_SIZE \ 11486+ round_up((0x80000 + sizeof(struct fault_log_info)), SIZE_1K) 11487+#define CALLSTACK_MAX_ENTRIES 20 11488+ 11489+/* ---- local prototypes ---- */ 11490+ 11491+/* ---- local function prototypes ---- */ 11492+static int save_kmsg_from_buffer(const char *log_dir, 11493+ const char *file_name, int clean_buf); 11494+static void dump(const char *log_dir, struct error_info *info); 11495+static void reset(struct error_info *info); 11496+static int get_last_log_info(struct error_info *info); 11497+static int save_last_log(const char *log_dir, struct error_info *info); 11498+static int bbox_reboot_notify(struct notifier_block *nb, 11499+ unsigned long code, void *unused); 11500+static int bbox_task_panic(struct notifier_block *this, 11501+ unsigned long event, void *ptr); 11502+ 11503+/* ---- local variables ---- */ 11504+static char *kernel_log; 11505+static DEFINE_SEMAPHORE(kmsg_sem); 11506+static struct notifier_block bbox_reboot_nb = { 11507+ .notifier_call = bbox_reboot_notify, 11508+}; 11509+ 11510+static struct notifier_block bbox_panic_block = { 11511+ .notifier_call = bbox_task_panic, 11512+}; 11513+ 11514+/* ---- function definitions ---- */ 11515+static void dump_stacktrace(char *pbuf, size_t buf_size, bool is_panic) 11516+{ 11517+ int i; 11518+ size_t stack_len = 0; 11519+ size_t com_len = 0; 11520+ unsigned long entries[CALLSTACK_MAX_ENTRIES]; 11521+ unsigned int nr_entries; 11522+ char tmp_buf[ERROR_DESC_MAX_LEN]; 11523+ bool find_panic = false; 11524+ 11525+ if (unlikely(!pbuf || !buf_size)) 11526+ return; 11527+ 11528+ memset(pbuf, 0, buf_size); 11529+ memset(tmp_buf, 0, sizeof(tmp_buf)); 11530+ nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 0); 11531+ com_len = scnprintf(pbuf, buf_size, "Comm:%s,CPU:%d,Stack:", 11532+ current->comm, raw_smp_processor_id()); 11533+ for (i = 0; i < nr_entries; i++) { 11534+ if (stack_len >= sizeof(tmp_buf)) { 11535+ tmp_buf[sizeof(tmp_buf) - 1] = '\0'; 11536+ break; 11537+ } 11538+ stack_len += scnprintf(tmp_buf + stack_len, sizeof(tmp_buf) - stack_len, 11539+ "%pS-", (void *)entries[i]); 11540+ if (!find_panic && is_panic) { 11541+ if (strncmp(tmp_buf, "panic", strlen("panic")) == 0) 11542+ find_panic = true; 11543+ else 11544+ (void)memset(tmp_buf, 0, sizeof(tmp_buf)); 11545+ } 11546+ } 11547+ if (com_len >= buf_size) 11548+ return; 11549+ stack_len = min(buf_size - com_len, strlen(tmp_buf)); 11550+ memcpy(pbuf + com_len, tmp_buf, stack_len); 11551+ *(pbuf + buf_size - 1) = '\0'; 11552+} 11553+ 11554+static int save_kmsg_from_buffer(const char *log_dir, 11555+ const char *file_name, int clean_buf) 11556+{ 11557+ int ret = -1; 11558+ char path[PATH_MAX_LEN]; 11559+ struct fault_log_info *pinfo = NULL; 11560+ 11561+ if (unlikely(!log_dir || !file_name)) { 11562+ bbox_print_err("log_dir: %p, file_name: %p!\n", log_dir, file_name); 11563+ return -EINVAL; 11564+ } 11565+ 11566+ memset(path, 0, sizeof(path)); 11567+ (void)scnprintf(path, sizeof(path) - 1, "%s/%s", log_dir, file_name); 11568+ down(&kmsg_sem); 11569+ if (kernel_log) { 11570+ pinfo = (struct fault_log_info *)kernel_log; 11571+ ret = full_write_file(path, kernel_log + sizeof(*pinfo), 11572+ min(KERNEL_LOG_MAX_SIZE - sizeof(*pinfo), 11573+ (size_t)pinfo->len), 0); 11574+ if (clean_buf) 11575+ memset(kernel_log, 0, KERNEL_LOG_MAX_SIZE); 11576+ } else { 11577+ bbox_print_err("kernel_log: %p!\n", kernel_log); 11578+ } 11579+ up(&kmsg_sem); 11580+ if (ret == 0) 11581+ change_own(path, AID_ROOT, AID_SYSTEM); 11582+ 11583+ return ret; 11584+} 11585+ 11586+static void dump(const char *log_dir, struct error_info *info) 11587+{ 11588+ if (unlikely(!log_dir || !info)) { 11589+ bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info); 11590+ return; 11591+ } 11592+ 11593+ if (!strcmp(info->event, EVENT_PANIC) || 11594+ !strcmp(info->event, EVENT_SYSREBOOT) || 11595+ !strcmp(info->event, EVENT_POWEROFF)) { 11596+ struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log; 11597+ 11598+ if (down_trylock(&kmsg_sem) != 0) { 11599+ bbox_print_err("down_trylock failed!\n"); 11600+ return; 11601+ } 11602+ 11603+ if (kernel_log) { 11604+ memcpy(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG)); 11605+ memcpy(&pinfo->info, info, sizeof(*info)); 11606+ 11607+#if __BITS_PER_LONG == 64 11608+ __flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE); 11609+#else 11610+ __cpuc_flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE); 11611+#endif 11612+ } 11613+ 11614+ up(&kmsg_sem); 11615+ } else { 11616+ bbox_print_info("module [%s] starts saving log for event [%s]!\n", 11617+ info->module, info->event); 11618+ save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 0); 11619+ bbox_print_info("module [%s] ends saving log for event [%s]!\n", 11620+ info->module, info->event); 11621+ } 11622+} 11623+ 11624+static void reset(struct error_info *info) 11625+{ 11626+ if (unlikely(!info)) { 11627+ bbox_print_err("info: %p!\n", info); 11628+ return; 11629+ } 11630+ 11631+ if (!strcmp(info->event, EVENT_PANIC)) 11632+ emergency_restart(); 11633+} 11634+ 11635+static int get_last_log_info(struct error_info *info) 11636+{ 11637+ struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log; 11638+ int log_size = KERNEL_LOG_MAX_SIZE; 11639+ unsigned int i = 0; 11640+ 11641+ if (unlikely(!info || !kernel_log)) 11642+ return -EINVAL; 11643+ 11644+ if (storage_lastword->get_log((void *)kernel_log, log_size) < 0) { 11645+ bbox_print_err("Get last log from strorage failed!\n"); 11646+ return -ENOENT; 11647+ } 11648+ 11649+ down(&kmsg_sem); 11650+ if (!memcmp(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG))) { 11651+ memcpy(info, &pinfo->info, sizeof(*info)); 11652+ for (i = 0; i < strlen((*info).event); i++) 11653+ (*info).event[i] = toupper((*info).event[i]); 11654+ 11655+ if (strncmp((*info).module, "PSTORE", strlen("PSTORE")) == 0) 11656+ memcpy((*info).module, MODULE_SYSTEM, sizeof((*info).module)); 11657+ 11658+ up(&kmsg_sem); 11659+ return 0; 11660+ } 11661+ up(&kmsg_sem); 11662+ bbox_print_info("There's no valid fault log!\n"); 11663+ 11664+ return -ENOMSG; 11665+} 11666+ 11667+static int save_last_log(const char *log_dir, struct error_info *info) 11668+{ 11669+ int ret = -1; 11670+ 11671+ if (unlikely(!log_dir || !info)) { 11672+ bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info); 11673+ return -EINVAL; 11674+ } 11675+ 11676+ ret = save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 1); 11677+ bbox_print_info("save last fault log %s!\n", 11678+ ret ? "failed" : "successfully"); 11679+ 11680+ return ret; 11681+} 11682+ 11683+static int bbox_reboot_notify(struct notifier_block *nb, 11684+ unsigned long code, void *unused) 11685+{ 11686+ char error_desc[ERROR_DESC_MAX_LEN]; 11687+ 11688+ /* notify blackbox to do dump */ 11689+ memset(error_desc, 0, sizeof(error_desc)); 11690+ dump_stacktrace(error_desc, sizeof(error_desc), false); 11691+ kmsg_dump(KMSG_DUMP_UNDEF); 11692+ 11693+ switch (code) { 11694+ case SYS_RESTART: 11695+ bbox_notify_error(EVENT_SYSREBOOT, MODULE_SYSTEM, error_desc, 1); 11696+ break; 11697+ case SYS_POWER_OFF: 11698+ bbox_notify_error(EVENT_POWEROFF, MODULE_SYSTEM, error_desc, 0); 11699+ break; 11700+ default: 11701+ bbox_print_err("Invalid event code: %lu!\n", code); 11702+ break; 11703+ } 11704+ 11705+ return NOTIFY_DONE; 11706+} 11707+ 11708+static int bbox_task_panic(struct notifier_block *this, 11709+ unsigned long event, void *ptr) 11710+{ 11711+ char error_desc[ERROR_DESC_MAX_LEN]; 11712+ 11713+ /* notify blackbox to do dump */ 11714+ kmsg_dump(KMSG_DUMP_OOPS); 11715+ memset(error_desc, 0, sizeof(error_desc)); 11716+ bbox_notify_error(EVENT_PANIC, MODULE_SYSTEM, error_desc, 1); 11717+ 11718+ return NOTIFY_DONE; 11719+} 11720+ 11721+#ifdef CONFIG_BLACKBOX_TEST 11722+static void test_bbox(void) 11723+{ 11724+ struct module_ops ops = { 11725+ .module = "TEST", 11726+ .dump = NULL, 11727+ .reset = NULL, 11728+ .get_last_log_info = NULL, 11729+ .save_last_log = NULL, 11730+ }; 11731+ 11732+ if (bbox_register_module_ops(&ops) != 0) { 11733+ bbox_print_err("bbox_register_module_ops failed!\n"); 11734+ return -EINVAL; 11735+ } 11736+ kmsg_dump(KMSG_DUMP_OOPS); 11737+ bbox_notify_error("EVENT_TEST", "TEST", "Test bbox_notify_error", 0); 11738+ 11739+} 11740+#endif 11741+ 11742+static int __init blackbox_init(void) 11743+{ 11744+ int ret = -1; 11745+ struct kmsg_dumper *dumper = NULL; 11746+ struct module_ops ops = { 11747+ .module = MODULE_SYSTEM, 11748+ .dump = dump, 11749+ .reset = reset, 11750+ .get_last_log_info = get_last_log_info, 11751+ .save_last_log = save_last_log, 11752+ }; 11753+ 11754+ if (bbox_register_module_ops(&ops) != 0) { 11755+ bbox_print_err("bbox_register_module_ops failed!\n"); 11756+ return -EINVAL; 11757+ } 11758+ 11759+ /* allocate buffer for kmsg */ 11760+ kernel_log = kmalloc(KERNEL_LOG_MAX_SIZE, GFP_KERNEL); 11761+ if (!kernel_log) 11762+ goto __err; 11763+ 11764+ bbox_print_info("kernel_log: %p for blackbox!\n", kernel_log); 11765+ 11766+ /* register kdumper */ 11767+ dumper = vmalloc(sizeof(*dumper)); 11768+ if (!dumper) 11769+ goto __err; 11770+ 11771+ memset(dumper, 0, sizeof(*dumper)); 11772+ dumper->max_reason = KMSG_DUMP_MAX; 11773+ dumper->dump = storage_lastword->blackbox_dump; 11774+ ret = kmsg_dump_register(dumper); 11775+ if (ret != 0) { 11776+ bbox_print_err("kmsg_dump_register failed!\n"); 11777+ goto __err; 11778+ } 11779+ atomic_notifier_chain_register(&panic_notifier_list, &bbox_panic_block); 11780+ 11781+ register_reboot_notifier(&bbox_reboot_nb); 11782+#ifdef CONFIG_BLACKBOX_TEST 11783+ test_bbox(); 11784+#endif 11785+ return 0; 11786+ 11787+__err: 11788+ kfree(kernel_log); 11789+ kernel_log = NULL; 11790+ 11791+ if (dumper) { 11792+ vfree(dumper); 11793+ dumper = NULL; 11794+ } 11795+ 11796+ return ret; 11797+} 11798+ 11799+postcore_initcall(blackbox_init); 11800+MODULE_LICENSE("GPL v2"); 11801+MODULE_DESCRIPTION("Blackbox for system"); 11802+MODULE_AUTHOR("OHOS hi3516dv300"); 11803diff --git a/arch/arm/mach-hibvt/system_adapter_by_memory.c b/arch/arm/mach-hibvt/system_adapter_by_memory.c 11804new file mode 100644 11805index 000000000..92a680a9e 11806--- /dev/null 11807+++ b/arch/arm/mach-hibvt/system_adapter_by_memory.c 11808@@ -0,0 +1,339 @@ 11809+// SPDX-License-Identifier: GPL-2.0 11810+/* 11811+ * Copyright (C) 2021 Huawei Technologies Co., Ltd. All rights reserved. 11812+ */ 11813+ 11814+#include <asm/cacheflush.h> 11815+#include <linux/blackbox.h> 11816+#include <linux/kmsg_dump.h> 11817+#include <linux/semaphore.h> 11818+#include <linux/slab.h> 11819+#include <linux/module.h> 11820+#include <linux/stacktrace.h> 11821+#include <linux/reboot.h> 11822+#include <linux/vmalloc.h> 11823+#include <linux/ctype.h> 11824+#include <linux/blackbox_common.h> 11825+#include <linux/blackbox_storage.h> 11826+ 11827+/* ---- local macroes ---- */ 11828+#define BOOTLOADER_LOG_NAME "fastboot_log" 11829+#define KERNEL_LOG_NAME "last_kmsg" 11830+#define SIZE_1K 1024 11831+#define KERNEL_LOG_MAX_SIZE \ 11832+ round_up((0x80000 + sizeof(struct fault_log_info)), SIZE_1K) 11833+#define CALLSTACK_MAX_ENTRIES 20 11834+ 11835+/* ---- local prototypes ---- */ 11836+ 11837+/* ---- local function prototypes ---- */ 11838+static int save_kmsg_from_buffer(const char *log_dir, 11839+ const char *file_name, int clean_buf); 11840+static void dump(const char *log_dir, struct error_info *info); 11841+static void reset(struct error_info *info); 11842+static int get_last_log_info(struct error_info *info); 11843+static int save_last_log(const char *log_dir, struct error_info *info); 11844+static int bbox_reboot_notify(struct notifier_block *nb, 11845+ unsigned long code, void *unused); 11846+static int bbox_task_panic(struct notifier_block *this, 11847+ unsigned long event, void *ptr); 11848+ 11849+/* ---- local variables ---- */ 11850+static char *kernel_log; 11851+static DEFINE_SEMAPHORE(kmsg_sem); 11852+static struct notifier_block bbox_reboot_nb = { 11853+ .notifier_call = bbox_reboot_notify, 11854+}; 11855+ 11856+static struct notifier_block bbox_panic_block = { 11857+ .notifier_call = bbox_task_panic, 11858+}; 11859+ 11860+/* ---- function definitions ---- */ 11861+static void dump_stacktrace(char *pbuf, size_t buf_size, bool is_panic) 11862+{ 11863+ int i; 11864+ size_t stack_len = 0; 11865+ size_t com_len = 0; 11866+ unsigned long entries[CALLSTACK_MAX_ENTRIES]; 11867+ unsigned int nr_entries; 11868+ char tmp_buf[ERROR_DESC_MAX_LEN]; 11869+ bool find_panic = false; 11870+ 11871+ if (unlikely(!pbuf || !buf_size)) 11872+ return; 11873+ 11874+ memset(pbuf, 0, buf_size); 11875+ memset(tmp_buf, 0, sizeof(tmp_buf)); 11876+ nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 0); 11877+ com_len = scnprintf(pbuf, buf_size, "Comm:%s,CPU:%d,Stack:", 11878+ current->comm, raw_smp_processor_id()); 11879+ for (i = 0; i < nr_entries; i++) { 11880+ if (stack_len >= sizeof(tmp_buf)) { 11881+ tmp_buf[sizeof(tmp_buf) - 1] = '\0'; 11882+ break; 11883+ } 11884+ stack_len += scnprintf(tmp_buf + stack_len, sizeof(tmp_buf) - stack_len, 11885+ "%pS-", (void *)entries[i]); 11886+ if (!find_panic && is_panic) { 11887+ if (strncmp(tmp_buf, "panic", strlen("panic")) == 0) 11888+ find_panic = true; 11889+ else 11890+ (void)memset(tmp_buf, 0, sizeof(tmp_buf)); 11891+ } 11892+ } 11893+ if (com_len >= buf_size) 11894+ return; 11895+ stack_len = min(buf_size - com_len, strlen(tmp_buf)); 11896+ memcpy(pbuf + com_len, tmp_buf, stack_len); 11897+ *(pbuf + buf_size - 1) = '\0'; 11898+} 11899+ 11900+static int save_kmsg_from_buffer(const char *log_dir, 11901+ const char *file_name, int clean_buf) 11902+{ 11903+ int ret = -1; 11904+ char path[PATH_MAX_LEN]; 11905+ struct fault_log_info *pinfo = NULL; 11906+ 11907+ if (unlikely(!log_dir || !file_name)) { 11908+ bbox_print_err("log_dir: %p, file_name: %p!\n", log_dir, file_name); 11909+ return -EINVAL; 11910+ } 11911+ 11912+ memset(path, 0, sizeof(path)); 11913+ (void)scnprintf(path, sizeof(path) - 1, "%s/%s", log_dir, file_name); 11914+ down(&kmsg_sem); 11915+ if (kernel_log) { 11916+ pinfo = (struct fault_log_info *)kernel_log; 11917+ ret = full_write_file(path, kernel_log + sizeof(*pinfo), 11918+ min(KERNEL_LOG_MAX_SIZE - sizeof(*pinfo), 11919+ (size_t)pinfo->len), 0); 11920+ if (clean_buf) 11921+ memset(kernel_log, 0, KERNEL_LOG_MAX_SIZE); 11922+ } else { 11923+ bbox_print_err("kernel_log: %p!\n", kernel_log); 11924+ } 11925+ up(&kmsg_sem); 11926+ if (ret == 0) 11927+ change_own(path, AID_ROOT, AID_SYSTEM); 11928+ 11929+ return ret; 11930+} 11931+ 11932+static void dump(const char *log_dir, struct error_info *info) 11933+{ 11934+ if (unlikely(!log_dir || !info)) { 11935+ bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info); 11936+ return; 11937+ } 11938+ 11939+ if (!strcmp(info->event, EVENT_PANIC) || 11940+ !strcmp(info->event, EVENT_SYSREBOOT) || 11941+ !strcmp(info->event, EVENT_POWEROFF)) { 11942+ struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log; 11943+ 11944+ if (down_trylock(&kmsg_sem) != 0) { 11945+ bbox_print_err("down_trylock failed!\n"); 11946+ return; 11947+ } 11948+ 11949+ if (kernel_log) { 11950+ memcpy(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG)); 11951+ memcpy(&pinfo->info, info, sizeof(*info)); 11952+ 11953+#if __BITS_PER_LONG == 64 11954+ __flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE); 11955+#else 11956+ __cpuc_flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE); 11957+#endif 11958+ } 11959+ 11960+ up(&kmsg_sem); 11961+ } else { 11962+ bbox_print_info("module [%s] starts saving log for event [%s]!\n", 11963+ info->module, info->event); 11964+ save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 0); 11965+ bbox_print_info("module [%s] ends saving log for event [%s]!\n", 11966+ info->module, info->event); 11967+ } 11968+} 11969+ 11970+static void reset(struct error_info *info) 11971+{ 11972+ if (unlikely(!info)) { 11973+ bbox_print_err("info: %p!\n", info); 11974+ return; 11975+ } 11976+ 11977+ if (!strcmp(info->event, EVENT_PANIC)) 11978+ emergency_restart(); 11979+} 11980+ 11981+static int get_last_log_info(struct error_info *info) 11982+{ 11983+ struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log; 11984+ int log_size = KERNEL_LOG_MAX_SIZE; 11985+ 11986+ if (unlikely(!info || !kernel_log)) 11987+ return -EINVAL; 11988+ 11989+ if (storage_lastword->get_log((void *)kernel_log, log_size) < 0) { 11990+ bbox_print_err("Get last log from strorage failed!\n"); 11991+ return -ENOENT; 11992+ } 11993+ 11994+ down(&kmsg_sem); 11995+ if (!memcmp(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG))) { 11996+ memcpy(info, &pinfo->info, sizeof(*info)); 11997+ 11998+ up(&kmsg_sem); 11999+ return 0; 12000+ } 12001+ up(&kmsg_sem); 12002+ bbox_print_info("There's no valid fault log!\n"); 12003+ 12004+ return -ENOMSG; 12005+} 12006+ 12007+static int save_last_log(const char *log_dir, struct error_info *info) 12008+{ 12009+ int ret = -1; 12010+ 12011+ if (unlikely(!log_dir || !info)) { 12012+ bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info); 12013+ return -EINVAL; 12014+ } 12015+ 12016+ ret = save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 1); 12017+ bbox_print_info("save last fault log %s!\n", 12018+ ret ? "failed" : "successfully"); 12019+ 12020+ return ret; 12021+} 12022+ 12023+static int bbox_reboot_notify(struct notifier_block *nb, 12024+ unsigned long code, void *unused) 12025+{ 12026+ char error_desc[ERROR_DESC_MAX_LEN]; 12027+ 12028+ /* notify blackbox to do dump */ 12029+ memset(error_desc, 0, sizeof(error_desc)); 12030+ dump_stacktrace(error_desc, sizeof(error_desc), false); 12031+ kmsg_dump(KMSG_DUMP_UNDEF); 12032+ 12033+ switch (code) { 12034+ case SYS_RESTART: 12035+ bbox_notify_error(EVENT_SYSREBOOT, MODULE_SYSTEM, error_desc, 1); 12036+ break; 12037+ case SYS_POWER_OFF: 12038+ bbox_notify_error(EVENT_POWEROFF, MODULE_SYSTEM, error_desc, 0); 12039+ break; 12040+ default: 12041+ bbox_print_err("Invalid event code: %lu!\n", code); 12042+ break; 12043+ } 12044+ 12045+ return NOTIFY_DONE; 12046+} 12047+ 12048+static int bbox_task_panic(struct notifier_block *this, 12049+ unsigned long event, void *ptr) 12050+{ 12051+ char error_desc[ERROR_DESC_MAX_LEN]; 12052+ 12053+ /* notify blackbox to do dump */ 12054+ kmsg_dump(KMSG_DUMP_OOPS); 12055+ memset(error_desc, 0, sizeof(error_desc)); 12056+ bbox_notify_error(EVENT_PANIC, MODULE_SYSTEM, error_desc, 1); 12057+ 12058+ return NOTIFY_DONE; 12059+} 12060+ 12061+#ifdef CONFIG_BLACKBOX_TEST 12062+static void test_bbox(void) 12063+{ 12064+ struct module_ops ops = { 12065+ .module = "TEST", 12066+ .dump = NULL, 12067+ .reset = NULL, 12068+ .get_last_log_info = NULL, 12069+ .save_last_log = NULL, 12070+ }; 12071+ 12072+ if (bbox_register_module_ops(&ops) != 0) { 12073+ bbox_print_err("bbox_register_module_ops failed!\n"); 12074+ return -EINVAL; 12075+ } 12076+ kmsg_dump(KMSG_DUMP_OOPS); 12077+ bbox_notify_error("EVENT_TEST", "TEST", "Test bbox_notify_error", 0); 12078+ 12079+} 12080+#endif 12081+ 12082+static int __init blackbox_init(void) 12083+{ 12084+ int ret = -1; 12085+ struct kmsg_dumper *dumper = NULL; 12086+ struct module_ops ops = { 12087+ .module = MODULE_SYSTEM, 12088+ .dump = dump, 12089+ .reset = reset, 12090+ .get_last_log_info = get_last_log_info, 12091+ .save_last_log = save_last_log, 12092+ }; 12093+ 12094+ if (bbox_register_module_ops(&ops) != 0) { 12095+ bbox_print_err("bbox_register_module_ops failed!\n"); 12096+ return -EINVAL; 12097+ } 12098+ 12099+ /* allocate buffer for kmsg */ 12100+ kernel_log = kmalloc(KERNEL_LOG_MAX_SIZE, GFP_KERNEL); 12101+ if (!kernel_log) 12102+ goto __err; 12103+ 12104+ bbox_print_info("kernel_log: %p for blackbox!\n", kernel_log); 12105+ 12106+ if (storage_lastword->storage_log(kernel_log, KERNEL_LOG_MAX_SIZE) < 0) { 12107+ bbox_print_err("storage_log failed!\n"); 12108+ goto __err; 12109+ } 12110+ 12111+ /* register kdumper */ 12112+ dumper = vmalloc(sizeof(*dumper)); 12113+ if (!dumper) 12114+ goto __err; 12115+ 12116+ memset(dumper, 0, sizeof(*dumper)); 12117+ dumper->max_reason = KMSG_DUMP_MAX; 12118+ dumper->dump = storage_lastword->blackbox_dump; 12119+ ret = kmsg_dump_register(dumper); 12120+ if (ret != 0) { 12121+ bbox_print_err("kmsg_dump_register failed!\n"); 12122+ goto __err; 12123+ } 12124+ atomic_notifier_chain_register(&panic_notifier_list, &bbox_panic_block); 12125+ 12126+ register_reboot_notifier(&bbox_reboot_nb); 12127+#ifdef CONFIG_BLACKBOX_TEST 12128+ test_bbox(); 12129+#endif 12130+ return 0; 12131+ 12132+__err: 12133+ kfree(kernel_log); 12134+ kernel_log = NULL; 12135+ 12136+ if (dumper) { 12137+ vfree(dumper); 12138+ dumper = NULL; 12139+ } 12140+ 12141+ return ret; 12142+} 12143+ 12144+postcore_initcall(blackbox_init); 12145+MODULE_LICENSE("GPL v2"); 12146+MODULE_DESCRIPTION("Blackbox for system"); 12147+MODULE_AUTHOR("OHOS"); 12148diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c 12149index c4b8df2ad..374737bd5 100644 12150--- a/arch/arm/mm/dma-mapping.c 12151+++ b/arch/arm/mm/dma-mapping.c 12152@@ -237,7 +237,7 @@ const struct dma_map_ops arm_coherent_dma_ops = { 12153 }; 12154 EXPORT_SYMBOL(arm_coherent_dma_ops); 12155 12156-static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) 12157+void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) 12158 { 12159 /* 12160 * Ensure that the allocated pages are zeroed, and that any data 12161@@ -266,6 +266,7 @@ static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag 12162 } 12163 } 12164 } 12165+EXPORT_SYMBOL(__dma_clear_buffer); 12166 12167 /* 12168 * Allocate a DMA buffer for 'dev' of size 'size' using the 12169@@ -454,6 +455,12 @@ static void __dma_remap(struct page *page, size_t size, pgprot_t prot) 12170 flush_tlb_kernel_range(start, end); 12171 } 12172 12173+void hisi_flush_tlb_kernel_range(unsigned long start, unsigned long end) 12174+{ 12175+ flush_tlb_kernel_range(start, end); 12176+} 12177+EXPORT_SYMBOL(hisi_flush_tlb_kernel_range); 12178+ 12179 static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, 12180 pgprot_t prot, struct page **ret_page, 12181 const void *caller, bool want_vaddr) 12182@@ -2296,6 +2303,13 @@ void arch_teardown_dma_ops(struct device *dev) 12183 set_dma_ops(dev, NULL); 12184 } 12185 12186+void hi_dmac_map_area(const void *kaddr, size_t size, 12187+ enum dma_data_direction dir) 12188+{ 12189+ dmac_map_area(kaddr, size, dir); 12190+} 12191+EXPORT_SYMBOL(hi_dmac_map_area); 12192+ 12193 #ifdef CONFIG_SWIOTLB 12194 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, 12195 enum dma_data_direction dir) 12196diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c 12197old mode 100644 12198new mode 100755 12199diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile 12200index 485b7dbd4..65b9f45c8 100644 12201--- a/arch/arm64/Makefile 12202+++ b/arch/arm64/Makefile 12203@@ -11,6 +11,7 @@ 12204 # Copyright (C) 1995-2001 by Russell King 12205 12206 LDFLAGS_vmlinux :=--no-undefined -X 12207+OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S 12208 12209 ifeq ($(CONFIG_RELOCATABLE), y) 12210 # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour 12211diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile 12212index cd3414898..f3e98628b 100644 12213--- a/arch/arm64/boot/Makefile 12214+++ b/arch/arm64/boot/Makefile 12215@@ -18,12 +18,28 @@ OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S 12216 12217 targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo 12218 12219+dtstree := $(srctree)/$(src)/dts 12220+ 12221+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts))) 12222+ 12223+DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES)) 12224+ifneq ($(DTB_NAMES),) 12225+DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES)) 12226+else 12227+DTB_LIST := $(dtb-y) 12228+endif 12229+ 12230+DTB_OBJS := $(addprefix $(obj)/dts/,$(DTB_LIST)) 12231+ 12232 $(obj)/Image: vmlinux FORCE 12233 $(call if_changed,objcopy) 12234 12235 $(obj)/Image.bz2: $(obj)/Image FORCE 12236 $(call if_changed,bzip2) 12237 12238+$(obj)/Image-dtb: $(obj)/Image $(DTB_OBJS) FORCE 12239+ $(call if_changed,cat) 12240+ 12241 $(obj)/Image.gz: $(obj)/Image FORCE 12242 $(call if_changed,gzip) 12243 12244@@ -36,10 +52,35 @@ $(obj)/Image.lzma: $(obj)/Image FORCE 12245 $(obj)/Image.lzo: $(obj)/Image FORCE 12246 $(call if_changed,lzo) 12247 12248-install: 12249+$(obj)/Image.gz-dtb: $(obj)/Image.gz $(DTB_OBJS) FORCE 12250+ $(call if_changed,cat) 12251+ 12252+UIMAGE_LOADADDR=$(TEXT_OFFSET) 12253+UIMAGE_ENTRYADDR=$(TEXT_OFFSET) 12254+#UIMAGE_COMPRESSION = gzip 12255+check_for_multiple_loadaddr = \ 12256+if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \ 12257+ echo 'multiple (or no) load addresses: $(UIMAGE_LOADADDR)'; \ 12258+ echo 'This is incompatible with uImages'; \ 12259+ echo 'Specify LOADADDR on the commandline to build an uImage'; \ 12260+ false; \ 12261+fi 12262+ 12263+rm_uimage: 12264+ @rm -f $(obj)/uImage 12265+ 12266+$(obj)/uImage: $(obj)/Image rm_uimage FORCE 12267+ @$(check_for_multiple_loadaddr) 12268+ @dd if=$< of=$<.dd ibs=4096 conv=sync && mv $<.dd $< 12269+ $(call if_changed,uimage) 12270+ $(if $(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),@$(kecho) ' CAT $(DTB_OBJS) to $@') 12271+ $(if $(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),@cat $(DTB_OBJS) >>$@,) 12272+ @$(kecho) ' Image $@ is ready' 12273+ 12274+install:$(obj)/uImage 12275 $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ 12276 $(obj)/Image System.map "$(INSTALL_PATH)" 12277 12278-zinstall: 12279+zinstall:$(obj)/uImage 12280 $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ 12281 $(obj)/Image.gz System.map "$(INSTALL_PATH)" 12282diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile 12283index 9b1170658..9520bb244 100644 12284--- a/arch/arm64/boot/dts/Makefile 12285+++ b/arch/arm64/boot/dts/Makefile 12286@@ -30,3 +30,5 @@ subdir-y += ti 12287 subdir-y += toshiba 12288 subdir-y += xilinx 12289 subdir-y += zte 12290+dtbs: $(addprefix $(obj)/, $(DTB_LIST)) 12291+clean-files := dts/*.dtb *.dtb 12292diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c 12293index 1006ed2d7..aa1d2f2b9 100644 12294--- a/arch/arm64/kernel/pci.c 12295+++ b/arch/arm64/kernel/pci.c 12296@@ -29,6 +29,18 @@ int pcibios_alloc_irq(struct pci_dev *dev) 12297 12298 return 0; 12299 } 12300+#else 12301+#ifdef CONFIG_ARCH_HISI_BVT 12302+/* 12303+ * Try to assign the IRQ number when probing a new device 12304+ */ 12305+int pcibios_alloc_irq(struct pci_dev *dev) 12306+{ 12307+ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); 12308+ 12309+ return 0; 12310+} 12311+#endif 12312 #endif 12313 12314 /* 12315diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c 12316index c0a7f0d90..a5ca33ad8 100644 12317--- a/arch/arm64/mm/init.c 12318+++ b/arch/arm64/mm/init.c 12319@@ -180,6 +180,10 @@ static void __init reserve_elfcorehdr(void) 12320 */ 12321 static phys_addr_t __init max_zone_phys(unsigned int zone_bits) 12322 { 12323+#ifdef CONFIG_ARCH_HISI_BVT 12324+ phys_addr_t max_dma_phys; 12325+ extern phys_addr_t hisi_get_zones_start(void); 12326+#endif 12327 phys_addr_t zone_mask = DMA_BIT_MASK(zone_bits); 12328 phys_addr_t phys_start = memblock_start_of_DRAM(); 12329 12330@@ -188,7 +192,12 @@ static phys_addr_t __init max_zone_phys(unsigned int zone_bits) 12331 else if (phys_start > zone_mask) 12332 zone_mask = U32_MAX; 12333 12334+#ifdef CONFIG_ARCH_HISI_BVT 12335+ max_dma_phys = min(zone_mask, memblock_end_of_DRAM() - 1) + 1; 12336+ return min(max_dma_phys, hisi_get_zones_start()); 12337+#else 12338 return min(zone_mask, memblock_end_of_DRAM() - 1) + 1; 12339+#endif 12340 } 12341 12342 static void __init zone_sizes_init(unsigned long min, unsigned long max) 12343diff --git a/drivers/Kconfig b/drivers/Kconfig 12344index abf8938eb..2e65f9182 100644 12345--- a/drivers/Kconfig 12346+++ b/drivers/Kconfig 12347@@ -244,4 +244,11 @@ source "drivers/hooks/Kconfig" 12348 12349 source "drivers/hck/Kconfig" 12350 12351+source "drivers/hidmac/Kconfig" 12352+ 12353+source "drivers/hiedmac/Kconfig" 12354+ 12355+source "drivers/hisilicon/Kconfig" 12356+ 12357+source "drivers/hi_vdmav100/Kconfig" 12358 endmenu 12359diff --git a/drivers/Makefile b/drivers/Makefile 12360index d9e92b5e3..e9e62665f 100644 12361--- a/drivers/Makefile 12362+++ b/drivers/Makefile 12363@@ -195,3 +195,7 @@ obj-$(CONFIG_MOST) += most/ 12364 obj-$(CONFIG_ACCESS_TOKENID) += accesstokenid/ 12365 obj-$(CONFIG_VENDOR_HOOKS) += hooks/ 12366 obj-$(CONFIG_HCK_VENDOR_HOOKS) += hck/ 12367+obj-$(CONFIG_HI_DMAC) += hidmac/ 12368+obj-$(CONFIG_HIEDMAC) += hiedmac/ 12369+obj-$(CONFIG_ARCH_HISI_BVT) += hisilicon/ 12370+obj-$(CONFIG_HI_VDMA_V100) += hi_vdmav100/ 12371diff --git a/drivers/android/binder.c b/drivers/android/binder.c 12372index 3604f0df6..2108d6686 100644 12373--- a/drivers/android/binder.c 12374+++ b/drivers/android/binder.c 12375@@ -2966,7 +2966,7 @@ static void binder_transaction(struct binder_proc *proc, 12376 return_error = BR_FAILED_REPLY; 12377 return_error_param = -EINVAL; 12378 return_error_line = __LINE__; 12379- goto err_invalid_target_handle; 12380+ //goto err_invalid_target_handle; 12381 } 12382 } 12383 if (!target_node) { 12384diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig 12385index 030cb32da..97d530d3e 100644 12386--- a/drivers/ata/Kconfig 12387+++ b/drivers/ata/Kconfig 12388@@ -2,6 +2,7 @@ 12389 # 12390 # SATA/PATA driver configuration 12391 # 12392+source "drivers/ata/Kconfig.hiahci" 12393 12394 config HAVE_PATA_PLATFORM 12395 bool 12396diff --git a/drivers/ata/Kconfig.hiahci b/drivers/ata/Kconfig.hiahci 12397new file mode 100644 12398index 000000000..030de3fc9 12399--- /dev/null 12400+++ b/drivers/ata/Kconfig.hiahci 12401@@ -0,0 +1,44 @@ 12402+menuconfig HISI_SATA 12403+ bool "Hisilicon sata device support" 12404+ depends on (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3521DV200 || ARCH_HI3520DV500) 12405+ default n 12406+ select ATA 12407+ select ATA_VERBOSE_ERROR 12408+ select SATA_PMP 12409+ select SATA_AHCI_PLATFORM 12410+ 12411+if HISI_SATA 12412+config HISI_SATA_IOBASE 12413+ hex "Hisi sata IO address" 12414+ default "0x10390000" if (ARCH_HI3531DV200 || ARCH_HI3535AV100) 12415+ default "0x10390000" if (ARCH_HI3521DV200 || ARCH_HI3520DV500) 12416+ help 12417+ hisilicon sata io base address. 12418+ 12419+config HISI_SATA_FBS 12420+ int "Hisi sata FIS-Based switching" 12421+ default 1 12422+ range 0 1 12423+ help 12424+ Hisatav200 supports FBS. 12425+ FBS is FIS-Based switching. 12426+ Choose y if you want to use it. 12427+ 12428+config HISI_SATA_NCQ 12429+ int "Hisi sata Native Command Queuing" 12430+ default 1 12431+ range 0 1 12432+ help 12433+ Hisatav200 supports NCQ. 12434+ NCQ is Native Command Queuing. 12435+ Choose y if you want to use it. 12436+ 12437+config HISI_ESATA 12438+ bool "Support Hisi eSATA" 12439+ default n 12440+ help 12441+ Hisatav200 supports eSATA. 12442+ Choose y if you want to use it. 12443+ 12444+endif 12445+ 12446diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile 12447index b8aebfb14..f81f2d66b 100644 12448--- a/drivers/ata/Makefile 12449+++ b/drivers/ata/Makefile 12450@@ -1,6 +1,7 @@ 12451 # SPDX-License-Identifier: GPL-2.0 12452 12453 obj-$(CONFIG_ATA) += libata.o 12454+obj-$(CONFIG_HISI_SATA) += hisi_sata_dbg.o 12455 12456 # non-SFF interface 12457 obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o 12458diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h 12459index d1f284f0c..af7963b12 100644 12460--- a/drivers/ata/ahci.h 12461+++ b/drivers/ata/ahci.h 12462@@ -224,6 +224,9 @@ enum { 12463 error-handling stage) */ 12464 AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ 12465 AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */ 12466+#ifdef CONFIG_HISI_SATA 12467+ AHCI_HFLAG_NO_SXS = (1 << 19), /* do not support External SATA */ 12468+#endif 12469 12470 #ifdef CONFIG_PCI_MSI 12471 AHCI_HFLAG_MULTI_MSI = (1 << 20), /* per-port MSI(-X) */ 12472@@ -346,6 +349,12 @@ struct ahci_host_priv { 12473 struct regulator **target_pwrs; /* Optional */ 12474 struct regulator *ahci_regulator;/* Optional */ 12475 struct regulator *phy_regulator;/* Optional */ 12476+#ifdef CONFIG_HISI_SATA 12477+#define PCI_AHCI 0 12478+#define ORI_AHCI 1 12479+ u32 type; 12480+#endif 12481+ 12482 /* 12483 * If platform uses PHYs. There is a 1:1 relation between the port number and 12484 * the PHY position in this array. 12485diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c 12486index 3aab2e3d5..385d3d7d5 100644 12487--- a/drivers/ata/ahci_platform.c 12488+++ b/drivers/ata/ahci_platform.c 12489@@ -22,6 +22,16 @@ 12490 12491 #define DRV_NAME "ahci" 12492 12493+#ifdef CONFIG_HISI_SATA_NCQ 12494+static unsigned int ncq_en = CONFIG_HISI_SATA_NCQ; 12495+module_param(ncq_en, uint, 0600); 12496+MODULE_PARM_DESC(ncq_en, "ahci ncq flag (default:1)"); 12497+#endif 12498+ 12499+#ifdef CONFIG_HISI_SATA 12500+extern unsigned int sata_port_map; 12501+#endif 12502+ 12503 static const struct ata_port_info ahci_port_info = { 12504 .flags = AHCI_FLAG_COMMON, 12505 .pio_mask = ATA_PIO4, 12506@@ -59,8 +69,21 @@ static int ahci_probe(struct platform_device *pdev) 12507 of_property_read_u32(dev->of_node, 12508 "ports-implemented", &hpriv->force_port_map); 12509 12510+#ifdef CONFIG_HISI_SATA 12511+ hpriv->type = ORI_AHCI; 12512+ hpriv->force_port_map = sata_port_map; 12513+#ifndef CONFIG_HISI_ESATA 12514+ hpriv->flags |= AHCI_HFLAG_NO_SXS; 12515+#endif 12516+ 12517+#ifdef CONFIG_HISI_SATA_NCQ 12518+ if (!ncq_en) 12519+ hpriv->flags |= AHCI_HFLAG_NO_NCQ; 12520+#endif 12521+#else 12522 if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) 12523 hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; 12524+#endif 12525 12526 port = acpi_device_get_match_data(dev); 12527 if (!port) 12528diff --git a/drivers/ata/hisi_sata_dbg.c b/drivers/ata/hisi_sata_dbg.c 12529new file mode 100644 12530index 000000000..935c71689 12531--- /dev/null 12532+++ b/drivers/ata/hisi_sata_dbg.c 12533@@ -0,0 +1,174 @@ 12534+/* 12535+ * Copyright (c) 2009-2014 HiSilicon Technologies Co., Ltd. 12536+ * 12537+ * This program is free software; you can redistribute it and/or modify 12538+ * it under the terms of the GNU General Public License as published by 12539+ * the Free Software Foundation; either version 2 of the License, or 12540+ * (at your option) any later version. 12541+ * 12542+ * This program is distributed in the hope that it will be useful, 12543+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 12544+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12545+ * GNU General Public License for more details. 12546+ * 12547+ * You should have received a copy of the GNU General Public License 12548+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 12549+ */ 12550+ 12551+#include <linux/kernel.h> 12552+#include <linux/delay.h> 12553+#include <linux/module.h> 12554+#include <linux/libata.h> 12555+#include <linux/io.h> 12556+ 12557+#include "ahci.h" 12558+#include "hisi_sata_dbg.h" 12559+ 12560+void hisi_sata_mem_dump(unsigned int *addr, unsigned int size) 12561+{ 12562+ unsigned int ix; 12563+ 12564+ for (ix = 0; ix < size; ix += 0x04, addr++) { 12565+ if (!(ix & 0x0F)) 12566+ pr_debug("\n0x%08X: ", 12567+ (unsigned int)virt_to_phys(addr)); 12568+ pr_debug("%08X ", *addr); 12569+ } 12570+} 12571+EXPORT_SYMBOL(hisi_sata_mem_dump); 12572+ 12573+void hisi_sata_phys_mem_dump(unsigned int addr, unsigned int size) 12574+{ 12575+ hisi_sata_mem_dump(phys_to_virt(addr), size); 12576+} 12577+EXPORT_SYMBOL(hisi_sata_phys_mem_dump); 12578+ 12579+void hisi_ahci_reg_dump(void) 12580+{ 12581+ unsigned int ix; 12582+ unsigned int regbase; 12583+ 12584+ regbase = CONFIG_HISI_SATA_IOBASE; 12585+ pr_debug("AHCI GHC Register dump:"); 12586+ for (ix = 0; ix <= 0x28; ix += 0x04) { 12587+ if (!(ix & 0x0F)) 12588+ pr_debug("\n0x%08X: ", (regbase + ix)); 12589+ } 12590+ pr_debug("\n"); 12591+ 12592+ regbase = CONFIG_HISI_SATA_IOBASE + 0x0100; 12593+ pr_debug("AHCI PORT 0 Register dump:"); 12594+ for (ix = 0; ix <= 0x7F; ix += 0x04) { 12595+ if (!(ix & 0x0F)) 12596+ pr_debug("\n0x%08X: ", (regbase + ix)); 12597+ } 12598+ pr_debug("\n"); 12599+} 12600+EXPORT_SYMBOL(hisi_ahci_reg_dump); 12601+ 12602+void hisi_ahci_rx_fis_dump(struct ata_link *link, int pmp_port_num) 12603+{ 12604+ struct ahci_port_priv *pp = NULL; 12605+ 12606+ pp = link->ap->private_data; 12607+ if (NULL == pp) { 12608+ pr_debug("Error: pp=NULL\n"); 12609+ return; 12610+ } 12611+ pr_debug("ACHI Received FIS:"); 12612+ hisi_sata_phys_mem_dump((unsigned int)(pp->rx_fis_dma), 12613+ AHCI_RX_FIS_SZ * pmp_port_num); 12614+ pr_debug("\n"); 12615+} 12616+EXPORT_SYMBOL_GPL(hisi_ahci_rx_fis_dump); 12617+ 12618+void hisi_ata_taskfile_dump(struct ata_taskfile *tf) 12619+{ 12620+ if (NULL == tf) { 12621+ pr_debug("Error: tf=NULL\n"); 12622+ return; 12623+ } 12624+ 12625+ pr_debug("Taskfile dump:\n"); 12626+ pr_debug("flags:0x%08lX, protocol:0x%02X, command:0x%02X, device:0x%02X, ctl:0x%02X\n", 12627+ tf->flags, tf->protocol, tf->command, tf->device, tf->ctl); 12628+ pr_debug("feature:0x%08X, nsect:0x%02X, lbal:0x%02X, lbam:0x%02X, lbah:0x%02X\n", 12629+ tf->feature, tf->nsect, tf->lbal, tf->lbam, tf->lbah); 12630+ pr_debug("hob_feature:0x%08X, hob_nsect:0x%02X, hob_lbal:0x%02X, hob_lbam:0x%02X, hob_lbah:0x%02X\n", 12631+ tf->hob_feature, tf->hob_nsect, tf->hob_lbal, 12632+ tf->hob_lbam, tf->hob_lbah); 12633+} 12634+EXPORT_SYMBOL_GPL(hisi_ata_taskfile_dump); 12635+ 12636+static void __hisi_ahci_st_md(void __iomem *addr) 12637+{ 12638+ unsigned int *addr_v = NULL; 12639+ unsigned int *tmp = NULL; 12640+ unsigned int i; 12641+ 12642+ addr_v = (unsigned int *)addr; 12643+ 12644+ pr_debug("\n\n"); 12645+ for (i = 0; i < 16; i++) { 12646+ tmp = addr_v + i * 4; 12647+ pr_debug("%8x: %8x %8x %8x %8x\n", 12648+ (unsigned int)(uintptr_t)(addr + i * 16), 12649+ *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3)); 12650+ } 12651+ 12652+ pr_debug("\n"); 12653+} 12654+ 12655+void hisi_ahci_st_dump(const void __iomem *port_base) 12656+{ 12657+ unsigned int tmp; 12658+ 12659+ pr_debug("\n**********Dmac status**********\n"); 12660+ tmp = readl(port_base + 0x58); 12661+ pr_debug("txdmac_curr_st:0x%2x\n", (tmp >> 24) & 0xf); 12662+ tmp = readl(port_base + 0x64); 12663+ pr_debug("rxdmac_curr_st:0x%2x\n", (tmp >> 24) & 0xf); 12664+ tmp = readl(port_base + 0x70); 12665+ pr_debug("dmac tx fifo:count-0x%x-empty-%x-ful-%x\n", 12666+ (tmp >> 0) & 0xff, 12667+ (tmp >> 16) & 0x1, (tmp >> 17) & 0x1); 12668+ pr_debug("dmac rx fifo:count-0x%x-empty-%x-ful-%x\n", 12669+ (tmp >> 8) & 0xff, 12670+ (tmp >> 18) & 0x1, (tmp >> 19) & 0x1); 12671+ 12672+ pr_debug("\n"); 12673+ pr_debug("**********HBA status**********\n"); 12674+ tmp = readl(port_base + 0x50); 12675+ pr_debug("pxxx_curr_st:0x%2x ndrx_curr_st:0x%2x\n", 12676+ (tmp >> 24) & 0xf, 12677+ (tmp >> 16) & 0xff); 12678+ pr_debug("cfis_curr_st:0x%2x piox_curr_st:0x%2x\n", 12679+ (tmp >> 12) & 0xf, 12680+ (tmp >> 8) & 0xf); 12681+ pr_debug("pmxx_curr_st:0x%2x errx_curr_st:0x%2x\n", 12682+ (tmp >> 4) & 0xf, 12683+ (tmp >> 0) & 0xf); 12684+ 12685+ pr_debug("\n"); 12686+ pr_debug("**********Link status**********\n"); 12687+ tmp = readl(port_base + 0x54); 12688+ pr_debug("link_curr_st:0x%2x\n", (tmp >> 24) & 0x1f); 12689+ pr_debug("link tx fifo:count-0x%x-empty-%x-ful-%x\n", 12690+ (tmp >> 0) & 0x1f, 12691+ (tmp >> 5) & 0x1, (tmp >> 6) & 0x1); 12692+ pr_debug("link rx fifo:count-0x%x-empty-%x-ful-%x\n", 12693+ (tmp >> 8) & 0x1f, 12694+ (tmp >> 13) & 0x1, (tmp >> 14) & 0x1); 12695+ pr_debug("link df fifo:count-0x%x-empty-%x-ful-%x\n\n", 12696+ (tmp >> 16) & 0x1f, 12697+ (tmp >> 21) & 0x1, (tmp >> 22) & 0x1); 12698+ 12699+ pr_debug("**********CMD header**********\n"); 12700+ tmp = readl(port_base + 0x0); 12701+ __hisi_ahci_st_md(phys_to_virt(tmp)); 12702+ __hisi_ahci_st_md(phys_to_virt(tmp + 0x100)); 12703+ __hisi_ahci_st_md(phys_to_virt(tmp + 0x200)); 12704+ __hisi_ahci_st_md(phys_to_virt(tmp + 0x300)); 12705+} 12706+EXPORT_SYMBOL_GPL(hisi_ahci_st_dump); 12707+ 12708diff --git a/drivers/ata/hisi_sata_dbg.h b/drivers/ata/hisi_sata_dbg.h 12709new file mode 100644 12710index 000000000..5103658a4 12711--- /dev/null 12712+++ b/drivers/ata/hisi_sata_dbg.h 12713@@ -0,0 +1,58 @@ 12714+/* 12715+ * Copyright (c) 2009-2014 HiSilicon Technologies Co., Ltd. 12716+ * 12717+ * This program is free software; you can redistribute it and/or modify 12718+ * it under the terms of the GNU General Public License as published by 12719+ * the Free Software Foundation; either version 2 of the License, or 12720+ * (at your option) any later version. 12721+ * 12722+ * This program is distributed in the hope that it will be useful, 12723+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 12724+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12725+ * GNU General Public License for more details. 12726+ * 12727+ * You should have received a copy of the GNU General Public License 12728+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 12729+ */ 12730+ 12731+#ifndef _HISI_SATA_DBG_H 12732+#define _HISI_SATA_DBG_H 12733+#include <linux/kernel.h> 12734+#include <linux/delay.h> 12735+#include <linux/libata.h> 12736+#include "ahci.h" 12737+ 12738+void hisi_sata_mem_dump(unsigned int *addr, unsigned int size); 12739+void hisi_sata_phys_mem_dump(unsigned int addr, unsigned int size); 12740+void hisi_ahci_rx_fis_dump(struct ata_link *link, int pmp_port_num); 12741+void hisi_ata_taskfile_dump(struct ata_taskfile *tf); 12742+void hisi_ahci_st_dump(const void __iomem *port_base); 12743+void hisi_ahci_reg_dump(void); 12744+ 12745+#define HISI_AHCI_REG_DUMP(X) \ 12746+do { \ 12747+ pr_debug("------------------[ Start ]--------------------\n"); \ 12748+ pr_debug("Dump AHCI registers at %s %d\n", __func__, __LINE__); \ 12749+ hisi_ahci_reg_dump(); \ 12750+ pr_debug("------------------[ End ]--------------------\n"); \ 12751+} while (0) 12752+ 12753+#define hisi_sata_readl(addr) do { \ 12754+ unsigned int reg = readl((unsigned int)addr); \ 12755+ pr_debug("HI_AHCI(REG) %s:%d: readl(0x%08X) = 0x%08X\n", \ 12756+ __func__, __LINE__, (unsigned int)addr, reg); \ 12757+ reg; \ 12758+ } while (0) 12759+ 12760+#define hisi_sata_writel(v, addr) do { writel(v, (unsigned int)addr); \ 12761+ pr_debug("HI_AHCI(REG) %s:%d: writel(0x%08X) = 0x%08X\n", \ 12762+ __func__, __LINE__, (unsigned int)addr, \ 12763+ (unsigned int)(v)); \ 12764+ } while (0) 12765+ 12766+#undef HISI_DUMP_AHCI_REG_OPS 12767+#ifdef HISI_DUMP_AHCI_REG_OPS 12768+#define readl(addr) hisi_sata_readl(addr) 12769+#define write(v, addr) hisi_sata_writel(v, addr) 12770+#endif 12771+#endif /* _HISI_SATA_DBG_H */ 12772diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c 12773index fec2e9754..bff99aebd 100644 12774--- a/drivers/ata/libahci.c 12775+++ b/drivers/ata/libahci.c 12776@@ -31,6 +31,7 @@ 12777 #include <linux/pci.h> 12778 #include "ahci.h" 12779 #include "libata.h" 12780+#include "hisi_sata_dbg.h" 12781 12782 static int ahci_skip_host_reset; 12783 int ahci_ignore_sss; 12784@@ -42,6 +43,33 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip) 12785 module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); 12786 MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); 12787 12788+#ifdef CONFIG_HISI_SATA_FBS 12789+static int fbs_en = CONFIG_HISI_SATA_FBS; 12790+module_param(fbs_en, uint, 0600); 12791+MODULE_PARM_DESC(fbs_en, "ahci fbs flags (default:1)"); 12792+ 12793+#define AHCI_TIMEOUT_COUNT 10 12794+#define AHCI_POLL_TIMER (20 * HZ) 12795+ 12796+struct ata_fbs_ctrl { 12797+ unsigned int fbs_enable_ctrl; /* fbs enable or disable control switch */ 12798+ unsigned int fbs_mode_ctrl; /* 1.5G: fbs disable, 3G/6G: fbs enable */ 12799+ unsigned int fbs_enable_flag; 12800+ unsigned int fbs_disable_flag; 12801+ unsigned int fbs_cmd_issue_flag; 12802+ struct timer_list poll_timer; 12803+#ifdef CONFIG_HISI_SATA 12804+ struct ata_port *ap; 12805+#endif 12806+}; 12807+static struct ata_fbs_ctrl fbs_ctrl[4]; 12808+extern void hisi_sata_set_fifoth(void *mmio); 12809+#endif 12810+#ifdef CONFIG_HISI_SATA 12811+extern void hisi_sata_reset_rxtx_assert(unsigned int port_no); 12812+extern void hisi_sata_reset_rxtx_deassert(unsigned int port_no); 12813+#endif 12814+ 12815 static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, 12816 unsigned hints); 12817 static ssize_t ahci_led_show(struct ata_port *ap, char *buf); 12818@@ -460,6 +488,13 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) 12819 cap |= HOST_CAP_NCQ; 12820 } 12821 12822+#ifdef CONFIG_HISI_SATA 12823+ if ((cap & HOST_CAP_SXS) && (hpriv->flags & AHCI_HFLAG_NO_SXS)) { 12824+ dev_info(dev, "controller can't support eSATA, turning off CAP_SXS\n"); 12825+ cap &= ~HOST_CAP_SXS; 12826+ } 12827+#endif 12828+ 12829 if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { 12830 dev_info(dev, "controller can't do PMP, turning off CAP_PMP\n"); 12831 cap &= ~HOST_CAP_PMP; 12832@@ -1396,8 +1431,28 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, 12833 bool fbs_disabled = false; 12834 int rc; 12835 12836+#ifdef CONFIG_HISI_SATA_FBS 12837+ unsigned int port_num = ap->port_no; 12838+#endif 12839+ 12840 DPRINTK("ENTER\n"); 12841 12842+#ifdef CONFIG_HISI_SATA_FBS 12843+ if (fbs_ctrl[port_num].fbs_enable_ctrl && 12844+ (link->pmp == SATA_PMP_CTRL_PORT) && 12845+ (hpriv->type == ORI_AHCI)) { 12846+ struct ahci_port_priv *pp = ap->private_data; 12847+ 12848+ if (pp->fbs_enabled == false) 12849+ ahci_enable_fbs(ap); 12850+ 12851+ fbs_ctrl[port_num].fbs_enable_flag = 0; 12852+ fbs_ctrl[port_num].fbs_disable_flag = 0; 12853+ fbs_ctrl[port_num].fbs_cmd_issue_flag = 0; 12854+ 12855+ } 12856+#endif 12857+ 12858 /* prepare for SRST (AHCI-1.1 10.4.1) */ 12859 rc = ahci_kick_engine(ap); 12860 if (rc && rc != -EOPNOTSUPP) 12861@@ -1426,6 +1481,10 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, 12862 AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY, msecs)) { 12863 rc = -EIO; 12864 reason = "1st FIS failed"; 12865+#ifdef CONFIG_HISI_SATA 12866+ hisi_sata_reset_rxtx_assert(ap->port_no); 12867+ hisi_sata_reset_rxtx_deassert(ap->port_no); 12868+#endif 12869 goto fail; 12870 } 12871 12872@@ -1623,6 +1682,68 @@ static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc) 12873 struct ata_port *ap = qc->ap; 12874 struct ahci_port_priv *pp = ap->private_data; 12875 12876+#ifdef CONFIG_HISI_SATA_FBS 12877+ struct ahci_host_priv *hpriv = ap->host->private_data; 12878+ int is_atapi = ata_is_atapi(qc->tf.protocol); 12879+ void __iomem *port_mmio = ahci_port_base(ap); 12880+ unsigned int port_num = ap->port_no; 12881+ unsigned int cmd_timeout_count; 12882+ 12883+ if (fbs_ctrl[port_num].fbs_enable_ctrl && 12884+ (ap->link.pmp == SATA_PMP_CTRL_PORT) && 12885+ (hpriv->type == ORI_AHCI)) { 12886+ if (is_atapi || fbs_ctrl[ap->port_no].fbs_cmd_issue_flag) { 12887+ mod_timer(&fbs_ctrl[port_num].poll_timer, 12888+ jiffies + AHCI_POLL_TIMER); 12889+ 12890+ if (!fbs_ctrl[port_num].fbs_disable_flag) { 12891+ cmd_timeout_count = 0; 12892+ while (readl(port_mmio + PORT_SCR_ACT) 12893+ || readl(port_mmio 12894+ + PORT_CMD_ISSUE) 12895+ || readl(port_mmio 12896+ + PORT_IRQ_STAT)) { 12897+ cmd_timeout_count++; 12898+ if (cmd_timeout_count >= 12899+ AHCI_TIMEOUT_COUNT) { 12900+ fbs_ctrl[ap->port_no]. 12901+ fbs_cmd_issue_flag = 1; 12902+ return ATA_DEFER_LINK; 12903+ } 12904+ } 12905+ 12906+ if (pp->fbs_enabled == true) 12907+ ahci_disable_fbs(ap); 12908+ 12909+ ap->excl_link = NULL; 12910+ ap->nr_active_links = 0; 12911+ fbs_ctrl[port_num].fbs_disable_flag = 1; 12912+ fbs_ctrl[port_num].fbs_enable_flag = 0; 12913+ fbs_ctrl[ap->port_no].fbs_cmd_issue_flag = 0; 12914+ } 12915+ } else { 12916+ if (fbs_ctrl[port_num].fbs_enable_flag) { 12917+ cmd_timeout_count = 0; 12918+ while (readl(port_mmio + PORT_SCR_ACT) 12919+ || readl(port_mmio 12920+ + PORT_CMD_ISSUE) 12921+ || readl(port_mmio 12922+ + PORT_IRQ_STAT)) { 12923+ cmd_timeout_count++; 12924+ if (cmd_timeout_count >= 12925+ AHCI_TIMEOUT_COUNT) { 12926+ return ATA_DEFER_LINK; 12927+ } 12928+ } 12929+ 12930+ if (pp->fbs_enabled == false) 12931+ ahci_enable_fbs(ap); 12932+ fbs_ctrl[port_num].fbs_enable_flag = 0; 12933+ fbs_ctrl[port_num].fbs_disable_flag = 0; 12934+ } 12935+ } 12936+ } 12937+#endif 12938 if (!sata_pmp_attached(ap) || pp->fbs_enabled) 12939 return ata_std_qc_defer(qc); 12940 else 12941@@ -1669,6 +1790,7 @@ static enum ata_completion_errors ahci_qc_prep(struct ata_queued_cmd *qc) 12942 return AC_ERR_OK; 12943 } 12944 12945+#ifndef CONFIG_HISI_SATA_FBS 12946 static void ahci_fbs_dec_intr(struct ata_port *ap) 12947 { 12948 struct ahci_port_priv *pp = ap->private_data; 12949@@ -1692,6 +1814,7 @@ static void ahci_fbs_dec_intr(struct ata_port *ap) 12950 if (fbs & PORT_FBS_DEC) 12951 dev_err(ap->host->dev, "failed to clear device error\n"); 12952 } 12953+#endif 12954 12955 static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) 12956 { 12957@@ -1799,7 +1922,9 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) 12958 ata_port_freeze(ap); 12959 else if (fbs_need_dec) { 12960 ata_link_abort(link); 12961+#ifndef CONFIG_HISI_SATA_FBS 12962 ahci_fbs_dec_intr(ap); 12963+#endif 12964 } else 12965 ata_port_abort(ap); 12966 } 12967@@ -2200,7 +2325,9 @@ static void ahci_enable_fbs(struct ata_port *ap) 12968 writel(fbs | PORT_FBS_EN, port_mmio + PORT_FBS); 12969 fbs = readl(port_mmio + PORT_FBS); 12970 if (fbs & PORT_FBS_EN) { 12971+#ifndef CONFIG_HISI_SATA_FBS 12972 dev_info(ap->host->dev, "FBS is enabled\n"); 12973+#endif 12974 pp->fbs_enabled = true; 12975 pp->fbs_last_dev = -1; /* initialization */ 12976 } else 12977@@ -2240,6 +2367,9 @@ static void ahci_disable_fbs(struct ata_port *ap) 12978 } 12979 12980 hpriv->start_engine(ap); 12981+#ifdef CONFIG_HISI_SATA_FBS 12982+ hisi_sata_set_fifoth(port_mmio); 12983+#endif 12984 } 12985 12986 static void ahci_pmp_attach(struct ata_port *ap) 12987@@ -2248,12 +2378,24 @@ static void ahci_pmp_attach(struct ata_port *ap) 12988 struct ahci_port_priv *pp = ap->private_data; 12989 u32 cmd; 12990 12991+#ifdef CONFIG_HISI_SATA_FBS 12992+ struct ahci_host_priv *hpriv = ap->host->private_data; 12993+ unsigned int port_num = ap->port_no; 12994+#endif 12995+ 12996 cmd = readl(port_mmio + PORT_CMD); 12997 cmd |= PORT_CMD_PMP; 12998 writel(cmd, port_mmio + PORT_CMD); 12999 13000 ahci_enable_fbs(ap); 13001 13002+#ifdef CONFIG_HISI_SATA_FBS 13003+ if (hpriv->type == ORI_AHCI) { 13004+ if (!fbs_ctrl[port_num].fbs_enable_ctrl) 13005+ ahci_disable_fbs(ap); 13006+ } 13007+#endif 13008+ 13009 pp->intr_mask |= PORT_IRQ_BAD_PMP; 13010 13011 /* 13012@@ -2322,6 +2464,32 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) 13013 } 13014 #endif 13015 13016+#ifdef CONFIG_HISI_SATA_FBS 13017+static void ahci_poll_func(unsigned long arg) 13018+{ 13019+ struct ata_port *ap = (struct ata_port *)arg; 13020+ unsigned int port_num = ap->port_no; 13021+ 13022+ if (ap->link.pmp == SATA_PMP_CTRL_PORT) { 13023+ fbs_ctrl[port_num].fbs_enable_flag = 1; 13024+ fbs_ctrl[port_num].fbs_disable_flag = 0; 13025+ } 13026+} 13027+ 13028+static void ahci_poll_timerout(struct timer_list *t) 13029+{ 13030+ struct ata_fbs_ctrl *ata_fbs_ctrl_ptr = from_timer(ata_fbs_ctrl_ptr, t, poll_timer); 13031+ struct ata_port *ap = ata_fbs_ctrl_ptr->ap; 13032+ 13033+ if (ap == NULL) { 13034+ pr_err("%s:poll_timer parameter is error!\n", __func__); 13035+ return; 13036+ } 13037+ 13038+ ahci_poll_func((uintptr_t)ap); 13039+} 13040+#endif 13041+ 13042 static int ahci_port_start(struct ata_port *ap) 13043 { 13044 struct ahci_host_priv *hpriv = ap->host->private_data; 13045@@ -2414,6 +2582,19 @@ static int ahci_port_start(struct ata_port *ap) 13046 13047 ap->private_data = pp; 13048 13049+#ifdef CONFIG_HISI_SATA_FBS 13050+ if (hpriv->type == ORI_AHCI) { 13051+ fbs_ctrl[ap->port_no].fbs_enable_ctrl = fbs_en; 13052+ fbs_ctrl[ap->port_no].fbs_enable_flag = 0; 13053+ fbs_ctrl[ap->port_no].fbs_disable_flag = 0; 13054+ fbs_ctrl[ap->port_no].fbs_cmd_issue_flag = 0; 13055+ fbs_ctrl[ap->port_no].ap = ap; 13056+ 13057+ timer_setup(&fbs_ctrl[ap->port_no].poll_timer, ahci_poll_timerout, 0); 13058+ fbs_ctrl[ap->port_no].poll_timer.expires = jiffies + AHCI_POLL_TIMER; 13059+ } 13060+#endif 13061+ 13062 /* engage engines, captain */ 13063 return ahci_port_resume(ap); 13064 } 13065diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c 13066index 70da8b86c..5725b026b 100644 13067--- a/drivers/block/paride/pcd.c 13068+++ b/drivers/block/paride/pcd.c 13069@@ -1031,6 +1031,9 @@ static int __init pcd_init(void) 13070 } 13071 13072 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { 13073+ if (!cd->disk) 13074+ continue; 13075+ 13076 if (cd->present) { 13077 register_cdrom(cd->disk, &cd->info); 13078 cd->disk->private_data = cd; 13079diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile 13080index da8fcf147..04bbcd945 100644 13081--- a/drivers/clk/Makefile 13082+++ b/drivers/clk/Makefile 13083@@ -82,6 +82,7 @@ obj-$(CONFIG_ARCH_BERLIN) += berlin/ 13084 obj-$(CONFIG_ARCH_DAVINCI) += davinci/ 13085 obj-$(CONFIG_H8300) += h8300/ 13086 obj-$(CONFIG_ARCH_HISI) += hisilicon/ 13087+obj-$(CONFIG_ARCH_HISI_BVT) += hisilicon/ 13088 obj-y += imgtec/ 13089 obj-y += imx/ 13090 obj-y += ingenic/ 13091diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig 13092index 6a9e93a0b..4d212e5a1 100644 13093--- a/drivers/clk/hisilicon/Kconfig 13094+++ b/drivers/clk/hisilicon/Kconfig 13095@@ -22,6 +22,38 @@ config COMMON_CLK_HI3660 13096 help 13097 Build the clock driver for hi3660. 13098 13099+config COMMON_CLK_HI3531DV200 13100+ tristate "Hi3531DV200 Clock Driver" 13101+ depends on ARCH_HI3531DV200 || COMPILE_TEST 13102+ select RESET_HISI 13103+ default ARCH_HISI_BVT 13104+ help 13105+ Build the clock driver for Hi3531DV200. 13106+ 13107+config COMMON_CLK_HI3535AV100 13108+ tristate "Hi3535AV100 Clock Driver" 13109+ depends on ARCH_HI3535AV100 || COMPILE_TEST 13110+ select RESET_HISI 13111+ default ARCH_HISI_BVT 13112+ help 13113+ Build the clock driver for Hi3535AV100. 13114+ 13115+config COMMON_CLK_HI3521DV200 13116+ tristate "Hi3521DV200 Clock Driver" 13117+ depends on ARCH_HI3521DV200 || COMPILE_TEST 13118+ select RESET_HISI 13119+ default ARCH_HISI_BVT 13120+ help 13121+ Build the clock driver for hi3521DV200. 13122+ 13123+config COMMON_CLK_HI3520DV500 13124+ tristate "Hi3520DV500 Clock Driver" 13125+ depends on ARCH_HI3520DV500 || COMPILE_TEST 13126+ select RESET_HISI 13127+ default ARCH_HISI_BVT 13128+ help 13129+ Build the clock driver for hi3520DV500. 13130+ 13131 config COMMON_CLK_HI3670 13132 bool "Hi3670 Clock Driver" 13133 depends on ARCH_HISI || COMPILE_TEST 13134@@ -37,6 +69,166 @@ config COMMON_CLK_HI3798CV200 13135 help 13136 Build the clock driver for hi3798cv200. 13137 13138+config COMMON_CLK_HI3516A 13139+ tristate "Hi3516A Clock Driver" 13140+ depends on ARCH_HI3516A || COMPILE_TEST 13141+ select RESET_HISI 13142+ default ARCH_HISI 13143+ help 13144+ Build the clock driver for hi3516A. 13145+ 13146+config COMMON_CLK_HI3516CV500 13147+ tristate "Hi3516CV500 Clock Driver" 13148+ depends on ARCH_HI3516CV500 || COMPILE_TEST 13149+ select RESET_HISI 13150+ default ARCH_HISI_BVT 13151+ help 13152+ Build the clock driver for hi3516CV500. 13153+ 13154+config COMMON_CLK_HI3516EV200 13155+ tristate "Hi3516EV200 Clock Driver" 13156+ depends on ARCH_HI3516EV200 || COMPILE_TEST 13157+ select RESET_HISI 13158+ default ARCH_HISI 13159+ help 13160+ Build the clock driver for hi3516EV200. 13161+ 13162+config COMMON_CLK_HI3516EV300 13163+ tristate "Hi3516EV300 Clock Driver" 13164+ depends on ARCH_HI3516EV300 || COMPILE_TEST 13165+ select RESET_HISI 13166+ default ARCH_HISI 13167+ help 13168+ Build the clock driver for hi3516EV300. 13169+ 13170+config COMMON_CLK_HI3518EV300 13171+ tristate "Hi3518EV300 Clock Driver" 13172+ depends on ARCH_HI3518EV300 || COMPILE_TEST 13173+ select RESET_HISI 13174+ default ARCH_HISI 13175+ help 13176+ Build the clock driver for hi3518EV300. 13177+ 13178+config COMMON_CLK_HI3516DV200 13179+ tristate "Hi3516DV200 Clock Driver" 13180+ depends on ARCH_HI3516DV200 || COMPILE_TEST 13181+ select RESET_HISI 13182+ default ARCH_HISI 13183+ help 13184+ Build the clock driver for hi3516DV200. 13185+ 13186+config COMMON_CLK_HI3516DV300 13187+ tristate "Hi3516DV300 Clock Driver" 13188+ depends on ARCH_HI3516DV300 || COMPILE_TEST 13189+ select RESET_HISI 13190+ default ARCH_HISI_BVT 13191+ help 13192+ Build the clock driver for hi3516DV300. 13193+ 13194+config COMMON_CLK_HI3556V200 13195+ tristate "Hi3556V200 Clock Driver" 13196+ depends on ARCH_HI3556V200 || COMPILE_TEST 13197+ select RESET_HISI 13198+ default ARCH_HISI_BVT 13199+ help 13200+ Build the clock driver for hi3556V200. 13201+ 13202+config COMMON_CLK_HI3559V200 13203+ tristate "Hi3559V200 Clock Driver" 13204+ depends on ARCH_HI3559V200 || COMPILE_TEST 13205+ select RESET_HISI 13206+ default ARCH_HISI_BVT 13207+ help 13208+ Build the clock driver for hi3559V200. 13209+ 13210+config COMMON_CLK_HI3562V100 13211+ tristate "Hi3562V100 Clock Driver" 13212+ depends on ARCH_HI3562V100 || COMPILE_TEST 13213+ select RESET_HISI 13214+ default ARCH_HISI_BVT 13215+ help 13216+ Build the clock driver for hi3562V100. 13217+ 13218+config COMMON_CLK_HI3566V100 13219+ tristate "Hi3566V100 Clock Driver" 13220+ depends on ARCH_HI3566V100 || COMPILE_TEST 13221+ select RESET_HISI 13222+ default ARCH_HISI_BVT 13223+ help 13224+ Build the clock driver for hi3566V100. 13225+ 13226+config COMMON_CLK_HI3518EV20X 13227+ tristate "Hi3518EV20X Clock Driver" 13228+ depends on ARCH_HI3518EV20X || COMPILE_TEST 13229+ select RESET_HISI 13230+ default ARCH_HISI_BVT 13231+ help 13232+ Build the clock driver for hi3516A. 13233+ 13234+config COMMON_CLK_HI3536DV100 13235+ tristate "Hi3536DV100 Clock Driver" 13236+ depends on ARCH_HI3536DV100 || COMPILE_TEST 13237+ select RESET_HISI 13238+ default ARCH_HISI 13239+ help 13240+ Build the clock driver for hi3536DV100. 13241+ 13242+config COMMON_CLK_HI3559AV100 13243+ tristate "Hi3559AV100 Clock Driver" 13244+ depends on ARCH_HI3559AV100 || COMPILE_TEST 13245+ select RESET_HISI 13246+ default ARCH_HISI_BVT 13247+ help 13248+ Build the clock driver for hi3559av100. 13249+ 13250+config COMMON_CLK_HI3569V100 13251+ tristate "Hi3569V100 Clock Driver" 13252+ depends on ARCH_HI3569V100 || COMPILE_TEST 13253+ select RESET_HISI 13254+ default ARCH_HISI_BVT 13255+ help 13256+ Build the clock driver for hi3569v100. 13257+ 13258+config COMMON_CLK_HI3521A 13259+ tristate "Hi3521A Clock Driver" 13260+ depends on ARCH_HI3521A || COMPILE_TEST 13261+ select RESET_HISI 13262+ default ARCH_HISI_BVT 13263+ help 13264+ Build the clock driver for hi3521A. 13265+ 13266+config COMMON_CLK_HI3531A 13267+ tristate "Hi3531A Clock Driver" 13268+ depends on ARCH_HI3531A || COMPILE_TEST 13269+ select RESET_HISI 13270+ default ARCH_HISI_BVT 13271+ help 13272+ Build the clock driver for hi3531A. 13273+ 13274+config COMMON_CLK_HI3556AV100 13275+ tristate "Hi3556AV100 Clock Driver" 13276+ depends on ARCH_HI3556AV100 || COMPILE_TEST 13277+ select RESET_HISI 13278+ default ARCH_HISI 13279+ help 13280+ Build the clock driver for hi3556av100. 13281+ 13282+config COMMON_CLK_HI3519AV100 13283+ tristate "Hi3519AV100 Clock Driver" 13284+ depends on ARCH_HI3519AV100 || COMPILE_TEST 13285+ select RESET_HISI 13286+ default ARCH_HISI 13287+ help 13288+ Build the clock driver for hi3519av100. 13289+ 13290+config COMMON_CLK_HI3568V100 13291+ tristate "Hi3568V100 Clock Driver" 13292+ depends on ARCH_HI3568V100 || COMPILE_TEST 13293+ select RESET_HISI 13294+ default ARCH_HISI 13295+ help 13296+ Build the clock driver for hi3568v100. 13297+ 13298 config COMMON_CLK_HI6220 13299 bool "Hi6220 Clock Driver" 13300 depends on ARCH_HISI || COMPILE_TEST 13301@@ -46,7 +238,7 @@ config COMMON_CLK_HI6220 13302 13303 config RESET_HISI 13304 bool "HiSilicon Reset Controller Driver" 13305- depends on ARCH_HISI || COMPILE_TEST 13306+ depends on ARCH_HISI || COMPILE_TEST || ARCH_HISI_BVT 13307 select RESET_CONTROLLER 13308 help 13309 Build reset controller driver for HiSilicon device chipsets. 13310diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile 13311index b2441b99f..91dc23fdb 100644 13312--- a/drivers/clk/hisilicon/Makefile 13313+++ b/drivers/clk/hisilicon/Makefile 13314@@ -14,6 +14,7 @@ obj-$(CONFIG_COMMON_CLK_HI3660) += clk-hi3660.o 13315 obj-$(CONFIG_COMMON_CLK_HI3670) += clk-hi3670.o 13316 obj-$(CONFIG_COMMON_CLK_HI3798CV200) += crg-hi3798cv200.o 13317 obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o 13318+obj-$(CONFIG_COMMON_CLK_HI3516DV300) += clk-hi3516dv300.o 13319 obj-$(CONFIG_RESET_HISI) += reset.o 13320 obj-$(CONFIG_STUB_CLK_HI6220) += clk-hi6220-stub.o 13321 obj-$(CONFIG_STUB_CLK_HI3660) += clk-hi3660-stub.o 13322diff --git a/drivers/clk/hisilicon/clk-hi3516dv300.c b/drivers/clk/hisilicon/clk-hi3516dv300.c 13323new file mode 100644 13324index 000000000..1a2ab9975 13325--- /dev/null 13326+++ b/drivers/clk/hisilicon/clk-hi3516dv300.c 13327@@ -0,0 +1,271 @@ 13328+/* 13329+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 13330+ * 13331+ * This program is free software; you can redistribute it and/or modify it 13332+ * under the terms of the GNU General Public License as published by the 13333+ * Free Software Foundation; either version 2 of the License, or (at your 13334+ * option) any later version. 13335+ * 13336+ * This program is distributed in the hope that it will be useful, 13337+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 13338+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13339+ * GNU General Public License for more details. 13340+ * 13341+ * You should have received a copy of the GNU General Public License 13342+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 13343+ * 13344+ */ 13345+ 13346+#include <dt-bindings/clock/hi3516dv300-clock.h> 13347+#include <linux/clk-provider.h> 13348+#include <linux/module.h> 13349+#include <linux/of_device.h> 13350+#include <linux/platform_device.h> 13351+#include "clk.h" 13352+#include "crg.h" 13353+#include "reset.h" 13354+ 13355+static struct hisi_fixed_rate_clock hi3516dv300_fixed_rate_clks[] __initdata = { 13356+ { HI3516DV300_FIXED_3M, "3m", NULL, 0, 3000000, }, 13357+ { HI3516DV300_FIXED_6M, "6m", NULL, 0, 6000000, }, 13358+ { HI3516DV300_FIXED_12M, "12m", NULL, 0, 12000000, }, 13359+ { HI3516DV300_FIXED_24M, "24m", NULL, 0, 24000000, }, 13360+ { HI3516DV300_FIXED_25M, "25m", NULL, 0, 25000000, }, 13361+ { HI3516DV300_FIXED_50M, "50m", NULL, 0, 50000000, }, 13362+ { HI3516DV300_FIXED_54M, "54m", NULL, 0, 54000000, }, 13363+ { HI3516DV300_FIXED_83P3M, "83.3m", NULL, 0, 83300000, }, 13364+ { HI3516DV300_FIXED_100M, "100m", NULL, 0, 100000000, }, 13365+ { HI3516DV300_FIXED_125M, "125m", NULL, 0, 125000000, }, 13366+ { HI3516DV300_FIXED_150M, "150m", NULL, 0, 150000000, }, 13367+ { HI3516DV300_FIXED_163M, "163m", NULL, 0, 163000000, }, 13368+ { HI3516DV300_FIXED_200M, "200m", NULL, 0, 200000000, }, 13369+ { HI3516DV300_FIXED_250M, "250m", NULL, 0, 250000000, }, 13370+ { HI3516DV300_FIXED_257M, "257m", NULL, 0, 257000000, }, 13371+ { HI3516DV300_FIXED_300M, "300m", NULL, 0, 300000000, }, 13372+ { HI3516DV300_FIXED_324M, "324m", NULL, 0, 324000000, }, 13373+ { HI3516DV300_FIXED_342M, "342m", NULL, 0, 342000000, }, 13374+ { HI3516DV300_FIXED_342M, "375m", NULL, 0, 375000000, }, 13375+ { HI3516DV300_FIXED_396M, "396m", NULL, 0, 396000000, }, 13376+ { HI3516DV300_FIXED_400M, "400m", NULL, 0, 400000000, }, 13377+ { HI3516DV300_FIXED_448M, "448m", NULL, 0, 448000000, }, 13378+ { HI3516DV300_FIXED_500M, "500m", NULL, 0, 500000000, }, 13379+ { HI3516DV300_FIXED_540M, "540m", NULL, 0, 540000000, }, 13380+ { HI3516DV300_FIXED_600M, "600m", NULL, 0, 600000000, }, 13381+ { HI3516DV300_FIXED_750M, "750m", NULL, 0, 750000000, }, 13382+ { HI3516DV300_FIXED_1000M, "1000m", NULL, 0, 1000000000, }, 13383+ { HI3516DV300_FIXED_1500M, "1500m", NULL, 0, 1500000000UL, }, 13384+}; 13385+ 13386+static const char *sysaxi_mux_p[] __initconst = { 13387+ "24m", "200m", "300m" 13388+}; 13389+static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; 13390+static const char *uart_mux_p[] __initconst = {"24m", "6m"}; 13391+static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "163m", "200m", "257m", "300m", "396m"}; 13392+static const char *eth_mux_p[] __initconst = {"100m", "54m"}; 13393+static const char *mmc_mux_p[] __initconst = {"100m", "50m", "25m"}; 13394+static const char *pwm_mux_p[] __initconst = {"3m", "50m", "24m", "24m"}; 13395+ 13396+static u32 sysaxi_mux_table[] = {0, 1, 2}; 13397+static u32 sysapb_mux_table[] = {0, 1}; 13398+static u32 uart_mux_table[] = {0, 1}; 13399+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; 13400+static u32 eth_mux_table[] = {0, 1}; 13401+static u32 mmc_mux_table[] = {1, 2, 3}; 13402+static u32 pwm_mux_table[] = {0, 1, 2, 3}; 13403+ 13404+static struct hisi_mux_clock hi3516dv300_mux_clks[] __initdata = { 13405+ { 13406+ HI3516DV300_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, 13407+ ARRAY_SIZE(sysaxi_mux_p), 13408+ CLK_SET_RATE_PARENT, 0x80, 6, 2, 0, sysaxi_mux_table, 13409+ }, 13410+ { 13411+ HI3516DV300_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, 13412+ ARRAY_SIZE(sysapb_mux_p), 13413+ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, 13414+ }, 13415+ { 13416+ HI3516DV300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), 13417+ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, 13418+ }, 13419+ { 13420+ HI3516DV300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 13421+ CLK_SET_RATE_PARENT, 0x148, 2, 2, 0, mmc_mux_table, 13422+ }, 13423+ { 13424+ HI3516DV300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 13425+ CLK_SET_RATE_PARENT, 0x160, 2, 2, 0, mmc_mux_table, 13426+ }, 13427+ { 13428+ HI3516DV300_MMC2_MUX, "mmc2_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 13429+ CLK_SET_RATE_PARENT, 0x154, 2, 2, 0, mmc_mux_table, 13430+ }, 13431+ { 13432+ HI3516DV300_UART_MUX, "uart_mux0", uart_mux_p, 13433+ ARRAY_SIZE(uart_mux_p), 13434+ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, 13435+ }, 13436+ { 13437+ HI3516DV300_UART1_MUX, "uart_mux1", uart_mux_p, 13438+ ARRAY_SIZE(uart_mux_p), 13439+ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, 13440+ }, 13441+ { 13442+ HI3516DV300_UART2_MUX, "uart_mux2", uart_mux_p, 13443+ ARRAY_SIZE(uart_mux_p), 13444+ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, 13445+ }, 13446+ { 13447+ HI3516DV300_UART3_MUX, "uart_mux3", uart_mux_p, 13448+ ARRAY_SIZE(uart_mux_p), 13449+ CLK_SET_RATE_PARENT, 0x1bc, 21, 1, 0, uart_mux_table, 13450+ }, 13451+ { 13452+ HI3516DV300_UART4_MUX, "uart_mux4", uart_mux_p, 13453+ ARRAY_SIZE(uart_mux_p), 13454+ CLK_SET_RATE_PARENT, 0x1bc, 22, 1, 0, uart_mux_table, 13455+ }, 13456+ { 13457+ HI3516DV300_PWM_MUX, "pwm_mux", pwm_mux_p, 13458+ ARRAY_SIZE(pwm_mux_p), 13459+ CLK_SET_RATE_PARENT, 0x1bc, 8, 2, 0, pwm_mux_table, 13460+ }, 13461+ /* ethernet clock select */ 13462+ { 13463+ HI3516DV300_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), 13464+ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, 13465+ }, 13466+}; 13467+ 13468+static struct hisi_fixed_factor_clock hi3516dv300_fixed_factor_clks[] __initdata 13469+ = { 13470+ { 13471+ HI3516DV300_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, 13472+ CLK_SET_RATE_PARENT 13473+ }, 13474+}; 13475+ 13476+static struct hisi_gate_clock hi3516dv300_gate_clks[] __initdata = { 13477+ { 13478+ HI3516DV300_FMC_CLK, "clk_fmc", "fmc_mux", 13479+ CLK_SET_RATE_PARENT, 0x144, 1, 0, 13480+ }, 13481+ { 13482+ HI3516DV300_MMC0_CLK, "clk_mmc0", "mmc0_mux", 13483+ CLK_SET_RATE_PARENT, 0x148, 1, 0, 13484+ }, 13485+ { 13486+ HI3516DV300_MMC1_CLK, "clk_mmc1", "mmc1_mux", 13487+ CLK_SET_RATE_PARENT, 0x160, 1, 0, 13488+ }, 13489+ { 13490+ HI3516DV300_MMC2_CLK, "clk_mmc2", "mmc2_mux", 13491+ CLK_SET_RATE_PARENT, 0x154, 1, 0, 13492+ }, 13493+ { 13494+ HI3516DV300_UART0_CLK, "clk_uart0", "uart_mux0", 13495+ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, 13496+ }, 13497+ { 13498+ HI3516DV300_UART1_CLK, "clk_uart1", "uart_mux1", 13499+ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, 13500+ }, 13501+ { 13502+ HI3516DV300_UART2_CLK, "clk_uart2", "uart_mux2", 13503+ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, 13504+ }, 13505+ { 13506+ HI3516DV300_UART3_CLK, "clk_uart3", "uart_mux3", 13507+ CLK_SET_RATE_PARENT, 0x1b8, 3, 0, 13508+ }, 13509+ { 13510+ HI3516DV300_UART4_CLK, "clk_uart4", "uart_mux4", 13511+ CLK_SET_RATE_PARENT, 0x1b8, 4, 0, 13512+ }, 13513+ { 13514+ HI3516DV300_I2C0_CLK, "clk_i2c0", "50m", 13515+ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, 13516+ }, 13517+ { 13518+ HI3516DV300_I2C1_CLK, "clk_i2c1", "50m", 13519+ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, 13520+ }, 13521+ { 13522+ HI3516DV300_I2C2_CLK, "clk_i2c2", "50m", 13523+ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, 13524+ }, 13525+ { 13526+ HI3516DV300_I2C3_CLK, "clk_i2c3", "50m", 13527+ CLK_SET_RATE_PARENT, 0x1b8, 14, 0, 13528+ }, 13529+ { 13530+ HI3516DV300_I2C4_CLK, "clk_i2c4", "50m", 13531+ CLK_SET_RATE_PARENT, 0x1b8, 15, 0, 13532+ }, 13533+ { 13534+ HI3516DV300_I2C5_CLK, "clk_i2c5", "50m", 13535+ CLK_SET_RATE_PARENT, 0x1b8, 16, 0, 13536+ }, 13537+ { 13538+ HI3516DV300_I2C6_CLK, "clk_i2c6", "50m", 13539+ CLK_SET_RATE_PARENT, 0x1b8, 17, 0, 13540+ }, 13541+ { 13542+ HI3516DV300_I2C7_CLK, "clk_i2c7", "50m", 13543+ CLK_SET_RATE_PARENT, 0x1b8, 18, 0, 13544+ }, 13545+ { 13546+ HI3516DV300_SPI0_CLK, "clk_spi0", "100m", 13547+ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, 13548+ }, 13549+ { 13550+ HI3516DV300_SPI1_CLK, "clk_spi1", "100m", 13551+ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, 13552+ }, 13553+ { 13554+ HI3516DV300_SPI2_CLK, "clk_spi2", "100m", 13555+ CLK_SET_RATE_PARENT, 0x1bc, 14, 0, 13556+ }, 13557+ { 13558+ HI3516DV300_ETH0_CLK, "clk_eth0", "eth_mux", 13559+ CLK_SET_RATE_PARENT, 0x16c, 1, 0, 13560+ }, 13561+ { 13562+ HI3516DV300_DMAC_CLK, "clk_dmac", NULL, 13563+ CLK_SET_RATE_PARENT, 0x194, 1, 0, 13564+ }, 13565+ { 13566+ HI3516DV300_DMAC_AXICLK, "axiclk_dmac", NULL, 13567+ CLK_SET_RATE_PARENT, 0x194, 2, 0, 13568+ }, 13569+ { 13570+ HI3516DV300_PWM_CLK, "clk_pwm", "pwm_mux", 13571+ CLK_SET_RATE_PARENT, 0x1bc, 7, 0, 13572+ }, 13573+}; 13574+ 13575+static void __init hi3516dv300_clk_init(struct device_node *np) 13576+{ 13577+ struct hisi_clock_data *clk_data; 13578+ 13579+ clk_data = hisi_clk_init(np, HI3516DV300_NR_CLKS); 13580+ if (!clk_data) 13581+ return; 13582+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) 13583+ hibvt_reset_init(np, HI3516DV300_NR_RSTS); 13584+ 13585+ hisi_clk_register_fixed_rate(hi3516dv300_fixed_rate_clks, 13586+ ARRAY_SIZE(hi3516dv300_fixed_rate_clks), 13587+ clk_data); 13588+ hisi_clk_register_mux(hi3516dv300_mux_clks, ARRAY_SIZE(hi3516dv300_mux_clks), 13589+ clk_data); 13590+ hisi_clk_register_fixed_factor(hi3516dv300_fixed_factor_clks, 13591+ ARRAY_SIZE(hi3516dv300_fixed_factor_clks), clk_data); 13592+ hisi_clk_register_gate(hi3516dv300_gate_clks, 13593+ ARRAY_SIZE(hi3516dv300_gate_clks), clk_data); 13594+} 13595+ 13596+CLK_OF_DECLARE(hi3516dv300_clk, "hisilicon,hi3516dv300-clock", 13597+ hi3516dv300_clk_init); 13598+ 13599diff --git a/drivers/clk/hisilicon/clk-hi3519av100.c b/drivers/clk/hisilicon/clk-hi3519av100.c 13600new file mode 100644 13601index 000000000..657767941 13602--- /dev/null 13603+++ b/drivers/clk/hisilicon/clk-hi3519av100.c 13604@@ -0,0 +1,559 @@ 13605+/* 13606+ * Hi3519A Clock Driver 13607+ * 13608+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 13609+ * 13610+ * This program is free software; you can redistribute it and/or modify it 13611+ * under the terms of the GNU General Public License as published by the 13612+ * Free Software Foundation; either version 2 of the License, or (at your 13613+ * option) any later version. 13614+ * 13615+ * This program is distributed in the hope that it will be useful, 13616+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 13617+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13618+ * GNU General Public License for more details. 13619+ * 13620+ * You should have received a copy of the GNU General Public License 13621+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 13622+ * 13623+ */ 13624+ 13625+#include <linux/of_address.h> 13626+#include <dt-bindings/clock/hi3519av100-clock.h> 13627+#include <linux/slab.h> 13628+#include <linux/delay.h> 13629+#include "clk.h" 13630+#include "reset.h" 13631+ 13632+struct hi3519av100_pll_clock { 13633+ u32 id; 13634+ const char *name; 13635+ const char *parent_name; 13636+ u32 ctrl_reg1; 13637+ u8 frac_shift; 13638+ u8 frac_width; 13639+ u8 postdiv1_shift; 13640+ u8 postdiv1_width; 13641+ u8 postdiv2_shift; 13642+ u8 postdiv2_width; 13643+ u32 ctrl_reg2; 13644+ u8 fbdiv_shift; 13645+ u8 fbdiv_width; 13646+ u8 refdiv_shift; 13647+ u8 refdiv_width; 13648+}; 13649+ 13650+struct hi3519av100_clk_pll { 13651+ struct clk_hw hw; 13652+ u32 id; 13653+ void __iomem *ctrl_reg1; 13654+ u8 frac_shift; 13655+ u8 frac_width; 13656+ u8 postdiv1_shift; 13657+ u8 postdiv1_width; 13658+ u8 postdiv2_shift; 13659+ u8 postdiv2_width; 13660+ void __iomem *ctrl_reg2; 13661+ u8 fbdiv_shift; 13662+ u8 fbdiv_width; 13663+ u8 refdiv_shift; 13664+ u8 refdiv_width; 13665+}; 13666+ 13667+static struct hi3519av100_pll_clock hi3519av100_pll_clks[] __initdata = { 13668+ { 13669+ HI3519AV100_APLL_CLK, "apll", NULL, 0x0, 0, 24, 24, 3, 28, 3, 13670+ 0x4, 0, 12, 12, 6 13671+ }, 13672+}; 13673+ 13674+#define to_pll_clk(_hw) container_of(_hw, struct hi3519av100_clk_pll, hw) 13675+ 13676+/* soc clk config */ 13677+static struct hisi_fixed_rate_clock hi3519av100_fixed_rate_clks[] __initdata = { 13678+ { HI3519AV100_FIXED_2376M, "2376m", NULL, 0, 2376000000UL, }, 13679+ { HI3519AV100_FIXED_1188M, "1188m", NULL, 0, 1188000000, }, 13680+ { HI3519AV100_FIXED_594M, "594m", NULL, 0, 594000000, }, 13681+ { HI3519AV100_FIXED_297M, "297m", NULL, 0, 297000000, }, 13682+ { HI3519AV100_FIXED_148P5M, "148p5m", NULL, 0, 148500000, }, 13683+ { HI3519AV100_FIXED_74P25M, "74p25m", NULL, 0, 74250000, }, 13684+ { HI3519AV100_FIXED_792M, "792m", NULL, 0, 792000000, }, 13685+ { HI3519AV100_FIXED_475M, "475m", NULL, 0, 475000000, }, 13686+ { HI3519AV100_FIXED_340M, "340m", NULL, 0, 340000000, }, 13687+ { HI3519AV100_FIXED_72M, "72m", NULL, 0, 72000000, }, 13688+ { HI3519AV100_FIXED_400M, "400m", NULL, 0, 400000000, }, 13689+ { HI3519AV100_FIXED_200M, "200m", NULL, 0, 200000000, }, 13690+ { HI3519AV100_FIXED_54M, "54m", NULL, 0, 54000000, }, 13691+ { HI3519AV100_FIXED_27M, "27m", NULL, 0, 1188000000, }, 13692+ { HI3519AV100_FIXED_37P125M, "37p125m", NULL, 0, 37125000, }, 13693+ { HI3519AV100_FIXED_3000M, "3000m", NULL, 0, 3000000000UL, }, 13694+ { HI3519AV100_FIXED_1500M, "1500m", NULL, 0, 1500000000, }, 13695+ { HI3519AV100_FIXED_500M, "500m", NULL, 0, 500000000, }, 13696+ { HI3519AV100_FIXED_250M, "250m", NULL, 0, 250000000, }, 13697+ { HI3519AV100_FIXED_125M, "125m", NULL, 0, 125000000, }, 13698+ { HI3519AV100_FIXED_1000M, "1000m", NULL, 0, 1000000000, }, 13699+ { HI3519AV100_FIXED_600M, "600m", NULL, 0, 600000000, }, 13700+ { HI3519AV100_FIXED_750M, "750m", NULL, 0, 750000000, }, 13701+ { HI3519AV100_FIXED_150M, "150m", NULL, 0, 150000000, }, 13702+ { HI3519AV100_FIXED_75M, "75m", NULL, 0, 75000000, }, 13703+ { HI3519AV100_FIXED_300M, "300m", NULL, 0, 300000000, }, 13704+ { HI3519AV100_FIXED_60M, "60m", NULL, 0, 60000000, }, 13705+ { HI3519AV100_FIXED_214M, "214m", NULL, 0, 214000000, }, 13706+ { HI3519AV100_FIXED_107M, "107m", NULL, 0, 107000000, }, 13707+ { HI3519AV100_FIXED_100M, "100m", NULL, 0, 100000000, }, 13708+ { HI3519AV100_FIXED_50M, "50m", NULL, 0, 50000000, }, 13709+ { HI3519AV100_FIXED_25M, "25m", NULL, 0, 25000000, }, 13710+ { HI3519AV100_FIXED_24M, "24m", NULL, 0, 24000000, }, 13711+ { HI3519AV100_FIXED_3M, "3m", NULL, 0, 3000000, }, 13712+ { HI3519AV100_FIXED_100K, "100k", NULL, 0, 100000, }, 13713+ { HI3519AV100_FIXED_400K, "400k", NULL, 0, 400000, }, 13714+ { HI3519AV100_FIXED_49P5M, "49p5m", NULL, 0, 49500000, }, 13715+ { HI3519AV100_FIXED_99M, "99m", NULL, 0, 99000000, }, 13716+ { HI3519AV100_FIXED_187P5M, "187p5m", NULL, 0, 187500000, }, 13717+ { HI3519AV100_FIXED_198M, "198m", NULL, 0, 198000000, }, 13718+}; 13719+ 13720+ 13721+static const char *fmc_mux_p[] __initdata = { 13722+ "24m", "100m", "150m", "198m", "250m", "300m", "396m" 13723+}; 13724+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; 13725+ 13726+static const char *mmc_mux_p[] __initdata = { 13727+ "100k", "25m", "49p5m", "99m", "187p5m", "150m", "198m", "400k" 13728+}; 13729+static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; 13730+ 13731+static const char *sysapb_mux_p[] __initdata = { 13732+ "24m", "50m", 13733+}; 13734+static u32 sysapb_mux_table[] = {0, 1}; 13735+ 13736+static const char *sysbus_mux_p[] __initdata = { 13737+ "24m", "300m" 13738+}; 13739+static u32 sysbus_mux_table[] = {0, 1}; 13740+ 13741+static const char *uart_mux_p[] __initdata = {"50m", "24m", "3m"}; 13742+static u32 uart_mux_table[] = {0, 1, 2}; 13743+ 13744+static const char *a53_1_clksel_mux_p[] __initdata = { 13745+ "24m", "apll", "vpll", "792m" 13746+}; 13747+static u32 a53_1_clksel_mux_table[] = {0, 1, 2, 3}; 13748+ 13749+static struct hisi_mux_clock hi3519av100_mux_clks[] __initdata = { 13750+ { 13751+ HI3519AV100_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), 13752+ CLK_SET_RATE_PARENT, 0x170, 2, 3, 0, fmc_mux_table, 13753+ }, 13754+ 13755+ { 13756+ HI3519AV100_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 13757+ CLK_SET_RATE_PARENT, 0x1a8, 24, 3, 0, mmc_mux_table, 13758+ }, 13759+ 13760+ { 13761+ HI3519AV100_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 13762+ CLK_SET_RATE_PARENT, 0x1ec, 24, 3, 0, mmc_mux_table, 13763+ }, 13764+ 13765+ { 13766+ HI3519AV100_MMC2_MUX, "mmc2_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 13767+ CLK_SET_RATE_PARENT, 0x214, 24, 3, 0, mmc_mux_table, 13768+ }, 13769+ 13770+ { 13771+ HI3519AV100_SYSAPB_MUX, "sysapb_mux", sysapb_mux_p, ARRAY_SIZE(sysapb_mux_p), 13772+ CLK_SET_RATE_PARENT, 0xe8, 3, 1, 0, sysapb_mux_table 13773+ }, 13774+ 13775+ { 13776+ HI3519AV100_SYSBUS_MUX, "sysbus_mux", sysbus_mux_p, ARRAY_SIZE(sysbus_mux_p), 13777+ CLK_SET_RATE_PARENT, 0xe8, 0, 1, 1, sysbus_mux_table 13778+ }, 13779+ 13780+ { 13781+ HI3519AV100_UART0_MUX, "uart0_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13782+ CLK_SET_RATE_PARENT, 0x1a4, 0, 2, 1, uart_mux_table 13783+ }, 13784+ 13785+ { 13786+ HI3519AV100_UART1_MUX, "uart1_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13787+ CLK_SET_RATE_PARENT, 0x1a4, 2, 2, 1, uart_mux_table 13788+ }, 13789+ 13790+ { 13791+ HI3519AV100_UART2_MUX, "uart2_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13792+ CLK_SET_RATE_PARENT, 0x1a4, 4, 2, 1, uart_mux_table 13793+ }, 13794+ 13795+ { 13796+ HI3519AV100_UART3_MUX, "uart3_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13797+ CLK_SET_RATE_PARENT, 0x1a4, 6, 2, 1, uart_mux_table 13798+ }, 13799+ 13800+ { 13801+ HI3519AV100_UART4_MUX, "uart4_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13802+ CLK_SET_RATE_PARENT, 0x1a4, 8, 2, 1, uart_mux_table 13803+ }, 13804+ 13805+ { 13806+ HI3519AV100_UART5_MUX, "uart5_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13807+ CLK_SET_RATE_PARENT, 0x1a4, 10, 2, 1, uart_mux_table 13808+ }, 13809+ 13810+ { 13811+ HI3519AV100_UART6_MUX, "uart6_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13812+ CLK_SET_RATE_PARENT, 0x1a4, 12, 2, 1, uart_mux_table 13813+ }, 13814+ 13815+ { 13816+ HI3519AV100_UART7_MUX, "uart7_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13817+ CLK_SET_RATE_PARENT, 0x1a4, 14, 2, 1, uart_mux_table 13818+ }, 13819+ 13820+ { 13821+ HI3519AV100_UART8_MUX, "uart8_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 13822+ CLK_SET_RATE_PARENT, 0x1a4, 28, 2, 1, uart_mux_table 13823+ }, 13824+ 13825+ { 13826+ HI3519AV100_A53_1_MUX, "a53_1_mux", a53_1_clksel_mux_p, ARRAY_SIZE(a53_1_clksel_mux_p), 13827+ CLK_SET_RATE_PARENT, 0xe4, 10, 2, 3, a53_1_clksel_mux_table 13828+ }, 13829+ 13830+}; 13831+ 13832+static struct hisi_fixed_factor_clock hi3519av100_fixed_factor_clks[] __initdata 13833+ = { 13834+ 13835+}; 13836+ 13837+static struct hisi_gate_clock hi3519av100_gate_clks[] __initdata = { 13838+ { 13839+ HI3519AV100_FMC_CLK, "clk_fmc", "fmc_mux", 13840+ CLK_SET_RATE_PARENT, 0x170, 1, 0, 13841+ }, 13842+ { 13843+ HI3519AV100_MMC0_CLK, "clk_mmc0", "mmc0_mux", 13844+ CLK_SET_RATE_PARENT, 0x1a8, 28, 0, 13845+ }, 13846+ { 13847+ HI3519AV100_MMC1_CLK, "clk_mmc1", "mmc1_mux", 13848+ CLK_SET_RATE_PARENT, 0x1ec, 28, 0, 13849+ }, 13850+ { 13851+ HI3519AV100_MMC2_CLK, "clk_mmc2", "mmc2_mux", 13852+ CLK_SET_RATE_PARENT, 0x214, 28, 0, 13853+ }, 13854+ { 13855+ HI3519AV100_UART0_CLK, "clk_uart0", "uart0_mux", 13856+ CLK_SET_RATE_PARENT, 0x198, 16, 0, 13857+ }, 13858+ { 13859+ HI3519AV100_UART1_CLK, "clk_uart1", "uart1_mux", 13860+ CLK_SET_RATE_PARENT, 0x198, 17, 0, 13861+ }, 13862+ { 13863+ HI3519AV100_UART2_CLK, "clk_uart2", "uart2_mux", 13864+ CLK_SET_RATE_PARENT, 0x198, 18, 0, 13865+ }, 13866+ { 13867+ HI3519AV100_UART3_CLK, "clk_uart3", "uart3_mux", 13868+ CLK_SET_RATE_PARENT, 0x198, 19, 0, 13869+ }, 13870+ { 13871+ HI3519AV100_UART4_CLK, "clk_uart4", "uart4_mux", 13872+ CLK_SET_RATE_PARENT, 0x198, 20, 0, 13873+ }, 13874+ { 13875+ HI3519AV100_UART5_CLK, "clk_uart5", "uart5_mux", 13876+ CLK_SET_RATE_PARENT, 0x198, 21, 0, 13877+ }, 13878+ { 13879+ HI3519AV100_UART6_CLK, "clk_uart6", "uart6_mux", 13880+ CLK_SET_RATE_PARENT, 0x198, 22, 0, 13881+ }, 13882+ { 13883+ HI3519AV100_UART7_CLK, "clk_uart7", "uart7_mux", 13884+ CLK_SET_RATE_PARENT, 0x198, 23, 0, 13885+ }, 13886+ { 13887+ HI3519AV100_UART8_CLK, "clk_uart8", "uart8_mux", 13888+ CLK_SET_RATE_PARENT, 0x198, 29, 0, 13889+ }, 13890+ { 13891+ HI3519AV100_ETH_CLK, "clk_eth", NULL, 13892+ CLK_SET_RATE_PARENT, 0x0174, 1, 0, 13893+ }, 13894+ { 13895+ HI3519AV100_ETH_MACIF_CLK, "clk_eth_macif", NULL, 13896+ CLK_SET_RATE_PARENT, 0x0174, 5, 0, 13897+ }, 13898+ /* i2c */ 13899+ { 13900+ HI3519AV100_I2C0_CLK, "clk_i2c0", "50m", 13901+ CLK_SET_RATE_PARENT, 0x01a0, 16, 0, 13902+ }, 13903+ { 13904+ HI3519AV100_I2C1_CLK, "clk_i2c1", "50m", 13905+ CLK_SET_RATE_PARENT, 0x01a0, 17, 0, 13906+ }, 13907+ { 13908+ HI3519AV100_I2C2_CLK, "clk_i2c2", "50m", 13909+ CLK_SET_RATE_PARENT, 0x01a0, 18, 0, 13910+ }, 13911+ { 13912+ HI3519AV100_I2C3_CLK, "clk_i2c3", "50m", 13913+ CLK_SET_RATE_PARENT, 0x01a0, 19, 0, 13914+ }, 13915+ { 13916+ HI3519AV100_I2C4_CLK, "clk_i2c4", "50m", 13917+ CLK_SET_RATE_PARENT, 0x01a0, 20, 0, 13918+ }, 13919+ { 13920+ HI3519AV100_I2C5_CLK, "clk_i2c5", "50m", 13921+ CLK_SET_RATE_PARENT, 0x01a0, 21, 0, 13922+ }, 13923+ { 13924+ HI3519AV100_I2C6_CLK, "clk_i2c6", "50m", 13925+ CLK_SET_RATE_PARENT, 0x01a0, 22, 0, 13926+ }, 13927+ { 13928+ HI3519AV100_I2C7_CLK, "clk_i2c7", "50m", 13929+ CLK_SET_RATE_PARENT, 0x01a0, 23, 0, 13930+ }, 13931+ { 13932+ HI3519AV100_I2C8_CLK, "clk_i2c8", "50m", 13933+ CLK_SET_RATE_PARENT, 0x01a0, 24, 0, 13934+ }, 13935+ { 13936+ HI3519AV100_I2C9_CLK, "clk_i2c9", "50m", 13937+ CLK_SET_RATE_PARENT, 0x01a0, 25, 0, 13938+ }, 13939+ { 13940+ HI3519AV100_SPI0_CLK, "clk_spi0", "100m", 13941+ CLK_SET_RATE_PARENT, 0x0198, 24, 0, 13942+ }, 13943+ { 13944+ HI3519AV100_SPI1_CLK, "clk_spi1", "100m", 13945+ CLK_SET_RATE_PARENT, 0x0198, 25, 0, 13946+ }, 13947+ { 13948+ HI3519AV100_SPI2_CLK, "clk_spi2", "100m", 13949+ CLK_SET_RATE_PARENT, 0x0198, 26, 0, 13950+ }, 13951+ { 13952+ HI3519AV100_SPI3_CLK, "clk_spi3", "100m", 13953+ CLK_SET_RATE_PARENT, 0x0198, 27, 0, 13954+ }, 13955+ { 13956+ HI3519AV100_SPI4_CLK, "clk_spi4", "100m", 13957+ CLK_SET_RATE_PARENT, 0x0198, 28, 0, 13958+ }, 13959+ { 13960+ HI3519AV100_EDMAC_AXICLK, "axi_clk_edmac", NULL, 13961+ CLK_SET_RATE_PARENT, 0x16c, 6, 0, 13962+ }, 13963+ { 13964+ HI3519AV100_EDMAC_CLK, "clk_edmac", NULL, 13965+ CLK_SET_RATE_PARENT, 0x16c, 5, 0, 13966+ }, 13967+ { 13968+ HI3519AV100_EDMAC1_AXICLK, "axi_clk_edmac1", NULL, 13969+ CLK_SET_RATE_PARENT, 0x16c, 9, 0, 13970+ }, 13971+ { 13972+ HI3519AV100_EDMAC1_CLK, "clk_edmac1", NULL, 13973+ CLK_SET_RATE_PARENT, 0x16c, 8, 0, 13974+ }, 13975+ { 13976+ HI3519AV100_VDMAC_CLK, "clk_vdmac", NULL, 13977+ CLK_SET_RATE_PARENT, 0x14c, 5, 0, 13978+ }, 13979+}; 13980+ 13981+static void hi3519av100_calc_pll(u32 *frac_val, 13982+ u32 *postdiv1_val, 13983+ u32 *postdiv2_val, 13984+ u32 *fbdiv_val, 13985+ u32 *refdiv_val, 13986+ u64 rate) 13987+{ 13988+ u64 rem; 13989+ *frac_val = 0; 13990+ rem = do_div(rate, 1000000); 13991+ *fbdiv_val = rate; 13992+ *refdiv_val = 24; 13993+ if ((rem * (1 << 24)) > ULLONG_MAX) { 13994+ pr_err("Data over limits!\n"); 13995+ return; 13996+ } 13997+ rem = rem * (1 << 24); 13998+ do_div(rem, 1000000); 13999+ *frac_val = rem; 14000+} 14001+ 14002+static int clk_pll_set_rate(struct clk_hw *hw, 14003+ unsigned long rate, 14004+ unsigned long parent_rate) 14005+{ 14006+ struct hi3519av100_clk_pll *clk = to_pll_clk(hw); 14007+ u32 frac_val, postdiv1_val, postdiv2_val, fbdiv_val, refdiv_val; 14008+ u32 val; 14009+ 14010+ postdiv1_val = postdiv2_val = 0; 14011+ 14012+ hi3519av100_calc_pll(&frac_val, &postdiv1_val, &postdiv2_val, 14013+ &fbdiv_val, &refdiv_val, rate); 14014+ 14015+ val = readl_relaxed(clk->ctrl_reg1); 14016+ val &= ~(((1 << clk->frac_width) - 1) << clk->frac_shift); 14017+ val &= ~(((1 << clk->postdiv1_width) - 1) << clk->postdiv1_shift); 14018+ val &= ~(((1 << clk->postdiv2_width) - 1) << clk->postdiv2_shift); 14019+ 14020+ val |= frac_val << clk->frac_shift; 14021+ val |= postdiv1_val << clk->postdiv1_shift; 14022+ val |= postdiv2_val << clk->postdiv2_shift; 14023+ writel_relaxed(val, clk->ctrl_reg1); 14024+ 14025+ val = readl_relaxed(clk->ctrl_reg2); 14026+ val &= ~(((1 << clk->fbdiv_width) - 1) << clk->fbdiv_shift); 14027+ val &= ~(((1 << clk->refdiv_width) - 1) << clk->refdiv_shift); 14028+ 14029+ val |= fbdiv_val << clk->fbdiv_shift; 14030+ val |= refdiv_val << clk->refdiv_shift; 14031+ writel_relaxed(val, clk->ctrl_reg2); 14032+ 14033+ return 0; 14034+} 14035+ 14036+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, 14037+ unsigned long parent_rate) 14038+{ 14039+ struct hi3519av100_clk_pll *clk = to_pll_clk(hw); 14040+ u64 frac_val, fbdiv_val; 14041+ u32 val; 14042+ u64 tmp, rate; 14043+ u32 refdiv_val; 14044+ 14045+ val = readl_relaxed(clk->ctrl_reg1); 14046+ val = val >> clk->frac_shift; 14047+ val &= ((1 << clk->frac_width) - 1); 14048+ frac_val = val; 14049+ 14050+ val = readl_relaxed(clk->ctrl_reg2); 14051+ val = val >> clk->fbdiv_shift; 14052+ val &= ((1 << clk->fbdiv_width) - 1); 14053+ fbdiv_val = val; 14054+ 14055+ val = readl_relaxed(clk->ctrl_reg2); 14056+ val = val >> clk->refdiv_shift; 14057+ val &= ((1 << clk->refdiv_width) - 1); 14058+ refdiv_val = val; 14059+ 14060+ /* rate = 24000000 * (fbdiv + frac / (1<<24) ) / refdiv */ 14061+ rate = 0; 14062+ if ((24000000 * fbdiv_val) > ULLONG_MAX) { 14063+ pr_err("Data over limits!\n"); 14064+ return 0; 14065+ } 14066+ tmp = 24000000 * fbdiv_val; 14067+ rate += tmp; 14068+ do_div(rate, refdiv_val); 14069+ 14070+ return rate; 14071+} 14072+ 14073+static int clk_pll_determine_rate(struct clk_hw *hw, 14074+ struct clk_rate_request *req) 14075+{ 14076+ return req->rate; 14077+} 14078+ 14079+static struct clk_ops clk_pll_ops = { 14080+ .set_rate = clk_pll_set_rate, 14081+ .determine_rate = clk_pll_determine_rate, 14082+ .recalc_rate = clk_pll_recalc_rate, 14083+}; 14084+ 14085+void __init hi3519av100_clk_register_pll(struct hi3519av100_pll_clock *clks, 14086+ int nums, struct hisi_clock_data *data) 14087+{ 14088+ int i; 14089+ void __iomem *base = NULL; 14090+ 14091+ if (clks == NULL || data == NULL) 14092+ return; 14093+ 14094+ base = data->base; 14095+ for (i = 0; i < nums; i++) { 14096+ struct hi3519av100_clk_pll *p_clk = NULL; 14097+ struct clk *clk = NULL; 14098+ struct clk_init_data init; 14099+ 14100+ p_clk = kzalloc(sizeof(*p_clk), GFP_KERNEL); 14101+ if (!p_clk) 14102+ return; 14103+ 14104+ init.name = clks[i].name; 14105+ init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; 14106+ init.parent_names = 14107+ (clks[i].parent_name ? &clks[i].parent_name : NULL); 14108+ init.num_parents = (clks[i].parent_name ? 1 : 0); 14109+ init.ops = &clk_pll_ops; 14110+ 14111+ p_clk->ctrl_reg1 = base + clks[i].ctrl_reg1; 14112+ p_clk->frac_shift = clks[i].frac_shift; 14113+ p_clk->frac_width = clks[i].frac_width; 14114+ p_clk->postdiv1_shift = clks[i].postdiv1_shift; 14115+ p_clk->postdiv1_width = clks[i].postdiv1_width; 14116+ p_clk->postdiv2_shift = clks[i].postdiv2_shift; 14117+ p_clk->postdiv2_width = clks[i].postdiv2_width; 14118+ 14119+ p_clk->ctrl_reg2 = base + clks[i].ctrl_reg2; 14120+ p_clk->fbdiv_shift = clks[i].fbdiv_shift; 14121+ p_clk->fbdiv_width = clks[i].fbdiv_width; 14122+ p_clk->refdiv_shift = clks[i].refdiv_shift; 14123+ p_clk->refdiv_width = clks[i].refdiv_width; 14124+ p_clk->hw.init = &init; 14125+ 14126+ clk = clk_register(NULL, &p_clk->hw); 14127+ if (IS_ERR(clk)) { 14128+ kfree(p_clk); 14129+ pr_err("%s: failed to register clock %s\n", 14130+ __func__, clks[i].name); 14131+ continue; 14132+ } 14133+ 14134+ data->clk_data.clks[clks[i].id] = clk; 14135+ } 14136+} 14137+ 14138+static void __init hi3519av100_clk_init(struct device_node *np) 14139+{ 14140+ struct hisi_clock_data *clk_data; 14141+ 14142+ clk_data = hisi_clk_init(np, HI3519AV100_NR_CLKS); 14143+ if (!clk_data) 14144+ return; 14145+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) 14146+ hibvt_reset_init(np, HI3519AV100_NR_RSTS); 14147+ 14148+ hisi_clk_register_fixed_rate(hi3519av100_fixed_rate_clks, 14149+ ARRAY_SIZE(hi3519av100_fixed_rate_clks), 14150+ clk_data); 14151+ hisi_clk_register_mux(hi3519av100_mux_clks, ARRAY_SIZE(hi3519av100_mux_clks), 14152+ clk_data); 14153+ hisi_clk_register_fixed_factor(hi3519av100_fixed_factor_clks, 14154+ ARRAY_SIZE(hi3519av100_fixed_factor_clks), clk_data); 14155+ hisi_clk_register_gate(hi3519av100_gate_clks, 14156+ ARRAY_SIZE(hi3519av100_gate_clks), clk_data); 14157+ 14158+ hi3519av100_clk_register_pll(hi3519av100_pll_clks, 14159+ ARRAY_SIZE(hi3519av100_pll_clks), clk_data); 14160+} 14161+ 14162+CLK_OF_DECLARE(hi3519av100_clk, "hisilicon,hi3519av100-clock", 14163+ hi3519av100_clk_init); 14164diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c 14165index ba6afad66..b13b91609 100644 14166--- a/drivers/clk/hisilicon/clk-hisi-phase.c 14167+++ b/drivers/clk/hisilicon/clk-hisi-phase.c 14168@@ -77,7 +77,7 @@ static int hisi_clk_set_phase(struct clk_hw *hw, int degrees) 14169 14170 val = readl(phase->reg); 14171 val &= ~phase->mask; 14172- val |= regval << phase->shift; 14173+ val |= (unsigned int)regval << phase->shift; 14174 writel(val, phase->reg); 14175 14176 spin_unlock_irqrestore(phase->lock, flags); 14177diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c 14178index 54d9fdc93..9ca4fc05f 100644 14179--- a/drivers/clk/hisilicon/clk.c 14180+++ b/drivers/clk/hisilicon/clk.c 14181@@ -82,6 +82,10 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np, 14182 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data); 14183 return clk_data; 14184 err_data: 14185+ if (base) { 14186+ iounmap(base); 14187+ base = NULL; 14188+ } 14189 kfree(clk_data); 14190 err: 14191 return NULL; 14192diff --git a/drivers/clk/hisilicon/crg.h b/drivers/clk/hisilicon/crg.h 14193index 803f6ba6d..a84758660 100644 14194--- a/drivers/clk/hisilicon/crg.h 14195+++ b/drivers/clk/hisilicon/crg.h 14196@@ -13,7 +13,7 @@ struct hisi_reset_controller; 14197 14198 struct hisi_crg_funcs { 14199 struct hisi_clock_data* (*register_clks)(struct platform_device *pdev); 14200- void (*unregister_clks)(struct platform_device *pdev); 14201+ void (*unregister_clks)(const struct platform_device *pdev); 14202 }; 14203 14204 struct hisi_crg_dev { 14205diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c 14206index 93cee17db..e9a03d924 100644 14207--- a/drivers/clk/hisilicon/reset.c 14208+++ b/drivers/clk/hisilicon/reset.c 14209@@ -87,6 +87,36 @@ static const struct reset_control_ops hisi_reset_ops = { 14210 .deassert = hisi_reset_deassert, 14211 }; 14212 14213+#ifdef CONFIG_ARCH_HISI_BVT 14214+int __init hibvt_reset_init(struct device_node *np, 14215+ int nr_rsts) 14216+{ 14217+ struct hisi_reset_controller *rstc; 14218+ 14219+ rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); 14220+ if (!rstc) 14221+ return -ENOMEM; 14222+ 14223+ rstc->membase = of_iomap(np, 0); 14224+ if (!rstc->membase){ 14225+ kfree(rstc); 14226+ return -EINVAL; 14227+ } 14228+ 14229+ spin_lock_init(&rstc->lock); 14230+ 14231+ rstc->rcdev.owner = THIS_MODULE; 14232+ rstc->rcdev.nr_resets = nr_rsts; 14233+ rstc->rcdev.ops = &hisi_reset_ops; 14234+ rstc->rcdev.of_node = np; 14235+ rstc->rcdev.of_reset_n_cells = 2; 14236+ rstc->rcdev.of_xlate = hisi_reset_of_xlate; 14237+ 14238+ return reset_controller_register(&rstc->rcdev); 14239+} 14240+EXPORT_SYMBOL_GPL(hibvt_reset_init); 14241+#endif 14242+ 14243 struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev) 14244 { 14245 struct hisi_reset_controller *rstc; 14246diff --git a/drivers/clk/hisilicon/reset.h b/drivers/clk/hisilicon/reset.h 14247index 81ff9e9e3..5954bdf91 100644 14248--- a/drivers/clk/hisilicon/reset.h 14249+++ b/drivers/clk/hisilicon/reset.h 14250@@ -11,6 +11,9 @@ struct hisi_reset_controller; 14251 14252 #ifdef CONFIG_RESET_CONTROLLER 14253 struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev); 14254+#ifdef CONFIG_ARCH_HISI_BVT 14255+int __init hibvt_reset_init(struct device_node *np, int nr_rsts); 14256+#endif 14257 void hisi_reset_exit(struct hisi_reset_controller *rstc); 14258 #else 14259 static inline 14260diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig 14261index 39f4d8866..ddf6f7373 100644 14262--- a/drivers/clocksource/Kconfig 14263+++ b/drivers/clocksource/Kconfig 14264@@ -347,6 +347,14 @@ config ARM_ARCH_TIMER_EVTSTREAM 14265 config ARM_ARCH_TIMER_OOL_WORKAROUND 14266 bool 14267 14268+config ARM_ARCH_TIMER_VCT_ACCESS 14269+ bool "Support for ARM architected timer virtual counter access in userspace" 14270+ default n 14271+ depends on ARM_ARCH_TIMER 14272+ help 14273+ This option enables support for reading the ARM architected timer's 14274+ virtual counter in userspace. 14275+ 14276 config FSL_ERRATUM_A008585 14277 bool "Workaround for Freescale/NXP Erratum A-008585" 14278 default y 14279@@ -402,6 +410,12 @@ config ARM_TIMER_SP804 14280 select CLKSRC_MMIO 14281 select TIMER_OF if OF 14282 14283+config TIMER_HISP804 14284+ bool "Support for hisilicon SP804 module" 14285+ depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP 14286+ select CLKSRC_MMIO 14287+ select TIMER_OF if OF 14288+ 14289 config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK 14290 bool 14291 depends on ARM_GLOBAL_TIMER 14292diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile 14293index 1c444cc3b..1a184f6ba 100644 14294--- a/drivers/clocksource/Makefile 14295+++ b/drivers/clocksource/Makefile 14296@@ -69,6 +69,7 @@ obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o 14297 obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o 14298 obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o 14299 obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp804.o 14300+obj-$(CONFIG_TIMER_HISP804) += timer-hisp804.o 14301 obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o 14302 obj-$(CONFIG_KEYSTONE_TIMER) += timer-keystone.o 14303 obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o 14304diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c 14305index f4881764b..d435d1266 100644 14306--- a/drivers/clocksource/arm_arch_timer.c 14307+++ b/drivers/clocksource/arm_arch_timer.c 14308@@ -631,7 +631,8 @@ static bool arch_timer_counter_has_wa(void) 14309 } 14310 #else 14311 #define arch_timer_check_ool_workaround(t,a) do { } while(0) 14312-#define arch_timer_this_cpu_has_cntvct_wa() ({false;}) 14313+#define arch_timer_this_cpu_has_cntvct_wa() \ 14314+ ({IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS) ? false : true;}) 14315 #define arch_timer_counter_has_wa() ({false;}) 14316 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */ 14317 14318diff --git a/drivers/clocksource/timer-hisp804.c b/drivers/clocksource/timer-hisp804.c 14319new file mode 100644 14320index 000000000..b2c857a41 14321--- /dev/null 14322+++ b/drivers/clocksource/timer-hisp804.c 14323@@ -0,0 +1,356 @@ 14324+/****************************************************************************** 14325+ * Copyright (C) 2017 Hisilicon Technologies CO.,LTD. 14326+ * 14327+ * Licensed under the Apache License, Version 2.0 (the "License"); 14328+ * you may not use this file except in compliance with the License. 14329+ * You may obtain a copy of the License at 14330+ * 14331+ * http://www.apache.org/licenses/LICENSE-2.0 14332+ * 14333+ * Unless required by applicable law or agreed to in writing, software 14334+ * distributed under the License is distributed on an "AS IS" BASIS, 14335+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14336+ * See the License for the specific language governing permissions and 14337+ * limitations under the License. 14338+ * 14339+ * Create By Cai Zhiying 2017.2.4 14340+ * 14341+******************************************************************************/ 14342+ 14343+#define pr_fmt(fmt) "hisp804: " fmt 14344+ 14345+#include <linux/clk.h> 14346+#include <linux/clocksource.h> 14347+#include <linux/clockchips.h> 14348+#include <linux/err.h> 14349+#include <linux/interrupt.h> 14350+#include <linux/irq.h> 14351+#include <linux/cpu.h> 14352+#include <linux/io.h> 14353+#include <linux/smp.h> 14354+#include <linux/of.h> 14355+#include <linux/of_address.h> 14356+#include <linux/of_irq.h> 14357+#include <linux/sched_clock.h> 14358+ 14359+#define TIMER_LOAD 0x00 /* ACVR rw */ 14360+#define TIMER_VALUE 0x04 /* ACVR ro */ 14361+#define TIMER_CTRL 0x08 /* ACVR rw */ 14362+#define TIMER_CTRL_ONESHOT (1 << 0) /* CVR */ 14363+#define TIMER_CTRL_32BIT (1 << 1) /* CVR */ 14364+#define TIMER_CTRL_DIV1 (0 << 2) /* ACVR */ 14365+#define TIMER_CTRL_DIV16 (1 << 2) /* ACVR */ 14366+#define TIMER_CTRL_DIV256 (2 << 2) /* ACVR */ 14367+#define TIMER_CTRL_IE (1 << 5) /* VR */ 14368+#define TIMER_CTRL_PERIODIC (1 << 6) /* ACVR */ 14369+#define TIMER_CTRL_ENABLE (1 << 7) /* ACVR */ 14370+ 14371+#define TIMER_INTCLR 0x0c /* ACVR wo */ 14372+#define TIMER_RIS 0x10 /* CVR ro */ 14373+#define TIMER_MIS 0x14 /* CVR ro */ 14374+#define TIMER_BGLOAD 0x18 /* CVR rw */ 14375+ 14376+#define CPU_TASKS_FROZEN 0x0010 14377+ 14378+struct hisp804_clocksource { 14379+ void __iomem *base; 14380+ struct clocksource clksrc; 14381+}; 14382+ 14383+#define to_hiclksrc(e) \ 14384+ container_of(e, struct hisp804_clocksource, clksrc) 14385+ 14386+static struct hisp804_clocksource hisp804_clksrc; 14387+ 14388+static void __iomem *hisp804_sched_clock_base; 14389+ 14390+struct hisp804_clockevent_device { 14391+ struct clock_event_device clkevt; 14392+ struct irqaction action; 14393+ void __iomem *base; 14394+ unsigned long rate; 14395+ unsigned long reload; 14396+ char name[16]; 14397+}; 14398+ 14399+#define to_hiclkevt(e) \ 14400+ container_of(e, struct hisp804_clockevent_device, clkevt) 14401+ 14402+static struct hisp804_clockevent_device __percpu *hisp804_clkevt; 14403+ 14404+static void hisp804_clocksource_enable(void __iomem *base) 14405+{ 14406+ writel(0, base + TIMER_CTRL); 14407+ writel(0xffffffff, base + TIMER_LOAD); 14408+ writel(0xffffffff, base + TIMER_VALUE); 14409+ writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, 14410+ base + TIMER_CTRL); 14411+} 14412+ 14413+static void hisp804_clocksource_resume(struct clocksource *cs) 14414+{ 14415+ hisp804_clocksource_enable(to_hiclksrc(cs)->base); 14416+} 14417+ 14418+static u64 notrace hisp804_sched_clock_read(void) 14419+{ 14420+ return ~readl_relaxed(hisp804_sched_clock_base + TIMER_VALUE); 14421+} 14422+ 14423+static cycle_t hisp804_clocksource_read(struct clocksource *cs) 14424+{ 14425+ return ~(cycle_t)readl_relaxed(to_hiclksrc(cs)->base + TIMER_VALUE); 14426+} 14427+ 14428+static void __init hisp804_clocksource_init(void __iomem *base, 14429+ unsigned long rate) 14430+{ 14431+ hisp804_clksrc.base = base; 14432+ hisp804_clksrc.clksrc.name = "hisp804"; 14433+ hisp804_clksrc.clksrc.rating = 499; 14434+ hisp804_clksrc.clksrc.read = hisp804_clocksource_read; 14435+ hisp804_clksrc.clksrc.resume = hisp804_clocksource_resume; 14436+ hisp804_clksrc.clksrc.mask = CLOCKSOURCE_MASK(32); 14437+ hisp804_clksrc.clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; 14438+ 14439+ hisp804_clocksource_enable(base); 14440+ 14441+ clocksource_register_hz(&hisp804_clksrc.clksrc, rate); 14442+ 14443+ hisp804_sched_clock_base = base; 14444+ sched_clock_register(hisp804_sched_clock_read, 32, rate); 14445+} 14446+ 14447+static int hisp804_clockevent_shutdown(struct clock_event_device *clkevt) 14448+{ 14449+ struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt); 14450+ 14451+ writel(0, hiclkevt->base + TIMER_CTRL); 14452+ 14453+ return 0; 14454+} 14455+ 14456+static int hisp804_clockevent_set_next_event(unsigned long next, 14457+ struct clock_event_device *clkevt) 14458+{ 14459+ unsigned long ctrl; 14460+ struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt); 14461+ 14462+ writel(TIMER_CTRL_32BIT, hiclkevt->base + TIMER_CTRL); 14463+ 14464+ writel(next, hiclkevt->base + TIMER_LOAD); 14465+ writel(next, hiclkevt->base + TIMER_LOAD); 14466+ 14467+ ctrl = TIMER_CTRL_32BIT | 14468+ TIMER_CTRL_IE | 14469+ TIMER_CTRL_ONESHOT | 14470+ TIMER_CTRL_ENABLE; 14471+ writel(ctrl, hiclkevt->base + TIMER_CTRL); 14472+ 14473+ return 0; 14474+} 14475+ 14476+static int sp804_clockevent_set_periodic(struct clock_event_device *clkevt) 14477+{ 14478+ unsigned long ctrl; 14479+ struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt); 14480+ 14481+ writel(TIMER_CTRL_32BIT, hiclkevt->base + TIMER_CTRL); 14482+ 14483+ writel(hiclkevt->reload, hiclkevt->base + TIMER_LOAD); 14484+ writel(hiclkevt->reload, hiclkevt->base + TIMER_LOAD); 14485+ 14486+ ctrl = TIMER_CTRL_32BIT | 14487+ TIMER_CTRL_IE | 14488+ TIMER_CTRL_PERIODIC | 14489+ TIMER_CTRL_ENABLE; 14490+ writel(ctrl, hiclkevt->base + TIMER_CTRL); 14491+ 14492+ return 0; 14493+} 14494+ 14495+static irqreturn_t hisp804_clockevent_timer_interrupt(int irq, void *dev_id) 14496+{ 14497+ struct clock_event_device *clkevt = dev_id; 14498+ struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt); 14499+ 14500+ /* clear the interrupt */ 14501+ writel(1, hiclkevt->base + TIMER_INTCLR); 14502+ 14503+ clkevt->event_handler(clkevt); 14504+ 14505+ return IRQ_HANDLED; 14506+} 14507+ 14508+static int hisp804_clockevent_setup(struct hisp804_clockevent_device *hiclkevt) 14509+{ 14510+ struct clock_event_device *clkevt = &hiclkevt->clkevt; 14511+ 14512+ writel(0, hiclkevt->base + TIMER_CTRL); 14513+ 14514+ BUG_ON(setup_irq(clkevt->irq, &hiclkevt->action)); 14515+ 14516+ irq_force_affinity(clkevt->irq, clkevt->cpumask); 14517+ 14518+ clockevents_config_and_register(clkevt, hiclkevt->rate, 0xf, 14519+ 0x7fffffff); 14520+ 14521+ return 0; 14522+} 14523+ 14524+static void hisp804_clockevent_stop(struct hisp804_clockevent_device *hiclkevt) 14525+{ 14526+ struct clock_event_device *clkevt = &hiclkevt->clkevt; 14527+ 14528+ pr_info("disable IRQ%d cpu #%d\n", clkevt->irq, smp_processor_id()); 14529+ 14530+ disable_irq(clkevt->irq); 14531+ 14532+ remove_irq(clkevt->irq, &hiclkevt->action); 14533+ 14534+ clkevt->set_state_shutdown(clkevt); 14535+} 14536+ 14537+static int hisp804_clockevent_cpu_notify(struct notifier_block *self, 14538+ unsigned long action, void *hcpu) 14539+{ 14540+ /* 14541+ * Grab cpu pointer in each case to avoid spurious 14542+ * preemptible warnings 14543+ */ 14544+ switch (action & ~CPU_TASKS_FROZEN) { 14545+ case CPU_ONLINE: 14546+ hisp804_clockevent_setup(this_cpu_ptr(hisp804_clkevt)); 14547+ break; 14548+ case CPU_DEAD: 14549+ hisp804_clockevent_stop(this_cpu_ptr(hisp804_clkevt)); 14550+ break; 14551+ default: 14552+ break; 14553+ } 14554+ 14555+ return NOTIFY_OK; 14556+} 14557+ 14558+static struct notifier_block hisp804_clockevent_cpu_nb = { 14559+ .notifier_call = hisp804_clockevent_cpu_notify, 14560+}; 14561+ 14562+static void __init clockevent_init(struct hisp804_clockevent_device *hiclkevt, 14563+ void __iomem *base, int irq, int cpu, 14564+ unsigned long rate, unsigned long reload) 14565+{ 14566+ struct irqaction *action = NULL; 14567+ struct clock_event_device *clkevt = NULL; 14568+ 14569+ hiclkevt->base = base; 14570+ hiclkevt->rate = rate; 14571+ hiclkevt->reload = reload; 14572+ snprintf(hiclkevt->name, sizeof(hiclkevt->name), "clockevent %d", cpu); 14573+ 14574+ clkevt = &hiclkevt->clkevt; 14575+ 14576+ clkevt->name = hiclkevt->name; 14577+ clkevt->cpumask = cpumask_of(cpu); 14578+ clkevt->irq = irq; 14579+ clkevt->set_next_event = hisp804_clockevent_set_next_event; 14580+ clkevt->set_state_shutdown = hisp804_clockevent_shutdown; 14581+ clkevt->set_state_periodic = sp804_clockevent_set_periodic; 14582+ clkevt->features = CLOCK_EVT_FEAT_PERIODIC | 14583+ CLOCK_EVT_FEAT_ONESHOT | 14584+ CLOCK_EVT_FEAT_DYNIRQ; 14585+ clkevt->rating = 400; 14586+ 14587+ action = &hiclkevt->action; 14588+ 14589+ action->name = hiclkevt->name; 14590+ action->dev_id = hiclkevt; 14591+ action->irq = irq; 14592+ action->flags = IRQF_TIMER | IRQF_NOBALANCING; 14593+ action->handler = hisp804_clockevent_timer_interrupt; 14594+} 14595+ 14596+static int __init hisp804_timer_init(struct device_node *node) 14597+{ 14598+ int ret, irq, ix, nr_cpus; 14599+ struct clk *clk1 = NULL, *clk2 = NULL; 14600+ void __iomem *base = NULL; 14601+ unsigned long rate1, rate2, reload1, reload2; 14602+ 14603+ hisp804_clkevt = alloc_percpu(struct hisp804_clockevent_device); 14604+ if (!hisp804_clkevt) { 14605+ pr_err("can't alloc memory.\n"); 14606+ goto out; 14607+ } 14608+ 14609+ clk1 = of_clk_get(node, 0); 14610+ if (IS_ERR(clk1)) 14611+ goto out_free; 14612+ 14613+ clk_prepare_enable(clk1); 14614+ 14615+ rate1 = clk_get_rate(clk1); 14616+ reload1 = DIV_ROUND_CLOSEST(rate1, HZ); 14617+ 14618+ /* Get the 2nd clock if the timer has 3 timer clocks */ 14619+ if (of_count_phandle_with_args(node, "clocks", "#clock-cells") == 3) { 14620+ clk2 = of_clk_get(node, 1); 14621+ if (IS_ERR(clk2)) { 14622+ pr_err("hisp804: %s clock not found: %d\n", node->name, 14623+ (int)PTR_ERR(clk2)); 14624+ goto out_free; 14625+ } 14626+ clk_prepare_enable(clk2); 14627+ rate2 = clk_get_rate(clk2); 14628+ reload2 = DIV_ROUND_CLOSEST(rate2, HZ); 14629+ } else { 14630+ rate2 = rate1; 14631+ reload2 = rate2; 14632+ } 14633+ 14634+ nr_cpus = of_irq_count(node); 14635+ if (nr_cpus > num_possible_cpus()) 14636+ nr_cpus = num_possible_cpus(); 14637+ 14638+ /* local timer for each CPU */ 14639+ for (ix = 0; ix < nr_cpus; ix++) { 14640+ irq = irq_of_parse_and_map(node, ix); 14641+ base = of_iomap(node, ix + 1); 14642+ if (!base) { 14643+ pr_err("can't iomap timer %d\n", ix); 14644+ while (--ix >= 0) 14645+ iounmap(per_cpu_ptr(hisp804_clkevt, ix)->base); 14646+ goto out_free; 14647+ } 14648+ 14649+ clockevent_init(per_cpu_ptr(hisp804_clkevt, ix), base, irq, 14650+ ix, rate2, reload2); 14651+ } 14652+ 14653+ base = of_iomap(node, 0); 14654+ if (!base) { 14655+ pr_err("can't iomap timer %d\n", 0); 14656+ goto out_unmap; 14657+ } 14658+ 14659+ hisp804_clocksource_init(base, rate1); 14660+ 14661+ ret = hi_register_cpu_notifier(&hisp804_clockevent_cpu_nb); 14662+ if (ret) 14663+ goto out_notifier; 14664+ 14665+ hisp804_clockevent_setup(this_cpu_ptr(hisp804_clkevt)); 14666+ 14667+ return 0; 14668+ 14669+out_notifier: 14670+ iounmap(base); 14671+out_unmap: 14672+ for (ix = 0; ix < nr_irqs; ix++) 14673+ iounmap(per_cpu_ptr(hisp804_clkevt, ix)->base); 14674+out_free: 14675+ free_percpu(hisp804_clkevt); 14676+out: 14677+ return -ENODEV; 14678+} 14679+CLOCKSOURCE_OF_DECLARE(hisp804, "hisilicon,hisp804", hisp804_timer_init); 14680\ No newline at end of file 14681diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig 14682index 08013345d..96107fbef 100644 14683--- a/drivers/dma/Kconfig 14684+++ b/drivers/dma/Kconfig 14685@@ -328,6 +328,20 @@ config K3_DMA 14686 Support the DMA engine for Hisilicon K3 platform 14687 devices. 14688 14689+config HIEDMACV310 14690+ tristate "Hisilicon EDMAC Controller support" 14691+ depends on ARCH_HISI_BVT 14692+ select DMA_ENGINE 14693+ select DMA_VIRTUAL_CHANNELS 14694+ help 14695+ The Direction Memory Access(EDMA) is a high-speed data transfer 14696+ operation. It supports data read/write between peripherals and 14697+ memories without using the CPU. 14698+ Hisilicon EDMA Controller(EDMAC) directly transfers data between 14699+ a memory and a peripheral, between peripherals, or between memories. 14700+ This avoids the CPU intervention and reduces the interrupt handling 14701+ overhead of the CPU. 14702+ 14703 config LPC18XX_DMAMUX 14704 bool "NXP LPC18xx/43xx DMA MUX for PL080" 14705 depends on ARCH_LPC18XX || COMPILE_TEST 14706@@ -710,7 +724,6 @@ config ZX_DMA 14707 help 14708 Support the DMA engine for ZTE ZX family platform devices. 14709 14710- 14711 # driver files 14712 source "drivers/dma/bestcomm/Kconfig" 14713 14714diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile 14715index 948a8da05..c5f89432d 100644 14716--- a/drivers/dma/Makefile 14717+++ b/drivers/dma/Makefile 14718@@ -82,7 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o 14719 obj-$(CONFIG_ZX_DMA) += zx_dma.o 14720 obj-$(CONFIG_ST_FDMA) += st_fdma.o 14721 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/ 14722- 14723+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o 14724 obj-y += mediatek/ 14725 obj-y += qcom/ 14726 obj-y += ti/ 14727diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c 14728new file mode 100644 14729index 000000000..a198c9224 14730--- /dev/null 14731+++ b/drivers/dma/hiedmacv310.c 14732@@ -0,0 +1,1443 @@ 14733+/* 14734+ * driver/dma/hiedmacv310.c 14735+ * 14736+ * The Hiedma Controller v310 Device Driver for HiSilicon 14737+ * 14738+ * Copyright (c) 2020 HiSilicon Technologies Co., Ltd. 14739+ * 14740+ * This program is free software; you can redistribute it and/or modify it 14741+ * under the terms of the GNU General Public License as published by the 14742+ * Free Software Foundation; either version 2 of the License, or (at your 14743+ * option) any later version. 14744+ * 14745+ * This program is distributed in the hope that it will be useful, 14746+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 14747+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14748+ * GNU General Public License for more details. 14749+ * 14750+ * You should have received a copy of the GNU General Public License 14751+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 14752+ * 14753+ */ 14754+#include <linux/debugfs.h> 14755+#include <linux/delay.h> 14756+#include <linux/clk.h> 14757+#include <linux/reset.h> 14758+#include <linux/platform_device.h> 14759+#include <linux/device.h> 14760+#include <linux/dmaengine.h> 14761+#include <linux/dmapool.h> 14762+#include <linux/dma-mapping.h> 14763+#include <linux/export.h> 14764+#include <linux/init.h> 14765+#include <linux/interrupt.h> 14766+#include <linux/module.h> 14767+#include <linux/of.h> 14768+#include <linux/of_dma.h> 14769+#include <linux/pm_runtime.h> 14770+#include <linux/seq_file.h> 14771+#include <linux/slab.h> 14772+#include <linux/io.h> 14773+#include <linux/regmap.h> 14774+#include <linux/mfd/syscon.h> 14775+ 14776+#include "hiedmacv310.h" 14777+#include "dmaengine.h" 14778+#include "virt-dma.h" 14779+ 14780+#define DRIVER_NAME "hiedmacv310" 14781+ 14782+#define MAX_TSFR_LLIS 512 14783+#define EDMACV300_LLI_WORDS 64 14784+#define EDMACV300_POOL_ALIGN 64 14785+#define BITS_PER_HALF_WORD 32 14786+#define ERR_STATUS_REG_NUM 3 14787+ 14788+typedef struct hiedmac_lli { 14789+ u64 next_lli; 14790+ u32 reserved[5]; 14791+ u32 count; 14792+ u64 src_addr; 14793+ u64 dest_addr; 14794+ u32 config; 14795+ u32 pad[3]; 14796+} hiedmac_lli; 14797+ 14798+struct hiedmac_sg { 14799+ dma_addr_t src_addr; 14800+ dma_addr_t dst_addr; 14801+ size_t len; 14802+ struct list_head node; 14803+}; 14804+ 14805+struct transfer_desc { 14806+ struct virt_dma_desc virt_desc; 14807+ dma_addr_t llis_busaddr; 14808+ u64 *llis_vaddr; 14809+ u32 ccfg; 14810+ size_t size; 14811+ bool done; 14812+ bool cyclic; 14813+}; 14814+ 14815+enum edmac_dma_chan_state { 14816+ HIEDMAC_CHAN_IDLE, 14817+ HIEDMAC_CHAN_RUNNING, 14818+ HIEDMAC_CHAN_PAUSED, 14819+ HIEDMAC_CHAN_WAITING, 14820+}; 14821+ 14822+struct hiedmacv310_dma_chan { 14823+ bool slave; 14824+ int signal; 14825+ int id; 14826+ struct virt_dma_chan virt_chan; 14827+ struct hiedmacv310_phy_chan *phychan; 14828+ struct dma_slave_config cfg; 14829+ struct transfer_desc *at; 14830+ struct hiedmacv310_driver_data *host; 14831+ enum edmac_dma_chan_state state; 14832+}; 14833+ 14834+struct hiedmacv310_phy_chan { 14835+ unsigned int id; 14836+ void __iomem *base; 14837+ spinlock_t lock; 14838+ struct hiedmacv310_dma_chan *serving; 14839+}; 14840+ 14841+struct hiedmacv310_driver_data { 14842+ struct platform_device *dev; 14843+ struct dma_device slave; 14844+ struct dma_device memcpy; 14845+ void __iomem *base; 14846+ struct regmap *misc_regmap; 14847+ void __iomem *crg_ctrl; 14848+ struct hiedmacv310_phy_chan *phy_chans; 14849+ struct dma_pool *pool; 14850+ unsigned int misc_ctrl_base; 14851+ int irq; 14852+ unsigned int id; 14853+ struct clk *clk; 14854+ struct clk *axi_clk; 14855+ struct reset_control *rstc; 14856+ unsigned int channels; 14857+ unsigned int slave_requests; 14858+ unsigned int max_transfer_size; 14859+}; 14860+ 14861+#ifdef DEBUG_HIEDMAC 14862+void dump_lli(const u64 *llis_vaddr, unsigned int num) 14863+{ 14864+ hiedmac_lli *plli = (hiedmac_lli *)llis_vaddr; 14865+ unsigned int i; 14866+ 14867+ hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "lli num = 0%d\n", num); 14868+ for (i = 0; i < num; i++) { 14869+ printk("lli%d:lli_L: 0x%llx\n", i, plli[i].next_lli & 0xffffffff); 14870+ printk("lli%d:lli_H: 0x%llx\n", i, (plli[i].next_lli >> BITS_PER_HALF_WORD) & 0xffffffff); 14871+ printk("lli%d:count: 0x%x\n", i, plli[i].count); 14872+ printk("lli%d:src_addr_L: 0x%llx\n", i, plli[i].src_addr & 0xffffffff); 14873+ printk("lli%d:src_addr_H: 0x%llx\n", i, (plli[i].src_addr >> BITS_PER_HALF_WORD) & 0xffffffff); 14874+ printk("lli%d:dst_addr_L: 0x%llx\n", i, plli[i].dest_addr & 0xffffffff); 14875+ printk("lli%d:dst_addr_H: 0x%llx\n", i, (plli[i].dest_addr >> BITS_PER_HALF_WORD) & 0xffffffff); 14876+ printk("lli%d:CONFIG: 0x%x\n", i, plli[i].config); 14877+ } 14878+} 14879+ 14880+#else 14881+void dump_lli(u64 *llis_vaddr, unsigned int num) 14882+{ 14883+} 14884+#endif 14885+ 14886+static inline struct hiedmacv310_dma_chan *to_edamc_chan(const struct dma_chan *chan) 14887+{ 14888+ return container_of(chan, struct hiedmacv310_dma_chan, virt_chan.chan); 14889+} 14890+ 14891+static inline struct transfer_desc *to_edmac_transfer_desc( 14892+ const struct dma_async_tx_descriptor *tx) 14893+{ 14894+ return container_of(tx, struct transfer_desc, virt_desc.tx); 14895+} 14896+ 14897+static struct dma_chan *hiedmac_find_chan_id( 14898+ const struct hiedmacv310_driver_data *hiedmac, 14899+ int request_num) 14900+{ 14901+ struct hiedmacv310_dma_chan *edmac_dma_chan = NULL; 14902+ 14903+ list_for_each_entry(edmac_dma_chan, &hiedmac->slave.channels, 14904+ virt_chan.chan.device_node) { 14905+ if (edmac_dma_chan->id == request_num) 14906+ return &edmac_dma_chan->virt_chan.chan; 14907+ } 14908+ return NULL; 14909+} 14910+ 14911+static struct dma_chan *hiedma_of_xlate(struct of_phandle_args *dma_spec, 14912+ struct of_dma *ofdma) 14913+{ 14914+ struct hiedmacv310_driver_data *hiedmac = ofdma->of_dma_data; 14915+ struct hiedmacv310_dma_chan *edmac_dma_chan = NULL; 14916+ struct dma_chan *dma_chan = NULL; 14917+ struct regmap *misc = NULL; 14918+ unsigned int signal, request_num; 14919+ unsigned int reg = 0; 14920+ unsigned int offset = 0; 14921+ 14922+ if (!hiedmac) 14923+ return NULL; 14924+ 14925+ misc = hiedmac->misc_regmap; 14926+ 14927+ if (dma_spec->args_count != 2) { /* check num of dts node args */ 14928+ hiedmacv310_error("args count not true!\n"); 14929+ return NULL; 14930+ } 14931+ 14932+ request_num = dma_spec->args[0]; 14933+ signal = dma_spec->args[1]; 14934+ 14935+ hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "host->id = %d,signal = %d, request_num = %d\n", 14936+ hiedmac->id, signal, request_num); 14937+ 14938+ if (misc != NULL) { 14939+#ifdef CONFIG_ACCESS_M7_DEV 14940+ offset = hiedmac->misc_ctrl_base; 14941+ reg = 0xc0; 14942+ regmap_write(misc, offset, reg); 14943+#else 14944+ offset = hiedmac->misc_ctrl_base + (request_num & (~0x3)); 14945+ regmap_read(misc, offset, ®); 14946+ /* set misc for signal line */ 14947+ reg &= ~(0x3f << ((request_num & 0x3) << 3)); 14948+ reg |= signal << ((request_num & 0x3) << 3); 14949+ regmap_write(misc, offset, reg); 14950+#endif 14951+ } 14952+ 14953+ hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "offset = 0x%x, reg = 0x%x\n", offset, reg); 14954+ 14955+ dma_chan = hiedmac_find_chan_id(hiedmac, request_num); 14956+ if (!dma_chan) { 14957+ hiedmacv310_error("DMA slave channel is not found!\n"); 14958+ return NULL; 14959+ } 14960+ 14961+ edmac_dma_chan = to_edamc_chan(dma_chan); 14962+ edmac_dma_chan->signal = request_num; 14963+ return dma_get_slave_channel(dma_chan); 14964+} 14965+ 14966+static int hiedmacv310_devm_get(struct hiedmacv310_driver_data *hiedmac) 14967+{ 14968+ struct platform_device *platdev = hiedmac->dev; 14969+ struct resource *res = NULL; 14970+ 14971+ hiedmac->clk = devm_clk_get(&(platdev->dev), "apb_pclk"); 14972+ if (IS_ERR(hiedmac->clk)) { 14973+ return PTR_ERR(hiedmac->clk); 14974+ } 14975+ 14976+ hiedmac->axi_clk = devm_clk_get(&(platdev->dev), "axi_aclk"); 14977+ if (IS_ERR(hiedmac->axi_clk)) { 14978+ return PTR_ERR(hiedmac->axi_clk); 14979+ } 14980+ 14981+ hiedmac->irq = platform_get_irq(platdev, 0); 14982+ if (unlikely(hiedmac->irq < 0)) 14983+ return -ENODEV; 14984+ 14985+ hiedmac->rstc = devm_reset_control_get(&(platdev->dev), "dma-reset"); 14986+ if (IS_ERR(hiedmac->rstc)) 14987+ return PTR_ERR(hiedmac->rstc); 14988+ 14989+ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); 14990+ if (!res) { 14991+ hiedmacv310_error("no reg resource\n"); 14992+ return -ENODEV; 14993+ } 14994+ 14995+ hiedmac->base = devm_ioremap_resource(&(platdev->dev), res); 14996+ if (IS_ERR(hiedmac->base)) 14997+ return PTR_ERR(hiedmac->base); 14998+ return 0; 14999+} 15000+ 15001+static int hiedmacv310_of_property_read(struct hiedmacv310_driver_data *hiedmac) 15002+{ 15003+ struct platform_device *platdev = hiedmac->dev; 15004+ struct device_node *np = platdev->dev.of_node; 15005+ int ret; 15006+ 15007+ if (!of_find_property(np, "misc_regmap", NULL) || 15008+ !of_find_property(np, "misc_ctrl_base", NULL)) 15009+ hiedmac->misc_regmap = 0; 15010+ else { 15011+ hiedmac->misc_regmap = syscon_regmap_lookup_by_phandle(np, "misc_regmap"); 15012+ if (IS_ERR(hiedmac->misc_regmap)) 15013+ return PTR_ERR(hiedmac->misc_regmap); 15014+ 15015+ ret = of_property_read_u32(np, "misc_ctrl_base", &(hiedmac->misc_ctrl_base)); 15016+ if (ret) { 15017+ hiedmacv310_error("get dma-misc_ctrl_base fail\n"); 15018+ return -ENODEV; 15019+ } 15020+ } 15021+ ret = of_property_read_u32(np, "devid", &(hiedmac->id)); 15022+ if (ret) { 15023+ hiedmacv310_error("get hiedmac id fail\n"); 15024+ return -ENODEV; 15025+ } 15026+ ret = of_property_read_u32(np, "dma-channels", &(hiedmac->channels)); 15027+ if (ret) { 15028+ hiedmacv310_error("get dma-channels fail\n"); 15029+ return -ENODEV; 15030+ } 15031+ ret = of_property_read_u32(np, "dma-requests", &(hiedmac->slave_requests)); 15032+ if (ret) { 15033+ hiedmacv310_error("get dma-requests fail\n"); 15034+ return -ENODEV; 15035+ } 15036+ hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "dma-channels = %d, dma-requests = %d\n", 15037+ hiedmac->channels, hiedmac->slave_requests); 15038+ return 0; 15039+} 15040+ 15041+static int get_of_probe(struct hiedmacv310_driver_data *hiedmac) 15042+{ 15043+ struct platform_device *platdev = hiedmac->dev; 15044+ int ret; 15045+ 15046+ ret = hiedmacv310_devm_get(hiedmac); 15047+ if (ret) { 15048+ return ret; 15049+ } 15050+ 15051+ ret = hiedmacv310_of_property_read(hiedmac); 15052+ if (ret) { 15053+ return ret; 15054+ } 15055+ 15056+ return of_dma_controller_register(platdev->dev.of_node, 15057+ hiedma_of_xlate, hiedmac); 15058+} 15059+ 15060+static void hiedmac_free_chan_resources(struct dma_chan *chan) 15061+{ 15062+ vchan_free_chan_resources(to_virt_chan(chan)); 15063+} 15064+ 15065+static size_t read_residue_from_phychan( 15066+ struct hiedmacv310_dma_chan *edmac_dma_chan, 15067+ struct transfer_desc *tsf_desc) 15068+{ 15069+ size_t bytes; 15070+ u64 next_lli; 15071+ struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan; 15072+ unsigned int i, index; 15073+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15074+ hiedmac_lli *plli = NULL; 15075+ 15076+ next_lli = (hiedmacv310_readl(hiedmac->base + hiedmac_cx_lli_l(phychan->id)) & 15077+ (~(HIEDMAC_LLI_ALIGN - 1))); 15078+ next_lli |= ((u64)(hiedmacv310_readl(hiedmac->base + hiedmac_cx_lli_h( 15079+ phychan->id)) & 0xffffffff) << BITS_PER_HALF_WORD); 15080+ bytes = hiedmacv310_readl(hiedmac->base + hiedmac_cx_curr_cnt0( 15081+ phychan->id)); 15082+ if (next_lli != 0) { 15083+ /* It means lli mode */ 15084+ bytes += tsf_desc->size; 15085+ index = (next_lli - tsf_desc->llis_busaddr) / sizeof(*plli); 15086+ plli = (hiedmac_lli *)(tsf_desc->llis_vaddr); 15087+ for (i = 0; i < index; i++) 15088+ bytes -= plli[i].count; 15089+ } 15090+ return bytes; 15091+} 15092+ 15093+static enum dma_status hiedmac_tx_status(struct dma_chan *chan, 15094+ dma_cookie_t cookie, 15095+ struct dma_tx_state *txstate) 15096+{ 15097+ enum dma_status ret; 15098+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15099+ struct virt_dma_desc *vd = NULL; 15100+ struct transfer_desc *tsf_desc = NULL; 15101+ unsigned long flags; 15102+ size_t bytes; 15103+ 15104+ ret = dma_cookie_status(chan, cookie, txstate); 15105+ if (ret == DMA_COMPLETE) { 15106+ return ret; 15107+ } 15108+ 15109+ if (edmac_dma_chan->state == HIEDMAC_CHAN_PAUSED && ret == DMA_IN_PROGRESS) { 15110+ ret = DMA_PAUSED; 15111+ return ret; 15112+ } 15113+ 15114+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); 15115+ vd = vchan_find_desc(&edmac_dma_chan->virt_chan, cookie); 15116+ if (vd) { 15117+ /* no been trasfer */ 15118+ tsf_desc = to_edmac_transfer_desc(&vd->tx); 15119+ bytes = tsf_desc->size; 15120+ } else { 15121+ /* trasfering */ 15122+ tsf_desc = edmac_dma_chan->at; 15123+ 15124+ if (!(edmac_dma_chan->phychan) || !tsf_desc) { 15125+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15126+ return ret; 15127+ } 15128+ bytes = read_residue_from_phychan(edmac_dma_chan, tsf_desc); 15129+ } 15130+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15131+ dma_set_residue(txstate, bytes); 15132+ return ret; 15133+} 15134+ 15135+static struct hiedmacv310_phy_chan *hiedmac_get_phy_channel( 15136+ const struct hiedmacv310_driver_data *hiedmac, 15137+ struct hiedmacv310_dma_chan *edmac_dma_chan) 15138+{ 15139+ struct hiedmacv310_phy_chan *ch = NULL; 15140+ unsigned long flags; 15141+ int i; 15142+ 15143+ for (i = 0; i < hiedmac->channels; i++) { 15144+ ch = &hiedmac->phy_chans[i]; 15145+ 15146+ spin_lock_irqsave(&ch->lock, flags); 15147+ 15148+ if (!ch->serving) { 15149+ ch->serving = edmac_dma_chan; 15150+ spin_unlock_irqrestore(&ch->lock, flags); 15151+ break; 15152+ } 15153+ spin_unlock_irqrestore(&ch->lock, flags); 15154+ } 15155+ 15156+ if (i == hiedmac->channels) { 15157+ return NULL; 15158+ } 15159+ 15160+ return ch; 15161+} 15162+ 15163+static void hiedmac_write_lli(const struct hiedmacv310_driver_data *hiedmac, 15164+ const struct hiedmacv310_phy_chan *phychan, 15165+ const struct transfer_desc *tsf_desc) 15166+{ 15167+ hiedmac_lli *plli = (hiedmac_lli *)tsf_desc->llis_vaddr; 15168+ 15169+ if (plli->next_lli != 0x0) 15170+ hiedmacv310_writel((plli->next_lli & 0xffffffff) | HIEDMAC_LLI_ENABLE, 15171+ hiedmac->base + hiedmac_cx_lli_l(phychan->id)); 15172+ else 15173+ hiedmacv310_writel((plli->next_lli & 0xffffffff), 15174+ hiedmac->base + hiedmac_cx_lli_l(phychan->id)); 15175+ 15176+ hiedmacv310_writel(((plli->next_lli >> 32) & 0xffffffff), 15177+ hiedmac->base + hiedmac_cx_lli_h(phychan->id)); 15178+ hiedmacv310_writel(plli->count, hiedmac->base + hiedmac_cx_cnt0(phychan->id)); 15179+ hiedmacv310_writel(plli->src_addr & 0xffffffff, 15180+ hiedmac->base + hiedmac_cx_src_addr_l(phychan->id)); 15181+ hiedmacv310_writel((plli->src_addr >> 32) & 0xffffffff, 15182+ hiedmac->base + hiedmac_cx_src_addr_h(phychan->id)); 15183+ hiedmacv310_writel(plli->dest_addr & 0xffffffff, 15184+ hiedmac->base + hiedmac_cx_dest_addr_l(phychan->id)); 15185+ hiedmacv310_writel((plli->dest_addr >> 32) & 0xffffffff, 15186+ hiedmac->base + hiedmac_cx_dest_addr_h(phychan->id)); 15187+ hiedmacv310_writel(plli->config, 15188+ hiedmac->base + hiedmac_cx_config(phychan->id)); 15189+} 15190+ 15191+static void hiedmac_start_next_txd(struct hiedmacv310_dma_chan *edmac_dma_chan) 15192+{ 15193+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15194+ struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan; 15195+ struct virt_dma_desc *vd = vchan_next_desc(&edmac_dma_chan->virt_chan); 15196+ struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx); 15197+ unsigned int val; 15198+ list_del(&tsf_desc->virt_desc.node); 15199+ edmac_dma_chan->at = tsf_desc; 15200+ hiedmac_write_lli(hiedmac, phychan, tsf_desc); 15201+ val = hiedmacv310_readl(hiedmac->base + hiedmac_cx_config(phychan->id)); 15202+ hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, " HIEDMAC_Cx_CONFIG = 0x%x\n", val); 15203+ hiedmacv310_writel(val | HIEDMAC_CXCONFIG_LLI_START, 15204+ hiedmac->base + hiedmac_cx_config(phychan->id)); 15205+} 15206+ 15207+static void hiedmac_start(struct hiedmacv310_dma_chan *edmac_dma_chan) 15208+{ 15209+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15210+ struct hiedmacv310_phy_chan *ch; 15211+ ch = hiedmac_get_phy_channel(hiedmac, edmac_dma_chan); 15212+ if (!ch) { 15213+ hiedmacv310_error("no phy channel available !\n"); 15214+ edmac_dma_chan->state = HIEDMAC_CHAN_WAITING; 15215+ return; 15216+ } 15217+ edmac_dma_chan->phychan = ch; 15218+ edmac_dma_chan->state = HIEDMAC_CHAN_RUNNING; 15219+ hiedmac_start_next_txd(edmac_dma_chan); 15220+} 15221+ 15222+static void hiedmac_issue_pending(struct dma_chan *chan) 15223+{ 15224+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15225+ unsigned long flags; 15226+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); 15227+ if (vchan_issue_pending(&edmac_dma_chan->virt_chan)) { 15228+ if (!edmac_dma_chan->phychan && edmac_dma_chan->state != HIEDMAC_CHAN_WAITING) 15229+ hiedmac_start(edmac_dma_chan); 15230+ } 15231+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15232+} 15233+ 15234+static void hiedmac_free_txd_list(struct hiedmacv310_dma_chan *edmac_dma_chan) 15235+{ 15236+ LIST_HEAD(head); 15237+ vchan_get_all_descriptors(&edmac_dma_chan->virt_chan, &head); 15238+ vchan_dma_desc_free_list(&edmac_dma_chan->virt_chan, &head); 15239+} 15240+ 15241+static int hiedmac_config(struct dma_chan *chan, 15242+ struct dma_slave_config *config) 15243+{ 15244+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15245+ if (!edmac_dma_chan->slave) { 15246+ hiedmacv310_error("slave is null!"); 15247+ return -EINVAL; 15248+ } 15249+ edmac_dma_chan->cfg = *config; 15250+ return 0; 15251+} 15252+ 15253+static void hiedmac_pause_phy_chan(const struct hiedmacv310_dma_chan *edmac_dma_chan) 15254+{ 15255+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15256+ struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan; 15257+ unsigned int val; 15258+ int timeout; 15259+ 15260+ val = hiedmacv310_readl(hiedmac->base + hiedmac_cx_config(phychan->id)); 15261+ val &= ~CCFG_EN; 15262+ hiedmacv310_writel(val, hiedmac->base + hiedmac_cx_config(phychan->id)); 15263+ /* Wait for channel inactive */ 15264+ for (timeout = 2000; timeout > 0; timeout--) { 15265+ if (!((0x1 << phychan->id) & hiedmacv310_readl(hiedmac->base + HIEDMAC_CH_STAT))) 15266+ break; 15267+ hiedmacv310_writel(val, hiedmac->base + hiedmac_cx_config(phychan->id)); 15268+ udelay(1); 15269+ } 15270+ if (timeout == 0) 15271+ hiedmacv310_error(":channel%u timeout waiting for pause, timeout:%d\n", 15272+ phychan->id, timeout); 15273+} 15274+ 15275+static int hiedmac_pause(struct dma_chan *chan) 15276+{ 15277+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15278+ unsigned long flags; 15279+ 15280+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); 15281+ if (!edmac_dma_chan->phychan) { 15282+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15283+ return 0; 15284+ } 15285+ hiedmac_pause_phy_chan(edmac_dma_chan); 15286+ edmac_dma_chan->state = HIEDMAC_CHAN_PAUSED; 15287+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15288+ return 0; 15289+} 15290+ 15291+static void hiedmac_resume_phy_chan(const struct hiedmacv310_dma_chan *edmac_dma_chan) 15292+{ 15293+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15294+ struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan; 15295+ unsigned int val; 15296+ val = hiedmacv310_readl(hiedmac->base + hiedmac_cx_config(phychan->id)); 15297+ val |= CCFG_EN; 15298+ hiedmacv310_writel(val, hiedmac->base + hiedmac_cx_config(phychan->id)); 15299+} 15300+ 15301+static int hiedmac_resume(struct dma_chan *chan) 15302+{ 15303+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15304+ unsigned long flags; 15305+ 15306+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); 15307+ 15308+ if (!edmac_dma_chan->phychan) { 15309+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15310+ return 0; 15311+ } 15312+ 15313+ hiedmac_resume_phy_chan(edmac_dma_chan); 15314+ edmac_dma_chan->state = HIEDMAC_CHAN_RUNNING; 15315+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15316+ 15317+ return 0; 15318+} 15319+ 15320+void hiedmac_phy_free(struct hiedmacv310_dma_chan *chan); 15321+static void hiedmac_desc_free(struct virt_dma_desc *vd); 15322+static int hiedmac_terminate_all(struct dma_chan *chan) 15323+{ 15324+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15325+ unsigned long flags; 15326+ 15327+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); 15328+ if (!edmac_dma_chan->phychan && !edmac_dma_chan->at) { 15329+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15330+ return 0; 15331+ } 15332+ 15333+ edmac_dma_chan->state = HIEDMAC_CHAN_IDLE; 15334+ 15335+ if (edmac_dma_chan->phychan) 15336+ hiedmac_phy_free(edmac_dma_chan); 15337+ if (edmac_dma_chan->at) { 15338+ hiedmac_desc_free(&edmac_dma_chan->at->virt_desc); 15339+ edmac_dma_chan->at = NULL; 15340+ } 15341+ hiedmac_free_txd_list(edmac_dma_chan); 15342+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); 15343+ 15344+ return 0; 15345+} 15346+ 15347+static u32 get_width(enum dma_slave_buswidth width) 15348+{ 15349+ switch (width) { 15350+ case DMA_SLAVE_BUSWIDTH_1_BYTE: 15351+ return HIEDMAC_WIDTH_8BIT; 15352+ case DMA_SLAVE_BUSWIDTH_2_BYTES: 15353+ return HIEDMAC_WIDTH_16BIT; 15354+ case DMA_SLAVE_BUSWIDTH_4_BYTES: 15355+ return HIEDMAC_WIDTH_32BIT; 15356+ case DMA_SLAVE_BUSWIDTH_8_BYTES: 15357+ return HIEDMAC_WIDTH_64BIT; 15358+ default: 15359+ hiedmacv310_error("check here, width warning!\n"); 15360+ return ~0; 15361+ } 15362+} 15363+ 15364+static unsigned int hiedmac_set_config_value(enum dma_transfer_direction direction, 15365+ unsigned int addr_width, 15366+ unsigned int burst, 15367+ unsigned int signal) 15368+{ 15369+ unsigned int config, width; 15370+ 15371+ if (direction == DMA_MEM_TO_DEV) { 15372+ config = HIEDMAC_CONFIG_SRC_INC; 15373+ } else { 15374+ config = HIEDMAC_CONFIG_DST_INC; 15375+ } 15376+ hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "addr_width = 0x%x\n", addr_width); 15377+ width = get_width(addr_width); 15378+ hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "width = 0x%x\n", width); 15379+ config |= width << HIEDMAC_CONFIG_SRC_WIDTH_SHIFT; 15380+ config |= width << HIEDMAC_CONFIG_DST_WIDTH_SHIFT; 15381+ hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "tsf_desc->ccfg = 0x%x\n", config); 15382+ hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "burst = 0x%x\n", burst); 15383+ config |= burst << HIEDMAC_CONFIG_SRC_BURST_SHIFT; 15384+ config |= burst << HIEDMAC_CONFIG_DST_BURST_SHIFT; 15385+ if (signal >= 0) { 15386+ hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "edmac_dma_chan->signal = %d\n", signal); 15387+ config |= (unsigned int)signal << HIEDMAC_CXCONFIG_SIGNAL_SHIFT; 15388+ } 15389+ config |= HIEDMAC_CXCONFIG_DEV_MEM_TYPE << HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT; 15390+ return config; 15391+} 15392+ 15393+struct transfer_desc *hiedmac_init_tsf_desc(struct dma_chan *chan, 15394+ enum dma_transfer_direction direction, 15395+ dma_addr_t *slave_addr) 15396+{ 15397+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15398+ struct transfer_desc *tsf_desc; 15399+ unsigned int burst = 0; 15400+ unsigned int addr_width = 0; 15401+ unsigned int maxburst = 0; 15402+ tsf_desc = kzalloc(sizeof(*tsf_desc), GFP_NOWAIT); 15403+ if (!tsf_desc) 15404+ return NULL; 15405+ if (direction == DMA_MEM_TO_DEV) { 15406+ *slave_addr = edmac_dma_chan->cfg.dst_addr; 15407+ addr_width = edmac_dma_chan->cfg.dst_addr_width; 15408+ maxburst = edmac_dma_chan->cfg.dst_maxburst; 15409+ } else if (direction == DMA_DEV_TO_MEM) { 15410+ *slave_addr = edmac_dma_chan->cfg.src_addr; 15411+ addr_width = edmac_dma_chan->cfg.src_addr_width; 15412+ maxburst = edmac_dma_chan->cfg.src_maxburst; 15413+ } else { 15414+ kfree(tsf_desc); 15415+ hiedmacv310_error("direction unsupported!\n"); 15416+ return NULL; 15417+ } 15418+ 15419+ if (maxburst > (HIEDMAC_MAX_BURST_WIDTH)) 15420+ burst |= (HIEDMAC_MAX_BURST_WIDTH - 1); 15421+ else if (maxburst == 0) 15422+ burst |= HIEDMAC_MIN_BURST_WIDTH; 15423+ else 15424+ burst |= (maxburst - 1); 15425+ 15426+ tsf_desc->ccfg = hiedmac_set_config_value(direction, addr_width, 15427+ burst, edmac_dma_chan->signal); 15428+ hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "tsf_desc->ccfg = 0x%x\n", tsf_desc->ccfg); 15429+ return tsf_desc; 15430+} 15431+ 15432+static int hiedmac_fill_desc(const struct hiedmac_sg *dsg, 15433+ struct transfer_desc *tsf_desc, 15434+ unsigned int length, unsigned int num) 15435+{ 15436+ hiedmac_lli *plli = NULL; 15437+ 15438+ if (num >= MAX_TSFR_LLIS) { 15439+ hiedmacv310_error("lli out of range. \n"); 15440+ return -ENOMEM; 15441+ } 15442+ 15443+ plli = (hiedmac_lli*)(tsf_desc->llis_vaddr); 15444+ memset(&plli[num], 0x0, sizeof(*plli)); 15445+ 15446+ plli[num].src_addr = dsg->src_addr; 15447+ plli[num].dest_addr = dsg->dst_addr; 15448+ plli[num].config = tsf_desc->ccfg; 15449+ plli[num].count = length; 15450+ tsf_desc->size += length; 15451+ 15452+ if (num > 0) { 15453+ plli[num - 1].next_lli = (tsf_desc->llis_busaddr + (num) * sizeof( 15454+ *plli)) & (~(HIEDMAC_LLI_ALIGN - 1)); 15455+ plli[num - 1].next_lli |= HIEDMAC_LLI_ENABLE; 15456+ } 15457+ return 0; 15458+} 15459+ 15460+static void free_dsg(struct list_head *dsg_head) 15461+{ 15462+ struct hiedmac_sg *dsg = NULL; 15463+ struct hiedmac_sg *_dsg = NULL; 15464+ 15465+ list_for_each_entry_safe(dsg, _dsg, dsg_head, node) { 15466+ list_del(&dsg->node); 15467+ kfree(dsg); 15468+ } 15469+} 15470+ 15471+static int hiedmac_add_sg(struct list_head *sg_head, 15472+ dma_addr_t dst, dma_addr_t src, 15473+ size_t len) 15474+{ 15475+ struct hiedmac_sg *dsg = NULL; 15476+ 15477+ if (len == 0) { 15478+ hiedmacv310_error("Transfer length is 0. \n"); 15479+ return -ENOMEM; 15480+ } 15481+ 15482+ dsg = (struct hiedmac_sg *)kzalloc(sizeof(*dsg), GFP_NOWAIT); 15483+ if (!dsg) { 15484+ free_dsg(sg_head); 15485+ hiedmacv310_error("alloc memory for dsg fail.\n"); 15486+ return -ENOMEM; 15487+ } 15488+ 15489+ list_add_tail(&dsg->node, sg_head); 15490+ dsg->src_addr = src; 15491+ dsg->dst_addr = dst; 15492+ dsg->len = len; 15493+ return 0; 15494+} 15495+ 15496+static int hiedmac_add_sg_slave(struct list_head *sg_head, 15497+ dma_addr_t slave_addr, dma_addr_t addr, 15498+ size_t length, 15499+ enum dma_transfer_direction direction) 15500+{ 15501+ dma_addr_t src = 0; 15502+ dma_addr_t dst = 0; 15503+ if (direction == DMA_MEM_TO_DEV) { 15504+ src = addr; 15505+ dst = slave_addr; 15506+ } else if (direction == DMA_DEV_TO_MEM) { 15507+ src = slave_addr; 15508+ dst = addr; 15509+ } else { 15510+ hiedmacv310_error("invali dma_transfer_direction.\n"); 15511+ return -ENOMEM; 15512+ } 15513+ return hiedmac_add_sg(sg_head, dst, src, length); 15514+} 15515+ 15516+static int hiedmac_fill_sg_for_slave(struct list_head *sg_head, 15517+ dma_addr_t slave_addr, 15518+ struct scatterlist *sgl, 15519+ unsigned int sg_len, 15520+ enum dma_transfer_direction direction) 15521+{ 15522+ struct scatterlist *sg = NULL; 15523+ int tmp, ret; 15524+ size_t length; 15525+ dma_addr_t addr; 15526+ if (sgl == NULL) { 15527+ hiedmacv310_error("sgl is null!\n"); 15528+ return -ENOMEM; 15529+ } 15530+ 15531+ for_each_sg(sgl, sg, sg_len, tmp) { 15532+ addr = sg_dma_address(sg); 15533+ length = sg_dma_len(sg); 15534+ ret = hiedmac_add_sg_slave(sg_head, slave_addr, addr, length, direction); 15535+ if (ret) 15536+ break; 15537+ } 15538+ return ret; 15539+} 15540+ 15541+static inline int hiedmac_fill_sg_for_m2m_copy(struct list_head *sg_head, 15542+ dma_addr_t dst, dma_addr_t src, 15543+ size_t len) 15544+{ 15545+ return hiedmac_add_sg(sg_head, dst, src, len); 15546+} 15547+ 15548+static int hiedmac_fill_sg_for_cyclic(struct list_head *sg_head, 15549+ dma_addr_t slave_addr, 15550+ dma_addr_t buf_addr, size_t buf_len, 15551+ size_t period_len, 15552+ enum dma_transfer_direction direction) 15553+{ 15554+ size_t count_in_sg = 0; 15555+ size_t trans_bytes; 15556+ int ret; 15557+ while (count_in_sg < buf_len) { 15558+ trans_bytes = min(period_len, buf_len - count_in_sg); 15559+ count_in_sg += trans_bytes; 15560+ ret = hiedmac_add_sg_slave(sg_head, slave_addr, buf_addr + count_in_sg, count_in_sg, direction); 15561+ if (ret) 15562+ return ret; 15563+ } 15564+ return 0; 15565+} 15566+ 15567+static inline unsigned short get_max_width(dma_addr_t ccfg) 15568+{ 15569+ unsigned short src_width = (ccfg & HIEDMAC_CONTROL_SRC_WIDTH_MASK) >> HIEDMAC_CONFIG_SRC_WIDTH_SHIFT; 15570+ unsigned short dst_width = (ccfg & HIEDMAC_CONTROL_DST_WIDTH_MASK) >> HIEDMAC_CONFIG_DST_WIDTH_SHIFT; 15571+ return 1 << max(src_width, dst_width); /* to byte */ 15572+} 15573+ 15574+static int hiedmac_fill_asg_lli_for_desc(struct hiedmac_sg *dsg, 15575+ struct transfer_desc *tsf_desc, 15576+ unsigned int *lli_count) 15577+{ 15578+ int ret; 15579+ unsigned short width = get_max_width(tsf_desc->ccfg); 15580+ 15581+ while (dsg->len != 0) { 15582+ size_t lli_len = MAX_TRANSFER_BYTES; 15583+ lli_len = (lli_len / width) * width; /* bus width align */ 15584+ lli_len = min(lli_len, dsg->len); 15585+ ret = hiedmac_fill_desc(dsg, tsf_desc, lli_len, *lli_count); 15586+ if (ret) 15587+ return ret; 15588+ 15589+ if (tsf_desc->ccfg & HIEDMAC_CONFIG_SRC_INC) 15590+ dsg->src_addr += lli_len; 15591+ if (tsf_desc->ccfg & HIEDMAC_CONFIG_DST_INC) 15592+ dsg->dst_addr += lli_len; 15593+ dsg->len -= lli_len; 15594+ (*lli_count)++; 15595+ } 15596+ return 0; 15597+} 15598+ 15599+static int hiedmac_fill_lli_for_desc(struct list_head *sg_head, 15600+ struct transfer_desc *tsf_desc) 15601+{ 15602+ struct hiedmac_sg *dsg = NULL; 15603+ struct hiedmac_lli *last_plli = NULL; 15604+ unsigned int lli_count = 0; 15605+ int ret; 15606+ 15607+ list_for_each_entry(dsg, sg_head, node) { 15608+ ret = hiedmac_fill_asg_lli_for_desc(dsg, tsf_desc, &lli_count); 15609+ if (ret) 15610+ return ret; 15611+ } 15612+ 15613+ if (tsf_desc->cyclic) { 15614+ last_plli = (hiedmac_lli *)((uintptr_t)tsf_desc->llis_vaddr + 15615+ (lli_count - 1) * sizeof(*last_plli)); 15616+ last_plli->next_lli = tsf_desc->llis_busaddr | HIEDMAC_LLI_ENABLE; 15617+ } else { 15618+ last_plli = (hiedmac_lli *)((uintptr_t)tsf_desc->llis_vaddr + 15619+ (lli_count - 1) * sizeof(*last_plli)); 15620+ last_plli->next_lli = 0; 15621+ } 15622+ dump_lli(tsf_desc->llis_vaddr, lli_count); 15623+ return 0; 15624+} 15625+ 15626+static struct dma_async_tx_descriptor *hiedmac_prep_slave_sg( 15627+ struct dma_chan *chan, struct scatterlist *sgl, 15628+ unsigned int sg_len, enum dma_transfer_direction direction, 15629+ unsigned long flags, void *context) 15630+{ 15631+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15632+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15633+ struct transfer_desc *tsf_desc = NULL; 15634+ dma_addr_t slave_addr = 0; 15635+ int ret; 15636+ LIST_HEAD(sg_head); 15637+ if (sgl == NULL) { 15638+ hiedmacv310_error("sgl is null!\n"); 15639+ return NULL; 15640+ } 15641+ 15642+ tsf_desc = hiedmac_init_tsf_desc(chan, direction, &slave_addr); 15643+ if (!tsf_desc) 15644+ return NULL; 15645+ 15646+ tsf_desc->llis_vaddr = dma_pool_alloc(hiedmac->pool, GFP_NOWAIT, 15647+ &tsf_desc->llis_busaddr); 15648+ if (!tsf_desc->llis_vaddr) { 15649+ hiedmacv310_error("malloc memory from pool fail !\n"); 15650+ goto err_alloc_lli; 15651+ } 15652+ 15653+ ret = hiedmac_fill_sg_for_slave(&sg_head, slave_addr, sgl, sg_len, direction); 15654+ if (ret) 15655+ goto err_fill_sg; 15656+ ret = hiedmac_fill_lli_for_desc(&sg_head, tsf_desc); 15657+ free_dsg(&sg_head); 15658+ if (ret) 15659+ goto err_fill_sg; 15660+ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); 15661+ 15662+err_fill_sg: 15663+ dma_pool_free(hiedmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); 15664+err_alloc_lli: 15665+ kfree(tsf_desc); 15666+ return NULL; 15667+} 15668+ 15669+static struct dma_async_tx_descriptor *hiedmac_prep_dma_m2m_copy( 15670+ struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, 15671+ size_t len, unsigned long flags) 15672+{ 15673+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15674+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15675+ struct transfer_desc *tsf_desc = NULL; 15676+ LIST_HEAD(sg_head); 15677+ u32 config = 0; 15678+ int ret; 15679+ 15680+ if (!len) 15681+ return NULL; 15682+ 15683+ tsf_desc = kzalloc(sizeof(*tsf_desc), GFP_NOWAIT); 15684+ if (tsf_desc == NULL) { 15685+ hiedmacv310_error("get tsf desc fail!\n"); 15686+ return NULL; 15687+ } 15688+ 15689+ tsf_desc->llis_vaddr = dma_pool_alloc(hiedmac->pool, GFP_NOWAIT, 15690+ &tsf_desc->llis_busaddr); 15691+ if (!tsf_desc->llis_vaddr) { 15692+ hiedmacv310_error("malloc memory from pool fail !\n"); 15693+ goto err_alloc_lli; 15694+ } 15695+ 15696+ config |= HIEDMAC_CONFIG_SRC_INC | HIEDMAC_CONFIG_DST_INC; 15697+ config |= HIEDMAC_CXCONFIG_MEM_TYPE << HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT; 15698+ /* max burst width is 16 ,but reg value set 0xf */ 15699+ config |= (HIEDMAC_MAX_BURST_WIDTH - 1) << HIEDMAC_CONFIG_SRC_BURST_SHIFT; 15700+ config |= (HIEDMAC_MAX_BURST_WIDTH - 1) << HIEDMAC_CONFIG_DST_BURST_SHIFT; 15701+ config |= HIEDMAC_MEM_BIT_WIDTH << HIEDMAC_CONFIG_SRC_WIDTH_SHIFT; 15702+ config |= HIEDMAC_MEM_BIT_WIDTH << HIEDMAC_CONFIG_DST_WIDTH_SHIFT; 15703+ tsf_desc->ccfg = config; 15704+ ret = hiedmac_fill_sg_for_m2m_copy(&sg_head, dst, src, len); 15705+ if (ret) 15706+ goto err_fill_sg; 15707+ ret = hiedmac_fill_lli_for_desc(&sg_head, tsf_desc); 15708+ free_dsg(&sg_head); 15709+ if (ret) 15710+ goto err_fill_sg; 15711+ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); 15712+ 15713+err_fill_sg: 15714+ dma_pool_free(hiedmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); 15715+err_alloc_lli: 15716+ kfree(tsf_desc); 15717+ return NULL; 15718+} 15719+ 15720+ 15721+static struct dma_async_tx_descriptor *hiedmac_prep_dma_cyclic( 15722+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, 15723+ size_t period_len, enum dma_transfer_direction direction, 15724+ unsigned long flags) 15725+{ 15726+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); 15727+ struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host; 15728+ struct transfer_desc *tsf_desc = NULL; 15729+ dma_addr_t slave_addr = 0; 15730+ LIST_HEAD(sg_head); 15731+ int ret; 15732+ 15733+ tsf_desc = hiedmac_init_tsf_desc(chan, direction, &slave_addr); 15734+ if (!tsf_desc) 15735+ return NULL; 15736+ 15737+ tsf_desc->llis_vaddr = dma_pool_alloc(hiedmac->pool, GFP_NOWAIT, 15738+ &tsf_desc->llis_busaddr); 15739+ if (!tsf_desc->llis_vaddr) { 15740+ hiedmacv310_error("malloc memory from pool fail !\n"); 15741+ goto err_alloc_lli; 15742+ } 15743+ 15744+ tsf_desc->cyclic = true; 15745+ ret = hiedmac_fill_sg_for_cyclic(&sg_head, slave_addr, buf_addr, buf_len, period_len, direction); 15746+ if (ret) 15747+ goto err_fill_sg; 15748+ ret = hiedmac_fill_lli_for_desc(&sg_head, tsf_desc); 15749+ free_dsg(&sg_head); 15750+ if (ret) 15751+ goto err_fill_sg; 15752+ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); 15753+ 15754+err_fill_sg: 15755+ dma_pool_free(hiedmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); 15756+err_alloc_lli: 15757+ kfree(tsf_desc); 15758+ return NULL; 15759+} 15760+ 15761+static void hiedmac_phy_reassign(struct hiedmacv310_phy_chan *phy_chan, 15762+ struct hiedmacv310_dma_chan *chan) 15763+{ 15764+ phy_chan->serving = chan; 15765+ chan->phychan = phy_chan; 15766+ chan->state = HIEDMAC_CHAN_RUNNING; 15767+ 15768+ hiedmac_start_next_txd(chan); 15769+} 15770+ 15771+static void hiedmac_terminate_phy_chan(struct hiedmacv310_driver_data *hiedmac, 15772+ const struct hiedmacv310_dma_chan *edmac_dma_chan) 15773+{ 15774+ unsigned int val; 15775+ struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan; 15776+ hiedmac_pause_phy_chan(edmac_dma_chan); 15777+ val = 0x1 << phychan->id; 15778+ hiedmacv310_writel(val, hiedmac->base + HIEDMAC_INT_TC1_RAW); 15779+ hiedmacv310_writel(val, hiedmac->base + HIEDMAC_INT_ERR1_RAW); 15780+ hiedmacv310_writel(val, hiedmac->base + HIEDMAC_INT_ERR2_RAW); 15781+} 15782+ 15783+void hiedmac_phy_free(struct hiedmacv310_dma_chan *chan) 15784+{ 15785+ struct hiedmacv310_driver_data *hiedmac = chan->host; 15786+ struct hiedmacv310_dma_chan *p = NULL; 15787+ struct hiedmacv310_dma_chan *next = NULL; 15788+ 15789+ list_for_each_entry(p, &hiedmac->memcpy.channels, virt_chan.chan.device_node) { 15790+ if (p->state == HIEDMAC_CHAN_WAITING) { 15791+ next = p; 15792+ break; 15793+ } 15794+ } 15795+ 15796+ if (!next) { 15797+ list_for_each_entry(p, &hiedmac->slave.channels, virt_chan.chan.device_node) { 15798+ if (p->state == HIEDMAC_CHAN_WAITING) { 15799+ next = p; 15800+ break; 15801+ } 15802+ } 15803+ } 15804+ hiedmac_terminate_phy_chan(hiedmac, chan); 15805+ 15806+ if (next) { 15807+ spin_lock(&next->virt_chan.lock); 15808+ hiedmac_phy_reassign(chan->phychan, next); 15809+ spin_unlock(&next->virt_chan.lock); 15810+ } else { 15811+ chan->phychan->serving = NULL; 15812+ } 15813+ 15814+ chan->phychan = NULL; 15815+ chan->state = HIEDMAC_CHAN_IDLE; 15816+} 15817+ 15818+bool handle_irq(struct hiedmacv310_driver_data *hiedmac, int chan_id) 15819+{ 15820+ struct hiedmacv310_dma_chan *chan = NULL; 15821+ struct hiedmacv310_phy_chan *phy_chan = NULL; 15822+ struct transfer_desc *tsf_desc = NULL; 15823+ unsigned int channel_tc_status, channel_err_status[ERR_STATUS_REG_NUM]; 15824+ 15825+ phy_chan = &hiedmac->phy_chans[chan_id]; 15826+ chan = phy_chan->serving; 15827+ if (!chan) { 15828+ hiedmacv310_error("error interrupt on chan: %d!\n", chan_id); 15829+ return 0; 15830+ } 15831+ tsf_desc = chan->at; 15832+ 15833+ channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC1_RAW); 15834+ channel_tc_status = (channel_tc_status >> chan_id) & 0x01; 15835+ if (channel_tc_status) 15836+ hiedmacv310_writel(channel_tc_status << chan_id, hiedmac->base + HIEDMAC_INT_TC1_RAW); 15837+ 15838+ channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC2); 15839+ channel_tc_status = (channel_tc_status >> chan_id) & 0x01; 15840+ if (channel_tc_status) 15841+ hiedmacv310_writel(channel_tc_status << chan_id, hiedmac->base + HIEDMAC_INT_TC2_RAW); 15842+ channel_err_status[0] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR1); 15843+ channel_err_status[1] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR2); 15844+ channel_err_status[2] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR3); 15845+ if ((channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) & (1 << chan_id)) { 15846+ hiedmacv310_error("Error in hiedmac %d!,ERR1 = 0x%x,ERR2 = 0x%x,ERR3 = 0x%x\n", 15847+ chan_id, channel_err_status[0], 15848+ channel_err_status[1], channel_err_status[2]); 15849+ hiedmacv310_writel(1 << chan_id, hiedmac->base + HIEDMAC_INT_ERR1_RAW); 15850+ hiedmacv310_writel(1 << chan_id, hiedmac->base + HIEDMAC_INT_ERR2_RAW); 15851+ hiedmacv310_writel(1 << chan_id, hiedmac->base + HIEDMAC_INT_ERR3_RAW); 15852+ } 15853+ 15854+ spin_lock(&chan->virt_chan.lock); 15855+ 15856+ if (tsf_desc->cyclic) { 15857+ vchan_cyclic_callback(&tsf_desc->virt_desc); 15858+ spin_unlock(&chan->virt_chan.lock); 15859+ return 1; 15860+ } 15861+ chan->at = NULL; 15862+ tsf_desc->done = true; 15863+ vchan_cookie_complete(&tsf_desc->virt_desc); 15864+ 15865+ if (vchan_next_desc(&chan->virt_chan)) 15866+ hiedmac_start_next_txd(chan); 15867+ else 15868+ hiedmac_phy_free(chan); 15869+ spin_unlock(&chan->virt_chan.lock); 15870+ return 1; 15871+} 15872+ 15873+static irqreturn_t hiemdacv310_irq(int irq, void *dev) 15874+{ 15875+ struct hiedmacv310_driver_data *hiedmac = (struct hiedmacv310_driver_data *)dev; 15876+ u32 mask = 0; 15877+ unsigned int channel_status, temp, i; 15878+ 15879+ channel_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_STAT); 15880+ if (!channel_status) { 15881+ hiedmacv310_error("channel_status = 0x%x\n", channel_status); 15882+ return IRQ_NONE; 15883+ } 15884+ 15885+ for (i = 0; i < hiedmac->channels; i++) { 15886+ temp = (channel_status >> i) & 0x1; 15887+ if (temp) 15888+ mask |= handle_irq(hiedmac, i) << i; 15889+ } 15890+ return mask ? IRQ_HANDLED : IRQ_NONE; 15891+} 15892+ 15893+static inline void hiedmac_dma_slave_init(struct hiedmacv310_dma_chan *chan) 15894+{ 15895+ chan->slave = true; 15896+} 15897+ 15898+static void hiedmac_desc_free(struct virt_dma_desc *vd) 15899+{ 15900+ struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx); 15901+ struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(vd->tx.chan); 15902+ dma_descriptor_unmap(&vd->tx); 15903+ dma_pool_free(edmac_dma_chan->host->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); 15904+ kfree(tsf_desc); 15905+} 15906+ 15907+static int hiedmac_init_virt_channels(struct hiedmacv310_driver_data *hiedmac, 15908+ struct dma_device *dmadev, 15909+ unsigned int channels, bool slave) 15910+{ 15911+ struct hiedmacv310_dma_chan *chan = NULL; 15912+ int i; 15913+ INIT_LIST_HEAD(&dmadev->channels); 15914+ 15915+ for (i = 0; i < channels; i++) { 15916+ chan = kzalloc(sizeof(struct hiedmacv310_dma_chan), GFP_KERNEL); 15917+ if (!chan) { 15918+ hiedmacv310_error("fail to allocate memory for virt channels!"); 15919+ return -1; 15920+ } 15921+ 15922+ chan->host = hiedmac; 15923+ chan->state = HIEDMAC_CHAN_IDLE; 15924+ chan->signal = -1; 15925+ 15926+ if (slave) { 15927+ chan->id = i; 15928+ hiedmac_dma_slave_init(chan); 15929+ } 15930+ chan->virt_chan.desc_free = hiedmac_desc_free; 15931+ vchan_init(&chan->virt_chan, dmadev); 15932+ } 15933+ return 0; 15934+} 15935+ 15936+void hiedmac_free_virt_channels(struct dma_device *dmadev) 15937+{ 15938+ struct hiedmacv310_dma_chan *chan = NULL; 15939+ struct hiedmacv310_dma_chan *next = NULL; 15940+ 15941+ list_for_each_entry_safe(chan, next, &dmadev->channels, virt_chan.chan.device_node) { 15942+ list_del(&chan->virt_chan.chan.device_node); 15943+ kfree(chan); 15944+ } 15945+} 15946+ 15947+static void hiedmacv310_prep_dma_device(struct platform_device *pdev, 15948+ struct hiedmacv310_driver_data *hiedmac) 15949+{ 15950+ dma_cap_set(DMA_MEMCPY, hiedmac->memcpy.cap_mask); 15951+ hiedmac->memcpy.dev = &pdev->dev; 15952+ hiedmac->memcpy.device_free_chan_resources = hiedmac_free_chan_resources; 15953+ hiedmac->memcpy.device_prep_dma_memcpy = hiedmac_prep_dma_m2m_copy; 15954+ hiedmac->memcpy.device_tx_status = hiedmac_tx_status; 15955+ hiedmac->memcpy.device_issue_pending = hiedmac_issue_pending; 15956+ hiedmac->memcpy.device_config = hiedmac_config; 15957+ hiedmac->memcpy.device_pause = hiedmac_pause; 15958+ hiedmac->memcpy.device_resume = hiedmac_resume; 15959+ hiedmac->memcpy.device_terminate_all = hiedmac_terminate_all; 15960+ hiedmac->memcpy.directions = BIT(DMA_MEM_TO_MEM); 15961+ hiedmac->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; 15962+ 15963+ dma_cap_set(DMA_SLAVE, hiedmac->slave.cap_mask); 15964+ dma_cap_set(DMA_CYCLIC, hiedmac->slave.cap_mask); 15965+ hiedmac->slave.dev = &pdev->dev; 15966+ hiedmac->slave.device_free_chan_resources = hiedmac_free_chan_resources; 15967+ hiedmac->slave.device_tx_status = hiedmac_tx_status; 15968+ hiedmac->slave.device_issue_pending = hiedmac_issue_pending; 15969+ hiedmac->slave.device_prep_slave_sg = hiedmac_prep_slave_sg; 15970+ hiedmac->slave.device_prep_dma_cyclic = hiedmac_prep_dma_cyclic; 15971+ hiedmac->slave.device_config = hiedmac_config; 15972+ hiedmac->slave.device_resume = hiedmac_resume; 15973+ hiedmac->slave.device_pause = hiedmac_pause; 15974+ hiedmac->slave.device_terminate_all = hiedmac_terminate_all; 15975+ hiedmac->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); 15976+ hiedmac->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; 15977+} 15978+ 15979+static int hiedmacv310_init_chan(struct hiedmacv310_driver_data *hiedmac) 15980+{ 15981+ int i, ret; 15982+ hiedmac->phy_chans = kzalloc((hiedmac->channels * sizeof( 15983+ struct hiedmacv310_phy_chan)), 15984+ GFP_KERNEL); 15985+ if (!hiedmac->phy_chans) { 15986+ hiedmacv310_error("malloc for phy chans fail!"); 15987+ return -ENOMEM; 15988+ } 15989+ 15990+ for (i = 0; i < hiedmac->channels; i++) { 15991+ struct hiedmacv310_phy_chan *phy_ch = &hiedmac->phy_chans[i]; 15992+ phy_ch->id = i; 15993+ phy_ch->base = hiedmac->base + hiedmac_cx_base(i); 15994+ spin_lock_init(&phy_ch->lock); 15995+ phy_ch->serving = NULL; 15996+ } 15997+ 15998+ ret = hiedmac_init_virt_channels(hiedmac, &hiedmac->memcpy, hiedmac->channels, 15999+ false); 16000+ if (ret) { 16001+ hiedmacv310_error("fail to init memory virt channels!"); 16002+ goto free_phychans; 16003+ } 16004+ 16005+ ret = hiedmac_init_virt_channels(hiedmac, &hiedmac->slave, hiedmac->slave_requests, 16006+ true); 16007+ if (ret) { 16008+ hiedmacv310_error("fail to init slave virt channels!"); 16009+ goto free_memory_virt_channels; 16010+ } 16011+ return 0; 16012+ 16013+free_memory_virt_channels: 16014+ hiedmac_free_virt_channels(&hiedmac->memcpy); 16015+free_phychans: 16016+ kfree(hiedmac->phy_chans); 16017+ return -ENOMEM; 16018+} 16019+ 16020+static void hiedmacv310_free_chan(struct hiedmacv310_driver_data *hiedmac) 16021+{ 16022+ hiedmac_free_virt_channels(&hiedmac->slave); 16023+ hiedmac_free_virt_channels(&hiedmac->memcpy); 16024+ kfree(hiedmac->phy_chans); 16025+} 16026+ 16027+static void hiedmacv310_prep_phy_device(const struct hiedmacv310_driver_data *hiedmac) 16028+{ 16029+ clk_prepare_enable(hiedmac->clk); 16030+ clk_prepare_enable(hiedmac->axi_clk); 16031+ reset_control_deassert(hiedmac->rstc); 16032+ 16033+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC1_RAW); 16034+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC2_RAW); 16035+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR1_RAW); 16036+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR2_RAW); 16037+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR3_RAW); 16038+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 16039+ hiedmac->base + HIEDMAC_INT_TC1_MASK); 16040+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 16041+ hiedmac->base + HIEDMAC_INT_TC2_MASK); 16042+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 16043+ hiedmac->base + HIEDMAC_INT_ERR1_MASK); 16044+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 16045+ hiedmac->base + HIEDMAC_INT_ERR2_MASK); 16046+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 16047+ hiedmac->base + HIEDMAC_INT_ERR3_MASK); 16048+} 16049+ 16050+static struct hiedmacv310_driver_data* hiedmacv310_prep_hiedmac_device(struct platform_device *pdev) 16051+{ 16052+ int ret; 16053+ struct hiedmacv310_driver_data *hiedmac = NULL; 16054+ ssize_t trasfer_size; 16055+ 16056+ ret = dma_set_mask_and_coherent(&(pdev->dev), DMA_BIT_MASK(64)); 16057+ if (ret) 16058+ return NULL; 16059+ 16060+ hiedmac = kzalloc(sizeof(*hiedmac), GFP_KERNEL); 16061+ if (!hiedmac) { 16062+ hiedmacv310_error("malloc for hiedmac fail!"); 16063+ return NULL; 16064+ } 16065+ 16066+ hiedmac->dev = pdev; 16067+ 16068+ ret = get_of_probe(hiedmac); 16069+ if (ret) { 16070+ hiedmacv310_error("get dts info fail!"); 16071+ goto free_hiedmac; 16072+ } 16073+ 16074+ hiedmacv310_prep_dma_device(pdev, hiedmac); 16075+ hiedmac->max_transfer_size = MAX_TRANSFER_BYTES; 16076+ trasfer_size = MAX_TSFR_LLIS * EDMACV300_LLI_WORDS * sizeof(u32); 16077+ 16078+ hiedmac->pool = dma_pool_create(DRIVER_NAME, &(pdev->dev), 16079+ trasfer_size, EDMACV300_POOL_ALIGN, 0); 16080+ if (!hiedmac->pool) { 16081+ hiedmacv310_error("create pool fail!"); 16082+ goto free_hiedmac; 16083+ } 16084+ 16085+ ret = hiedmacv310_init_chan(hiedmac); 16086+ if (ret) { 16087+ goto free_pool; 16088+ } 16089+ return hiedmac; 16090+ 16091+free_pool: 16092+ dma_pool_destroy(hiedmac->pool); 16093+free_hiedmac: 16094+ kfree(hiedmac); 16095+ return NULL; 16096+} 16097+ 16098+static void free_hiedmac_device(struct hiedmacv310_driver_data *hiedmac) 16099+{ 16100+ hiedmacv310_free_chan(hiedmac); 16101+ dma_pool_destroy(hiedmac->pool); 16102+ kfree(hiedmac); 16103+} 16104+ 16105+static int __init hiedmacv310_probe(struct platform_device *pdev) 16106+{ 16107+ int ret; 16108+ struct hiedmacv310_driver_data *hiedmac = NULL; 16109+ 16110+ hiedmac = hiedmacv310_prep_hiedmac_device(pdev); 16111+ if (hiedmac == NULL) { 16112+ return -ENOMEM; 16113+ } 16114+ 16115+ ret = request_irq(hiedmac->irq, hiemdacv310_irq, 0, DRIVER_NAME, hiedmac); 16116+ if (ret) { 16117+ hiedmacv310_error("fail to request irq"); 16118+ goto free_hiedmac; 16119+ } 16120+ hiedmacv310_prep_phy_device(hiedmac); 16121+ ret = dma_async_device_register(&hiedmac->memcpy); 16122+ if (ret) { 16123+ hiedmacv310_error("%s failed to register memcpy as an async device - %d\n", __func__, ret); 16124+ goto free_irq_res; 16125+ } 16126+ 16127+ ret = dma_async_device_register(&hiedmac->slave); 16128+ if (ret) { 16129+ hiedmacv310_error("%s failed to register slave as an async device - %d\n", __func__, ret); 16130+ goto free_memcpy_device; 16131+ } 16132+ return 0; 16133+ 16134+free_memcpy_device: 16135+ dma_async_device_unregister(&hiedmac->memcpy); 16136+free_irq_res: 16137+ free_irq(hiedmac->irq, hiedmac); 16138+free_hiedmac: 16139+ free_hiedmac_device(hiedmac); 16140+ return -ENOMEM; 16141+} 16142+ 16143+static int hiemda_remove(struct platform_device *pdev) 16144+{ 16145+ int err = 0; 16146+ return err; 16147+} 16148+ 16149+static const struct of_device_id hiedmacv310_match[] = { 16150+ { .compatible = "hisilicon,hiedmacv310" }, 16151+ {}, 16152+}; 16153+ 16154+static struct platform_driver hiedmacv310_driver = { 16155+ .remove = hiemda_remove, 16156+ .driver = { 16157+ .name = "hiedmacv310", 16158+ .of_match_table = hiedmacv310_match, 16159+ }, 16160+}; 16161+ 16162+static int __init hiedmacv310_init(void) 16163+{ 16164+ return platform_driver_probe(&hiedmacv310_driver, hiedmacv310_probe); 16165+} 16166+subsys_initcall(hiedmacv310_init); 16167+ 16168+static void __exit hiedmacv310_exit(void) 16169+{ 16170+ platform_driver_unregister(&hiedmacv310_driver); 16171+} 16172+module_exit(hiedmacv310_exit); 16173+ 16174+MODULE_LICENSE("GPL"); 16175+MODULE_AUTHOR("Hisilicon"); 16176diff --git a/drivers/dma/hiedmacv310.h b/drivers/dma/hiedmacv310.h 16177new file mode 100644 16178index 000000000..1fc093945 16179--- /dev/null 16180+++ b/drivers/dma/hiedmacv310.h 16181@@ -0,0 +1,153 @@ 16182+/* 16183+ * driver/dma/hiedmacv310.h 16184+ * 16185+ * The Hiedma Controller v310 Device Driver for HiSilicon 16186+ * 16187+ * Copyright (c) 2020 HiSilicon Technologies Co., Ltd. 16188+ * 16189+ * This program is free software; you can redistribute it and/or modify it 16190+ * under the terms of the GNU General Public License as published by the 16191+ * Free Software Foundation; either version 2 of the License, or (at your 16192+ * option) any later version. 16193+ * 16194+ * This program is distributed in the hope that it will be useful, 16195+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 16196+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16197+ * GNU General Public License for more details. 16198+ * 16199+ * You should have received a copy of the GNU General Public License 16200+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 16201+ * 16202+ */ 16203+#ifndef __HIEDMACV310_H__ 16204+#define __HIEDMACV310_H__ 16205+ 16206+/* debug control */ 16207+#define HIEDMACV310_CONFIG_TRACE_LEVEL 3 16208+#define HIEDMACV310_TRACE_LEVEL 0 16209+#define HIEDMACV310_REG_TRACE_LEVEL 3 16210+#define HIEDMACV310_TRACE_FMT KERN_INFO 16211+ 16212+#ifdef DEBUG_HIEDMAC 16213+#define hiedmacv310_trace(level, msg...) do { \ 16214+ if ((level) >= HIEDMACV310_TRACE_LEVEL) { \ 16215+ printk(HIEDMACV310_TRACE_FMT"%s:%d: ", __func__, __LINE__); \ 16216+ printk(msg); \ 16217+ printk("\n"); \ 16218+ } \ 16219+} while (0) 16220+ 16221+ 16222+#define hiedmacv310_assert(cond) do { \ 16223+ if (!(cond)) { \ 16224+ printk(KERN_ERR "Assert:hiedmacv310:%s:%d\n", \ 16225+ __func__, \ 16226+ __LINE__); \ 16227+ BUG(); \ 16228+ } \ 16229+} while (0) 16230+ 16231+#define hiedmacv310_error(s...) do { \ 16232+ printk(KERN_ERR "hiedmacv310:%s:%d: ", __func__, __LINE__); \ 16233+ printk(s); \ 16234+ printk("\n"); \ 16235+} while (0) 16236+ 16237+#else 16238+ 16239+#define hiedmacv310_trace(level, msg...) 16240+#define hiedmacv310_assert(level, msg...) 16241+#define hiedmacv310_error(level, msg...) 16242+ 16243+#endif 16244+ 16245+#define hiedmacv310_readl(addr) ((unsigned int)readl((void *)(addr))) 16246+ 16247+#define hiedmacv310_writel(v, addr) do { writel(v, (void *)(addr)); \ 16248+} while (0) 16249+ 16250+ 16251+#define MAX_TRANSFER_BYTES 0xffff 16252+ 16253+/* reg offset */ 16254+#define HIEDMAC_INT_STAT 0x0 16255+#define HIEDMAC_INT_TC1 0x4 16256+#define HIEDMAC_INT_TC2 0x8 16257+#define HIEDMAC_INT_ERR1 0xc 16258+#define HIEDMAC_INT_ERR2 0x10 16259+#define HIEDMAC_INT_ERR3 0x14 16260+ 16261+#define HIEDMAC_INT_TC1_MASK 0x18 16262+#define HIEDMAC_INT_TC2_MASK 0x1c 16263+#define HIEDMAC_INT_ERR1_MASK 0x20 16264+#define HIEDMAC_INT_ERR2_MASK 0x24 16265+#define HIEDMAC_INT_ERR3_MASK 0x28 16266+ 16267+#define HIEDMAC_INT_TC1_RAW 0x600 16268+#define HIEDMAC_INT_TC2_RAW 0x608 16269+#define HIEDMAC_INT_ERR1_RAW 0x610 16270+#define HIEDMAC_INT_ERR2_RAW 0x618 16271+#define HIEDMAC_INT_ERR3_RAW 0x620 16272+ 16273+#define hiedmac_cx_curr_cnt0(cn) (0x404 + (cn) * 0x20) 16274+#define hiedmac_cx_curr_src_addr_l(cn) (0x408 + (cn) * 0x20) 16275+#define hiedmac_cx_curr_src_addr_h(cn) (0x40c + (cn) * 0x20) 16276+#define hiedmac_cx_curr_dest_addr_l(cn) (0x410 + (cn) * 0x20) 16277+#define hiedmac_cx_curr_dest_addr_h(cn) (0x414 + (cn) * 0x20) 16278+ 16279+#define HIEDMAC_CH_PRI 0x688 16280+#define HIEDMAC_CH_STAT 0x690 16281+#define HIEDMAC_DMA_CTRL 0x698 16282+ 16283+#define hiedmac_cx_base(cn) (0x800 + (cn) * 0x40) 16284+#define hiedmac_cx_lli_l(cn) (0x800 + (cn) * 0x40) 16285+#define hiedmac_cx_lli_h(cn) (0x804 + (cn) * 0x40) 16286+#define hiedmac_cx_cnt0(cn) (0x81c + (cn) * 0x40) 16287+#define hiedmac_cx_src_addr_l(cn) (0x820 + (cn) * 0x40) 16288+#define hiedmac_cx_src_addr_h(cn) (0x824 + (cn) * 0x40) 16289+#define hiedmac_cx_dest_addr_l(cn) (0x828 + (cn) * 0x40) 16290+#define hiedmac_cx_dest_addr_h(cn) (0x82c + (cn) * 0x40) 16291+#define hiedmac_cx_config(cn) (0x830 + (cn) * 0x40) 16292+ 16293+#define HIEDMAC_ALL_CHAN_CLR 0xff 16294+#define HIEDMAC_INT_ENABLE_ALL_CHAN 0xff 16295+ 16296+ 16297+#define HIEDMAC_CONFIG_SRC_INC (1 << 31) 16298+#define HIEDMAC_CONFIG_DST_INC (1 << 30) 16299+ 16300+#define HIEDMAC_CONFIG_SRC_WIDTH_SHIFT 16 16301+#define HIEDMAC_CONFIG_DST_WIDTH_SHIFT 12 16302+#define HIEDMAC_WIDTH_8BIT 0b0 16303+#define HIEDMAC_WIDTH_16BIT 0b1 16304+#define HIEDMAC_WIDTH_32BIT 0b10 16305+#define HIEDMAC_WIDTH_64BIT 0b11 16306+#ifdef CONFIG_64BIT 16307+#define HIEDMAC_MEM_BIT_WIDTH HIEDMAC_WIDTH_64BIT 16308+#else 16309+#define HIEDMAC_MEM_BIT_WIDTH HIEDMAC_WIDTH_32BIT 16310+#endif 16311+ 16312+#define HIEDMAC_MAX_BURST_WIDTH 16 16313+#define HIEDMAC_MIN_BURST_WIDTH 1 16314+#define HIEDMAC_CONFIG_SRC_BURST_SHIFT 24 16315+#define HIEDMAC_CONFIG_DST_BURST_SHIFT 20 16316+ 16317+#define HIEDMAC_LLI_ALIGN 0x40 16318+#define HIEDMAC_LLI_DISABLE 0x0 16319+#define HIEDMAC_LLI_ENABLE 0x2 16320+ 16321+#define HIEDMAC_CXCONFIG_SIGNAL_SHIFT 0x4 16322+#define HIEDMAC_CXCONFIG_MEM_TYPE 0x0 16323+#define HIEDMAC_CXCONFIG_DEV_MEM_TYPE 0x1 16324+#define HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT 0x2 16325+#define HIEDMAC_CXCONFIG_LLI_START 0x1 16326+ 16327+#define HIEDMAC_CXCONFIG_ITC_EN 0x1 16328+#define HIEDMAC_CXCONFIG_ITC_EN_SHIFT 0x1 16329+ 16330+#define CCFG_EN 0x1 16331+ 16332+#define HIEDMAC_CONTROL_SRC_WIDTH_MASK GENMASK(18, 16) 16333+#define HIEDMAC_CONTROL_DST_WIDTH_MASK GENMASK(14, 12) 16334+#endif 16335diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c 16336index f1b53dd1d..0825ad601 100644 16337--- a/drivers/gpio/gpio-pl061.c 16338+++ b/drivers/gpio/gpio-pl061.c 16339@@ -289,6 +289,9 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) 16340 struct pl061 *pl061; 16341 struct gpio_irq_chip *girq; 16342 int ret, irq; 16343+#ifdef CONFIG_ARCH_HISI_BVT 16344+ int gpio_idx; 16345+#endif 16346 16347 pl061 = devm_kzalloc(dev, sizeof(*pl061), GFP_KERNEL); 16348 if (pl061 == NULL) 16349@@ -301,7 +304,20 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) 16350 raw_spin_lock_init(&pl061->lock); 16351 pl061->gc.request = gpiochip_generic_request; 16352 pl061->gc.free = gpiochip_generic_free; 16353+#ifdef CONFIG_ARCH_HISI_BVT 16354+ if (dev->of_node) { 16355+ gpio_idx = of_alias_get_id(dev->of_node, "gpio"); 16356+ if (gpio_idx < 0) 16357+ return -ENOMEM; 16358+ pl061->gc.base = gpio_idx * PL061_GPIO_NR; 16359+ } 16360+ 16361+ if (pl061->gc.base < 0) 16362+ pl061->gc.base = -1; 16363+#else 16364 pl061->gc.base = -1; 16365+#endif 16366+ 16367 pl061->gc.get_direction = pl061_get_direction; 16368 pl061->gc.direction_input = pl061_direction_input; 16369 pl061->gc.direction_output = pl061_direction_output; 16370diff --git a/drivers/gpu/drm/hisilicon/Kconfig b/drivers/gpu/drm/hisilicon/Kconfig 16371index cc5a244db..d69de65db 100644 16372--- a/drivers/gpu/drm/hisilicon/Kconfig 16373+++ b/drivers/gpu/drm/hisilicon/Kconfig 16374@@ -5,3 +5,4 @@ 16375 16376 source "drivers/gpu/drm/hisilicon/hibmc/Kconfig" 16377 source "drivers/gpu/drm/hisilicon/kirin/Kconfig" 16378+source "drivers/gpu/drm/hisilicon/hismart/Kconfig" 16379diff --git a/drivers/gpu/drm/hisilicon/Makefile b/drivers/gpu/drm/hisilicon/Makefile 16380index 69dec6084..4d4968e65 100644 16381--- a/drivers/gpu/drm/hisilicon/Makefile 16382+++ b/drivers/gpu/drm/hisilicon/Makefile 16383@@ -5,3 +5,4 @@ 16384 16385 obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc/ 16386 obj-$(CONFIG_DRM_HISI_KIRIN) += kirin/ 16387+obj-$(CONFIG_DRM_HISI_HISMART) += hismart/ 16388diff --git a/drivers/gpu/drm/hisilicon/hismart/Kconfig b/drivers/gpu/drm/hisilicon/hismart/Kconfig 16389new file mode 100644 16390index 000000000..ffc8564a8 16391--- /dev/null 16392+++ b/drivers/gpu/drm/hisilicon/hismart/Kconfig 16393@@ -0,0 +1,8 @@ 16394+config DRM_HISI_HISMART 16395+ tristate "DRM Support for Hisilicon Smart Media / Smart Vision SoC chipset" 16396+ depends on DRM && (ARM || ARM64) 16397+ select DRM_KMS_HELPER 16398+ select DRM_GEM_CMA_HELPER 16399+ help 16400+ Choose this option to enable DRM on Hisilicon Smart Media / Smart Vision SoC chipset 16401+ 16402diff --git a/drivers/gpu/drm/hisilicon/hismart/Makefile b/drivers/gpu/drm/hisilicon/hismart/Makefile 16403new file mode 100644 16404index 000000000..e89172f24 16405--- /dev/null 16406+++ b/drivers/gpu/drm/hisilicon/hismart/Makefile 16407@@ -0,0 +1,27 @@ 16408+KERNEL_DIR := $(srctree) 16409+SDK_ROOT_DIR = $(shell cd $(KERNEL_DIR)/../../../../../device/soc/hisilicon/hi3516dv300/sdk_linux/drv && /bin/pwd) 16410+$(warning SDK_ROOT_DIR= $(SDK_ROOT_DIR)) 16411+EXTRA_CFLAGS += -I$(SDK_ROOT_DIR)/mpp/cbb/vo/vo_dev/drm_hal \ 16412+ -I$(SDK_ROOT_DIR)/mpp/component/hifb/drm_hal \ 16413+ -I$(SDK_ROOT_DIR)/mpp/component/hdmi/src/mkp/drm_hal \ 16414+ -I$(SDK_ROOT_DIR)/mpp/cbb/include \ 16415+ -I$(SDK_ROOT_DIR)/mpp/cbb/include/adapt \ 16416+ -I$(SDK_ROOT_DIR)/mpp/cbb/based/arch/hi3516cv500/include/hi3516cv500 \ 16417+ -I$(SDK_ROOT_DIR)/mpp/cbb/vo/vo_dev/include \ 16418+ -I$(SDK_ROOT_DIR)/mpp/cbb/vo/vo_dev/include/adapt \ 16419+ -I$(SDK_ROOT_DIR)/mpp/cbb/vo/include/adapt \ 16420+ -I$(SDK_ROOT_DIR)/mpp/cbb/vo/include \ 16421+ -I$(SDK_ROOT_DIR)/osal/include 16422+$(warning CONFIG_DRM_HISI_HISMART = $(CONFIG_DRM_HISI_HISMART)) 16423+hi_drm-y := \ 16424+ hi_drm_drv.o \ 16425+ hi_drm_crtc.o \ 16426+ hi_adp_crtc.o \ 16427+ hi_drm_hdmitx.o \ 16428+ hi_adp_hdmitx.o \ 16429+ hi_drm_func_ext.o \ 16430+ hi_drm_mipitx.o \ 16431+ hi_adp_mipitx.o 16432+ 16433+obj-y += hi_drm.o 16434+ 16435diff --git a/drivers/gpu/drm/hisilicon/hismart/drm_hal_mipitx.h b/drivers/gpu/drm/hisilicon/hismart/drm_hal_mipitx.h 16436new file mode 100644 16437index 000000000..88192d01f 16438--- /dev/null 16439+++ b/drivers/gpu/drm/hisilicon/hismart/drm_hal_mipitx.h 16440@@ -0,0 +1,91 @@ 16441+/* 16442+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 16443+ * Description: Hisilicon DRM driver 16444+ * Author: Hisilicon multimedia software group 16445+ * Create: 2020-7-29 16446+ */ 16447+ 16448+#ifndef __DRM_HAL_MIPITX_H__ 16449+#define __DRM_HAL_MIPITX_H__ 16450+ 16451+/* output timming */ 16452+enum IntfSync { 16453+ OUTPUT_USER = 0, /* User timing */ 16454+ OUTPUT_PAL, /* PAL standard */ 16455+ OUTPUT_NTSC, /* NTSC standard */ 16456+ OUTPUT_1080P24, /* 1920 x 1080 at 24 Hz. */ 16457+ OUTPUT_1080P25, /* 1920 x 1080 at 25 Hz. */ 16458+ OUTPUT_1080P30, /* 1920 x 1080 at 30 Hz. */ 16459+ OUTPUT_720P50, /* 1280 x 720 at 50 Hz. */ 16460+ OUTPUT_720P60, /* 1280 x 720 at 60 Hz. */ 16461+ OUTPUT_1080I50, /* 1920 x 1080 at 50 Hz, interlace. */ 16462+ OUTPUT_1080I60, /* 1920 x 1080 at 60 Hz, interlace. */ 16463+ OUTPUT_1080P50, /* 1920 x 1080 at 50 Hz. */ 16464+ OUTPUT_1080P60, /* 1920 x 1080 at 60 Hz. */ 16465+ OUTPUT_576P50, /* 720 x 576 at 50 Hz. */ 16466+ OUTPUT_480P60, /* 720 x 480 at 60 Hz. */ 16467+ OUTPUT_800X600_60, /* VESA 800 x 600 at 60 Hz (non-interlaced) */ 16468+ OUTPUT_1024X768_60, /* VESA 1024 x 768 at 60 Hz (non-interlaced) */ 16469+ OUTPUT_1280X1024_60, /* VESA 1280 x 1024 at 60 Hz (non-interlaced) */ 16470+ OUTPUT_1366X768_60, /* VESA 1366 x 768 at 60 Hz (non-interlaced) */ 16471+ OUTPUT_1440X900_60, /* VESA 1440 x 900 at 60 Hz (non-interlaced) CVT Compliant */ 16472+ OUTPUT_1280X800_60, /* 1280*800@60Hz VGA@60Hz */ 16473+ OUTPUT_1600X1200_60, /* VESA 1600 x 1200 at 60 Hz (non-interlaced) */ 16474+ OUTPUT_1680X1050_60, /* VESA 1680 x 1050 at 60 Hz (non-interlaced) */ 16475+ OUTPUT_1920X1200_60, /* VESA 1920 x 1600 at 60 Hz (non-interlaced) CVT (Reduced Blanking) */ 16476+ OUTPUT_640X480_60, /* VESA 640 x 480 at 60 Hz (non-interlaced) CVT */ 16477+ OUTPUT_960H_PAL, /* ITU-R BT.1302 960 x 576 at 50 Hz (interlaced) */ 16478+ OUTPUT_960H_NTSC, /* ITU-R BT.1302 960 x 480 at 60 Hz (interlaced) */ 16479+ OUTPUT_1920X2160_30, /* 1920x2160_30 */ 16480+ OUTPUT_2560X1440_30, /* 2560x1440_30 */ 16481+ OUTPUT_2560X1440_60, /* 2560x1440_60 */ 16482+ OUTPUT_2560X1600_60, /* 2560x1600_60 */ 16483+ OUTPUT_3840X2160_24, /* 3840x2160_24 */ 16484+ OUTPUT_3840X2160_25, /* 3840x2160_25 */ 16485+ OUTPUT_3840X2160_30, /* 3840x2160_30 */ 16486+ OUTPUT_3840X2160_50, /* 3840x2160_50 */ 16487+ OUTPUT_3840X2160_60, /* 3840x2160_60 */ 16488+ OUTPUT_4096X2160_24, /* 4096x2160_24 */ 16489+ OUTPUT_4096X2160_25, /* 4096x2160_25 */ 16490+ OUTPUT_4096X2160_30, /* 4096x2160_30 */ 16491+ OUTPUT_4096X2160_50, /* 4096x2160_50 */ 16492+ OUTPUT_4096X2160_60, /* 4096x2160_60 */ 16493+ OUTPUT_320X240_60, /* For ota5182 at 60 Hz (8bit) */ 16494+ OUTPUT_320X240_50, /* For ili9342 at 50 Hz (6bit) */ 16495+ OUTPUT_240X320_50, /* Hi3559AV100: For ili9341 at 50 Hz (6bit) */ 16496+ OUTPUT_240X320_60, /* For ili9341 at 60 Hz (16bit) */ 16497+ OUTPUT_800X600_50, /* For LCD at 50 Hz (24bit) */ 16498+ OUTPUT_720X1280_60, /* For MIPI DSI Tx 720 x1280 at 60 Hz */ 16499+ OUTPUT_1080X1920_60, /* For MIPI DSI Tx 1080x1920 at 60 Hz */ 16500+ OUTPUT_7680X4320_30, /* For HDMI2.1 at 30 Hz */ 16501+}; 16502+ 16503+struct DispInfo { 16504+ unsigned int width; 16505+ unsigned int hbp; 16506+ unsigned int hfp; 16507+ unsigned int hsw; 16508+ unsigned int height; 16509+ unsigned int vbp; 16510+ unsigned int vfp; 16511+ unsigned int vsw; 16512+ unsigned int frameRate; 16513+ unsigned int intfType; 16514+ enum IntfSync intfSync; 16515+ unsigned int minLevel; 16516+ unsigned int maxLevel; 16517+ unsigned int defLevel; 16518+}; 16519+ 16520+struct DispOperations { 16521+ int (*init)(unsigned int dev_id); 16522+ int (*on)(unsigned int dev_id); 16523+ int (*off)(unsigned int dev_id); 16524+ int (*setBacklight)(unsigned int dev_id, unsigned int level); 16525+ int (*getDispInfo)(unsigned int dev_id, struct DispInfo *info); 16526+}; 16527+ 16528+struct DispOperations *GetDispOps(void); 16529+ 16530+#endif /* __DRM_HAL_MIPITX_H__ */ 16531+ 16532diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.c b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.c 16533new file mode 100755 16534index 000000000..897f7838f 16535--- /dev/null 16536+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.c 16537@@ -0,0 +1,777 @@ 16538+/* 16539+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 16540+ * Description: Hisilicon DRM driver 16541+ * Author: Hisilicon multimedia software group 16542+ * Create: 2020-7-29 16543+ */ 16544+ 16545+#include "hi_adp_crtc.h" 16546+#include <linux/clk.h> 16547+#include <linux/component.h> 16548+#include <linux/of_address.h> 16549+#include <video/videomode.h> 16550+#include <drm/drm_atomic_helper.h> 16551+#include <drm/drm_crtc.h> 16552+#include <drm/drm_crtc_helper.h> 16553+#include <drm/drm_fb_cma_helper.h> 16554+#include <drm/drm_fb_helper.h> 16555+#include <drm/drm_gem_cma_helper.h> 16556+#include <drm/drm_of.h> 16557+#include <drm/drm_plane_helper.h> 16558+#include <drm/drm_util.h> 16559+#include <drm/drm_framebuffer.h> 16560+#include <drm/drm_fourcc.h> 16561+#include <drm/drm_gem_framebuffer_helper.h> 16562+#include "hi_drm_drv.h" 16563+#include "drm_hal_common.h" 16564+#include "drm_hal_display.h" 16565+#include "drm_hal_gfx.h" 16566+#include "hi_drm_func_ext.h" 16567+ 16568+struct hi_drm_plane { 16569+ struct drm_plane base; 16570+ struct hi_drm_crtc *root_hi_crtc; /* which hi_crtc this plane belongs to */ 16571+ enum drm_hal_gfx_layer id; /* layer id */ 16572+ unsigned int status; /* 0: closed, 1: opened */ 16573+}; 16574+ 16575+struct hi_drm_crtc { 16576+ struct drm_crtc base; 16577+ /* each crtc can have several planes */ 16578+ struct hi_drm_plane primary[HI_DRM_MAX_PRIMARY_NUM]; 16579+ struct hi_drm_plane cursor; 16580+ struct hi_drm_plane overlay[HI_DRM_MAX_OVERLAY_NUM]; 16581+ enum drm_hal_disp_chn id; /* display id */ 16582+ adp_crtc_callback adp_crtc_cb; 16583+ unsigned int status; /* 0: closed, 1: opened */ 16584+ bool vb_enable; 16585+}; 16586+ 16587+struct hi_drm_crtc_global { 16588+ struct hi_drm_crtc crtcs[HI_DRM_MAX_CRTC_NUM]; 16589+ struct drm_hal_disp_dev *disp_dev; /* the pointer to drm hal display api */ 16590+ struct drm_hal_gfx_dev *gfx_dev; /* the pointer to drm hal graphics api */ 16591+}; 16592+ 16593+#define to_hi_crtc(x) container_of(x, struct hi_drm_crtc, base) 16594+#define to_hi_plane(x) container_of(x, struct hi_drm_plane, base) 16595+ 16596+static struct hi_drm_crtc_global *g_hi_crtcs = NULL; 16597+ 16598+static struct drm_hal_disp_dev* adp_crtc_get_disp_func(void) 16599+{ 16600+ int ret; 16601+ 16602+ if (g_hi_crtcs->disp_dev != NULL) { 16603+ return g_hi_crtcs->disp_dev; 16604+ } 16605+ 16606+ ret = drm_get_export_func(MOD_ID_DISP, (hi_void **)&g_hi_crtcs->disp_dev); 16607+ if (ret != HI_SUCCESS) { 16608+ return NULL; 16609+ } 16610+ 16611+ return (struct drm_hal_disp_dev *)g_hi_crtcs->disp_dev; 16612+} 16613+ 16614+static struct drm_hal_gfx_dev* adp_crtc_get_gfx_func(void) 16615+{ 16616+ int ret; 16617+ 16618+ if (g_hi_crtcs->gfx_dev != NULL) { 16619+ return g_hi_crtcs->gfx_dev; 16620+ } 16621+ 16622+ ret = drm_get_export_func(MOD_ID_GFX, (hi_void **)&g_hi_crtcs->gfx_dev); 16623+ if (ret != HI_SUCCESS) { 16624+ return NULL; 16625+ } 16626+ 16627+ return (struct drm_hal_gfx_dev *)g_hi_crtcs->gfx_dev; 16628+} 16629+ 16630+static void adp_gfx_get_capability(struct drm_hal_gfx_capability *cap) 16631+{ 16632+ cap->layer_cap[DRM_HAL_GFX_G0].available = 1; 16633+ cap->layer_cap[DRM_HAL_GFX_G0].connected_disp_chn = DRM_HAL_DISP_0; 16634+ cap->layer_cap[DRM_HAL_GFX_G0].max_w = 1920; /* 1920 max width */ 16635+ cap->layer_cap[DRM_HAL_GFX_G0].max_h = 1080; /* 1080 max height */ 16636+ cap->layer_cap[DRM_HAL_GFX_G0].format_num = 2; /* 2:support 2 color format */ 16637+ cap->layer_cap[DRM_HAL_GFX_G0].formats[0] = DRM_HAL_FMT_ARGB8888; 16638+ cap->layer_cap[DRM_HAL_GFX_G0].formats[1] = DRM_HAL_FMT_ARGB1555; 16639+ 16640+ cap->layer_cap[DRM_HAL_GFX_G1].available = 0; 16641+ 16642+ cap->layer_cap[DRM_HAL_GFX_G2].available = 0; 16643+ 16644+ cap->layer_cap[DRM_HAL_GFX_G3].available = 1; 16645+ cap->layer_cap[DRM_HAL_GFX_G3].connected_disp_chn = DRM_HAL_DISP_0; 16646+ cap->layer_cap[DRM_HAL_GFX_G3].max_w = 256; /* 256 max width */ 16647+ cap->layer_cap[DRM_HAL_GFX_G3].max_h = 256; /* 256 max height */ 16648+ cap->layer_cap[DRM_HAL_GFX_G3].format_num = 2; /* 2:support 2 color format */ 16649+ cap->layer_cap[DRM_HAL_GFX_G3].formats[0] = DRM_HAL_FMT_ARGB8888; 16650+ cap->layer_cap[DRM_HAL_GFX_G3].formats[1] = DRM_HAL_FMT_ARGB1555; 16651+ 16652+ return; 16653+} 16654+ 16655+int hi_adp_plane_get_by_index(struct drm_crtc *crtc, struct drm_plane **plane, enum drm_plane_type type, int index) 16656+{ 16657+ int i; 16658+ int matched = 0; 16659+ struct drm_hal_gfx_capability cap; 16660+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 16661+ 16662+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 16663+ 16664+ /* currently only support primary plane, need support cursor plane later */ 16665+ if (type != DRM_PLANE_TYPE_PRIMARY) { 16666+ HI_DRM_ERR("plane type %d not support!\n", type); 16667+ return -1; 16668+ } 16669+ 16670+ if (index >= HI_DRM_MAX_PRIMARY_NUM) { 16671+ HI_DRM_ERR("invalid index: %d!\n", index); 16672+ return -1; 16673+ } 16674+ 16675+ adp_gfx_get_capability(&cap); 16676+ 16677+ for (i = 0; i < DRM_HAL_GFX_MAX; i++) { 16678+ if (cap.layer_cap[i].available != 0 && 16679+ cap.layer_cap[i].connected_disp_chn == hi_crtc->id) { 16680+ if (matched++ == index) 16681+ break; 16682+ } 16683+ } 16684+ hi_crtc->primary[index].id = i; 16685+ hi_crtc->primary[index].root_hi_crtc = hi_crtc; 16686+ *plane = &hi_crtc->primary[index].base; 16687+ 16688+ return 0; 16689+} 16690+ 16691+static int hi_adp_crtc_set_csc(void) 16692+{ 16693+ int ret; 16694+ hi_vo_csc csc = {0}; 16695+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 16696+ 16697+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 16698+ HI_DRM_CHECK_PTR_RETURN(disp_dev->get_csc); 16699+ HI_DRM_CHECK_PTR_RETURN(disp_dev->set_csc); 16700+ 16701+ ret = disp_dev->get_csc(DRM_HAL_GFX_G0, &csc); 16702+ if (ret != 0) { 16703+ HI_DRM_ERR("disp_dev->get_csc error, ret=%#x\n", ret); 16704+ return ret; 16705+ } 16706+ 16707+ csc.csc_matrix = VO_CSC_MATRIX_IDENTITY; 16708+ ret = disp_dev->set_csc(DRM_HAL_GFX_G0, &csc); 16709+ if (ret != 0) { 16710+ HI_DRM_ERR("disp_dev->set_csc error, ret=%#x\n", ret); 16711+ return ret; 16712+ } 16713+ return 0; 16714+} 16715+ 16716+int hi_adp_plane_reset_csc(struct drm_plane *plane) 16717+{ 16718+ int ret = 0; 16719+ struct drm_connector *connector; 16720+ struct drm_connector_list_iter conn_iter; 16721+ enum drm_connector_status mipi_status = 0; 16722+ enum drm_connector_status hdmi_status = 0; 16723+ 16724+ drm_connector_list_iter_begin(plane->dev, &conn_iter); 16725+ drm_for_each_connector_iter(connector, &conn_iter) { 16726+ if (connector->connector_type == DRM_MODE_CONNECTOR_DSI) { 16727+ mipi_status = connector->status; 16728+ } else if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) { 16729+ hdmi_status = connector->status; 16730+ } 16731+ } 16732+ if (hdmi_status != connector_status_connected && mipi_status == connector_status_connected) { 16733+ ret = hi_adp_crtc_set_csc(); 16734+ } 16735+ drm_connector_list_iter_end(&conn_iter); 16736+ return ret; 16737+} 16738+ 16739+int hi_adp_plane_open(struct drm_plane *plane) 16740+{ 16741+ int ret; 16742+ struct hi_drm_plane *hi_plane = to_hi_plane(plane); 16743+ struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func(); 16744+ 16745+ HI_DRM_CHECK_PTR_RETURN(hi_plane); 16746+ HI_DRM_CHECK_PTR_RETURN(gfx_dev); 16747+ HI_DRM_CHECK_PTR_RETURN(gfx_dev->open); 16748+ HI_DRM_CHECK_PTR_RETURN(gfx_dev->enable); 16749+ HI_DRM_CHECK_PTR_RETURN(gfx_dev->close); 16750+ 16751+ /* plane already opened */ 16752+ if (hi_plane->status == 1) { 16753+ return 0; 16754+ } 16755+ /* ensure the relied crtc has been opened */ 16756+ ret = hi_adp_crtc_open(&hi_plane->root_hi_crtc->base); 16757+ if (ret != 0) { 16758+ return -1; 16759+ } 16760+ 16761+ ret = gfx_dev->open(hi_plane->id); 16762+ if (ret != 0) { 16763+ goto err_crtc_close; 16764+ } 16765+ 16766+ ret = gfx_dev->enable(hi_plane->id); 16767+ if (ret != 0) { 16768+ goto err_dev_close; 16769+ } 16770+ hi_plane->status = 1; 16771+ 16772+ return 0; 16773+ 16774+err_dev_close: 16775+ gfx_dev->close(hi_plane->id); 16776+err_crtc_close: 16777+ hi_adp_crtc_close(&hi_plane->root_hi_crtc->base); 16778+ return ret; 16779+} 16780+ 16781+static int adp_plane_close(struct drm_plane *plane) 16782+{ 16783+ int ret; 16784+ struct hi_drm_plane *hi_plane = to_hi_plane(plane); 16785+ struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func(); 16786+ 16787+ HI_DRM_CHECK_PTR_RETURN(hi_plane); 16788+ HI_DRM_CHECK_PTR_RETURN(gfx_dev); 16789+ HI_DRM_CHECK_PTR_RETURN(gfx_dev->disable); 16790+ HI_DRM_CHECK_PTR_RETURN(gfx_dev->close); 16791+ 16792+ /* plane already closed */ 16793+ if (hi_plane->status == 0) { 16794+ return 0; 16795+ } 16796+ 16797+ ret = gfx_dev->disable(hi_plane->id); 16798+ if (ret != 0) { 16799+ return -1; 16800+ } 16801+ 16802+ ret = gfx_dev->close(hi_plane->id); 16803+ if (ret != 0) { 16804+ return -1; 16805+ } 16806+ hi_plane->status = 0; 16807+ return 0; 16808+} 16809+ 16810+int hi_adp_plane_close(struct drm_plane *plane) 16811+{ 16812+ return adp_plane_close(plane); 16813+} 16814+ 16815+static void adp_format_translate(u32 drm_fmt, enum drm_hal_color_fmt *hal_fmt) 16816+{ 16817+ switch (drm_fmt) { 16818+ case DRM_FORMAT_ARGB8888: 16819+ /* fall-through */ 16820+ case DRM_FORMAT_XRGB8888: 16821+ *hal_fmt = DRM_HAL_FMT_ARGB8888; 16822+ break; 16823+ case DRM_FORMAT_RGB888: 16824+ *hal_fmt = DRM_HAL_FMT_RGB888; 16825+ break; 16826+ case DRM_FORMAT_RGB565: 16827+ *hal_fmt = DRM_HAL_FMT_RGB565; 16828+ break; 16829+ case DRM_FORMAT_ARGB1555: 16830+ /* fall-through */ 16831+ case DRM_FORMAT_XRGB1555: 16832+ *hal_fmt = DRM_HAL_FMT_ARGB1555; 16833+ break; 16834+ default: 16835+ *hal_fmt = DRM_HAL_FMT_MAX; 16836+ break; 16837+ } 16838+ return; 16839+} 16840+ 16841+void hi_adp_plane_update(struct drm_plane *plane) 16842+{ 16843+ int ret; 16844+ struct drm_plane_state *state = plane->state; 16845+ struct drm_framebuffer *fb = state->fb; 16846+ struct hi_drm_plane *hi_plane = to_hi_plane(plane); 16847+ struct drm_hal_rect hal_rect; 16848+ enum drm_hal_color_fmt hal_fmt; 16849+ struct drm_gem_object *gem = NULL; 16850+ struct drm_gem_cma_object *cma_gem = NULL; 16851+ struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func(); 16852+ 16853+ HI_DRM_FUNC_ENTER(); 16854+ /* no framebuffer or status not ready */ 16855+ if (fb == NULL || IS_ERR_OR_NULL(hi_plane) || IS_ERR_OR_NULL(hi_plane->root_hi_crtc) || 16856+ IS_ERR_OR_NULL(gfx_dev) || IS_ERR_OR_NULL(gfx_dev->set_attr) || IS_ERR_OR_NULL(gfx_dev->refresh) || 16857+ hi_plane->root_hi_crtc->status == 0) { 16858+ return; 16859+ } 16860+ 16861+ /* for cma gem only. */ 16862+ gem = drm_gem_fb_get_obj(fb, 0); 16863+ cma_gem = to_drm_gem_cma_obj(gem); 16864+ /* no memory */ 16865+ if (IS_ERR_OR_NULL(cma_gem)) { 16866+ return; 16867+ } 16868+ 16869+ /* rect */ 16870+ hal_rect.x = 0; 16871+ hal_rect.y = 0; 16872+ hal_rect.w = fb->width; 16873+ hal_rect.h = fb->height; 16874+ ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_SIZE, &hal_rect); 16875+ if (ret != 0) { 16876+ drm_hal_err("error, ret=%#x!\n", ret); 16877+ } 16878+ 16879+ /* format */ 16880+ adp_format_translate(fb->format->format, &hal_fmt); 16881+ ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_FORMAT, &hal_fmt); 16882+ if (ret != 0) { 16883+ drm_hal_err("error, ret=%#x!\n", ret); 16884+ } 16885+ 16886+ /* stride */ 16887+ ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_STRIDE, &fb->pitches[0]); 16888+ if (ret != 0) { 16889+ drm_hal_err("error, ret=%#x!\n", ret); 16890+ } 16891+ 16892+ /* buffer address */ 16893+ ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_BUFFER, &cma_gem->paddr); 16894+ if (ret != 0) { 16895+ drm_hal_err("error, ret=%#x!\n", ret); 16896+ } 16897+ 16898+ /* enable the registers */ 16899+ ret = gfx_dev->refresh(hi_plane->id); 16900+ if (ret != 0) { 16901+ drm_hal_err("error, ret=%#x!\n", ret); 16902+ } 16903+ HI_DRM_FUNC_EXIT(); 16904+ return; 16905+} 16906+ 16907+/* adp crtc global init */ 16908+int hi_adp_crtc_init(void) 16909+{ 16910+ g_hi_crtcs = kzalloc(sizeof(struct hi_drm_crtc_global), GFP_KERNEL); 16911+ if (g_hi_crtcs == NULL) { 16912+ return -ENOMEM; 16913+ } 16914+ 16915+ return 0; 16916+} 16917+ 16918+void hi_adp_crtc_deinit(void) 16919+{ 16920+ struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func(); 16921+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 16922+ 16923+ if (gfx_dev->deinit != NULL) { 16924+ gfx_dev->deinit(); 16925+ } 16926+ if (disp_dev->deinit != NULL) { 16927+ disp_dev->deinit(); 16928+ } 16929+ if (g_hi_crtcs != NULL) { 16930+ kfree(g_hi_crtcs); 16931+ g_hi_crtcs = NULL; 16932+ } 16933+ return; 16934+} 16935+ 16936+void hi_adp_crtc_get_cap(struct hi_adp_crtc_cap *cap) 16937+{ 16938+ if (cap != NULL) { 16939+ cap->crtc_num = 1; 16940+ } 16941+ return; 16942+} 16943+ 16944+int hi_adp_crtc_get_by_index(struct drm_crtc **crtc, int index) 16945+{ 16946+ if (index >= HI_DRM_MAX_CRTC_NUM) { 16947+ HI_DRM_ERR("invalid index %d\n", index); 16948+ return -1; 16949+ } 16950+ 16951+ HI_DRM_CHECK_PTR_RETURN(g_hi_crtcs); 16952+ *crtc = &g_hi_crtcs->crtcs[index].base; 16953+ /* translate the index to drm hal enum */ 16954+ switch (index) { 16955+ case 0: 16956+ g_hi_crtcs->crtcs[index].id = DRM_HAL_DISP_0; 16957+ break; 16958+ case 1: 16959+ g_hi_crtcs->crtcs[index].id = DRM_HAL_DISP_1; 16960+ break; 16961+ default: 16962+ return -1; 16963+ } 16964+ return 0; 16965+} 16966+ 16967+int hi_adp_crtc_open(struct drm_crtc *crtc) 16968+{ 16969+ int ret; 16970+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 16971+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 16972+ 16973+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 16974+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 16975+ HI_DRM_CHECK_PTR_RETURN(disp_dev->open); 16976+ HI_DRM_CHECK_PTR_RETURN(disp_dev->enable); 16977+ HI_DRM_CHECK_PTR_RETURN(disp_dev->close); 16978+ 16979+ if (hi_crtc->status >= 1) { 16980+ HI_DRM_INFO("crtc already opened!\n"); 16981+ return 0; 16982+ } 16983+ 16984+ HI_DRM_INFO("prepare to open display: %d\n", hi_crtc->id); 16985+ 16986+ ret = disp_dev->open(hi_crtc->id); 16987+ if (ret != 0) { 16988+ HI_DRM_ERR("disp_dev->open error, ret=%#x\n", ret); 16989+ goto err_ret; 16990+ } 16991+ 16992+ ret = disp_dev->enable(hi_crtc->id); 16993+ if (ret != 0) { 16994+ HI_DRM_ERR("disp_dev->enable error, ret=%#x\n", ret); 16995+ goto err_disp_close; 16996+ } 16997+ 16998+ hi_crtc->status = 1; 16999+ hi_crtc->vb_enable = false; 17000+ 17001+ return 0; 17002+err_disp_close: 17003+ (void)disp_dev->close(hi_crtc->id); 17004+err_ret: 17005+ return ret; 17006+} 17007+ 17008+int hi_adp_crtc_close(struct drm_crtc *crtc) 17009+{ 17010+ int ret; 17011+ int i; 17012+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17013+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 17014+ 17015+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 17016+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 17017+ HI_DRM_CHECK_PTR_RETURN(disp_dev->disable); 17018+ HI_DRM_CHECK_PTR_RETURN(disp_dev->close); 17019+ 17020+ if (hi_crtc->status == 0) { 17021+ HI_DRM_INFO("crtc already closed!\n"); 17022+ return 0; 17023+ } 17024+ 17025+ ret = disp_dev->disable(hi_crtc->id); 17026+ if (ret != 0) { 17027+ HI_DRM_ERR("disp_dev->disable error, ret=%#x\n", ret); 17028+ } 17029+ 17030+ /* close the crtc planes here to avoid the crtc vblank timeout issue!!! */ 17031+ for (i = 0; i < HI_DRM_MAX_PRIMARY_NUM; i++) { 17032+ if (hi_crtc->primary[i].status == 1) { 17033+ (void)adp_plane_close(&hi_crtc->primary[i].base); 17034+ } 17035+ } 17036+ 17037+ if (hi_crtc->cursor.status == 1) { 17038+ (void)adp_plane_close(&hi_crtc->cursor.base); 17039+ } 17040+ 17041+ ret |= disp_dev->close(hi_crtc->id); 17042+ if (ret != 0) { 17043+ HI_DRM_ERR("disp_dev->close error, ret=%#x\n", ret); 17044+ } 17045+ hi_crtc->status = 0; 17046+ return ret; 17047+} 17048+ 17049+int hi_adp_crtc_set_mode(struct drm_crtc *crtc, const struct drm_display_mode *mode) 17050+{ 17051+ int ret; 17052+ struct drm_hal_timing timing; 17053+ enum drm_hal_timing_fmt fmt; 17054+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17055+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 17056+ 17057+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 17058+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 17059+ HI_DRM_CHECK_PTR_RETURN(disp_dev->set_attr); 17060+ 17061+ timing.clock = mode->clock; 17062+ timing.hdisplay = mode->hdisplay; 17063+ timing.hskew = mode->hskew; 17064+ timing.hsync_end = mode->hsync_end; 17065+ timing.hsync_start = mode->hsync_start; 17066+ timing.htotal = mode->htotal; 17067+ timing.vdisplay = mode->vdisplay; 17068+ timing.vscan = mode->vscan; 17069+ timing.vsync_end = mode->vsync_end; 17070+ timing.vsync_start = mode->vsync_start; 17071+ timing.vtotal = mode->vtotal; 17072+ 17073+ fmt = hi_adp_crtc_timing_translate(&timing); 17074+ ret = disp_dev->set_attr(hi_crtc->id, DRM_HAL_DISP_ATTR_TIMING, (void *)&fmt); 17075+ if (ret != 0) { 17076+ HI_DRM_ERR("disp_dev->set_attr timing error, ret=%#x\n", ret); 17077+ return ret; 17078+ } 17079+ return 0; 17080+} 17081+ 17082+/* userfor mipitx */ 17083+int hi_adp_crtc_add_user_intf(struct drm_crtc *crtc) 17084+{ 17085+ int ret; 17086+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17087+ hi_vo_user_intfsync_info intf_sync_attr = {0}; 17088+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 17089+ 17090+ HI_DRM_CHECK_PTR_RETURN(crtc); 17091+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 17092+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 17093+ HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_user_intf_sync); 17094+ 17095+ HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_user_intf_sync); 17096+ intf_sync_attr.clk_reverse = HI_TRUE; 17097+ intf_sync_attr.dev_div = 1; 17098+ intf_sync_attr.pre_div = 1; 17099+ intf_sync_attr.user_intf_sync_attr.clk_source = VO_CLK_SOURCE_PLL; 17100+ intf_sync_attr.user_intf_sync_attr.user_sync_pll.fbdiv = 257; 17101+ intf_sync_attr.user_intf_sync_attr.user_sync_pll.frac = 10442139; 17102+ intf_sync_attr.user_intf_sync_attr.user_sync_pll.refdiv = 4; 17103+ intf_sync_attr.user_intf_sync_attr.user_sync_pll.postdiv1 = 7; 17104+ intf_sync_attr.user_intf_sync_attr.user_sync_pll.postdiv2 = 7; 17105+ ret = disp_dev->attach_user_intf_sync(hi_crtc->id, &intf_sync_attr, 0); 17106+ if (ret != 0) { 17107+ HI_DRM_ERR("attach_user_intf_sync error, ret=%#x\n", ret); 17108+ return ret; 17109+ } 17110+ return 0; 17111+} 17112+ 17113+int hi_adp_crtc_add_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id) 17114+{ 17115+ int ret; 17116+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17117+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 17118+ 17119+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 17120+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 17121+ HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_intf); 17122+ 17123+ ret = disp_dev->attach_intf(hi_crtc->id, intf_type, (void *)(&intf_id)); 17124+ if (ret != 0) { 17125+ HI_DRM_ERR("dd->attach_intf error, ret=%#x\n", ret); 17126+ return ret; 17127+ } 17128+ return 0; 17129+} 17130+ 17131+int hi_adp_crtc_del_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id) 17132+{ 17133+ int ret; 17134+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17135+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 17136+ 17137+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 17138+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 17139+ HI_DRM_CHECK_PTR_RETURN(disp_dev->detach_intf); 17140+ 17141+ ret = disp_dev->detach_intf(hi_crtc->id, intf_type, (void *)(&intf_id)); 17142+ if (ret != 0) { 17143+ HI_DRM_ERR("dd->detach_intf error, ret=%#x\n", ret); 17144+ return ret; 17145+ } 17146+ return 0; 17147+} 17148+ 17149+int hi_adp_crtc_add_user_intf_sync(struct drm_crtc *crtc, hi_vo_user_intfsync_info *intf_sync_attr, 17150+ unsigned int intf_id) 17151+{ 17152+ int ret; 17153+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17154+ struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func(); 17155+ 17156+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 17157+ HI_DRM_CHECK_PTR_RETURN(disp_dev); 17158+ HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_user_intf_sync); 17159+ ret = disp_dev->attach_user_intf_sync(hi_crtc->id, intf_sync_attr, (void *)(&intf_id)); 17160+ if (ret != 0) { 17161+ HI_DRM_ERR("attach_user_intf_sync error, ret=%#x\n", ret); 17162+ return ret; 17163+ } 17164+ return 0; 17165+} 17166+ 17167+ 17168+static struct hi_drm_crtc *adp_get_crtc_by_layer(enum drm_hal_gfx_layer layer) 17169+{ 17170+ int i; 17171+ struct drm_hal_gfx_capability cap = {0}; 17172+ 17173+ if (layer >= DRM_HAL_GFX_MAX) { 17174+ return NULL; 17175+ } 17176+ 17177+ adp_gfx_get_capability(&cap); 17178+ 17179+ if (cap.layer_cap[layer].available == 0) { 17180+ return NULL; 17181+ } 17182+ 17183+ for (i = 0; i < HI_DRM_MAX_CRTC_NUM; i++) { 17184+ if (g_hi_crtcs->crtcs[i].id == cap.layer_cap[layer].connected_disp_chn) { 17185+ return &g_hi_crtcs->crtcs[i]; 17186+ } 17187+ } 17188+ return NULL; 17189+} 17190+ 17191+int hi_adp_disp_cb(enum drm_hal_gfx_layer layer, enum drm_hal_gfx_cb_type type, void *para) 17192+{ 17193+ struct hi_drm_crtc *hi_crtc = adp_get_crtc_by_layer(layer); 17194+ 17195+ HI_DRM_CHECK_PTR_RETURN(hi_crtc); 17196+ 17197+ if (type == DRM_HAL_GFX_CB_INTR_100 && hi_crtc->adp_crtc_cb != NULL && hi_crtc->status != 0) { 17198+ return hi_crtc->adp_crtc_cb(&hi_crtc->base, HI_ADP_CRTC_VBLANK, para); 17199+ } 17200+ return 0; 17201+} 17202+ 17203+int hi_adp_crtc_reg_callback(struct drm_crtc *crtc, adp_crtc_callback cb) 17204+{ 17205+ int ret; 17206+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17207+ struct drm_plane *primary = crtc->primary; 17208+ struct hi_drm_plane *hi_plane = to_hi_plane(primary); 17209+ struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func(); 17210+ 17211+ if (IS_ERR_OR_NULL(hi_crtc) || IS_ERR_OR_NULL(hi_plane) || 17212+ IS_ERR_OR_NULL(gfx_dev) || IS_ERR_OR_NULL(gfx_dev->register_cb)) { 17213+ return -1; 17214+ } 17215+ 17216+ /* the callback function has already be refistered */ 17217+ if (hi_crtc->adp_crtc_cb != NULL) { 17218+ return 0; 17219+ } 17220+ /* 17221+ * register the callback to the layer of primary plane 17222+ * it is better that we can use the DHD interrupts from the display API, maybe we can improve this later 17223+ */ 17224+ ret = gfx_dev->register_cb(hi_plane->id, DRM_HAL_GFX_CB_INTR_100, hi_adp_disp_cb); 17225+ if (ret != 0) { 17226+ HI_DRM_ERR("gfx dev register callback error\n"); 17227+ return ret; 17228+ } 17229+ hi_crtc->adp_crtc_cb = cb; 17230+ return 0; 17231+} 17232+ 17233+void hi_adp_crtc_set_vblank(struct drm_crtc *crtc, bool enable) 17234+{ 17235+ struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc); 17236+ hi_crtc->vb_enable = enable; 17237+ return; 17238+} 17239+ 17240+struct adp_crtc_timing_map { 17241+ enum drm_hal_timing_fmt timing_fmt; 17242+ struct drm_hal_timing timing; 17243+}; 17244+ 17245+static struct adp_crtc_timing_map g_adp_crtc_timing_map[] = { 17246+ {DRM_HAL_TIMING_FMT_1080P_60, {148500, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0}}, 17247+ {DRM_HAL_TIMING_FMT_1080P_50, {148500, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0}}, 17248+ {DRM_HAL_TIMING_FMT_1080P_59_94, {148352, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0}}, 17249+ {DRM_HAL_TIMING_FMT_1080P_30, {74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0}}, 17250+ {DRM_HAL_TIMING_FMT_1080P_25, {74250, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0}}, 17251+ {DRM_HAL_TIMING_FMT_1080P_24, {74250, 1920, 2558, 2602, 2750, 0, 1080, 1084, 1089, 1125, 0}}, 17252+ {DRM_HAL_TIMING_FMT_1080I_60, {74250, 1920, 2008, 2052, 2200, 0, 540, 542, 547, 562, 0}}, 17253+ {DRM_HAL_TIMING_FMT_1080I_50, {74250, 1920, 2448, 2492, 2640, 0, 540, 542, 547, 562, 0}}, 17254+ {DRM_HAL_TIMING_FMT_720P_60, {74250, 1280, 1390, 1430, 1650, 0, 720, 725, 730, 750, 0}}, 17255+ {DRM_HAL_TIMING_FMT_720P_50, {74250, 1280, 1720, 1760, 1980, 0, 720, 725, 730, 750, 0}}, 17256+ {DRM_HAL_TIMING_FMT_576P_50, {27000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0}}, 17257+ {DRM_HAL_TIMING_FMT_480P_60, {27000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0}}, 17258+ {DRM_HAL_TIMING_FMT_PAL, {13500, 720, 732, 795, 864, 0, 288, 290, 293, 312, 0}}, 17259+ {DRM_HAL_TIMING_FMT_NTSC, {13500, 720, 739, 801, 858, 0, 240, 244, 247, 262, 0}}, 17260+ {DRM_HAL_TIMING_FMT_VESA_800X600_60, {40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0}}, 17261+ {DRM_HAL_TIMING_FMT_VESA_1024X768_60, {48400, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0}}, 17262+ {DRM_HAL_TIMING_FMT_VESA_1280X800_60, {83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0}}, 17263+ {DRM_HAL_TIMING_FMT_VESA_1280X1024_60, {108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0}}, 17264+ {DRM_HAL_TIMING_FMT_VESA_1366X768_60, {85500, 1366, 1436, 1579, 1792, 0, 768, 771, 774, 798, 0}}, 17265+ {DRM_HAL_TIMING_FMT_VESA_1440X900_60, {106500, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0}}, 17266+ {DRM_HAL_TIMING_FMT_VESA_1600X1200_60, {162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0}}, 17267+ {DRM_HAL_TIMING_FMT_VESA_1680X1050_60, {146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0}}, 17268+ {DRM_HAL_TIMING_FMT_VESA_1920X1200_60, {193250, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0}}, 17269+ {DRM_HAL_TIMING_FMT_2560X1440_60, {238750, 2560, 2608, 2640, 2720, 0, 1440, 1442, 1447, 1481, 0}}, 17270+ {DRM_HAL_TIMING_FMT_2560X1600_60, {268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0}}, 17271+ {DRM_HAL_TIMING_FMT_3840X2160P_24, {297000, 3840, 5116, 5204, 5500, 0, 2160, 2168, 2178, 2250, 0}}, 17272+ {DRM_HAL_TIMING_FMT_3840X2160P_25, {297000, 3840, 4896, 4984, 5280, 0, 2160, 2168, 2178, 2250, 0}}, 17273+ {DRM_HAL_TIMING_FMT_3840X2160P_30, {297000, 3840, 4016, 4104, 4400, 0, 2160, 2168, 2178, 2250, 0}}, 17274+ {DRM_HAL_TIMING_FMT_3840X2160P_50, {594000, 3840, 4896, 4984, 5280, 0, 2160, 2168, 2178, 2250, 0}}, 17275+ {DRM_HAL_TIMING_FMT_3840X2160P_60, {594000, 3840, 4016, 4104, 4400, 0, 2160, 2168, 2178, 2250, 0}}, 17276+ {DRM_HAL_TIMING_FMT_4096X2160P_24, {297000, 4096, 5116, 5204, 5500, 0, 2160, 2168, 2178, 2250, 0}}, 17277+ {DRM_HAL_TIMING_FMT_4096X2160P_25, {297000, 4096, 5064, 5152, 5280, 0, 2160, 2168, 2178, 2250, 0}}, 17278+ {DRM_HAL_TIMING_FMT_4096X2160P_30, {297000, 4096, 4184, 4272, 4400, 0, 2160, 2168, 2178, 2250, 0}}, 17279+ {DRM_HAL_TIMING_FMT_4096X2160P_50, {594000, 4096, 5064, 5152, 5280, 0, 2160, 2168, 2178, 2250, 0}}, 17280+ {DRM_HAL_TIMING_FMT_4096X2160P_60, {594000, 4096, 4184, 4272, 4400, 0, 2160, 2168, 2178, 2250, 0}}, 17281+ {DRM_HAL_TIMING_FMT_USER, {155493, 480, 528, 560, 620, 0, 960, 963, 968, 974, 0}}, 17282+}; 17283+ 17284+enum drm_hal_timing_fmt hi_adp_crtc_timing_translate(struct drm_hal_timing *timing) 17285+{ 17286+ int i; 17287+ 17288+ for (i = 0; i < sizeof(g_adp_crtc_timing_map) / sizeof(struct adp_crtc_timing_map); i++) { 17289+ if (g_adp_crtc_timing_map[i].timing.clock == timing->clock && 17290+ g_adp_crtc_timing_map[i].timing.hdisplay == timing->hdisplay && 17291+ g_adp_crtc_timing_map[i].timing.hsync_start == timing->hsync_start && 17292+ g_adp_crtc_timing_map[i].timing.hsync_end == timing->hsync_end && 17293+ g_adp_crtc_timing_map[i].timing.htotal == timing->htotal && 17294+ g_adp_crtc_timing_map[i].timing.hskew == timing->hskew && 17295+ g_adp_crtc_timing_map[i].timing.vdisplay == timing->vdisplay && 17296+ g_adp_crtc_timing_map[i].timing.vsync_start == timing->vsync_start && 17297+ g_adp_crtc_timing_map[i].timing.vsync_end == timing->vsync_end && 17298+ g_adp_crtc_timing_map[i].timing.vtotal == timing->vtotal && 17299+ g_adp_crtc_timing_map[i].timing.vscan == timing->vscan) { 17300+ break; 17301+ } 17302+ } 17303+ 17304+ HI_DRM_INFO("find matched: i = %d!\n", i); 17305+ 17306+ if (i == sizeof(g_adp_crtc_timing_map) / sizeof(struct adp_crtc_timing_map)) { 17307+ HI_DRM_ERR("can not find the matched format!\n"); 17308+ HI_DRM_ERR("org timing: %d %d %d %d %d %d %d %d %d %d %d\n", timing->clock, timing->hdisplay, 17309+ timing->hsync_start, timing->hsync_end, timing->htotal, timing->hskew, timing->vdisplay, 17310+ timing->vsync_start, timing->vsync_end, timing->vtotal, timing->vscan); 17311+ return DRM_HAL_TIMING_FMT_MAX; 17312+ } 17313+ return g_adp_crtc_timing_map[i].timing_fmt; 17314+} 17315diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.h b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.h 17316new file mode 100644 17317index 000000000..31f13ff5f 17318--- /dev/null 17319+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.h 17320@@ -0,0 +1,69 @@ 17321+/* 17322+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 17323+ * Description: Hisilicon DRM driver 17324+ * Author: Hisilicon multimedia software group 17325+ * Create: 2020-7-29 17326+ */ 17327+ 17328+#ifndef __HI_ADP_CRTC_H__ 17329+#define __HI_ADP_CRTC_H__ 17330+ 17331+#include <drm/drm_crtc.h> 17332+#include <drm/drm_mode.h> 17333+#include "drm_hal_common.h" 17334+#include "hi_comm_vo_adapt.h" 17335+ 17336+#define HI_DRM_MAX_CRTC_NUM 2 17337+#define HI_DRM_MAX_PRIMARY_NUM 2 17338+#define HI_DRM_MAX_OVERLAY_NUM 2 17339+ 17340+enum hi_adp_crtc_event { 17341+ HI_ADP_CRTC_VBLANK, 17342+}; 17343+ 17344+struct hi_adp_crtc_cap { 17345+ int crtc_num; 17346+}; 17347+ 17348+int hi_adp_crtc_init(void); 17349+ 17350+void hi_adp_crtc_deinit(void); 17351+ 17352+void hi_adp_crtc_get_cap(struct hi_adp_crtc_cap *cap); 17353+ 17354+int hi_adp_plane_get_by_index(struct drm_crtc *crtc, struct drm_plane **plane, enum drm_plane_type type, int index); 17355+ 17356+int hi_adp_plane_open(struct drm_plane *plane); 17357+ 17358+int hi_adp_plane_close(struct drm_plane *plane); 17359+ 17360+void hi_adp_plane_update(struct drm_plane *plane); 17361+ 17362+int hi_adp_crtc_get_by_index(struct drm_crtc **crtc, int index); 17363+ 17364+int hi_adp_crtc_open(struct drm_crtc *crtc); 17365+ 17366+int hi_adp_crtc_close(struct drm_crtc *crtc); 17367+ 17368+int hi_adp_crtc_set_mode(struct drm_crtc *crtc, const struct drm_display_mode *mode); 17369+ 17370+int hi_adp_crtc_add_user_intf(struct drm_crtc *crtc); 17371+ 17372+int hi_adp_crtc_add_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id); 17373+ 17374+int hi_adp_crtc_del_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id); 17375+ 17376+int hi_adp_crtc_add_user_intf_sync(struct drm_crtc *crtc, hi_vo_user_intfsync_info *intf_sync_attr, 17377+ unsigned int intf_id); 17378+ 17379+typedef int (*adp_crtc_callback)(struct drm_crtc *crtc, enum hi_adp_crtc_event event, void *para); 17380+ 17381+int hi_adp_crtc_reg_callback(struct drm_crtc *crtc, adp_crtc_callback cb); 17382+ 17383+void hi_adp_crtc_set_vblank(struct drm_crtc *crtc, bool enable); 17384+ 17385+enum drm_hal_timing_fmt hi_adp_crtc_timing_translate(struct drm_hal_timing *timing); 17386+ 17387+int hi_adp_plane_reset_csc(struct drm_plane *plane); 17388+ 17389+#endif /* __HI_ADP_CRTC_H__ */ 17390diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.c 17391new file mode 100644 17392index 000000000..7b72a0639 17393--- /dev/null 17394+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.c 17395@@ -0,0 +1,345 @@ 17396+/* 17397+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 17398+ * Description: Hisilicon DRM driver 17399+ * Author: Hisilicon multimedia software group 17400+ * Create: 2020-7-29 17401+ */ 17402+ 17403+#include "hi_adp_hdmitx.h" 17404+#include <linux/clk.h> 17405+#include <linux/component.h> 17406+#include <linux/of_address.h> 17407+#include <video/videomode.h> 17408+#include <drm/drm_atomic_helper.h> 17409+#include <drm/drm_crtc.h> 17410+#include <drm/drm_crtc_helper.h> 17411+#include <drm/drm_fb_cma_helper.h> 17412+#include <drm/drm_fb_helper.h> 17413+#include <drm/drm_gem_cma_helper.h> 17414+#include <drm/drm_of.h> 17415+#include <drm/drm_plane_helper.h> 17416+#include <drm/drm_util.h> 17417+#include "hi_drm_drv.h" 17418+#include "hi_adp_crtc.h" 17419+#include "drm_hal_common.h" 17420+#include "drm_hal_hdmitx.h" 17421+#include "drm_hal_display.h" 17422+#include "hi_drm_func_ext.h" 17423+ 17424+#define HI_DRM_MAX_EDID_NUM 10 17425+ 17426+struct hi_drm_hdmitx { 17427+ struct drm_connector conn; 17428+ struct drm_encoder encoder; 17429+ 17430+ unsigned int drm_hdmi_id; 17431+ enum drm_hal_hdmitx_id hi_hdmi_id; 17432+ 17433+ unsigned int open; /* 0: close, 1: open */ 17434+ unsigned int enable; /* 0: disable, 1: enable */ 17435+}; 17436+ 17437+#define to_hi_hdmitx_by_conn(x) container_of(x, struct hi_drm_hdmitx, conn) 17438+#define to_hi_hdmitx_by_encoder(x) container_of(x, struct hi_drm_hdmitx, encoder) 17439+ 17440+struct hi_drm_hdmitx_global { 17441+ struct hi_drm_hdmitx hdmitx[HI_DRM_MAX_HDMI_NUM]; 17442+ struct drm_hal_hdmitx_dev *hdmi_dev; 17443+}; 17444+ 17445+static struct hi_drm_hdmitx_global *g_hi_hdmitx = NULL; 17446+ 17447+static struct drm_hal_hdmitx_dev* adp_hdmitx_get_intf_func(void) 17448+{ 17449+ int ret; 17450+ 17451+ if (g_hi_hdmitx->hdmi_dev != NULL) { 17452+ return g_hi_hdmitx->hdmi_dev; 17453+ } 17454+ 17455+ ret = drm_get_export_func(MOD_ID_HDMI, (hi_void **)&g_hi_hdmitx->hdmi_dev); 17456+ if (ret != HI_SUCCESS) { 17457+ return NULL; 17458+ } 17459+ 17460+ return (struct drm_hal_hdmitx_dev *)g_hi_hdmitx->hdmi_dev; 17461+} 17462+ 17463+static int hdmitx_channel_check_open(struct hi_drm_hdmitx *hdmitx) 17464+{ 17465+ int ret; 17466+ struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func(); 17467+ 17468+ HI_DRM_CHECK_PTR_RETURN(hdmitx); 17469+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev); 17470+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->open); 17471+ 17472+ if (hdmitx->open == 1) { 17473+ return 0; 17474+ } 17475+ 17476+ ret = hdmi_dev->open(hdmitx->hi_hdmi_id); 17477+ if (ret != 0) { 17478+ drm_hal_err("error, ret=%#x!\n", ret); 17479+ return ret; 17480+ } 17481+ hdmitx->open = 1; 17482+ return 0; 17483+} 17484+ 17485+static int hdmitx_channel_check_close(struct hi_drm_hdmitx *hdmitx) 17486+{ 17487+ int ret; 17488+ struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func(); 17489+ 17490+ HI_DRM_CHECK_PTR_RETURN(hdmitx); 17491+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev); 17492+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->close); 17493+ 17494+ if (hdmitx->open == 0) { 17495+ return 0; 17496+ } 17497+ 17498+ ret = hdmi_dev->close(hdmitx->hi_hdmi_id); 17499+ if (ret != 0) { 17500+ drm_hal_err("error, ret=%#x!\n", ret); 17501+ return ret; 17502+ } 17503+ hdmitx->open = 0; 17504+ return 0; 17505+} 17506+ 17507+static int hdmitx_channel_check_enable(struct hi_drm_hdmitx *hdmitx) 17508+{ 17509+ int ret; 17510+ struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func(); 17511+ 17512+ HI_DRM_CHECK_PTR_RETURN(hdmitx); 17513+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev); 17514+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->enable); 17515+ 17516+ if (hdmitx->enable == 1) { 17517+ return 0; 17518+ } 17519+ 17520+ ret = hdmi_dev->enable(hdmitx->hi_hdmi_id); 17521+ if (ret != 0) { 17522+ drm_hal_err("error, ret=%#x!\n", ret); 17523+ return ret; 17524+ } 17525+ hdmitx->enable = 1; 17526+ return 0; 17527+} 17528+ 17529+static int hdmitx_channel_check_disable(struct hi_drm_hdmitx *hdmitx) 17530+{ 17531+ int ret; 17532+ struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func(); 17533+ 17534+ HI_DRM_CHECK_PTR_RETURN(hdmitx); 17535+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev); 17536+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->disable); 17537+ 17538+ if (hdmitx->enable == 0) { 17539+ return 0; 17540+ } 17541+ 17542+ ret = hdmi_dev->disable(hdmitx->hi_hdmi_id); 17543+ if (ret != 0) { 17544+ drm_hal_err("error, ret=%#x!\n", ret); 17545+ return ret; 17546+ } 17547+ hdmitx->enable = 0; 17548+ return 0; 17549+} 17550+ 17551+int hi_adp_hdmitx_get_edid(struct drm_connector *conn, void *edid, int len) 17552+{ 17553+ int ret; 17554+ struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_conn(conn); 17555+ struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func(); 17556+ 17557+ HI_DRM_CHECK_PTR_RETURN(edid); 17558+ HI_DRM_CHECK_PTR_RETURN(hi_hdmitx); 17559+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev); 17560+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->read_edid); 17561+ 17562+ ret = hdmitx_channel_check_open(hi_hdmitx); 17563+ if (ret != 0) { 17564+ return ret; 17565+ } 17566+ 17567+ ret = hdmi_dev->read_edid(hi_hdmitx->hi_hdmi_id, edid, len); 17568+ if (ret <= 0) { 17569+ return -1; 17570+ } 17571+ return 0; 17572+} 17573+ 17574+enum drm_connector_status hi_adp_hdmitx_detect(struct drm_connector *conn, bool force) 17575+{ 17576+ int ret; 17577+ enum drm_hal_hdmitx_connect_status stat; 17578+ struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_conn(conn); 17579+ struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func(); 17580+ 17581+ HI_DRM_CHECK_PTR_RETURN(hi_hdmitx); 17582+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev); 17583+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->get_status); 17584+ 17585+ ret = hdmitx_channel_check_open(hi_hdmitx); 17586+ if (ret != 0) { 17587+ return ret; 17588+ } 17589+ 17590+ ret = hdmi_dev->get_status(hi_hdmitx->hi_hdmi_id, DRM_HAL_HDMITX_STAT_CONNECTOR, &stat); 17591+ if (ret != 0) { 17592+ return connector_status_unknown; 17593+ } 17594+ 17595+ HI_DRM_INFO("hdmitx status detected: %d\n", stat); 17596+ 17597+ switch (stat) { 17598+ case DRM_HAL_HDMITX_CONNECTED: 17599+ return connector_status_connected; 17600+ case DRM_HAL_HDMITX_DISCONNECTED: 17601+ return connector_status_disconnected; 17602+ case DRM_HAL_HDMITX_UNKNOWN: 17603+ return connector_status_unknown; 17604+ default: 17605+ return connector_status_unknown; 17606+ } 17607+ return connector_status_unknown; 17608+} 17609+ 17610+int hi_adp_hdmitx_enable(struct drm_encoder *encoder) 17611+{ 17612+ int ret; 17613+ struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_encoder(encoder); 17614+ 17615+ HI_DRM_CHECK_PTR_RETURN(hi_hdmitx); 17616+ 17617+ ret = hdmitx_channel_check_open(hi_hdmitx); 17618+ if (ret != 0) { 17619+ return ret; 17620+ } 17621+ 17622+ ret = hdmitx_channel_check_enable(hi_hdmitx); 17623+ if (ret != 0) { 17624+ goto err_check_close; 17625+ } 17626+ return 0; 17627+err_check_close: 17628+ hdmitx_channel_check_close(hi_hdmitx); 17629+ return ret; 17630+} 17631+ 17632+int hi_adp_hdmitx_disable(struct drm_encoder *encoder) 17633+{ 17634+ int ret; 17635+ struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_encoder(encoder); 17636+ 17637+ HI_DRM_CHECK_PTR_RETURN(hi_hdmitx); 17638+ 17639+ ret = hdmitx_channel_check_disable(hi_hdmitx); 17640+ if (ret != 0) { 17641+ return ret; 17642+ } 17643+ 17644+ ret = hdmitx_channel_check_close(hi_hdmitx); 17645+ if (ret != 0) { 17646+ return ret; 17647+ } 17648+ return 0; 17649+} 17650+ 17651+int hi_adp_hdmitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode, 17652+ struct drm_connector_state *conn_state) 17653+{ 17654+ int ret; 17655+ struct drm_hal_hdmitx_attr hdmi_attr = {0}; 17656+ struct drm_hal_timing timing; 17657+ struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_encoder(encoder); 17658+ struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func(); 17659+ 17660+ HI_DRM_CHECK_PTR_RETURN(hi_hdmitx); 17661+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev); 17662+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->get_attr); 17663+ HI_DRM_CHECK_PTR_RETURN(hdmi_dev->set_attr); 17664+ 17665+ ret = hdmitx_channel_check_open(hi_hdmitx); 17666+ if (ret != 0) { 17667+ return ret; 17668+ } 17669+ 17670+ if (hi_hdmitx->enable == 1) { 17671+ return 0; 17672+ } 17673+ 17674+ /* dispatch the mode to the connected crtc */ 17675+ ret = hi_adp_crtc_set_mode(conn_state->crtc, mode); 17676+ if (ret != 0) { 17677+ drm_hal_err("error, ret=%#x!\n", ret); 17678+ } 17679+ 17680+ /* attach the interface to crtc */ 17681+ ret = hi_adp_crtc_add_intf(conn_state->crtc, DRM_HAL_DISP_INTF_HDMITX, hi_hdmitx->hi_hdmi_id); 17682+ if (ret != 0) { 17683+ drm_hal_err("error, ret=%#x!\n", ret); 17684+ } 17685+ 17686+ ret = hdmi_dev->get_attr(hi_hdmitx->hi_hdmi_id, &hdmi_attr); 17687+ if (ret != 0) { 17688+ drm_hal_err("error, ret=%#x!\n", ret); 17689+ } 17690+ 17691+ timing.clock = mode->clock; 17692+ timing.hdisplay = mode->hdisplay; 17693+ timing.hskew = mode->hskew; 17694+ timing.hsync_end = mode->hsync_end; 17695+ timing.hsync_start = mode->hsync_start; 17696+ timing.htotal = mode->htotal; 17697+ timing.vdisplay = mode->vdisplay; 17698+ timing.vscan = mode->vscan; 17699+ timing.vsync_end = mode->vsync_end; 17700+ timing.vsync_start = mode->vsync_start; 17701+ timing.vtotal = mode->vtotal; 17702+ hdmi_attr.fmt = hi_adp_crtc_timing_translate(&timing); 17703+ ret = hdmi_dev->set_attr(hi_hdmitx->hi_hdmi_id, &hdmi_attr); 17704+ if (ret != 0) { 17705+ drm_hal_err("error, ret=%#x!\n", ret); 17706+ } 17707+ return 0; 17708+} 17709+ 17710+int hi_adp_hdmitx_get_by_index(unsigned int drm_hdmi_id, struct drm_connector **conn, struct drm_encoder **encoder) 17711+{ 17712+ HI_DRM_CHECK_PTR_RETURN(g_hi_hdmitx); 17713+ 17714+ /* only support 1xHDMI yet */ 17715+ if (drm_hdmi_id != DRM_MODE_CONNECTOR_HDMIA) { 17716+ return -1; 17717+ } 17718+ 17719+ g_hi_hdmitx->hdmitx[0].drm_hdmi_id = drm_hdmi_id; 17720+ g_hi_hdmitx->hdmitx[0].hi_hdmi_id = DRM_HAL_HDMITX_0; 17721+ *conn = &g_hi_hdmitx->hdmitx[0].conn; 17722+ *encoder = &g_hi_hdmitx->hdmitx[0].encoder; 17723+ return 0; 17724+} 17725+ 17726+int hi_adp_hdmitx_init(void) 17727+{ 17728+ g_hi_hdmitx = kzalloc(sizeof(struct hi_drm_hdmitx_global), GFP_KERNEL); 17729+ if (g_hi_hdmitx == NULL) { 17730+ return -ENOMEM; 17731+ } 17732+ 17733+ return 0; 17734+} 17735+ 17736+void hi_adp_hdmitx_deinit(void) 17737+{ 17738+ kfree(g_hi_hdmitx); 17739+ g_hi_hdmitx = NULL; 17740+} 17741diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.h 17742new file mode 100644 17743index 000000000..4c7f08883 17744--- /dev/null 17745+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.h 17746@@ -0,0 +1,28 @@ 17747+/* 17748+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 17749+ * Description: Hisilicon DRM driver 17750+ * Author: Hisilicon multimedia software group 17751+ * Create: 2020-7-29 17752+ */ 17753+ 17754+#ifndef __HI_ADP_HDMITX_H__ 17755+#define __HI_ADP_HDMITX_H__ 17756+ 17757+#include <drm/drm_connector.h> 17758+#include <drm/drm_encoder.h> 17759+#include <drm/drm_modes.h> 17760+ 17761+#define HI_DRM_MAX_HDMI_NUM 2 17762+ 17763+int hi_adp_hdmitx_init(void); 17764+void hi_adp_hdmitx_deinit(void); 17765+int hi_adp_hdmitx_get_by_index(unsigned int drm_hdmi_id, struct drm_connector **conn, struct drm_encoder **encoder); 17766+int hi_adp_hdmitx_get_edid(struct drm_connector *conn, void *edid, int len); 17767+enum drm_connector_status hi_adp_hdmitx_detect(struct drm_connector *conn, bool force); 17768+int hi_adp_hdmitx_enable(struct drm_encoder *encoder); 17769+int hi_adp_hdmitx_disable(struct drm_encoder *encoder); 17770+int hi_adp_hdmitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode, 17771+ struct drm_connector_state *conn_state); 17772+ 17773+#endif /* __HI_ADP_HDMITX_H__ */ 17774+ 17775diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.c 17776new file mode 100755 17777index 000000000..1902f1e8f 17778--- /dev/null 17779+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.c 17780@@ -0,0 +1,300 @@ 17781+/* 17782+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 17783+ * Description: Hisilicon DRM driver 17784+ * Author: Hisilicon multimedia software group 17785+ * Create: 2020-7-29 17786+ */ 17787+ 17788+#include "hi_adp_mipitx.h" 17789+#include <linux/clk.h> 17790+#include <linux/component.h> 17791+#include <linux/of_address.h> 17792+#include <video/videomode.h> 17793+#include <drm/drm_atomic_helper.h> 17794+#include <drm/drm_crtc.h> 17795+#include <drm/drm_crtc_helper.h> 17796+#include <drm/drm_fb_cma_helper.h> 17797+#include <drm/drm_fb_helper.h> 17798+#include <drm/drm_gem_cma_helper.h> 17799+#include <drm/drm_of.h> 17800+#include <drm/drm_plane_helper.h> 17801+#include <drm/drm_util.h> 17802+#include <drm/drm_panel.h> 17803+#include "hi_drm_drv.h" 17804+#include "hi_adp_crtc.h" 17805+#include "drm_hal_mipitx.h" 17806+#include "drm_hal_display.h" 17807+ 17808+#define MIPI_PHYSICAL_WIDTH 60 17809+#define MIPI_PHYSICAL_HEIGHT 120 17810+#define BRIGHTNESS_MAX 255 17811+#define DEFAULT_BRIGHTNESS 255 17812+ 17813+struct ext_drm_tv_property { 17814+ struct drm_property *tv_brightness_property; 17815+}; 17816+ 17817+struct hi_drm_mipitx { 17818+ struct drm_connector conn; 17819+ struct drm_encoder encoder; 17820+ 17821+ unsigned int drm_mipi_id; 17822+ unsigned int enable; /* 0: disable, 1: enable */ 17823+ struct ext_drm_tv_property private; 17824+}; 17825+ 17826+#define to_hi_mipitx_by_conn(x) container_of(x, struct hi_drm_mipitx, conn) 17827+#define to_hi_mipitx_by_encoder(x) container_of(x, struct hi_drm_mipitx, encoder) 17828+ 17829+struct hi_drm_mipitx_global { 17830+ struct hi_drm_mipitx mipitx; 17831+ struct DispOperations *mipi_dev; 17832+}; 17833+ 17834+static struct drm_display_mode default_mode = { 17835+ .clock = 155493, /* 155493 khz */ 17836+ .hdisplay = 480, /* 480 width */ 17837+ .hsync_start = 480 + 48, /* 480 48 alg data */ 17838+ .hsync_end = 480 + 48 + 32, /* 480 48 32 alg data */ 17839+ .htotal = 480 + 48 + 32 + 60, /* 480 48 32 60 alg data */ 17840+ .vdisplay = 960, /* 960 height */ 17841+ .vsync_start = 960 + 3, /* 960 3 alg data */ 17842+ .vsync_end = 960 + 3 + 5, /* 960 3 5 alg data */ 17843+ .vtotal = 960 + 3 + 5 + 6, /* 960 3 5 6 alg data */ 17844+ .flags = 0, /* 0 alg data */ 17845+}; 17846+ 17847+static struct hi_drm_mipitx_global *g_hi_mipitx = NULL; 17848+ 17849+static struct DispOperations *adp_get_mipitx_func(void) 17850+{ 17851+ int ret; 17852+ 17853+ if (g_hi_mipitx->mipi_dev != NULL) { 17854+ return g_hi_mipitx->mipi_dev; 17855+ } 17856+ 17857+ ///TODO: 17858+ g_hi_mipitx->mipi_dev = GetDispOps(); 17859+ if (IS_ERR_OR_NULL(g_hi_mipitx->mipi_dev) || IS_ERR_OR_NULL(g_hi_mipitx->mipi_dev->init)) { 17860+ drm_hal_err("error, ret=%#x!\n", ret); 17861+ return NULL; 17862+ } 17863+ 17864+ ret = g_hi_mipitx->mipi_dev->init(DRM_HAL_GFX_G0); 17865+ if (ret != 0) { 17866+ drm_hal_err("error, ret=%#x!\n", ret); 17867+ return NULL; 17868+ } 17869+ 17870+ return (struct DispOperations *)g_hi_mipitx->mipi_dev; 17871+} 17872+ 17873+ 17874+int hi_adp_mipitx_get_modes(struct drm_connector *connector) 17875+{ 17876+ struct drm_display_mode *mode; 17877+ mode = drm_mode_duplicate(connector->dev, &default_mode); 17878+ if (mode == NULL) { 17879+ drm_hal_err("drm_mode_duplicate failure!\n"); 17880+ return -ENOMEM; 17881+ } 17882+ drm_mode_set_name(mode); 17883+ drm_mode_probed_add(connector, mode); 17884+ connector->display_info.width_mm = MIPI_PHYSICAL_WIDTH; 17885+ connector->display_info.height_mm = MIPI_PHYSICAL_HEIGHT; 17886+ return 1; 17887+} 17888+ 17889+int hi_adp_mipitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode, 17890+ struct drm_connector_state *conn_state) 17891+{ 17892+ int ret; 17893+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_encoder(encoder); 17894+ 17895+ HI_DRM_CHECK_PTR_RETURN(hi_mipitx); 17896+ 17897+ if (hi_mipitx->enable == 1) { 17898+ return 0; 17899+ } 17900+ 17901+ ret = hi_adp_crtc_add_user_intf(conn_state->crtc); 17902+ if (ret != 0) { 17903+ return ret; 17904+ } 17905+ /* dispatch the mode to the connected crtc */ 17906+ ret = hi_adp_crtc_set_mode(conn_state->crtc, mode); 17907+ if (ret != 0) { 17908+ drm_hal_err("error, ret=%#x!\n", ret); 17909+ } 17910+ 17911+ /* attach the interface to crtc */ 17912+ ret = hi_adp_crtc_add_intf(conn_state->crtc, DRM_HAL_DISP_INTF_MIPITX, hi_mipitx->drm_mipi_id); 17913+ if (ret != 0) { 17914+ drm_hal_err("error, ret=%#x!\n", ret); 17915+ } 17916+ 17917+ return 0; 17918+} 17919+ 17920+int hi_adp_mipitx_enable(struct drm_encoder *encoder) 17921+{ 17922+ int ret; 17923+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_encoder(encoder); 17924+ struct DispOperations *mipi_dev = adp_get_mipitx_func(); 17925+ HI_DRM_CHECK_PTR_RETURN(hi_mipitx); 17926+ HI_DRM_CHECK_PTR_RETURN(mipi_dev); 17927+ HI_DRM_CHECK_PTR_RETURN(mipi_dev->setBacklight); 17928+ 17929+ if (hi_mipitx->enable == 1) { 17930+ return 0; 17931+ } 17932+ 17933+ ret = mipi_dev->on(DRM_HAL_GFX_G0); 17934+ if (ret != 0) { 17935+ drm_hal_err("error, ret=%#x!\n", ret); 17936+ return ret; 17937+ } 17938+ 17939+ hi_mipitx->enable = 1; 17940+ return 0; 17941+} 17942+ 17943+int hi_adp_mipitx_disable(struct drm_encoder *encoder) 17944+{ 17945+ int ret; 17946+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_encoder(encoder); 17947+ struct DispOperations *mipi_dev = adp_get_mipitx_func(); 17948+ 17949+ HI_DRM_CHECK_PTR_RETURN(hi_mipitx); 17950+ HI_DRM_CHECK_PTR_RETURN(mipi_dev); 17951+ HI_DRM_CHECK_PTR_RETURN(mipi_dev->off); 17952+ 17953+ if (hi_mipitx->enable == 0) { 17954+ return 0; 17955+ } 17956+ 17957+ ret = mipi_dev->off(DRM_HAL_GFX_G0); 17958+ if (ret != 0) { 17959+ drm_hal_err("error, ret=%#x!\n", ret); 17960+ return ret; 17961+ } 17962+ 17963+ hi_mipitx->enable = 0; 17964+ return 0; 17965+} 17966+ 17967+int adp_conn_atomic_set_property(struct drm_connector *connector, struct drm_connector_state *state, 17968+ struct drm_property *property, uint64_t val) 17969+{ 17970+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector); 17971+ if (property == hi_mipitx->private.tv_brightness_property) { 17972+ state->tv.brightness = val; 17973+ } else { 17974+ HI_DRM_ERR("[CONNECTOR:%d:%s] unknown property [PROP:%d%s]\n", connector->base.id, 17975+ connector->name, property->base.id, property->name); 17976+ return -EINVAL; 17977+ } 17978+ return 0; 17979+} 17980+ 17981+int adp_conn_atomic_get_property(struct drm_connector *connector, const struct drm_connector_state *state, 17982+ struct drm_property *property, uint64_t *val) 17983+{ 17984+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector); 17985+ 17986+ if (property == hi_mipitx->private.tv_brightness_property) { 17987+ *val = state->tv.brightness; 17988+ } else { 17989+ HI_DRM_ERR("[CONNECTOR:%d:%s] unknown property [PROP:%d%s]\n", connector->base.id, 17990+ connector->name, property->base.id, property->name); 17991+ return -EINVAL; 17992+ } 17993+ return 0; 17994+} 17995+ 17996+int adp_mipi_set_brightness(struct drm_connector *connector,uint32_t brightness) 17997+{ 17998+ int ret; 17999+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector); 18000+ struct DispOperations *mipi_dev = adp_get_mipitx_func(); 18001+ 18002+ HI_DRM_CHECK_PTR_RETURN(hi_mipitx); 18003+ HI_DRM_CHECK_PTR_RETURN(mipi_dev); 18004+ HI_DRM_CHECK_PTR_RETURN(mipi_dev->setBacklight); 18005+ if (connector == NULL) { 18006+ return 0; 18007+ } 18008+ if (brightness < 0 || brightness >255) { 18009+ HI_DRM_INFO("brightness value out of range[0~255]!"); 18010+ return 0; 18011+ } 18012+ ret = mipi_dev->setBacklight(DRM_HAL_GFX_G0, brightness); 18013+ if (ret != 0) { 18014+ drm_hal_err("error, ret = %#x!\n", ret); 18015+ return ret; 18016+ } 18017+ return 0; 18018+} 18019+ 18020+int adp_conn_private_properties_init(struct drm_device *dev, struct drm_connector *connector) 18021+{ 18022+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector); 18023+ 18024+ hi_mipitx->private.tv_brightness_property = drm_property_create_range(dev, 0, "brightness", 0, BRIGHTNESS_MAX); 18025+ if (hi_mipitx->private.tv_brightness_property == NULL) { 18026+ HI_DRM_ERR("tv_brightness_property create error\n"); 18027+ return -ENOMEM; 18028+ } 18029+ drm_object_attach_property(&connector->base, hi_mipitx->private.tv_brightness_property, DEFAULT_BRIGHTNESS); 18030+ return 0; 18031+} 18032+ 18033+void adp_conn_private_properties_deinit(struct drm_device *dev, struct drm_connector *connector) 18034+{ 18035+ struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector); 18036+ 18037+ if (hi_mipitx->private.tv_brightness_property != NULL) { 18038+ drm_property_destroy(dev, hi_mipitx->private.tv_brightness_property); 18039+ hi_mipitx->private.tv_brightness_property = NULL; 18040+ } 18041+ return; 18042+} 18043+ 18044+int hi_adp_mipitx_get_by_index(unsigned int drm_mipi_id, struct drm_connector **conn, struct drm_encoder **encoder) 18045+{ 18046+ HI_DRM_CHECK_PTR_RETURN(g_hi_mipitx); 18047+ 18048+ if (drm_mipi_id != DRM_MODE_CONNECTOR_DSI) { 18049+ return -1; 18050+ } 18051+ 18052+ g_hi_mipitx->mipitx.drm_mipi_id = drm_mipi_id; 18053+ *conn = &g_hi_mipitx->mipitx.conn; 18054+ *encoder = &g_hi_mipitx->mipitx.encoder; 18055+ 18056+ return 0; 18057+} 18058+ 18059+int hi_adp_mipitx_init(void) 18060+{ 18061+ int ret = -1; 18062+ g_hi_mipitx = kzalloc(sizeof(struct hi_drm_mipitx_global), GFP_KERNEL); 18063+ if (g_hi_mipitx == NULL) { 18064+ drm_hal_err("error, ret=%#x!\n", ret); 18065+ return -ENOMEM; 18066+ } 18067+ 18068+ return 0; 18069+} 18070+ 18071+void hi_adp_mipitx_deinit(void) 18072+{ 18073+ if (IS_ERR_OR_NULL(g_hi_mipitx)) { 18074+ return; 18075+ } 18076+ 18077+ kfree(g_hi_mipitx); 18078+ g_hi_mipitx = NULL; 18079+} 18080+ 18081diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.h 18082new file mode 100644 18083index 000000000..a006da477 18084--- /dev/null 18085+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.h 18086@@ -0,0 +1,32 @@ 18087+/* 18088+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 18089+ * Description: Hisilicon DRM driver 18090+ * Author: Hisilicon multimedia software group 18091+ * Create: 2020-7-29 18092+ */ 18093+ 18094+#ifndef __HI_ADP_MIPITX_H__ 18095+#define __HI_ADP_MIPITX_H__ 18096+ 18097+#include <drm/drm_connector.h> 18098+#include <drm/drm_encoder.h> 18099+ 18100+int hi_adp_mipitx_init(void); 18101+void hi_adp_mipitx_deinit(void); 18102+int hi_adp_mipitx_get_by_index(unsigned int drm_mipi_id, struct drm_connector **conn, struct drm_encoder **encoder); 18103+int hi_adp_mipitx_enable(struct drm_encoder *encoder); 18104+int hi_adp_mipitx_disable(struct drm_encoder *encoder); 18105+int hi_adp_mipitx_get_modes(struct drm_connector *connector); 18106+int hi_adp_mipitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode, 18107+ struct drm_connector_state *conn_state); 18108+ 18109+int adp_conn_private_properties_init(struct drm_device *dev, struct drm_connector *connector); 18110+void adp_conn_private_properties_deinit(struct drm_device *dev, struct drm_connector *connector); 18111+int adp_conn_atomic_set_property(struct drm_connector *connector, struct drm_connector_state *state, 18112+ struct drm_property *property, uint64_t val); 18113+int adp_conn_atomic_get_property(struct drm_connector *connector, const struct drm_connector_state *state, 18114+ struct drm_property *property, uint64_t *val); 18115+int adp_mipi_set_brightness(struct drm_connector *connector,uint32_t brightness); 18116+ 18117+#endif /* __HI_ADP_MIPITX_H__ */ 18118+ 18119diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.c 18120new file mode 100755 18121index 000000000..ee41abf3b 18122--- /dev/null 18123+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.c 18124@@ -0,0 +1,389 @@ 18125+/* 18126+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 18127+ * Description: Hisilicon DRM driver 18128+ * Author: Hisilicon multimedia software group 18129+ * Create: 2020-7-29 18130+ */ 18131+ 18132+#include "hi_drm_crtc.h" 18133+#include <linux/clk.h> 18134+#include <linux/component.h> 18135+#include <linux/of_address.h> 18136+#include <video/videomode.h> 18137+#include <drm/drm_atomic_helper.h> 18138+#include <drm/drm_crtc.h> 18139+#include <drm/drm_crtc_helper.h> 18140+#include <drm/drm_gem_cma_helper.h> 18141+#include <drm/drm_of.h> 18142+#include <drm/drm_plane_helper.h> 18143+#include <drm/drm_util.h> 18144+#include <drm/drm_vblank.h> 18145+#include "hi_drm_drv.h" 18146+#include "hi_adp_crtc.h" 18147+ 18148+static const uint32_t hi_graphics_formats[] = { 18149+ DRM_FORMAT_ARGB8888, 18150+ DRM_FORMAT_XRGB8888, 18151+ DRM_FORMAT_RGB888, 18152+ DRM_FORMAT_RGB565, 18153+ DRM_FORMAT_ARGB1555, 18154+ DRM_FORMAT_ARGB4444, 18155+}; 18156+ 18157+static int hi_drm_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) 18158+{ 18159+ int ret; 18160+ HI_DRM_FUNC_ENTER(); 18161+ /* open the plane at the begining */ 18162+ ret = hi_adp_plane_open(plane); 18163+ if (ret != 0) { 18164+ HI_DRM_ERR("hi_adp_plane_open err, ret=%#x\n", ret); 18165+ return ret; 18166+ } 18167+ 18168+ /* 18169+ * 1. after open gfx,default csc is RGB to YUV 18170+ * 2. hdmi use default csc 18171+ * 3. mipi close csc 18172+ */ 18173+ ret = hi_adp_plane_reset_csc(plane); 18174+ if (ret != 0) { 18175+ HI_DRM_ERR("hi_adp_plane_reset_csc err, ret=%#x\n", ret); 18176+ return ret; 18177+ } 18178+ 18179+ HI_DRM_FUNC_EXIT(); 18180+ return 0; 18181+} 18182+ 18183+static void hi_drm_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) 18184+{ 18185+ HI_DRM_FUNC_ENTER(); 18186+ hi_adp_plane_update(plane); 18187+ HI_DRM_FUNC_EXIT(); 18188+} 18189+ 18190+static const struct drm_plane_helper_funcs hi_drm_plane_helper_funcs = { 18191+ .atomic_check = hi_drm_plane_atomic_check, 18192+ .atomic_update = hi_drm_plane_atomic_update, 18193+}; 18194+ 18195+static void hi_drm_plane_destroy(struct drm_plane *plane) 18196+{ 18197+ int ret; 18198+ HI_DRM_FUNC_ENTER(); 18199+ ret = hi_adp_plane_close(plane); 18200+ if (ret != 0) { 18201+ HI_DRM_ERR("hi_adp_plane_close err, ret=%#x\n", ret); 18202+ } 18203+ drm_plane_cleanup(plane); 18204+ HI_DRM_FUNC_EXIT(); 18205+} 18206+ 18207+static const struct drm_plane_funcs hi_drm_plane_funcs = { 18208+ .update_plane = drm_atomic_helper_update_plane, 18209+ .disable_plane = drm_atomic_helper_disable_plane, 18210+ .destroy = hi_drm_plane_destroy, 18211+ .reset = drm_atomic_helper_plane_reset, 18212+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 18213+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 18214+}; 18215+ 18216+static int hi_drm_plane_init(struct drm_device *drm, struct drm_plane *plane, uint32_t possible_crtcs) 18217+{ 18218+ int ret; 18219+ HI_DRM_FUNC_ENTER(); 18220+ ret = drm_universal_plane_init(drm, plane, possible_crtcs, &hi_drm_plane_funcs, hi_graphics_formats, 18221+ ARRAY_SIZE(hi_graphics_formats), NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 18222+ if (ret != 0) { 18223+ HI_DRM_ERR("drm_universal_plane_init err, ret=%#x\n", ret); 18224+ return ret; 18225+ } 18226+ drm_plane_helper_add(plane, &hi_drm_plane_helper_funcs); 18227+ HI_DRM_FUNC_EXIT(); 18228+ return 0; 18229+} 18230+ 18231+static void hi_drm_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) 18232+{ 18233+ int ret; 18234+ HI_DRM_FUNC_ENTER(); 18235+ ret = hi_adp_crtc_open(crtc); 18236+ if (ret != 0) { 18237+ HI_DRM_ERR("hi_adp_crtc_open error, ret = %#x\n", ret); 18238+ return; 18239+ } 18240+ drm_crtc_vblank_on(crtc); 18241+ HI_DRM_FUNC_EXIT(); 18242+} 18243+ 18244+static void hi_drm_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) 18245+{ 18246+ int ret; 18247+ HI_DRM_FUNC_ENTER(); 18248+ ret = hi_adp_crtc_close(crtc); 18249+ if (ret != 0) { 18250+ HI_DRM_ERR("hi_adp_crtc_close err, ret=%#x\n", ret); 18251+ return; 18252+ } 18253+ drm_crtc_vblank_off(crtc); 18254+ HI_DRM_FUNC_EXIT(); 18255+} 18256+ 18257+static void hi_drm_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) 18258+{ 18259+ struct drm_pending_vblank_event *event = crtc->state->event; 18260+ HI_DRM_FUNC_ENTER(); 18261+ 18262+ if (event == NULL) { 18263+ return; 18264+ } 18265+ crtc->state->event = NULL; 18266+ spin_lock_irq(&crtc->dev->event_lock); 18267+ if (drm_crtc_vblank_get(crtc) == 0) { 18268+ drm_crtc_arm_vblank_event(crtc, event); 18269+ } else { 18270+ drm_crtc_send_vblank_event(crtc, event); 18271+ } 18272+ spin_unlock_irq(&crtc->dev->event_lock); 18273+ HI_DRM_FUNC_EXIT(); 18274+} 18275+ 18276+static bool hi_drm_crtc_mode_fixup(struct drm_crtc *crtc, 18277+ const struct drm_display_mode *mode, 18278+ struct drm_display_mode *adjusted_mode) 18279+{ 18280+ int ret; 18281+ HI_DRM_FUNC_ENTER(); 18282+ HI_DRM_INFO("mode: %d %d %d %d %d %d %d %d %d %d %d\n", 18283+ crtc->state->mode.clock, 18284+ crtc->state->mode.hdisplay, 18285+ crtc->state->mode.hsync_start, 18286+ crtc->state->mode.hsync_end, 18287+ crtc->state->mode.htotal, 18288+ crtc->state->mode.hskew, 18289+ crtc->state->mode.vdisplay, 18290+ crtc->state->mode.vsync_start, 18291+ crtc->state->mode.vsync_end, 18292+ crtc->state->mode.vtotal, 18293+ crtc->state->mode.vscan); 18294+ 18295+ HI_DRM_INFO("mode: %d %d %d %d %d %d %d %d %d %d %d\n", 18296+ mode->clock, 18297+ mode->hdisplay, 18298+ mode->hsync_start, 18299+ mode->hsync_end, 18300+ mode->htotal, 18301+ mode->hskew, 18302+ mode->vdisplay, 18303+ mode->vsync_start, 18304+ mode->vsync_end, 18305+ mode->vtotal, 18306+ mode->vscan); 18307+ ret = hi_adp_crtc_set_mode(crtc, mode); 18308+ if (ret != 0) { 18309+ HI_DRM_ERR("hi_adp_crtc_set_mode err, ret=%#x\n", ret); 18310+ } 18311+ HI_DRM_FUNC_EXIT(); 18312+ return true; 18313+} 18314+ 18315+static void hi_drm_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) 18316+{ 18317+ HI_DRM_FUNC_ENTER(); 18318+ HI_DRM_FUNC_EXIT(); 18319+ return; 18320+} 18321+ 18322+static const struct drm_crtc_helper_funcs hi_drm_crtc_helper_funcs = { 18323+ .mode_fixup = hi_drm_crtc_mode_fixup, 18324+ .atomic_enable = hi_drm_crtc_atomic_enable, 18325+ .atomic_disable = hi_drm_crtc_atomic_disable, 18326+ .atomic_begin = hi_drm_crtc_atomic_begin, 18327+ .atomic_flush = hi_drm_crtc_atomic_flush, 18328+}; 18329+ 18330+int hi_drm_crtc_callback(struct drm_crtc *crtc, enum hi_adp_crtc_event event, void *para) 18331+{ 18332+ if (event != HI_ADP_CRTC_VBLANK) { 18333+ return -1; 18334+ } 18335+ 18336+ if (drm_crtc_handle_vblank(crtc) != true) { 18337+ return -1; 18338+ } 18339+ return 0; 18340+} 18341+ 18342+static int hi_drm_crtc_enable_vblank(struct drm_crtc *crtc) 18343+{ 18344+ int ret; 18345+ HI_DRM_FUNC_ENTER(); 18346+ 18347+ ret = hi_adp_crtc_reg_callback(crtc, hi_drm_crtc_callback); 18348+ if (ret != 0) { 18349+ return ret; 18350+ } 18351+ 18352+ hi_adp_crtc_set_vblank(crtc, true); 18353+ 18354+ HI_DRM_FUNC_EXIT(); 18355+ 18356+ return 0; 18357+} 18358+ 18359+static void hi_drm_crtc_disable_vblank(struct drm_crtc *crtc) 18360+{ 18361+ HI_DRM_FUNC_ENTER(); 18362+ 18363+ hi_adp_crtc_set_vblank(crtc, false); 18364+ 18365+ hi_adp_crtc_reg_callback(crtc, NULL); 18366+ 18367+ HI_DRM_FUNC_EXIT(); 18368+} 18369+ 18370+static void hi_drm_crtc_destroy(struct drm_crtc *crtc) 18371+{ 18372+ int ret; 18373+ 18374+ HI_DRM_FUNC_ENTER(); 18375+ /* ensure the crtc closed in the final cleanup call */ 18376+ ret = hi_adp_crtc_close(crtc); 18377+ if (ret != 0) { 18378+ HI_DRM_ERR("hi_adp_crtc_close err, ret=%#x\n", ret); 18379+ } 18380+ drm_crtc_cleanup(crtc); 18381+ HI_DRM_FUNC_EXIT(); 18382+} 18383+ 18384+static const struct drm_crtc_funcs hi_drm_crtc_funcs = { 18385+ .set_config = drm_atomic_helper_set_config, 18386+ .page_flip = drm_atomic_helper_page_flip, 18387+ .destroy = hi_drm_crtc_destroy, 18388+ .reset = drm_atomic_helper_crtc_reset, 18389+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 18390+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 18391+ .enable_vblank = hi_drm_crtc_enable_vblank, 18392+ .disable_vblank = hi_drm_crtc_disable_vblank, 18393+}; 18394+ 18395+static void hi_drm_crtc_init_by_index(struct drm_device *drm, int index) 18396+{ 18397+ int ret; 18398+ struct drm_plane *primary = NULL; 18399+ struct drm_crtc *crtc = NULL; 18400+ 18401+ HI_DRM_FUNC_ENTER(); 18402+ /* get the crtc resource */ 18403+ ret = hi_adp_crtc_get_by_index(&crtc, index); 18404+ if (ret != 0) { 18405+ HI_DRM_ERR("hi_adp_crtc_get_by_index err, ret=%#x\n", ret); 18406+ return; 18407+ } 18408+ 18409+ /* get the primary 0 plane on this crtc */ 18410+ ret = hi_adp_plane_get_by_index(crtc, &primary, DRM_PLANE_TYPE_PRIMARY, 0); 18411+ if (ret != 0) { 18412+ HI_DRM_ERR("hi_adp_plane_get_by_index err, ret=%#x\n", ret); 18413+ return; 18414+ } 18415+ 18416+ ret = hi_drm_plane_init(drm, primary, index + 1); 18417+ if (ret != 0) { 18418+ HI_DRM_ERR("hi_drm_plane_init err, ret=%#x\n", ret); 18419+ return; 18420+ } 18421+ 18422+ ret = drm_crtc_init_with_planes(drm, crtc, primary, NULL, &hi_drm_crtc_funcs, NULL); 18423+ if (ret != 0) { 18424+ HI_DRM_ERR("drm_crtc_init_with_planes error, ret = %#x\n", ret); 18425+ return; 18426+ } 18427+ drm_crtc_helper_add(crtc, &hi_drm_crtc_helper_funcs); 18428+ HI_DRM_INFO("crtc %p index %d, plane id %d\n", crtc, crtc->index, primary->index); 18429+ HI_DRM_FUNC_EXIT(); 18430+ return; 18431+} 18432+ 18433+static void hi_drm_crtc_cleanup_by_index(struct drm_device *drm, int index) 18434+{ 18435+ int ret; 18436+ struct drm_crtc *crtc = NULL; 18437+ 18438+ ret = hi_adp_crtc_get_by_index(&crtc, index); 18439+ if (ret != 0) { 18440+ HI_DRM_ERR("hi_adp_crtc_get_by_index err, ret=%#x\n", ret); 18441+ return; 18442+ } 18443+ hi_drm_plane_destroy(crtc->primary); 18444+ hi_drm_crtc_destroy(crtc); 18445+} 18446+ 18447+int hi_drm_crtc_init(struct drm_device *drm) 18448+{ 18449+ int ret; 18450+ int i; 18451+ struct hi_adp_crtc_cap cap; 18452+ 18453+ HI_DRM_FUNC_ENTER(); 18454+ ret = hi_adp_crtc_init(); 18455+ if (ret != 0) { 18456+ HI_DRM_ERR("hi_adp_crtc_init error, ret=%#x\n", ret); 18457+ return ret; 18458+ } 18459+ 18460+ hi_adp_crtc_get_cap(&cap); 18461+ 18462+ for (i = 0; i < cap.crtc_num; i++) { 18463+ hi_drm_crtc_init_by_index(drm, i); 18464+ } 18465+ HI_DRM_FUNC_EXIT(); 18466+ return 0; 18467+} 18468+ 18469+void hi_drm_crtc_cleanup(struct drm_device *drm) 18470+{ 18471+ int i; 18472+ struct hi_adp_crtc_cap cap; 18473+ 18474+ HI_DRM_FUNC_ENTER(); 18475+ hi_adp_crtc_get_cap(&cap); 18476+ for (i = 0; i < cap.crtc_num; i++) { 18477+ hi_drm_crtc_cleanup_by_index(drm, i); 18478+ } 18479+ hi_adp_crtc_deinit(); 18480+ HI_DRM_FUNC_EXIT(); 18481+} 18482+ 18483+void hi_drm_crtc_lastclose(struct drm_device *drm) 18484+{ 18485+ int ret; 18486+ int i; 18487+ int j; 18488+ struct hi_adp_crtc_cap cap; 18489+ struct drm_crtc *crtc = NULL; 18490+ struct drm_plane *plane = NULL; 18491+ 18492+ HI_DRM_FUNC_ENTER(); 18493+ 18494+ hi_adp_crtc_get_cap(&cap); 18495+ for (i = 0; i < cap.crtc_num; i++) { 18496+ ret = hi_adp_crtc_get_by_index(&crtc, i); 18497+ if (ret != 0) { 18498+ continue; 18499+ } 18500+ HI_DRM_INFO("now close the crtc, id=%d\n", i); 18501+ (void)hi_adp_crtc_close(crtc); 18502+ /* only support primary plane yet */ 18503+ for (j = 0; j < HI_DRM_MAX_PRIMARY_NUM; j++) { 18504+ ret = hi_adp_plane_get_by_index(crtc, &plane, DRM_PLANE_TYPE_PRIMARY, j); 18505+ if (ret != 0) { 18506+ continue; 18507+ } 18508+ HI_DRM_INFO("now close the plane, id=%d\n", j); 18509+ (void)hi_adp_plane_close(plane); 18510+ } 18511+ } 18512+ HI_DRM_FUNC_EXIT(); 18513+} 18514diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.h 18515new file mode 100644 18516index 000000000..ebe7aac6f 18517--- /dev/null 18518+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.h 18519@@ -0,0 +1,17 @@ 18520+/* 18521+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 18522+ * Description: Hisilicon DRM driver 18523+ * Author: Hisilicon multimedia software group 18524+ * Create: 2020-7-29 18525+ */ 18526+ 18527+#ifndef __HI_DRM_CTRC_H__ 18528+#define __HI_DRM_CTRC_H__ 18529+ 18530+#include <drm/drm_device.h> 18531+ 18532+int hi_drm_crtc_init(struct drm_device *drm); 18533+void hi_drm_crtc_cleanup(struct drm_device *drm); 18534+void hi_drm_crtc_lastclose(struct drm_device *drm); 18535+ 18536+#endif /* __HI_DRM_CTRC_H__ */ 18537diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.c 18538new file mode 100755 18539index 000000000..075cb248c 18540--- /dev/null 18541+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.c 18542@@ -0,0 +1,385 @@ 18543+/* 18544+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 18545+ * Description: Hisilicon DRM driver 18546+ * Author: Hisilicon multimedia software group 18547+ * Create: 2020-7-29 18548+ */ 18549+ 18550+#include "hi_drm_drv.h" 18551+#include <linux/clk.h> 18552+#include <linux/component.h> 18553+#include <linux/list.h> 18554+#include <linux/module.h> 18555+#include <linux/of_graph.h> 18556+#include <linux/of_platform.h> 18557+#include <linux/spinlock.h> 18558+#include <drm/drm_atomic_helper.h> 18559+#include <drm/drm_crtc.h> 18560+#include <drm/drm_crtc_helper.h> 18561+#include <drm/drm_gem_cma_helper.h> 18562+#include <drm/drm_of.h> 18563+#include <drm/drm_util.h> 18564+#include <drm/drm_gem_framebuffer_helper.h> 18565+#include <drm/drm_drv.h> 18566+#include <drm/drm_vblank.h> 18567+#include "hi_drm_crtc.h" 18568+#include "hi_drm_hdmitx.h" 18569+#include "hi_drm_mipitx.h" 18570+#include "hisilicon_drm.h" 18571+#include "osal_list.h" 18572+#include "hi_adp_mipitx.h" 18573+#define DRIVER_NAME "hisilicon" 18574+#define DRIVER_DESC "hisilicon Soc DRM" 18575+#define DRIVER_DATE "20200602" 18576+#define DRIVER_MAJOR 1 18577+#define DRIVER_MINOR 0 18578+ 18579+#define HI_DRM_MAX_WIDTH 8192 18580+#define HI_DRM_MAX_HEIGHT 8192 18581+ 18582+struct hi_drm_phys { 18583+ unsigned long long phys_addr; 18584+ unsigned long long size; 18585+ struct osal_list_head list; 18586+}; 18587+OSAL_LIST_HEAD(g_phys_addr); 18588+ 18589+static struct drm_device *drm_dev; 18590+ 18591+static const struct file_operations hi_drm_driver_fops = { 18592+ .owner = THIS_MODULE, 18593+ .open = drm_open, 18594+ .poll = drm_poll, 18595+ .read = drm_read, 18596+ .unlocked_ioctl = drm_ioctl, 18597+ .compat_ioctl = drm_compat_ioctl, 18598+ .release = drm_release, 18599+ .mmap = drm_gem_cma_mmap, 18600+}; 18601+ 18602+static void hi_drm_lastclose(struct drm_device *dev) 18603+{ 18604+ HI_DRM_INFO("=========== come to the last close! ===========\n"); 18605+ 18606+ hi_drm_crtc_lastclose(dev); 18607+} 18608+ 18609+static int hi_drm_get_prime_phyaddr(struct drm_device *dev, void *data, struct drm_file *file) 18610+{ 18611+ struct drm_hisilicon_phyaddr *arg = data; 18612+ struct drm_gem_object *gem_obj = NULL; 18613+ struct sg_table *sgt = NULL; 18614+ struct page *page = NULL; 18615+ int ret; 18616+ uint32_t handle = 0; 18617+ ret = drm_gem_prime_fd_to_handle(dev, file, arg->fd, &handle); 18618+ if (ret) { 18619+ HI_DRM_ERR("fd %d to handle failed", arg->fd); 18620+ return -1; 18621+ } 18622+ gem_obj = drm_gem_object_lookup(file, handle); 18623+ if (gem_obj == NULL) { 18624+ HI_DRM_ERR("gem object not finde fd %d, handle 0x%x", arg->fd, handle); 18625+ return -1; 18626+ } 18627+ sgt = drm_gem_cma_prime_get_sg_table(gem_obj); 18628+ if (sgt == NULL) { 18629+ HI_DRM_ERR("gem prime get sg_table failed"); 18630+ drm_gem_object_put(gem_obj); 18631+ return -1; 18632+ } 18633+ page = sg_page(sgt->sgl); 18634+ arg->phyaddr = PFN_PHYS(page_to_pfn(page)); 18635+ drm_gem_object_put(gem_obj); 18636+ return 0; 18637+} 18638+ 18639+static const struct drm_ioctl_desc hidrm_ioctls[] = { 18640+ DRM_IOCTL_DEF_DRV(HISILICON_GEM_FD_TO_PHYADDR, hi_drm_get_prime_phyaddr, DRM_UNLOCKED), 18641+}; 18642+ 18643+int drm_check_dumb_phy_addr(unsigned long long addr_start, unsigned long long size) 18644+{ 18645+ struct hi_drm_phys *p = NULL; 18646+ unsigned long long addr_end = addr_start + size; 18647+ unsigned long long temp_start, temp_end; 18648+ /* if address is valid */ 18649+ osal_list_for_each_entry(p, &g_phys_addr, list) { 18650+ temp_start = p->phys_addr; 18651+ temp_end = p->phys_addr + p->size; 18652+ if ((addr_start >= temp_start) && (addr_end <= temp_end)) { 18653+ return 0; 18654+ } 18655+ } 18656+ HI_DRM_ERR("drm_check_dumb_phy_addr, addr_start-addr_end [0x%llx-0x%llx]\n", addr_start, addr_end); 18657+ return -1; 18658+} 18659+EXPORT_SYMBOL(drm_check_dumb_phy_addr); 18660+ 18661+static int hi_drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_device *drm, 18662+ struct drm_mode_create_dumb *args) 18663+{ 18664+ int ret; 18665+ struct drm_gem_object *gem_obj = NULL; 18666+ struct sg_table *sgt = NULL; 18667+ struct page *page = NULL; 18668+ struct hi_drm_phys *node = NULL; 18669+ ret = drm_gem_cma_dumb_create(file_priv, drm, args); 18670+ if (ret != 0) { 18671+ return ret; 18672+ } 18673+ 18674+ node = kmalloc(sizeof(struct hi_drm_phys), GFP_KERNEL); 18675+ if (node == NULL) { 18676+ HI_DRM_ERR("kmalloc node failed\n"); 18677+ return 0; 18678+ } 18679+ (void)memset(node, 0, sizeof(struct hi_drm_phys)); 18680+ 18681+ /* get phyaddr and size */ 18682+ gem_obj = drm_gem_object_lookup(file_priv, args->handle); 18683+ if (gem_obj == NULL) { 18684+ HI_DRM_ERR("gem object not finde handle 0x%x", args->handle); 18685+ kfree(node); 18686+ return -1; 18687+ } 18688+ sgt = drm_gem_cma_prime_get_sg_table(gem_obj); 18689+ if (sgt == NULL) { 18690+ HI_DRM_ERR("gem prime get sg_table failed"); 18691+ drm_gem_object_put(gem_obj); 18692+ kfree(node); 18693+ return -1; 18694+ } 18695+ page = sg_page(sgt->sgl); 18696+ node->phys_addr = PFN_PHYS(page_to_pfn(page)); 18697+ node->size = args->size; 18698+ drm_gem_object_put(gem_obj); 18699+ osal_list_add(&node->list, &g_phys_addr); 18700+ return 0; 18701+} 18702+ 18703+static void hi_drm_gem_cma_free_object(struct drm_gem_object *gem_obj) 18704+{ 18705+ struct sg_table *sgt = NULL; 18706+ struct page *page = NULL; 18707+ struct hi_drm_phys *p = NULL; 18708+ unsigned long long phyaddr; 18709+ 18710+ sgt = drm_gem_cma_prime_get_sg_table(gem_obj); 18711+ if (sgt == NULL) { 18712+ HI_DRM_ERR("gem prime get sg_table failed"); 18713+ return; 18714+ } 18715+ page = sg_page(sgt->sgl); 18716+ phyaddr = PFN_PHYS(page_to_pfn(page)); 18717+ 18718+ drm_gem_cma_free_object(gem_obj); 18719+ osal_list_for_each_entry(p, &g_phys_addr, list) { 18720+ if (p->phys_addr == phyaddr) { 18721+ osal_list_del(&p->list); 18722+ kfree(p); 18723+ return; 18724+ } 18725+ } 18726+ HI_DRM_ERR("list has no node to del\n"); 18727+ return; 18728+} 18729+ 18730+static struct drm_driver hi_drm_driver = { 18731+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC, 18732+ .lastclose = hi_drm_lastclose, 18733+ .dumb_create = hi_drm_gem_cma_dumb_create, 18734+ .gem_vm_ops = &drm_gem_cma_vm_ops, 18735+ .gem_free_object_unlocked = hi_drm_gem_cma_free_object, 18736+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 18737+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 18738+ .gem_prime_import = drm_gem_prime_import, 18739+ .gem_prime_export = drm_gem_prime_export, 18740+ .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, 18741+ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, 18742+ .gem_prime_vmap = drm_gem_cma_prime_vmap, 18743+ .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 18744+ .gem_prime_mmap = drm_gem_cma_prime_mmap, 18745+ .fops = &hi_drm_driver_fops, 18746+ .name = DRIVER_NAME, 18747+ .desc = DRIVER_DESC, 18748+ .date = DRIVER_DATE, 18749+ .major = DRIVER_MAJOR, 18750+ .minor = DRIVER_MINOR, 18751+ .ioctls = hidrm_ioctls, 18752+ .num_ioctls = ARRAY_SIZE(hidrm_ioctls), 18753+}; 18754+ 18755+static struct drm_framebuffer *hi_drm_fb_create(struct drm_device *dev, 18756+ struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) 18757+{ 18758+ return drm_gem_fb_create(dev, file_priv, mode_cmd); 18759+} 18760+ 18761+int hi_drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) 18762+{ 18763+ struct drm_connector *connector = NULL; 18764+ struct drm_connector_state *old_connector_state = NULL; 18765+ struct drm_connector_state *new_connector_state = NULL; 18766+ int i; 18767+ 18768+ for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) { 18769+ if ((connector->connector_type == DRM_MODE_CONNECTOR_DSI) && 18770+ (old_connector_state->tv.brightness != new_connector_state->tv.brightness)) { 18771+ adp_mipi_set_brightness(connector, new_connector_state->tv.brightness); 18772+ } 18773+ } 18774+ return drm_atomic_helper_commit(dev, state, nonblock); 18775+} 18776+ 18777+static const struct drm_mode_config_funcs hi_drm_mode_config_funcs = { 18778+ .fb_create = hi_drm_fb_create, 18779+ .atomic_check = drm_atomic_helper_check, 18780+ .atomic_commit = hi_drm_atomic_helper_commit, 18781+}; 18782+ 18783+static void hi_drm_mode_config_init(struct drm_device *dev) 18784+{ 18785+ dev->mode_config.min_width = 0; 18786+ dev->mode_config.min_height = 0; 18787+ dev->mode_config.max_width = HI_DRM_MAX_WIDTH; 18788+ dev->mode_config.max_height = HI_DRM_MAX_HEIGHT; 18789+ dev->mode_config.funcs = &hi_drm_mode_config_funcs; 18790+} 18791+ 18792+static int hi_drm_kms_init(struct drm_device *drm) 18793+{ 18794+ int ret; 18795+ HI_DRM_FUNC_ENTER(); 18796+ drm_mode_config_init(drm); 18797+ hi_drm_mode_config_init(drm); 18798+ ret = hi_drm_crtc_init(drm); 18799+ if (ret != 0) { 18800+ HI_DRM_ERR("hi_drm_crtc_init err, ret=%#x\n", ret); 18801+ goto err_mode_cleanup; 18802+ } 18803+ ret = hi_drm_hdmitx_init(drm); 18804+ if (ret != 0) { 18805+ HI_DRM_ERR("hi_drm_hdmitx_init err, ret=%#x\n", ret); 18806+ goto err_crtc_cleanup; 18807+ } 18808+ ret = hi_drm_mipitx_init(drm); 18809+ if (ret != 0) { 18810+ HI_DRM_ERR("hi_drm_mipitx_init err, ret=%#x\n", ret); 18811+ goto err_hdmi_connector_cleanup; 18812+ } 18813+ ret = drm_vblank_init(drm, drm->mode_config.num_crtc); 18814+ if (ret != 0) { 18815+ HI_DRM_ERR("drm_vblank_init err, ret=%#x\n", ret); 18816+ goto err_all_connector_cleanup; 18817+ } 18818+ 18819+ drm->irq_enabled = true; 18820+ drm_mode_config_reset(drm); 18821+ HI_DRM_FUNC_EXIT(); 18822+ return 0; 18823+err_all_connector_cleanup: 18824+ hi_drm_mipitx_cleanup(drm); 18825+err_hdmi_connector_cleanup: 18826+ hi_drm_hdmitx_cleanup(drm); 18827+err_crtc_cleanup: 18828+ hi_drm_crtc_cleanup(drm); 18829+err_mode_cleanup: 18830+ drm_mode_config_cleanup(drm); 18831+ return ret; 18832+} 18833+ 18834+static void hi_drm_kms_cleanup(struct drm_device *drm) 18835+{ 18836+ HI_DRM_FUNC_ENTER(); 18837+ 18838+ hi_drm_hdmitx_cleanup(drm); 18839+ 18840+ hi_drm_crtc_cleanup(drm); 18841+ 18842+ drm_mode_config_cleanup(drm); 18843+ 18844+ HI_DRM_FUNC_EXIT(); 18845+} 18846+ 18847+static int hi_drm_platform_probe(struct platform_device *pdev) 18848+{ 18849+ struct drm_driver *driver = &hi_drm_driver; 18850+ struct hi_drm_private *private = NULL; 18851+ struct device *dev = &pdev->dev; 18852+ int ret; 18853+ 18854+ HI_DRM_FUNC_ENTER(); 18855+ 18856+ drm_dev = drm_dev_alloc(driver, dev); 18857+ if (IS_ERR(drm_dev)) { 18858+ return PTR_ERR(drm_dev); 18859+ } 18860+ 18861+ private = devm_kzalloc(drm_dev->dev, sizeof(struct hi_drm_private), GFP_KERNEL); 18862+ if (private == NULL) { 18863+ ret = -ENOMEM; 18864+ goto err_put_drm_dev; 18865+ } 18866+ 18867+ drm_dev->dev_private = private; 18868+ 18869+ ret = hi_drm_kms_init(drm_dev); 18870+ if (ret != 0) { 18871+ HI_DRM_ERR("hi_drm_kms_init err, ret=%#x\n", ret); 18872+ goto err_drm_priv_free; 18873+ } 18874+ 18875+ ret = drm_dev_register(drm_dev, 0); 18876+ if (ret != 0) { 18877+ HI_DRM_ERR("drm_dev_init err, ret=%#x\n", ret); 18878+ goto err_drm_kms_cleanup; 18879+ } 18880+ 18881+ HI_DRM_FUNC_EXIT(); 18882+ 18883+ return 0; 18884+ 18885+err_drm_kms_cleanup: 18886+ hi_drm_kms_cleanup(drm_dev); 18887+err_drm_priv_free: 18888+ devm_kfree(drm_dev->dev, drm_dev->dev_private); 18889+ drm_dev->dev_private = NULL; 18890+err_put_drm_dev: 18891+ drm_dev_put(drm_dev); 18892+ return ret; 18893+} 18894+ 18895+static int hi_drm_platform_remove(struct platform_device *pdev) 18896+{ 18897+ devm_kfree(drm_dev->dev, drm_dev->dev_private); 18898+ drm_dev->dev_private = NULL; 18899+ 18900+ drm_dev_unregister(drm_dev); 18901+ 18902+ hi_drm_kms_cleanup(drm_dev); 18903+ 18904+ drm_dev_put(drm_dev); 18905+ 18906+ return 0; 18907+} 18908+ 18909+static const struct of_device_id hi_drm_dt_ids[] = { 18910+ { .compatible = "hisilicon,hi-drm", }, 18911+ { /* sentinel */ }, 18912+}; 18913+ 18914+static struct platform_driver hi_drm_platform_driver = { 18915+ .probe = hi_drm_platform_probe, 18916+ .remove = hi_drm_platform_remove, 18917+ .driver = { 18918+ .name = "hi-drm", 18919+ .of_match_table = hi_drm_dt_ids, 18920+ }, 18921+}; 18922+ 18923+module_platform_driver(hi_drm_platform_driver); 18924+ 18925+MODULE_DESCRIPTION("hisilicon DRM driver"); 18926+MODULE_LICENSE("GPL v2"); 18927+ 18928diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.h 18929new file mode 100755 18930index 000000000..c399f78b6 18931--- /dev/null 18932+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.h 18933@@ -0,0 +1,29 @@ 18934+/* 18935+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 18936+ * Description: Hisilicon DRM driver 18937+ * Author: Hisilicon multimedia software group 18938+ * Create: 2020-7-29 18939+ */ 18940+ 18941+#ifndef __HI_DRM_DRV_H__ 18942+#define __HI_DRM_DRV_H__ 18943+ 18944+#include <drm/drm_util.h> 18945+ 18946+#define HI_DRM_FUNC_ENTER() DRM_DEBUG("function %s enter...\n", __FUNCTION__) 18947+#define HI_DRM_FUNC_EXIT() DRM_DEBUG("function %s exit...\n", __FUNCTION__) 18948+#define HI_DRM_ERR(fmt...) DRM_ERROR(fmt) 18949+#define HI_DRM_WARN(fmt...) DRM_WARN(fmt) 18950+#define HI_DRM_INFO(fmt...) DRM_DEBUG(fmt) 18951+ 18952+#define HI_DRM_CHECK_PTR_RETURN(ptr) do { \ 18953+ if (IS_ERR_OR_NULL(ptr)) { \ 18954+ return -PTR_ERR(ptr); \ 18955+ } \ 18956+} while (0) 18957+ 18958+struct hi_drm_private { 18959+ void *reserved; 18960+}; 18961+ 18962+#endif /* __HI_DRM_DRV_H__ */ 18963diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.c 18964new file mode 100644 18965index 000000000..f29e7f998 18966--- /dev/null 18967+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.c 18968@@ -0,0 +1,43 @@ 18969+/* 18970+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 18971+ * Description: Hisilicon DRM driver 18972+ * Author: Hisilicon multimedia software group 18973+ * Create: 2020-7-29 18974+ */ 18975+ 18976+#include "hi_drm_func_ext.h" 18977+#include <linux/module.h> 18978+#include <linux/stddef.h> 18979+ 18980+hi_drm_export_func g_drm_ext_func = { 18981+ .disp_func = NULL, 18982+ .gfx_func = NULL, 18983+ .hdmi_func = NULL, 18984+}; 18985+ 18986+int drm_get_export_func(enum hi_mod_ext_id mod_id, void **func) 18987+{ 18988+ if (func == NULL) { 18989+ return -1; 18990+ } 18991+ switch (mod_id) { 18992+ case MOD_ID_DISP: 18993+ *func = g_drm_ext_func.disp_func; 18994+ break; 18995+ case MOD_ID_GFX: 18996+ *func = g_drm_ext_func.gfx_func; 18997+ break; 18998+ case MOD_ID_HDMI: 18999+ *func = g_drm_ext_func.hdmi_func; 19000+ break; 19001+ default: 19002+ return -1; 19003+ } 19004+ return 0; 19005+} 19006+ 19007+hi_drm_export_func *drm_export_func_register() 19008+{ 19009+ return &g_drm_ext_func; 19010+} 19011+EXPORT_SYMBOL(drm_export_func_register); 19012\ No newline at end of file 19013diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.h 19014new file mode 100644 19015index 000000000..83a96b22b 19016--- /dev/null 19017+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.h 19018@@ -0,0 +1,27 @@ 19019+/* 19020+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 19021+ * Description: Hisilicon DRM driver 19022+ * Author: Hisilicon multimedia software group 19023+ * Create: 2020-7-29 19024+ */ 19025+ 19026+#ifndef __HI_DRM_FUNC_EXT_H__ 19027+#define __HI_DRM_FUNC_EXT_H__ 19028+ 19029+enum hi_mod_ext_id { 19030+ MOD_ID_DISP, 19031+ MOD_ID_GFX, 19032+ MOD_ID_HDMI, 19033+ MOD_ID_MAX 19034+}; 19035+ 19036+typedef struct { 19037+ void *disp_func; 19038+ void *gfx_func; 19039+ void *hdmi_func; 19040+}hi_drm_export_func; 19041+ 19042+int drm_get_export_func(enum hi_mod_ext_id, void **); 19043+hi_drm_export_func *drm_export_func_register(void); 19044+ 19045+#endif /* __HI_DRM_FUNC_EXT_H__ */ 19046diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.c 19047new file mode 100755 19048index 000000000..1d11d98a2 19049--- /dev/null 19050+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.c 19051@@ -0,0 +1,233 @@ 19052+/* 19053+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 19054+ * Description: Hisilicon DRM driver 19055+ * Author: Hisilicon multimedia software group 19056+ * Create: 2020-7-29 19057+ */ 19058+ 19059+#include "hi_drm_hdmitx.h" 19060+#include <linux/clk.h> 19061+#include <linux/component.h> 19062+#include <linux/of_address.h> 19063+#include <video/videomode.h> 19064+#include <drm/drm_atomic_helper.h> 19065+#include <drm/drm_crtc.h> 19066+#include <drm/drm_crtc_helper.h> 19067+#include <drm/drm_fb_cma_helper.h> 19068+#include <drm/drm_fb_helper.h> 19069+#include <drm/drm_gem_cma_helper.h> 19070+#include <drm/drm_of.h> 19071+#include <drm/drm_plane_helper.h> 19072+#include <drm/drm_util.h> 19073+#include <drm/drm_probe_helper.h> 19074+#include "hi_drm_drv.h" 19075+#include "hi_adp_hdmitx.h" 19076+#include "hi_adp_crtc.h" 19077+ 19078+static int hi_conn_get_modes(struct drm_connector *connector) 19079+{ 19080+ int ret; 19081+ int count; 19082+ struct edid *edid = NULL; 19083+ void *data = NULL; 19084+ const int max_edid_num = 4; 19085+ 19086+ HI_DRM_FUNC_ENTER(); 19087+ data = kzalloc(sizeof(struct edid) * max_edid_num, GFP_KERNEL); 19088+ if (data == NULL) { 19089+ return -ENOMEM; 19090+ } 19091+ 19092+ ret = hi_adp_hdmitx_get_edid(connector, data, sizeof(struct edid) * max_edid_num); 19093+ if (ret != 0) { 19094+ HI_DRM_ERR("hi_adp_hdmitx_get_edid err, ret=%#x\n", ret); 19095+ goto hdmitx_free_data; 19096+ } 19097+ 19098+ edid = (struct edid *)data; 19099+ ret = drm_connector_update_edid_property(connector, edid); 19100+ if (ret != 0) { 19101+ HI_DRM_ERR("drm_mode_connector_update_edid_property err, ret=%#x\n", ret); 19102+ goto hdmitx_free_data; 19103+ } 19104+ count = drm_add_edid_modes(connector, edid); 19105+ kfree(data); 19106+ HI_DRM_FUNC_EXIT(); 19107+ return count; 19108+hdmitx_free_data: 19109+ kfree(data); 19110+ return ret; 19111+} 19112+ 19113+static enum drm_connector_status hi_conn_detect(struct drm_connector *connector, bool force) 19114+{ 19115+ HI_DRM_FUNC_ENTER(); 19116+ HI_DRM_FUNC_EXIT(); 19117+ return hi_adp_hdmitx_detect(connector, force); 19118+} 19119+ 19120+static const struct drm_connector_helper_funcs hi_conn_helper_funcs = { 19121+ .get_modes = hi_conn_get_modes, 19122+}; 19123+ 19124+static const struct drm_connector_funcs hi_connector_funcs = { 19125+ .fill_modes = drm_helper_probe_single_connector_modes, 19126+ .detect = hi_conn_detect, 19127+ .destroy = drm_connector_cleanup, 19128+ .reset = drm_atomic_helper_connector_reset, 19129+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 19130+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 19131+}; 19132+ 19133+static int hi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, 19134+ struct drm_connector_state *conn_state) 19135+{ 19136+ HI_DRM_FUNC_ENTER(); 19137+ HI_DRM_INFO("mode: %d %d %d %d %d %d %d %d %d %d %d\n", 19138+ crtc_state->mode.clock, 19139+ crtc_state->mode.hdisplay, 19140+ crtc_state->mode.hsync_start, 19141+ crtc_state->mode.hsync_end, 19142+ crtc_state->mode.htotal, 19143+ crtc_state->mode.hskew, 19144+ crtc_state->mode.vdisplay, 19145+ crtc_state->mode.vsync_start, 19146+ crtc_state->mode.vsync_end, 19147+ crtc_state->mode.vtotal, 19148+ crtc_state->mode.vscan); 19149+ hi_adp_hdmitx_set_mode(encoder, &crtc_state->mode, conn_state); 19150+ HI_DRM_FUNC_EXIT(); 19151+ 19152+ return 0; 19153+} 19154+ 19155+static void hi_encoder_enable(struct drm_encoder *encoder) 19156+{ 19157+ int ret; 19158+ HI_DRM_FUNC_ENTER(); 19159+ ret = hi_adp_hdmitx_enable(encoder); 19160+ if (ret != 0) { 19161+ HI_DRM_ERR("hi_adp_hdmitx_enable err, ret=%#x\n", ret); 19162+ } 19163+ HI_DRM_FUNC_EXIT(); 19164+} 19165+ 19166+static void hi_encoder_disable(struct drm_encoder *encoder) 19167+{ 19168+ int ret; 19169+ HI_DRM_FUNC_ENTER(); 19170+ 19171+ ret = hi_adp_hdmitx_disable(encoder); 19172+ if (ret != 0) { 19173+ HI_DRM_ERR("hi_adp_hdmitx_enable err, ret=%#x\n", ret); 19174+ } 19175+ HI_DRM_FUNC_EXIT(); 19176+} 19177+ 19178+static enum drm_mode_status hi_encoder_mode_valid(struct drm_encoder *encoder, const struct drm_display_mode *mode) 19179+{ 19180+ HI_DRM_FUNC_ENTER(); 19181+ HI_DRM_FUNC_EXIT(); 19182+ return MODE_OK; 19183+} 19184+ 19185+static void hi_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, 19186+ struct drm_display_mode *adj_mode) 19187+{ 19188+ HI_DRM_FUNC_ENTER(); 19189+ HI_DRM_FUNC_EXIT(); 19190+} 19191+ 19192+static const struct drm_encoder_helper_funcs hi_encoder_helper_funcs = { 19193+ .atomic_check = hi_encoder_atomic_check, 19194+ .mode_valid = hi_encoder_mode_valid, 19195+ .mode_set = hi_encoder_mode_set, 19196+ .enable = hi_encoder_enable, 19197+ .disable = hi_encoder_disable 19198+}; 19199+ 19200+static void hi_drm_encoder_destroy(struct drm_encoder *encoder) 19201+{ 19202+ int ret; 19203+ HI_DRM_FUNC_ENTER(); 19204+ 19205+ ret = hi_adp_hdmitx_disable(encoder); 19206+ if (ret != 0) { 19207+ HI_DRM_ERR("hi_adp_hdmitx_disable err, ret=%#x\n", ret); 19208+ } 19209+ drm_encoder_cleanup(encoder); 19210+ HI_DRM_FUNC_EXIT(); 19211+} 19212+ 19213+static const struct drm_encoder_funcs hi_encoder_funcs = { 19214+ .destroy = hi_drm_encoder_destroy, 19215+}; 19216+ 19217+static void hdmitx_init_by_index(struct drm_device *drm, unsigned int id) 19218+{ 19219+ int ret; 19220+ struct drm_connector *conn = NULL; 19221+ struct drm_encoder *encoder = NULL; 19222+ HI_DRM_FUNC_ENTER(); 19223+ ret = hi_adp_hdmitx_get_by_index(id, &conn, &encoder); 19224+ if (ret != 0) { 19225+ HI_DRM_INFO("hdmi id %u not support!\n", id); 19226+ return; 19227+ } 19228+ 19229+ if (id == DRM_MODE_CONNECTOR_HDMIA) { 19230+ encoder->possible_crtcs = 1; /* 1: dhd0 */ 19231+ } else { 19232+ encoder->possible_crtcs = 2; /* 2: dhd1 */ 19233+ } 19234+ 19235+ drm_encoder_init(drm, encoder, &hi_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); 19236+ drm_encoder_helper_add(encoder, &hi_encoder_helper_funcs); 19237+ drm_connector_init(drm, conn, &hi_connector_funcs, id); 19238+ drm_connector_helper_add(conn, &hi_conn_helper_funcs); 19239+ drm_connector_attach_encoder(conn, encoder); 19240+ HI_DRM_FUNC_EXIT(); 19241+} 19242+ 19243+static void hdmitx_deinit_by_index(struct drm_device *drm, unsigned int id) 19244+{ 19245+ int ret; 19246+ struct drm_connector *conn = NULL; 19247+ struct drm_encoder *encoder = NULL; 19248+ HI_DRM_FUNC_ENTER(); 19249+ ret = hi_adp_hdmitx_get_by_index(id, &conn, &encoder); 19250+ if (ret != 0) { 19251+ HI_DRM_INFO("hdmi id %u not support!\n", id); 19252+ return; 19253+ } 19254+ /* ensure disabled at the final cleanup call */ 19255+ ret = hi_adp_hdmitx_disable(encoder); 19256+ if (ret != 0) { 19257+ HI_DRM_ERR("hi_adp_hdmitx_disable err, ret=%#x\n", ret); 19258+ } 19259+ 19260+ drm_connector_cleanup(conn); 19261+ drm_encoder_cleanup(encoder); 19262+ HI_DRM_FUNC_EXIT(); 19263+} 19264+ 19265+int hi_drm_hdmitx_init(struct drm_device *drm) 19266+{ 19267+ int ret; 19268+ HI_DRM_FUNC_ENTER(); 19269+ ret = hi_adp_hdmitx_init(); 19270+ if (ret != 0) { 19271+ return ret; 19272+ } 19273+ hdmitx_init_by_index(drm, DRM_MODE_CONNECTOR_HDMIA); 19274+ HI_DRM_FUNC_EXIT(); 19275+ return 0; 19276+} 19277+ 19278+void hi_drm_hdmitx_cleanup(struct drm_device *drm) 19279+{ 19280+ HI_DRM_FUNC_ENTER(); 19281+ hdmitx_deinit_by_index(drm, DRM_MODE_CONNECTOR_HDMIA); 19282+ hi_adp_hdmitx_deinit(); 19283+ HI_DRM_FUNC_EXIT(); 19284+} 19285diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.h 19286new file mode 100644 19287index 000000000..22285a50e 19288--- /dev/null 19289+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.h 19290@@ -0,0 +1,16 @@ 19291+/* 19292+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 19293+ * Description: Hisilicon DRM driver 19294+ * Author: Hisilicon multimedia software group 19295+ * Create: 2020-7-29 19296+ */ 19297+ 19298+#ifndef __HI_DRM_HDMITX_H__ 19299+#define __HI_DRM_HDMITX_H__ 19300+ 19301+#include <drm/drm_device.h> 19302+ 19303+int hi_drm_hdmitx_init(struct drm_device *drm); 19304+void hi_drm_hdmitx_cleanup(struct drm_device *drm); 19305+ 19306+#endif /* __HI_DRM_HDMITX_H__ */ 19307diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.c 19308new file mode 100755 19309index 000000000..7f5d10cc3 19310--- /dev/null 19311+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.c 19312@@ -0,0 +1,189 @@ 19313+/* 19314+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 19315+ * Description: Hisilicon DRM driver 19316+ * Author: Hisilicon multimedia software group 19317+ * Create: 2020-7-29 19318+ */ 19319+ 19320+#include "hi_drm_mipitx.h" 19321+#include <linux/clk.h> 19322+#include <linux/component.h> 19323+#include <linux/of_address.h> 19324+#include <video/videomode.h> 19325+#include <drm/drm_atomic_helper.h> 19326+#include <drm/drm_crtc.h> 19327+#include <drm/drm_crtc_helper.h> 19328+#include <drm/drm_fb_cma_helper.h> 19329+#include <drm/drm_fb_helper.h> 19330+#include <drm/drm_gem_cma_helper.h> 19331+#include <drm/drm_of.h> 19332+#include <drm/drm_plane_helper.h> 19333+#include <drm/drm_util.h> 19334+#include <drm/drm_probe_helper.h> 19335+#include "hi_drm_drv.h" 19336+#include "hi_adp_mipitx.h" 19337+#include "hi_adp_crtc.h" 19338+ 19339+static int hi_dsi_conn_get_modes(struct drm_connector *connector) 19340+{ 19341+ HI_DRM_FUNC_ENTER(); 19342+ HI_DRM_FUNC_EXIT(); 19343+ return hi_adp_mipitx_get_modes(connector); 19344+} 19345+ 19346+static const struct drm_connector_helper_funcs hi_mipi_dsi_conn_helper_funcs = { 19347+ .get_modes = hi_dsi_conn_get_modes, 19348+}; 19349+ 19350+static enum drm_connector_status hi_dsi_connector_detect(struct drm_connector *connector, bool force) 19351+{ 19352+ HI_DRM_FUNC_ENTER(); 19353+ HI_DRM_FUNC_EXIT(); 19354+ return connector_status_connected; 19355+} 19356+ 19357+static const struct drm_connector_funcs hi_mipi_dsi_connector_funcs = { 19358+ .detect = hi_dsi_connector_detect, 19359+ .fill_modes = drm_helper_probe_single_connector_modes, 19360+ .destroy = drm_connector_cleanup, 19361+ .reset = drm_atomic_helper_connector_reset, 19362+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 19363+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 19364+ .atomic_set_property = adp_conn_atomic_set_property, 19365+ .atomic_get_property = adp_conn_atomic_get_property, 19366+}; 19367+ 19368+static int hi_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, 19369+ struct drm_connector_state *conn_state) 19370+{ 19371+ HI_DRM_FUNC_ENTER(); 19372+ /* set mode, attach the interface to crtc, mipi on and set blacklight */ 19373+ hi_adp_mipitx_set_mode(encoder, &crtc_state->mode, conn_state); 19374+ HI_DRM_FUNC_EXIT(); 19375+ return 0; 19376+} 19377+ 19378+static enum drm_mode_status hi_mipi_dsi_encoder_mode_valid(struct drm_encoder *encoder, 19379+ const struct drm_display_mode *mode) 19380+{ 19381+ HI_DRM_FUNC_ENTER(); 19382+ HI_DRM_FUNC_EXIT(); 19383+ return MODE_OK; 19384+} 19385+ 19386+static void hi_mipi_dsi_encoder_enable(struct drm_encoder *encoder) 19387+{ 19388+ int ret; 19389+ HI_DRM_FUNC_ENTER(); 19390+ ret = hi_adp_mipitx_enable(encoder); 19391+ if (ret != 0) { 19392+ HI_DRM_ERR("hi_mipi_dsi_encoder_enable err, ret=%#x\n", ret); 19393+ } 19394+ HI_DRM_FUNC_EXIT(); 19395+ return; 19396+} 19397+ 19398+static void hi_mipi_dsi_encoder_disable(struct drm_encoder *encoder) 19399+{ 19400+ int ret; 19401+ HI_DRM_FUNC_ENTER(); 19402+ ret = hi_adp_mipitx_disable(encoder); 19403+ if (ret != 0) { 19404+ HI_DRM_ERR("hi_mipi_dsi_encoder_disable err, ret=%#x\n", ret); 19405+ } 19406+ HI_DRM_FUNC_EXIT(); 19407+ return; 19408+} 19409+ 19410+static const struct drm_encoder_helper_funcs hi_mipi_dsi_encoder_helper_funcs = { 19411+ .atomic_check = hi_mipi_dsi_encoder_atomic_check, 19412+ .mode_valid = hi_mipi_dsi_encoder_mode_valid, 19413+ .enable = hi_mipi_dsi_encoder_enable, /* SetBacklight */ 19414+ .disable = hi_mipi_dsi_encoder_disable, /* off */ 19415+}; 19416+ 19417+static const struct drm_encoder_funcs hi_mipi_dsi_encoder_funcs = { 19418+ .destroy = drm_encoder_cleanup, 19419+}; 19420+ 19421+static void mipitx_init_by_index(struct drm_device *drm, unsigned int id) 19422+{ 19423+ int ret; 19424+ struct drm_connector *conn = NULL; 19425+ struct drm_encoder *encoder = NULL; 19426+ HI_DRM_FUNC_ENTER(); 19427+ ret = hi_adp_mipitx_get_by_index(id, &conn, &encoder); 19428+ if (ret != 0) { 19429+ HI_DRM_INFO("mipi id %u not support!\n", id); 19430+ return; 19431+ } 19432+ 19433+ /* bind crtc */ 19434+ if (id == DRM_MODE_CONNECTOR_DSI) { 19435+ encoder->possible_crtcs = 1; /* 1: dhd0 */ 19436+ } else { 19437+ encoder->possible_crtcs = 2; /* 2: dhd1 */ 19438+ } 19439+ 19440+ drm_encoder_init(drm, encoder, &hi_mipi_dsi_encoder_funcs, DRM_MODE_ENCODER_DSI, NULL); 19441+ drm_encoder_helper_add(encoder, &hi_mipi_dsi_encoder_helper_funcs); 19442+ drm_connector_init(drm, conn, &hi_mipi_dsi_connector_funcs, id); 19443+ drm_connector_helper_add(conn, &hi_mipi_dsi_conn_helper_funcs); 19444+ drm_connector_attach_encoder(conn, encoder); 19445+ ret = adp_conn_private_properties_init(drm, conn); 19446+ if (ret != 0) { 19447+ HI_DRM_ERR("adp_conn_private_properties_init failed\n"); 19448+ drm_connector_cleanup(conn); 19449+ return; 19450+ } 19451+ HI_DRM_FUNC_EXIT(); 19452+ return; 19453+} 19454+ 19455+static void mipitx_deinit_by_index(struct drm_device *drm, unsigned int id) 19456+{ 19457+ int ret; 19458+ struct drm_connector *conn = NULL; 19459+ struct drm_encoder *encoder = NULL; 19460+ HI_DRM_FUNC_ENTER(); 19461+ ret = hi_adp_mipitx_get_by_index(id, &conn, &encoder); 19462+ if (ret != 0) { 19463+ HI_DRM_INFO("mipi id %u not support!\n", id); 19464+ return; 19465+ } 19466+ 19467+ /* ensure disabled at the final cleanup call */ 19468+ ret = hi_adp_mipitx_disable(encoder); 19469+ if (ret != 0) { 19470+ HI_DRM_ERR("hi_adp_hdmitx_disable err, ret=%#x\n", ret); 19471+ } 19472+ adp_conn_private_properties_deinit(drm, conn); 19473+ drm_connector_cleanup(conn); 19474+ drm_encoder_cleanup(encoder); 19475+ HI_DRM_FUNC_EXIT(); 19476+ return; 19477+} 19478+ 19479+int hi_drm_mipitx_init(struct drm_device *drm) 19480+{ 19481+ int ret; 19482+ HI_DRM_FUNC_ENTER(); 19483+ ret = hi_adp_mipitx_init(); 19484+ if (ret != 0) { 19485+ HI_DRM_ERR("hi_adp_mipitx_init err, ret=%#x\n", ret); 19486+ return ret; 19487+ } 19488+ mipitx_init_by_index(drm, DRM_MODE_CONNECTOR_DSI); 19489+ HI_DRM_FUNC_EXIT(); 19490+ return 0; 19491+} 19492+ 19493+void hi_drm_mipitx_cleanup(struct drm_device *drm) 19494+{ 19495+ HI_DRM_FUNC_ENTER(); 19496+ mipitx_deinit_by_index(drm, DRM_MODE_CONNECTOR_DSI); 19497+ hi_adp_mipitx_deinit(); 19498+ HI_DRM_FUNC_EXIT(); 19499+ return; 19500+} 19501+ 19502diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.h 19503new file mode 100644 19504index 000000000..34d2f0a37 19505--- /dev/null 19506+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.h 19507@@ -0,0 +1,17 @@ 19508+/* 19509+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 19510+ * Description: Hisilicon DRM driver 19511+ * Author: Hisilicon multimedia software group 19512+ * Create: 2020-7-29 19513+ */ 19514+ 19515+#ifndef __HI_DRM_MIPITX_H__ 19516+#define __HI_DRM_MIPITX_H__ 19517+ 19518+#include <drm/drm_device.h> 19519+ 19520+int hi_drm_mipitx_init(struct drm_device *drm); 19521+void hi_drm_mipitx_cleanup(struct drm_device *drm); 19522+ 19523+#endif /* __HI_DRM_MIPITX_H__ */ 19524+ 19525diff --git a/drivers/gpu/drm/hisilicon/hismart/hisilicon_drm.h b/drivers/gpu/drm/hisilicon/hismart/hisilicon_drm.h 19526new file mode 100644 19527index 000000000..5f247a1a9 19528--- /dev/null 19529+++ b/drivers/gpu/drm/hisilicon/hismart/hisilicon_drm.h 19530@@ -0,0 +1,31 @@ 19531+/* 19532+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2016-2019. All rights reserved. 19533+ * Description: On behalf of a display device, hwcomposer is called for composition and sent for display 19534+ * Author: Hisilicon gfx group 19535+ * Created: 2021.01.01 19536+ */ 19537+#ifndef HISILICON_DRM_H 19538+#define HISILICON_DRM_H 19539+ 19540+#include <drm/drm.h> 19541+ 19542+#if defined(__cplusplus) 19543+extern "C" { 19544+#endif 19545+#define DRM_HISILICON_GEM_FD_TO_PHYADDR 0x1 19546+ 19547+struct drm_hisilicon_phyaddr { 19548+ /* * return the physical address */ 19549+ __u64 phyaddr; 19550+ /* * dmabuf file descriptor */ 19551+ __s32 fd; 19552+}; 19553+ 19554+#define DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR \ 19555+ DRM_IOWR(DRM_COMMAND_BASE + DRM_HISILICON_GEM_FD_TO_PHYADDR, struct drm_hisilicon_phyaddr) 19556+ 19557+#if defined(__cplusplus) 19558+} 19559+#endif 19560+ 19561+#endif /* HISILICON_DRM_H */ 19562diff --git a/drivers/hi_vdmav100/Kconfig b/drivers/hi_vdmav100/Kconfig 19563new file mode 100644 19564index 000000000..ecaa952b9 19565--- /dev/null 19566+++ b/drivers/hi_vdmav100/Kconfig 19567@@ -0,0 +1,26 @@ 19568+menuconfig HI_VDMA_V100 19569+ tristate "Hisilicon VDMA Controller V100" 19570+ depends on ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100 19571+ default n if ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100 19572+ help 19573+ This is the driver for hisilicon VDMA controoller 19574+ IP. 19575+ 19576+if HI_VDMA_V100 19577+ 19578+config HI_VDMA_CHN_NUM 19579+ int "HI_VDMAV100 max channel number" 19580+ default 32 19581+ 19582+config HI_VDMA_TRANSFER_THRESHOLD 19583+ int "Hi VDMA data transfer threshold KBytes" 19584+ range 4 16384 19585+ default "128" if (ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100) 19586+ 19587+config HI_VDMA_MISC_DEV 19588+ bool "HI_VDMAV100 misc dev" 19589+ default y if (ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100) 19590+ depends on HI_VDMA_V100 19591+ 19592+ 19593+endif 19594diff --git a/drivers/hi_vdmav100/Makefile b/drivers/hi_vdmav100/Makefile 19595new file mode 100644 19596index 000000000..ccac799b5 19597--- /dev/null 19598+++ b/drivers/hi_vdmav100/Makefile 19599@@ -0,0 +1,2 @@ 19600+obj-$(CONFIG_HI_VDMA_V100) += hi_vdmav100.o 19601+obj-$(CONFIG_HI_VDMA_MISC_DEV) += hi_vdmav100_misc.o 19602diff --git a/drivers/hi_vdmav100/hi_vdma.h b/drivers/hi_vdmav100/hi_vdma.h 19603new file mode 100644 19604index 000000000..3644fe621 19605--- /dev/null 19606+++ b/drivers/hi_vdmav100/hi_vdma.h 19607@@ -0,0 +1,41 @@ 19608+/* 19609+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd. 19610+ * 19611+ * This program is free software; you can redistribute it and/or modify 19612+ * it under the terms of the GNU General Public License as published by 19613+ * the Free Software Foundation; either version 2 of the License, or 19614+ * (at your option) any later version. 19615+ * 19616+ * This program is distributed in the hope that it will be useful, 19617+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 19618+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19619+ * GNU General Public License for more details. 19620+ * 19621+ * You should have received a copy of the GNU General Public License 19622+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 19623+ */ 19624+ 19625+#ifndef __VDMA_USER_H__ 19626+#define __VDMA_USER_H__ 19627+ 19628+struct hivdmac_host { 19629+ struct device *dev; 19630+ struct clk *clk; 19631+ struct reset_control *rstc; 19632+ void __iomem *regbase; 19633+ 19634+ int irq; 19635+}; 19636+ 19637+#define VDMA_DATA_CMD 0x6 19638+ 19639+struct dmac_user_para { 19640+ uintptr_t src; 19641+ uintptr_t dst; 19642+ unsigned int size; 19643+}; 19644+ 19645+extern int hi_vdma_m2m_copy(void *dst, const void *src, size_t count); 19646+ 19647+ 19648+#endif 19649diff --git a/drivers/hi_vdmav100/hi_vdmav100.c b/drivers/hi_vdmav100/hi_vdmav100.c 19650new file mode 100644 19651index 000000000..0199ddd23 19652--- /dev/null 19653+++ b/drivers/hi_vdmav100/hi_vdmav100.c 19654@@ -0,0 +1,534 @@ 19655+/* 19656+ * clock driver for hisilicon hi3519 or hi3559 soc 19657+ * 19658+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd. 19659+ * 19660+ * 19661+ * This program is free software; you can redistribute it and/or modify it 19662+ * under the terms of the GNU General Public License as published by the 19663+ * Free Software Foundation; either version 2 of the License, or (at your 19664+ * option) any later version. 19665+ * 19666+ * This program is distributed in the hope that it will be useful, 19667+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 19668+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19669+ * GNU General Public License for more details. 19670+ * 19671+ * You should have received a copy of the GNU General Public License 19672+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 19673+ * 19674+ */ 19675+#include <linux/kernel.h> 19676+#include <linux/module.h> 19677+#include <linux/init.h> 19678+#include <linux/types.h> 19679+#include <linux/errno.h> 19680+#include <linux/fcntl.h> 19681+#include <linux/mm.h> 19682+#include <linux/miscdevice.h> 19683+#include <linux/proc_fs.h> 19684+#include <linux/fs.h> 19685+#include <linux/slab.h> 19686+#include <linux/spinlock.h> 19687+#include <linux/delay.h> 19688+#include <linux/uaccess.h> 19689+#include <linux/io.h> 19690+#include <linux/wait.h> 19691+#include <linux/sched.h> 19692+#include <linux/interrupt.h> 19693+#include <linux/ioport.h> 19694+#include <linux/string.h> 19695+#include <linux/dma-mapping.h> 19696+#include <linux/platform_device.h> 19697+#include <linux/mod_devicetable.h> 19698+#include <linux/vmalloc.h> 19699+#include <asm/pgtable.h> 19700+#include <asm/page.h> 19701+#include <linux/mm_types.h> 19702+#include <linux/mmu_context.h> 19703+#include <asm/tlbflush.h> 19704+#include <linux/clk.h> 19705+#include <linux/reset.h> 19706+ 19707+#include "hi_vdmav100.h" 19708+#include "hi_vdma.h" 19709+ 19710+#define user_addr(ptr) (((uintptr_t)ptr < TASK_SIZE) \ 19711+ && ((uintptr_t)ptr > 0)) 19712+ 19713+int vdma_flag = 0; 19714+EXPORT_SYMBOL(vdma_flag); 19715+ 19716+void __iomem *hi_reg_vdma_base_va; 19717+ 19718+spinlock_t my_lock; 19719+spinlock_t reg_lock; 19720+ 19721+unsigned int irq_flag; 19722+ 19723+unsigned int wake_channel_flag[DMAC_MAX_CHANNELS]; 19724+ 19725+wait_queue_head_t dmac_wait_queue[DMAC_MAX_CHANNELS]; 19726+ 19727+int hi_g_channel_status[DMAC_MAX_CHANNELS]; 19728+ 19729+/* 19730+ * dmac interrupt handle function 19731+ */ 19732+irqreturn_t vdma_isr(int irq, void *dev_id) 19733+{ 19734+ unsigned int dma_intr_status, channel_intr_status; 19735+ unsigned int i; 19736+ 19737+ if (hi_reg_vdma_base_va == NULL) 19738+ return -1; 19739+ dmac_readw(hi_reg_vdma_base_va + DMAC_INT_STATUS, dma_intr_status); 19740+ 19741+ /* decide which channel has trigger the interrupt */ 19742+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 19743+ if (((dma_intr_status >> i) & 0x1) == 1) { 19744+ dmac_readw(hi_reg_vdma_base_va 19745+ + DMAC_CxINTR_RAW(i), 19746+ channel_intr_status); 19747+ 19748+ /* clear the channel error interrupt */ 19749+ dmac_writew(hi_reg_vdma_base_va 19750+ + DMAC_CxINTR_RAW(i), 19751+ channel_intr_status); 19752+ 19753+ if ((channel_intr_status & CX_INT_STAT) 19754+ == CX_INT_STAT) { 19755+ /* transfer finish interrupt */ 19756+ if ((channel_intr_status & CX_INT_TC_RAW) 19757+ == CX_INT_TC_RAW) { 19758+ wake_channel_flag[i] = DMA_TRANS_OK; 19759+ 19760+ /* save the current channel transfer * 19761+ * status to hi_g_channel_status[i] */ 19762+ hi_g_channel_status[i] = 19763+ DMAC_CHN_SUCCESS; 19764+ 19765+ wake_up(&dmac_wait_queue[i]); 19766+ goto exit; 19767+ } 19768+ 19769+ wake_channel_flag[i] = DMA_TRANS_FAULT; 19770+ pr_err("%d channel!,intr_raw=%x\n", 19771+ i, channel_intr_status); 19772+ hi_g_channel_status[i] = 19773+ -DMAC_CHN_CONFIG_ERROR; 19774+ 19775+ wake_up(&dmac_wait_queue[i]); 19776+ goto exit; 19777+ } 19778+ } 19779+ } 19780+ 19781+exit: 19782+ return IRQ_HANDLED; 19783+} 19784+ 19785+/* 19786+ * allocate channel. 19787+ */ 19788+int hi_vdma_channel_allocate(void *pisr) 19789+{ 19790+ unsigned int i, channelinfo, tmp, channel_intr; 19791+ unsigned long flags; 19792+ 19793+ spin_lock_irqsave(&my_lock, flags); 19794+ 19795+ if (hi_reg_vdma_base_va == NULL) 19796+ return 0; 19797+ dmac_readw(hi_reg_vdma_base_va + DMAC_CHANNEL_STATUS, channelinfo); 19798+ 19799+ for (i = 0; i < CHANNEL_NUM; i++) { 19800+ if (hi_g_channel_status[i] == DMAC_CHN_VACANCY) { 19801+ dmac_readw(hi_reg_vdma_base_va + DMAC_CxINTR_RAW(i), 19802+ channel_intr); 19803+ tmp = channelinfo >> i; 19804+ /* check the vdma channel data transfer is finished ? */ 19805+ if (((tmp & 0x01) == 0x00) && (channel_intr == 0x00)) { 19806+ hi_g_channel_status[i] = DMAC_CHN_ALLOCAT; 19807+ spin_unlock_irqrestore(&my_lock, flags); 19808+ return i; /* return channel number */ 19809+ } 19810+ } 19811+ } 19812+ 19813+ spin_unlock_irqrestore(&my_lock, flags); 19814+ return DMAC_CHANNEL_INVALID; 19815+} 19816+ 19817+/* 19818+ * free channel 19819+ */ 19820+int hi_vdma_channel_free(unsigned int channel) 19821+{ 19822+ hi_g_channel_status[channel] = DMAC_CHN_VACANCY; 19823+ 19824+ return 0; 19825+} 19826+ 19827+/* 19828+ * channel enable 19829+ * start a vdma transfer immediately 19830+ */ 19831+int hi_vdma_channelstart(unsigned int channel, 19832+ const unsigned int *src, const unsigned int *dest) 19833+{ 19834+ struct mm_struct *mm = NULL; 19835+ unsigned int reg[DMAC_MAX_CHANNELS]; 19836+ 19837+ if (channel >= DMAC_MAX_CHANNELS) { 19838+ pr_err("channel number is out of scope(%d).\n", 19839+ DMAC_MAX_CHANNELS); 19840+ return -EINVAL; 19841+ } 19842+ 19843+ hi_g_channel_status[channel] = DMAC_NOT_FINISHED; 19844+ 19845+ mm = current->mm; 19846+ if (!mm) { 19847+ mm = &init_mm; 19848+ } 19849+ 19850+ if (mm->pgd == NULL) 19851+ return -EINVAL; 19852+ /* set ttbr */ 19853+ /* get TTBR from the page */ 19854+ reg[channel] = __pa(mm->pgd); 19855+ 19856+ /* only [31:10] is the ttbr */ 19857+ reg[channel] &= 0xfffffc00; 19858+ 19859+ /* set the RGN,AFE,AFFD,TRE */ 19860+ reg[channel] |= TTB_RGN | AFE | TRE; 19861+ 19862+ if (user_addr(dest)) { 19863+ reg[channel] &= ~DEST_IS_KERNEL; 19864+ } else { 19865+ reg[channel] |= DEST_IS_KERNEL; 19866+ } 19867+ 19868+ if (user_addr(src)) { 19869+ reg[channel] &= ~SRC_IS_KERNEL; 19870+ } else { 19871+ reg[channel] |= SRC_IS_KERNEL; 19872+ } 19873+ 19874+ if (in_atomic() || in_interrupt()) { 19875+ /* disable the channel interrupt */ 19876+ reg[channel] &= ~DMAC_INTR_ENABLE; 19877+ } else { 19878+ /* enable the channel interrupt */ 19879+ reg[channel] |= DMAC_INTR_ENABLE; 19880+ } 19881+ 19882+ reg[channel] |= DMAC_CHANNEL_ENABLE; 19883+ 19884+ if (hi_reg_vdma_base_va == NULL) 19885+ return 0; 19886+ /* set the TTBR register */ 19887+ dmac_writew(hi_reg_vdma_base_va + DMAC_CxTTBR(channel), 19888+ reg[channel]); 19889+ return 0; 19890+} 19891+ 19892+/* 19893+ * Apply VDMA interrupt resource 19894+ * init channel state 19895+ */ 19896+int hi_vdma_driver_init(struct hivdmac_host *dma) 19897+{ 19898+ unsigned int i; 19899+ unsigned int tmp_reg = 0; 19900+ 19901+ if (hi_reg_vdma_base_va == NULL) 19902+ return 0; 19903+ dmac_readw(hi_reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg); 19904+ tmp_reg |= AUTO_CLK_GT_EN; 19905+ dmac_writew(hi_reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg); 19906+ 19907+ /* set rd dust address is ram 0 */ 19908+ dmac_writew(hi_reg_vdma_base_va + DMAC_RD_DUSTB_ADDR, 0x04c11000); 19909+ 19910+ /* set wr dust address is ram 0x1000 */ 19911+ dmac_writew(hi_reg_vdma_base_va + DMAC_WR_DUSTB_ADDR, 0x04c11000); 19912+ 19913+ /* set prrr register */ 19914+ dmac_writew(hi_reg_vdma_base_va + DMAC_MMU_PRRR, PRRR); 19915+ /* set nmrr register */ 19916+ dmac_writew(hi_reg_vdma_base_va + DMAC_MMU_NMRR, NMRR); 19917+ 19918+ /* config global reg for VDMA */ 19919+ tmp_reg |= EVENT_BROADCAST_EN | WR_CMD_NUM_PER_ARB | 19920+ RD_CMD_NUM_PER_ARB | WR_OTD_NUM | RD_OTD_NUM | WFE_EN; 19921+ dmac_writew(hi_reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg); 19922+ 19923+ for (i = 0; i < CHANNEL_NUM; i++) { 19924+ hi_g_channel_status[i] = DMAC_CHN_VACANCY; 19925+ init_waitqueue_head(&dmac_wait_queue[i]); 19926+ } 19927+ 19928+ spin_lock_init(&my_lock); 19929+ spin_lock_init(®_lock); 19930+ 19931+ return 0; 19932+} 19933+ 19934+/* 19935+ * wait for transfer end 19936+ */ 19937+int hi_vdma_wait(unsigned int channel) 19938+{ 19939+ unsigned long data_jiffies_timeout = jiffies + DMA_TIMEOUT_HZ; 19940+ unsigned int channel_intr_raw; 19941+ 19942+ while (1) { 19943+ if (hi_reg_vdma_base_va == NULL) 19944+ return 0; 19945+ /* read the status of current interrupt */ 19946+ dmac_readw(hi_reg_vdma_base_va + DMAC_CxINTR_RAW(channel), 19947+ channel_intr_raw); 19948+ 19949+ /* clear the interrupt */ 19950+ dmac_writew(hi_reg_vdma_base_va 19951+ + DMAC_CxINTR_RAW(channel), 19952+ channel_intr_raw); 19953+ 19954+ if (channel >= DMAC_MAX_CHANNELS) 19955+ return 0; 19956+ /* save the current channel transfer status to * 19957+ * hi_g_channel_status[i] */ 19958+ if ((channel_intr_raw & CX_INT_STAT) == CX_INT_STAT) { 19959+ /* transfer finish interrupt */ 19960+ if ((channel_intr_raw & CX_INT_TC_RAW) == 19961+ CX_INT_TC_RAW) { 19962+ hi_g_channel_status[channel] = DMAC_CHN_SUCCESS; 19963+ return DMAC_CHN_SUCCESS; 19964+ } 19965+ 19966+ /* transfer abort interrupt */ 19967+ pr_debug("data transfer error in VDMA %x channel!", 19968+ channel); 19969+ pr_debug("intr_raw=%x\n", channel_intr_raw); 19970+ hi_g_channel_status[channel] = 19971+ -DMAC_CHN_CONFIG_ERROR; 19972+ return -DMAC_CHN_CONFIG_ERROR; 19973+ } 19974+ 19975+ if (!time_before(jiffies, data_jiffies_timeout)) { /* timeout */ 19976+ pr_err("wait interrupt timeout, channel=%d, func:%s, line:%d\n", 19977+ channel, __func__, __LINE__); 19978+ return -1; 19979+ } 19980+ } 19981+ 19982+ return -1; 19983+} 19984+ 19985+/* 19986+ * execute memory to memory vdma transfer 19987+ */ 19988+static int hi_vdma_m2m_transfer(const unsigned int *psource, 19989+ const unsigned int *pdest, 19990+ unsigned int uwtransfersize) 19991+{ 19992+ unsigned int ulchnn; 19993+ int ret = 0; 19994+ 19995+ ulchnn = (unsigned int)hi_vdma_channel_allocate(NULL); 19996+ 19997+ if (ulchnn == DMAC_CHANNEL_INVALID) { 19998+ pr_err("DMAC_CHANNEL_INVALID.\n"); 19999+ 20000+ return -1; 20001+ } 20002+ 20003+ wake_channel_flag[ulchnn] = 0; 20004+ 20005+ dmac_writew(hi_reg_vdma_base_va + DMAC_CxLENGTH(ulchnn), 20006+ uwtransfersize); 20007+ dmac_writew(hi_reg_vdma_base_va + DMAC_CxSRCADDR(ulchnn), 20008+ (uintptr_t)psource); 20009+ dmac_writew(hi_reg_vdma_base_va + DMAC_CxDESTADDR(ulchnn), 20010+ (uintptr_t)pdest); 20011+ 20012+ if (hi_vdma_channelstart(ulchnn, psource, pdest) != 0) { 20013+ ret = -1; 20014+ goto exit; 20015+ } 20016+ 20017+ if (hi_vdma_wait(ulchnn) != DMAC_CHN_SUCCESS) { 20018+ ret = -1; 20019+ goto exit; 20020+ } 20021+ 20022+exit: 20023+ hi_vdma_channel_free(ulchnn); 20024+ 20025+ return ret; 20026+} 20027+EXPORT_SYMBOL(hi_vdma_m2m_transfer); 20028+ 20029+int hi_vdma_m2m_copy(void *dst, const void *src, size_t count) 20030+{ 20031+ int ret; 20032+ 20033+ if (((uintptr_t)dst & 0xff) || ((uintptr_t)src & 0xff)) { 20034+ return -1; 20035+ } 20036+ if (((uintptr_t)src < (uintptr_t)dst) && 20037+ (((uintptr_t)src + count) > (uintptr_t)dst)) { 20038+ return -1; 20039+ } 20040+ if (((uintptr_t)src >= (uintptr_t)dst) && 20041+ ((uintptr_t)src < ((uintptr_t)dst + count))) { 20042+ return -1; 20043+ } 20044+ if (abs((uintptr_t)dst - (uintptr_t)src) < PAGE_SIZE) { 20045+ return -1; 20046+ } 20047+ 20048+ ret = hi_vdma_m2m_transfer((unsigned int *)src, dst, count); 20049+ 20050+ if (ret < 0) { 20051+ return ret; 20052+ } else { 20053+ return 0; 20054+ } 20055+} 20056+EXPORT_SYMBOL(hi_vdma_m2m_copy); 20057+ 20058+static int hivdmac_probe(struct platform_device *platdev) 20059+{ 20060+ unsigned int i; 20061+ struct hivdmac_host *dma = NULL; 20062+ struct resource *res = NULL; 20063+ int ret; 20064+ dma = devm_kzalloc(&platdev->dev, sizeof(*dma), GFP_KERNEL); 20065+ if (!dma) { 20066+ return -ENOMEM; 20067+ } 20068+ 20069+ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); 20070+ if (!res) { 20071+ dev_err(&platdev->dev, "no mmio resource\n"); 20072+ return -ENODEV; 20073+ } 20074+ 20075+ dma->regbase = devm_ioremap_resource(&platdev->dev, res); 20076+ if (IS_ERR(dma->regbase)) { 20077+ return PTR_ERR(dma->regbase); 20078+ } 20079+ 20080+ dma->clk = devm_clk_get(&platdev->dev, NULL); 20081+ if (IS_ERR(dma->clk)) { 20082+ return PTR_ERR(dma->clk); 20083+ } 20084+ 20085+ clk_prepare_enable(dma->clk); 20086+ 20087+ dma->rstc = devm_reset_control_get(&platdev->dev, "dma-reset"); 20088+ if (IS_ERR(dma->rstc)) { 20089+ return PTR_ERR(dma->rstc); 20090+ } 20091+ 20092+ dma->irq = platform_get_irq(platdev, 0); 20093+ if (unlikely(dma->irq < 0)) { 20094+ return -ENODEV; 20095+ } 20096+ hi_reg_vdma_base_va = dma->regbase; 20097+ pr_debug("vdma reg base is %p\n", hi_reg_vdma_base_va); 20098+ dma->dev = &platdev->dev; 20099+ 20100+ ret = hi_vdma_driver_init(dma); 20101+ if (ret) { 20102+ return -ENODEV; 20103+ } 20104+ 20105+ platform_set_drvdata(platdev, dma); 20106+ 20107+ for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) { 20108+ hi_g_channel_status[i] = DMAC_CHN_VACANCY; 20109+ } 20110+ 20111+ vdma_flag = 1; 20112+ printk("hivdmav100 driver inited.\n"); 20113+ return ret; 20114+} 20115+ 20116+static int hivdmac_remove(struct platform_device *platdev) 20117+{ 20118+ int i; 20119+ struct hivdmac_host *dma = platform_get_drvdata(platdev); 20120+ 20121+ clk_disable_unprepare(dma->clk); 20122+ 20123+ for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) { 20124+ hi_g_channel_status[i] = DMAC_CHN_VACANCY; 20125+ } 20126+ 20127+ vdma_flag = 0; 20128+ printk("hivdmav100 driver deinited.\n"); 20129+ 20130+ return 0; 20131+} 20132+ 20133+static int hivdmac_suspend(struct platform_device *platdev, 20134+ pm_message_t state) 20135+{ 20136+ int i; 20137+ struct hivdmac_host *dma = platform_get_drvdata(platdev); 20138+ 20139+ clk_prepare_enable(dma->clk); 20140+ 20141+ for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) { 20142+ hi_g_channel_status[i] = DMAC_CHN_VACANCY; 20143+ } 20144+ 20145+ clk_disable_unprepare(dma->clk); 20146+ 20147+ vdma_flag = 0; 20148+ 20149+ return 0; 20150+} 20151+ 20152+static int hivdmac_resume(struct platform_device *platdev) 20153+{ 20154+ int i; 20155+ struct hivdmac_host *dma = platform_get_drvdata(platdev); 20156+ 20157+ hi_vdma_driver_init(dma); 20158+ 20159+ for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) { 20160+ hi_g_channel_status[i] = DMAC_CHN_VACANCY; 20161+ } 20162+ 20163+ vdma_flag = 1; 20164+ 20165+ return 0; 20166+} 20167+ 20168+static const struct of_device_id hisi_vdmac_dt_ids[] = { 20169+ {.compatible = "hisilicon,hisi-vdmac"}, 20170+ { }, 20171+}; 20172+MODULE_DEVICE_TABLE(of, hisi_vdmac_dt_ids); 20173+ 20174+static struct platform_driver hisi_vdmac_driver = { 20175+ .driver = { 20176+ .name = "hisi-vdmac", 20177+ .of_match_table = hisi_vdmac_dt_ids, 20178+ }, 20179+ .probe = hivdmac_probe, 20180+ .remove = hivdmac_remove, 20181+ .suspend = hivdmac_suspend, 20182+ .resume = hivdmac_resume, 20183+}; 20184+ 20185+module_platform_driver(hisi_vdmac_driver); 20186+ 20187+MODULE_LICENSE("GPL"); 20188+MODULE_AUTHOR("BVT_OSDRV"); 20189diff --git a/drivers/hi_vdmav100/hi_vdmav100.h b/drivers/hi_vdmav100/hi_vdmav100.h 20190new file mode 100644 20191index 000000000..8b8d3e6c0 20192--- /dev/null 20193+++ b/drivers/hi_vdmav100/hi_vdmav100.h 20194@@ -0,0 +1,122 @@ 20195+/* 20196+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd. 20197+ * 20198+ * This program is free software; you can redistribute it and/or modify 20199+ * it under the terms of the GNU General Public License as published by 20200+ * the Free Software Foundation; either version 2 of the License, or 20201+ * (at your option) any later version. 20202+ * 20203+ * This program is distributed in the hope that it will be useful, 20204+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 20205+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20206+ * GNU General Public License for more details. 20207+ * 20208+ * You should have received a copy of the GNU General Public License 20209+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 20210+ */ 20211+#ifndef __HI_VDMA_H__ 20212+#define __HI_VDMA_H__ 20213+ 20214+#define dmac_writew(addr, value) \ 20215+ ((*(volatile unsigned int *)(addr)) = (value)) 20216+ 20217+#define dmac_readw(addr, v) \ 20218+ (v = (*(volatile unsigned int *)(addr))) 20219+ 20220+#define DMAC_GLOBLE_CTRL 0x000 20221+#define WFE_EN (0x1 << 23) 20222+#define EVENT_BROADCAST_EN (0x1 << 21) 20223+#define AUTO_CLK_GT_EN (0x1 << 17) 20224+#define AUTO_PRI_EN (0x1 << 16) 20225+#define WR_CMD_NUM_PER_ARB (0x4 << 12) 20226+#define RD_CMD_NUM_PER_ARB (0x4 << 8) 20227+#define WR_OTD_NUM (0xF << 4) 20228+#define RD_OTD_NUM (0xF) 20229+ 20230+#define DMAC_PRI_THRESHOLD 0x004 20231+/* PRRR and NMRR define */ 20232+#define DMAC_MMU_NMRR 0x008 20233+#define DMAC_MMU_PRRR 0x00C 20234+/* read and write dustb address register define */ 20235+#define DMAC_RD_DUSTB_ADDR 0x010 20236+#define DMAC_WR_DUSTB_ADDR 0x014 20237+/* channel status register define */ 20238+#define DMAC_CHANNEL_STATUS 0x01c 20239+#define DMAC_WORK_DURATION 0x020 20240+#define DMAC_INT_STATUS 0x02c 20241+/* the definition for DMAC channel register */ 20242+#define DMAC_CHANNEL_BASE 0x100 20243+#define DMAC_CxSRCADDR(i) (DMAC_CHANNEL_BASE + 0x00 + 0x20 * i) 20244+#define DMAC_CxDESTADDR(i) (DMAC_CHANNEL_BASE + 0x04 + 0x20 * i) 20245+#define DMAC_CxLENGTH(i) (DMAC_CHANNEL_BASE + 0x08 + 0x20 * i) 20246+#define DMAC_CxTTBR(i) (DMAC_CHANNEL_BASE + 0x0C + 0x20 * i) 20247+#define DMAC_CxMISC(i) (DMAC_CHANNEL_BASE + 0x10 + 0x20 * i) 20248+#define DMAC_CxINTR_RAW(i) (DMAC_CHANNEL_BASE + 0x14 + 0x20 * i) 20249+#define CX_INT_STAT (0x1 << 4) 20250+#define CX_INT_TC_RAW (0x1 << 3) 20251+#define CX_INT_TE_RAW (0x1 << 2) 20252+#define CX_INT_TM_RAW (0x1 << 1) 20253+#define CX_INT_AP_RAW (0x1 << 0) 20254+ 20255+#define DMAC_INTR_ENABLE (0x1 << 8) 20256+ 20257+/* channel enable */ 20258+#define DMAC_CHANNEL_ENABLE (0x1 << 9) 20259+ 20260+/* access flag enable */ 20261+#define AFE (0x1 << 6) 20262+ 20263+/* user and kernel define */ 20264+#define DEST_IS_KERNEL (0x1 << 2) 20265+#define SRC_IS_KERNEL (0x1 << 1) 20266+ 20267+/* for TTBR */ 20268+#define TTB_RGN (0x1 << 3) /* outer cache write back allocate */ 20269+ 20270+/* for ap and cache remap */ 20271+ 20272+/* remap enable,ap access check enable */ 20273+#define TRE 0x001 20274+ 20275+#define PRRR 0xff0a81a8 20276+#define NMRR 0x40e040e0 20277+ 20278+#define DMAC_SYNC_VAL 0x0 20279+ 20280+/* definition for the return value */ 20281+#define DMAC_ERROR_BASE 100 20282+#define DMAC_CHANNEL_INVALID (DMAC_ERROR_BASE + 1) 20283+ 20284+#define DMAC_TRXFERSIZE_INVALID (DMAC_ERROR_BASE + 2) 20285+#define DMAC_SOURCE_ADDRESS_INVALID (DMAC_ERROR_BASE + 3) 20286+#define DMAC_DESTINATION_ADDRESS_INVALID (DMAC_ERROR_BASE + 4) 20287+#define DMAC_MEMORY_ADDRESS_INVALID (DMAC_ERROR_BASE + 5) 20288+#define DMAC_PERIPHERAL_ID_INVALID (DMAC_ERROR_BASE + 6) 20289+#define DMAC_DIRECTION_ERROR (DMAC_ERROR_BASE + 7) 20290+#define DMAC_TRXFER_ERROR (DMAC_ERROR_BASE + 8) 20291+#define DMAC_LLIHEAD_ERROR (DMAC_ERROR_BASE + 9) 20292+#define DMAC_SWIDTH_ERROR (DMAC_ERROR_BASE + 0xa) 20293+#define DMAC_LLI_ADDRESS_INVALID (DMAC_ERROR_BASE + 0xb) 20294+#define DMAC_TRANS_CONTROL_INVALID (DMAC_ERROR_BASE + 0xc) 20295+#define DMAC_MEMORY_ALLOCATE_ERROR (DMAC_ERROR_BASE + 0xd) 20296+#define DMAC_NOT_FINISHED (DMAC_ERROR_BASE + 0xe) 20297+ 20298+#define DMAC_TIMEOUT (DMAC_ERROR_BASE + 0xf) 20299+#define DMAC_CHN_SUCCESS (DMAC_ERROR_BASE + 0x10) 20300+#define DMAC_CHN_CONFIG_ERROR (DMAC_ERROR_BASE + 0x11) 20301+#define DMAC_CHN_DATA_ERROR (DMAC_ERROR_BASE + 0x12) 20302+#define DMAC_CHN_TIMEOUT (DMAC_ERROR_BASE + 0x13) 20303+#define DMAC_CHN_ALLOCAT (DMAC_ERROR_BASE + 0x14) 20304+#define DMAC_CHN_VACANCY (DMAC_ERROR_BASE + 0x15) 20305+ 20306+#define DMAC_MAX_CHANNELS CONFIG_HI_VDMA_CHN_NUM 20307+ 20308+#define CHANNEL_NUM DMAC_MAX_CHANNELS 20309+ 20310+#define DMA_TRANS_OK 0x1 20311+#define DMA_PAGE_FAULT 0x2 20312+#define DMA_TRANS_FAULT 0x3 20313+#define DMA_TIMEOUT_HZ (3 * HZ) 20314+ 20315+extern int g_channel_status[DMAC_MAX_CHANNELS]; 20316+#endif 20317diff --git a/drivers/hi_vdmav100/hi_vdmav100_misc.c b/drivers/hi_vdmav100/hi_vdmav100_misc.c 20318new file mode 100644 20319index 000000000..777a7c47c 20320--- /dev/null 20321+++ b/drivers/hi_vdmav100/hi_vdmav100_misc.c 20322@@ -0,0 +1,109 @@ 20323+/* 20324+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd. 20325+ * 20326+ * This program is free software; you can redistribute it and/or modify 20327+ * it under the terms of the GNU General Public License as published by 20328+ * the Free Software Foundation; either version 2 of the License, or 20329+ * (at your option) any later version. 20330+ * 20331+ * This program is distributed in the hope that it will be useful, 20332+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 20333+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20334+ * GNU General Public License for more details. 20335+ * 20336+ * You should have received a copy of the GNU General Public License 20337+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 20338+ */ 20339+ 20340+#include <linux/init.h> 20341+#include <linux/module.h> 20342+#include <linux/delay.h> 20343+#include <linux/vmalloc.h> 20344+#include <asm/pgtable.h> 20345+#include <linux/slab.h> 20346+#include <linux/mm.h> 20347+#include <asm/page.h> 20348+#include <linux/spinlock.h> 20349+#include <linux/kernel.h> 20350+#include <linux/ioctl.h> 20351+#include <linux/slab.h> 20352+#include <linux/fs.h> 20353+#include <linux/miscdevice.h> 20354+#include <linux/mm_types.h> 20355+#include <linux/mmu_context.h> 20356+#include <asm/tlbflush.h> 20357+#include <linux/uaccess.h> 20358+ 20359+#include "hi_vdma.h" 20360+ 20361+#define hidmac_error(s...) do { \ 20362+ pr_err("hidmac:%s:%d: ", __func__, __LINE__); \ 20363+ printk(s); \ 20364+ printk("\n"); \ 20365+} while (0) 20366+ 20367+ 20368+static long hi_vdma_ioctl(struct file *filep, unsigned int cmd, 20369+ unsigned long arg) 20370+{ 20371+ long ret = 0; 20372+ struct dmac_user_para para; 20373+ 20374+ if (copy_from_user((void *)¶, (void *)(uintptr_t)arg, sizeof(para))) { 20375+ return -EINVAL; 20376+ } 20377+ 20378+ switch (cmd) { 20379+ case VDMA_DATA_CMD: 20380+ ret = hi_vdma_m2m_copy((void *)para.dst, (void *)para.src, para.size); 20381+ break; 20382+ default: 20383+ hidmac_error("unknown command :%x\n", cmd); 20384+ ret = -1; 20385+ break; 20386+ } 20387+ 20388+ return ret; 20389+} 20390+ 20391+static int hi_vdma_open(struct inode *inode, struct file *file) 20392+{ 20393+ return 0; 20394+} 20395+ 20396+static int hi_vdma_release(struct inode *inode, struct file *file) 20397+{ 20398+ return 0; 20399+} 20400+ 20401+static const struct file_operations hi_vdma_fops = { 20402+ .owner = THIS_MODULE, 20403+ .unlocked_ioctl = hi_vdma_ioctl, 20404+ .open = hi_vdma_open, 20405+ .release = hi_vdma_release, 20406+}; 20407+ 20408+static struct miscdevice hi_vdma_misc_device = { 20409+ .minor = MISC_DYNAMIC_MINOR, 20410+ .name = "hi_vdma", 20411+ .fops = &hi_vdma_fops, 20412+}; 20413+ 20414+static int __init hi_vdma_init(void) 20415+{ 20416+ int ret; 20417+ 20418+ ret = misc_register(&hi_vdma_misc_device); 20419+ 20420+ return ret; 20421+} 20422+ 20423+static void __exit hi_vdma_exit(void) 20424+{ 20425+ misc_deregister(&hi_vdma_misc_device); 20426+} 20427+ 20428+module_init(hi_vdma_init); 20429+module_exit(hi_vdma_exit); 20430+MODULE_LICENSE("GPL"); 20431+MODULE_DESCRIPTION("Hisilicon VDMA MISC Driver"); 20432diff --git a/drivers/hidmac/Kconfig b/drivers/hidmac/Kconfig 20433new file mode 100644 20434index 000000000..dcb3e08bf 20435--- /dev/null 20436+++ b/drivers/hidmac/Kconfig 20437@@ -0,0 +1,21 @@ 20438+# 20439+# Sensor device configuration 20440+# 20441+ 20442+config HI_DMAC 20443+ tristate "Hisilicon DMAC Controller support" 20444+ depends on (ARCH_HISI_BVT) 20445+ help 20446+ The Direction Memory Access(DMA) is a high-speed data transfer 20447+ operation. It supports data read/write between peripherals and 20448+ memories without using the CPU. 20449+ Hisilicon DMA Controller(DMAC) directly transfers data between 20450+ a memory and a peripheral, between peripherals, or between memories. 20451+ This avoids the CPU intervention and reduces the interrupt handling 20452+ overhead of the CPU. 20453+ 20454+if HI_DMAC 20455+config HI_DMAC_CHANNEL_NUM 20456+ int "hi dmac channel num" 20457+ default "4" 20458+endif 20459diff --git a/drivers/hidmac/Makefile b/drivers/hidmac/Makefile 20460new file mode 100644 20461index 000000000..7e41f4c37 20462--- /dev/null 20463+++ b/drivers/hidmac/Makefile 20464@@ -0,0 +1,6 @@ 20465+# 20466+# Makefile for the hi dmac drivers. 20467+# 20468+ 20469+obj-$(CONFIG_HI_DMAC) += hi_pl08x.o 20470+ 20471diff --git a/drivers/hidmac/hi_pl08x.c b/drivers/hidmac/hi_pl08x.c 20472new file mode 100644 20473index 000000000..4281caf7e 20474--- /dev/null 20475+++ b/drivers/hidmac/hi_pl08x.c 20476@@ -0,0 +1,1303 @@ 20477+/* 20478+ * 20479+ * Copyright (c) 2017 HiSilicon Technologies Co., Ltd. 20480+ * 20481+ * This program is free software; you can redistribute it and/or modify 20482+ * it under the terms of the GNU General Public License as published by 20483+ * the Free Software Foundation; either version 2 of the License, or 20484+ * (at your option) any later version. 20485+ * 20486+ * This program is distributed in the hope that it will be useful, 20487+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 20488+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20489+ * GNU General Public License for more details. 20490+ * 20491+ * You should have received a copy of the GNU General Public License 20492+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 20493+ * 20494+ */ 20495+ 20496+#include <linux/gfp.h> 20497+#include <linux/kernel.h> 20498+#include <linux/module.h> 20499+#include <linux/i2c.h> 20500+#include <linux/init.h> 20501+#include <linux/time.h> 20502+#include <linux/interrupt.h> 20503+#include <linux/delay.h> 20504+#include <linux/errno.h> 20505+#include <linux/err.h> 20506+#include <linux/platform_device.h> 20507+#include <linux/dma-mapping.h> 20508+#include <linux/pm_runtime.h> 20509+#include <linux/slab.h> 20510+#include <linux/of.h> 20511+#include <linux/clk.h> 20512+#include <linux/reset.h> 20513+#include <asm/io.h> 20514+#include <linux/hidmac.h> 20515+ 20516+#include "hi_pl08x.h" 20517+ 20518+#ifdef CONFIG_ARCH_HI3536DV100 20519+#include "hidmac_hi3536dv100.h" 20520+#endif 20521+ 20522+#ifdef CONFIG_ARCH_HI3518EV20X 20523+#include "hidmac_hi3518ev20x.h" 20524+#endif 20525+ 20526+#ifdef CONFIG_ARCH_HI3516A 20527+#include "hidmac_hi3516a.h" 20528+#endif 20529+ 20530+#ifdef CONFIG_ARCH_HI3521A 20531+#include "hidmac_hi3521a.h" 20532+#endif 20533+ 20534+#ifdef CONFIG_ARCH_HI3531A 20535+#include "hidmac_hi3531a.h" 20536+#endif 20537+ 20538+#define RX 0 20539+#define TX 1 20540+static int dmac_channel[CHANNEL_NUM] = {0, 1, 2, 3}; 20541+int g_channel_status[CHANNEL_NUM]; 20542+ 20543+/* #define DEBUG */ 20544+ 20545+#define DEBUG 20546+#ifdef DEBUG 20547+#define dma_err printk 20548+#else 20549+#define dma_err(fmt, ...) do {} while (0) 20550+#endif 20551+ 20552+/* 20553+ * Define Memory range 20554+ */ 20555+mem_addr mem_num[MEM_MAX_NUM] = { 20556+ {DDRAM_ADRS, DDRAM_SIZE}, 20557+ {FLASH_BASE, FLASH_SIZE} 20558+}; 20559+ 20560+typedef void REG_ISR(int *p_dma_chn, int *p_dma_status); 20561+REG_ISR *function[CHANNEL_NUM]; 20562+ 20563+struct hidmac_host { 20564+ struct clk *clk; 20565+ struct reset_control *rstc; 20566+ void __iomem *regbase; 20567+ 20568+ int irq; 20569+}; 20570+ 20571+void __iomem *dma_regbase; 20572+unsigned int pllihead[2]; 20573+ 20574+#define CLR_INT(i) ((*(unsigned int *)(dma_regbase+0x008)) = (1 << i)) 20575+ 20576+/* 20577+ * dmac interrupt handle function 20578+ */ 20579+irqreturn_t dmac_isr(int irq, void *dev_id) 20580+{ 20581+ struct hidmac_host *dma = dev_id; 20582+ unsigned int channel_status; 20583+ unsigned int channel_tc_status, channel_err_status; 20584+ unsigned int i; 20585+ 20586+ /* read the status of current interrupt */ 20587+ dmac_readw(dma->regbase + DMAC_INTSTATUS, channel_status); 20588+ 20589+ /* decide which channel has trigger the interrupt */ 20590+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 20591+ if ((((channel_status >> i) & 0x1) == 0x01)) { 20592+ /* The INT status should be read first then clear it */ 20593+ dmac_readw(dma->regbase + DMAC_INTTCSTATUS, channel_tc_status); 20594+ dmac_readw(dma->regbase + DMAC_INTERRORSTATUS, channel_err_status); 20595+ CLR_INT(i); 20596+ if (g_channel_status[i] == DMAC_CHN_VACANCY 20597+ && (function[i]) == NULL) { 20598+ if ((0x01 == ((channel_tc_status >> i) & 0x01))) 20599+ dmac_writew(dma->regbase + DMAC_INTTCCLEAR, 20600+ (0x01 << i)); 20601+ else if ((0x01 == ((channel_err_status 20602+ >> i) & 0x01))) 20603+ dmac_writew(dma->regbase + DMAC_INTERRCLR, 20604+ (0x01 << i)); 20605+ continue; 20606+ } 20607+ 20608+ /* save the current channel transfer */ 20609+ /* status to g_channel_status[i] */ 20610+ if ((0x01 == ((channel_tc_status >> i) & 0x01))) { 20611+ g_channel_status[i] = DMAC_CHN_SUCCESS; 20612+ dmac_writew(dma->regbase + DMAC_INTTCCLEAR, (0x01 << i)); 20613+ } else if ((0x01 == ((channel_err_status >> i) & 0x01))) { 20614+ g_channel_status[i] = -DMAC_CHN_ERROR; 20615+ dmac_writew(dma->regbase + DMAC_INTERRCLR, (0x01 << i)); 20616+ } else { 20617+ pr_err("Isr Error in DMAC_IntHandeler"); 20618+ pr_err("%d! channel\n", i); 20619+ } 20620+ 20621+ if ((function[i]) != NULL) { 20622+ function[i](&i, &g_channel_status[i]); 20623+ } 20624+ } 20625+ } 20626+ 20627+ return IRQ_RETVAL(1); 20628+} 20629+ 20630+/* 20631+ * update the state of channels 20632+ */ 20633+#define HI_DMA_UPDATE_TIMEOUT 5000000 20634+static int dma_update_status(unsigned int channel) 20635+{ 20636+ unsigned int channel_status; 20637+ unsigned int channel_tc_status[3]; 20638+ unsigned int channel_err_status[3]; 20639+ unsigned int i = channel; 20640+ unsigned int time = 0; 20641+ unsigned int j; 20642+ 20643+ while (1) { 20644+ for (j = 0; j < 3; j++) { 20645+ dmac_readw(dma_regbase + DMAC_RAWINTTCSTATUS, channel_status); 20646+ channel_tc_status[j] = (channel_status >> i) & 0x01; 20647+ dmac_readw(dma_regbase + DMAC_RAWINTERRORSTATUS, channel_status); 20648+ channel_err_status[j] = (channel_status >> i) & 0x01; 20649+ } 20650+ 20651+ if ((channel_tc_status[0] == 0x1) && 20652+ (channel_tc_status[1] == 0x1) && 20653+ (channel_tc_status[2] == 0x1)) { 20654+ g_channel_status[i] = DMAC_CHN_SUCCESS; 20655+ dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x01 << i)); 20656+ break; 20657+ } else if ((channel_err_status[0] == 0x1) && 20658+ (channel_err_status[1] == 0x1) && 20659+ (channel_err_status[2] == 0x1)) { 20660+ g_channel_status[i] = -DMAC_CHN_ERROR; 20661+ dma_err("Error in DMAC %d finish!\n", i); 20662+ dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x01 << i)); 20663+ break; 20664+ } 20665+ 20666+ if (++time == HI_DMA_UPDATE_TIMEOUT) { 20667+ dma_err("Timeout in DMAC %d!\n", i); 20668+ g_channel_status[i] = -DMAC_CHN_TIMEOUT; 20669+ break; 20670+ } 20671+ } 20672+ 20673+ return g_channel_status[i]; 20674+} 20675+ 20676+/* 20677+ * check the state of channels 20678+ */ 20679+static int dmac_check_over(unsigned int channel) 20680+{ 20681+ int status = 0; 20682+ 20683+ if (-DMAC_CHN_ERROR == g_channel_status[channel]) { 20684+ dma_err("Error transfer %d finished\n", channel); 20685+ dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), DMAC_CxDISABLE); 20686+ g_channel_status[channel] = DMAC_CHN_VACANCY; 20687+ status = -DMAC_CHN_ERROR; 20688+ } else if (g_channel_status[channel] == DMAC_NOT_FINISHED) { 20689+ status = DMAC_NOT_FINISHED; 20690+ } else if (g_channel_status[channel] == DMAC_CHN_ALLOCAT) { 20691+ status = DMAC_CHN_ALLOCAT; 20692+ } else if (g_channel_status[channel] == DMAC_CHN_VACANCY) { 20693+ status = DMAC_CHN_VACANCY; 20694+ } else if (-DMAC_CHN_TIMEOUT == g_channel_status[channel]) { 20695+ dma_err("transfer %d timeout!\n", channel); 20696+ status = -DMAC_CHN_TIMEOUT; 20697+ } else if (g_channel_status[channel] == DMAC_CHN_SUCCESS) { 20698+ /* The transfer of Channel %d has finished successfully! */ 20699+ status = DMAC_CHN_SUCCESS; 20700+ } else { 20701+ dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), DMAC_CxDISABLE); 20702+ g_channel_status[channel] = DMAC_CHN_VACANCY; 20703+ status = -DMAC_CHN_ERROR; 20704+ } 20705+ return status; 20706+} 20707+ 20708+spinlock_t my_lcok = __SPIN_LOCK_UNLOCKED(old_style_spin_init); 20709+unsigned long flags; 20710+ 20711+/* 20712+ * allocate channel. 20713+ */ 20714+int dmac_channel_allocate(void *pisr) 20715+{ 20716+ unsigned int i, channelinfo, g_channelinfo; 20717+ 20718+ for (i = 0; i < CHANNEL_NUM; i++) { 20719+ dmac_check_over(dmac_channel[i]); 20720+ } 20721+ 20722+ dmac_readw(dma_regbase + DMAC_ENBLDCHNS, g_channelinfo); 20723+ g_channelinfo = g_channelinfo & 0x00ff; 20724+ 20725+ for (i = 0; i < CHANNEL_NUM; i++) { 20726+ if (g_channel_status[dmac_channel[i]] == DMAC_CHN_VACANCY) { 20727+ channelinfo = g_channelinfo >> dmac_channel[i]; 20728+ if (0x00 == (channelinfo & 0x01)) { 20729+ /* clear the interrupt in this channel */ 20730+ dmac_writew(dma_regbase + DMAC_INTERRCLR, 20731+ (0x01 << dmac_channel[i])); 20732+ dmac_writew(dma_regbase + DMAC_INTTCCLEAR, 20733+ (0x01 << dmac_channel[i])); 20734+ 20735+ g_channel_status[dmac_channel[i]] 20736+ = DMAC_CHN_ALLOCAT; 20737+ return dmac_channel[i]; 20738+ } 20739+ } 20740+ } 20741+ 20742+ dma_err("no to alloc\n"); 20743+ return -EINVAL; 20744+} 20745+EXPORT_SYMBOL(dmac_channel_allocate); 20746+ 20747+int dmac_register_isr(unsigned int channel, void *pisr) 20748+{ 20749+ if (channel > CHANNEL_NUM - 1) { 20750+ dma_err("channel which choosed %d is error !\n", channel); 20751+ return -1; 20752+ } 20753+ 20754+ if (g_channel_status[channel] != DMAC_CHN_VACANCY) { 20755+ dma_err("dma chn %d is in used!\n", channel); 20756+ return -1; 20757+ } 20758+ 20759+ /* clear the interrupt in this channel */ 20760+ dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x01 << channel)); 20761+ dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x01 << channel)); 20762+ 20763+ function[channel] = (void *)pisr; 20764+ g_channel_status[channel] = DMAC_CHN_ALLOCAT; 20765+ 20766+ return 0; 20767+} 20768+EXPORT_SYMBOL(dmac_register_isr); 20769+ 20770+/* 20771+ * free channel 20772+ */ 20773+int dmac_channel_free(unsigned int channel) 20774+{ 20775+ if (channel >= DMAC_MAX_CHANNELS) { 20776+ dma_err("channel larger than total.\n"); 20777+ return -EINVAL; 20778+ } 20779+ 20780+ g_channel_status[channel] = DMAC_CHN_VACANCY; 20781+ return 0; 20782+} 20783+EXPORT_SYMBOL(dmac_channel_free); 20784+ 20785+static unsigned int dmac_check_request(unsigned int peripheral_addr, 20786+ int direction) 20787+{ 20788+ int i; 20789+ /* check request pipe with peripheral_addr */ 20790+ for (i = direction; i < DMAC_MAX_PERIPHERALS; i = i + 2) { 20791+ if (g_peripheral[i].peri_addr == peripheral_addr) { 20792+ return i; 20793+ } 20794+ } 20795+ 20796+ dma_err("Invalid devaddr\n"); 20797+ 20798+ return -1; 20799+} 20800+ 20801+/* 20802+ * init dmac register 20803+ * clear interrupt flags 20804+ * called by dma_driver_init 20805+ */ 20806+int dmac_init(struct hidmac_host *dma) 20807+{ 20808+ unsigned int i, tempvalue; 20809+ int ret; 20810+ 20811+ clk_prepare_enable(dma->clk); 20812+ reset_control_deassert(dma->rstc); 20813+ 20814+ dmac_readw(dma->regbase + DMAC_CONFIG, tempvalue); 20815+ if (tempvalue == 0) { 20816+ dmac_writew(dma->regbase + DMAC_CONFIG, 20817+ DMAC_CONFIG_VAL); 20818+ dmac_writew(dma->regbase + DMAC_INTTCCLEAR, 0xFF); 20819+ dmac_writew(dma->regbase + DMAC_INTERRCLR, 0xFF); 20820+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 20821+ dmac_writew(dma->regbase + DMAC_CxCONFIG(i), 20822+ DMAC_CxDISABLE); 20823+ function[i] = NULL; 20824+ } 20825+ } 20826+ 20827+ /* creat LLI */ 20828+ /* alloc space for dma lli, as the source is uncontinuous, so... */ 20829+ ret = allocate_dmalli_space(pllihead, 1); 20830+ if (ret < 0) { 20831+ return -1; 20832+ } 20833+ 20834+ if (request_irq(dma->irq, dmac_isr, 0, "hi_dma", dma)) { 20835+ dma_err("DMA Irq %d request failed\n", dma->irq); 20836+ free_dmalli_space(pllihead, 1); 20837+ return -1; 20838+ } 20839+ 20840+ return 0; 20841+} 20842+ 20843+/* 20844+ * alloc_dma_lli_space 20845+ * output: 20846+ * ppheadlli[0]: memory physics address 20847+ * ppheadlli[1]: virtual address 20848+ * 20849+ */ 20850+int allocate_dmalli_space(unsigned int *ppheadlli, unsigned int page_num) 20851+{ 20852+ dma_addr_t dma_phys; 20853+ void *dma_virt; 20854+ 20855+ dma_virt = dma_alloc_coherent(NULL, page_num * PAGE_SIZE, 20856+ &dma_phys, GFP_DMA | GFP_KERNEL); 20857+ if (dma_virt == NULL) { 20858+ dma_err("can't get dma mem from system\n"); 20859+ return -1; 20860+ } 20861+ 20862+ ppheadlli[0] = (unsigned int)(dma_phys); 20863+ ppheadlli[1] = (unsigned int)(dma_virt); 20864+ 20865+ return 0; 20866+} 20867+EXPORT_SYMBOL(allocate_dmalli_space); 20868+ 20869+/* 20870+ * free_dma_lli_space 20871+ */ 20872+int free_dmalli_space(unsigned int *ppheadlli, unsigned int page_num) 20873+{ 20874+ dma_addr_t dma_phys; 20875+ unsigned int dma_virt; 20876+ 20877+ dma_phys = (dma_addr_t)(ppheadlli[0]); 20878+ dma_virt = ppheadlli[1]; 20879+ 20880+ dma_free_coherent(NULL, page_num * PAGE_SIZE, 20881+ (void *)dma_virt, dma_phys); 20882+ 20883+ ppheadlli[0] = 0; 20884+ ppheadlli[1] = 0; 20885+ return 0; 20886+} 20887+EXPORT_SYMBOL(free_dmalli_space); 20888+ 20889+/* 20890+ * config register for memory to memory DMA transfer without LLI 20891+ * note: 20892+ * it is necessary to call dmac_channelstart for channel enable 20893+ */ 20894+int dmac_start_m2m(unsigned int channel, unsigned int psource, 20895+ unsigned int pdest, unsigned int uwnumtransfers) 20896+{ 20897+ unsigned int uwchannel_num, tmp_trasnsfer; 20898+ 20899+ if (uwnumtransfers > (MAXTRANSFERSIZE << 2)) { 20900+ dma_err("Invalidate transfer size,size=%x\n", uwnumtransfers); 20901+ return -EINVAL; 20902+ } 20903+ 20904+ uwchannel_num = channel; 20905+ 20906+ if ((uwchannel_num == DMAC_CHANNEL_INVALID) || 20907+ (uwchannel_num > CHANNEL_NUM)) { 20908+ pr_err("failure of DMAC channel allocation in M2M function!\n"); 20909+ return -EFAULT; 20910+ } 20911+ 20912+ dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num), psource); 20913+ dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num), pdest); 20914+ dmac_writew(dma_regbase + DMAC_CxLLI(uwchannel_num), 0); 20915+ tmp_trasnsfer = (uwnumtransfers >> 2) & 0xfff; 20916+ tmp_trasnsfer = tmp_trasnsfer | (DMAC_CxCONTROL_M2M & (~0xfff)); 20917+ dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num), tmp_trasnsfer); 20918+ dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num), DMAC_CxCONFIG_M2M); 20919+ 20920+ return 0; 20921+} 20922+EXPORT_SYMBOL(dmac_start_m2m); 20923+ 20924+/* 20925+ * channel enable 20926+ * start a dma transfer immediately 20927+ */ 20928+int dmac_channelstart(unsigned int u32channel) 20929+{ 20930+ unsigned int reg_value; 20931+ 20932+ if (u32channel >= DMAC_MAX_CHANNELS) { 20933+ dma_err("channel larger %d\n", DMAC_MAX_CHANNELS); 20934+ return -EINVAL; 20935+ } 20936+ 20937+ g_channel_status[u32channel] = DMAC_NOT_FINISHED; 20938+ dmac_readw(dma_regbase + DMAC_CxCONFIG(u32channel), reg_value); 20939+ dmac_writew(dma_regbase + DMAC_CxCONFIG(u32channel), 20940+ (reg_value | DMAC_CHANNEL_ENABLE)); 20941+ 20942+ return 0; 20943+} 20944+EXPORT_SYMBOL(dmac_channelstart); 20945+ 20946+/* 20947+ * wait for transfer end 20948+ */ 20949+int dmac_wait(int channel) 20950+{ 20951+ int ret_result; 20952+ int ret = 0; 20953+ 20954+ if (channel < 0) { 20955+ return -1; 20956+ } 20957+ 20958+ while (1) { 20959+ ret_result = dma_update_status(channel); 20960+ if (ret_result == -DMAC_CHN_ERROR) { 20961+ dma_err("Transfer Error.\n"); 20962+ ret = -1; 20963+ goto end; 20964+ } else if (ret_result == DMAC_NOT_FINISHED) { 20965+ udelay(10); 20966+ } else if (ret_result == DMAC_CHN_SUCCESS) { 20967+ ret = DMAC_CHN_SUCCESS; 20968+ goto end; 20969+ } else if (ret_result == DMAC_CHN_VACANCY) { 20970+ ret = DMAC_CHN_SUCCESS; 20971+ goto end; 20972+ } else if (ret_result == -DMAC_CHN_TIMEOUT) { 20973+ dma_err("Timeout.\n"); 20974+ dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), DMAC_CxDISABLE); 20975+ g_channel_status[channel] = DMAC_CHN_VACANCY; 20976+ ret = -1; 20977+ goto end; 20978+ } 20979+ } 20980+end: 20981+ dmac_channelclose(channel); 20982+ return ret; 20983+} 20984+EXPORT_SYMBOL(dmac_wait); 20985+ 20986+/* 20987+ * buile LLI for memory to memory DMA transfer 20988+ */ 20989+int dmac_buildllim2m_isp(unsigned int *ppheadlli, unsigned int *psource, 20990+ unsigned int *pdest, unsigned int *length, 20991+ unsigned int lli_num) 20992+{ 20993+ unsigned int address, phy_address; 20994+ unsigned int j; 20995+ 20996+ if (ppheadlli != NULL) { 20997+ phy_address = (unsigned int)(ppheadlli[0]); 20998+ dma_debug("phy_address: 0x%X\n", phy_address); 20999+ address = (unsigned int)(ppheadlli[1]); 21000+ dma_debug("address: 0x%X\n", address); 21001+ for (j = 0; j < lli_num; j++) { 21002+ dma_debug("psource[%d]: 0x%X\n", j, psource[j]); 21003+ dmac_writew(address, psource[j]); 21004+ address += 4; 21005+ phy_address += 4; 21006+ dma_debug("pdest[%d]: 0x%X\n", j, pdest[j]); 21007+ dmac_writew(address, pdest[j]); 21008+ address += 4; 21009+ phy_address += 4; 21010+ 21011+ /* if the last node, next_lli_addr = 0 */ 21012+ if (j == (lli_num - 1)) { 21013+ dmac_writew(address, 0); 21014+ } else 21015+ dmac_writew(address, 21016+ (((phy_address + 8) & (~0x03)) | 21017+ DMAC_CxLLI_LM)); 21018+ 21019+ address += 4; 21020+ phy_address += 4; 21021+ 21022+ if (j == (lli_num - 1)) { 21023+ dmac_writew(address, 21024+ ((DMAC_CxCONTROL_LLIM2M_ISP & 21025+ (~0xfff)) | (length[j]) | 21026+ 0x80000000)); 21027+ } else { 21028+ dmac_writew(address, 21029+ (((DMAC_CxCONTROL_LLIM2M_ISP & (~0xfff)) | 21030+ (length[j])) & 0x7fffffff)); 21031+ } 21032+ 21033+ address += 4; 21034+ phy_address += 4; 21035+ } 21036+ } 21037+ 21038+ return 0; 21039+} 21040+EXPORT_SYMBOL(dmac_buildllim2m_isp); 21041+ 21042+/* 21043+ * buile LLI for memory to memory DMA transfer 21044+ */ 21045+int dmac_buildllim2m(unsigned int *ppheadlli, unsigned int pdest, 21046+ unsigned int psource, unsigned int totaltransfersize, 21047+ unsigned int uwnumtransfers) 21048+{ 21049+ unsigned int lli_num = 0; 21050+ unsigned int last_lli = 0; 21051+ unsigned int address, phy_address, srcaddr, denstaddr; 21052+ unsigned int j; 21053+ 21054+ lli_num = (totaltransfersize / uwnumtransfers); 21055+ 21056+ if ((totaltransfersize % uwnumtransfers) != 0) { 21057+ last_lli = 1, ++lli_num; 21058+ } 21059+ 21060+ if (ppheadlli != NULL) { 21061+ phy_address = (unsigned int)(ppheadlli[0]); 21062+ address = (unsigned int)(ppheadlli[1]); 21063+ for (j = 0; j < lli_num; j++) { 21064+ srcaddr = (psource + (j * uwnumtransfers)); 21065+ dmac_writew(address, srcaddr); 21066+ address += 4; 21067+ phy_address += 4; 21068+ denstaddr = (pdest + (j * uwnumtransfers)); 21069+ dmac_writew(address, denstaddr); 21070+ address += 4; 21071+ phy_address += 4; 21072+ if (j == (lli_num - 1)) { 21073+ dmac_writew(address, 0); 21074+ } else 21075+ dmac_writew(address, 21076+ (((phy_address + 8) & (~0x03)) | 21077+ DMAC_CxLLI_LM)); 21078+ 21079+ address += 4; 21080+ phy_address += 4; 21081+ 21082+ if ((j == (lli_num - 1)) && (last_lli == 0)) 21083+ dmac_writew(address, ((DMAC_CxCONTROL_LLIM2M & 21084+ (~0xfff)) | 21085+ (uwnumtransfers >> 2) | 21086+ 0x80000000)); 21087+ else if ((j == (lli_num - 1)) && (last_lli == 1)) 21088+ dmac_writew(address, 21089+ ((DMAC_CxCONTROL_LLIM2M & 21090+ (~0xfff)) | 21091+ ((totaltransfersize % 21092+ uwnumtransfers) >> 2) | 21093+ 0x80000000)); 21094+ else 21095+ dmac_writew(address, 21096+ (((DMAC_CxCONTROL_LLIM2M & (~0xfff)) | 21097+ (uwnumtransfers >> 2)) & 0x7fffffff)); 21098+ 21099+ address += 4; 21100+ phy_address += 4; 21101+ } 21102+ } 21103+ 21104+ return 0; 21105+} 21106+EXPORT_SYMBOL(dmac_buildllim2m); 21107+ 21108+/* 21109+ * disable channel 21110+ * used before the operation of register configuration 21111+ */ 21112+int dmac_channelclose(unsigned int channel) 21113+{ 21114+ unsigned int reg_value, count; 21115+ 21116+ if (channel >= DMAC_MAX_CHANNELS) { 21117+ dma_err("channel larger than total.\n"); 21118+ return -EINVAL; 21119+ } 21120+ 21121+ dmac_readw(dma_regbase + DMAC_CxCONFIG(channel), reg_value); 21122+ 21123+#define CHANNEL_CLOSE_IMMEDIATE 21124+#ifdef CHANNEL_CLOSE_IMMEDIATE 21125+ reg_value &= 0xFFFFFFFE; 21126+ dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), reg_value); 21127+#else 21128+ reg_value |= DMAC_CONFIGURATIONx_HALT_DMA_ENABLE; 21129+ /* ignore incoming dma request */ 21130+ dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), reg_value); 21131+ dmac_readw(dma_regbase + DMAC_CxCONFIG(channel), reg_value); 21132+ /* if FIFO is empty */ 21133+ while ((reg_value & DMAC_CONFIGURATIONx_ACTIVE) 21134+ == DMAC_CONFIGURATIONx_ACTIVE) { 21135+ dmac_readw(dma_regbase + DMAC_CxCONFIG(channel), reg_value); 21136+ } 21137+ reg_value &= 0xFFFFFFFE; 21138+ dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), reg_value); 21139+#endif 21140+ 21141+ dmac_readw(dma_regbase + DMAC_ENBLDCHNS, reg_value); 21142+ reg_value = reg_value & 0x00ff; 21143+ count = 0; 21144+ while (((reg_value >> channel) & 0x1) == 1) { 21145+ dmac_readw(dma_regbase + DMAC_ENBLDCHNS, reg_value); 21146+ reg_value = reg_value & 0x00ff; 21147+ if (count++ > 10000) { 21148+ dma_err("close failure.\n"); 21149+ return -1; 21150+ } 21151+ } 21152+ 21153+ return 0; 21154+} 21155+EXPORT_SYMBOL(dmac_channelclose); 21156+ 21157+/* 21158+ * load configuration from LLI for memory to memory 21159+ */ 21160+int dmac_start_llim2m(unsigned int channel, unsigned int *pfirst_lli) 21161+{ 21162+ unsigned int uwchannel_num; 21163+ dmac_lli plli; 21164+ unsigned int first_lli; 21165+ 21166+ if (pfirst_lli == NULL) { 21167+ dma_err("Invalidate LLI head!\n"); 21168+ return -EFAULT; 21169+ } 21170+ 21171+ uwchannel_num = channel; 21172+ if ((uwchannel_num == DMAC_CHANNEL_INVALID) || 21173+ (uwchannel_num > 7)) { 21174+ dma_err("failure of DMAC channel allocation in"); 21175+ dma_err("LLIM2M function,channel=%x!\n ", uwchannel_num); 21176+ return -EINVAL; 21177+ } 21178+ 21179+ memset(&plli, 0, sizeof(plli)); 21180+ first_lli = (unsigned int)pfirst_lli[1]; 21181+ dmac_readw(first_lli, plli.src_addr); 21182+ dmac_readw(first_lli + 4, plli.dst_addr); 21183+ dmac_readw(first_lli + 8, plli.next_lli); 21184+ dmac_readw(first_lli + 12, plli.lli_transfer_ctrl); 21185+ 21186+ dmac_channelclose(uwchannel_num); 21187+ dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x1 << uwchannel_num)); 21188+ dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << uwchannel_num)); 21189+ dmac_writew(dma_regbase + DMAC_SYNC, 0x0); 21190+ 21191+ dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num), 21192+ DMAC_CxDISABLE); 21193+ dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num), 21194+ (unsigned int)(plli.src_addr)); 21195+ dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num), 21196+ (unsigned int)(plli.dst_addr)); 21197+ dmac_writew(dma_regbase + DMAC_CxLLI(uwchannel_num), 21198+ (unsigned int)(plli.next_lli)); 21199+ dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num), 21200+ (unsigned int)(plli.lli_transfer_ctrl)); 21201+ dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num), 21202+ DMAC_CxCONFIG_LLIM2M); 21203+ 21204+ return 0; 21205+} 21206+EXPORT_SYMBOL(dmac_start_llim2m); 21207+ 21208+/* 21209+ * load configuration from LLI for memory and peripheral 21210+ */ 21211+int dmac_start_llim2p(unsigned int channel, unsigned int *pfirst_lli, 21212+ unsigned int uwperipheralid) 21213+{ 21214+ unsigned int uwchannel_num; 21215+ dmac_lli plli; 21216+ unsigned int first_lli; 21217+ unsigned int temp = 0; 21218+ 21219+ if (pfirst_lli == NULL) { 21220+ dma_err("Invalidate LLI head!\n"); 21221+ return -EINVAL; 21222+ } 21223+ uwchannel_num = channel; 21224+ if ((uwchannel_num == DMAC_CHANNEL_INVALID) || 21225+ (uwchannel_num > CHANNEL_NUM)) { 21226+ dma_err("failure of DMAC channel allocation in"); 21227+ dma_err("LLIM2P function, channel=%x!\n ", uwchannel_num); 21228+ return -EINVAL; 21229+ } 21230+ 21231+ memset(&plli, 0, sizeof(plli)); 21232+ first_lli = (unsigned int)pfirst_lli[1]; 21233+ dmac_readw(first_lli, plli.src_addr); 21234+ dmac_readw(first_lli + 4, plli.dst_addr); 21235+ dmac_readw(first_lli + 8, plli.next_lli); 21236+ dmac_readw(first_lli + 12, plli.lli_transfer_ctrl); 21237+ 21238+ dmac_channelclose(uwchannel_num); 21239+ dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x1 << uwchannel_num)); 21240+ dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << uwchannel_num)); 21241+ dmac_writew(dma_regbase + DMAC_SYNC, 0x0); 21242+ 21243+ dmac_readw(dma_regbase + DMAC_CxCONFIG(uwchannel_num), temp); 21244+ dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num), 21245+ temp | DMAC_CxDISABLE); 21246+ dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num), 21247+ plli.src_addr); 21248+ dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num), 21249+ plli.dst_addr); 21250+ dmac_writew(dma_regbase + DMAC_CxLLI(uwchannel_num), 21251+ plli.next_lli); 21252+ dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num), 21253+ plli.lli_transfer_ctrl); 21254+ 21255+ return 0; 21256+} 21257+EXPORT_SYMBOL(dmac_start_llim2p); 21258+ 21259+/* 21260+ * enable memory and peripheral dma transfer 21261+ * note: 21262+ * it is necessary to call dmac_channelstart to enable channel 21263+ */ 21264+int dmac_start_m2p(unsigned int channel, unsigned int memaddr, 21265+ unsigned int uwperipheralid, unsigned int uwnumtransfers, 21266+ unsigned int next_lli_addr) 21267+{ 21268+ unsigned int uwtrans_control = 0; 21269+ unsigned int addtmp, tmp; 21270+ unsigned int uwdst_addr = 0; 21271+ unsigned int uwsrc_addr = 0; 21272+ unsigned int uwwidth; 21273+ int uwchannel_num; 21274+ 21275+ addtmp = memaddr; 21276+ 21277+ if ((uwperipheralid > 15)) { 21278+ dma_err("Invalid peripheral id%x\n", uwperipheralid); 21279+ return -EINVAL; 21280+ } 21281+ 21282+ uwchannel_num = (int)channel; 21283+ if ((uwchannel_num == DMAC_CHANNEL_INVALID) || 21284+ (uwchannel_num > CHANNEL_NUM) || (uwchannel_num < 0)) { 21285+ dma_err("failure alloc\n"); 21286+ return -EFAULT; 21287+ } 21288+ 21289+ /* must modified with different peripheral */ 21290+ uwwidth = g_peripheral[uwperipheralid].transfer_width; 21291+ 21292+ /* check transfer direction * 21293+ * even number-->TX, odd number-->RX */ 21294+ uwsrc_addr = memaddr; 21295+ uwdst_addr = (unsigned int)(g_peripheral[uwperipheralid].peri_addr); 21296+ 21297+ tmp = uwnumtransfers >> uwwidth; 21298+ if (tmp & (~0x0fff)) { 21299+ dma_err("Invalidate size%x\n", uwnumtransfers); 21300+ return -EINVAL; 21301+ } 21302+ 21303+ tmp = tmp & 0xfff; 21304+ uwtrans_control = tmp | 21305+ (g_peripheral[uwperipheralid].transfer_ctrl & (~0xfff)); 21306+ dmac_writew(dma_regbase + DMAC_INTTCCLEAR, 21307+ (0x1 << (unsigned int)uwchannel_num)); 21308+ dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << (unsigned int)uwchannel_num)); 21309+ dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num), 21310+ (unsigned int)uwsrc_addr); 21311+ dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num), 21312+ (unsigned int)uwdst_addr); 21313+ dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num), 21314+ (unsigned int)uwtrans_control); 21315+ dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num), 21316+ (g_peripheral[uwperipheralid].transfer_cfg)); 21317+ 21318+ return 0; 21319+} 21320+ 21321+/* 21322+ * enable memory and peripheral dma transfer 21323+ * note: 21324+ * it is necessary to call dmac_channelstart to enable channel 21325+ */ 21326+int dmac_start_p2m(unsigned int channel, unsigned int memaddr, 21327+ unsigned int uwperipheralid, unsigned int uwnumtransfers, 21328+ unsigned int next_lli_addr) 21329+{ 21330+ unsigned int uwtrans_control = 0; 21331+ unsigned int addtmp, tmp; 21332+ unsigned int uwdst_addr = 0; 21333+ unsigned int uwsrc_addr = 0; 21334+ unsigned int uwwidth; 21335+ int uwchannel_num; 21336+ 21337+ addtmp = memaddr; 21338+ 21339+ if ((uwperipheralid > 15)) { 21340+ dma_err("Invalid peripheral id%x\n", uwperipheralid); 21341+ return -EINVAL; 21342+ } 21343+ 21344+ uwchannel_num = (int)channel; 21345+ if ((uwchannel_num == DMAC_CHANNEL_INVALID) || 21346+ (uwchannel_num > 3) || (uwchannel_num < 0)) { 21347+ dma_err("failure alloc\n"); 21348+ return -EFAULT; 21349+ } 21350+ 21351+ /* must modified with different peripheral */ 21352+ uwwidth = g_peripheral[uwperipheralid].transfer_width; 21353+ 21354+ /* check transfer direction * 21355+ * even number-->TX, odd number-->RX */ 21356+ uwsrc_addr = (unsigned int)(g_peripheral[uwperipheralid].peri_addr); 21357+ uwdst_addr = memaddr; 21358+ 21359+ tmp = uwnumtransfers >> uwwidth; 21360+ if (tmp & (~0x0fff)) { 21361+ dma_err("Invalidate size%x\n", uwnumtransfers); 21362+ return -EINVAL; 21363+ } 21364+ 21365+ tmp = tmp & 0xfff; 21366+ uwtrans_control = tmp | 21367+ (g_peripheral[uwperipheralid].transfer_ctrl & (~0xfff)); 21368+ dmac_writew(dma_regbase + DMAC_INTTCCLEAR, 21369+ (0x1 << (unsigned int)uwchannel_num)); 21370+ dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << (unsigned int)uwchannel_num)); 21371+ dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num), 21372+ (unsigned int)uwsrc_addr); 21373+ dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num), 21374+ (unsigned int)uwdst_addr); 21375+ dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num), 21376+ (unsigned int)uwtrans_control); 21377+ dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num), 21378+ (g_peripheral[uwperipheralid].transfer_cfg)); 21379+ 21380+ return 0; 21381+} 21382+ 21383+/* 21384+ * execute memory to memory dma transfer without LLI 21385+ */ 21386+int dmac_m2m_transfer(unsigned int source, unsigned int dest, 21387+ unsigned int length) 21388+{ 21389+ unsigned int ulchnn; 21390+ unsigned int dma_size = 0; 21391+ unsigned int dma_count, left_size; 21392+ 21393+ left_size = length; 21394+ dma_count = 0; 21395+ ulchnn = dmac_channel_allocate(NULL); 21396+ 21397+ ulchnn = 2; 21398+ 21399+ dma_err("use channel %d\n", ulchnn); 21400+ 21401+ while ((left_size >> 2) >= 0xffc) { 21402+ dma_size = 0xffc; 21403+ left_size -= (dma_size << 2); 21404+ dma_err("left_size is %x.", left_size); 21405+ dmac_start_m2m(ulchnn, 21406+ (unsigned int)(source + 21407+ dma_count * 21408+ (dma_size << 2)), 21409+ (unsigned int)(dest + 21410+ dma_count * 21411+ (dma_size << 2)), 21412+ (dma_size << 2)); 21413+ if (dmac_channelstart(ulchnn) != 0) { 21414+ dma_err("start channel error...\n"); 21415+ return -1; 21416+ } 21417+ 21418+ if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) { 21419+ dma_err("dma transfer error...\n"); 21420+ return -1; 21421+ } 21422+ 21423+ dma_count++; 21424+ } 21425+ 21426+ dmac_start_m2m(ulchnn, (source + dma_count * (dma_size << 2)), 21427+ (dest + dma_count * (dma_size << 2)), (left_size << 2)); 21428+ 21429+ if (dmac_channelstart(ulchnn) != 0) { 21430+ return -1; 21431+ } 21432+ 21433+ if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) { 21434+ return -1; 21435+ } 21436+ 21437+ return 0; 21438+} 21439+EXPORT_SYMBOL(dmac_m2m_transfer); 21440+ 21441+/* 21442+ * execute memory to peripheral dma transfer without LLI 21443+ */ 21444+int dmac_m2p_transfer(unsigned int memaddr, unsigned int uwperipheralid, 21445+ unsigned int length) 21446+{ 21447+ unsigned int dma_size = 0; 21448+ unsigned int dma_count, left_size, ulchnn, uwwidth; 21449+ 21450+ left_size = length; 21451+ dma_count = 0; 21452+ 21453+ ulchnn = dmac_channel_allocate(NULL); 21454+ if (ulchnn == DMAC_CHANNEL_INVALID) { 21455+ return -1; 21456+ } 21457+ 21458+ uwwidth = g_peripheral[uwperipheralid].transfer_width; 21459+ 21460+ while ((left_size >> uwwidth) >= 0xffc) { 21461+ dma_size = 0xffc; 21462+ left_size -= (dma_size << uwwidth); 21463+ 21464+ if (dmac_start_m2p(ulchnn, 21465+ (unsigned int)(memaddr + dma_count * dma_size), 21466+ uwperipheralid, (dma_size << uwwidth), 0) < 0) { 21467+ return -1; 21468+ } 21469+ 21470+ if (dmac_channelstart(ulchnn) != 0) { 21471+ return -1; 21472+ } 21473+ 21474+ if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) { 21475+ dmac_channel_free(ulchnn); 21476+ return -1; 21477+ } 21478+ 21479+ dma_count++; 21480+ } 21481+ 21482+ pr_debug("memaddr=0x%x\n", (unsigned int)(memaddr + 21483+ dma_count * dma_size)); 21484+ 21485+ if (dmac_start_m2p(ulchnn, 21486+ (unsigned int)(memaddr + dma_count * dma_size), 21487+ uwperipheralid, left_size, 0) < 0) { 21488+ return -1; 21489+ } 21490+ 21491+ if (dmac_channelstart(ulchnn) != 0) { 21492+ return -1; 21493+ } 21494+ 21495+ return ulchnn; 21496+} 21497+ 21498+/* 21499+ * execute memory to peripheral dma transfer without LLI 21500+ */ 21501+int dmac_p2m_transfer(unsigned int memaddr, unsigned int uwperipheralid, 21502+ unsigned int length) 21503+{ 21504+ unsigned int dma_size = 0; 21505+ unsigned int ulchnn, dma_count, left_size; 21506+ unsigned int uwwidth; 21507+ 21508+ left_size = length; 21509+ dma_count = 0; 21510+ 21511+ ulchnn = dmac_channel_allocate(NULL); 21512+ if (ulchnn == DMAC_CHANNEL_INVALID) { 21513+ return -1; 21514+ } 21515+ 21516+ uwwidth = g_peripheral[uwperipheralid].transfer_width; 21517+ 21518+ while ((left_size >> uwwidth) >= 0xffc) { 21519+ dma_size = 0xffc; 21520+ left_size -= (dma_size << uwwidth); 21521+ 21522+ if (dmac_start_p2m(ulchnn, 21523+ (unsigned int)(memaddr + dma_count * dma_size), 21524+ uwperipheralid, (dma_size << uwwidth), 0) < 0) { 21525+ return -1; 21526+ } 21527+ 21528+ if (dmac_channelstart(ulchnn) != 0) { 21529+ return -1; 21530+ } 21531+ 21532+ if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) { 21533+ dmac_channel_free(ulchnn); 21534+ return -1; 21535+ } 21536+ 21537+ dma_count++; 21538+ } 21539+ 21540+ pr_debug("memaddr=0x%x\n", (unsigned int)(memaddr + 21541+ dma_count * dma_size)); 21542+ 21543+ if (dmac_start_p2m(ulchnn, 21544+ (unsigned int)(memaddr + dma_count * dma_size), 21545+ uwperipheralid, left_size, 0) < 0) { 21546+ return -1; 21547+ } 21548+ 21549+ if (dmac_channelstart(ulchnn) != 0) { 21550+ return -1; 21551+ } 21552+ 21553+ return ulchnn; 21554+} 21555+ 21556+/* 21557+ * memory to memory dma transfer with LLI 21558+ * 21559+ * @source 21560+ * @dest 21561+ * @length 21562+ * @num 21563+ * */ 21564+int do_dma_llim2m_isp(unsigned int *source, 21565+ unsigned int *dest, 21566+ unsigned int *length, 21567+ unsigned int num) 21568+{ 21569+ unsigned int chnn; 21570+ int ret; 21571+ 21572+ /* the dma channel is default using 2 */ 21573+ chnn = 2; 21574+ 21575+ ret = dmac_buildllim2m_isp(pllihead, source, dest, length, num); 21576+ if (ret) { 21577+ dma_err("build lli error...\n"); 21578+ return -1; 21579+ } 21580+ 21581+ ret = dmac_start_llim2m(chnn, pllihead); 21582+ if (ret) { 21583+ return -1; 21584+ } 21585+ 21586+ if (dmac_channelstart(chnn) != 0) { 21587+ dma_err("start channel error...\n"); 21588+ return -1; 21589+ } 21590+ 21591+ return ret; 21592+} 21593+EXPORT_SYMBOL(do_dma_llim2m_isp); 21594+ 21595+int do_dma_m2p(unsigned int memaddr, unsigned int peripheral_addr, 21596+ unsigned int length) 21597+{ 21598+ int ret = 0; 21599+ int uwperipheralid; 21600+ 21601+ uwperipheralid = dmac_check_request(peripheral_addr, TX); 21602+ if (uwperipheralid < 0) { 21603+ dma_err("m2p:Invalid devaddr\n"); 21604+ return -1; 21605+ } 21606+ 21607+ ret = dmac_m2p_transfer(memaddr, uwperipheralid, length); 21608+ if (ret == -1) { 21609+ dma_err("m2p:trans err\n"); 21610+ return -1; 21611+ } 21612+ 21613+ return ret; 21614+} 21615+ 21616+int do_dma_p2m(unsigned int memaddr, unsigned int peripheral_addr, 21617+ unsigned int length) 21618+{ 21619+ int ret = -1; 21620+ int uwperipheralid; 21621+ 21622+ uwperipheralid = dmac_check_request(peripheral_addr, RX); 21623+ if (uwperipheralid < 0) { 21624+ dma_err("p2m:Invalid devaddr.\n"); 21625+ return -1; 21626+ } 21627+ 21628+ ret = dmac_p2m_transfer(memaddr, uwperipheralid, length); 21629+ if (ret == -1) { 21630+ dma_err("p2m:trans err\n"); 21631+ return -1; 21632+ } 21633+ 21634+ return ret; 21635+} 21636+ 21637+/* 21638+ * Apply DMA interrupt resource 21639+ * init channel state 21640+ */ 21641+static int hi_dmac_probe(struct platform_device *platdev) 21642+{ 21643+ unsigned int i; 21644+ struct hidmac_host *dma; 21645+ struct resource *res; 21646+ int ret; 21647+ 21648+ dma = devm_kzalloc(&platdev->dev, sizeof(*dma), GFP_KERNEL); 21649+ if (!dma) { 21650+ return -ENOMEM; 21651+ } 21652+ 21653+ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); 21654+ if (!res) { 21655+ dev_err(&platdev->dev, "no mmio resource\n"); 21656+ return -ENODEV; 21657+ } 21658+ 21659+ dma->regbase = devm_ioremap_resource(&platdev->dev, res); 21660+ if (IS_ERR(dma->regbase)) { 21661+ return PTR_ERR(dma->regbase); 21662+ } 21663+ 21664+ dma->clk = devm_clk_get(&platdev->dev, NULL); 21665+ if (IS_ERR(dma->clk)) { 21666+ return PTR_ERR(dma->clk); 21667+ } 21668+ 21669+ dma->rstc = devm_reset_control_get(&platdev->dev, "dma-reset"); 21670+ if (IS_ERR(dma->rstc)) { 21671+ return PTR_ERR(dma->rstc); 21672+ } 21673+ 21674+ dma->irq = platform_get_irq(platdev, 0); 21675+ if (unlikely(dma->irq < 0)) { 21676+ return -ENODEV; 21677+ } 21678+ 21679+ dma_regbase = dma->regbase; 21680+ 21681+ ret = dmac_init(dma); 21682+ if (ret) { 21683+ return -ENODEV; 21684+ } 21685+ 21686+ platform_set_drvdata(platdev, dma); 21687+ 21688+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 21689+ g_channel_status[i] = DMAC_CHN_VACANCY; 21690+ } 21691+ 21692+ dev_info(&platdev->dev, "hidmac probe!\n"); 21693+ return ret; 21694+} 21695+ 21696+static int hi_dmac_remove(struct platform_device *platdev) 21697+{ 21698+ int i; 21699+ struct hidmac_host *dma = platform_get_drvdata(platdev); 21700+ 21701+ clk_disable_unprepare(dma->clk); 21702+ 21703+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 21704+ g_channel_status[i] = DMAC_CHN_VACANCY; 21705+ } 21706+ 21707+ free_dmalli_space(pllihead, 1); 21708+ 21709+ return 0; 21710+} 21711+ 21712+static int hi_dmac_suspend(struct platform_device *platdev, 21713+ pm_message_t state) 21714+{ 21715+ int i; 21716+ struct hidmac_host *dma = platform_get_drvdata(platdev); 21717+ 21718+ clk_prepare_enable(dma->clk); 21719+ 21720+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 21721+ g_channel_status[i] = DMAC_CHN_VACANCY; 21722+ } 21723+ 21724+ clk_disable_unprepare(dma->clk); 21725+ 21726+ return 0; 21727+} 21728+ 21729+static int hi_dmac_resume(struct platform_device *platdev) 21730+{ 21731+ int i; 21732+ struct hidmac_host *dma = platform_get_drvdata(platdev); 21733+ unsigned int tempvalue; 21734+ 21735+ clk_prepare_enable(dma->clk); 21736+ reset_control_deassert(dma->rstc); 21737+ 21738+ dmac_readw(dma->regbase + DMAC_CONFIG, tempvalue); 21739+ if (tempvalue == 0) { 21740+ dmac_writew(dma->regbase + DMAC_CONFIG, 21741+ DMAC_CONFIG_VAL); 21742+ dmac_writew(dma->regbase + DMAC_INTTCCLEAR, 0xFF); 21743+ dmac_writew(dma->regbase + DMAC_INTERRCLR, 0xFF); 21744+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 21745+ dmac_writew(dma->regbase + DMAC_CxCONFIG(i), 21746+ DMAC_CxDISABLE); 21747+ function[i] = NULL; 21748+ } 21749+ } 21750+ 21751+ for (i = 0; i < DMAC_MAX_CHANNELS; i++) { 21752+ g_channel_status[i] = DMAC_CHN_VACANCY; 21753+ } 21754+ 21755+ return 0; 21756+} 21757+ 21758+static const struct of_device_id hisi_dmac_dt_ids[] = { 21759+ { .compatible = "hisilicon,hisi-dmac" }, 21760+ { } 21761+}; 21762+MODULE_DEVICE_TABLE(of, hisi_dmac_dt_ids); 21763+ 21764+static struct platform_driver hisi_dmac_driver = { 21765+ .driver = { 21766+ .name = "hisi-dmac", 21767+ .of_match_table = hisi_dmac_dt_ids, 21768+ }, 21769+ .probe = hi_dmac_probe, 21770+ .remove = hi_dmac_remove, 21771+ .suspend = hi_dmac_suspend, 21772+ .resume = hi_dmac_resume, 21773+}; 21774+ 21775+module_platform_driver(hisi_dmac_driver); 21776+ 21777+MODULE_LICENSE("GPL"); 21778+MODULE_AUTHOR("Hisilicon"); 21779+MODULE_DESCRIPTION("HiSilicon DMA Controller driver"); 21780diff --git a/drivers/hidmac/hi_pl08x.h b/drivers/hidmac/hi_pl08x.h 21781new file mode 100644 21782index 000000000..1c3babf22 21783--- /dev/null 21784+++ b/drivers/hidmac/hi_pl08x.h 21785@@ -0,0 +1,90 @@ 21786+/* 21787+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 21788+ * 21789+ * This program is free software; you can redistribute it and/or modify 21790+ * it under the terms of the GNU General Public License as published by 21791+ * the Free Software Foundation; either version 2 of the License, or 21792+ * (at your option) any later version. 21793+ * 21794+ * This program is distributed in the hope that it will be useful, 21795+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 21796+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21797+ * GNU General Public License for more details. 21798+ * 21799+ * You should have received a copy of the GNU General Public License 21800+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 21801+ */ 21802+ 21803+ 21804+#ifndef __HI_DMAC_H__ 21805+#define __HI_DMAC_H__ 21806+ 21807+#define dmac_writew(addr, value) \ 21808+ writel(value, (void *)(addr)) 21809+#define dmac_readw(addr, v) \ 21810+ v = readl((void *)(addr)) 21811+ 21812+#ifdef DMA_DEBUG 21813+#define dma_debug printk 21814+#else 21815+#define dma_debug(fmt, ...) do {} while (0); 21816+#endif 21817+ 21818+#define DMAC_CONFIGURATIONx_HALT_DMA_ENABLE (0x01L<<18) 21819+#define DMAC_CONFIGURATIONx_ACTIVE (0x01L<<17) 21820+#define DMAC_CONFIGURATIONx_CHANNEL_ENABLE 1 21821+#define DMAC_CONFIGURATIONx_CHANNEL_DISABLE 0 21822+ 21823+/* definition for the return value */ 21824+#define DMAC_ERROR_BASE 100 21825+#define DMAC_CHANNEL_INVALID (DMAC_ERROR_BASE+1) 21826+ 21827+#define DMAC_TRXFERSIZE_INVALID (DMAC_ERROR_BASE+2) 21828+#define DMAC_SOURCE_ADDRESS_INVALID (DMAC_ERROR_BASE+3) 21829+#define DMAC_DESTINATION_ADDRESS_INVALID (DMAC_ERROR_BASE+4) 21830+#define DMAC_MEMORY_ADDRESS_INVALID (DMAC_ERROR_BASE+5) 21831+#define DMAC_PERIPHERAL_ID_INVALID (DMAC_ERROR_BASE+6) 21832+#define DMAC_DIRECTION_ERROR (DMAC_ERROR_BASE+7) 21833+#define DMAC_TRXFER_ERROR (DMAC_ERROR_BASE+8) 21834+#define DMAC_LLIHEAD_ERROR (DMAC_ERROR_BASE+9) 21835+#define DMAC_SWIDTH_ERROR (DMAC_ERROR_BASE+0xa) 21836+#define DMAC_LLI_ADDRESS_INVALID (DMAC_ERROR_BASE+0xb) 21837+#define DMAC_TRANS_CONTROL_INVALID (DMAC_ERROR_BASE+0xc) 21838+#define DMAC_MEMORY_ALLOCATE_ERROR (DMAC_ERROR_BASE+0xd) 21839+#define DMAC_NOT_FINISHED (DMAC_ERROR_BASE+0xe) 21840+ 21841+#define DMAC_TIMEOUT (DMAC_ERROR_BASE+0xf) 21842+#define DMAC_CHN_SUCCESS (DMAC_ERROR_BASE+0x10) 21843+#define DMAC_CHN_ERROR (DMAC_ERROR_BASE+0x11) 21844+#define DMAC_CHN_TIMEOUT (DMAC_ERROR_BASE+0x12) 21845+#define DMAC_CHN_ALLOCAT (DMAC_ERROR_BASE+0x13) 21846+#define DMAC_CHN_VACANCY (DMAC_ERROR_BASE+0x14) 21847+ 21848+#define DMAC_CONFIGURATIONx_ACTIVE_NOT 0 21849+ 21850+/* the means the bit in the channel control register */ 21851+#define DMAC_TRANS_SIZE 0xff0 21852+ 21853+/* DMAC peripheral structure */ 21854+typedef struct dmac_peripheral { 21855+ /* peripherial ID */ 21856+ unsigned int peri_id; 21857+ /* peripheral data register address */ 21858+ unsigned int peri_addr; 21859+ /* default channel control word */ 21860+ unsigned int transfer_ctrl; 21861+ /* default channel configuration word */ 21862+ unsigned int transfer_cfg; 21863+ /* default channel configuration word */ 21864+ unsigned int transfer_width; 21865+} dmac_peripheral; 21866+ 21867+typedef struct mem_addr { 21868+ unsigned int addr_base; 21869+ unsigned int size; 21870+} mem_addr; 21871+ 21872+typedef unsigned int dma_addr_t; 21873+/* #define PAGE_SIZE 0x1000 */ 21874+ 21875+#endif /* End of #ifndef __HI_INC_ECSDMACC_H__ */ 21876diff --git a/drivers/hiedmac/Kconfig b/drivers/hiedmac/Kconfig 21877new file mode 100644 21878index 000000000..183747be8 21879--- /dev/null 21880+++ b/drivers/hiedmac/Kconfig 21881@@ -0,0 +1,29 @@ 21882+# 21883+# Sensor device configuration 21884+# 21885+ 21886+config HIEDMAC 21887+ tristate "Hisilicon EDMAC Controller support" 21888+ depends on (ARCH_HISI_BVT && !HIEDMACV310) 21889+ help 21890+ The Direction Memory Access(EDMA) is a high-speed data transfer 21891+ operation. It supports data read/write between peripherals and 21892+ memories without using the CPU. 21893+ Hisilicon EDMA Controller(EDMAC) directly transfers data between 21894+ a memory and a peripheral, between peripherals, or between memories. 21895+ This avoids the CPU intervention and reduces the interrupt handling 21896+ overhead of the CPU. 21897+ 21898+if HIEDMAC 21899+ 21900+config HIEDMAC_CHANNEL_NUM 21901+ int "hiedmac channel num" 21902+ default "8" 21903+ 21904+config HIEDMAC_INTERRUPT 21905+ bool "Hisilicon EDMAC Controller interrupt mode support" 21906+ depends on HIEDMAC 21907+ help 21908+ open Hisilicon EDMAC Controller interrupt mode 21909+ 21910+endif 21911diff --git a/drivers/hiedmac/Makefile b/drivers/hiedmac/Makefile 21912new file mode 100644 21913index 000000000..a1b4b8b76 21914--- /dev/null 21915+++ b/drivers/hiedmac/Makefile 21916@@ -0,0 +1,4 @@ 21917+# 21918+# Makefile for the hiedmac drivers. 21919+# 21920+obj-$(CONFIG_HIEDMAC) += hiedmacv310.o 21921diff --git a/drivers/hiedmac/hiedmacv310.c b/drivers/hiedmac/hiedmacv310.c 21922new file mode 100644 21923index 000000000..282ac3eaa 21924--- /dev/null 21925+++ b/drivers/hiedmac/hiedmacv310.c 21926@@ -0,0 +1,946 @@ 21927+/* 21928+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 21929+ * 21930+ * This program is free software; you can redistribute it and/or modify 21931+ * it under the terms of the GNU General Public License as published by 21932+ * the Free Software Foundation; either version 2 of the License, or 21933+ * (at your option) any later version. 21934+ * 21935+ * This program is distributed in the hope that it will be useful, 21936+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 21937+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21938+ * GNU General Public License for more details. 21939+ * 21940+ * You should have received a copy of the GNU General Public License 21941+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 21942+ */ 21943+ 21944+#include <linux/debugfs.h> 21945+#include <linux/delay.h> 21946+#include <linux/clk.h> 21947+#include <linux/reset.h> 21948+#include <linux/platform_device.h> 21949+#include <linux/device.h> 21950+#include <linux/export.h> 21951+#include <linux/init.h> 21952+#include <linux/interrupt.h> 21953+#include <linux/module.h> 21954+#include <linux/of.h> 21955+#include <linux/of_dma.h> 21956+#include <linux/pm_runtime.h> 21957+#include <linux/seq_file.h> 21958+#include <linux/dma-mapping.h> 21959+#include <linux/slab.h> 21960+#include <linux/io.h> 21961+#include <linux/regmap.h> 21962+#include <linux/mfd/syscon.h> 21963+#include <linux/hiedmac.h> 21964+ 21965+#include "hiedmacv310.h" 21966+ 21967+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) 21968+#include "hiedma_hi3531dv200.h" 21969+#endif 21970+ 21971+#if defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500) 21972+#include "hiedma_hi3521dv200.h" 21973+#endif 21974+ 21975+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 21976+#include "hiedma_hi3559av100.h" 21977+#endif 21978+ 21979+#if defined(CONFIG_ARCH_HI3519AV100) || defined(CONFIG_ARCH_HI3556AV100) || \ 21980+ defined(CONFIG_ARCH_HI3568V100) 21981+#include "hiedma_hi3519av100.h" 21982+#endif 21983+ 21984+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 21985+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 21986+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 21987+#include "hiedma_hi3516cv500.h" 21988+#endif 21989+ 21990+#if defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) || \ 21991+ defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200) 21992+#include "hiedma_hi3516ev200.h" 21993+#endif 21994+ 21995+int g_channel_status[HIEDMAC_CHANNEL_NUM]; 21996+DMAC_ISR *function[HIEDMAC_CHANNEL_NUM]; 21997+unsigned long pllihead[2] = {0, 0}; 21998+void __iomem *dma_regbase; 21999+int hiedmacv310_trace_level_n = HIEDMACV310_TRACE_LEVEL; 22000+ 22001+struct hiedmac_host { 22002+ struct platform_device *pdev; 22003+ void __iomem *base; 22004+ struct regmap *misc_regmap; 22005+ unsigned int misc_ctrl_base; 22006+ void __iomem *crg_ctrl; 22007+ unsigned int id; 22008+ struct clk *clk; 22009+ struct clk *axi_clk; 22010+ unsigned int irq; 22011+ struct reset_control *rstc; 22012+ unsigned int channels; 22013+ unsigned int slave_requests; 22014+}; 22015+ 22016+#define DRIVER_NAME "hiedmacv310" 22017+ 22018+int dmac_channel_allocate(void) 22019+{ 22020+ unsigned int i; 22021+ 22022+ for (i = 0; i < HIEDMAC_CHANNEL_NUM; i++) { 22023+ if (g_channel_status[i] == DMAC_CHN_VACANCY) { 22024+ g_channel_status[i] = DMAC_CHN_ALLOCAT; 22025+ return i; 22026+ } 22027+ } 22028+ 22029+ hiedmacv310_error("no to alloc\n"); 22030+ return -1; 22031+} 22032+EXPORT_SYMBOL(dmac_channel_allocate); 22033+ 22034+/* 22035+ * update the state of channels 22036+ */ 22037+static int hiedmac_update_status(unsigned int channel) 22038+{ 22039+ unsigned int channel_status; 22040+ unsigned int channel_tc_status; 22041+ unsigned int channel_err_status[3]; 22042+ unsigned int i = channel; 22043+ unsigned long update_jiffies_timeout; 22044+ 22045+ update_jiffies_timeout = jiffies + HIEDMAC_UPDATE_TIMEOUT; 22046+ 22047+ while (1) { 22048+ channel_status = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_STAT); 22049+ channel_status = (channel_status >> i) & 0x01; 22050+ if (channel_status) { 22051+ channel_tc_status = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_TC1); 22052+ channel_tc_status = (channel_tc_status >> i) & 0x01; 22053+ if (channel_tc_status) { 22054+ hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_TC1_RAW); 22055+ g_channel_status[i] = DMAC_CHN_SUCCESS; 22056+ break; 22057+ } 22058+ 22059+ channel_tc_status = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_TC2); 22060+ channel_tc_status = (channel_tc_status >> i) & 0x01; 22061+ if (channel_tc_status) { 22062+ hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_TC2_RAW); 22063+ g_channel_status[i] = DMAC_CHN_SUCCESS; 22064+ break; 22065+ } 22066+ 22067+ channel_err_status[0] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR1); 22068+ channel_err_status[0] = (channel_err_status[0] >> i) & 0x01; 22069+ channel_err_status[1] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR2); 22070+ channel_err_status[1] = (channel_err_status[1] >> i) & 0x01; 22071+ channel_err_status[2] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR3); 22072+ channel_err_status[2] = (channel_err_status[2] >> i) & 0x01; 22073+ 22074+ if (channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) { 22075+ hiedmacv310_error("Error in HIEDMAC %d finish!\n", i); 22076+ channel_err_status[0] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR1); 22077+ channel_err_status[1] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR2); 22078+ channel_err_status[2] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR3); 22079+ g_channel_status[i] = -DMAC_CHN_ERROR; 22080+ hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_ERR1_RAW); 22081+ hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_ERR2_RAW); 22082+ hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_ERR3_RAW); 22083+ break; 22084+ } 22085+ } 22086+ 22087+ if (!time_before(jiffies, update_jiffies_timeout)) { 22088+ hiedmacv310_error("Timeout in DMAC %d!\n", i); 22089+ g_channel_status[i] = -DMAC_CHN_TIMEOUT; 22090+ break; 22091+ } 22092+ } 22093+ 22094+ return g_channel_status[i]; 22095+} 22096+ 22097+/* 22098+ * register user's function 22099+ */ 22100+int dmac_register_isr(unsigned int channel, void *pisr) 22101+{ 22102+ if (channel < 0 || channel > HIEDMAC_CHANNEL_NUM - 1) { 22103+ hiedmacv310_error("invalid channel,channel=%0d\n", channel); 22104+ return -EINVAL; 22105+ } 22106+ 22107+ function[channel] = (void *)pisr; 22108+ 22109+ return 0; 22110+} 22111+EXPORT_SYMBOL(dmac_register_isr); 22112+ 22113+/* 22114+ * free channel 22115+ */ 22116+int dmac_channel_free(unsigned int channel) 22117+{ 22118+ if ((channel >= 0) && (channel < HIEDMAC_CHANNEL_NUM)) 22119+ g_channel_status[channel] = DMAC_CHN_VACANCY; 22120+ 22121+ return 0; 22122+} 22123+EXPORT_SYMBOL(dmac_channel_free); 22124+ 22125+static unsigned int dmac_check_request(unsigned int peripheral_addr, 22126+ int direction) 22127+{ 22128+ int i; 22129+ 22130+ for (i = direction; i < EDMAC_MAX_PERIPHERALS; i += 2) { 22131+ if (g_peripheral[i].peri_addr == peripheral_addr) 22132+ return i; 22133+ } 22134+ hiedmacv310_error("Invalid devaddr\n"); 22135+ return -1; 22136+} 22137+ 22138+void edmac_channel_free(int channel) 22139+{ 22140+ if ((channel >= 0) && (channel < HIEDMAC_CHANNEL_NUM)) 22141+ g_channel_status[channel] = DMAC_CHN_VACANCY; 22142+} 22143+/* 22144+ * wait for transfer end 22145+ */ 22146+int dmac_wait(int channel) 22147+{ 22148+ int ret_result; 22149+ int ret = 0; 22150+ 22151+ if (channel < 0) 22152+ return -1; 22153+ 22154+ while (1) { 22155+ ret_result = hiedmac_update_status(channel); 22156+ if (ret_result == -DMAC_CHN_ERROR) { 22157+ hiedmacv310_error("Transfer Error.\n"); 22158+ ret = -1; 22159+ goto end; 22160+ } else if (ret_result == DMAC_NOT_FINISHED) 22161+ udelay(10); 22162+ else if (ret_result == DMAC_CHN_SUCCESS) { 22163+ ret = DMAC_CHN_SUCCESS; 22164+ goto end; 22165+ } else if (ret_result == DMAC_CHN_VACANCY) { 22166+ ret = DMAC_CHN_SUCCESS; 22167+ goto end; 22168+ } else if (ret_result == -DMAC_CHN_TIMEOUT) { 22169+ hiedmacv310_error("Timeout.\n"); 22170+ hiedmacv310_writel(HIEDMAC_Cx_DISABLE, 22171+ dma_regbase + HIEDMAC_Cx_CONFIG(channel)); 22172+ g_channel_status[channel] = DMAC_CHN_VACANCY; 22173+ ret = -1; 22174+ return ret; 22175+ } 22176+ } 22177+end: 22178+ hiedmacv310_writel(HIEDMAC_Cx_DISABLE, 22179+ dma_regbase + HIEDMAC_Cx_CONFIG(channel)); 22180+ edmac_channel_free(channel); 22181+ return ret; 22182+} 22183+EXPORT_SYMBOL(dmac_wait); 22184+ 22185+/* 22186+ * execute memory to peripheral dma transfer without LLI 22187+ */ 22188+int dmac_m2p_transfer(unsigned long long memaddr, unsigned int uwperipheralid, 22189+ unsigned int length) 22190+{ 22191+ unsigned int ulchnn; 22192+ unsigned int uwwidth; 22193+ unsigned int temp; 22194+ 22195+ ulchnn = dmac_channel_allocate(); 22196+ if (-1 == ulchnn) 22197+ return -1; 22198+ 22199+ hiedmacv310_trace(4, "ulchnn = %d\n", ulchnn); 22200+ uwwidth = g_peripheral[uwperipheralid].transfer_width; 22201+ if (length >> uwwidth >= HIEDMAC_TRANS_MAXSIZE) { 22202+ hiedmacv310_error("The length is more than 64k!\n"); 22203+ return -1; 22204+ } 22205+ 22206+ hiedmacv310_writel(memaddr & 0xffffffff, 22207+ dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn)); 22208+#ifdef CONFIG_ARM64 22209+ hiedmacv310_writel((memaddr >> 32) & 0xffffffff, 22210+ dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(ulchnn)); 22211+#endif 22212+ hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_L = 0x%x\n", 22213+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn))); 22214+ 22215+ hiedmacv310_writel(g_peripheral[uwperipheralid].peri_addr & 0xffffffff, 22216+ dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn)); 22217+#ifdef CONFIG_ARM64 22218+ hiedmacv310_writel((g_peripheral[uwperipheralid].peri_addr >> 32) & 0xffffffff, 22219+ dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(ulchnn)); 22220+#endif 22221+ hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_L = 0x%x\n", 22222+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn))); 22223+ 22224+ hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn)); 22225+ hiedmacv310_trace(4, "HIEDMAC_Cx_LLI_L = 0x%x\n", 22226+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn))); 22227+ 22228+ hiedmacv310_writel(length, dma_regbase + HIEDMAC_Cx_CNT0(ulchnn)); 22229+ hiedmacv310_trace(4, "HIEDMAC_Cx_CNT0 = 0x%x\n", 22230+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_CNT0(ulchnn))); 22231+ 22232+ temp = g_peripheral[uwperipheralid].transfer_cfg | uwwidth << 22233+ EDMA_SRC_WIDTH_OFFSET | 22234+ (uwperipheralid << PERI_ID_OFFSET) | 22235+ EDMA_CH_ENABLE; 22236+ hiedmacv310_trace(4, "HIEDMAC_Cx_CONFIG = 0x%x\n", temp); 22237+ hiedmacv310_writel(temp, dma_regbase + HIEDMAC_Cx_CONFIG(ulchnn)); 22238+ return ulchnn; 22239+} 22240+ 22241+/* 22242+ * execute memory to peripheral dma transfer without LLI 22243+ */ 22244+int dmac_p2m_transfer(unsigned long memaddr, unsigned int uwperipheralid, 22245+ unsigned int length) 22246+{ 22247+ unsigned int ulchnn; 22248+ unsigned int uwwidth; 22249+ unsigned int temp; 22250+ 22251+ ulchnn = dmac_channel_allocate(); 22252+ if (-1 == ulchnn) 22253+ return -1; 22254+ 22255+ hiedmacv310_trace(4, "ulchnn = %d\n", ulchnn); 22256+ uwwidth = g_peripheral[uwperipheralid].transfer_width; 22257+ if (length >> uwwidth >= HIEDMAC_TRANS_MAXSIZE) { 22258+ hiedmacv310_error("The length is more than 64k!\n"); 22259+ return -1; 22260+ } 22261+ 22262+ hiedmacv310_writel(memaddr & 0xffffffff, 22263+ dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn)); 22264+#ifdef CONFIG_ARM64 22265+ hiedmacv310_writel((memaddr >> 32) & 0xffffffff, 22266+ dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(ulchnn)); 22267+#endif 22268+ hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_L = 0x%x\n", 22269+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn))); 22270+ 22271+ hiedmacv310_writel(g_peripheral[uwperipheralid].peri_addr & 0xffffffff, 22272+ dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn)); 22273+#ifdef CONFIG_ARM64 22274+ hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(ulchnn)); 22275+#endif 22276+ hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_L = 0x%x\n", 22277+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn))); 22278+ 22279+ hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn)); 22280+ hiedmacv310_trace(4, "HIEDMAC_Cx_LLI_L = 0x%x\n", 22281+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn))); 22282+ 22283+ hiedmacv310_writel(length, dma_regbase + HIEDMAC_Cx_CNT0(ulchnn)); 22284+ hiedmacv310_trace(4, "HIEDMAC_Cx_CNT0 = 0x%x\n", 22285+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_CNT0(ulchnn))); 22286+ 22287+ temp = g_peripheral[uwperipheralid].transfer_cfg | uwwidth << 22288+ EDMA_SRC_WIDTH_OFFSET | 22289+ (uwperipheralid << PERI_ID_OFFSET) | 22290+ EDMA_CH_ENABLE; 22291+ hiedmacv310_trace(4, "HIEDMAC_Cx_CONFIG = 0x%x\n", temp); 22292+ hiedmacv310_writel(temp, dma_regbase + HIEDMAC_Cx_CONFIG(ulchnn)); 22293+ return ulchnn; 22294+} 22295+ 22296+int do_dma_m2p(unsigned long long memaddr, unsigned int peripheral_addr, 22297+ unsigned int length) 22298+{ 22299+ int ret = 0; 22300+ int uwperipheralid; 22301+ 22302+ uwperipheralid = dmac_check_request(peripheral_addr, EDMAC_TX); 22303+ if (uwperipheralid < 0) { 22304+ hiedmacv310_error("m2p:Invalid devaddr\n"); 22305+ return -1; 22306+ } 22307+ 22308+ ret = dmac_m2p_transfer(memaddr, uwperipheralid, length); 22309+ if (ret == -1) { 22310+ hiedmacv310_error("m2p:trans err\n"); 22311+ return -1; 22312+ } 22313+ 22314+ return ret; 22315+} 22316+EXPORT_SYMBOL(do_dma_m2p); 22317+ 22318+int do_dma_p2m(unsigned long memaddr, unsigned int peripheral_addr, 22319+ unsigned int length) 22320+{ 22321+ int ret = -1; 22322+ int uwperipheralid; 22323+ 22324+ uwperipheralid = dmac_check_request(peripheral_addr, EDMAC_RX); 22325+ if (uwperipheralid < 0) { 22326+ hiedmacv310_error("p2m:Invalid devaddr.\n"); 22327+ return -1; 22328+ } 22329+ 22330+ ret = dmac_p2m_transfer(memaddr, uwperipheralid, length); 22331+ if (ret == -1) { 22332+ hiedmacv310_error("p2m:trans err\n"); 22333+ return -1; 22334+ } 22335+ 22336+ return ret; 22337+} 22338+EXPORT_SYMBOL(do_dma_p2m); 22339+ 22340+/* 22341+ * buile LLI for memory to memory DMA transfer 22342+ */ 22343+int dmac_buildllim2m(unsigned long *ppheadlli, 22344+ unsigned long psource, 22345+ unsigned long pdest, 22346+ unsigned int totaltransfersize, 22347+ unsigned int uwnumtransfers) 22348+{ 22349+ int lli_num = 0; 22350+ unsigned long phy_address; 22351+ int j; 22352+ dmac_lli *plli = NULL; 22353+ 22354+ if (uwnumtransfers == 0) 22355+ return -EINVAL; 22356+ 22357+ lli_num = (totaltransfersize / uwnumtransfers); 22358+ if ((totaltransfersize % uwnumtransfers) != 0) 22359+ lli_num++; 22360+ 22361+ hiedmacv310_trace(4, "lli_num:%d\n", lli_num); 22362+ 22363+ phy_address = ppheadlli[0]; 22364+ plli = (dmac_lli *)ppheadlli[1]; 22365+ hiedmacv310_trace(4, "phy_address: 0x%lx\n", phy_address); 22366+ hiedmacv310_trace(4, "address: 0x%p\n", plli); 22367+ for (j = 0; j < lli_num; j++) { 22368+ memset(plli, 0x0, sizeof(dmac_lli)); 22369+ /* 22370+ * at the last transfer, chain_en should be set to 0x0; 22371+ * others tansfer,chain_en should be set to 0x2; 22372+ */ 22373+ plli->next_lli = (phy_address + (j + 1) * sizeof(dmac_lli)) & 22374+ (~(HIEDMAC_LLI_ALIGN - 1)); 22375+ if (j < lli_num - 1) { 22376+ plli->next_lli |= HIEDMAC_LLI_ENABLE; 22377+ plli->count = uwnumtransfers; 22378+ } else { 22379+ plli->next_lli |= HIEDMAC_LLI_DISABLE; 22380+ plli->count = totaltransfersize % uwnumtransfers; 22381+ } 22382+ 22383+ plli->src_addr = psource; 22384+ plli->dest_addr = pdest; 22385+ plli->config = HIEDMAC_CxCONFIG_M2M_LLI; 22386+ 22387+ psource += uwnumtransfers; 22388+ pdest += uwnumtransfers; 22389+ plli++; 22390+ } 22391+ 22392+ return 0; 22393+} 22394+EXPORT_SYMBOL(dmac_buildllim2m); 22395+ 22396+/* 22397+ * load configuration from LLI for memory to memory 22398+ */ 22399+int dmac_start_llim2m(unsigned int channel, unsigned long *pfirst_lli) 22400+{ 22401+ unsigned int i = channel; 22402+ dmac_lli *plli; 22403+ 22404+ plli = (dmac_lli *)pfirst_lli[1]; 22405+ hiedmacv310_trace(4, "plli.src_addr: 0x%lx\n", plli->src_addr); 22406+ hiedmacv310_trace(4, "plli.dst_addr: 0x%lx\n", plli->dest_addr); 22407+ hiedmacv310_trace(4, "plli.next_lli: 0x%lx\n", plli->next_lli); 22408+ hiedmacv310_trace(4, "plli.count: 0x%d\n", plli->count); 22409+ 22410+ hiedmacv310_writel(plli->dest_addr & 0xffffffff, 22411+ dma_regbase + HIEDMAC_Cx_LLI_L(i)); 22412+#ifdef CONFIG_ARM64 22413+ hiedmacv310_writel((plli->dest_addr >> 32) & 0xffffffff, 22414+ dma_regbase + HIEDMAC_Cx_LLI_H(i)); 22415+#endif 22416+ hiedmacv310_writel(plli->count, dma_regbase + HIEDMAC_Cx_CNT0(i)); 22417+ 22418+ hiedmacv310_writel(plli->src_addr & 0xffffffff, 22419+ dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(i)); 22420+#ifdef CONFIG_ARM64 22421+ hiedmacv310_writel((plli->src_addr >> 32) & 0xffffffff, 22422+ dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(i)); 22423+#endif 22424+ hiedmacv310_writel(plli->dest_addr & 0xffffffff, 22425+ dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(i)); 22426+#ifdef CONFIG_ARM64 22427+ hiedmacv310_writel((plli->dest_addr >> 32) & 0xffffffff, 22428+ dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(i)); 22429+#endif 22430+ hiedmacv310_writel(plli->config | EDMA_CH_ENABLE, 22431+ dma_regbase + HIEDMAC_Cx_CONFIG(i)); 22432+ 22433+ return 0; 22434+} 22435+EXPORT_SYMBOL(dmac_start_llim2m); 22436+ 22437+/* 22438+ * config register for memory to memory DMA transfer without LLI 22439+ */ 22440+int dmac_start_m2m(unsigned int channel, unsigned long psource, 22441+ unsigned long pdest, unsigned int uwnumtransfers) 22442+{ 22443+ unsigned int i = channel; 22444+ 22445+ if (uwnumtransfers > HIEDMAC_TRANS_MAXSIZE || uwnumtransfers == 0) { 22446+ hiedmacv310_error("Invalidate transfer size,size=%x\n", uwnumtransfers); 22447+ return -EINVAL; 22448+ } 22449+ hiedmacv310_trace(4, "channel[%d],source=0x%lx,dest=0x%lx,length=%d\n", 22450+ channel, psource, pdest, uwnumtransfers); 22451+ 22452+ hiedmacv310_writel(psource & 0xffffffff, 22453+ dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(i)); 22454+ hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_L = 0x%x\n", 22455+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(i))); 22456+#ifdef CONFIG_ARM64 22457+ hiedmacv310_writel((psource >> 32) & 0xffffffff, 22458+ dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(i)); 22459+ hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_H = 0x%x\n", 22460+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(i))); 22461+#endif 22462+ hiedmacv310_writel(pdest & 0xffffffff, dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(i)); 22463+ hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_L = 0x%x\n", 22464+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(i))); 22465+#ifdef CONFIG_ARM64 22466+ hiedmacv310_writel((pdest >> 32) & 0xffffffff, 22467+ dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(i)); 22468+ hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_H = 0x%x\n", 22469+ hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(i))); 22470+#endif 22471+ hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_LLI_L(i)); 22472+ 22473+ hiedmacv310_writel(uwnumtransfers, dma_regbase + HIEDMAC_Cx_CNT0(i)); 22474+ 22475+ hiedmacv310_writel(HIEDMAC_CxCONFIG_M2M | EDMA_CH_ENABLE, 22476+ dma_regbase + HIEDMAC_Cx_CONFIG(i)); 22477+ 22478+ return 0; 22479+} 22480+EXPORT_SYMBOL(dmac_start_m2m); 22481+ 22482+/* 22483+ * execute memory to memory dma transfer without LLI 22484+ */ 22485+int dmac_m2m_transfer(unsigned long source, unsigned long dest, 22486+ unsigned int length) 22487+{ 22488+ unsigned int dma_size = 0; 22489+ unsigned int ulchnn, dma_count, left_size; 22490+ 22491+ left_size = length; 22492+ dma_count = 0; 22493+ ulchnn = dmac_channel_allocate(); 22494+ if (ulchnn < 0) { 22495+ return -EINVAL; 22496+ } 22497+ 22498+ hiedmacv310_trace(6, "using channel[%d],source=0x%lx,dest=0x%lx,length=%d\n", 22499+ ulchnn, source, dest, length); 22500+ 22501+ while (left_size) { 22502+ if (left_size >= HIEDMAC_TRANS_MAXSIZE) 22503+ dma_size = HIEDMAC_TRANS_MAXSIZE; 22504+ else 22505+ dma_size = left_size; 22506+ dmac_start_m2m(ulchnn, 22507+ source + dma_count * dma_size, 22508+ dest + dma_count * dma_size, 22509+ dma_size); 22510+ 22511+ if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) { 22512+ hiedmacv310_error("dma transfer error...\n"); 22513+ return -1; 22514+ } 22515+ left_size -= dma_size; 22516+ dma_count++; 22517+ hiedmacv310_trace(4, "left_size is %d.\n", left_size); 22518+ } 22519+ 22520+ return 0; 22521+} 22522+EXPORT_SYMBOL(dmac_m2m_transfer); 22523+ 22524+/* 22525+ * memory to memory dma transfer with LLI 22526+ * 22527+ * @source 22528+ * @dest 22529+ * @length 22530+ * */ 22531+int do_dma_llim2m(unsigned long source, 22532+ unsigned long dest, 22533+ unsigned long length) 22534+{ 22535+ int ret = 0; 22536+ unsigned chnn; 22537+ 22538+ chnn = dmac_channel_allocate(); 22539+ if (chnn < 0) { 22540+ ret = -1; 22541+ goto end; 22542+ } 22543+ hiedmacv310_trace(4, "chnn:%d,src:%lx,dst:%lx,len:%ld.\n", chnn, source, dest, 22544+ length); 22545+ 22546+ if (pllihead[0] == 0) { 22547+ hiedmacv310_error("ppheadlli[0] is NULL.\n"); 22548+ ret = -ENOMEM; 22549+ goto end; 22550+ } 22551+ 22552+ ret = dmac_buildllim2m(pllihead, source, dest, length, HIEDMAC_TRANS_MAXSIZE); 22553+ if (ret) { 22554+ hiedmacv310_error("build lli error...\n"); 22555+ ret = -EIO; 22556+ goto end; 22557+ } 22558+ ret = dmac_start_llim2m(chnn, pllihead); 22559+ if (ret) { 22560+ hiedmacv310_error("start lli error...\n"); 22561+ ret = -EIO; 22562+ goto end; 22563+ } 22564+ 22565+end: 22566+ return ret; 22567+} 22568+EXPORT_SYMBOL(do_dma_llim2m); 22569+ 22570+/* 22571+ * alloc_dma_lli_space 22572+ * output: 22573+ * ppheadlli[0]: memory physics address 22574+ * ppheadlli[1]: virtual address 22575+ * 22576+ */ 22577+int allocate_dmalli_space(struct device *dev, unsigned long *ppheadlli, 22578+ unsigned int page_num) 22579+{ 22580+ dma_addr_t dma_phys; 22581+ void *dma_virt; 22582+ 22583+ dma_virt = dma_alloc_coherent(dev, page_num * PAGE_SIZE, 22584+ &dma_phys, GFP_DMA); 22585+ if (dma_virt == NULL) { 22586+ hiedmacv310_error("can't get dma mem from system\n"); 22587+ return -1; 22588+ } 22589+ 22590+ ppheadlli[0] = (unsigned long)(dma_phys); 22591+ ppheadlli[1] = (unsigned long)(dma_virt); 22592+ 22593+ if (dma_phys & (HIEDMAC_LLI_ALIGN - 1)) { 22594+ return -1; 22595+ } 22596+ 22597+ return 0; 22598+} 22599+EXPORT_SYMBOL(allocate_dmalli_space); 22600+ 22601+static int hiedmac_priv_init(struct hiedmac_host *hiedmac, 22602+ edmac_peripheral *peripheral_info) 22603+{ 22604+ struct regmap *misc = hiedmac->misc_regmap; 22605+ int i = 0; 22606+ unsigned int count = 0; 22607+ unsigned int offset = 0; 22608+ unsigned ctrl = 0; 22609+ 22610+ for (i = 0; i < EDMAC_MAX_PERIPHERALS; i++) { 22611+ if (peripheral_info[i].host_sel == hiedmac->id) { 22612+ if (count > 32) { 22613+ hiedmacv310_error("request table is not true!\n"); 22614+ return -1; 22615+ } 22616+ if (misc != NULL) { 22617+ offset = hiedmac->misc_ctrl_base + (count & (~0x3)); 22618+ regmap_read(misc, offset, &ctrl); 22619+ ctrl &= ~(0x3f << ((count & 0x3) << 3)); 22620+ ctrl |= peripheral_info[i].peri_id << ((count & 0x3) << 3); 22621+ regmap_write(misc, offset, ctrl); 22622+ } 22623+ peripheral_info[i].dynamic_periphery_num = count; 22624+ count++; 22625+ } 22626+ } 22627+ 22628+ return 0; 22629+} 22630+ 22631+static int get_of_probe(struct hiedmac_host *hiedmac) 22632+{ 22633+ struct resource *res = NULL; 22634+ struct platform_device *platdev = hiedmac->pdev; 22635+ struct device_node *np = platdev->dev.of_node; 22636+ int ret; 22637+ 22638+ ret = of_property_read_u32((&platdev->dev)->of_node, 22639+ "devid", &(hiedmac->id)); 22640+ if (ret) { 22641+ hiedmacv310_error("get hiedmac id fail\n"); 22642+ return -ENODEV; 22643+ } 22644+ 22645+ hiedmac->clk = devm_clk_get(&(platdev->dev), "apb_pclk"); 22646+ if (IS_ERR(hiedmac->clk)) { 22647+ hiedmacv310_error("get hiedmac clk fail\n"); 22648+ return PTR_ERR(hiedmac->clk); 22649+ } 22650+ 22651+ hiedmac->axi_clk = devm_clk_get(&(platdev->dev), "axi_aclk"); 22652+ if (IS_ERR(hiedmac->axi_clk)) { 22653+ hiedmacv310_error("get hiedmac axi clk fail\n"); 22654+ return PTR_ERR(hiedmac->axi_clk); 22655+ } 22656+ 22657+ hiedmac->rstc = devm_reset_control_get(&(platdev->dev), "dma-reset"); 22658+ if (IS_ERR(hiedmac->rstc)) { 22659+ hiedmacv310_error("get hiedmac rstc fail\n"); 22660+ return PTR_ERR(hiedmac->rstc); 22661+ } 22662+ 22663+ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); 22664+ if (!res) { 22665+ hiedmacv310_error("no reg resource\n"); 22666+ return -ENODEV; 22667+ } 22668+ 22669+ hiedmac->base = devm_ioremap_resource(&(platdev->dev), res); 22670+ if (IS_ERR(hiedmac->base)) { 22671+ hiedmacv310_error("get hiedmac base fail\n"); 22672+ return PTR_ERR(hiedmac->base); 22673+ } 22674+ if (!of_find_property(np, "misc_regmap", NULL) || 22675+ !of_find_property(np, "misc_ctrl_base", NULL)) { 22676+ hiedmac->misc_regmap = 0; 22677+ } else { 22678+ hiedmac->misc_regmap = syscon_regmap_lookup_by_phandle(np, "misc_regmap"); 22679+ if (IS_ERR(hiedmac->misc_regmap)) { 22680+ hiedmacv310_error("get hiedmac misc fail\n"); 22681+ return PTR_ERR(hiedmac->misc_regmap); 22682+ } 22683+ 22684+ ret = of_property_read_u32((&platdev->dev)->of_node, 22685+ "misc_ctrl_base", &(hiedmac->misc_ctrl_base)); 22686+ if (ret) { 22687+ hiedmacv310_error("get dma-misc_ctrl_base fail\n"); 22688+ return -ENODEV; 22689+ } 22690+ } 22691+ hiedmac->irq = platform_get_irq(platdev, 0); 22692+ if (unlikely(hiedmac->irq < 0)) 22693+ return -ENODEV; 22694+ 22695+ ret = of_property_read_u32((&platdev->dev)->of_node, 22696+ "dma-channels", &(hiedmac->channels)); 22697+ if (ret) { 22698+ hiedmacv310_error("get dma-channels fail\n"); 22699+ return -ENODEV; 22700+ } 22701+ ret = of_property_read_u32((&platdev->dev)->of_node, 22702+ "dma-requests", &(hiedmac->slave_requests)); 22703+ if (ret) { 22704+ hiedmacv310_error("get dma-requests fail\n"); 22705+ return -ENODEV; 22706+ } 22707+ hiedmacv310_trace(2, "dma-channels = %d, dma-requests = %d\n", 22708+ hiedmac->channels, hiedmac->slave_requests); 22709+ 22710+ hiedmac_priv_init(hiedmac, (edmac_peripheral *)&g_peripheral); 22711+ 22712+ return 0; 22713+} 22714+ 22715+/* Don't need irq mode now */ 22716+#if defined(CONFIG_HIEDMAC_INTERRUPT) 22717+static irqreturn_t hiemdacv310_irq(int irq, void *dev) 22718+{ 22719+ struct hiedmac_host *hiedmac = (struct hiedmac_host *)dev; 22720+ unsigned int channel_err_status[3]; 22721+ unsigned int channel_tc_status = 0; 22722+ unsigned int channel_status = 0; 22723+ int i = 0; 22724+ unsigned int mask = 0; 22725+ 22726+ channel_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_STAT); 22727+ if (!channel_status) { 22728+ hiedmacv310_error("channel_status = 0x%x\n", channel_status); 22729+ return IRQ_NONE; 22730+ } 22731+ 22732+ for (i = 0; i < hiedmac->channels; i++) { 22733+ channel_status = (channel_status >> i) & 0x1; 22734+ if (channel_status) { 22735+ channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC1_RAW); 22736+ channel_tc_status = (channel_tc_status >> i) & 0x01; 22737+ if (channel_tc_status) 22738+ hiedmacv310_writel(channel_tc_status << i, hiedmac->base + HIEDMAC_INT_TC1_RAW); 22739+ 22740+ channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC2); 22741+ channel_tc_status = (channel_tc_status >> i) & 0x01; 22742+ if (channel_tc_status) 22743+ hiedmacv310_writel(channel_tc_status << i, hiedmac->base + HIEDMAC_INT_TC2_RAW); 22744+ 22745+ channel_err_status[0] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR1); 22746+ channel_err_status[0] = (channel_err_status[0] >> i) & 0x01; 22747+ channel_err_status[1] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR2); 22748+ channel_err_status[1] = (channel_err_status[1] >> i) & 0x01; 22749+ channel_err_status[2] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR3); 22750+ channel_err_status[2] = (channel_err_status[2] >> i) & 0x01; 22751+ 22752+ if (channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) { 22753+ hiedmacv310_error("Error in hiedmac %d finish!,ERR1 = 0x%x,ERR2 = 0x%x,ERR3 = 0x%x\n", 22754+ i, channel_err_status[0], channel_err_status[1], channel_err_status[2]); 22755+ hiedmacv310_writel(1 << i, hiedmac->base + HIEDMAC_INT_ERR1_RAW); 22756+ hiedmacv310_writel(1 << i, hiedmac->base + HIEDMAC_INT_ERR2_RAW); 22757+ hiedmacv310_writel(1 << i, hiedmac->base + HIEDMAC_INT_ERR3_RAW); 22758+ } 22759+ if ((function[i]) != NULL) 22760+ function[i](i, g_channel_status[i]); 22761+ 22762+ mask |= (1 << i); 22763+ hiedmacv310_writel(HIEDMAC_Cx_DISABLE, dma_regbase + HIEDMAC_Cx_CONFIG(i)); 22764+ edmac_channel_free(i); 22765+ } 22766+ } 22767+ 22768+ return mask ? IRQ_HANDLED : IRQ_NONE; 22769+} 22770+#endif 22771+ 22772+static int __init hiedmacv310_probe(struct platform_device *pdev) 22773+{ 22774+ int ret = 0; 22775+ int i = 0; 22776+ struct hiedmac_host *hiedmac = NULL; 22777+ 22778+ hiedmac = kzalloc(sizeof(*hiedmac), GFP_KERNEL); 22779+ if (!hiedmac) { 22780+ hiedmacv310_error("malloc for hiedmac fail!"); 22781+ ret = -ENOMEM; 22782+ return ret; 22783+ } 22784+ hiedmac->pdev = pdev; 22785+ 22786+ ret = get_of_probe(hiedmac); 22787+ if (ret) { 22788+ hiedmacv310_error("get dts info fail!"); 22789+ goto free_hiedmac; 22790+ } 22791+ 22792+ clk_prepare_enable(hiedmac->clk); 22793+ clk_prepare_enable(hiedmac->axi_clk); 22794+ 22795+ reset_control_deassert(hiedmac->rstc); 22796+ 22797+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC1_RAW); 22798+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC2_RAW); 22799+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR1_RAW); 22800+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR2_RAW); 22801+ hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR3_RAW); 22802+ 22803+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 22804+ hiedmac->base + HIEDMAC_INT_TC1_MASK); 22805+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 22806+ hiedmac->base + HIEDMAC_INT_TC2_MASK); 22807+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 22808+ hiedmac->base + HIEDMAC_INT_ERR1_MASK); 22809+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 22810+ hiedmac->base + HIEDMAC_INT_ERR2_MASK); 22811+ hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN, 22812+ hiedmac->base + HIEDMAC_INT_ERR3_MASK); 22813+ 22814+ for (i = 0; i < HIEDMAC_CHANNEL_NUM; i++) 22815+ g_channel_status[i] = DMAC_CHN_VACANCY; 22816+ 22817+ dma_regbase = hiedmac->base; 22818+ 22819+ ret = allocate_dmalli_space(&(hiedmac->pdev->dev), pllihead, 22820+ HIEDMAC_LLI_PAGE_NUM); 22821+ if (ret < 0) 22822+ goto free_hiedmac; 22823+ 22824+#if defined(CONFIG_HIEDMAC_INTERRUPT) 22825+ /* register irq if necessary !*/ 22826+ ret = request_irq(hiedmac->irq, hiemdacv310_irq, 0, DRIVER_NAME, hiedmac); 22827+ if (ret) { 22828+ hiedmacv310_error("fail to request irq"); 22829+ goto free_hiedmac; 22830+ } 22831+#endif 22832+ return 0; 22833+ 22834+free_hiedmac: 22835+ kfree(hiedmac); 22836+ 22837+ return ret; 22838+} 22839+ 22840+static int hiemda_remove(struct platform_device *pdev) 22841+{ 22842+ int err = 0; 22843+ return err; 22844+} 22845+ 22846+static const struct of_device_id hiedmacv310_match[] = { 22847+ { .compatible = "hisilicon,hiedmacv310_n" }, 22848+ {}, 22849+}; 22850+ 22851+static struct platform_driver hiedmacv310_driver = { 22852+ .remove = hiemda_remove, 22853+ .driver = { 22854+ .name = "hiedmacv310_n", 22855+ .of_match_table = hiedmacv310_match, 22856+ }, 22857+}; 22858+ 22859+static int __init hiedmacv310_init(void) 22860+{ 22861+ return platform_driver_probe(&hiedmacv310_driver, hiedmacv310_probe); 22862+} 22863+subsys_initcall(hiedmacv310_init); 22864+ 22865+static void __exit hiedmacv310_exit(void) 22866+{ 22867+ platform_driver_unregister(&hiedmacv310_driver); 22868+} 22869+module_exit(hiedmacv310_exit); 22870+ 22871+MODULE_LICENSE("GPL"); 22872+MODULE_AUTHOR("Hisilicon"); 22873diff --git a/drivers/hiedmac/hiedmacv310.h b/drivers/hiedmac/hiedmacv310.h 22874new file mode 100644 22875index 000000000..4344d8940 22876--- /dev/null 22877+++ b/drivers/hiedmac/hiedmacv310.h 22878@@ -0,0 +1,184 @@ 22879+/* 22880+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 22881+ * 22882+ * This program is free software; you can redistribute it and/or modify 22883+ * it under the terms of the GNU General Public License as published by 22884+ * the Free Software Foundation; either version 2 of the License, or 22885+ * (at your option) any later version. 22886+ * 22887+ * This program is distributed in the hope that it will be useful, 22888+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 22889+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22890+ * GNU General Public License for more details. 22891+ * 22892+ * You should have received a copy of the GNU General Public License 22893+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 22894+ */ 22895+ 22896+#ifndef __HIEDMACV310_H__ 22897+#define __HIEDMACV310_H__ 22898+ 22899+/* debug control */ 22900+extern int hiedmacv310_trace_level_n; 22901+#define HIEDMACV310_TRACE_LEVEL 5 22902+ 22903+#define HIEDMACV310_TRACE_FMT KERN_INFO 22904+ 22905+typedef void DMAC_ISR(unsigned int channel, int status); 22906+ 22907+#define HIEDMAC_UPDATE_TIMEOUT (30 * HZ) 22908+#define HIEDMAC_TRANS_MAXSIZE (64 * 1024 - 1) 22909+ 22910+#define DEBUG_HIEDMAC 22911+#ifdef DEBUG_HIEDMAC 22912+ 22913+#define hiedmacv310_trace(level, msg...) do { \ 22914+ if ((level) >= hiedmacv310_trace_level_n) { \ 22915+ printk(HIEDMACV310_TRACE_FMT"%s:%d: ", __func__, __LINE__); \ 22916+ printk(msg); \ 22917+ printk("\n"); \ 22918+ } \ 22919+} while (0) 22920+ 22921+ 22922+#define hiedmacv310_assert(cond) do { \ 22923+ if (!(cond)) { \ 22924+ printk(KERN_ERR "Assert:hiedmacv310:%s:%d\n", \ 22925+ __func__, \ 22926+ __LINE__); \ 22927+ BUG(); \ 22928+ } \ 22929+} while (0) 22930+ 22931+#define hiedmacv310_error(s...) do { \ 22932+ printk(KERN_ERR "hiedmacv310:%s:%d: ", __func__, __LINE__); \ 22933+ printk(s); \ 22934+ printk("\n"); \ 22935+} while (0) 22936+ 22937+#else 22938+ 22939+#define hiedmacv310_trace(level, msg...) do { } while (0) 22940+#define hiedmacv310_assert(level, msg...) do { } while (0) 22941+#define hiedmacv310_error(level, msg...) do { } while (0) 22942+ 22943+#endif 22944+ 22945+#define hiedmacv310_readl(addr) ({unsigned int reg = readl((void *)(addr)); \ 22946+ reg; }) 22947+ 22948+#define hiedmacv310_writel(v, addr) do { writel(v, (void *)(addr)); \ 22949+} while (0) 22950+ 22951+ 22952+#define MAX_TRANSFER_BYTES 0xffff 22953+ 22954+/* reg offset */ 22955+#define HIEDMAC_INT_STAT (0x0) 22956+#define HIEDMAC_INT_TC1 (0x4) 22957+#define HIEDMAC_INT_TC2 (0x8) 22958+#define HIEDMAC_INT_ERR1 (0xc) 22959+#define HIEDMAC_INT_ERR2 (0x10) 22960+#define HIEDMAC_INT_ERR3 (0x14) 22961+#define HIEDMAC_INT_TC1_MASK (0x18) 22962+#define HIEDMAC_INT_TC2_MASK (0x1c) 22963+#define HIEDMAC_INT_ERR1_MASK (0x20) 22964+#define HIEDMAC_INT_ERR2_MASK (0x24) 22965+#define HIEDMAC_INT_ERR3_MASK (0x28) 22966+ 22967+#define HIEDMAC_INT_TC1_RAW (0x600) 22968+#define HIEDMAC_INT_TC2_RAW (0x608) 22969+#define HIEDMAC_INT_ERR1_RAW (0x610) 22970+#define HIEDMAC_INT_ERR2_RAW (0x618) 22971+#define HIEDMAC_INT_ERR3_RAW (0x620) 22972+ 22973+#define HIEDMAC_Cx_CURR_CNT0(cn) (0x404 + cn * 0x20) 22974+#define HIEDMAC_Cx_CURR_SRC_ADDR_L(cn) (0x408 + cn * 0x20) 22975+#define HIEDMAC_Cx_CURR_SRC_ADDR_H(cn) (0x40c + cn * 0x20) 22976+#define HIEDMAC_Cx_CURR_DEST_ADDR_L(cn) (0x410 + cn * 0x20) 22977+#define HIEDMAC_Cx_CURR_DEST_ADDR_H(cn) (0x414 + cn * 0x20) 22978+ 22979+#define HIEDMAC_CH_PRI (0x688) 22980+#define HIEDMAC_CH_STAT (0x690) 22981+#define HIEDMAC_DMA_CTRL (0x698) 22982+ 22983+#define HIEDMAC_Cx_BASE(cn) (0x800 + cn * 0x40) 22984+#define HIEDMAC_Cx_LLI_L(cn) (0x800 + cn * 0x40) 22985+#define HIEDMAC_Cx_LLI_H(cn) (0x804 + cn * 0x40) 22986+#define HIEDMAC_Cx_CNT0(cn) (0x81c + cn * 0x40) 22987+#define HIEDMAC_Cx_SRC_ADDR_L(cn) (0x820 + cn * 0x40) 22988+#define HIEDMAC_Cx_SRC_ADDR_H(cn) (0x824 + cn * 0x40) 22989+#define HIEDMAC_Cx_DEST_ADDR_L(cn) (0x828 + cn * 0x40) 22990+#define HIEDMAC_Cx_DEST_ADDR_H(cn) (0x82c + cn * 0x40) 22991+#define HIEDMAC_Cx_CONFIG(cn) (0x830 + cn * 0x40) 22992+ 22993+#define HIEDMAC_CxCONFIG_M2M 0xCFF33000 22994+#define HIEDMAC_CxCONFIG_M2M_LLI 0xCFF00000 22995+#define HIEDMAC_CxCONFIG_CHN_START 0x1 22996+#define HIEDMAC_Cx_DISABLE 0x0 22997+ 22998+#define HIEDMAC_ALL_CHAN_CLR (0xff) 22999+#define HIEDMAC_INT_ENABLE_ALL_CHAN (0xff) 23000+ 23001+ 23002+#define HIEDMAC_CONFIG_SRC_INC (1<<31) 23003+#define HIEDMAC_CONFIG_DST_INC (1<<30) 23004+ 23005+#define HIEDMAC_CONFIG_SRC_WIDTH_SHIFT (16) 23006+#define HIEDMAC_CONFIG_DST_WIDTH_SHIFT (12) 23007+#define HIEDMAC_WIDTH_8BIT (0x0) 23008+#define HIEDMAC_WIDTH_16BIT (0x1) 23009+#define HIEDMAC_WIDTH_32BIT (0x10) 23010+#define HIEDMAC_WIDTH_64BIT (0x11) 23011+ 23012+#define HIEDMAC_MAX_BURST_WIDTH (16) 23013+#define HIEDMAC_MIN_BURST_WIDTH (1) 23014+#define HIEDMAC_CONFIG_SRC_BURST_SHIFT (24) 23015+#define HIEDMAC_CONFIG_DST_BURST_SHIFT (20) 23016+ 23017+#define HIEDMAC_LLI_ALIGN 0x40 23018+#define HIEDMAC_LLI_DISABLE 0x0 23019+#define HIEDMAC_LLI_ENABLE 0x2 23020+ 23021+#define HIEDMAC_CXCONFIG_SIGNAL_SHIFT (0x4) 23022+#define HIEDMAC_CXCONFIG_MEM_TYPE (0x0) 23023+#define HIEDMAC_CXCONFIG_DEV_MEM_TYPE (0x1) 23024+#define HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT (0x2) 23025+#define HIEDMAC_CxCONFIG_LLI_START (0x1) 23026+ 23027+#define HIEDMAC_CXCONFIG_ITC_EN (0x1) 23028+#define HIEDMAC_CXCONFIG_ITC_EN_SHIFT (0x1) 23029+ 23030+#define CCFG_EN 0x1 23031+ 23032+/* DMAC peripheral structure */ 23033+typedef struct edmac_peripheral { 23034+ /* peripherial ID */ 23035+ unsigned int peri_id; 23036+ /* peripheral data register address */ 23037+ unsigned long peri_addr; 23038+ /* config requset */ 23039+ int host_sel; 23040+#define DMAC_HOST0 0 23041+#define DMAC_HOST1 1 23042+#define DMAC_NOT_USE (-1) 23043+ /* default channel configuration word */ 23044+ unsigned int transfer_cfg; 23045+ /* default channel configuration word */ 23046+ unsigned int transfer_width; 23047+ unsigned int dynamic_periphery_num; 23048+} edmac_peripheral; 23049+ 23050+ 23051+#define PERI_ID_OFFSET 4 23052+#define EDMA_SRC_WIDTH_OFFSET 16 23053+#define EDMA_DST_WIDTH_OFFSET 12 23054+#define EDMA_CH_ENABLE 1 23055+ 23056+#define PERI_8BIT_MODE 0 23057+#define PERI_16BIT_MODE 1 23058+#define PERI_32BIT_MODE 2 23059+#define PERI_64BIT_MODE 3 23060+ 23061+#define HIEDMAC_LLI_PAGE_NUM 0x4 /* 4*4K*65535B/64≈16MB */ 23062+#endif 23063diff --git a/drivers/hisilicon/Kconfig b/drivers/hisilicon/Kconfig 23064new file mode 100644 23065index 000000000..ab5884c08 23066--- /dev/null 23067+++ b/drivers/hisilicon/Kconfig 23068@@ -0,0 +1,4 @@ 23069+menu "Hisilicon driver support" 23070+ 23071+source "drivers/hisilicon/cma/Kconfig" 23072+endmenu 23073diff --git a/drivers/hisilicon/Makefile b/drivers/hisilicon/Makefile 23074new file mode 100644 23075index 000000000..0ba50a756 23076--- /dev/null 23077+++ b/drivers/hisilicon/Makefile 23078@@ -0,0 +1 @@ 23079+obj-$(CONFIG_CMA) += cma/ 23080diff --git a/drivers/hisilicon/cma/Kconfig b/drivers/hisilicon/cma/Kconfig 23081new file mode 100644 23082index 000000000..7472dccd8 23083--- /dev/null 23084+++ b/drivers/hisilicon/cma/Kconfig 23085@@ -0,0 +1,16 @@ 23086+ 23087+config CMA_MEM_SHARED 23088+ bool "Support sharing CMA memory with the heap" 23089+ depends on CMA && DMA_CMA 23090+ default no 23091+ help 23092+ Support sharing CMA memory with the heap. 23093+ 23094+config CMA_ADVANCE_SHARE 23095+ bool "Support cma advance share" 23096+ depends on CMA && DMA_CMA 23097+ select CMA_MEM_SHARED 23098+ default no 23099+ help 23100+ Support advance sharing CMA memory with the heap. 23101+ CMA Multiplex Ratio will be improved when this macro defined. 23102diff --git a/drivers/hisilicon/cma/Makefile b/drivers/hisilicon/cma/Makefile 23103new file mode 100644 23104index 000000000..eefda7f57 23105--- /dev/null 23106+++ b/drivers/hisilicon/cma/Makefile 23107@@ -0,0 +1,2 @@ 23108+ 23109+obj-$(CONFIG_CMA) += hi_cma.o 23110diff --git a/drivers/hisilicon/cma/hi_cma.c b/drivers/hisilicon/cma/hi_cma.c 23111new file mode 100644 23112index 000000000..6ce2e2b45 23113--- /dev/null 23114+++ b/drivers/hisilicon/cma/hi_cma.c 23115@@ -0,0 +1,203 @@ 23116+/* 23117+ * hi_cma.c 23118+ * 23119+ * Copyright (c) 2019 HiSilicon Technologies Co., Ltd. 23120+ * 23121+ * This program is free software; you can redistribute it and/or modify 23122+ * it under the terms of the GNU General Public License as published by 23123+ * the Free Software Foundation; either version 2 of the License, or 23124+ * (at your option) any later version. 23125+ * 23126+ * This program is distributed in the hope that it will be useful, 23127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 23128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23129+ * GNU General Public License for more details. 23130+ * 23131+ * You should have received a copy of the GNU General Public License 23132+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 23133+ */ 23134+#include <linux/hi_cma.h> 23135+ 23136+static u32 num_zones; 23137+static struct cma_zone hisi_zone[ZONE_MAX]; 23138+static int use_bootargs; 23139+ 23140+unsigned int get_cma_size(void) 23141+{ 23142+ u32 i; 23143+ u64 total = 0; 23144+ 23145+ for (i = 0; i < num_zones; i++) { 23146+ total += hisi_zone[i].nbytes; 23147+ } 23148+ 23149+ /* unit is M */ 23150+ return (unsigned int)(total >> 20); 23151+} 23152+ 23153+int is_hicma_address(phys_addr_t phys, unsigned long size) 23154+{ 23155+ phys_addr_t start, end; 23156+ u32 i; 23157+ 23158+ for (i = 0; i < num_zones; i++) { 23159+ start = hisi_zone[i].phys_start; 23160+ end = hisi_zone[i].phys_start + hisi_zone[i].nbytes; 23161+ 23162+ if ((phys >= start) && ((phys + size) <= end)) { 23163+ /* 23164+ * Yes, found! 23165+ */ 23166+ return 1; 23167+ } 23168+ } 23169+ 23170+ return 0; 23171+} 23172+EXPORT_SYMBOL(is_hicma_address); 23173+ 23174+static int __init hisi_mmz_parse_cmdline(char *s) 23175+{ 23176+ char *line = NULL, *tmp = NULL; 23177+ char tmpline[256]; 23178+ 23179+ if (s == NULL) { 23180+ pr_info("There is no cma zone!\n"); 23181+ return 0; 23182+ } 23183+ strncpy(tmpline, s, sizeof(tmpline) - 1); 23184+ tmpline[sizeof(tmpline) - 1] = '\0'; 23185+ tmp = tmpline; 23186+ 23187+ while ((line = strsep(&tmp, ":")) != NULL) { 23188+ int i; 23189+ char *argv[6]; 23190+ 23191+ for (i = 0; (argv[i] = strsep(&line, ",")) != NULL;) 23192+ if (++i == ARRAY_SIZE(argv)) { 23193+ break; 23194+ } 23195+ 23196+ if (num_zones >= ZONE_MAX) 23197+ return 0; 23198+ hisi_zone[num_zones].pdev.coherent_dma_mask = DMA_BIT_MASK(64); 23199+ if (i == 4) { 23200+ strlcpy(hisi_zone[num_zones].name, argv[0], NAME_LEN_MAX); 23201+ hisi_zone[num_zones].gfp = (uintptr_t)memparse(argv[1], NULL); 23202+ hisi_zone[num_zones].phys_start = (uintptr_t)memparse(argv[2], NULL); 23203+ hisi_zone[num_zones].nbytes = (uintptr_t)memparse(argv[3], NULL); 23204+ } 23205+ 23206+ else if (i == 6) { 23207+ strlcpy(hisi_zone[num_zones].name, argv[0], NAME_LEN_MAX); 23208+ hisi_zone[num_zones].gfp = (uintptr_t)memparse(argv[1], NULL); 23209+ hisi_zone[num_zones].phys_start = (uintptr_t)memparse(argv[2], NULL); 23210+ hisi_zone[num_zones].nbytes = (uintptr_t)memparse(argv[3], NULL); 23211+ hisi_zone[num_zones].alloc_type = (uintptr_t)memparse(argv[4], NULL); 23212+ hisi_zone[num_zones].block_align = (uintptr_t)memparse(argv[5], NULL); 23213+ } else { 23214+ pr_err("hisi ion parameter is not correct\n"); 23215+ continue; 23216+ } 23217+ 23218+ num_zones++; 23219+ } 23220+ if (num_zones != 0) { 23221+ use_bootargs = 1; 23222+ } 23223+ 23224+ return 0; 23225+} 23226+early_param("mmz", hisi_mmz_parse_cmdline); 23227+ 23228+phys_addr_t hisi_get_zones_start(void) 23229+{ 23230+ u32 i; 23231+ phys_addr_t lowest_zone_base = memblock_end_of_DRAM(); 23232+ 23233+ for (i = 0; i < num_zones; i++) { 23234+ if (lowest_zone_base > hisi_zone[i].phys_start) { 23235+ lowest_zone_base = hisi_zone[i].phys_start; 23236+ } 23237+ } 23238+ 23239+ return lowest_zone_base; 23240+} 23241+EXPORT_SYMBOL(hisi_get_zones_start); 23242+ 23243+struct cma_zone *hisi_get_cma_zone(const char *name) 23244+{ 23245+ u32 i = 0; 23246+ 23247+ if (name == NULL) 23248+ return NULL; 23249+ for (i = 0; i < num_zones; i++) 23250+ if (strcmp(hisi_zone[i].name, name) == 0) { 23251+ break; 23252+ } 23253+ 23254+ if (i == num_zones) { 23255+ return NULL; 23256+ } 23257+ 23258+ return &hisi_zone[i]; 23259+} 23260+EXPORT_SYMBOL(hisi_get_cma_zone); 23261+ 23262+struct device *hisi_get_cma_device(const char *name) 23263+{ 23264+ u32 i = 0; 23265+ 23266+ if (name == NULL) 23267+ return NULL; 23268+ 23269+ for (i = 0; i < num_zones; i++) 23270+ if (strcmp(hisi_zone[i].name, name) == 0) { 23271+ break; 23272+ } 23273+ 23274+ if (i == num_zones) { 23275+ return NULL; 23276+ } 23277+ 23278+ return &hisi_zone[i].pdev; 23279+} 23280+EXPORT_SYMBOL(hisi_get_cma_device); 23281+ 23282+int __init hisi_declare_heap_memory(void) 23283+{ 23284+ struct cma *cma; 23285+ u32 i; 23286+ int ret = 0; 23287+ 23288+ if (use_bootargs == 0) { 23289+ pr_info("cma zone is not set!\n"); 23290+ return ret; 23291+ } 23292+ 23293+ for (i = 0; i < num_zones; i++) { 23294+ ret = dma_contiguous_reserve_area(hisi_zone[i].nbytes, 23295+ hisi_zone[i].phys_start, 0, &cma, true); 23296+ if (ret) { 23297+ panic("declare cma zone %s base: %lux size:%lux MB failed. ret:%d", 23298+ hisi_zone[i].name, (unsigned long)hisi_zone[i].phys_start, 23299+ (unsigned long)hisi_zone[i].nbytes >> 20, ret); 23300+ } else { 23301+ hisi_zone[i].pdev.cma_area = cma; 23302+ } 23303+ 23304+ hisi_zone[i].phys_start = 23305+ cma_get_base(hisi_zone[i].pdev.cma_area); 23306+ hisi_zone[i].nbytes = cma_get_size(hisi_zone[i].pdev.cma_area); 23307+ } 23308+ 23309+ return ret; 23310+} 23311+EXPORT_SYMBOL(hisi_declare_heap_memory); 23312+ 23313+static int hisi_mmz_setup(struct reserved_mem *rmem) 23314+{ 23315+ return 0; 23316+} 23317+RESERVEDMEM_OF_DECLARE(cma, "hisi-mmz", hisi_mmz_setup); 23318+ 23319diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig 23320index 7e693dcbd..c428abba0 100644 23321--- a/drivers/i2c/busses/Kconfig 23322+++ b/drivers/i2c/busses/Kconfig 23323@@ -640,6 +640,16 @@ config I2C_GPIO_FAULT_INJECTOR 23324 faults to an I2C bus, so another bus master can be stress-tested. 23325 This is for debugging. If unsure, say 'no'. 23326 23327+config I2C_HIBVT 23328+ tristate "Hisilicon BVT I2C Controller" 23329+ depends on ARCH_HISI_BVT 23330+ help 23331+ Say Y here to include support for Hisilicon BVT I2C controller in the 23332+ Hisilicon BVT SoCs. 23333+ 23334+ This driver can also be built as a module. If so, the module 23335+ will be called i2c-hibvt. 23336+ 23337 config I2C_HIGHLANDER 23338 tristate "Highlander FPGA SMBus interface" 23339 depends on SH_HIGHLANDER || COMPILE_TEST 23340@@ -1420,4 +1430,20 @@ config I2C_FSI 23341 This driver can also be built as a module. If so, the module will be 23342 called as i2c-fsi. 23343 23344+config DMA_MSG_MIN_LEN 23345+ int "Hisilicon I2C support DMA minimum LEN" 23346+ depends on I2C_HIBVT 23347+ range 1 4090 23348+ default 5 23349+ help 23350+ The i2c_msg minimum LEN of i2c support DMA,range from 1 to 4091 23351+ 23352+config DMA_MSG_MAX_LEN 23353+ int "Hisilicon I2C support DMA maximum LEN" 23354+ depends on I2C_HIBVT 23355+ range DMA_MSG_MIN_LEN 4090 23356+ default 4090 23357+ help 23358+ The i2c_msg maximum LEN of i2c support DMA,range from i2c_msg minimum LEN to 4090, 23359+ because DMA for 0xFFC one-time largest data transfers; 23360 endmenu 23361diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile 23362index 683c49fac..2c615a7c1 100644 23363--- a/drivers/i2c/busses/Makefile 23364+++ b/drivers/i2c/busses/Makefile 23365@@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o 23366 obj-$(CONFIG_I2C_EMEV2) += i2c-emev2.o 23367 obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o 23368 obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o 23369+obj-$(CONFIG_I2C_HIBVT) += i2c-hibvt.o 23370 obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o 23371 obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o 23372 obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o 23373diff --git a/drivers/i2c/busses/i2c-hibvt.c b/drivers/i2c/busses/i2c-hibvt.c 23374new file mode 100644 23375index 000000000..4c7cd494a 23376--- /dev/null 23377+++ b/drivers/i2c/busses/i2c-hibvt.c 23378@@ -0,0 +1,1451 @@ 23379+/* 23380+ * Hisilicon BVT I2C Controller Driver 23381+ * 23382+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 23383+ * 23384+ * This program is free software; you can redistribute it and/or modify it 23385+ * under the terms of the GNU General Public License as published by the 23386+ * Free Software Foundation; either version 2 of the License, or (at your 23387+ * option) any later version. 23388+ * 23389+ * This program is distributed in the hope that it will be useful, 23390+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 23391+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23392+ * GNU General Public License for more details. 23393+ * 23394+ * You should have received a copy of the GNU General Public License 23395+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 23396+ * 23397+ */ 23398+#include <linux/slab.h> 23399+#include <linux/clk.h> 23400+#include <linux/delay.h> 23401+#include <linux/i2c.h> 23402+#include <linux/interrupt.h> 23403+#include <linux/io.h> 23404+#include <linux/module.h> 23405+#include <linux/platform_device.h> 23406+#include <linux/dma-mapping.h> 23407+#include <asm/string.h> 23408+ 23409+#if defined(CONFIG_HI_DMAC) 23410+#include <linux/hidmac.h> 23411+#endif 23412+ 23413+#if defined(CONFIG_HIEDMAC) 23414+#include <linux/hiedmac.h> 23415+#endif 23416+ 23417+/* 23418+ * I2C Registers offsets 23419+ */ 23420+#define HIBVT_I2C_GLB 0x0 23421+#define HIBVT_I2C_SCL_H 0x4 23422+#define HIBVT_I2C_SCL_L 0x8 23423+#define HIBVT_I2C_DATA1 0x10 23424+#define HIBVT_I2C_TXF 0x20 23425+#define HIBVT_I2C_RXF 0x24 23426+#define HIBVT_I2C_CMD_BASE 0x30 23427+#define HIBVT_I2C_LOOP1 0xb0 23428+#define HIBVT_I2C_DST1 0xb4 23429+#define HIBVT_I2C_LOOP2 0xb8 23430+#define HIBVT_I2C_DST2 0xbc 23431+#define HIBVT_I2C_TX_WATER 0xc8 23432+#define HIBVT_I2C_RX_WATER 0xcc 23433+#define HIBVT_I2C_CTRL1 0xd0 23434+#define HIBVT_I2C_CTRL2 0xd4 23435+#define HIBVT_I2C_STAT 0xd8 23436+#define HIBVT_I2C_INTR_RAW 0xe0 23437+#define HIBVT_I2C_INTR_EN 0xe4 23438+#define HIBVT_I2C_INTR_STAT 0xe8 23439+ 23440+/* 23441+ * I2C Global Config Register -- HIBVT_I2C_GLB 23442+ */ 23443+#define GLB_EN_MASK BIT(0) 23444+#define GLB_SDA_HOLD_MASK GENMASK(23, 8) 23445+#define GLB_SDA_HOLD_SHIFT (8) 23446+#define should_copy_to_continuous_mem(addr) true 23447+ 23448+/* 23449+ * I2C Timing CMD Register -- HIBVT_I2C_CMD_BASE + n * 4 (n = 0, 1, 2, ... 31) 23450+ */ 23451+#define CMD_EXIT 0x0 23452+#define CMD_TX_S 0x1 23453+#define CMD_TX_D1_2 0x4 23454+#define CMD_TX_D1_1 0x5 23455+#define CMD_TX_FIFO 0x9 23456+#define CMD_RX_FIFO 0x12 23457+#define CMD_RX_ACK 0x13 23458+#define CMD_IGN_ACK 0x15 23459+#define CMD_TX_ACK 0x16 23460+#define CMD_TX_NACK 0x17 23461+#define CMD_JMP1 0x18 23462+#define CMD_JMP2 0x19 23463+#define CMD_UP_TXF 0x1d 23464+#define CMD_TX_RS 0x1e 23465+#define CMD_TX_P 0x1f 23466+ 23467+/* 23468+ * I2C Control Register 1 -- HIBVT_I2C_CTRL1 23469+ */ 23470+#define CTRL1_CMD_START_MASK BIT(0) 23471+#define CTRL1_DMA_OP_MASK (0x3 << 8) 23472+#define CTRL1_DMA_R (0x3 << 8) 23473+#define CTRL1_DMA_W (0x2 << 8) 23474+ 23475+/* 23476+ * I2C Status Register -- HIBVT_I2C_STAT 23477+ */ 23478+#define STAT_RXF_NOE_MASK BIT(16) /* RX FIFO not empty flag */ 23479+#define STAT_TXF_NOF_MASK BIT(19) /* TX FIFO not full flag */ 23480+ 23481+/* 23482+ * I2C Interrupt status and mask Register -- 23483+ * HIBVT_I2C_INTR_RAW, HIBVT_I2C_STAT, HIBVT_I2C_INTR_STAT 23484+ */ 23485+#define INTR_ABORT_MASK (BIT(0) | BIT(11)) 23486+#define INTR_RX_MASK BIT(2) 23487+#define INTR_TX_MASK BIT(4) 23488+#define INTR_CMD_DONE_MASK BIT(12) 23489+#define INTR_USE_MASK (INTR_ABORT_MASK \ 23490+ |INTR_RX_MASK \ 23491+ | INTR_TX_MASK \ 23492+ | INTR_CMD_DONE_MASK) 23493+#define INTR_ALL_MASK GENMASK(31, 0) 23494+ 23495+#define I2C_DEFAULT_FREQUENCY 100000 23496+#define I2C_TXF_DEPTH 64 23497+#define I2C_RXF_DEPTH 64 23498+#define I2C_TXF_WATER 32 23499+#define I2C_RXF_WATER 32 23500+#define I2C_WAIT_TIMEOUT 0x400 23501+#define I2C_IRQ_TIMEOUT (msecs_to_jiffies(1000)) 23502+ 23503+struct hibvt_i2c_dev { 23504+ struct device *dev; 23505+ struct i2c_adapter adap; 23506+ resource_size_t phybase; 23507+ void __iomem *base; 23508+ struct clk *clk; 23509+ int irq; 23510+ 23511+ unsigned int freq; 23512+ struct i2c_msg *msg; 23513+ unsigned int msg_num; 23514+ unsigned int msg_idx; 23515+ unsigned int msg_buf_ptr; 23516+ struct completion msg_complete; 23517+ 23518+ spinlock_t lock; 23519+ int status; 23520+}; 23521+static inline void hibvt_i2c_disable(const struct hibvt_i2c_dev *i2c); 23522+static inline void hibvt_i2c_cfg_irq(const struct hibvt_i2c_dev *i2c, 23523+ unsigned int flag); 23524+static inline unsigned int hibvt_i2c_clr_irq(const struct hibvt_i2c_dev *i2c); 23525+static inline void hibvt_i2c_enable(const struct hibvt_i2c_dev *i2c); 23526+ 23527+#define CHECK_SDA_IN_SHIFT (16) 23528+#define GPIO_MODE_SHIFT (8) 23529+#define FORCE_SCL_OEN_SHIFT (4) 23530+#define FORCE_SDA_OEN_SHIFT (0) 23531+ 23532+static void hibvt_i2c_rescue(const struct hibvt_i2c_dev *i2c) 23533+{ 23534+ unsigned int val; 23535+ unsigned int time_cnt; 23536+ int index; 23537+ 23538+ hibvt_i2c_disable(i2c); 23539+ hibvt_i2c_cfg_irq(i2c, 0); 23540+ hibvt_i2c_clr_irq(i2c); 23541+ 23542+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | 23543+ (0x1 << FORCE_SDA_OEN_SHIFT); 23544+ writel(val, i2c->base + HIBVT_I2C_CTRL2); 23545+ 23546+ time_cnt = 0; 23547+ do { 23548+ for (index = 0; index < 9; index++) { 23549+ val = (0x1 << GPIO_MODE_SHIFT) | 0x1; 23550+ writel(val, i2c->base + HIBVT_I2C_CTRL2); 23551+ 23552+ udelay(5); 23553+ 23554+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | 23555+ (0x1 << FORCE_SDA_OEN_SHIFT); 23556+ writel(val, i2c->base + HIBVT_I2C_CTRL2); 23557+ 23558+ udelay(5); 23559+ } 23560+ 23561+ time_cnt++; 23562+ if (time_cnt > I2C_WAIT_TIMEOUT) { 23563+ dev_err(i2c->dev, "wait Timeout!\n"); 23564+ goto disable_rescue; 23565+ } 23566+ 23567+ val = readl(i2c->base + HIBVT_I2C_CTRL2); 23568+ } while (!(val & (0x1 << CHECK_SDA_IN_SHIFT))); 23569+ 23570+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | 23571+ (0x1 << FORCE_SDA_OEN_SHIFT); 23572+ writel(val, i2c->base + HIBVT_I2C_CTRL2); 23573+ 23574+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT); 23575+ writel(val, i2c->base + HIBVT_I2C_CTRL2); 23576+ 23577+ udelay(10); 23578+ 23579+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | 23580+ (0x1 << FORCE_SDA_OEN_SHIFT); 23581+ writel(val, i2c->base + HIBVT_I2C_CTRL2); 23582+ 23583+disable_rescue: 23584+ val = (0x1 << FORCE_SCL_OEN_SHIFT) | 0x1; 23585+ writel(val, i2c->base + HIBVT_I2C_CTRL2); 23586+} 23587+ 23588+static inline void hibvt_i2c_disable(const struct hibvt_i2c_dev *i2c) 23589+{ 23590+ unsigned int val; 23591+ 23592+ val = readl(i2c->base + HIBVT_I2C_GLB); 23593+ val &= ~GLB_EN_MASK; 23594+ writel(val, i2c->base + HIBVT_I2C_GLB); 23595+} 23596+ 23597+static inline void hibvt_i2c_enable(const struct hibvt_i2c_dev *i2c) 23598+{ 23599+ unsigned int val; 23600+ 23601+ val = readl(i2c->base + HIBVT_I2C_GLB); 23602+ val |= GLB_EN_MASK; 23603+ writel(val, i2c->base + HIBVT_I2C_GLB); 23604+} 23605+ 23606+static inline void hibvt_i2c_cfg_irq(const struct hibvt_i2c_dev *i2c, 23607+ unsigned int flag) 23608+{ 23609+ writel(flag, i2c->base + HIBVT_I2C_INTR_EN); 23610+} 23611+ 23612+static inline void hibvt_i2c_disable_irq(const struct hibvt_i2c_dev *i2c, 23613+ unsigned int flag) 23614+{ 23615+ unsigned int val; 23616+ 23617+ val = readl(i2c->base + HIBVT_I2C_INTR_EN); 23618+ val &= ~flag; 23619+ writel(val, i2c->base + HIBVT_I2C_INTR_EN); 23620+} 23621+ 23622+static inline unsigned int hibvt_i2c_clr_irq(const struct hibvt_i2c_dev *i2c) 23623+{ 23624+ unsigned int val; 23625+ 23626+ val = readl(i2c->base + HIBVT_I2C_INTR_STAT); 23627+ writel(INTR_ALL_MASK, i2c->base + HIBVT_I2C_INTR_RAW); 23628+ 23629+ return val; 23630+} 23631+ 23632+static inline void hibvt_i2c_cmdreg_set(const struct hibvt_i2c_dev *i2c, 23633+ unsigned int cmd, unsigned int *offset) 23634+{ 23635+ dev_dbg(i2c->dev, "hii2c reg: offset=0x%x, cmd=0x%x...\n", 23636+ *offset * 4, cmd); 23637+ writel(cmd, i2c->base + HIBVT_I2C_CMD_BASE + *offset * 4); 23638+ (*offset)++; 23639+} 23640+ 23641+/* 23642+ * config i2c slave addr 23643+ */ 23644+static inline void hibvt_i2c_set_addr(const struct hibvt_i2c_dev *i2c) 23645+{ 23646+ struct i2c_msg *msg = i2c->msg; 23647+ u16 addr; 23648+ 23649+ if (msg->flags & I2C_M_TEN) { 23650+ /* First byte is 11110XX0 where XX is upper 2 bits */ 23651+ addr = ((msg->addr & 0x300) << 1) | 0xf000; 23652+ if (msg->flags & I2C_M_RD) 23653+ addr |= 1 << 8; 23654+ 23655+ /* Second byte is the remaining 8 bits */ 23656+ addr |= msg->addr & 0xff; 23657+ } else { 23658+ addr = (msg->addr & 0x7f) << 1; 23659+ if (msg->flags & I2C_M_RD) 23660+ addr |= 1; 23661+ } 23662+ 23663+ writel(addr, i2c->base + HIBVT_I2C_DATA1); 23664+} 23665+ 23666+/* 23667+ * Start command sequence 23668+ */ 23669+static inline void hibvt_i2c_start_cmd(const struct hibvt_i2c_dev *i2c) 23670+{ 23671+ unsigned int val; 23672+ 23673+ val = readl(i2c->base + HIBVT_I2C_CTRL1); 23674+ val |= CTRL1_CMD_START_MASK; 23675+ writel(val, i2c->base + HIBVT_I2C_CTRL1); 23676+} 23677+ 23678+static int hibvt_i2c_wait_rx_noempty(const struct hibvt_i2c_dev *i2c) 23679+{ 23680+ unsigned int time_cnt = 0; 23681+ unsigned int val; 23682+ 23683+ do { 23684+ val = readl(i2c->base + HIBVT_I2C_STAT); 23685+ if (val & STAT_RXF_NOE_MASK) 23686+ return 0; 23687+ 23688+ udelay(50); 23689+ } while (time_cnt++ < I2C_WAIT_TIMEOUT); 23690+ 23691+ hibvt_i2c_rescue(i2c); 23692+ 23693+ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", 23694+ readl(i2c->base + HIBVT_I2C_INTR_RAW), val); 23695+ return -EIO; 23696+} 23697+ 23698+static int hibvt_i2c_wait_tx_nofull(const struct hibvt_i2c_dev *i2c) 23699+{ 23700+ unsigned int time_cnt = 0; 23701+ unsigned int val; 23702+ 23703+ do { 23704+ val = readl(i2c->base + HIBVT_I2C_STAT); 23705+ if (val & STAT_TXF_NOF_MASK) 23706+ return 0; 23707+ 23708+ udelay(50); 23709+ } while (time_cnt++ < I2C_WAIT_TIMEOUT); 23710+ 23711+ hibvt_i2c_rescue(i2c); 23712+ 23713+ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", 23714+ readl(i2c->base + HIBVT_I2C_INTR_RAW), val); 23715+ return -EIO; 23716+} 23717+ 23718+static int hibvt_i2c_wait_idle(const struct hibvt_i2c_dev *i2c) 23719+{ 23720+ unsigned int time_cnt = 0; 23721+ unsigned int val; 23722+ 23723+ do { 23724+ val = readl(i2c->base + HIBVT_I2C_INTR_RAW); 23725+ if (val & (INTR_ABORT_MASK)) { 23726+ dev_err(i2c->dev, "wait idle abort!, RIS: 0x%x\n", 23727+ val); 23728+ return -EIO; 23729+ } 23730+ 23731+ if (val & INTR_CMD_DONE_MASK) 23732+ return 0; 23733+ 23734+ udelay(50); 23735+ } while (time_cnt++ < I2C_WAIT_TIMEOUT); 23736+ 23737+ hibvt_i2c_rescue(i2c); 23738+ 23739+ dev_err(i2c->dev, "wait idle timeout, RIS: 0x%x, SR: 0x%x\n", 23740+ val, readl(i2c->base + HIBVT_I2C_STAT)); 23741+ 23742+ return -EIO; 23743+} 23744+ 23745+static void hibvt_i2c_set_freq(struct hibvt_i2c_dev *i2c) 23746+{ 23747+ unsigned int max_freq, freq; 23748+ unsigned int clk_rate; 23749+ unsigned int val; 23750+ 23751+ freq = i2c->freq; 23752+ clk_rate = clk_get_rate(i2c->clk); 23753+ max_freq = clk_rate >> 1; 23754+ 23755+ if (freq > max_freq) { 23756+ i2c->freq = max_freq; 23757+ freq = i2c->freq; 23758+ } 23759+ 23760+ if (!freq) { 23761+ pr_err("hibvt_i2c_set_freq:freq can't be zero!"); 23762+ return; 23763+ } 23764+ 23765+ if (freq <= 100000) { 23766+ /* in normal mode F_scl: freq 23767+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.5 23768+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.5 23769+ */ 23770+ val = clk_rate / (freq * 2); 23771+ writel(val, i2c->base + HIBVT_I2C_SCL_H); 23772+ writel(val, i2c->base + HIBVT_I2C_SCL_L); 23773+ } else { 23774+ /* in fast mode F_scl: freq 23775+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.36 23776+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.64 23777+ */ 23778+ val = ((clk_rate / 100) * 36) / freq; 23779+ writel(val, i2c->base + HIBVT_I2C_SCL_H); 23780+ val = ((clk_rate / 100) * 64) / freq; 23781+ writel(val, i2c->base + HIBVT_I2C_SCL_L); 23782+ } 23783+ 23784+ val = readl(i2c->base + HIBVT_I2C_GLB); 23785+ val &= ~GLB_SDA_HOLD_MASK; 23786+ val |= ((0xa << GLB_SDA_HOLD_SHIFT) & GLB_SDA_HOLD_MASK); 23787+ writel(val, i2c->base + HIBVT_I2C_GLB); 23788+} 23789+ 23790+/* 23791+ * set i2c controller TX and RX FIFO water 23792+ */ 23793+static inline void hibvt_i2c_set_water(const struct hibvt_i2c_dev *i2c) 23794+{ 23795+ writel(I2C_TXF_WATER, i2c->base + HIBVT_I2C_TX_WATER); 23796+ writel(I2C_RXF_WATER, i2c->base + HIBVT_I2C_RX_WATER); 23797+} 23798+ 23799+/* 23800+ * initialise the controller, set i2c bus interface freq 23801+ */ 23802+static void hibvt_i2c_hw_init(struct hibvt_i2c_dev *i2c) 23803+{ 23804+ hibvt_i2c_disable(i2c); 23805+ hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK); 23806+ hibvt_i2c_set_freq(i2c); 23807+ hibvt_i2c_set_water(i2c); 23808+} 23809+ 23810+/* 23811+ * hibvt_i2c_cfg_cmd - config i2c controller command sequence 23812+ * 23813+ * After all the timing command is configured, 23814+ * and then start the command, you can i2c communication, 23815+ * and then only need to read and write i2c fifo. 23816+ */ 23817+static void hibvt_i2c_cfg_cmd(const struct hibvt_i2c_dev *i2c) 23818+{ 23819+ struct i2c_msg *msg = i2c->msg; 23820+ int offset = 0; 23821+ 23822+ if (i2c->msg_idx == 0) 23823+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_S, &offset); 23824+ else 23825+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset); 23826+ 23827+ if (msg->flags & I2C_M_TEN) { 23828+ if (i2c->msg_idx == 0) { 23829+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); 23830+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); 23831+ } else { 23832+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); 23833+ } 23834+ } else { 23835+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); 23836+ } 23837+ 23838+ if (msg->flags & I2C_M_IGNORE_NAK) 23839+ hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); 23840+ else 23841+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); 23842+ 23843+ if (msg->flags & I2C_M_RD) { 23844+ if (msg->len >= 2) { 23845+ writel(offset, i2c->base + HIBVT_I2C_DST1); 23846+ writel(msg->len - 2, i2c->base + HIBVT_I2C_LOOP1); 23847+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); 23848+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset); 23849+ hibvt_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); 23850+ } 23851+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); 23852+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset); 23853+ } else { 23854+ writel(offset, i2c->base + HIBVT_I2C_DST1); 23855+ writel(msg->len - 1, i2c->base + HIBVT_I2C_LOOP1); 23856+ hibvt_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); 23857+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); 23858+ 23859+ if (msg->flags & I2C_M_IGNORE_NAK) 23860+ hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); 23861+ else 23862+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); 23863+ 23864+ hibvt_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); 23865+ } 23866+ 23867+ if ((i2c->msg_idx == (i2c->msg_num - 1)) || (msg->flags & I2C_M_STOP)) { 23868+ dev_dbg(i2c->dev, "run to %s %d...TX STOP\n", 23869+ __func__, __LINE__); 23870+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_P, &offset); 23871+ } 23872+ 23873+ hibvt_i2c_cmdreg_set(i2c, CMD_EXIT, &offset); 23874+} 23875+ 23876+static void hibvt_i2c_cfg_cmd_mul_reg(struct hibvt_i2c_dev *i2c,unsigned int reg_data_width) 23877+{ 23878+ struct i2c_msg *msg = i2c->msg; 23879+ int offset = 0; 23880+ int i; 23881+ 23882+ if (i2c->msg_idx == 0) { 23883+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_S, &offset); 23884+ } else { 23885+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset); 23886+ } 23887+ 23888+ if (msg->flags & I2C_M_TEN) { 23889+ if (i2c->msg_idx == 0) { 23890+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); 23891+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); 23892+ } else { 23893+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); 23894+ } 23895+ } else { 23896+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); 23897+ } 23898+ 23899+ if (msg->flags & I2C_M_IGNORE_NAK) { 23900+ hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); 23901+ } else { 23902+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); 23903+ } 23904+ 23905+ if (msg->flags & I2C_M_RD) { 23906+ if (msg->len >= 2) { 23907+ writel(offset, i2c->base + HIBVT_I2C_DST1); 23908+ writel(msg->len - 2, i2c->base + HIBVT_I2C_LOOP1); 23909+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); 23910+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset); 23911+ hibvt_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); 23912+ } 23913+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); 23914+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset); 23915+ } else { 23916+ for(i = 0; i < reg_data_width - 1; i++){ 23917+ hibvt_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); 23918+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); 23919+ hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); 23920+ } 23921+ hibvt_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); 23922+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); 23923+ hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); 23924+ } 23925+ 23926+ hibvt_i2c_cmdreg_set(i2c, CMD_TX_P, &offset); 23927+ if(((msg->len / reg_data_width) - 1) > 0){ 23928+ writel(0, i2c->base + HIBVT_I2C_DST2); 23929+ writel((msg->len / reg_data_width) - 1, i2c->base + HIBVT_I2C_LOOP2); 23930+ hibvt_i2c_cmdreg_set(i2c, CMD_JMP2, &offset); 23931+ } 23932+ hibvt_i2c_cmdreg_set(i2c, CMD_EXIT, &offset); 23933+} 23934+ 23935+static inline void check_i2c_send_complete(struct hibvt_i2c_dev *i2c) 23936+{ 23937+ unsigned int val; 23938+ val = readl(i2c->base + HIBVT_I2C_GLB); 23939+ if(val & GLB_EN_MASK){ 23940+ hibvt_i2c_wait_idle(i2c); 23941+ hibvt_i2c_disable(i2c); 23942+ } 23943+} 23944+ 23945+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC) 23946+int dma_to_i2c(unsigned long src, unsigned int dst, unsigned int length) 23947+{ 23948+ int chan; 23949+ 23950+ chan = do_dma_m2p(src, dst, length); 23951+ if (chan == -1) 23952+ pr_err("dma_to_i2c error\n"); 23953+ 23954+ return chan; 23955+} 23956+ 23957+int i2c_to_dma(unsigned int src, unsigned long dst, 23958+ unsigned int length) 23959+{ 23960+ int chan; 23961+ 23962+ chan = do_dma_p2m(dst, src, length); 23963+ if (chan == -1) 23964+ pr_err("dma_p2m error...\n"); 23965+ 23966+ return chan; 23967+} 23968+ 23969+static int hibvt_i2c_do_dma_write(struct hibvt_i2c_dev *i2c, 23970+ unsigned long dma_dst_addr) 23971+{ 23972+ int chan, val; 23973+ int status = 0; 23974+ struct i2c_msg *msg = i2c->msg; 23975+ 23976+ check_i2c_send_complete(i2c); 23977+ hibvt_i2c_set_freq(i2c); 23978+ writel(0x1, i2c->base + HIBVT_I2C_TX_WATER); 23979+ hibvt_i2c_enable(i2c); 23980+ hibvt_i2c_clr_irq(i2c); 23981+ hibvt_i2c_set_addr(i2c); 23982+ hibvt_i2c_cfg_cmd(i2c); 23983+ 23984+ /* transmit DATA from DMAC to I2C in DMA mode */ 23985+ chan = dma_to_i2c(dma_dst_addr, (i2c->phybase + HIBVT_I2C_TXF), 23986+ msg->len); 23987+ if (chan == -1) { 23988+ status = -1; 23989+ goto fail_0; 23990+ } 23991+ 23992+ val = readl(i2c->base + HIBVT_I2C_CTRL1); 23993+ val &= ~CTRL1_DMA_OP_MASK; 23994+ val |= CTRL1_DMA_W | CTRL1_CMD_START_MASK; 23995+ writel(val, i2c->base + HIBVT_I2C_CTRL1); 23996+ 23997+ if (dmac_wait(chan) != DMAC_CHN_SUCCESS) { 23998+ status = -1; 23999+ goto fail_1; 24000+ } 24001+ 24002+ status = hibvt_i2c_wait_idle(i2c); 24003+ 24004+fail_1: 24005+ dmac_channel_free((unsigned int)chan); 24006+fail_0: 24007+ hibvt_i2c_disable(i2c); 24008+ 24009+ return status; 24010+} 24011+ 24012+static int hibvt_i2c_do_dma_write_mul_reg(struct hibvt_i2c_dev *i2c, 24013+ unsigned long dma_dst_addr, unsigned int reg_data_width) 24014+{ 24015+ int chan, val, status = 0; 24016+ struct i2c_msg *msg = i2c->msg; 24017+ 24018+ 24019+ check_i2c_send_complete(i2c); 24020+ hibvt_i2c_set_freq(i2c); 24021+ writel(0x1, i2c->base + HIBVT_I2C_TX_WATER); 24022+ hibvt_i2c_enable(i2c); 24023+ hibvt_i2c_clr_irq(i2c); 24024+ hibvt_i2c_set_addr(i2c); 24025+ hibvt_i2c_cfg_cmd_mul_reg(i2c, reg_data_width); 24026+ 24027+ /* transmit DATA from DMAC to I2C in DMA mode */ 24028+ chan = dma_to_i2c(dma_dst_addr, (i2c->phybase + HIBVT_I2C_TXF), 24029+ msg->len); 24030+ if (chan == -1) { 24031+ status = -1; 24032+ goto fail_0; 24033+ } 24034+ 24035+ val = readl(i2c->base + HIBVT_I2C_CTRL1); 24036+ val &= ~CTRL1_DMA_OP_MASK; 24037+ val |= CTRL1_DMA_W | CTRL1_CMD_START_MASK; 24038+ writel(val, i2c->base + HIBVT_I2C_CTRL1); 24039+ 24040+fail_0: 24041+ return status; 24042+} 24043+ 24044+static int hibvt_i2c_do_dma_read(struct hibvt_i2c_dev *i2c, 24045+ unsigned long dma_dst_addr) 24046+{ 24047+ int val, chan; 24048+ int status = 0; 24049+ struct i2c_msg *msg = i2c->msg; 24050+ 24051+ check_i2c_send_complete(i2c); 24052+ hibvt_i2c_set_freq(i2c); 24053+ writel(0x0, i2c->base + HIBVT_I2C_RX_WATER); 24054+ hibvt_i2c_enable(i2c); 24055+ hibvt_i2c_clr_irq(i2c); 24056+ hibvt_i2c_set_addr(i2c); 24057+ hibvt_i2c_cfg_cmd(i2c); 24058+ 24059+ /* transmit DATA from I2C to DMAC in DMA mode */ 24060+ chan = i2c_to_dma((i2c->phybase + HIBVT_I2C_RXF), 24061+ dma_dst_addr, msg->len); 24062+ if (chan == -1) { 24063+ status = -1; 24064+ goto fail_0; 24065+ } 24066+ 24067+ val = readl(i2c->base + HIBVT_I2C_CTRL1); 24068+ val &= ~CTRL1_DMA_OP_MASK; 24069+ val |= CTRL1_CMD_START_MASK | CTRL1_DMA_R; 24070+ writel(val, i2c->base + HIBVT_I2C_CTRL1); 24071+ 24072+ if (dmac_wait(chan) != DMAC_CHN_SUCCESS) { 24073+ status = -1; 24074+ goto fail_1; 24075+ } 24076+ 24077+ status = hibvt_i2c_wait_idle(i2c); 24078+ 24079+fail_1: 24080+ dmac_channel_free((unsigned int)chan); 24081+fail_0: 24082+ hibvt_i2c_disable(i2c); 24083+ 24084+ return status; 24085+} 24086+ 24087+static int copy_to_continuous_mem(struct hibvt_i2c_dev *i2c) 24088+{ 24089+ if (should_copy_to_continuous_mem(i2c->msg->buf)) { 24090+ i2c->msg->highmem_buf = i2c->msg->buf; 24091+ i2c->msg->buf = kmalloc(i2c->msg->len, GFP_KERNEL | __GFP_ATOMIC); 24092+ if (i2c->msg->buf == NULL) { 24093+ i2c->msg->buf = i2c->msg->highmem_buf; 24094+ dev_err(i2c->dev, "Allocate continuous memory fail.\n"); 24095+ return -EINVAL; 24096+ } 24097+ } else { 24098+ i2c->msg->highmem_buf = NULL; 24099+ } 24100+ return 0; 24101+} 24102+ 24103+static int hibvt_i2c_dma_xfer_one_msg(struct hibvt_i2c_dev *i2c) 24104+{ 24105+ unsigned int status; 24106+ struct i2c_msg *msg = i2c->msg; 24107+ dma_addr_t dma_dst_addr; 24108+ 24109+ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", 24110+ __func__, __LINE__, msg->flags, msg->len); 24111+ 24112+ if (copy_to_continuous_mem(i2c)) 24113+ return -EINVAL; 24114+ 24115+ if (msg->flags & I2C_M_RD) { 24116+ mb(); 24117+ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, 24118+ msg->len, DMA_FROM_DEVICE); 24119+ status = dma_mapping_error(i2c->dev, dma_dst_addr); 24120+ if (status) { 24121+ dev_err(i2c->dev, "DMA mapping failed\n"); 24122+ goto out; 24123+ } 24124+ 24125+ status = hibvt_i2c_do_dma_read(i2c, dma_dst_addr); 24126+ 24127+ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_FROM_DEVICE); 24128+ mb(); 24129+ if (i2c->msg->highmem_buf) 24130+ memcpy(msg->highmem_buf, msg->buf, msg->len); 24131+ } else { 24132+ if (i2c->msg->highmem_buf) 24133+ memcpy(msg->buf, msg->highmem_buf, msg->len); 24134+ mb(); 24135+ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, 24136+ msg->len, DMA_TO_DEVICE); 24137+ status = dma_mapping_error(i2c->dev, dma_dst_addr); 24138+ if (status) { 24139+ dev_err(i2c->dev, "DMA mapping failed\n"); 24140+ goto out; 24141+ } 24142+ 24143+ status = hibvt_i2c_do_dma_write(i2c, dma_dst_addr); 24144+ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_TO_DEVICE); 24145+ mb(); 24146+ } 24147+ 24148+out: 24149+ if (i2c->msg->highmem_buf) { 24150+ kfree(msg->buf); 24151+ msg->buf = msg->highmem_buf; 24152+ msg->highmem_buf = NULL; 24153+ } 24154+ 24155+ if (!status) { 24156+ status = hibvt_i2c_wait_idle(i2c); 24157+ hibvt_i2c_disable(i2c); 24158+ } 24159+ 24160+ return status; 24161+} 24162+ 24163+static int hibvt_i2c_dma_xfer_one_msg_mul_reg(struct hibvt_i2c_dev *i2c, unsigned int reg_data_width) 24164+{ 24165+ unsigned int status; 24166+ struct i2c_msg *msg = i2c->msg; 24167+ dma_addr_t dma_dst_addr; 24168+ 24169+ 24170+ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", 24171+ __func__, __LINE__, msg->flags, msg->len); 24172+ 24173+ if (copy_to_continuous_mem(i2c)) 24174+ return -EINVAL; 24175+ 24176+ if (msg->flags & I2C_M_RD) { 24177+ mb(); 24178+ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, 24179+ msg->len, DMA_FROM_DEVICE); 24180+ status = dma_mapping_error(i2c->dev, dma_dst_addr); 24181+ if (status) { 24182+ dev_err(i2c->dev, "DMA mapping failed\n"); 24183+ goto out; 24184+ } 24185+ 24186+ status = hibvt_i2c_do_dma_read(i2c, dma_dst_addr); 24187+ 24188+ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_FROM_DEVICE); 24189+ mb(); 24190+ if (i2c->msg->highmem_buf) 24191+ memcpy(msg->highmem_buf, msg->buf, msg->len); 24192+ } else { 24193+ if (i2c->msg->highmem_buf) 24194+ memcpy(msg->buf, msg->highmem_buf, msg->len); 24195+ mb(); 24196+ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, 24197+ msg->len, DMA_TO_DEVICE); 24198+ status = dma_mapping_error(i2c->dev, dma_dst_addr); 24199+ if (status) { 24200+ dev_err(i2c->dev, "DMA mapping failed\n"); 24201+ goto out; 24202+ } 24203+ 24204+ status = hibvt_i2c_do_dma_write_mul_reg(i2c, dma_dst_addr, reg_data_width); 24205+ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_TO_DEVICE); 24206+ mb(); 24207+ } 24208+ 24209+out: 24210+ if (i2c->msg->highmem_buf) { 24211+ kfree(msg->buf); 24212+ msg->buf = msg->highmem_buf; 24213+ msg->highmem_buf = NULL; 24214+ } 24215+ return status; 24216+} 24217+#endif 24218+static int hibvt_i2c_polling_xfer_one_msg(struct hibvt_i2c_dev *i2c) 24219+{ 24220+ int status; 24221+ unsigned int val; 24222+ struct i2c_msg *msg = i2c->msg; 24223+ 24224+ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", 24225+ __func__, __LINE__, msg->flags, msg->len); 24226+ 24227+ check_i2c_send_complete(i2c); 24228+ hibvt_i2c_enable(i2c); 24229+ hibvt_i2c_clr_irq(i2c); 24230+ hibvt_i2c_set_addr(i2c); 24231+ hibvt_i2c_cfg_cmd(i2c); 24232+ hibvt_i2c_start_cmd(i2c); 24233+ 24234+ i2c->msg_buf_ptr = 0; 24235+ 24236+ if (msg->flags & I2C_M_RD) { 24237+ while (i2c->msg_buf_ptr < msg->len) { 24238+ status = hibvt_i2c_wait_rx_noempty(i2c); 24239+ if (status) 24240+ goto end; 24241+ 24242+ val = readl(i2c->base + HIBVT_I2C_RXF); 24243+ msg->buf[i2c->msg_buf_ptr] = val; 24244+ i2c->msg_buf_ptr++; 24245+ } 24246+ } else { 24247+ while (i2c->msg_buf_ptr < msg->len) { 24248+ status = hibvt_i2c_wait_tx_nofull(i2c); 24249+ if (status) 24250+ goto end; 24251+ 24252+ val = msg->buf[i2c->msg_buf_ptr]; 24253+ writel(val, i2c->base + HIBVT_I2C_TXF); 24254+ i2c->msg_buf_ptr++; 24255+ } 24256+ } 24257+ 24258+ status = hibvt_i2c_wait_idle(i2c); 24259+end: 24260+ hibvt_i2c_disable(i2c); 24261+ 24262+ return status; 24263+} 24264+ 24265+static int hibvt_i2c_polling_xfer_one_msg_mul_reg(struct hibvt_i2c_dev *i2c, unsigned int reg_data_width) 24266+{ 24267+ int status; 24268+ unsigned int val; 24269+ struct i2c_msg *msg = i2c->msg; 24270+ 24271+ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", 24272+ __func__, __LINE__, msg->flags, msg->len); 24273+ 24274+ check_i2c_send_complete(i2c); 24275+ hibvt_i2c_enable(i2c); 24276+ hibvt_i2c_clr_irq(i2c); 24277+ hibvt_i2c_set_addr(i2c); 24278+ hibvt_i2c_cfg_cmd_mul_reg(i2c, reg_data_width); 24279+ hibvt_i2c_start_cmd(i2c); 24280+ 24281+ i2c->msg_buf_ptr = 0; 24282+ 24283+ if (msg->flags & I2C_M_RD) { 24284+ while (i2c->msg_buf_ptr < msg->len) { 24285+ status = hibvt_i2c_wait_rx_noempty(i2c); 24286+ if (status) { 24287+ goto end; 24288+ } 24289+ 24290+ val = readl(i2c->base + HIBVT_I2C_RXF); 24291+ msg->buf[i2c->msg_buf_ptr] = val; 24292+ i2c->msg_buf_ptr++; 24293+ 24294+ } 24295+ } else { 24296+ while (i2c->msg_buf_ptr < msg->len) { 24297+ status = hibvt_i2c_wait_tx_nofull(i2c); 24298+ if (status) { 24299+ goto end; 24300+ } 24301+ 24302+ val = msg->buf[i2c->msg_buf_ptr]; 24303+ writel(val, i2c->base + HIBVT_I2C_TXF); 24304+ i2c->msg_buf_ptr++; 24305+ } 24306+ } 24307+ 24308+end: 24309+ return status; 24310+} 24311+ 24312+static irqreturn_t hibvt_i2c_isr(int irq, void *dev_id) 24313+{ 24314+ struct hibvt_i2c_dev *i2c = dev_id; 24315+ unsigned int irq_status; 24316+ struct i2c_msg *msg = i2c->msg; 24317+ 24318+ spin_lock(&i2c->lock); 24319+ 24320+ irq_status = hibvt_i2c_clr_irq(i2c); 24321+ dev_dbg(i2c->dev, "%s RIS: 0x%x\n", __func__, irq_status); 24322+ 24323+ if (!irq_status) { 24324+ dev_dbg(i2c->dev, "no irq\n"); 24325+ goto end; 24326+ } 24327+ 24328+ if (irq_status & INTR_ABORT_MASK) { 24329+ dev_err(i2c->dev, "irq handle abort, RIS: 0x%x\n", 24330+ irq_status); 24331+ i2c->status = -EIO; 24332+ hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK); 24333+ 24334+ complete(&i2c->msg_complete); 24335+ goto end; 24336+ } 24337+ 24338+ if (msg->flags & I2C_M_RD) { 24339+ while ((readl(i2c->base + HIBVT_I2C_STAT) & STAT_RXF_NOE_MASK) 24340+ && (i2c->msg_buf_ptr < msg->len)) { 24341+ msg->buf[i2c->msg_buf_ptr] = 24342+ readl(i2c->base + HIBVT_I2C_RXF); 24343+ i2c->msg_buf_ptr++; 24344+ } 24345+ } else { 24346+ while ((readl(i2c->base + HIBVT_I2C_STAT) & STAT_TXF_NOF_MASK) 24347+ && (i2c->msg_buf_ptr < msg->len)) { 24348+ writel(msg->buf[i2c->msg_buf_ptr], 24349+ i2c->base + HIBVT_I2C_TXF); 24350+ i2c->msg_buf_ptr++; 24351+ } 24352+ } 24353+ 24354+ if (i2c->msg_buf_ptr >= msg->len) 24355+ hibvt_i2c_disable_irq(i2c, INTR_TX_MASK | INTR_RX_MASK); 24356+ 24357+ if (irq_status & INTR_CMD_DONE_MASK) { 24358+ dev_dbg(i2c->dev, "cmd done\n"); 24359+ i2c->status = 0; 24360+ hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK); 24361+ 24362+ complete(&i2c->msg_complete); 24363+ } 24364+ 24365+end: 24366+ spin_unlock(&i2c->lock); 24367+ 24368+ return IRQ_HANDLED; 24369+} 24370+ 24371+static int hibvt_i2c_interrupt_xfer_one_msg(struct hibvt_i2c_dev *i2c) 24372+{ 24373+ int status; 24374+ struct i2c_msg *msg = i2c->msg; 24375+ unsigned long timeout; 24376+ unsigned long flags; 24377+ 24378+ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", 24379+ __func__, __LINE__, msg->flags, msg->len); 24380+ 24381+ reinit_completion(&i2c->msg_complete); 24382+ i2c->msg_buf_ptr = 0; 24383+ i2c->status = -EIO; 24384+ 24385+ spin_lock_irqsave(&i2c->lock, flags); 24386+ check_i2c_send_complete(i2c); 24387+ hibvt_i2c_enable(i2c); 24388+ hibvt_i2c_clr_irq(i2c); 24389+ if (msg->flags & I2C_M_RD) 24390+ hibvt_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_TX_MASK); 24391+ else 24392+ hibvt_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_RX_MASK); 24393+ 24394+ hibvt_i2c_set_addr(i2c); 24395+ hibvt_i2c_cfg_cmd(i2c); 24396+ hibvt_i2c_start_cmd(i2c); 24397+ spin_unlock_irqrestore(&i2c->lock, flags); 24398+ 24399+ timeout = wait_for_completion_timeout(&i2c->msg_complete, 24400+ I2C_IRQ_TIMEOUT); 24401+ 24402+ spin_lock_irqsave(&i2c->lock, flags); 24403+ if (timeout == 0) { 24404+ hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK); 24405+ status = -EIO; 24406+ dev_err(i2c->dev, "%s timeout\n", 24407+ msg->flags & I2C_M_RD ? "rx" : "tx"); 24408+ } else { 24409+ status = i2c->status; 24410+ } 24411+ 24412+ hibvt_i2c_disable(i2c); 24413+ 24414+ spin_unlock_irqrestore(&i2c->lock, flags); 24415+ return status; 24416+} 24417+ 24418+/* 24419+ * Master transfer function 24420+ */ 24421+static int hibvt_i2c_xfer(struct i2c_adapter *adap, 24422+ struct i2c_msg *msgs, int num) 24423+{ 24424+ struct hibvt_i2c_dev *i2c = i2c_get_adapdata(adap); 24425+ int status = -EINVAL; 24426+ unsigned long flags; 24427+ 24428+ if (!msgs || (num <= 0)) { 24429+ dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n"); 24430+ return -EINVAL; 24431+ } 24432+ 24433+ spin_lock_irqsave(&i2c->lock, flags); 24434+ 24435+ i2c->msg = msgs; 24436+ i2c->msg_num = num; 24437+ i2c->msg_idx = 0; 24438+ 24439+ while (i2c->msg_idx < i2c->msg_num) { 24440+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC) 24441+ if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) && 24442+ (i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN)) { 24443+ status = hibvt_i2c_dma_xfer_one_msg(i2c); 24444+ if (status) 24445+ break; 24446+ } else if (i2c->irq >= 0) { 24447+#else 24448+ if (i2c->irq >= 0) { 24449+#endif 24450+ spin_unlock_irqrestore(&i2c->lock, flags); 24451+ status = hibvt_i2c_interrupt_xfer_one_msg(i2c); 24452+ spin_lock_irqsave(&i2c->lock, flags); 24453+ if (status) 24454+ break; 24455+ } else { 24456+ status = hibvt_i2c_polling_xfer_one_msg(i2c); 24457+ if (status) 24458+ break; 24459+ } 24460+ i2c->msg++; 24461+ i2c->msg_idx++; 24462+ } 24463+ 24464+ if (!status || i2c->msg_idx > 0) 24465+ status = i2c->msg_idx; 24466+ 24467+ spin_unlock_irqrestore(&i2c->lock, flags); 24468+ return status; 24469+} 24470+ 24471+/* hibvt_i2c_break_polling_xfer 24472+ * 24473+ * I2c polling independent branch, Shielding interrupt interface 24474+ */ 24475+static int hibvt_i2c_break_polling_xfer(const struct i2c_adapter *adap, 24476+ struct i2c_msg *msgs, int num) 24477+{ 24478+ struct hibvt_i2c_dev *i2c = i2c_get_adapdata(adap); 24479+ int status = -EINVAL; 24480+ unsigned long flags; 24481+ if (!msgs || (num <= 0)) { 24482+ dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n"); 24483+ return -EINVAL; 24484+ } 24485+ spin_lock_irqsave(&i2c->lock, flags); 24486+ i2c->msg = msgs; 24487+ i2c->msg_num = num; 24488+ i2c->msg_idx = 0; 24489+ while (i2c->msg_idx < i2c->msg_num) { 24490+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC) 24491+ if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) && 24492+ (i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN)) { 24493+ status = hibvt_i2c_dma_xfer_one_msg(i2c); 24494+ if (status) 24495+ break; 24496+ } 24497+#else 24498+ status = hibvt_i2c_polling_xfer_one_msg(i2c); 24499+ if (status) 24500+ break; 24501+#endif 24502+ i2c->msg++; 24503+ i2c->msg_idx++; 24504+ } 24505+ if (!status || i2c->msg_idx > 0) 24506+ status = i2c->msg_idx; 24507+ spin_unlock_irqrestore(&i2c->lock, flags); 24508+ return status; 24509+} 24510+ 24511+static int hibvt_i2c_mul_reg_xfer(struct i2c_adapter *adap, 24512+ struct i2c_msg *msgs, int num, unsigned int reg_data_width) 24513+{ 24514+ struct hibvt_i2c_dev *i2c = i2c_get_adapdata(adap); 24515+ int status = -EINVAL; 24516+ unsigned long flags; 24517+ if (!msgs || (num <= 0)) { 24518+ dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n"); 24519+ return -EINVAL; 24520+ } 24521+ spin_lock_irqsave(&i2c->lock, flags); 24522+ i2c->msg = msgs; 24523+ i2c->msg_num = num; 24524+ i2c->msg_idx = 0; 24525+ while (i2c->msg_idx < i2c->msg_num) { 24526+ if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) && (i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN) && (i2c->msg->flags & I2C_M_DMA)) { 24527+#if defined(CONFIG_HIEDMAC) && defined(CONFIG_HIEDMAC_INTERRUPT) 24528+ status = hibvt_i2c_dma_xfer_one_msg_mul_reg(i2c, reg_data_width); 24529+#endif 24530+ if (status) { 24531+ break; 24532+ } 24533+ } else { 24534+ status = hibvt_i2c_polling_xfer_one_msg_mul_reg(i2c, reg_data_width); 24535+ if (status) { 24536+ break; 24537+ } 24538+ } 24539+ i2c->msg++; 24540+ i2c->msg_idx++; 24541+ } 24542+ if (!status || i2c->msg_idx > 0) { 24543+ status = i2c->msg_idx; 24544+ } 24545+ spin_unlock_irqrestore(&i2c->lock, flags); 24546+ return status; 24547+} 24548+/* HI I2C READ * 24549+ * hi_i2c_master_recv - issue a single I2C message in master receive mode 24550+ * @client: Handle to slave device 24551+ * @buf: Where to store data read from slave 24552+ * @count: How many bytes to read, must be less than 64k since msg.len is u16 24553+ * 24554+ * Returns negative errno, or else the number of bytes read. 24555+ */ 24556+int hi_i2c_master_recv(const struct i2c_client *client, char *buf, 24557+ int count) 24558+{ 24559+ printk("Wrong interface call." 24560+ "hi_i2c_transfer is the only interface to i2c read!!!\n"); 24561+ 24562+ return -EIO; 24563+} 24564+EXPORT_SYMBOL(hi_i2c_master_recv); 24565+ 24566+/* HI I2C WRITE * 24567+ * hi_i2c_master_send - issue a single I2C message in master transmit mode 24568+ * @client: Handle to slave device 24569+ * @buf: Data that will be written to the slave 24570+ * @count: How many bytes to write, must be less than 64k since msg.len is u16 24571+ * 24572+ * Returns negative errno, or else the number of bytes written. 24573+ */ 24574+int hi_i2c_master_send(const struct i2c_client *client, 24575+ const char *buf, int count) 24576+{ 24577+ struct i2c_adapter *adap = NULL; 24578+ struct i2c_msg msg; 24579+ int msgs_count; 24580+ 24581+ if ((client == NULL) || (buf == NULL) || (client->adapter == NULL) || 24582+ (count < 0)) { 24583+ printk(KERN_ERR "invalid args\n"); 24584+ return -EINVAL; 24585+ } 24586+ 24587+ if ((client->addr > 0x3ff) || 24588+ (((client->flags & I2C_M_TEN) == 0) && (client->addr > 0x7f))) { 24589+ printk(KERN_ERR "dev address out of range\n"); 24590+ return -EINVAL; 24591+ } 24592+ 24593+ adap = client->adapter; 24594+ msg.addr = client->addr; 24595+ msg.flags = client->flags; 24596+ msg.len = count; 24597+ 24598+ msg.buf = (__u8 *)buf; 24599+ 24600+ msgs_count = hibvt_i2c_break_polling_xfer(adap, &msg, 1); 24601+ 24602+ return (msgs_count == 1) ? count : -EIO; 24603+} 24604+EXPORT_SYMBOL(hi_i2c_master_send); 24605+ 24606+ 24607+int hi_i2c_master_send_mul_reg(const struct i2c_client *client, 24608+ const char *buf, unsigned int count, unsigned int reg_data_width) 24609+{ 24610+ struct i2c_adapter *adap = client->adapter; 24611+ struct i2c_msg msg; 24612+ int msgs_count; 24613+ 24614+ if ((client->addr > 0x3ff) 24615+ || (((client->flags & I2C_M_TEN) == 0) && (client->addr > 0x7f))) { 24616+ printk(KERN_ERR "dev address out of range\n"); 24617+ return -EINVAL; 24618+ } 24619+ 24620+ msg.addr = client->addr; 24621+ msg.flags = client->flags; 24622+ msg.len = count; 24623+ 24624+ if ((!buf)||(count < 0)) { 24625+ printk(KERN_ERR "buf == NULL || count < 0, Invalid argument!\n"); 24626+ return -EINVAL; 24627+ } 24628+ msg.buf = (__u8 *)buf; 24629+ 24630+ msgs_count = hibvt_i2c_mul_reg_xfer(adap, &msg, 1,reg_data_width); 24631+ 24632+ return (msgs_count == 1) ? count : -EIO; 24633+} 24634+EXPORT_SYMBOL(hi_i2c_master_send_mul_reg); 24635+/** 24636+ * hi_i2c_transfer - execute a single or combined I2C message 24637+ * @adap: Handle to I2C bus 24638+ * @msgs: One or more messages to execute before STOP is issued to 24639+ * terminate the operation; each message begins with a START. 24640+ * @num: Number of messages to be executed. 24641+ * 24642+ * Returns negative errno, else the number of messages executed. 24643+ * 24644+ * Note that there is no requirement that each message be sent to 24645+ * the same slave address, although that is the most common model. 24646+ */ 24647+int hi_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, 24648+ int num) 24649+{ 24650+ int msgs_count; 24651+ 24652+ if ((!adap) || (!msgs)) { 24653+ printk(KERN_ERR "adap == NULL || msgs == NULL, Invalid argument!\n"); 24654+ return -EINVAL; 24655+ } 24656+ 24657+ if ((msgs[0].addr > 0x3ff) || 24658+ (((msgs[0].flags & I2C_M_TEN) == 0) && (msgs[0].addr > 0x7f))) { 24659+ printk(KERN_ERR "msgs[0] dev address out of range\n"); 24660+ return -EINVAL; 24661+ } 24662+ 24663+ if ((msgs[1].addr > 0x3ff) || 24664+ (((msgs[1].flags & I2C_M_TEN) == 0) && (msgs[1].addr > 0x7f))) { 24665+ printk(KERN_ERR "msgs[1] dev address out of range\n"); 24666+ return -EINVAL; 24667+ } 24668+ 24669+ msgs_count = hibvt_i2c_xfer(adap, msgs, num); 24670+ 24671+ return msgs_count; 24672+} 24673+EXPORT_SYMBOL(hi_i2c_transfer); 24674+ 24675+static u32 hibvt_i2c_func(struct i2c_adapter *adap) 24676+{ 24677+ return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | 24678+ I2C_FUNC_PROTOCOL_MANGLING | 24679+ I2C_FUNC_SMBUS_WORD_DATA | 24680+ I2C_FUNC_SMBUS_BYTE_DATA | 24681+ I2C_FUNC_SMBUS_BYTE | 24682+ I2C_FUNC_SMBUS_I2C_BLOCK; 24683+} 24684+ 24685+static const struct i2c_algorithm hibvt_i2c_algo = { 24686+ .master_xfer = hibvt_i2c_xfer, 24687+ .functionality = hibvt_i2c_func, 24688+}; 24689+ 24690+static int hibvt_i2c_probe(struct platform_device *pdev) 24691+{ 24692+ int status; 24693+ struct hibvt_i2c_dev *i2c; 24694+ struct i2c_adapter *adap = NULL; 24695+ struct resource *res = NULL; 24696+ 24697+ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); 24698+ if (!i2c) 24699+ return -ENOMEM; 24700+ 24701+ platform_set_drvdata(pdev, i2c); 24702+ i2c->dev = &pdev->dev; 24703+ spin_lock_init(&i2c->lock); 24704+ init_completion(&i2c->msg_complete); 24705+ 24706+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 24707+ if (!res) { 24708+ dev_err(i2c->dev, "Invalid mem resource./n"); 24709+ return -ENODEV; 24710+ } 24711+ 24712+ i2c->phybase = res->start; 24713+ i2c->base = devm_ioremap_resource(&pdev->dev, res); 24714+ if (IS_ERR(i2c->base)) { 24715+ dev_err(i2c->dev, "cannot ioremap resource\n"); 24716+ return -ENOMEM; 24717+ } 24718+ 24719+ i2c->clk = devm_clk_get(&pdev->dev, NULL); 24720+ if (IS_ERR(i2c->clk)) { 24721+ dev_err(i2c->dev, "cannot get clock\n"); 24722+ return -ENOENT; 24723+ } 24724+ clk_prepare_enable(i2c->clk); 24725+ 24726+ if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", 24727+ &i2c->freq)) { 24728+ dev_warn(i2c->dev, "setting default clock-frequency@%dHz\n", 24729+ I2C_DEFAULT_FREQUENCY); 24730+ i2c->freq = I2C_DEFAULT_FREQUENCY; 24731+ } 24732+ 24733+ /* i2c controller initialization, disable interrupt */ 24734+ hibvt_i2c_hw_init(i2c); 24735+ 24736+ i2c->irq = platform_get_irq(pdev, 0); 24737+ status = devm_request_irq(&pdev->dev, i2c->irq, hibvt_i2c_isr, 24738+ IRQF_SHARED, dev_name(&pdev->dev), i2c); 24739+ if (status) { 24740+ dev_dbg(i2c->dev, "falling back to polling mode"); 24741+ i2c->irq = -1; 24742+ } 24743+ 24744+ adap = &i2c->adap; 24745+ i2c_set_adapdata(adap, i2c); 24746+ adap->owner = THIS_MODULE; 24747+ strlcpy(adap->name, "hibvt-i2c", sizeof(adap->name)); 24748+ adap->dev.parent = &pdev->dev; 24749+ adap->dev.of_node = pdev->dev.of_node; 24750+ adap->algo = &hibvt_i2c_algo; 24751+ 24752+ /* Add the i2c adapter */ 24753+ status = i2c_add_adapter(adap); 24754+ if (status) { 24755+ dev_err(i2c->dev, "failed to add bus to i2c core\n"); 24756+ goto err_add_adapter; 24757+ } 24758+ 24759+ dev_info(i2c->dev, "%s%d@%dhz registered\n", 24760+ adap->name, adap->nr, i2c->freq); 24761+ 24762+ return 0; 24763+ 24764+err_add_adapter: 24765+ clk_disable_unprepare(i2c->clk); 24766+ return status; 24767+} 24768+ 24769+static int hibvt_i2c_remove(struct platform_device *pdev) 24770+{ 24771+ struct hibvt_i2c_dev *i2c = platform_get_drvdata(pdev); 24772+ 24773+ clk_disable_unprepare(i2c->clk); 24774+ i2c_del_adapter(&i2c->adap); 24775+ 24776+ return 0; 24777+} 24778+ 24779+#ifdef CONFIG_PM_SLEEP 24780+static int hibvt_i2c_suspend(struct device *dev) 24781+{ 24782+ struct hibvt_i2c_dev *i2c = dev_get_drvdata(dev); 24783+ 24784+ i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); 24785+ clk_disable_unprepare(i2c->clk); 24786+ i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); 24787+ 24788+ return 0; 24789+} 24790+ 24791+static int hibvt_i2c_resume(struct device *dev) 24792+{ 24793+ struct hibvt_i2c_dev *i2c = dev_get_drvdata(dev); 24794+ 24795+ i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); 24796+ clk_prepare_enable(i2c->clk); 24797+ hibvt_i2c_hw_init(i2c); 24798+ i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); 24799+ 24800+ return 0; 24801+} 24802+#endif 24803+ 24804+static SIMPLE_DEV_PM_OPS(hibvt_i2c_dev_pm, hibvt_i2c_suspend, 24805+ hibvt_i2c_resume); 24806+ 24807+static const struct of_device_id hibvt_i2c_match[] = { 24808+ { .compatible = "hisilicon,hibvt-i2c" }, 24809+ { .compatible = "hisilicon,hi3516cv300-i2c" }, 24810+ { .compatible = "hisilicon,hi3536dv100-i2c" }, 24811+ {}, 24812+}; 24813+MODULE_DEVICE_TABLE(of, hibvt_i2c_match); 24814+ 24815+static struct platform_driver hibvt_i2c_driver = { 24816+ .driver = { 24817+ .name = "hibvt-i2c", 24818+ .of_match_table = hibvt_i2c_match, 24819+ .pm = &hibvt_i2c_dev_pm, 24820+ }, 24821+ .probe = hibvt_i2c_probe, 24822+ .remove = hibvt_i2c_remove, 24823+}; 24824+ 24825+module_platform_driver(hibvt_i2c_driver); 24826+ 24827+MODULE_AUTHOR("Hisilicon"); 24828+MODULE_DESCRIPTION("HISILICON BVT I2C Bus driver"); 24829+MODULE_LICENSE("GPL v2"); 24830diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c 24831index f358120d5..0693b4917 100644 24832--- a/drivers/i2c/i2c-dev.c 24833+++ b/drivers/i2c/i2c-dev.c 24834@@ -232,7 +232,42 @@ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) 24835 24836 return result; 24837 } 24838+static noinline int i2c_config_mul_reg(struct i2c_client *client, unsigned long arg) 24839+{ 24840+ struct i2c_msg msg; 24841+ unsigned int reg_width; 24842+ unsigned int data_width; 24843+ unsigned int reg_data_width; 24844+ 24845+ if (copy_from_user(&msg, 24846+ (struct i2c_msg __user *)arg, 24847+ sizeof(msg))) 24848+ return -EFAULT; 24849+ 24850+ if(client->flags & I2C_M_16BIT_REG) 24851+ reg_width = 2; 24852+ else 24853+ reg_width = 1; 24854+ 24855+ if(client->flags & I2C_M_16BIT_DATA) 24856+ data_width = 2; 24857+ else 24858+ data_width = 1; 24859+ 24860+ reg_data_width = reg_width + data_width; 24861+ 24862+ msg.buf = memdup_user(msg.buf,msg.len); 24863+ 24864+ if(msg.len == 0 || reg_data_width > msg.len || msg.len % reg_data_width != 0){ 24865+ printk(KERN_ERR "msg.len err!!!\n"); 24866+ return -EINVAL; 24867+ } 24868+ 24869+ hi_i2c_master_send_mul_reg(client, msg.buf, msg.len, reg_data_width); 24870 24871+ return 0; 24872+ 24873+} 24874 static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, 24875 unsigned nmsgs, struct i2c_msg *msgs) 24876 { 24877@@ -485,6 +520,24 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 24878 */ 24879 client->adapter->timeout = msecs_to_jiffies(arg * 10); 24880 break; 24881+ case I2C_CONFIG_FLAGS: 24882+ if (arg & I2C_M_16BIT_REG) 24883+ client->flags |= I2C_M_16BIT_REG; 24884+ else 24885+ client->flags &= ~I2C_M_16BIT_REG; 24886+ 24887+ if (arg & I2C_M_16BIT_DATA) 24888+ client->flags |= I2C_M_16BIT_DATA; 24889+ else 24890+ client->flags &= ~I2C_M_16BIT_DATA; 24891+ 24892+ if (arg & I2C_M_DMA) 24893+ client->flags |= I2C_M_DMA; 24894+ else 24895+ client->flags &= ~I2C_M_DMA; 24896+ return 0; 24897+ case I2C_CONFIG_MUL_REG: 24898+ return i2c_config_mul_reg(client, arg); 24899 default: 24900 /* NOTE: returning a fault code here could cause trouble 24901 * in buggy userspace code. Some old kernel bugs returned 24902diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c 24903index 176f5f064..24dd82c4b 100644 24904--- a/drivers/irqchip/irq-gic.c 24905+++ b/drivers/irqchip/irq-gic.c 24906@@ -118,6 +118,24 @@ static DEFINE_STATIC_KEY_FALSE(needs_rmw_access); 24907 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; 24908 24909 static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); 24910+#if defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 24911+ defined(CONFIG_ARCH_HI3516CV500)|| defined(CONFIG_ARCH_HI3516DV300)|| \ 24912+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 24913+#ifdef CONFIG_ARCH_HISI_BVT_AMP 24914+/* 24915+ *Uesed to process gic sgi interrupt * 24916+ */ 24917+#define DIS_IRQ_CNT 6 24918+struct gic_sgi_handle { 24919+ unsigned int irq; 24920+ void (*handle)(unsigned int cpu_intrf, 24921+ unsigned int irq_num, 24922+ struct pt_regs *regs); 24923+}; 24924+struct gic_sgi_handle dis_irq_handle[DIS_IRQ_CNT]; 24925+EXPORT_SYMBOL(dis_irq_handle); 24926+#endif 24927+#endif 24928 24929 static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly; 24930 24931@@ -333,6 +351,29 @@ static int gic_retrigger(struct irq_data *data) 24932 return !gic_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, true); 24933 } 24934 24935+#if defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 24936+ defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 24937+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 24938+#ifdef CONFIG_ARCH_HISI_BVT_AMP 24939+/* used to process dis irq */ 24940+int dis_irq_proc(u32 irqnr, u32 irqstat, struct pt_regs *regs) 24941+{ 24942+ u32 idx; 24943+ 24944+ for (idx = 0; idx < DIS_IRQ_CNT; idx++) { 24945+ if ((irqnr == dis_irq_handle[idx].irq) 24946+ && (dis_irq_handle[idx].handle)) { 24947+ dis_irq_handle[idx].handle(((irqstat >> 10) & 0x7), 24948+ irqnr, regs); 24949+ return 1; 24950+ } 24951+ } 24952+ 24953+ return 0; 24954+} 24955+#endif 24956+#endif 24957+ 24958 static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) 24959 { 24960 u32 irqstat, irqnr; 24961@@ -468,7 +509,31 @@ static void gic_cpu_if_up(struct gic_chip_data *gic) 24962 writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL); 24963 } 24964 24965+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 24966+#include "irq-map-hi3559av100.h" 24967+static void gic_dist_init_amp(struct gic_chip_data *gic) 24968+{ 24969+ unsigned int i; 24970+ u32 cpumask; 24971+ unsigned int *irq_map_int = (unsigned int *)irq_map; 24972+ unsigned int gic_irqs = gic->gic_irqs; 24973+ void __iomem *base = gic_data_dist_base(gic); 24974 24975+ writel_relaxed(GICD_DISABLE, base + GIC_DIST_CTRL); 24976+ 24977+ /* 24978+ * Set all global interrupts to this CPU only. 24979+ */ 24980+ for (i = 32; i < gic_irqs; i += 4) { 24981+ cpumask = irq_map_int[i / 4]; 24982+ writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); 24983+ } 24984+ 24985+ gic_dist_config(base, gic_irqs, NULL); 24986+ 24987+ writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); 24988+} 24989+#else 24990 static void gic_dist_init(struct gic_chip_data *gic) 24991 { 24992 unsigned int i; 24993@@ -491,6 +556,7 @@ static void gic_dist_init(struct gic_chip_data *gic) 24994 24995 writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); 24996 } 24997+#endif 24998 24999 static int gic_cpu_init(struct gic_chip_data *gic) 25000 { 25001@@ -1161,6 +1227,9 @@ static int gic_init_bases(struct gic_chip_data *gic, 25002 { 25003 int gic_irqs, ret; 25004 25005+ struct device_node *np; 25006+ void * sysctrl_reg_base; 25007+ int gic_dist_init_flag; 25008 if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) { 25009 /* Frankein-GIC without banked registers... */ 25010 unsigned int cpu; 25011@@ -1232,7 +1301,25 @@ static int gic_init_bases(struct gic_chip_data *gic, 25012 goto error; 25013 } 25014 25015- gic_dist_init(gic); 25016+#define GIC_DIST_INIT_FLAG 0x47444946 25017+#define GIC_DIST_INIT_FLAG_OFFSET 0x0130 25018+ /* 0x47444946('G''D''I''F') is abbreviation of GIC_DIST_INIT_FLAG. */ 25019+ 25020+ np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); 25021+ sysctrl_reg_base = of_iomap(np, 0); 25022+ gic_dist_init_flag = readl(sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET); 25023+ 25024+ if(gic_dist_init_flag != GIC_DIST_INIT_FLAG) { 25025+ printk("Gic dist init...\n"); 25026+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 25027+ gic_dist_init_amp(gic); 25028+#else 25029+ gic_dist_init(gic); 25030+#endif 25031+ writel_relaxed(GIC_DIST_INIT_FLAG, sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET); 25032+ } else 25033+ printk("Gic dist not init...\n"); 25034+ 25035 ret = gic_cpu_init(gic); 25036 if (ret) 25037 goto error; 25038diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c 25039index cd6776c31..8d06332bb 100644 25040--- a/drivers/media/usb/gspca/ov519.c 25041+++ b/drivers/media/usb/gspca/ov519.c 25042@@ -3482,6 +3482,11 @@ static void ov511_mode_init_regs(struct sd *sd) 25043 return; 25044 } 25045 25046+ if (alt->desc.bNumEndpoints < 1) { 25047+ sd->gspca_dev.usb_err = -ENODEV; 25048+ return; 25049+ } 25050+ 25051 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); 25052 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5); 25053 25054@@ -3613,6 +3618,11 @@ static void ov518_mode_init_regs(struct sd *sd) 25055 return; 25056 } 25057 25058+ if (alt->desc.bNumEndpoints < 1) { 25059+ sd->gspca_dev.usb_err = -ENODEV; 25060+ return; 25061+ } 25062+ 25063 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); 25064 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); 25065 25066diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig 25067index b8847ae04..e6bf07fe1 100644 25068--- a/drivers/mfd/Kconfig 25069+++ b/drivers/mfd/Kconfig 25070@@ -520,6 +520,17 @@ config MFD_HI655X_PMIC 25071 help 25072 Select this option to enable Hisilicon hi655x series pmic driver. 25073 25074+config MFD_HISI_FMC 25075+ tristate "HiSilicon Flash Memory Controller" 25076+ depends on OF 25077+ depends on ARCH_HISI_BVT 25078+ select MFD_CORE 25079+ select REGMAP_MMIO 25080+ help 25081+ Select this option to enable the HiSilicon Flash Memory 25082+ Controller(FMC) driver. 25083+ 25084+ 25085 config HTC_PASIC3 25086 tristate "HTC PASIC3 LED/DS1WM chip support" 25087 select MFD_CORE 25088diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile 25089index 1780019d2..992e1895f 100644 25090--- a/drivers/mfd/Makefile 25091+++ b/drivers/mfd/Makefile 25092@@ -211,6 +211,7 @@ obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o 25093 obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o 25094 obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o 25095 obj-$(CONFIG_MFD_ATMEL_SMC) += atmel-smc.o 25096+obj-$(CONFIG_MFD_HISI_FMC) += hisi_fmc.o 25097 obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o 25098 obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o 25099 obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o 25100diff --git a/drivers/mfd/hisi_fmc.c b/drivers/mfd/hisi_fmc.c 25101new file mode 100644 25102index 000000000..7aa23e56d 25103--- /dev/null 25104+++ b/drivers/mfd/hisi_fmc.c 25105@@ -0,0 +1,134 @@ 25106+/* HiSilicon Flash Memory Controller Driver 25107+ * 25108+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 25109+ * 25110+ * This program is free software; you can redistribute it and/or modify 25111+ * it under the terms of the GNU General Public License as published by 25112+ * the Free Software Foundation; either version 2 of the License, or 25113+ * (at your option) any later version. 25114+ * 25115+ * This program is distributed in the hope that it will be useful, 25116+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 25117+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25118+ * GNU General Public License for more details. 25119+ * 25120+ * You should have received a copy of the GNU General Public License 25121+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 25122+ */ 25123+ 25124+#include <linux/clk.h> 25125+#include <linux/device.h> 25126+#include <linux/dma-mapping.h> 25127+#include <linux/err.h> 25128+#include <linux/mfd/core.h> 25129+#include <linux/mfd/hisi_fmc.h> 25130+#include <linux/module.h> 25131+#include <linux/of.h> 25132+#include <linux/platform_device.h> 25133+ 25134+unsigned char hifmc_cs_user[HIFMC_MAX_CHIP_NUM]; 25135+ 25136+DEFINE_MUTEX(fmc_switch_mutex); 25137+EXPORT_SYMBOL_GPL(fmc_switch_mutex); 25138+ 25139+/* ------------------------------------------------------------------------ */ 25140+static const struct mfd_cell hisi_fmc_devs[] = { 25141+ { 25142+ .name = "hisi_spi_nor", 25143+ .of_compatible = "hisilicon,fmc-spi-nor", 25144+ }, 25145+ { 25146+ .name = "hisi_spi_nand", 25147+ .of_compatible = "hisilicon,fmc-spi-nand", 25148+ }, 25149+ { 25150+ .name = "hisi_nand", 25151+ .of_compatible = "hisilicon,fmc-nand", 25152+ }, 25153+}; 25154+ 25155+static int hisi_fmc_probe(struct platform_device *pdev) 25156+{ 25157+ struct hisi_fmc *fmc = NULL; 25158+ struct resource *res = NULL; 25159+ struct device *dev = &pdev->dev; 25160+ int ret; 25161+ 25162+ fmc = devm_kzalloc(dev, sizeof(*fmc), GFP_KERNEL); 25163+ if (!fmc) 25164+ return -ENOMEM; 25165+ 25166+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control"); 25167+ fmc->regbase = devm_ioremap_resource(dev, res); 25168+ if (IS_ERR(fmc->regbase)) 25169+ return PTR_ERR(fmc->regbase); 25170+ 25171+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); 25172+ fmc->iobase = devm_ioremap_resource(dev, res); 25173+ if (IS_ERR(fmc->iobase)) 25174+ return PTR_ERR(fmc->iobase); 25175+ 25176+ fmc->clk = devm_clk_get(dev, NULL); 25177+ if (IS_ERR(fmc->clk)) 25178+ return PTR_ERR(fmc->clk); 25179+ 25180+ if (of_property_read_u32(dev->of_node, "max-dma-size", &fmc->dma_len)) { 25181+ dev_err(dev, "Please set the suitable max-dma-size value !!!\n"); 25182+ return -ENOMEM; 25183+ } 25184+ 25185+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 25186+ if (ret) { 25187+ dev_warn(dev, "Unable to set dma mask\n"); 25188+ return ret; 25189+ } 25190+ 25191+ fmc->buffer = dmam_alloc_coherent(dev, fmc->dma_len, 25192+ &fmc->dma_buffer, GFP_KERNEL); 25193+ if (IS_ERR(fmc->buffer)) 25194+ return PTR_ERR(fmc->buffer); 25195+ 25196+ mutex_init(&fmc->lock); 25197+ 25198+ platform_set_drvdata(pdev, fmc); 25199+ 25200+ ret = mfd_add_devices(dev, 0, hisi_fmc_devs, 25201+ ARRAY_SIZE(hisi_fmc_devs), NULL, 0, NULL); 25202+ if (ret) { 25203+ dev_err(dev, "add mfd devices failed: %d\n", ret); 25204+ return ret; 25205+ } 25206+ 25207+ return 0; 25208+} 25209+ 25210+static int hisi_fmc_remove(struct platform_device *pdev) 25211+{ 25212+ struct hisi_fmc *fmc = platform_get_drvdata(pdev); 25213+ 25214+ dmam_free_coherent(&pdev->dev, fmc->dma_len, 25215+ fmc->buffer, fmc->dma_buffer); 25216+ mfd_remove_devices(&pdev->dev); 25217+ mutex_destroy(&fmc->lock); 25218+ 25219+ return 0; 25220+} 25221+ 25222+static const struct of_device_id hisi_fmc_of_match_tbl[] = { 25223+ {.compatible = "hisilicon,hisi-fmc"}, 25224+ { } 25225+}; 25226+MODULE_DEVICE_TABLE(of, hisi_fmc_of_match_tbl); 25227+ 25228+static struct platform_driver hisi_fmc_driver = { 25229+ .driver = { 25230+ .name = "hifmc", 25231+ .of_match_table = hisi_fmc_of_match_tbl, 25232+ }, 25233+ .probe = hisi_fmc_probe, 25234+ .remove = hisi_fmc_remove, 25235+}; 25236+module_platform_driver(hisi_fmc_driver); 25237+ 25238+MODULE_LICENSE("GPL v2"); 25239+MODULE_DESCRIPTION("HiSilicon Flash Memory Controller Driver"); 25240diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c 25241index 94caee49d..c69c59dcb 100644 25242--- a/drivers/mmc/core/block.c 25243+++ b/drivers/mmc/core/block.c 25244@@ -537,18 +537,16 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, 25245 return err; 25246 } 25247 25248- if (idata->rpmb || prev_idata) { 25249- sbc.opcode = MMC_SET_BLOCK_COUNT; 25250- /* 25251- * We don't do any blockcount validation because the max size 25252- * may be increased by a future standard. We just copy the 25253- * 'Reliable Write' bit here. 25254- */ 25255- sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31)); 25256- if (prev_idata) 25257- sbc.arg = prev_idata->ic.arg; 25258- sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; 25259- mrq.sbc = &sbc; 25260+ if (idata->rpmb) { 25261+ struct mmc_command mmc_cmd = {}; 25262+ mmc_cmd.opcode = MMC_SET_BLOCK_COUNT; 25263+ mmc_cmd.arg = data.blocks & 0x0000FFFF; 25264+ if (idata->ic.write_flag & (1 << 31)) 25265+ mmc_cmd.arg |= 1 << 31; 25266+ mmc_cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; 25267+ err = mmc_wait_for_cmd(card->host, &mmc_cmd, 5); 25268+ if (err) 25269+ return err; 25270 } 25271 25272 if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) && 25273diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c 25274index b5f3f160c..0b0e367bc 100644 25275--- a/drivers/mmc/core/core.c 25276+++ b/drivers/mmc/core/core.c 25277@@ -1371,6 +1371,9 @@ void mmc_power_off(struct mmc_host *host) 25278 25279 void mmc_power_cycle(struct mmc_host *host, u32 ocr) 25280 { 25281+ if (host->type == MMC_HOST_TYPE_MMC) 25282+ return; 25283+ 25284 mmc_power_off(host); 25285 /* Wait at least 1 ms according to SD spec */ 25286 mmc_delay(1); 25287@@ -2286,9 +2289,12 @@ void mmc_rescan(struct work_struct *work) 25288 mmc_bus_put(host); 25289 25290 mmc_claim_host(host); 25291+ host->card_status = MMC_CARD_UNINIT; 25292 if (mmc_card_is_removable(host) && host->ops->get_cd && 25293 host->ops->get_cd(host) == 0) { 25294 mmc_power_off(host); 25295+ if (host->ops->card_info_save) 25296+ host->ops->card_info_save(host); 25297 mmc_release_host(host); 25298 goto out; 25299 } 25300@@ -2300,8 +2306,17 @@ void mmc_rescan(struct work_struct *work) 25301 continue; 25302 freq = host->f_max; 25303 } 25304- if (!mmc_rescan_try_freq(host, max(freq, host->f_min))) 25305+ 25306+ if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) { 25307+ host->card_status = MMC_CARD_INIT; 25308+ if (host->ops->card_info_save) 25309+ host->ops->card_info_save(host); 25310 break; 25311+ } else if ((i == (ARRAY_SIZE(freqs) - 1)) || 25312+ (freqs[i] <= host->f_min)) { 25313+ host->card_status = MMC_CARD_INIT_FAIL; 25314+ } 25315+ 25316 if (freqs[i] <= host->f_min) 25317 break; 25318 } 25319diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c 25320index 7494d5950..416fc6723 100644 25321--- a/drivers/mmc/core/mmc.c 25322+++ b/drivers/mmc/core/mmc.c 25323@@ -1414,7 +1414,9 @@ static int mmc_select_hs400es(struct mmc_card *card) 25324 25325 /* Set host controller to HS400 timing and frequency */ 25326 mmc_set_timing(host, MMC_TIMING_MMC_HS400); 25327- 25328+#if defined(CONFIG_MMC_SDHCI_HISI) || (defined(MODULE) && defined(CONFIG_MMC_SDHCI_HISI_MODULE)) 25329+ mmc_set_bus_speed(card); 25330+#endif 25331 /* Controller enable enhanced strobe function */ 25332 host->ios.enhanced_strobe = true; 25333 if (host->ops->hs400_enhanced_strobe) 25334@@ -1512,7 +1514,8 @@ static int mmc_select_timing(struct mmc_card *card) 25335 if (!mmc_can_ext_csd(card)) 25336 goto bus_speed; 25337 25338- if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) 25339+ if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES && 25340+ card->host->caps & MMC_CAP_8_BIT_DATA) 25341 err = mmc_select_hs400es(card); 25342 else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) 25343 err = mmc_select_hs200(card); 25344@@ -2239,6 +2242,7 @@ int mmc_attach_mmc(struct mmc_host *host) 25345 if (err) 25346 return err; 25347 25348+ host->type = MMC_HOST_TYPE_MMC; 25349 mmc_attach_bus(host, &mmc_ops); 25350 if (host->ocr_avail_mmc) 25351 host->ocr_avail = host->ocr_avail_mmc; 25352diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c 25353index bac343a8d..af8bf24cd 100644 25354--- a/drivers/mmc/core/sd.c 25355+++ b/drivers/mmc/core/sd.c 25356@@ -1349,6 +1349,7 @@ int mmc_attach_sd(struct mmc_host *host) 25357 if (err) 25358 return err; 25359 25360+ host->type = MMC_HOST_TYPE_SD; 25361 mmc_attach_bus(host, &mmc_sd_ops); 25362 if (host->ocr_avail_sd) 25363 host->ocr_avail = host->ocr_avail_sd; 25364diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c 25365index 1b0853a82..3e452090d 100644 25366--- a/drivers/mmc/core/sdio.c 25367+++ b/drivers/mmc/core/sdio.c 25368@@ -1193,6 +1193,7 @@ int mmc_attach_sdio(struct mmc_host *host) 25369 if (err) 25370 return err; 25371 25372+ host->type = MMC_HOST_TYPE_SDIO; 25373 mmc_attach_bus(host, &mmc_sdio_ops); 25374 if (host->ocr_avail_sdio) 25375 host->ocr_avail = host->ocr_avail_sdio; 25376@@ -1306,3 +1307,40 @@ int mmc_attach_sdio(struct mmc_host *host) 25377 return err; 25378 } 25379 25380+#ifdef CONFIG_ARCH_HISI_BVT 25381+/* sdio_reset_comm has been fixed in latest kernel/msm.git for Linux 25382+ * 2.6.27. The implementation prior to that buggy, and needs broadcom's 25383+ * patch for it*/ 25384+int sdio_reset_comm(struct mmc_card *card) 25385+{ 25386+ struct mmc_host *host = card->host; 25387+ u32 ocr; 25388+ u32 rocr; 25389+ int err; 25390+ 25391+ mmc_claim_host(host); 25392+ mmc_retune_disable(host); 25393+ mmc_go_idle(host); 25394+ mmc_set_clock(host, host->f_min); 25395+ err = mmc_send_io_op_cond(host, 0, &ocr); 25396+ if (err) 25397+ goto err; 25398+ rocr = mmc_select_voltage(host, ocr); 25399+ if (!rocr) { 25400+ err = -EINVAL; 25401+ goto err; 25402+ } 25403+ err = mmc_sdio_init_card(host, rocr, card); 25404+ if (err) 25405+ goto err; 25406+ mmc_release_host(host); 25407+ return 0; 25408+err: 25409+ printk("%s: Error resetting SDIO communications: %d\n", 25410+ mmc_hostname(host), err); 25411+ mmc_release_host(host); 25412+ return err; 25413+} 25414+EXPORT_SYMBOL(sdio_reset_comm); 25415+#endif 25416+ 25417diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig 25418index 31481c9fc..299758712 100644 25419--- a/drivers/mmc/host/Kconfig 25420+++ b/drivers/mmc/host/Kconfig 25421@@ -247,6 +247,21 @@ config MMC_SDHCI_CNS3XXX 25422 25423 If unsure, say N. 25424 25425+config MMC_SDHCI_HISI 25426+ tristate "SDHCI support on the Hisilicon Hi35xx SoC" 25427+ depends on ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3521DV200 ||\ 25428+ ARCH_HI3520DV500 || ARCH_HI3559AV100 || ARCH_HI3556AV100 ||\ 25429+ ARCH_HI3519AV100 || ARCH_HI3516EV200 || ARCH_HI3516EV300 ||\ 25430+ ARCH_HI3518EV300 || ARCH_HI3516DV200 || ARCH_HI3569V100 ||\ 25431+ ARCH_HI3568V100 25432+ depends on MMC_SDHCI_PLTFM 25433+ help 25434+ This selects the SDHCI support for Hi35xx System-on-Chip devices. 25435+ 25436+ If you have a controller with this interface, say Y or M here. 25437+ 25438+ If unsure, say N. 25439+ 25440 config MMC_SDHCI_ESDHC_MCF 25441 tristate "SDHCI support for the Freescale eSDHC ColdFire controller" 25442 depends on M5441x 25443@@ -1077,6 +1092,21 @@ config MMC_SDHCI_OMAP 25444 25445 If unsure, say N. 25446 25447+config MMC_CQ_HCI 25448+ tristate "Command Queue Support" 25449+ depends on HAS_DMA 25450+ help 25451+ This selects the Command Queue Host Controller Interface (CQHCI) 25452+ support present in host controllers of Qualcomm Technologies, Inc 25453+ amongst others. 25454+ This controller supports eMMC devices with command queue support. 25455+ 25456+ If you have a controller with this interface, say Y or M here. 25457+ 25458+ If unsure, say N. 25459+ 25460+source "drivers/mmc/host/himci/Kconfig" 25461+ 25462 config MMC_SDHCI_AM654 25463 tristate "Support for the SDHCI Controller in TI's AM654 SOCs" 25464 depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO 25465diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile 25466index 451c25fc2..e7ec6250e 100644 25467--- a/drivers/mmc/host/Makefile 25468+++ b/drivers/mmc/host/Makefile 25469@@ -94,6 +94,21 @@ obj-$(CONFIG_MMC_SDHCI_OF_AT91) += sdhci-of-at91.o 25470 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o 25471 obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o 25472 obj-$(CONFIG_MMC_SDHCI_OF_DWCMSHC) += sdhci-of-dwcmshc.o 25473+obj-$(CONFIG_MMC_SDHCI_HISI) += sdhci-of-hisi.o 25474+sdhci-of-hisi-objs := sdhci-hisi.o mci_proc.o 25475+sdhci-of-hisi-$(CONFIG_ARCH_HI3531DV200) += sdhci-hi3531dv200.o 25476+sdhci-of-hisi-$(CONFIG_ARCH_HI3535AV100) += sdhci-hi3531dv200.o 25477+sdhci-of-hisi-$(CONFIG_ARCH_HI3521DV200) += sdhci-hi3521dv200.o 25478+sdhci-of-hisi-$(CONFIG_ARCH_HI3520DV500) += sdhci-hi3521dv200.o 25479+sdhci-of-hisi-$(CONFIG_ARCH_HI3559AV100) += sdhci-hi3559av100.o 25480+sdhci-of-hisi-$(CONFIG_ARCH_HI3556AV100) += sdhci-hi3556av100.o 25481+sdhci-of-hisi-$(CONFIG_ARCH_HI3519AV100) += sdhci-hi3556av100.o 25482+sdhci-of-hisi-$(CONFIG_ARCH_HI3516EV200) += sdhci-hi3516ev200.o 25483+sdhci-of-hisi-$(CONFIG_ARCH_HI3516EV300) += sdhci-hi3516ev300.o 25484+sdhci-of-hisi-$(CONFIG_ARCH_HI3518EV300) += sdhci-hi3518ev300.o 25485+sdhci-of-hisi-$(CONFIG_ARCH_HI3516DV200) += sdhci-hi3516dv200.o 25486+sdhci-of-hisi-$(CONFIG_ARCH_HI3568V100) += sdhci-hi3556av100.o 25487+sdhci-of-hisi-$(CONFIG_ARCH_HI3569V100) += sdhci-hi3559av100.o 25488 obj-$(CONFIG_MMC_SDHCI_OF_SPARX5) += sdhci-of-sparx5.o 25489 obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o 25490 obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o 25491@@ -112,3 +127,5 @@ endif 25492 25493 obj-$(CONFIG_MMC_SDHCI_XENON) += sdhci-xenon-driver.o 25494 sdhci-xenon-driver-y += sdhci-xenon.o sdhci-xenon-phy.o 25495+ 25496+obj-$(CONFIG_HIMCI) += himci/ 25497diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c 25498index 7ba4f7141..f5614efa4 100644 25499--- a/drivers/mmc/host/cqhci.c 25500+++ b/drivers/mmc/host/cqhci.c 25501@@ -46,6 +46,11 @@ static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag) 25502 25503 static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag) 25504 { 25505+ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT) 25506+ return cq_host->trans_desc_dma_base + 25507+ (cq_host->mmc->max_segs * tag * 2 * 25508+ cq_host->trans_desc_len); 25509+ 25510 return cq_host->trans_desc_dma_base + 25511 (cq_host->mmc->max_segs * tag * 25512 cq_host->trans_desc_len); 25513@@ -53,6 +58,11 @@ static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag) 25514 25515 static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag) 25516 { 25517+ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT) 25518+ return cq_host->trans_desc_base + 25519+ (cq_host->trans_desc_len * 25520+ cq_host->mmc->max_segs * 2 * tag); 25521+ 25522 return cq_host->trans_desc_base + 25523 (cq_host->trans_desc_len * cq_host->mmc->max_segs * tag); 25524 } 25525@@ -193,8 +203,12 @@ static int cqhci_host_alloc_tdl(struct cqhci_host *cq_host) 25526 25527 cq_host->desc_size = cq_host->slot_sz * cq_host->num_slots; 25528 25529- cq_host->data_size = cq_host->trans_desc_len * cq_host->mmc->max_segs * 25530- cq_host->mmc->cqe_qdepth; 25531+ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT) 25532+ cq_host->data_size = cq_host->trans_desc_len * 25533+ cq_host->mmc->max_segs * 2 * cq_host->mmc->cqe_qdepth; 25534+ else 25535+ cq_host->data_size = cq_host->trans_desc_len * 25536+ cq_host->mmc->max_segs * cq_host->mmc->cqe_qdepth; 25537 25538 pr_debug("%s: cqhci: desc_size: %zu data_sz: %zu slot-sz: %d\n", 25539 mmc_hostname(cq_host->mmc), cq_host->desc_size, cq_host->data_size, 25540@@ -267,6 +281,8 @@ static void __cqhci_enable(struct cqhci_host *cq_host) 25541 25542 cqhci_writel(cq_host, cq_host->rca, CQHCI_SSC2); 25543 25544+ cqhci_writel(cq_host, SEND_QSR_INTERVAL, CQHCI_SSC1); 25545+ 25546 cqhci_set_irqs(cq_host, 0); 25547 25548 cqcfg |= CQHCI_ENABLE; 25549@@ -276,8 +292,6 @@ static void __cqhci_enable(struct cqhci_host *cq_host) 25550 if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) 25551 cqhci_writel(cq_host, 0, CQHCI_CTL); 25552 25553- mmc->cqe_on = true; 25554- 25555 if (cq_host->ops->enable) 25556 cq_host->ops->enable(mmc); 25557 25558@@ -452,7 +466,7 @@ static int cqhci_dma_map(struct mmc_host *host, struct mmc_request *mrq) 25559 return sg_count; 25560 } 25561 25562-static void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end, 25563+static void _cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end, 25564 bool dma64) 25565 { 25566 __le32 *attr = (__le32 __force *)desc; 25567@@ -474,6 +488,27 @@ static void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end, 25568 } 25569 } 25570 25571+static void cqhci_set_tran_desc(struct cqhci_host *cq_host, u8 **desc, 25572+ dma_addr_t addr, int len, bool end, bool dma64, unsigned int blksz) 25573+{ 25574+ int desc_len; 25575+ 25576+ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT && 25577+ addr % SYNOPSYS_DMA_LIMIT + len > SYNOPSYS_DMA_LIMIT) { 25578+ if ((addr + (unsigned int)len) % SYNOPSYS_DMA_LIMIT < blksz) 25579+ BUG_ON(1); 25580+ 25581+ desc_len = (SYNOPSYS_DMA_LIMIT - addr % SYNOPSYS_DMA_LIMIT); 25582+ _cqhci_set_tran_desc(*desc, addr, desc_len, false, dma64); 25583+ 25584+ *desc = *desc + cq_host->trans_desc_len; 25585+ len -= desc_len; 25586+ addr += desc_len; 25587+ } 25588+ 25589+ _cqhci_set_tran_desc(*desc, addr, len, end, dma64); 25590+} 25591+ 25592 static int cqhci_prep_tran_desc(struct mmc_request *mrq, 25593 struct cqhci_host *cq_host, int tag) 25594 { 25595@@ -500,7 +535,7 @@ static int cqhci_prep_tran_desc(struct mmc_request *mrq, 25596 25597 if ((i+1) == sg_count) 25598 end = true; 25599- cqhci_set_tran_desc(desc, addr, len, end, dma64); 25600+ cqhci_set_tran_desc(cq_host, &desc, addr, len, end, dma64, data->blksz); 25601 desc += cq_host->trans_desc_len; 25602 } 25603 25604@@ -951,6 +986,9 @@ static void cqhci_recovery_start(struct mmc_host *mmc) 25605 cq_host->ops->disable(mmc, true); 25606 25607 mmc->cqe_on = false; 25608+ 25609+ cqhci_deactivate(mmc); 25610+ 25611 } 25612 25613 static int cqhci_error_from_flags(unsigned int flags) 25614diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h 25615index 89bf6adbc..05571faf0 100644 25616--- a/drivers/mmc/host/cqhci.h 25617+++ b/drivers/mmc/host/cqhci.h 25618@@ -80,6 +80,12 @@ 25619 25620 /* send status config 1 */ 25621 #define CQHCI_SSC1 0x40 25622+/* 25623+ * Value n means CQE would send CMD13 during the transfer of data block 25624+ * BLOCK_CNT-n 25625+ */ 25626+#define SEND_QSR_INTERVAL 0x70001 25627+ 25628 #define CQHCI_SSC1_CBC_MASK GENMASK(19, 16) 25629 25630 /* send status config 2 */ 25631@@ -138,6 +144,7 @@ 25632 #define CQHCI_DAT_ADDR_LO(x) (((x) & 0xFFFFFFFF) << 32) 25633 #define CQHCI_DAT_ADDR_HI(x) (((x) & 0xFFFFFFFF) << 0) 25634 25635+#define SYNOPSYS_DMA_LIMIT 0x8000000 25636 struct cqhci_host_ops; 25637 struct mmc_host; 25638 struct mmc_request; 25639@@ -164,6 +171,7 @@ struct cqhci_host { 25640 25641 u32 quirks; 25642 #define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ 0x1 25643+#define CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT 0x2 25644 25645 bool enabled; 25646 bool halted; 25647diff --git a/drivers/mmc/host/himci/Kconfig b/drivers/mmc/host/himci/Kconfig 25648new file mode 100644 25649index 000000000..f3331c862 25650--- /dev/null 25651+++ b/drivers/mmc/host/himci/Kconfig 25652@@ -0,0 +1,23 @@ 25653+# 25654+# himci family SD/MMC device configuration 25655+# 25656+menuconfig HIMCI 25657+ tristate "himci driver support" 25658+ depends on ARCH_HI3516A || ARCH_HI3518EV20X || ARCH_HI3516CV500 || ARCH_HI3516DV300 || ARCH_HI3556V200 || ARCH_HI3559V200 || ARCH_HI3562V100 || ARCH_HI3566V100 25659+ default y if ARCH_HI3516A 25660+ select MMC_UNSAFE_RESUME 25661+ select MMC_EMBEDDED_SDIO 25662+ select MMC_BLOCK 25663+ select MMC_BLOCK_BOUNCE 25664+ help 25665+ This selects the Hisilicon Synopsys MultiMedia Card Driver 25666+ support. If you want use SD/MMC/SDIO driver, 25667+ Say Y or M here. 25668+ 25669+ default is Y. 25670+ 25671+config SEND_AUTO_STOP 25672+ bool "Send Auto Stop to terminate data transfer between host and SD card" 25673+ depends on HIMCI 25674+ default y 25675+ 25676diff --git a/drivers/mmc/host/himci/Makefile b/drivers/mmc/host/himci/Makefile 25677new file mode 100644 25678index 000000000..6858bfcef 25679--- /dev/null 25680+++ b/drivers/mmc/host/himci/Makefile 25681@@ -0,0 +1,2 @@ 25682+obj-$(CONFIG_HIMCI) += hisi_mci.o 25683+hisi_mci-y := himci.o himci_proc.o 25684diff --git a/drivers/mmc/host/himci/himci.c b/drivers/mmc/host/himci/himci.c 25685new file mode 100644 25686index 000000000..65aa8d24e 25687--- /dev/null 25688+++ b/drivers/mmc/host/himci/himci.c 25689@@ -0,0 +1,2580 @@ 25690+/* 25691+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 25692+ * 25693+ * This program is free software; you can redistribute it and/or modify 25694+ * it under the terms of the GNU General Public License as published by 25695+ * the Free Software Foundation; either version 2 of the License, or 25696+ * (at your option) any later version. 25697+ * 25698+ * This program is distributed in the hope that it will be useful, 25699+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 25700+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25701+ * GNU General Public License for more details. 25702+ * 25703+ * You should have received a copy of the GNU General Public License 25704+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 25705+ */ 25706+#define pr_fmt(fmt) "himci: " fmt 25707+ 25708+#include <linux/module.h> 25709+#include <linux/kernel.h> 25710+#include <linux/init.h> 25711+#include <linux/platform_device.h> 25712+#include <linux/mm.h> 25713+#include <linux/interrupt.h> 25714+#include <linux/dma-mapping.h> 25715+#include <linux/scatterlist.h> 25716+ 25717+#include <linux/mmc/host.h> 25718+#include <linux/mmc/mmc.h> 25719+#include <linux/mmc/card.h> 25720+#include <linux/mmc/core.h> 25721+#include <linux/mmc/sd.h> 25722+#include <linux/slab.h> 25723+ 25724+#include <linux/ioport.h> 25725+#include <linux/device.h> 25726+#include <linux/spinlock.h> 25727+ 25728+#include <linux/delay.h> 25729+#include <linux/dma-mapping.h> 25730+#include <linux/kthread.h> 25731+#include <linux/workqueue.h> 25732+#include <linux/freezer.h> 25733+#include <asm/dma.h> 25734+#include <asm/irq.h> 25735+#include <linux/sizes.h> 25736+#include <mach/io.h> 25737+ 25738+#include <linux/io.h> 25739+#include <linux/of.h> 25740+#include <linux/clk.h> 25741+#include <linux/clk-provider.h> 25742+#include <linux/reset.h> 25743+ 25744+#include "himci_reg.h" 25745+#include "himci.h" 25746+#include "himci_proc.h" 25747+ 25748+#ifdef CONFIG_ARCH_HI3516A 25749+#include "himci_hi3516a.c" 25750+#endif 25751+ 25752+#ifdef CONFIG_ARCH_HI3518EV20X 25753+#include "himci_hi3518ev20x.c" 25754+#endif 25755+ 25756+#ifdef CONFIG_ARCH_HI3516CV500 25757+#include "himci_hi3516cv500.c" 25758+#endif 25759+ 25760+#ifdef CONFIG_ARCH_HI3516DV300 25761+#include "himci_hi3516dv300.c" 25762+#endif 25763+ 25764+#ifdef CONFIG_ARCH_HI3556V200 25765+#include "himci_hi3556v200.c" 25766+#endif 25767+ 25768+#ifdef CONFIG_ARCH_HI3559V200 25769+#include "himci_hi3559v200.c" 25770+#endif 25771+ 25772+#ifdef CONFIG_ARCH_HI3562V100 25773+#include "himci_hi3559v200.c" 25774+#endif 25775+ 25776+#ifdef CONFIG_ARCH_HI3566V100 25777+#include "himci_hi3559v200.c" 25778+#endif 25779+ 25780+#define DRIVER_NAME "himci" 25781+ 25782+#ifndef CONFIG_HISI_MC 25783+#define CMD_DES_PAGE_SIZE (3 * PAGE_SIZE) 25784+#else 25785+#define CMD_DES_PAGE_SIZE (8 * PAGE_SIZE) 25786+#endif 25787+ 25788+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 25789+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 25790+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 25791+void __iomem *crg_ctrl, *misc_ctrl_1; 25792+#endif 25793+ 25794+#if defined(CONFIG_ARCH_HI3516DV300) 25795+#define PWR_CTRL0_REG 0x12090000 25796+#define GPIO_AT_PMC_ENABLE_BIT 0x80 25797+#define REG_SLEEP_TIME_MS 0x30 25798+#endif 25799+ 25800+static unsigned int detect_time = HI_MCI_DETECT_TIMEOUT; 25801+static unsigned int retry_count = MAX_RETRY_COUNT; 25802+static unsigned int request_timeout = HI_MCI_REQUEST_TIMEOUT; 25803+int trace_level = HIMCI_TRACE_LEVEL; 25804+unsigned int slot_index = 0; 25805+struct himci_host *mci_host[HIMCI_SLOT_NUM] = {NULL}; 25806+#ifdef MODULE 25807+ 25808+module_param(detect_time, uint, 0600); 25809+MODULE_PARM_DESC(detect_timer, "card detect time (default:500ms))"); 25810+ 25811+module_param(retry_count, uint, 0600); 25812+MODULE_PARM_DESC(retry_count, "retry count times (default:100))"); 25813+ 25814+module_param(request_timeout, uint, 0600); 25815+MODULE_PARM_DESC(request_timeout, "Request timeout time (default:3s))"); 25816+ 25817+module_param(trace_level, int, 0600); 25818+MODULE_PARM_DESC(trace_level, "HIMCI_TRACE_LEVEL"); 25819+ 25820+#endif 25821+ 25822+/* reset MMC host controller */ 25823+static void himci_sys_reset(struct himci_host *host) 25824+{ 25825+ unsigned int reg_value; 25826+ unsigned long flags; 25827+ 25828+ himci_trace(2, "reset"); 25829+ 25830+ local_irq_save(flags); 25831+ 25832+ reg_value = himci_readl(host->base + MCI_BMOD); 25833+ reg_value |= BMOD_SWR; 25834+ himci_writel(reg_value, host->base + MCI_BMOD); 25835+ mdelay(10); 25836+ 25837+ reg_value = himci_readl(host->base + MCI_BMOD); 25838+ reg_value |= BURST_16 | BURST_INCR; 25839+ himci_writel(reg_value, host->base + MCI_BMOD); 25840+ 25841+ reg_value = himci_readl(host->base + MCI_CTRL); 25842+ reg_value |= CTRL_RESET | FIFO_RESET | DMA_RESET; 25843+ himci_writel(reg_value, host->base + MCI_CTRL); 25844+ 25845+ local_irq_restore(flags); 25846+} 25847+ 25848+static void himci_ctrl_power(struct himci_host *host, 25849+ unsigned int flag, unsigned int force) 25850+{ 25851+ unsigned int port; 25852+ 25853+ himci_trace(2, "begin"); 25854+ 25855+ port = host->port; 25856+ 25857+ if (host->power_status != flag || force == FORCE_ENABLE) { 25858+ unsigned int reg_value; 25859+ 25860+ if (flag == POWER_OFF) { 25861+ reg_value = himci_readl(host->base + MCI_RESET_N); 25862+ reg_value &= ~(MMC_RST_N << port); 25863+ himci_writel(reg_value, host->base + MCI_RESET_N); 25864+ } 25865+ 25866+ reg_value = himci_readl(host->base + MCI_PWREN); 25867+ if (flag == POWER_OFF) 25868+ reg_value &= ~(0x1 << port); 25869+ else 25870+ reg_value |= (0x1 << port); 25871+ 25872+ himci_writel(reg_value, host->base + MCI_PWREN); 25873+ 25874+ if (flag == POWER_ON) { 25875+ reg_value = himci_readl(host->base + MCI_RESET_N); 25876+ reg_value |= (MMC_RST_N << port); 25877+ himci_writel(reg_value, host->base + MCI_RESET_N); 25878+ } 25879+ 25880+ if (in_interrupt()) 25881+ mdelay(100); 25882+ else 25883+ msleep(100); 25884+ 25885+ host->power_status = flag; 25886+ } 25887+} 25888+ 25889+/********************************************** 25890+ * 1: card off 25891+ * 0: card on 25892+ ***********************************************/ 25893+static unsigned int himci_sys_card_detect(struct himci_host *host) 25894+{ 25895+ unsigned int card_status; 25896+ 25897+ card_status = readl(host->base + MCI_CDETECT); 25898+ card_status &= (HIMCI_CARD0 << host->port); 25899+ if (card_status) 25900+ card_status = 1; 25901+ else 25902+ card_status = 0; 25903+ 25904+ return card_status; 25905+} 25906+ 25907+/********************************************** 25908+ * 1: card readonly 25909+ * 0: card read/write 25910+ ***********************************************/ 25911+static unsigned int himci_ctrl_card_readonly(struct himci_host *host) 25912+{ 25913+ unsigned int card_value = himci_readl(host->base + MCI_WRTPRT); 25914+ return card_value & (HIMCI_CARD0 << host->port); 25915+} 25916+ 25917+static int tuning_reset_flag = 0; 25918+ 25919+static int himci_wait_cmd(struct himci_host *host) 25920+{ 25921+ int wait_retry_count = 0; 25922+ int retry_count_cmd = 500; 25923+ unsigned int reg_data = 0; 25924+ unsigned long flags; 25925+ 25926+ himci_trace(2, "begin"); 25927+ himci_assert(host); 25928+ 25929+ while (1) { 25930+ /* 25931+ * Check if CMD::start_cmd bit is clear. 25932+ * start_cmd = 0 means MMC Host controller has loaded registers 25933+ * and next command can be loaded in. 25934+ */ 25935+ reg_data = himci_readl(host->base + MCI_CMD); 25936+ if ((reg_data & START_CMD) == 0) 25937+ return 0; 25938+ 25939+ /* Check if Raw_Intr_Status::HLE bit is set. */ 25940+ spin_lock_irqsave(&host->lock, flags); 25941+ reg_data = himci_readl(host->base + MCI_RINTSTS); 25942+ if (reg_data & HLE_INT_STATUS) { 25943+ reg_data |= HLE_INT_STATUS; 25944+ himci_writel(reg_data, host->base + MCI_RINTSTS); 25945+ spin_unlock_irqrestore(&host->lock, flags); 25946+ 25947+ himci_trace(5, "Other CMD is running," 25948+ "please operate cmd again!"); 25949+ return 1; 25950+ } 25951+ 25952+ spin_unlock_irqrestore(&host->lock, flags); 25953+ udelay(1); 25954+ 25955+ /* Check if number of retries for this are over. */ 25956+ wait_retry_count++; 25957+ if (wait_retry_count >= retry_count_cmd) { 25958+ if (host->is_tuning) 25959+ tuning_reset_flag = 1; 25960+ himci_trace(3, "send cmd is timeout!"); 25961+ return -1; 25962+ } 25963+ } 25964+} 25965+ 25966+static int himci_control_cclk(struct himci_host *host, unsigned int flag) 25967+{ 25968+ unsigned int reg; 25969+ union cmd_arg_u cmd_reg; 25970+ 25971+ himci_trace(2, "begin"); 25972+ himci_assert(host); 25973+ 25974+ reg = himci_readl(host->base + MCI_CLKENA); 25975+ if (flag == ENABLE) { 25976+ reg |= (CCLK_ENABLE << host->port); 25977+ reg |= (CCLK_LOW_POWER << host->port); 25978+ } else { 25979+ reg &= ~(CCLK_ENABLE << host->port); 25980+ reg &= ~(CCLK_LOW_POWER << host->port); 25981+ } 25982+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 25983+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 25984+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 25985+ if (host->devid == 2) 25986+ reg &= ~(CCLK_LOW_POWER << host->port); 25987+#endif 25988+ himci_writel(reg, host->base + MCI_CLKENA); 25989+ 25990+ cmd_reg.cmd_arg = himci_readl(host->base + MCI_CMD); 25991+ cmd_reg.bits.start_cmd = 1; 25992+ cmd_reg.bits.card_number = host->port; 25993+ cmd_reg.bits.cmd_index = 0; 25994+ cmd_reg.bits.data_transfer_expected = 0; 25995+ cmd_reg.bits.update_clk_reg_only = 1; 25996+ cmd_reg.bits.response_expect = 0; 25997+ cmd_reg.bits.send_auto_stop = 0; 25998+ cmd_reg.bits.wait_prvdata_complete = 0; 25999+ cmd_reg.bits.check_response_crc = 0; 26000+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 26001+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 26002+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 26003+ cmd_reg.bits.use_hold_reg = 1; 26004+#endif 26005+ himci_writel(cmd_reg.cmd_arg, host->base + MCI_CMD); 26006+ if (himci_wait_cmd(host) != 0) { 26007+ himci_trace(3, "disable or enable clk is timeout!"); 26008+ return -ETIMEDOUT; 26009+ } else { 26010+ return 0; 26011+ } 26012+} 26013+ 26014+static void himci_set_cclk(struct himci_host *host, unsigned int cclk) 26015+{ 26016+ unsigned int reg_value; 26017+ union cmd_arg_u clk_cmd; 26018+ unsigned int hclk; 26019+ 26020+ himci_trace(2, "begin"); 26021+ himci_assert(host); 26022+ himci_assert(cclk); 26023+ 26024+ hclk = cclk > MMC_CRG_MIN ? cclk : MMC_CRG_MIN; 26025+ clk_set_rate(host->clk, hclk); 26026+ 26027+ hclk = clk_get_rate(host->clk); 26028+ host->mmc->actual_clock = hclk; 26029+ 26030+ /* 26031+ * set card clk divider value, 26032+ * clk_divider = Fmmcclk/(Fmmc_cclk * 2) 26033+ */ 26034+ reg_value = hclk / (cclk * 2); 26035+ if ((hclk % (cclk * 2)) && (hclk > cclk)) 26036+ reg_value++; 26037+ if (reg_value > 0xFF) 26038+ reg_value = 0xFF; 26039+ 26040+ host->hclk = hclk; 26041+ host->cclk = reg_value ? (hclk / (reg_value * 2)) : hclk; 26042+ himci_writel((reg_value << (host->port * 8)), 26043+ host->base + MCI_CLKDIV); 26044+ 26045+ clk_cmd.cmd_arg = himci_readl(host->base + MCI_CMD); 26046+ clk_cmd.bits.start_cmd = 1; 26047+ clk_cmd.bits.card_number = host->port; 26048+ clk_cmd.bits.update_clk_reg_only = 1; 26049+ clk_cmd.bits.cmd_index = 0; 26050+ clk_cmd.bits.data_transfer_expected = 0; 26051+ clk_cmd.bits.response_expect = 0; 26052+ himci_writel(clk_cmd.cmd_arg, host->base + MCI_CMD); 26053+ if (himci_wait_cmd(host) != 0) 26054+ himci_trace(5, "set card clk divider is failed!"); 26055+} 26056+ 26057+static void himci_sys_ctrl_init(struct himci_host *host) 26058+{ 26059+ reset_control_assert(host->crg_rst); 26060+ udelay(100); 26061+ reset_control_deassert(host->crg_rst); 26062+} 26063+ 26064+static void himci_init_host(struct himci_host *host) 26065+{ 26066+ unsigned int tmp_reg = 0; 26067+ unsigned long flags; 26068+ 26069+ himci_trace(2, "begin"); 26070+ himci_assert(host); 26071+ 26072+ himci_sys_reset(host); 26073+ 26074+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 26075+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 26076+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 26077+ /* controller config gpio */ 26078+ tmp_reg = himci_readl(host->base + MCI_GPIO); 26079+ tmp_reg |= DTO_FIX_BYPASS; 26080+ himci_writel(tmp_reg, host->base + MCI_GPIO); 26081+#endif 26082+ 26083+#ifdef CONFIG_ARCH_HI3518EV20X 26084+ /* sd use clk0 emmc use clk1 */ 26085+ himci_writel(0x4, host->base + MCI_CLKSRC); 26086+#endif 26087+ 26088+ /* set drv/smpl phase shift */ 26089+ tmp_reg = 0; 26090+ tmp_reg |= SMPL_PHASE_DFLT | DRV_PHASE_DFLT; 26091+ himci_writel(tmp_reg, host->base + MCI_UHS_REG_EXT); 26092+ 26093+ /* set card read threshold */ 26094+ himci_writel(RW_THRESHOLD_SIZE, host->base + MCI_CARDTHRCTL); 26095+ 26096+ /* clear MMC host intr */ 26097+ himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS); 26098+ 26099+ spin_lock_irqsave(&host->lock, flags); 26100+ host->pending_events = 0; 26101+ spin_unlock_irqrestore(&host->lock, flags); 26102+ 26103+ /* MASK MMC all host intr */ 26104+ tmp_reg = himci_readl(host->base + MCI_INTMASK); 26105+ tmp_reg &= ~ALL_INT_MASK; 26106+ tmp_reg |= DATA_INT_MASK; 26107+ himci_writel(tmp_reg, host->base + MCI_INTMASK); 26108+ 26109+ /* enable inner DMA mode and close intr of MMC host controler */ 26110+ tmp_reg = himci_readl(host->base + MCI_CTRL); 26111+ tmp_reg &= ~INTR_EN; 26112+ tmp_reg |= USE_INTERNAL_DMA | INTR_EN; 26113+ himci_writel(tmp_reg, host->base + MCI_CTRL); 26114+ 26115+ /* set timeout param */ 26116+ himci_writel(DATA_TIMEOUT | RESPONSE_TIMEOUT, host->base + MCI_TIMEOUT); 26117+ 26118+ /* set FIFO param */ 26119+ tmp_reg = 0; 26120+ tmp_reg |= BURST_SIZE | RX_WMARK | TX_WMARK; 26121+ himci_writel(tmp_reg, host->base + MCI_FIFOTH); 26122+ 26123+ host->error_count = 0; 26124+ host->data_error_count = 0; 26125+} 26126+ 26127+static void himci_detect_card(struct timer_list *timer) 26128+{ 26129+ struct himci_host *host = container_of(timer, struct himci_host, timer); 26130+ unsigned int i, curr_status, status[5]; 26131+ unsigned int detect_retry_count = 0; 26132+ 26133+ himci_assert(host); 26134+ 26135+ while (1) { 26136+ for (i = 0; i < 5; i++) { 26137+ status[i] = himci_sys_card_detect(host); 26138+ udelay(10); 26139+ } 26140+ if ((status[0] == status[1]) 26141+ && (status[0] == status[2]) 26142+ && (status[0] == status[3]) 26143+ && (status[0] == status[4])) 26144+ break; 26145+ 26146+ detect_retry_count++; 26147+ if (detect_retry_count >= retry_count) { 26148+ himci_error("this is a dithering, card detect error!"); 26149+ goto err; 26150+ } 26151+ } 26152+ curr_status = status[0]; 26153+ if (curr_status != host->card_status) { 26154+ himci_trace(2, "begin card_status = %d\n", host->card_status); 26155+ host->card_status = curr_status; 26156+ if (curr_status != CARD_UNPLUGED) { 26157+ himci_sys_ctrl_init(host); 26158+ himci_init_host(host); 26159+ pr_info("card connected!\n"); 26160+ } else { 26161+ pr_info("card disconnected!\n"); 26162+ } 26163+ 26164+ mmc_detect_change(host->mmc, 0); 26165+ } 26166+err: 26167+ mod_timer(timer, jiffies + detect_time); 26168+} 26169+ 26170+static void himci_idma_start(struct himci_host *host) 26171+{ 26172+ unsigned int tmp; 26173+ 26174+ himci_trace(2, "begin"); 26175+ himci_writel(host->dma_paddr, host->base + MCI_DBADDR); 26176+ tmp = himci_readl(host->base + MCI_BMOD); 26177+ tmp |= BMOD_DMA_EN; 26178+ himci_writel(tmp, host->base + MCI_BMOD); 26179+} 26180+ 26181+static void himci_idma_stop(struct himci_host *host) 26182+{ 26183+ unsigned int tmp_reg; 26184+ 26185+ himci_trace(2, "begin"); 26186+ tmp_reg = himci_readl(host->base + MCI_BMOD); 26187+ tmp_reg &= ~BMOD_DMA_EN; 26188+ himci_writel(tmp_reg, host->base + MCI_BMOD); 26189+} 26190+ 26191+static void himci_idma_reset(struct himci_host *host) 26192+{ 26193+ u32 regval; 26194+ 26195+ regval = himci_readl(host->base + MCI_BMOD); 26196+ regval |= BMOD_SWR; 26197+ himci_writel(regval, host->base + MCI_BMOD); 26198+ 26199+ regval = himci_readl(host->base + MCI_CTRL); 26200+ regval |= CTRL_RESET | FIFO_RESET | DMA_RESET; 26201+ himci_writel(regval, host->base + MCI_CTRL); 26202+ 26203+ udelay(1); 26204+ himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS); 26205+} 26206+ 26207+static int himci_setup_data(struct himci_host *host, struct mmc_data *data) 26208+{ 26209+ unsigned int sg_phyaddr, sg_length; 26210+ unsigned int i; 26211+ unsigned int ret = 0; 26212+ unsigned int data_size; 26213+ unsigned int max_des, des_cnt; 26214+ struct himci_des *des = NULL; 26215+ 26216+ himci_trace(2, "begin"); 26217+ himci_assert(host); 26218+ himci_assert(data); 26219+ 26220+ host->data = data; 26221+ 26222+ if (data->flags & MMC_DATA_READ) 26223+ host->dma_dir = DMA_FROM_DEVICE; 26224+ else 26225+ host->dma_dir = DMA_TO_DEVICE; 26226+ 26227+ host->dma_sg = data->sg; 26228+ host->dma_sg_num = dma_map_sg(mmc_dev(host->mmc), 26229+ data->sg, data->sg_len, host->dma_dir); 26230+ himci_assert(host->dma_sg_num); 26231+ himci_trace(2, "host->dma_sg_num is %d\n", host->dma_sg_num); 26232+ data_size = data->blksz * data->blocks; 26233+ 26234+ if (data_size > (DMA_BUFFER * MAX_DMA_DES)) { 26235+ himci_error("mci request data_size is too big!\n"); 26236+ ret = -1; 26237+ goto out; 26238+ } 26239+ 26240+ himci_trace(2, "host->dma_paddr is 0x%08lx,host->dma_vaddr is 0x%08lx\n", 26241+ (uintptr_t)host->dma_paddr, 26242+ (uintptr_t)host->dma_vaddr); 26243+ 26244+ max_des = (CMD_DES_PAGE_SIZE / sizeof(struct himci_des)); 26245+ des = (struct himci_des *)host->dma_vaddr; 26246+ des_cnt = 0; 26247+ 26248+ for (i = 0; i < host->dma_sg_num; i++) { 26249+ sg_length = sg_dma_len(&data->sg[i]); 26250+ sg_phyaddr = sg_dma_address(&data->sg[i]); 26251+ himci_trace(2, "sg[%d] sg_length is 0x%08X, " \ 26252+ "sg_phyaddr is 0x%08X\n", \ 26253+ i, (unsigned int)sg_length, \ 26254+ (unsigned int)sg_phyaddr); 26255+ while (sg_length) { 26256+ des[des_cnt].idmac_des_ctrl = DMA_DES_OWN 26257+ | DMA_DES_NEXT_DES; 26258+ des[des_cnt].idmac_des_buf_addr = sg_phyaddr; 26259+ /* idmac_des_next_addr is paddr for dma */ 26260+ des[des_cnt].idmac_des_next_addr = host->dma_paddr 26261+ + (des_cnt + 1) * sizeof(struct himci_des); 26262+ 26263+ /* buffer size <= 4k */ 26264+ if (sg_length >= 0x1000) { 26265+ des[des_cnt].idmac_des_buf_size = 0x1000; 26266+ sg_length -= 0x1000; 26267+ sg_phyaddr += 0x1000; 26268+ } else { 26269+ /* data alignment */ 26270+ des[des_cnt].idmac_des_buf_size = sg_length; 26271+ sg_length = 0; 26272+ } 26273+ 26274+ himci_trace(2, "des[%d] vaddr is 0x%08X", i, 26275+ (unsigned int)(uintptr_t)&des[i]); 26276+ himci_trace(2, "des[%d].idmac_des_ctrl is 0x%08X", 26277+ i, (unsigned int)des[i].idmac_des_ctrl); 26278+ himci_trace(2, "des[%d].idmac_des_buf_size is 0x%08X", 26279+ i, (unsigned int)des[i].idmac_des_buf_size); 26280+ himci_trace(2, "des[%d].idmac_des_buf_addr 0x%08X", 26281+ i, (unsigned int)des[i].idmac_des_buf_addr); 26282+ himci_trace(2, "des[%d].idmac_des_next_addr is 0x%08X", 26283+ i, (unsigned int)des[i].idmac_des_next_addr); 26284+ des_cnt++; 26285+ } 26286+ 26287+ himci_assert(des_cnt < max_des); 26288+ } 26289+ des[0].idmac_des_ctrl |= DMA_DES_FIRST_DES; 26290+ des[des_cnt - 1].idmac_des_ctrl |= DMA_DES_LAST_DES; 26291+ des[des_cnt - 1].idmac_des_next_addr = 0; 26292+out: 26293+ return ret; 26294+} 26295+ 26296+static int himci_exec_cmd(struct himci_host *host, 26297+ struct mmc_command *cmd, struct mmc_data *data) 26298+{ 26299+ volatile union cmd_arg_u cmd_regs; 26300+ 26301+ himci_trace(2, "begin"); 26302+ himci_assert(host); 26303+ himci_assert(cmd); 26304+ 26305+ host->cmd = cmd; 26306+ 26307+ himci_writel(cmd->arg, host->base + MCI_CMDARG); 26308+ himci_trace(4, "arg_reg 0x%x, val 0x%x", MCI_CMDARG, cmd->arg); 26309+ cmd_regs.cmd_arg = himci_readl(host->base + MCI_CMD); 26310+ if (data) { 26311+ cmd_regs.bits.data_transfer_expected = 1; 26312+ if (data->flags & (MMC_DATA_WRITE | MMC_DATA_READ)) 26313+ cmd_regs.bits.transfer_mode = 0; 26314+ 26315+ if (data->flags & MMC_DATA_WRITE) 26316+ cmd_regs.bits.read_write = 1; 26317+ else if (data->flags & MMC_DATA_READ) 26318+ cmd_regs.bits.read_write = 0; 26319+ } else { 26320+ cmd_regs.bits.data_transfer_expected = 0; 26321+ cmd_regs.bits.transfer_mode = 0; 26322+ cmd_regs.bits.read_write = 0; 26323+ } 26324+ 26325+ cmd_regs.bits.send_auto_stop = 0; 26326+#ifdef CONFIG_SEND_AUTO_STOP 26327+ if ((host->mrq->stop) && (!(host->is_tuning))) 26328+ cmd_regs.bits.send_auto_stop = 1; 26329+#endif 26330+ 26331+ if (cmd == host->mrq->stop || 26332+ cmd->opcode == MMC_STOP_TRANSMISSION) { 26333+ cmd_regs.bits.stop_abort_cmd = 1; 26334+ cmd_regs.bits.wait_prvdata_complete = 0; 26335+ } else if (cmd->opcode == MMC_SEND_STATUS) { 26336+ cmd_regs.bits.stop_abort_cmd = 0; 26337+ cmd_regs.bits.wait_prvdata_complete = 0; 26338+ } else { 26339+ cmd_regs.bits.stop_abort_cmd = 0; 26340+ cmd_regs.bits.wait_prvdata_complete = 1; 26341+ } 26342+ 26343+ switch (mmc_resp_type(cmd)) { 26344+ case MMC_RSP_NONE: 26345+ cmd_regs.bits.response_expect = 0; 26346+ cmd_regs.bits.response_length = 0; 26347+ cmd_regs.bits.check_response_crc = 0; 26348+ break; 26349+ case MMC_RSP_R1: 26350+ case MMC_RSP_R1B: 26351+ cmd_regs.bits.response_expect = 1; 26352+ cmd_regs.bits.response_length = 0; 26353+ cmd_regs.bits.check_response_crc = 1; 26354+ break; 26355+ case MMC_RSP_R2: 26356+ cmd_regs.bits.response_expect = 1; 26357+ cmd_regs.bits.response_length = 1; 26358+ cmd_regs.bits.check_response_crc = 1; 26359+ break; 26360+ case MMC_RSP_R3: 26361+ case MMC_RSP_R1 & (~MMC_RSP_CRC): 26362+ cmd_regs.bits.response_expect = 1; 26363+ cmd_regs.bits.response_length = 0; 26364+ cmd_regs.bits.check_response_crc = 0; 26365+ break; 26366+ default: 26367+ host->cmd->error = -EINVAL; 26368+ himci_error("himci: unhandled response type %02x\n", 26369+ mmc_resp_type(cmd)); 26370+ return -EINVAL; 26371+ } 26372+ 26373+ himci_trace(3, "cmd->opcode = %d cmd->arg = 0x%X\n", 26374+ cmd->opcode, cmd->arg); 26375+ if (cmd->opcode == MMC_SELECT_CARD) { 26376+ host->card_rca = (cmd->arg >> 16); 26377+ } 26378+ if (cmd->opcode == MMC_GO_IDLE_STATE) 26379+ cmd_regs.bits.send_initialization = 1; 26380+ else 26381+ cmd_regs.bits.send_initialization = 0; 26382+ /* CMD 11 check switch voltage */ 26383+ if (cmd->opcode == SD_SWITCH_VOLTAGE) 26384+ cmd_regs.bits.volt_switch = 1; 26385+ else 26386+ cmd_regs.bits.volt_switch = 0; 26387+ 26388+ cmd_regs.bits.card_number = host->port; 26389+ cmd_regs.bits.cmd_index = cmd->opcode; 26390+ cmd_regs.bits.start_cmd = 1; 26391+ cmd_regs.bits.update_clk_reg_only = 0; 26392+ 26393+ himci_writel(DATA_INT_MASK, host->base + MCI_RINTSTS); 26394+ himci_writel(cmd_regs.cmd_arg, host->base + MCI_CMD); 26395+ himci_trace(4, "cmd_reg 0x%x, val 0x%x\n", MCI_CMD, cmd_regs.cmd_arg); 26396+ 26397+ if (himci_wait_cmd(host) != 0) { 26398+ himci_trace(3, "send card cmd is failed!"); 26399+ return -EINVAL; 26400+ } 26401+ return 0; 26402+} 26403+ 26404+static void himci_finish_request(struct himci_host *host, 26405+ struct mmc_request *mrq) 26406+{ 26407+ himci_trace(2, "begin"); 26408+ himci_assert(host); 26409+ himci_assert(mrq); 26410+ 26411+ host->mrq = NULL; 26412+ host->cmd = NULL; 26413+ host->data = NULL; 26414+ mmc_request_done(host->mmc, mrq); 26415+} 26416+ 26417+#define CMD_ERRORS \ 26418+ (R1_OUT_OF_RANGE | /* Command argument out of range */ \ 26419+ R1_ADDRESS_ERROR | /* Misaligned address */ \ 26420+ R1_BLOCK_LEN_ERROR | /* Transferred block length incorrect */ \ 26421+ R1_WP_VIOLATION | /* Tried to write to protected block */ \ 26422+ R1_CC_ERROR | /* Card controller error */ \ 26423+ R1_ERROR) /* General/unknown error */ 26424+ 26425+static void himci_cmd_done(struct himci_host *host, unsigned int stat) 26426+{ 26427+ unsigned int i; 26428+ struct mmc_command *cmd = host->cmd; 26429+ 26430+ himci_trace(2, "begin"); 26431+ himci_assert(host); 26432+ himci_assert(cmd); 26433+ 26434+ for (i = 0; i < 4; i++) { 26435+ if (mmc_resp_type(cmd) == MMC_RSP_R2) { 26436+ cmd->resp[i] = himci_readl(host->base + 26437+ MCI_RESP3 - i * 0x4); 26438+ /* R2 must delay some time here ,when use UHI card, 26439+ need check why */ 26440+ udelay(1000); 26441+ } else 26442+ cmd->resp[i] = himci_readl(host->base + 26443+ MCI_RESP0 + i * 0x4); 26444+ } 26445+ 26446+ if (stat & RTO_INT_STATUS) { 26447+ cmd->error = -ETIMEDOUT; 26448+ himci_trace(3, "irq cmd status stat = 0x%x is timeout error!", 26449+ stat); 26450+ } else if (stat & (RCRC_INT_STATUS | RE_INT_STATUS)) { 26451+ cmd->error = -EILSEQ; 26452+ himci_trace(3, "irq cmd status stat = 0x%x is response error!", 26453+ stat); 26454+ } 26455+ 26456+ if (((cmd->flags & MMC_RSP_R1) == MMC_RSP_R1) && 26457+ ((cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)) { 26458+ if ((cmd->resp[0] & CMD_ERRORS) && !host->is_tuning) { 26459+ host->error_count++; 26460+ host->mrq->cmd->error = -EACCES; 26461+ himci_trace(5, "The status of the card is abnormal, cmd->resp[0]: %x", 26462+ cmd->resp[0]); 26463+ } 26464+ 26465+ /* bad card situation: the TF card returns the contradictory card statut. 26466+ * that is, the card is in the ready state and in the programming state. 26467+ */ 26468+ if ((cmd->resp[0] & R1_READY_FOR_DATA) && (R1_CURRENT_STATE(cmd->resp[0]) == 26469+ R1_STATE_PRG)) { 26470+ host->error_count++; 26471+ host->mrq->cmd->error = -EACCES; 26472+ himci_trace(5, "The status of the card is abnormal, cmd->resp[0]: %x", 26473+ cmd->resp[0]); 26474+ } 26475+ } 26476+ 26477+ host->cmd = NULL; 26478+} 26479+ 26480+static void himci_data_done(struct himci_host *host, unsigned int stat) 26481+{ 26482+ struct mmc_data *data = host->data; 26483+ 26484+ himci_trace(2, "begin"); 26485+ himci_assert(host); 26486+ himci_assert(data); 26487+ 26488+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir); 26489+ 26490+ if (stat & (HTO_INT_STATUS | DRTO_INT_STATUS)) { 26491+ data->error = -ETIMEDOUT; 26492+ himci_trace(3, "irq data status stat = 0x%x is timeout error!", 26493+ stat); 26494+ } else if (stat & (EBE_INT_STATUS | SBE_INT_STATUS | 26495+ FRUN_INT_STATUS | DCRC_INT_STATUS)) { 26496+ data->error = -EILSEQ; 26497+ himci_trace(3, "irq data status stat = 0x%x is data error!", 26498+ stat); 26499+ } 26500+ 26501+ if (!data->error) 26502+ data->bytes_xfered = data->blocks * data->blksz; 26503+ else 26504+ data->bytes_xfered = 0; 26505+ 26506+ host->data = NULL; 26507+} 26508+ 26509+static int himci_wait_cmd_complete(struct himci_host *host) 26510+{ 26511+ unsigned int cmd_retry_count = 0; 26512+ unsigned long cmd_jiffies_timeout; 26513+ unsigned int cmd_irq_reg = 0; 26514+ struct mmc_command *cmd = host->cmd; 26515+ unsigned long flags; 26516+ 26517+ himci_trace(2, "begin"); 26518+ himci_assert(host); 26519+ himci_assert(cmd); 26520+ 26521+ cmd_jiffies_timeout = jiffies + request_timeout; 26522+ while (1) { 26523+ do { 26524+ spin_lock_irqsave(&host->lock, flags); 26525+ cmd_irq_reg = readl(host->base + MCI_RINTSTS); 26526+ 26527+ if (cmd_irq_reg & CD_INT_STATUS) { 26528+ himci_writel((CD_INT_STATUS | RTO_INT_STATUS 26529+ | RCRC_INT_STATUS | RE_INT_STATUS), 26530+ host->base + MCI_RINTSTS); 26531+ spin_unlock_irqrestore(&host->lock, flags); 26532+ himci_cmd_done(host, cmd_irq_reg); 26533+ return 0; 26534+ } else if (cmd_irq_reg & VOLT_SWITCH_INT_STATUS) { 26535+ himci_writel(VOLT_SWITCH_INT_STATUS, 26536+ host->base + MCI_RINTSTS); 26537+ spin_unlock_irqrestore(&host->lock, flags); 26538+ himci_cmd_done(host, cmd_irq_reg); 26539+ return 0; 26540+ } 26541+ spin_unlock_irqrestore(&host->lock, flags); 26542+ cmd_retry_count++; 26543+ } while (cmd_retry_count < retry_count); 26544+ 26545+ cmd_retry_count = 0; 26546+ 26547+ if (host->card_status == CARD_UNPLUGED) { 26548+ cmd->error = -ETIMEDOUT; 26549+ return -1; 26550+ } 26551+ 26552+ if (!time_before(jiffies, cmd_jiffies_timeout)) { 26553+ unsigned int i = 0; 26554+ for (i = 0; i < 4; i++) { 26555+ cmd->resp[i] = himci_readl(host->base + 26556+ MCI_RESP0 + 26557+ i * 0x4); 26558+ pr_err("voltage switch read MCI_RESP"); 26559+ pr_err("%d : 0x%x\n", i, cmd->resp[i]); 26560+ } 26561+ cmd->error = -ETIMEDOUT; 26562+ himci_trace(3, "wait cmd request complete is timeout!"); 26563+ return -1; 26564+ } 26565+ 26566+ schedule(); 26567+ } 26568+} 26569+/* 26570+ * designware support send stop command automatically when 26571+ * read or wirte multi blocks 26572+ */ 26573+#ifdef CONFIG_SEND_AUTO_STOP 26574+static int himci_wait_auto_stop_complete(struct himci_host *host) 26575+{ 26576+ unsigned int cmd_retry_count = 0; 26577+ unsigned long cmd_jiffies_timeout; 26578+ unsigned int cmd_irq_reg = 0; 26579+ unsigned long flags; 26580+ 26581+ himci_trace(2, "begin"); 26582+ himci_assert(host); 26583+ 26584+ cmd_jiffies_timeout = jiffies + request_timeout; 26585+ while (1) { 26586+ do { 26587+ spin_lock_irqsave(&host->lock, flags); 26588+ cmd_irq_reg = readl(host->base + MCI_RINTSTS); 26589+ if (cmd_irq_reg & ACD_INT_STATUS) { 26590+ himci_writel((ACD_INT_STATUS | RTO_INT_STATUS | 26591+ RCRC_INT_STATUS | 26592+ RE_INT_STATUS), 26593+ host->base + MCI_RINTSTS); 26594+ spin_unlock_irqrestore(&host->lock, flags); 26595+ return 0; 26596+ } 26597+ spin_unlock_irqrestore(&host->lock, flags); 26598+ cmd_retry_count++; 26599+ } while (cmd_retry_count < retry_count); 26600+ 26601+ cmd_retry_count = 0; 26602+ if (host->card_status == CARD_UNPLUGED) 26603+ return -1; 26604+ if (!time_before(jiffies, cmd_jiffies_timeout)) { 26605+ himci_trace(3, "wait auto stop complete is timeout!"); 26606+ return -1; 26607+ } 26608+ 26609+ schedule(); 26610+ } 26611+} 26612+#endif 26613+ 26614+static int himci_wait_data_complete(struct himci_host *host) 26615+{ 26616+ unsigned int tmp_reg; 26617+ struct mmc_data *data = host->data; 26618+ long time = request_timeout; 26619+ unsigned long flags; 26620+ 26621+ himci_trace(2, "begin"); 26622+ himci_assert(host); 26623+ himci_assert(data); 26624+ 26625+ time = wait_event_timeout(host->intr_wait, 26626+ test_bit(HIMCI_PEND_DTO_B, 26627+ &host->pending_events), time); 26628+ 26629+ /* Mask MMC host data intr */ 26630+ spin_lock_irqsave(&host->lock, flags); 26631+ tmp_reg = himci_readl(host->base + MCI_INTMASK); 26632+ tmp_reg &= ~DATA_INT_MASK; 26633+ himci_writel(tmp_reg, host->base + MCI_INTMASK); 26634+ host->pending_events &= ~HIMCI_PEND_DTO_M; 26635+ spin_unlock_irqrestore(&host->lock, flags); 26636+ 26637+ if (((time <= 0) 26638+ && (!test_bit(HIMCI_PEND_DTO_B, &host->pending_events))) 26639+ || (host->card_status == CARD_UNPLUGED)) { 26640+ data->error = -ETIMEDOUT; 26641+ himci_trace(5, "wait data request complete is timeout! 0x%08X", 26642+ host->irq_status); 26643+ himci_idma_stop(host); 26644+ himci_data_done(host, host->irq_status); 26645+ return -1; 26646+ } 26647+ 26648+ himci_idma_stop(host); 26649+ himci_data_done(host, host->irq_status); 26650+ return 0; 26651+} 26652+ 26653+static int himci_wait_card_complete(struct himci_host *host, 26654+ struct mmc_data *data) 26655+{ 26656+ unsigned int card_retry_count = 0; 26657+ unsigned long card_jiffies_timeout; 26658+ unsigned int card_status_reg = 0; 26659+ 26660+ himci_trace(2, "begin"); 26661+ himci_assert(host); 26662+ 26663+ card_jiffies_timeout = jiffies + request_timeout; 26664+ while (1) { 26665+ do { 26666+ card_status_reg = readl(host->base + MCI_STATUS); 26667+ if (!(card_status_reg & DATA_BUSY)) { 26668+ himci_trace(2, "end"); 26669+ return 0; 26670+ } 26671+ card_retry_count++; 26672+ } while (card_retry_count < retry_count); 26673+ 26674+ card_retry_count = 0; 26675+ 26676+ if (host->card_status == CARD_UNPLUGED) { 26677+ host->mrq->cmd->error = -ETIMEDOUT; 26678+ himci_trace(3, "card is unpluged!"); 26679+ return -1; 26680+ } 26681+ 26682+ if (!time_before(jiffies, card_jiffies_timeout)) { 26683+ host->mrq->cmd->error = -ETIMEDOUT; 26684+ himci_trace(3, "wait card ready complete is timeout!"); 26685+ return -1; 26686+ } 26687+ 26688+ schedule(); 26689+ } 26690+} 26691+ 26692+static void himci_request(struct mmc_host *mmc, struct mmc_request *mrq) 26693+{ 26694+ struct himci_host *host = mmc_priv(mmc); 26695+ int byte_cnt = 0; 26696+ int fifo_count = 0; 26697+ int ret = 0; 26698+ unsigned int tmp_reg; 26699+ unsigned long flags; 26700+ 26701+ himci_trace(2, "begin"); 26702+ himci_assert(mmc); 26703+ himci_assert(mrq); 26704+ himci_assert(host); 26705+ 26706+ host->mrq = mrq; 26707+ host->irq_status = 0; 26708+ 26709+ if (host->card_status == CARD_UNPLUGED) { 26710+ mrq->cmd->error = -ENODEV; 26711+ goto request_end; 26712+ } 26713+ 26714+ ret = himci_wait_card_complete(host, mrq->data); 26715+ if (ret) { 26716+ mrq->cmd->error = ret; 26717+ goto request_end; 26718+ } 26719+ 26720+ /* prepare data */ 26721+ if (mrq->data) { 26722+ ret = himci_setup_data(host, mrq->data); 26723+ if (ret) { 26724+ mrq->data->error = ret; 26725+ himci_trace(3, "data setup is error!"); 26726+ goto request_end; 26727+ } 26728+ 26729+ byte_cnt = mrq->data->blksz * mrq->data->blocks; 26730+ himci_writel(byte_cnt, host->base + MCI_BYTCNT); 26731+ himci_writel(mrq->data->blksz, host->base + MCI_BLKSIZ); 26732+ 26733+ /* reset fifo */ 26734+ tmp_reg = himci_readl(host->base + MCI_CTRL); 26735+ tmp_reg |= FIFO_RESET; 26736+ himci_writel(tmp_reg, host->base + MCI_CTRL); 26737+ 26738+ do { 26739+ tmp_reg = himci_readl(host->base + MCI_CTRL); 26740+ fifo_count++; 26741+ if (fifo_count >= retry_count) { 26742+ pr_info("fifo reset is timeout!"); 26743+ return; 26744+ } 26745+ } while (tmp_reg & FIFO_RESET); 26746+ 26747+ /* start DMA */ 26748+ himci_idma_start(host); 26749+ } else { 26750+ himci_writel(0, host->base + MCI_BYTCNT); 26751+ himci_writel(0, host->base + MCI_BLKSIZ); 26752+ } 26753+ if (mrq->sbc) { 26754+ ret = himci_exec_cmd(host, mrq->sbc, NULL); 26755+ if (ret) { 26756+ mrq->sbc->error = ret; 26757+ goto request_end; 26758+ } 26759+ 26760+ /* wait command send complete */ 26761+ ret = himci_wait_cmd_complete(host); 26762+ if (ret) { 26763+ mrq->sbc->error = ret; 26764+ goto request_end; 26765+ } 26766+ } 26767+ /* send command */ 26768+ ret = himci_exec_cmd(host, mrq->cmd, mrq->data); 26769+ if (ret) { 26770+ mrq->cmd->error = ret; 26771+ himci_idma_stop(host); 26772+ himci_trace(3, "can't send card cmd! ret = %d", ret); 26773+ goto request_end; 26774+ } 26775+ 26776+ /* wait command send complete */ 26777+ himci_wait_cmd_complete(host); 26778+ 26779+ /* start data transfer */ 26780+ if (mrq->data) { 26781+ if (!(mrq->cmd->error)) { 26782+ /* Open MMC host data intr */ 26783+ spin_lock_irqsave(&host->lock, flags); 26784+ tmp_reg = himci_readl(host->base + MCI_INTMASK); 26785+ tmp_reg |= DATA_INT_MASK; 26786+ himci_writel(tmp_reg, host->base + MCI_INTMASK); 26787+ spin_unlock_irqrestore(&host->lock, flags); 26788+ 26789+ /* wait data transfer complete */ 26790+ himci_wait_data_complete(host); 26791+ } else if (host->is_tuning) { 26792+ unsigned int stat; 26793+ unsigned int wait_retry_count = 0; 26794+ 26795+ do { 26796+ stat = himci_readl(host->base + MCI_RINTSTS); 26797+ if (stat & (HTO_INT_STATUS | DRTO_INT_STATUS | 26798+ EBE_INT_STATUS | SBE_INT_STATUS | 26799+ FRUN_INT_STATUS | DCRC_INT_STATUS)) { 26800+ himci_writel(stat, host->base + MCI_RINTSTS); 26801+ himci_trace(3, "data status = 0x%x is error!", stat); 26802+ himci_trace(3, "udelay count = %d is error!", wait_retry_count); 26803+ break; 26804+ } 26805+ udelay(100); 26806+ wait_retry_count++; 26807+ } while (wait_retry_count < 1000); 26808+ 26809+ /* CMD error in data command */ 26810+ himci_idma_stop(host); 26811+ } else { 26812+ /* CMD error in data command */ 26813+ himci_idma_stop(host); 26814+ } 26815+ 26816+ if (mrq->stop && (!mrq->sbc 26817+ || (mrq->sbc && (mrq->cmd->error || mrq->data->error)))) { 26818+#ifdef CONFIG_SEND_AUTO_STOP 26819+ int trans_cnt; 26820+ 26821+ trans_cnt = himci_readl(host->base + MCI_TCBCNT); 26822+ /* send auto stop */ 26823+ if ((trans_cnt == byte_cnt) && (!(host->is_tuning))) { 26824+ himci_trace(3, "byte_cnt = %d, trans_cnt = %d", 26825+ byte_cnt, trans_cnt); 26826+ ret = himci_wait_auto_stop_complete(host); 26827+ if (ret) { 26828+ mrq->stop->error = -ETIMEDOUT; 26829+ goto request_end; 26830+ } 26831+ } else { 26832+#endif 26833+ /* send soft stop command */ 26834+ himci_trace(3, "this time, send soft stop"); 26835+ ret = himci_exec_cmd(host, host->mrq->stop, 26836+ host->data); 26837+ if (ret) { 26838+ mrq->stop->error = ret; 26839+ goto request_end; 26840+ } 26841+ ret = himci_wait_cmd_complete(host); 26842+ if (ret) 26843+ goto request_end; 26844+#ifdef CONFIG_SEND_AUTO_STOP 26845+ } 26846+#endif 26847+ } 26848+ } 26849+ 26850+request_end: 26851+ /* clear MMC host intr */ 26852+ spin_lock_irqsave(&host->lock, flags); 26853+ himci_writel(ALL_SD_INT_CLR, host->base + MCI_RINTSTS); 26854+ spin_unlock_irqrestore(&host->lock, flags); 26855+ 26856+ if (mrq->data && mrq->data->error && !host->is_tuning) 26857+ host->data_error_count++; 26858+ himci_finish_request(host, mrq); 26859+} 26860+ 26861+static int himci_do_voltage_switch(struct himci_host *host, 26862+ struct mmc_ios *ios) 26863+{ 26864+ u32 ctrl; 26865+ 26866+ /* 26867+ * We first check whether the request is to set signalling voltage 26868+ * to 3.3V. If so, we change the voltage to 3.3V and return quickly. 26869+ */ 26870+ ctrl = himci_readl(host->base + MCI_UHS_REG); 26871+ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { 26872+ /* Set 1.8V Signal Enable in the MCI_UHS_REG to 1 */ 26873+ himci_trace(3, "switch voltage 330"); 26874+ ctrl &= ~(HI_SDXC_CTRL_VDD_180 << host->port); 26875+ himci_writel(ctrl, host->base + MCI_UHS_REG); 26876+ 26877+ /* Wait for 5ms */ 26878+ usleep_range(5000, 5500); 26879+ 26880+ /* 3.3V regulator output should be stable within 5 ms */ 26881+ ctrl = himci_readl(host->base + MCI_UHS_REG); 26882+ if (!(ctrl & (HI_SDXC_CTRL_VDD_180 << host->port))) { 26883+ /* config Pin drive capability */ 26884+ himci_set_drv_cap(host, 0); 26885+ return 0; 26886+ } else { 26887+ himci_error(": Switching to 3.3V "); 26888+ himci_error("signalling voltage failed\n"); 26889+ return -EIO; 26890+ } 26891+ } else if (!(ctrl & (HI_SDXC_CTRL_VDD_180 << host->port)) && 26892+ (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) { 26893+ /* Stop SDCLK */ 26894+ himci_trace(3, "switch voltage 180"); 26895+ himci_control_cclk(host, DISABLE); 26896+ 26897+ /* 26898+ * Enable 1.8V Signal Enable in the MCI_UHS_REG 26899+ */ 26900+ ctrl |= (HI_SDXC_CTRL_VDD_180 << host->port); 26901+ himci_writel(ctrl, host->base + MCI_UHS_REG); 26902+ 26903+ /* Wait for 5ms */ 26904+ usleep_range(8000, 8500); 26905+ 26906+ ctrl = himci_readl(host->base + MCI_UHS_REG); 26907+ if (ctrl & (HI_SDXC_CTRL_VDD_180 << host->port)) { 26908+ /* Provide SDCLK again and wait for 1ms */ 26909+ himci_control_cclk(host, ENABLE); 26910+ usleep_range(1000, 1500); 26911+ 26912+ if (host->mmc->caps2 & MMC_CAP2_HS200) { 26913+ /* eMMC needn't to check the int status */ 26914+ return 0; 26915+ } 26916+ /* 26917+ * If CMD11 return CMD down, then the card 26918+ * was successfully switched to 1.8V signaling. 26919+ */ 26920+ ctrl = himci_readl(host->base + MCI_RINTSTS); 26921+ if ((ctrl & VOLT_SWITCH_INT_STATUS) 26922+ && (ctrl & CD_INT_STATUS)) { 26923+ himci_writel(VOLT_SWITCH_INT_STATUS | CD_INT_STATUS, 26924+ host->base + MCI_RINTSTS); 26925+ /* config Pin drive capability */ 26926+ himci_set_drv_cap(host, 1); 26927+ return 0; 26928+ } 26929+ } 26930+ 26931+ /* 26932+ * If we are here, that means the switch to 1.8V signaling 26933+ * failed. We power cycle the card, and retry initialization 26934+ * sequence by setting S18R to 0. 26935+ */ 26936+ 26937+ ctrl &= ~(HI_SDXC_CTRL_VDD_180 << host->port); 26938+ himci_writel(ctrl, host->base + MCI_UHS_REG); 26939+ 26940+ /* Wait for 5ms */ 26941+ usleep_range(5000, 5500); 26942+ 26943+ himci_ctrl_power(host, POWER_OFF, FORCE_DISABLE); 26944+ /* Wait for 1ms as per the spec */ 26945+ usleep_range(1000, 1500); 26946+ himci_ctrl_power(host, POWER_ON, FORCE_DISABLE); 26947+ 26948+ himci_control_cclk(host, DISABLE); 26949+ 26950+ /* Wait for 1ms as per the spec */ 26951+ usleep_range(1000, 1500); 26952+ himci_control_cclk(host, ENABLE); 26953+ 26954+ himci_error(": Switching to 1.8V signalling "); 26955+ himci_error("voltage failed, retrying with S18R set to 0\n"); 26956+ return -EAGAIN; 26957+ } else 26958+ /* No signal voltage switch required */ 26959+ return 0; 26960+} 26961+ 26962+static int himci_start_signal_voltage_switch(struct mmc_host *mmc, 26963+ struct mmc_ios *ios) 26964+{ 26965+ struct himci_host *host = mmc_priv(mmc); 26966+ int err; 26967+ 26968+ err = himci_do_voltage_switch(host, ios); 26969+ return err; 26970+} 26971+ 26972+static int himci_send_stop(struct mmc_host *host) 26973+{ 26974+ struct mmc_command cmd = {0}; 26975+ int err; 26976+ 26977+ cmd.opcode = MMC_STOP_TRANSMISSION; 26978+ cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; 26979+ err = mmc_wait_for_cmd(host, &cmd, 0); 26980+ return err; 26981+} 26982+ 26983+static void himci_set_sap_phase(struct himci_host *host, u32 phase) 26984+{ 26985+ unsigned int reg_value; 26986+ unsigned long flags; 26987+ 26988+ spin_lock_irqsave(&host->lock, flags); 26989+ 26990+ reg_value = himci_readl(host->base + MCI_UHS_REG_EXT); 26991+ reg_value &= ~CLK_SMPL_PHS_MASK; 26992+ reg_value |= (phase << CLK_SMPL_PHS_SHIFT); 26993+ himci_writel(reg_value, host->base + MCI_UHS_REG_EXT); 26994+ 26995+ spin_unlock_irqrestore(&host->lock, flags); 26996+} 26997+ 26998+#if defined(CONFIG_ARCH_HI3516DV300) || defined(CONFIG_ARCH_HI3516CV500) || \ 26999+ defined(CONFIG_ARCH_HI3559V200) || defined(CONFIG_ARCH_HI3556V200) || \ 27000+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 27001+static void himci_edge_tuning_enable(struct himci_host *host) 27002+{ 27003+ unsigned int val; 27004+ void __iomem *tmp_reg = 0; 27005+ 27006+ if (host->devid == 0) 27007+ tmp_reg = crg_ctrl + 0x14c; 27008+ else if (host->devid == 1) 27009+ tmp_reg = crg_ctrl + 0x164; 27010+ else if (host->devid == 2) 27011+ tmp_reg = crg_ctrl + 0x158; 27012+ else { 27013+ himci_trace(5, "Devid error, host->devid: %x", host->devid); 27014+ return; 27015+ } 27016+ 27017+ himci_writel(0x80001, tmp_reg); 27018+ 27019+ val = himci_readl(host->base + MCI_TUNING_CTRL); 27020+ val |= HW_TUNING_EN; 27021+ himci_writel(val, host->base + MCI_TUNING_CTRL); 27022+} 27023+ 27024+static void himci_edge_tuning_disable(struct himci_host *host) 27025+{ 27026+ unsigned int val; 27027+ void __iomem *tmp_reg = 0; 27028+ 27029+ if (host->devid == 0) 27030+ tmp_reg = crg_ctrl + 0x14c; 27031+ else if (host->devid == 1) 27032+ tmp_reg = crg_ctrl + 0x164; 27033+ else if (host->devid == 2) 27034+ tmp_reg = crg_ctrl + 0x158; 27035+ else { 27036+ himci_trace(5, "Devid error, host->devid: %x", host->devid); 27037+ return; 27038+ } 27039+ val = himci_readl(tmp_reg); 27040+ val |= (1 << 16); 27041+ himci_writel(val, tmp_reg); 27042+ 27043+ val = himci_readl(host->base + MCI_TUNING_CTRL); 27044+ val &= ~HW_TUNING_EN; 27045+ himci_writel(val, host->base + MCI_TUNING_CTRL); 27046+} 27047+ 27048+static int himci_send_status(struct mmc_host *mmc) 27049+{ 27050+ int err; 27051+ struct mmc_command cmd = {0}; 27052+ struct himci_host *host = NULL; 27053+ 27054+ BUG_ON(!mmc); 27055+ 27056+ host = mmc_priv(mmc); 27057+ cmd.opcode = MMC_SEND_STATUS; 27058+ if (!mmc_host_is_spi(mmc)) 27059+ cmd.arg = (host->card_rca << 16); 27060+ cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; 27061+ 27062+ err = mmc_wait_for_cmd(mmc, &cmd, 1); 27063+ if (err) 27064+ return err; 27065+ 27066+ return 0; 27067+} 27068+ 27069+static int himci_send_tuning(struct mmc_host *mmc, u32 opcode) 27070+{ 27071+ int err = 0; 27072+ struct himci_host *host; 27073+ /* fix a problem that When the I/O voltage is increased to 1.89 V or 1.91V 27074+ * at high and low temperatures, the system is suspended during the reboot test. 27075+ */ 27076+ unsigned cmd_count = 1000; 27077+ 27078+ host = mmc_priv(mmc); 27079+ himci_control_cclk(host, DISABLE); 27080+tuning_retry: 27081+ himci_idma_reset(host); 27082+ himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS); 27083+ himci_control_cclk(host, ENABLE); 27084+ if (tuning_reset_flag == 1) { 27085+ tuning_reset_flag = 0; 27086+ cmd_count--; 27087+ if (cmd_count == 0) { 27088+ printk("BUG_ON:controller reset is failed!!!\n"); 27089+ return -EINVAL; 27090+ } 27091+ goto tuning_retry; 27092+ } 27093+ 27094+ err = mmc_send_tuning(mmc, opcode, NULL); 27095+ himci_send_stop(mmc); 27096+ himci_send_status(mmc); 27097+ return err; 27098+} 27099+ 27100+static u32 himci_get_sap_dll_taps(struct himci_host *host) 27101+{ 27102+ u32 regval = 0; 27103+ void __iomem *reg_sap_dll_status = 0; 27104+ 27105+ if (host->devid == 0) 27106+ reg_sap_dll_status = crg_ctrl + 0x150; 27107+ else if (host->devid == 1) 27108+ reg_sap_dll_status = crg_ctrl + 0x168; 27109+ else if (host->devid == 2) 27110+ reg_sap_dll_status = crg_ctrl + 0x15c; 27111+ else { 27112+ himci_trace(5, "Devid error, host->devid: %x", host->devid); 27113+ return 0; 27114+ } 27115+ regval = himci_readl(reg_sap_dll_status); 27116+ 27117+ return (regval & 0xff); 27118+} 27119+ 27120+static void himci_set_dll_element(struct himci_host *host, u32 element) 27121+{ 27122+ u32 regval; 27123+ void __iomem *reg_sap_dll_ctrl = 0; 27124+ 27125+ if (host->devid == 0) 27126+ reg_sap_dll_ctrl = crg_ctrl + 0x14c; 27127+ else if (host->devid == 1) 27128+ reg_sap_dll_ctrl = crg_ctrl + 0x164; 27129+ else if (host->devid == 2) 27130+ reg_sap_dll_ctrl = crg_ctrl + 0x158; 27131+ else { 27132+ himci_trace(5, "Devid error, host->devid: %x", host->devid); 27133+ return; 27134+ } 27135+ regval = himci_readl(reg_sap_dll_ctrl); 27136+ regval &= ~(0xFF << 8); 27137+ regval |= (element << 8); 27138+ himci_writel(regval, reg_sap_dll_ctrl); 27139+} 27140+ 27141+/********************************************* 27142+ ********************************************* 27143+ EdgeMode A: 27144+ |<---- totalphases(ele) ---->| 27145+ _____________ 27146+ ______|||||||||||||||_______ 27147+ edge_p2f edge_f2p 27148+ (endp) (startp) 27149+ 27150+ EdgeMode B: 27151+ |<---- totalphases(ele) ---->| 27152+ ________ _________ 27153+ ||||||||||_________||||||||||| 27154+ edge_f2p edge_p2f 27155+ (startp) (endp) 27156+ 27157+ BestPhase: 27158+ if(endp < startp) 27159+ endp = endp + totalphases; 27160+ Best = ((startp + endp) / 2) % totalphases 27161+********************************************** 27162+**********************************************/ 27163+static int himci_edgedll_mode_tuning(struct himci_host *host, u32 opcode, 27164+ int edge_p2f, int edge_f2p) 27165+{ 27166+ u32 index; 27167+ u32 found = 0; 27168+ u32 startp = -1; 27169+ u32 endp = -1; 27170+ u32 startp_init = 0; 27171+ u32 endp_init = 0; 27172+ u32 phaseoffset = 0; 27173+ u32 totalphases = 0; 27174+ u16 ele, start_ele, phase_dll_elements; 27175+ u8 mdly_tap_flag = 0; 27176+ int prev_err = 0, err = 0; 27177+ u32 phase_num = HIMCI_PHASE_SCALE; 27178+ 27179+ himci_trace(3, "begin"); 27180+ 27181+ mdly_tap_flag = himci_get_sap_dll_taps(host); 27182+ phase_dll_elements = mdly_tap_flag / HIMCI_PHASE_SCALE; 27183+ totalphases = phase_dll_elements * phase_num; 27184+ 27185+ startp_init = edge_f2p * phase_dll_elements; 27186+ endp_init = edge_p2f * phase_dll_elements; 27187+ startp = startp_init; 27188+ endp = endp_init; 27189+ 27190+ found = 1; 27191+ start_ele = 2; 27192+ 27193+ /* Note: edgedll tuning must from edge_p2f to edge_f2p */ 27194+ if (edge_f2p >= edge_p2f) { 27195+ phaseoffset = edge_p2f * phase_dll_elements; 27196+ for (index = edge_p2f; index < edge_f2p; index++) { 27197+ /* set phase shift */ 27198+ himci_set_sap_phase(host, index); 27199+ for (ele = start_ele; ele <= phase_dll_elements; ele++) { 27200+ himci_set_dll_element(host, ele); 27201+ err = himci_send_tuning(host->mmc, opcode); 27202+ 27203+ if (!err) 27204+ found = 1; 27205+ 27206+ if (!prev_err && err && (endp == endp_init)) 27207+ endp = phaseoffset + ele; 27208+ 27209+ if (err) 27210+ startp = phaseoffset + ele; 27211+ 27212+#ifdef TUNING_PROC_DEBUG 27213+ printk("\tphase:%01d ele:%02d st:%03d end:%03d error:%d\n", index, ele, startp, 27214+ endp, err); 27215+#endif 27216+ 27217+ prev_err = err; 27218+ err = 0; 27219+ } 27220+ phaseoffset += phase_dll_elements; 27221+ } 27222+ } else { 27223+ phaseoffset = edge_p2f * phase_dll_elements; 27224+ for (index = edge_p2f; index < phase_num; index++) { 27225+ /* set phase shift */ 27226+ himci_set_sap_phase(host, index); 27227+ for (ele = start_ele; ele <= phase_dll_elements; ele++) { 27228+ himci_set_dll_element(host, ele); 27229+ err = himci_send_tuning(host->mmc, opcode); 27230+ if (!err) 27231+ found = 1; 27232+ 27233+ if (!prev_err && err && (endp == endp_init)) 27234+ endp = phaseoffset + ele; 27235+ 27236+ if (err) 27237+ startp = phaseoffset + ele; 27238+ 27239+#ifdef TUNING_PROC_DEBUG 27240+ printk("\tphase:%02d ele:%02d st:%03d end:%03d error:%d\n", index, ele, startp, 27241+ endp, err); 27242+#endif 27243+ 27244+ prev_err = err; 27245+ err = 0; 27246+ } 27247+ phaseoffset += phase_dll_elements; 27248+ } 27249+ 27250+ phaseoffset = 0; 27251+ for (index = 0; index < edge_f2p; index++) { 27252+ /* set phase shift */ 27253+ himci_set_sap_phase(host, index); 27254+ for (ele = start_ele; ele <= phase_dll_elements; ele++) { 27255+ himci_set_dll_element(host, ele); 27256+ err = himci_send_tuning(host->mmc, opcode); 27257+ if (!err) 27258+ found = 1; 27259+ 27260+ if (!prev_err && err && (endp == endp_init)) 27261+ endp = phaseoffset + ele; 27262+ 27263+ if (err) 27264+ startp = phaseoffset + ele; 27265+ 27266+#ifdef TUNING_PROC_DEBUG 27267+ printk("\tphase:%02d ele:%02d st:%03d end:%03d error:%d\n", index, ele, startp, 27268+ endp, err); 27269+#endif 27270+ 27271+ prev_err = err; 27272+ err = 0; 27273+ } 27274+ phaseoffset += phase_dll_elements; 27275+ } 27276+ } 27277+ 27278+ if (found) { 27279+ printk("scan elemnts: startp:%d endp:%d\n", startp, endp); 27280+ 27281+ if (endp <= startp) 27282+ endp += totalphases; 27283+ 27284+ if (totalphases == 0) { 27285+ printk(KERN_NOTICE "totalphases is zero\n"); 27286+ return -1; 27287+ } 27288+ phaseoffset = ((startp + endp) / 2) % totalphases; 27289+ index = (phaseoffset / phase_dll_elements); 27290+ ele = (phaseoffset % phase_dll_elements); 27291+ ele = ((ele > start_ele) ? ele : start_ele); 27292+ 27293+ himci_set_sap_phase(host, index); 27294+ himci_set_dll_element(host, ele); 27295+ 27296+ printk(KERN_NOTICE 27297+ "Tuning SampleClock. mix set phase:[%02d/%02d] ele:[%02d/%02d] \n", index, 27298+ (phase_num - 1), ele, 27299+ phase_dll_elements); 27300+ himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS); 27301+ return 0; 27302+ } 27303+ printk(KERN_NOTICE "No valid phase shift! use default\n"); 27304+ return -1; 27305+} 27306+ 27307+static void himci_tuning_feedback(struct mmc_host *mmc) 27308+{ 27309+ struct himci_host *host = mmc_priv(mmc); 27310+ 27311+ himci_control_cclk(host, DISABLE); 27312+ msleep(1); 27313+ himci_sys_reset(host); 27314+ msleep(1); 27315+ himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS); 27316+ himci_control_cclk(host, ENABLE); 27317+ msleep(1); 27318+ host->pending_events = 0; 27319+} 27320+ 27321+static int himci_check_tuning(struct mmc_host *mmc, u32 opcode) 27322+{ 27323+ int err; 27324+ 27325+ err = himci_send_tuning(mmc, opcode); 27326+ 27327+ return err; 27328+} 27329+ 27330+static int himci_execute_mix_mode_tuning(struct mmc_host *mmc, u32 opcode) 27331+{ 27332+ struct himci_host *host = mmc_priv(mmc); 27333+ u32 index, regval; 27334+ u32 found = 0, prefound = 0; 27335+ u32 edge_p2f, edge_f2p; 27336+ u32 edge_num = 0; 27337+ int err; 27338+ u32 phase_num = HIMCI_PHASE_SCALE; 27339+ 27340+ himci_trace(3, "begin"); 27341+ edge_p2f = 0; 27342+ edge_f2p = phase_num; 27343+ 27344+ himci_edge_tuning_enable(host); 27345+ 27346+ for (index = 0; index < HIMCI_PHASE_SCALE; index++) { 27347+ /* set phase shift */ 27348+ himci_set_sap_phase(host, index); 27349+ err = himci_send_tuning(mmc, opcode); 27350+ if (!err) { 27351+ regval = himci_readl(host->base + MCI_TUNING_CTRL); 27352+ found = ((regval & FOUND_EDGE) == FOUND_EDGE); 27353+ } else { 27354+ found = 1; 27355+ } 27356+ 27357+ if (found) { 27358+ edge_num++; 27359+ } 27360+ if (prefound && !found) { 27361+ edge_f2p = index; 27362+ } else if (!prefound && found) { 27363+ edge_p2f = index; 27364+ } 27365+#ifdef TUNING_PROC_DEBUG 27366+ printk("\tphase:%02d found:%02d p2f:%d f2p:%d error:%d\n", index, found, 27367+ edge_p2f, edge_f2p, err); 27368+#endif 27369+ if ((edge_p2f != 0) && (edge_f2p != phase_num)) 27370+ break; 27371+ 27372+ prefound = found; 27373+ found = 0; 27374+ } 27375+ 27376+ if ((edge_p2f == 0) && (edge_f2p == phase_num)) { 27377+ printk("unfound correct edge! check your config is correct!!\n"); 27378+ return -1; 27379+ } 27380+ printk("scan edges:%d p2f:%d f2p:%d\n", edge_num, edge_p2f, edge_f2p); 27381+ 27382+ if (edge_f2p < edge_p2f) 27383+ index = (edge_f2p + edge_p2f) / 2 % phase_num; 27384+ else 27385+ index = (edge_f2p + phase_num + edge_p2f) / 2 % phase_num; 27386+ printk("mix set temp-phase %d\n", index); 27387+ himci_set_sap_phase(host, index); 27388+ err = himci_send_tuning(mmc, opcode); 27389+ 27390+ himci_edge_tuning_disable(host); 27391+ 27392+ err = himci_edgedll_mode_tuning(host, opcode, edge_p2f, edge_f2p); 27393+ return err; 27394+} 27395+#if 0 27396+static int himci_execute_edge_tuning(struct mmc_host *mmc, u32 opcode) 27397+{ 27398+ struct himci_host *host = mmc_priv(mmc); 27399+ unsigned int index, val; 27400+ unsigned int found = 0; 27401+ unsigned int prev_found = 0; 27402+ unsigned int prev_point = 0; 27403+ unsigned int start_point = NOT_FOUND, end_point = NOT_FOUND; 27404+ unsigned int phase = 0; 27405+ 27406+ himci_trace(3, "begin"); 27407+ 27408+ himci_edge_tuning_enable(host); 27409+ 27410+ for (index = 0; index < HIMCI_PHASE_SCALE; index++) { 27411+ himci_set_sap_phase(host, index); 27412+ 27413+ mmc_send_tuning(mmc, opcode, NULL); 27414+ 27415+ himci_send_stop(mmc); 27416+ 27417+ val = himci_readl(host->base + MCI_TUNING_CTRL); 27418+ found = val & FOUND_EDGE; 27419+ 27420+ himci_trace(3, "try phase:%02d, found:0x%x\n", index, found); 27421+ 27422+ if (prev_found && !found) { 27423+ end_point = prev_point; 27424+ } else if (!prev_found && found) { 27425+ if (index != 0) 27426+ start_point = index; 27427+ } 27428+ if ((start_point != NOT_FOUND) && (end_point != NOT_FOUND)) 27429+ goto scan_out; 27430+ 27431+ prev_point = index; 27432+ prev_found = found; 27433+ found = 0; 27434+ } 27435+ 27436+scan_out: 27437+ if ((start_point == NOT_FOUND) && (end_point == NOT_FOUND)) { 27438+ himci_trace(5, "%s: no valid phase shift! use default", 27439+ mmc_hostname(mmc)); 27440+ return 0; 27441+ } 27442+ 27443+ if (start_point == NOT_FOUND) 27444+ start_point = end_point; 27445+ 27446+ if (end_point == NOT_FOUND) 27447+ end_point = start_point; 27448+ 27449+ pr_info("tuning %s: found edge on (s:%d, e:%d)", 27450+ mmc_hostname(mmc), start_point, end_point); 27451+ 27452+ if (start_point > end_point) 27453+ end_point += HIMCI_PHASE_SCALE; 27454+ 27455+ phase = ((start_point + end_point) / 2) % HIMCI_PHASE_SCALE; 27456+ 27457+ phase += HIMCI_PHASE_SCALE / 2; 27458+ phase %= HIMCI_PHASE_SCALE; 27459+ 27460+ himci_set_sap_phase(host, phase); 27461+ 27462+ himci_edge_tuning_disable(host); 27463+ 27464+ himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS); 27465+ 27466+ pr_info("determing final phase %d\n", phase); 27467+ 27468+ return 0; 27469+} 27470+#endif 27471+ 27472+/* 27473+ * The procedure of tuning the phase shift of sampling clock 27474+ * 27475+ * 1.Set a phase shift of 0° on cclk_in_sample 27476+ * 2.Send the Tuning command to the card 27477+ * 3.increase the phase shift value of cclk_in_sample until the 27478+ * correct sampling point is received such that the host does not 27479+ * see any of the errors. 27480+ * 4.Mark this phase shift value as the starting point of the sampling 27481+ * window. 27482+ * 5.increase the phase shift value of cclk_in_sample until the host 27483+ * sees the errors starting to come again or the phase shift value 27484+ * reaches 360°. 27485+ * 6.Mark the last successful phase shift value as the ending 27486+ * point of the sampling window. 27487+ * 27488+ * A window is established where the tuning block is matched. 27489+ * For example, for a scenario where the tuning block is received 27490+ * correctly for a phase shift window of 90°and 180°, then an appropriate 27491+ * sampling point is established as 135°. Once a sampling point is 27492+ * established, no errors should be visible in the tuning block. 27493+ * 27494+ */ 27495+static int himci_execute_tuning(struct mmc_host *mmc, u32 opcode) 27496+{ 27497+ struct himci_host *host = mmc_priv(mmc); 27498+ int err; 27499+ 27500+ himci_trace(3, "begin"); 27501+ 27502+ host->is_tuning = 1; 27503+ err = himci_execute_mix_mode_tuning(mmc, opcode); 27504+ himci_tuning_feedback(mmc); 27505+ if (!err) 27506+ err = himci_check_tuning(mmc, opcode); 27507+ host->is_tuning = 0; 27508+ return err; 27509+} 27510+#else 27511+static int himci_execute_tuning(struct mmc_host *mmc, u32 opcode) 27512+{ 27513+ struct himci_host *host; 27514+ unsigned int index, count; 27515+ unsigned int err = 0; 27516+ unsigned int found = 0; /* identify if we have found a valid phase */ 27517+ unsigned int start_point; 27518+ unsigned int end_point; 27519+ unsigned int prev_err = NOT_FOUND; 27520+ unsigned int raise_point = NOT_FOUND; 27521+ unsigned int fall_point = NOT_FOUND; 27522+ int phase, ret; 27523+ 27524+ start_point = TUNING_START_PHASE; 27525+ end_point = TUNING_END_PHASE; 27526+ 27527+ host = mmc_priv(mmc); 27528+ 27529+ himci_writel(0x1, host->base + MCI_CARDTHRCTL); 27530+ 27531+ himci_trace(3, "start sd3.0 phase tuning..."); 27532+ host->is_tuning = 1; 27533+ for (index = start_point; index <= end_point; index++) { 27534+ /* set sample clk phase shift */ 27535+ himci_set_sap_phase(host, index); 27536+ 27537+ count = 0; 27538+ do { 27539+ ret = mmc_send_tuning(mmc, opcode, NULL); 27540+ himci_send_stop(mmc); /* send soft_stop tail */ 27541+ 27542+ if (ret) { 27543+ himci_trace(3, "send tuning CMD%u fail! phase:%d err:%d\n", 27544+ opcode, index, ret); 27545+ err = 1; 27546+ break; 27547+ } 27548+ count++; 27549+ } while (count < 1); 27550+ 27551+ if (!err) 27552+ found = 1; /* found a valid phase */ 27553+ 27554+ if (index > start_point) { 27555+ if (err && !prev_err) 27556+ fall_point = index - 1; 27557+ 27558+ if (!err && prev_err) 27559+ raise_point = index; 27560+ } 27561+ 27562+ if ((raise_point != NOT_FOUND) && (fall_point != NOT_FOUND)) 27563+ goto tuning_out; 27564+ 27565+ prev_err = err; 27566+ err = 0; 27567+ } 27568+ 27569+tuning_out: 27570+ host->is_tuning = 0; 27571+ if (!found) { 27572+ himci_trace(5, "%s: no valid phase shift! use default", 27573+ mmc_hostname(mmc)); 27574+ himci_writel(DEFAULT_PHASE, host->base + MCI_UHS_REG_EXT); 27575+ } else { 27576+ himci_trace(3, "Tuning finished!!"); 27577+ 27578+ if (NOT_FOUND == raise_point) 27579+ raise_point = start_point; 27580+ if (NOT_FOUND == fall_point) 27581+ fall_point = end_point; 27582+ 27583+ if (fall_point < raise_point) { 27584+ phase = (raise_point + fall_point) / 2; 27585+ phase = phase - (HIMCI_PHASE_SCALE / 2); 27586+ phase = (phase < 0) ? (HIMCI_PHASE_SCALE + phase) : phase; 27587+ } else 27588+ phase = (raise_point + fall_point) / 2; 27589+ 27590+ himci_set_sap_phase(host, phase); 27591+ 27592+ pr_info("tuning %s: valid phase shift [%d, %d] Final Phase %d\n", 27593+ mmc_hostname(mmc), raise_point, fall_point, phase); 27594+ } 27595+ 27596+ himci_writel(RW_THRESHOLD_SIZE, host->base + MCI_CARDTHRCTL); 27597+ 27598+ return 0; 27599+} 27600+#endif 27601+ 27602+static void himci_set_bus_width(struct himci_host *host, struct mmc_ios *ios) 27603+{ 27604+ unsigned int tmp_reg; 27605+ 27606+ /* set bus_width */ 27607+ himci_trace(3, "ios->bus_width = %d ", ios->bus_width); 27608+ tmp_reg = himci_readl(host->base + MCI_CTYPE); 27609+ tmp_reg &= ~((CARD_WIDTH_0 | CARD_WIDTH_1) << host->port); 27610+ 27611+ if (ios->bus_width == MMC_BUS_WIDTH_8) { 27612+ tmp_reg |= (CARD_WIDTH_0 << host->port); 27613+ himci_writel(tmp_reg, host->base + MCI_CTYPE); 27614+ } else if (ios->bus_width == MMC_BUS_WIDTH_4) { 27615+ tmp_reg |= (CARD_WIDTH_1 << host->port); 27616+ himci_writel(tmp_reg, host->base + MCI_CTYPE); 27617+ } else { 27618+ himci_writel(tmp_reg, host->base + MCI_CTYPE); 27619+ } 27620+} 27621+ 27622+static void himci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 27623+{ 27624+ struct himci_host *host = mmc_priv(mmc); 27625+ u32 ctrl; 27626+ int ret = 0; 27627+ 27628+ himci_trace(2, "begin"); 27629+ himci_assert(mmc); 27630+ himci_assert(ios); 27631+ himci_assert(host); 27632+ 27633+ himci_trace(3, "ios->power_mode = %d ", ios->power_mode); 27634+ if (!ios->clock) { 27635+ ret = himci_control_cclk(host, DISABLE); 27636+ if (ret) 27637+ return; 27638+ } 27639+ 27640+ switch (ios->power_mode) { 27641+ case MMC_POWER_OFF: 27642+ himci_ctrl_power(host, POWER_OFF, FORCE_DISABLE); 27643+ break; 27644+ case MMC_POWER_UP: 27645+ case MMC_POWER_ON: 27646+ himci_ctrl_power(host, POWER_ON, FORCE_DISABLE); 27647+ break; 27648+ default: 27649+ break; 27650+ } 27651+ himci_trace(3, "ios->clock = %d ", ios->clock); 27652+ if (ios->clock) { 27653+ ret = himci_control_cclk(host, DISABLE); 27654+ if (ret) 27655+ return; 27656+ himci_set_cclk(host, ios->clock); 27657+ ret = himci_control_cclk(host, ENABLE); 27658+ if (ret) 27659+ return; 27660+ 27661+ himci_set_default_phase(host); 27662+ 27663+ /* speed mode check, if it is DDR50 set DDR mode */ 27664+ if (ios->timing == MMC_TIMING_UHS_DDR50) { 27665+ ctrl = himci_readl(host->base + MCI_UHS_REG); 27666+ if (!((HI_SDXC_CTRL_DDR_REG << host->port) & ctrl)) { 27667+ ctrl |= (HI_SDXC_CTRL_DDR_REG << host->port); 27668+ himci_writel(ctrl, host->base + MCI_UHS_REG); 27669+ } 27670+ } 27671+ } else { 27672+ ret = himci_control_cclk(host, DISABLE); 27673+ if (ret) 27674+ return; 27675+ if (ios->timing != MMC_TIMING_UHS_DDR50) { 27676+ ctrl = himci_readl(host->base + MCI_UHS_REG); 27677+ if ((HI_SDXC_CTRL_DDR_REG << host->port) & ctrl) { 27678+ ctrl &= ~(HI_SDXC_CTRL_DDR_REG << host->port); 27679+ himci_writel(ctrl, host->base + MCI_UHS_REG); 27680+ } 27681+ } 27682+ } 27683+ 27684+ himci_set_drv_cap(host, 0); 27685+ 27686+ himci_set_bus_width(host, ios); 27687+} 27688+ 27689+static void himci_enable_sdio_irq(struct mmc_host *mmc, int enable) 27690+{ 27691+ struct himci_host *host = mmc_priv(mmc); 27692+ unsigned int reg_value; 27693+ unsigned long flags; 27694+ 27695+ spin_lock_irqsave(&host->lock, flags); 27696+ reg_value = himci_readl(host->base + MCI_INTMASK); 27697+ if (enable) 27698+ reg_value |= SDIO_INT_MASK; 27699+ else 27700+ reg_value &= ~SDIO_INT_MASK; 27701+ himci_writel(reg_value, host->base + MCI_INTMASK); 27702+ spin_unlock_irqrestore(&host->lock, flags); 27703+} 27704+ 27705+static int himci_get_card_detect(struct mmc_host *mmc) 27706+{ 27707+ unsigned ret; 27708+ struct himci_host *host = mmc_priv(mmc); 27709+ 27710+ himci_trace(2, "begin"); 27711+ ret = himci_sys_card_detect(host); 27712+ 27713+ if (ret) 27714+ return 0; 27715+ else 27716+ return 1; 27717+} 27718+ 27719+static int himci_get_ro(struct mmc_host *mmc) 27720+{ 27721+ unsigned ret; 27722+ struct himci_host *host = mmc_priv(mmc); 27723+ 27724+ himci_trace(2, "begin"); 27725+ himci_assert(mmc); 27726+ 27727+ ret = himci_ctrl_card_readonly(host); 27728+ 27729+ return ret; 27730+} 27731+ 27732+static void himci_hw_reset(struct mmc_host *mmc) 27733+{ 27734+ unsigned int reg_value; 27735+ struct himci_host *host = mmc_priv(mmc); 27736+ unsigned int port = host->port; 27737+ 27738+ reg_value = himci_readl(host->base + MCI_RESET_N); 27739+ reg_value &= ~(MMC_RST_N << port); 27740+ himci_writel(reg_value, host->base + MCI_RESET_N); 27741+ 27742+ /* For eMMC, minimum is 1us but give it 10us for good measure */ 27743+ udelay(10); 27744+ reg_value = himci_readl(host->base + MCI_RESET_N); 27745+ reg_value |= (MMC_RST_N << port); 27746+ himci_writel(reg_value, host->base + MCI_RESET_N); 27747+ 27748+ /* For eMMC, minimum is 200us but give it 300us for good measure */ 27749+ usleep_range(300, 1000); 27750+} 27751+ 27752+static int himci_card_busy(struct mmc_host *mmc) 27753+{ 27754+ struct himci_host *host = mmc_priv(mmc); 27755+ u32 regval; 27756+ 27757+ himci_trace(2, "begin"); 27758+ 27759+ regval = himci_readl(host->base + MCI_STATUS); 27760+ regval &= DATA_BUSY; 27761+ 27762+ return regval; 27763+} 27764+ 27765+static int himci_card_info_save(struct mmc_host *mmc) 27766+{ 27767+ struct mmc_card *card = mmc->card; 27768+ struct himci_host *host = mmc_priv(mmc); 27769+ struct card_info *c_info = &host->c_info; 27770+ 27771+ if (!card) { 27772+ memset(c_info, 0, sizeof(struct card_info)); 27773+ c_info->card_connect = CARD_DISCONNECT; 27774+ goto out; 27775+ } 27776+ 27777+ c_info->card_type = card->type; 27778+ c_info->card_state = card->state; 27779+ 27780+ c_info->timing = mmc->ios.timing; 27781+ c_info->card_support_clock = mmc->ios.clock; 27782+ 27783+ c_info->sd_bus_speed = card->sd_bus_speed; 27784+ 27785+ memcpy(c_info->ssr, card->raw_ssr, ARRAY_SIZE(c_info->ssr)); 27786+ 27787+ c_info->card_connect = CARD_CONNECT; 27788+out: 27789+ return 0; 27790+} 27791+ 27792+static const struct mmc_host_ops himci_ops = { 27793+ .request = himci_request, 27794+ .set_ios = himci_set_ios, 27795+ .get_ro = himci_get_ro, 27796+ .card_busy = himci_card_busy, 27797+ .start_signal_voltage_switch = himci_start_signal_voltage_switch, 27798+ .execute_tuning = himci_execute_tuning, 27799+ .enable_sdio_irq = himci_enable_sdio_irq, 27800+ .hw_reset = himci_hw_reset, 27801+ .get_cd = himci_get_card_detect, 27802+ .card_info_save = himci_card_info_save, 27803+}; 27804+ 27805+static irqreturn_t hisd_irq(int irq, void *dev_id) 27806+{ 27807+ struct himci_host *host = dev_id; 27808+ u32 state = 0; 27809+ int handle = 0; 27810+ u32 mstate = 0; 27811+ 27812+ spin_lock(&host->lock); 27813+ state = himci_readl(host->base + MCI_RINTSTS); 27814+ spin_unlock(&host->lock); 27815+ 27816+ /* bugfix: when send soft stop to SD Card, Host will report 27817+ sdio interrupt, This situation needs to be avoided */ 27818+ if (host->mmc->caps & MMC_CAP_SDIO_IRQ) { 27819+ if ((host->mmc->card != NULL) 27820+ && (host->mmc->card->type == MMC_TYPE_SDIO)) { 27821+ mstate = himci_readl(host->base + MCI_INTMASK); 27822+ if ((state & SDIO_INT_STATUS) && 27823+ (mstate & SDIO_INT_MASK)) { 27824+ spin_lock(&host->lock); 27825+ himci_writel(SDIO_INT_STATUS, 27826+ host->base + MCI_RINTSTS); 27827+ spin_unlock(&host->lock); 27828+ handle = 1; 27829+ mmc_signal_sdio_irq(host->mmc); 27830+ } 27831+ } 27832+ } 27833+ 27834+ if (state & DATA_INT_MASK) { 27835+ handle = 1; 27836+ host->pending_events |= HIMCI_PEND_DTO_M; 27837+ 27838+ spin_lock(&host->lock); 27839+ host->irq_status = himci_readl(host->base + MCI_RINTSTS); 27840+ himci_writel(DATA_INT_MASK, host->base + MCI_RINTSTS); 27841+ spin_unlock(&host->lock); 27842+ 27843+ wake_up(&host->intr_wait); 27844+ } 27845+ 27846+ if (handle) 27847+ return IRQ_HANDLED; 27848+ 27849+ return IRQ_NONE; 27850+} 27851+ 27852+static int himci_of_parse(struct device_node *np, struct mmc_host *mmc) 27853+{ 27854+ struct himci_host *host = mmc_priv(mmc); 27855+ int ret = mmc_of_parse(mmc); 27856+ int len; 27857+ 27858+ if (ret) 27859+ return ret; 27860+ 27861+ if (of_property_read_u32(np, "min-frequency", &mmc->f_min)) 27862+ mmc->f_min = MMC_CCLK_MIN; 27863+ 27864+ if (of_property_read_u32(np, "devid", &host->devid)) 27865+ return -EINVAL; 27866+ 27867+ if (of_find_property(np, "cap-mmc-hw-reset", &len)) 27868+ mmc->caps |= MMC_CAP_HW_RESET; 27869+ 27870+ if (host->devid == 0 || host->devid == 1) 27871+ mmc->caps |= MMC_CAP_CMD23; 27872+ return 0; 27873+} 27874+ 27875+static void himci_sdio_setup(void) 27876+{ 27877+#if defined(CONFIG_ARCH_HI3516DV300) 27878+ void __iomem *pwr_ctrl; 27879+ /* enable GPIO pin multiplexing in PMC module */ 27880+ unsigned int val; 27881+ 27882+ pwr_ctrl = ioremap(PWR_CTRL0_REG, 0x4); 27883+ if (!pwr_ctrl) { 27884+ printk("%s ioremap fail\n", __func__); 27885+ return; 27886+ } 27887+ val = readl(pwr_ctrl); 27888+ val = val | GPIO_AT_PMC_ENABLE_BIT; 27889+ writel(val, pwr_ctrl); 27890+ msleep(REG_SLEEP_TIME_MS); 27891+ iounmap(pwr_ctrl); 27892+#endif 27893+} 27894+ 27895+static int himci_probe(struct platform_device *pdev) 27896+{ 27897+ struct mmc_host *mmc = NULL; 27898+ struct himci_host *host = NULL; 27899+ struct resource *host_ioaddr_res = NULL; 27900+ int ret = 0, irq; 27901+ struct device_node *np = pdev->dev.of_node; 27902+ unsigned int regval; 27903+ static bool sdio_setup = false; 27904+ 27905+ himci_trace(2, "begin"); 27906+ pr_info("mmc host probe\n"); 27907+ himci_assert(pdev); 27908+ 27909+ if (sdio_setup == false) { 27910+ pr_info("sdio_setup entry!\n"); 27911+ himci_sdio_setup(); 27912+ sdio_setup = true; 27913+ } 27914+ 27915+ mmc = mmc_alloc_host(sizeof(struct himci_host), &pdev->dev); 27916+ if (!mmc) { 27917+ himci_error("no mem for hi mci host controller!\n"); 27918+ ret = -ENOMEM; 27919+ goto out; 27920+ } 27921+ 27922+ platform_set_drvdata(pdev, mmc); 27923+ 27924+ mmc->ops = &himci_ops; 27925+ 27926+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 27927+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 27928+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 27929+ 27930+ crg_ctrl = ioremap(0x12010000, 0x1000); 27931+ if (!crg_ctrl) { 27932+ printk("%s ioremap fail\n", __func__); 27933+ ret = -ENOMEM; 27934+ goto out; 27935+ } 27936+ 27937+ misc_ctrl_1 = ioremap(0x12030004, 0x4); 27938+ if (!misc_ctrl_1) { 27939+ printk("%s ioremap fail\n", __func__); 27940+ ret = -ENOMEM; 27941+ goto out; 27942+ } 27943+ regval = readl(misc_ctrl_1); 27944+ /* clear sdio0_pswitch_ctrl_sel bit */ 27945+ regval &= ~(0x1 << 2); 27946+ writel(regval, misc_ctrl_1); 27947+ iounmap(misc_ctrl_1); 27948+#endif 27949+ 27950+ host_ioaddr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 27951+ if (NULL == host_ioaddr_res) { 27952+ himci_error("no ioaddr rescources config!\n"); 27953+ ret = -ENODEV; 27954+ goto out; 27955+ } 27956+ 27957+ if (himci_of_parse(np, mmc)) { 27958+ himci_error("failed to parse mmc dts!\n"); 27959+ ret = -EINVAL; 27960+ goto out; 27961+ } 27962+ 27963+ /* reload by this controller */ 27964+#ifndef CONFIG_HISI_MC 27965+ mmc->max_blk_count = 2048; 27966+#else 27967+ mmc->max_blk_count = 4096; 27968+#endif 27969+ mmc->max_segs = 1024; 27970+ mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count; 27971+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; 27972+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 27973+ 27974+ host = mmc_priv(mmc); 27975+ pdev->id = host->devid; 27976+ if (host->devid >= HIMCI_SLOT_NUM) { 27977+ himci_error("devid is invalid!\n"); 27978+ ret = -EINVAL; 27979+ goto out; 27980+ } 27981+ mci_host[host->devid] = host; 27982+ host->pdev = pdev; 27983+ host->mmc = mmc; 27984+#ifdef CONFIG_ARCH_HI3518EV20X 27985+ if (host->mmc->caps & MMC_CAP_HW_RESET) 27986+ host->port = 1; 27987+ else 27988+ host->port = 0; 27989+#else 27990+ host->port = 0; 27991+#endif 27992+ host->dma_vaddr = dma_alloc_coherent(&pdev->dev, CMD_DES_PAGE_SIZE, 27993+ &host->dma_paddr, GFP_KERNEL); 27994+ if (!host->dma_vaddr) { 27995+ himci_error("no mem for himci dma!\n"); 27996+ ret = -ENOMEM; 27997+ goto out; 27998+ } 27999+ 28000+ host->base = devm_ioremap_resource(&pdev->dev, host_ioaddr_res); 28001+ if (IS_ERR_OR_NULL(host->base)) { 28002+ himci_error("no mem for himci base!\n"); 28003+ ret = -ENOMEM; 28004+ goto out; 28005+ } 28006+ 28007+ spin_lock_init(&host->lock); 28008+ 28009+ host->crg_rst = devm_reset_control_get(&pdev->dev, "mmc_reset"); 28010+ if (IS_ERR_OR_NULL(host->crg_rst)) { 28011+ himci_error("get rst fail.\n"); 28012+ ret = PTR_ERR(host->crg_rst); 28013+ goto out; 28014+ } 28015+ 28016+ reset_control_assert(host->crg_rst); 28017+ usleep_range(50, 60); 28018+ reset_control_deassert(host->crg_rst); 28019+ 28020+ host->clk = devm_clk_get(&pdev->dev, "mmc_clk"); 28021+ if (IS_ERR_OR_NULL(host->clk)) { 28022+ himci_error("get clock fail.\n"); 28023+ ret = PTR_ERR(host->clk); 28024+ goto out; 28025+ } 28026+ 28027+ clk_prepare_enable(host->clk); 28028+ 28029+ host->power_status = POWER_OFF; 28030+ 28031+ /* enable card */ 28032+ himci_init_host(host); 28033+ host->card_status = himci_sys_card_detect(host); 28034+ 28035+ timer_setup(&host->timer, himci_detect_card, 0); 28036+ host->timer.expires = jiffies + detect_time; 28037+ add_timer(&host->timer); 28038+ 28039+ init_waitqueue_head(&host->intr_wait); 28040+ irq = platform_get_irq(pdev, 0); 28041+ if (irq < 0) { 28042+ pr_err("no IRQ defined!\n"); 28043+ goto out; 28044+ } 28045+ 28046+ host->irq = irq; 28047+ ret = request_irq(irq, hisd_irq, 0, DRIVER_NAME, host); 28048+ if (ret) { 28049+ pr_err("request_irq error!\n"); 28050+ goto out; 28051+ } 28052+ 28053+ mmc_add_host(mmc); 28054+ return 0; 28055+out: 28056+ if (host) { 28057+ del_timer(&host->timer); 28058+ 28059+ if (host->base) 28060+ devm_iounmap(&pdev->dev, host->base); 28061+ 28062+ if (host->dma_vaddr) 28063+ dma_free_coherent(&pdev->dev, CMD_DES_PAGE_SIZE, 28064+ host->dma_vaddr, host->dma_paddr); 28065+ } 28066+ if (mmc) 28067+ mmc_free_host(mmc); 28068+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 28069+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 28070+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 28071+ if (crg_ctrl) 28072+ iounmap(crg_ctrl); 28073+#endif 28074+ return ret; 28075+} 28076+ 28077+static int __exit himci_remove(struct platform_device *pdev) 28078+{ 28079+ struct mmc_host *mmc = platform_get_drvdata(pdev); 28080+ 28081+ himci_trace(2, "begin"); 28082+ himci_assert(pdev); 28083+ 28084+ platform_set_drvdata(pdev, NULL); 28085+ 28086+ if (mmc) { 28087+ struct himci_host *host = mmc_priv(mmc); 28088+ 28089+ mmc_remove_host(mmc); 28090+ free_irq(host->irq, host); 28091+ del_timer_sync(&host->timer); 28092+ himci_ctrl_power(host, POWER_OFF, FORCE_DISABLE); 28093+ himci_control_cclk(host, DISABLE); 28094+ devm_iounmap(&pdev->dev, host->base); 28095+ dma_free_coherent(&pdev->dev, CMD_DES_PAGE_SIZE, host->dma_vaddr, 28096+ host->dma_paddr); 28097+ mmc_free_host(mmc); 28098+ } 28099+ return 0; 28100+} 28101+ 28102+static void himci_shutdown(struct platform_device *pdev) 28103+{ 28104+ struct mmc_host *mmc = platform_get_drvdata(pdev); 28105+ 28106+ himci_trace(3, "shutdown"); 28107+ if (mmc) { 28108+ unsigned int val; 28109+ struct himci_host *host = mmc_priv(mmc); 28110+ 28111+ /* bugfix: host reset can trigger error intr */ 28112+ himci_writel(0, host->base + MCI_IDINTEN); 28113+ himci_writel(0, host->base + MCI_INTMASK); 28114+ 28115+ val = himci_readl(host->base + MCI_CTRL); 28116+ val |= CTRL_RESET | FIFO_RESET | DMA_RESET; 28117+ himci_writel(val, host->base + MCI_CTRL); 28118+ } 28119+} 28120+ 28121+#ifdef CONFIG_PM 28122+static int himci_pltm_suspend(struct platform_device *pdev, 28123+ pm_message_t state) 28124+{ 28125+ struct mmc_host *mmc = platform_get_drvdata(pdev); 28126+ struct himci_host *host = NULL; 28127+ int ret = 0; 28128+ 28129+ if (mmc) { 28130+ host = mmc_priv(mmc); 28131+ del_timer_sync(&host->timer); 28132+ 28133+ if (__clk_is_enabled(host->clk)) 28134+ clk_disable_unprepare(host->clk); 28135+ } 28136+ 28137+ return ret; 28138+} 28139+ 28140+static int himci_pltm_resume(struct platform_device *pdev) 28141+{ 28142+ struct mmc_host *mmc = platform_get_drvdata(pdev); 28143+ struct himci_host *host = NULL; 28144+ int ret = 0; 28145+ 28146+ if (mmc) { 28147+ host = mmc_priv(mmc); 28148+ 28149+ if (!__clk_is_enabled(host->clk)) 28150+ clk_prepare_enable(host->clk); 28151+ 28152+ himci_sys_ctrl_init(host); 28153+ himci_init_host(host); 28154+ 28155+ add_timer(&host->timer); 28156+ } 28157+ 28158+ return ret; 28159+} 28160+#else 28161+#define himci_pltm_suspend NULL 28162+#define himci_pltm_resume NULL 28163+#endif 28164+ 28165+void hisi_sdio_rescan(int slot) 28166+{ 28167+ struct mmc_host *mmc = NULL; 28168+ struct himci_host *host; 28169+ 28170+ host = mci_host[slot]; 28171+ if (!host || !host->mmc) { 28172+ himci_trace(5, "mmc%d: invalid slot!\n", slot); 28173+ return; 28174+ } 28175+ 28176+ mmc = host->mmc; 28177+ del_timer_sync(&host->timer); 28178+ 28179+ mmc_remove_host(mmc); 28180+ 28181+ mmc_add_host(mmc); 28182+ 28183+ add_timer(&host->timer); 28184+} 28185+EXPORT_SYMBOL(hisi_sdio_rescan); 28186+ 28187+struct mmc_host *himci_get_mmc_host(int slot) 28188+{ 28189+ struct himci_host *host = NULL; 28190+ 28191+ if (slot >= HIMCI_SLOT_NUM || slot < 0) { 28192+ return NULL; 28193+ } 28194+ 28195+ host = mci_host[slot]; 28196+ if (host == NULL) { 28197+ return NULL; 28198+ } 28199+ return host->mmc; 28200+} 28201+EXPORT_SYMBOL(himci_get_mmc_host); 28202+ 28203+static const struct of_device_id 28204+ himci_match[] __maybe_unused = { 28205+ {.compatible = "hisilicon,hi3516a-himci"}, 28206+ {.compatible = "hisilicon,hi3518ev20x-himci"}, 28207+ {.compatible = "hisilicon,hi3516cv500-himci"}, 28208+ {.compatible = "hisilicon,hi3516dv300-himci"}, 28209+ {.compatible = "hisilicon,hi3556v200-himci"}, 28210+ {.compatible = "hisilicon,hi3559v200-himci"}, 28211+ {}, 28212+}; 28213+ 28214+static struct platform_driver himci_driver = { 28215+ .probe = himci_probe, 28216+ .remove = himci_remove, 28217+ .shutdown = himci_shutdown, 28218+ .suspend = himci_pltm_suspend, 28219+ .resume = himci_pltm_resume, 28220+ .driver = { 28221+ .name = DRIVER_NAME, 28222+ .owner = THIS_MODULE, 28223+ .of_match_table = of_match_ptr(himci_match), 28224+ }, 28225+}; 28226+ 28227+static int __init himci_init(void) 28228+{ 28229+ int ret; 28230+ 28231+ himci_trace(2, "begin"); 28232+ 28233+ /* 28234+ * We should register SDIO1 first to make sure that 28235+ * the eMMC device,which connected to SDIO1 is mmcblk0. 28236+ */ 28237+ 28238+ ret = platform_driver_register(&himci_driver); 28239+ if (ret) { 28240+ platform_driver_unregister(&himci_driver); 28241+ himci_error("Himci driver register failed!"); 28242+ return ret; 28243+ } 28244+ 28245+ /* device proc entry */ 28246+ ret = mci_proc_init(); 28247+ if (ret) 28248+ himci_error("device proc init is failed!"); 28249+ 28250+ return ret; 28251+} 28252+ 28253+static void __exit himci_exit(void) 28254+{ 28255+ himci_trace(2, "begin"); 28256+ 28257+ mci_proc_shutdown(); 28258+ 28259+ platform_driver_unregister(&himci_driver); 28260+} 28261+ 28262+module_init(himci_init); 28263+module_exit(himci_exit); 28264+ 28265+#ifdef MODULE 28266+MODULE_AUTHOR("Hisilicon Drive Group"); 28267+MODULE_DESCRIPTION("MMC/SD driver for the Hisilicon MMC/SD Host Controller"); 28268+MODULE_LICENSE("GPL"); 28269+#endif 28270diff --git a/drivers/mmc/host/himci/himci.h b/drivers/mmc/host/himci/himci.h 28271new file mode 100644 28272index 000000000..d882e847f 28273--- /dev/null 28274+++ b/drivers/mmc/host/himci/himci.h 28275@@ -0,0 +1,156 @@ 28276+#ifndef _HI_MCI_H_ 28277+#define _HI_MCI_H_ 28278+ 28279+#include <linux/mmc/mmc.h> 28280+ 28281+extern int trace_level; 28282+#define HIMCI_TRACE_LEVEL 5 28283+/* 28284+ 0 - all message 28285+ 1 - dump all register read/write 28286+ 2 - flow trace 28287+ 3 - timeout err and protocol err 28288+ */ 28289+ 28290+#define HIMCI_TRACE_FMT KERN_INFO 28291+ 28292+#define NOT_FOUND -1 28293+#define POWER_ON 1 28294+#define POWER_OFF 0 28295+#define FORCE_ENABLE 1 28296+#define FORCE_DISABLE 0 28297+ 28298+#define CARD_UNPLUGED 1 28299+#define CARD_PLUGED 0 28300+ 28301+#define ENABLE 1 28302+#define DISABLE 0 28303+ 28304+#define HI_MCI_DETECT_TIMEOUT (HZ / 2) 28305+ 28306+#define HI_MCI_REQUEST_TIMEOUT (30 * HZ) 28307+ 28308+#define MAX_RETRY_COUNT 100 28309+ 28310+#define MMC_CCLK_MIN 100000 28311+ 28312+/* Base address of SD card register */ 28313+#define HI_MCI_INTR (49 + 32) 28314+ 28315+#define himci_trace(level, msg...) do { \ 28316+ if ((level) >= trace_level) { \ 28317+ printk(HIMCI_TRACE_FMT "%s:%d: ", __func__, __LINE__); \ 28318+ printk(msg); \ 28319+ printk("\n"); \ 28320+ } \ 28321+} while (0) 28322+ 28323+#define himci_assert(cond) do { \ 28324+ if (!(cond)) { \ 28325+ printk(KERN_ERR "Assert:himci:%s:%d\n", \ 28326+ __func__, \ 28327+ __LINE__); \ 28328+ BUG(); \ 28329+ } \ 28330+} while (0) 28331+ 28332+#define himci_error(s...) do { \ 28333+ printk(KERN_ERR "himci:%s:%d: ", __func__, __LINE__); \ 28334+ printk(s); \ 28335+ printk("\n"); \ 28336+} while (0) 28337+ 28338+#define himci_readl(addr) ({unsigned int reg = readl(IOMEM((uintptr_t)addr)); \ 28339+ himci_trace(1, "readl(0x%04X) = 0x%08X", (unsigned int)(uintptr_t)addr, reg); \ 28340+ reg; }) 28341+ 28342+#define himci_writel(v, addr) do { writel(v, IOMEM((uintptr_t)addr)); \ 28343+ himci_trace(1, "writel(0x%04X) = 0x%08X", (unsigned int)(uintptr_t)addr, \ 28344+ (unsigned int)(uintptr_t)(v)); \ 28345+} while (0) 28346+ 28347+struct himci_des { 28348+ unsigned long idmac_des_ctrl; 28349+ unsigned long idmac_des_buf_size; 28350+ unsigned long idmac_des_buf_addr; 28351+ unsigned long idmac_des_next_addr; 28352+}; 28353+ 28354+struct card_info { 28355+ unsigned int card_type; 28356+ unsigned char timing; 28357+ unsigned char card_connect; 28358+#define CARD_CONNECT 1 28359+#define CARD_DISCONNECT 0 28360+ unsigned int card_support_clock; /* clock rate */ 28361+ unsigned int card_state; /* (our) card state */ 28362+ unsigned int sd_bus_speed; 28363+ unsigned int ssr[16]; 28364+}; 28365+ 28366+struct himci_host { 28367+ struct mmc_host *mmc; 28368+ struct platform_device *pdev; 28369+ spinlock_t lock; 28370+ struct mmc_request *mrq; 28371+ struct mmc_command *cmd; 28372+ struct mmc_data *data; 28373+ void __iomem *base; 28374+ struct scatterlist *dma_sg; 28375+ unsigned int dma_sg_num; 28376+ unsigned int dma_dir; 28377+ dma_addr_t dma_paddr; 28378+ unsigned int *dma_vaddr; 28379+ struct timer_list timer; 28380+ unsigned int irq; 28381+ unsigned int irq_status; 28382+ unsigned int is_tuning; 28383+ wait_queue_head_t intr_wait; 28384+#define HIMCI_PEND_DTO_B (0) 28385+#define HIMCI_PEND_DTO_M (1 << HIMCI_PEND_DTO_B) 28386+ unsigned long pending_events; 28387+ unsigned int power_status; 28388+ unsigned int card_rca; 28389+ unsigned int card_status; 28390+ unsigned int devid; 28391+ unsigned int hclk; 28392+ unsigned int cclk; 28393+ struct clk *clk; 28394+ struct reset_control *crg_rst; 28395+ unsigned int port; 28396+ unsigned int error_count; 28397+ unsigned int data_error_count; 28398+ struct card_info c_info; 28399+}; 28400+ 28401+union cmd_arg_u { 28402+ unsigned int cmd_arg; 28403+ struct cmd_bits_arg { 28404+ unsigned int cmd_index : 6; 28405+ unsigned int response_expect : 1; 28406+ unsigned int response_length : 1; 28407+ unsigned int check_response_crc : 1; 28408+ unsigned int data_transfer_expected : 1; 28409+ unsigned int read_write : 1; 28410+ unsigned int transfer_mode : 1; 28411+ unsigned int send_auto_stop : 1; 28412+ unsigned int wait_prvdata_complete : 1; 28413+ unsigned int stop_abort_cmd : 1; 28414+ unsigned int send_initialization : 1; 28415+ unsigned int card_number : 5; 28416+ unsigned int update_clk_reg_only : 1; /* bit 21 */ 28417+ unsigned int read_ceata_device : 1; 28418+ unsigned int ccs_expected : 1; 28419+ unsigned int enable_boot : 1; 28420+ unsigned int expect_boot_ack : 1; 28421+ unsigned int disable_boot : 1; 28422+ unsigned int boot_mode : 1; 28423+ unsigned int volt_switch : 1; 28424+ unsigned int use_hold_reg : 1; 28425+ unsigned int reserved : 1; 28426+ unsigned int start_cmd : 1; /* HSB */ 28427+ } bits; 28428+}; 28429+ 28430+struct mmc_host *get_mmchost(int hostid); 28431+#endif 28432diff --git a/drivers/mmc/host/himci/himci_hi3516dv300.c b/drivers/mmc/host/himci/himci_hi3516dv300.c 28433new file mode 100644 28434index 000000000..bb312d601 28435--- /dev/null 28436+++ b/drivers/mmc/host/himci/himci_hi3516dv300.c 28437@@ -0,0 +1,160 @@ 28438+/* 28439+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 28440+ * 28441+ * This program is free software; you can redistribute it and/or modify it 28442+ * under the terms of the GNU General Public License as published by the 28443+ * Free Software Foundation; either version 2 of the License, or (at your 28444+ * option) any later version. 28445+ * 28446+ * This program is distributed in the hope that it will be useful, 28447+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 28448+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28449+ * GNU General Public License for more details. 28450+ * 28451+ * You should have received a copy of the GNU General Public License 28452+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 28453+ * 28454+ */ 28455+#define MMC_CRG_MIN 25000000 28456+ 28457+#define TUNING_START_PHASE 0 28458+#define TUNING_END_PHASE 7 28459+#define HIMCI_PHASE_SCALE 8 28460+#define DRV_PHASE_DFLT (0x4<<23) 28461+#define SMPL_PHASE_DFLT (0x0<<16) 28462+ 28463+/* eMMC pad ctrl reg */ 28464+#define REG_CTRL_EMMC_START (0x10ff0000 + 0x0) 28465+/* sdio0 pad ctrl reg */ 28466+#define REG_CTRL_SDIO0_START (0x10ff0000 + 0x24) 28467+/* sdio1 pad ctrl reg */ 28468+#define REG_CTRL_SDIO1_START (0x112f0000 + 0x8) 28469+ 28470+static unsigned int pad_ctrl_start[] = {REG_CTRL_EMMC_START, REG_CTRL_SDIO0_START, REG_CTRL_SDIO1_START}; 28471+ 28472+/* clk cmd data0 data1 data2 data3 */ 28473+static unsigned int emmc_hs200_drv[] = {0x2b0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0}; 28474+static unsigned int emmc_hs_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0}; 28475+static unsigned int emmc_ds_drv[] = {0x6b0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0}; 28476+static unsigned int emmc_ds_400k_drv[] = {0x6c0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0}; 28477+ 28478+static unsigned int sdio0_sdr104_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0}; 28479+static unsigned int sdio0_sdr50_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0}; 28480+static unsigned int sdio0_sdr25_drv[] = {0x6b0, 0x5d0, 0x5d0, 0x5d0, 0x5d0, 0x5d0}; 28481+static unsigned int sdio0_sdr12_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0}; 28482+static unsigned int sdio0_hs_drv[] = {0x6d0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0}; 28483+static unsigned int sdio0_ds_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0}; 28484+ 28485+static unsigned int sdio1_sdr104_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0}; 28486+static unsigned int sdio1_sdr50_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0}; 28487+static unsigned int sdio1_sdr25_drv[] = {0x6b0, 0x5d0, 0x5d0, 0x5d0, 0x5d0, 0x5d0}; 28488+static unsigned int sdio1_sdr12_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0}; 28489+static unsigned int sdio1_hs_drv[] = {0x6d0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0}; 28490+static unsigned int sdio1_ds_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0}; 28491+ 28492+static void himci_set_drv_cap(struct himci_host *host, unsigned int vdd_180) 28493+{ 28494+ struct mmc_host *mmc = host->mmc; 28495+ struct mmc_ios *ios = &(mmc->ios); 28496+ unsigned int devid = host->devid; 28497+ unsigned char timing = ios->timing; 28498+ unsigned int i, j, start; 28499+ unsigned int *pin_drv_cap = NULL; 28500+ 28501+ if (devid == 0) { 28502+ if (timing == MMC_TIMING_MMC_HS200) 28503+ pin_drv_cap = emmc_hs200_drv; 28504+ else if (timing == MMC_TIMING_MMC_HS) 28505+ pin_drv_cap = emmc_hs_drv; 28506+ else { 28507+ if (ios->clock == 400000) /* 400K */ 28508+ pin_drv_cap = emmc_ds_400k_drv; 28509+ else 28510+ pin_drv_cap = emmc_ds_drv; 28511+ } 28512+ } else if (devid == 1) { 28513+ if (timing == MMC_TIMING_UHS_SDR104) 28514+ pin_drv_cap = sdio0_sdr104_drv; 28515+ else if (timing == MMC_TIMING_UHS_SDR50) 28516+ pin_drv_cap = sdio0_sdr50_drv; 28517+ else if (timing == MMC_TIMING_UHS_SDR25) 28518+ pin_drv_cap = sdio0_sdr25_drv; 28519+ else if (timing == MMC_TIMING_UHS_SDR12) 28520+ pin_drv_cap = sdio0_sdr12_drv; 28521+ else if (timing == MMC_TIMING_SD_HS) 28522+ pin_drv_cap = sdio0_hs_drv; 28523+ else 28524+ pin_drv_cap = sdio0_ds_drv; 28525+ } else { 28526+ if (timing == MMC_TIMING_UHS_SDR104) 28527+ pin_drv_cap = sdio1_sdr104_drv; 28528+ else if (timing == MMC_TIMING_UHS_SDR50) 28529+ pin_drv_cap = sdio1_sdr50_drv; 28530+ else if (timing == MMC_TIMING_UHS_SDR25) 28531+ pin_drv_cap = sdio1_sdr25_drv; 28532+ else if (timing == MMC_TIMING_UHS_SDR12) 28533+ pin_drv_cap = sdio1_sdr12_drv; 28534+ else if (timing == MMC_TIMING_SD_HS) 28535+ pin_drv_cap = sdio1_hs_drv; 28536+ else 28537+ pin_drv_cap = sdio1_ds_drv; 28538+ } 28539+ 28540+ start = (unsigned int)(long)ioremap((resource_size_t)pad_ctrl_start[devid], 28541+ (size_t)0x1000); 28542+ for (i = start, j = 0; j < 6; i = i + 4, j++) { 28543+ unsigned int reg = himci_readl(i); 28544+ /* 28545+ * [10]:SR 28546+ * [9]:internel pull down 28547+ * [8]:internel pull up 28548+ * [7:4]: 28549+ * */ 28550+ reg = reg & (~(0x7f0)); 28551+ reg |= pin_drv_cap[j]; 28552+ himci_writel(reg, i); 28553+ } 28554+ iounmap((void *)(long)start); 28555+} 28556+ 28557+#define DRV_PHASE_180 (0x4<<23) 28558+#define DRV_PHASE_135 (0x3<<23) 28559+#define DRV_PHASE_90 (0x2<<23) 28560+ 28561+#define SMP_PHASE_45 (0x1<<16) 28562+#define SMP_PHASE_0 (0x0<<16) 28563+ 28564+static void himci_set_default_phase(struct himci_host *host) 28565+{ 28566+ struct mmc_host *mmc = host->mmc; 28567+ struct mmc_ios *ios = &(mmc->ios); 28568+ unsigned int devid = host->devid; 28569+ unsigned char timing = ios->timing; 28570+ unsigned int phase_cfg, reg_value; 28571+ if (devid == 0) { 28572+ if (timing == MMC_TIMING_MMC_HS200) 28573+ phase_cfg = DRV_PHASE_135 | SMP_PHASE_0; 28574+ else if (timing == MMC_TIMING_MMC_HS) 28575+ phase_cfg = DRV_PHASE_180 | SMP_PHASE_45; 28576+ else { 28577+ phase_cfg = DRV_PHASE_180 | SMP_PHASE_0; 28578+ } 28579+ } else { 28580+ if (timing == MMC_TIMING_UHS_SDR104) 28581+ phase_cfg = DRV_PHASE_135 | SMP_PHASE_0; 28582+ else if (timing == MMC_TIMING_UHS_SDR50) 28583+ phase_cfg = DRV_PHASE_90 | SMP_PHASE_0; 28584+ else if (timing == MMC_TIMING_UHS_SDR25) 28585+ phase_cfg = DRV_PHASE_180 | SMP_PHASE_45; 28586+ else if (timing == MMC_TIMING_SD_HS) 28587+ phase_cfg = DRV_PHASE_135 | SMP_PHASE_45; 28588+ else 28589+ phase_cfg = DRV_PHASE_180 | SMP_PHASE_0; 28590+ } 28591+ 28592+ reg_value = himci_readl(host->base + MCI_UHS_REG_EXT); 28593+ reg_value &= ~CLK_SMPL_PHS_MASK; 28594+ reg_value &= ~CLK_DRV_PHS_MASK; 28595+ reg_value |= phase_cfg; 28596+ himci_writel(reg_value, host->base + MCI_UHS_REG_EXT); 28597+} 28598diff --git a/drivers/mmc/host/himci/himci_proc.c b/drivers/mmc/host/himci/himci_proc.c 28599new file mode 100644 28600index 000000000..ac339c4da 28601--- /dev/null 28602+++ b/drivers/mmc/host/himci/himci_proc.c 28603@@ -0,0 +1,246 @@ 28604+/* 28605+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 28606+ * 28607+ * This program is free software; you can redistribute it and/or modify 28608+ * it under the terms of the GNU General Public License as published by 28609+ * the Free Software Foundation; either version 2 of the License, or 28610+ * (at your option) any later version. 28611+ * 28612+ * This program is distributed in the hope that it will be useful, 28613+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 28614+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28615+ * GNU General Public License for more details. 28616+ * 28617+ * You should have received a copy of the GNU General Public License 28618+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 28619+ */ 28620+ 28621+#include <linux/proc_fs.h> 28622+#include <linux/seq_file.h> 28623+#include <linux/device.h> 28624+#include <linux/io.h> 28625+#include <linux/platform_device.h> 28626+ 28627+#include <linux/mmc/card.h> 28628+ 28629+#include <linux/export.h> 28630+#include <linux/mmc/host.h> 28631+#include "himci.h" 28632+#include "himci_reg.h" 28633+#include "himci_proc.h" 28634+ 28635+#define MCI_PARENT "mci" 28636+#define MCI_STATS_PROC "mci_info" 28637+#define MAX_CLOCK_SCALE (4) 28638+#define UNSTUFF_BITS(resp, start, size) \ 28639+ ({ \ 28640+ const int __size = size; \ 28641+ const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ 28642+ const int __off = 3 - ((start) / 32); \ 28643+ const int __shft = (start) & 31; \ 28644+ u32 __res; \ 28645+ \ 28646+ __res = resp[__off] >> __shft; \ 28647+ if (__size + __shft > 32) \ 28648+ __res |= resp[__off-1] << ((32 - __shft) % 32); \ 28649+ __res & __mask; \ 28650+ }) 28651+ 28652+extern unsigned int slot_index; 28653+static struct proc_dir_entry *proc_mci_dir; 28654+ 28655+static char *card_type[MAX_CARD_TYPE + 1] = { 28656+ "MMC card", 28657+ "SD card", 28658+ "SDIO card", 28659+ "SD combo (IO+mem) card", 28660+ "unknown" 28661+}; 28662+static char *clock_unit[MAX_CLOCK_SCALE] = { 28663+ "Hz", 28664+ "KHz", 28665+ "MHz", 28666+ "GHz" 28667+}; 28668+ 28669+static char *mci_get_card_type(unsigned int sd_type) 28670+{ 28671+ if (MAX_CARD_TYPE <= sd_type) 28672+ return card_type[MAX_CARD_TYPE]; 28673+ else 28674+ return card_type[sd_type]; 28675+} 28676+ 28677+static unsigned int analyze_clock_scale(unsigned int clock, 28678+ unsigned int *clock_val) 28679+{ 28680+ unsigned int scale = 0; 28681+ unsigned int tmp = clock; 28682+ 28683+ while (1) { 28684+ tmp = tmp / 1000; 28685+ if (0 < tmp) { 28686+ *clock_val = tmp; 28687+ scale++; 28688+ } else { 28689+ break; 28690+ } 28691+ } 28692+ return scale; 28693+} 28694+ 28695+static inline int is_card_uhs(unsigned char timing) 28696+{ 28697+ return timing >= MMC_TIMING_UHS_SDR12 && 28698+ timing <= MMC_TIMING_UHS_DDR50; 28699+}; 28700+ 28701+static inline int is_card_hs(unsigned char timing) 28702+{ 28703+ return timing == MMC_TIMING_SD_HS || timing == MMC_TIMING_MMC_HS; 28704+}; 28705+ 28706+static void mci_stats_seq_printout(struct seq_file *s) 28707+{ 28708+ unsigned int index_mci; 28709+ unsigned int clock; 28710+ unsigned int clock_scale; 28711+ unsigned int clock_value = 0; 28712+ const char *type = NULL; 28713+ unsigned int present; 28714+ struct himci_host *host = NULL; 28715+ struct card_info *c_info = NULL; 28716+ const char *uhs_bus_speed_mode = ""; 28717+ u32 speed_class, grade_speed_uhs; 28718+ static const char *const uhs_speeds[] = { 28719+ [UHS_SDR12_BUS_SPEED] = "SDR12 ", 28720+ [UHS_SDR25_BUS_SPEED] = "SDR25 ", 28721+ [UHS_SDR50_BUS_SPEED] = "SDR50 ", 28722+ [UHS_SDR104_BUS_SPEED] = "SDR104 ", 28723+ [UHS_DDR50_BUS_SPEED] = "DDR50 ", 28724+ }; 28725+ 28726+ for (index_mci = 0; index_mci < HIMCI_SLOT_NUM; index_mci++) { 28727+ host = mci_host[index_mci]; 28728+ if (!host || !host->mmc) { 28729+ seq_printf(s, "MCI%d: invalid\n", index_mci); 28730+ continue; 28731+ } else { 28732+ seq_printf(s, "MCI%d", index_mci); 28733+ } 28734+ c_info = &host->c_info; 28735+ 28736+ present = host->mmc->ops->get_cd(host->mmc); 28737+ if (present) { 28738+ seq_puts(s, ": pluged"); 28739+ } else { 28740+ seq_puts(s, ": unplugged"); 28741+ } 28742+ 28743+ if (CARD_CONNECT != c_info->card_connect) { 28744+ if (host->mmc->card_status == MMC_CARD_INIT_FAIL) 28745+ seq_puts(s, "_init_failed\n"); 28746+ else 28747+ seq_puts(s, "_disconnected\n"); 28748+ } else { 28749+ seq_puts(s, "_connected\n"); 28750+ seq_printf(s, 28751+ "\tType: %s", 28752+ mci_get_card_type(c_info->card_type) 28753+ ); 28754+ 28755+ if (c_info->card_state & MMC_STATE_BLOCKADDR) { 28756+ if (c_info->card_state & MMC_CARD_SDXC) 28757+ type = "SDXC"; 28758+ else 28759+ type = "SDHC"; 28760+ seq_printf(s, "(%s)\n", type); 28761+ } 28762+ 28763+ if (is_card_uhs(c_info->timing) && 28764+ c_info->sd_bus_speed < ARRAY_SIZE(uhs_speeds)) 28765+ uhs_bus_speed_mode = uhs_speeds[c_info->sd_bus_speed]; 28766+ 28767+ seq_printf(s, "\tMode: %s%s%s%s\n", 28768+ is_card_uhs(c_info->timing) ? "UHS " : 28769+ (is_card_hs(c_info->timing) ? "HS " : ""), 28770+ c_info->timing == MMC_TIMING_MMC_HS400 ? "HS400 " : 28771+ (c_info->timing == MMC_TIMING_MMC_HS200 ? "HS200 " : ""), 28772+ c_info->timing == MMC_TIMING_MMC_DDR52 ? "DDR " : "", 28773+ uhs_bus_speed_mode); 28774+ 28775+ speed_class = UNSTUFF_BITS(c_info->ssr, 440 - 384, 8); 28776+ grade_speed_uhs = UNSTUFF_BITS(c_info->ssr, 396 - 384, 4); 28777+ seq_printf(s, "\tSpeed Class: Class %s\n", 28778+ (0x00 == speed_class) ? "0" : 28779+ (0x01 == speed_class) ? "2" : 28780+ (0x02 == speed_class) ? "4" : 28781+ (0x03 == speed_class) ? "6" : 28782+ (0x04 == speed_class) ? "10" : 28783+ "Reserved"); 28784+ seq_printf(s, "\tUhs Speed Grade: %s\n", 28785+ (0x00 == grade_speed_uhs) ? 28786+ "Less than 10MB/sec(0h)" : 28787+ (0x01 == grade_speed_uhs) ? 28788+ "10MB/sec and above(1h)" : 28789+ "Reserved"); 28790+ 28791+ clock = host->hclk; 28792+ clock_scale = analyze_clock_scale(clock, &clock_value); 28793+ seq_printf(s, "\tHost work clock: %d%s\n", 28794+ clock_value, clock_unit[clock_scale]); 28795+ 28796+ clock = c_info->card_support_clock; 28797+ clock_scale = analyze_clock_scale(clock, &clock_value); 28798+ seq_printf(s, "\tCard support clock: %d%s\n", 28799+ clock_value, clock_unit[clock_scale]); 28800+ 28801+ clock = host->cclk; 28802+ clock_scale = analyze_clock_scale(clock, &clock_value); 28803+ seq_printf(s, "\tCard work clock: %d%s\n", 28804+ clock_value, clock_unit[clock_scale]); 28805+ /* add card read/write error count */ 28806+ seq_printf(s, "\tCard error count: %d\n", 28807+ host->error_count); 28808+ seq_printf(s, "\tCard data error count: %d\n", 28809+ host->data_error_count); 28810+ } 28811+ } 28812+} 28813+ 28814+/* define parameters where showed in proc file */ 28815+static int mci_stats_seq_show(struct seq_file *s, void *v) 28816+{ 28817+ mci_stats_seq_printout(s); 28818+ return 0; 28819+} 28820+ 28821+int mci_proc_init(void) 28822+{ 28823+ struct proc_dir_entry *proc_stats_entry = NULL; 28824+ proc_mci_dir = proc_mkdir(MCI_PARENT, NULL); 28825+ if (!proc_mci_dir) { 28826+ pr_err("%s: failed to create proc file %s\n", 28827+ __func__, MCI_PARENT); 28828+ return 1; 28829+ } 28830+ proc_stats_entry = proc_create_single_data(MCI_STATS_PROC, 0, 28831+ proc_mci_dir, mci_stats_seq_show, NULL); 28832+ if (!proc_stats_entry) { 28833+ pr_err("%s: failed to create proc file %s\n", 28834+ __func__, MCI_STATS_PROC); 28835+ return 1; 28836+ } 28837+ return 0; 28838+} 28839+ 28840+int mci_proc_shutdown(void) 28841+{ 28842+ if (proc_mci_dir) { 28843+ remove_proc_entry(MCI_STATS_PROC, proc_mci_dir); 28844+ remove_proc_entry(MCI_PARENT, NULL); 28845+ proc_mci_dir = NULL; 28846+ } 28847+ 28848+ return 0; 28849+} 28850diff --git a/drivers/mmc/host/himci/himci_proc.h b/drivers/mmc/host/himci/himci_proc.h 28851new file mode 100644 28852index 000000000..e6ea9a137 28853--- /dev/null 28854+++ b/drivers/mmc/host/himci/himci_proc.h 28855@@ -0,0 +1,36 @@ 28856+/* 28857+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 28858+ * 28859+ * This program is free software; you can redistribute it and/or modify 28860+ * it under the terms of the GNU General Public License as published by 28861+ * the Free Software Foundation; either version 2 of the License, or 28862+ * (at your option) any later version. 28863+ * 28864+ * This program is distributed in the hope that it will be useful, 28865+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 28866+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28867+ * GNU General Public License for more details. 28868+ * 28869+ * You should have received a copy of the GNU General Public License 28870+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 28871+ */ 28872+ 28873+/* 28874+ * MCI connection table manager 28875+ */ 28876+#ifndef __MCI_PROC_H__ 28877+#define __MCI_PROC_H__ 28878+ 28879+#include <linux/proc_fs.h> 28880+ 28881+#define MAX_CARD_TYPE 4 28882+#define MAX_SPEED_MODE 5 28883+#define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing copy from core/card.h */ 28884+#define MMC_CARD_SDXC (1<<3) /* card is SDXC copy from core/card.h */ 28885+#define HIMCI_SLOT_NUM 3 28886+ 28887+extern struct himci_host *mci_host[HIMCI_SLOT_NUM]; 28888+int mci_proc_init(void); 28889+int mci_proc_shutdown(void); 28890+ 28891+#endif /* __MCI_PROC_H__ */ 28892diff --git a/drivers/mmc/host/himci/himci_reg.h b/drivers/mmc/host/himci/himci_reg.h 28893new file mode 100644 28894index 000000000..d1d8f9f9d 28895--- /dev/null 28896+++ b/drivers/mmc/host/himci/himci_reg.h 28897@@ -0,0 +1,241 @@ 28898+/* 28899+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 28900+ * 28901+ * This program is free software; you can redistribute it and/or modify 28902+ * it under the terms of the GNU General Public License as published by 28903+ * the Free Software Foundation; either version 2 of the License, or 28904+ * (at your option) any later version. 28905+ * 28906+ * This program is distributed in the hope that it will be useful, 28907+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 28908+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28909+ * GNU General Public License for more details. 28910+ * 28911+ * You should have received a copy of the GNU General Public License 28912+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 28913+ */ 28914+ 28915+#ifndef _HI_MCI_REG_H_ 28916+#define _HI_MCI_REG_H_ 28917+ 28918+#define HI_MCI_IO_SIZE 0x1000 28919+ 28920+#define MCI_CTRL 0x00 28921+#define MCI_PWREN 0x04 28922+#define MCI_CLKDIV 0x08 28923+#define MCI_CLKSRC 0x0C 28924+#define MCI_CLKENA 0x10 28925+#define MCI_TIMEOUT 0x14 28926+#define MCI_CTYPE 0x18 28927+#define MCI_BLKSIZ 0x1c 28928+#define MCI_BYTCNT 0x20 28929+#define MCI_INTMASK 0x24 28930+#define MCI_CMDARG 0x28 28931+#define MCI_CMD 0x2C 28932+#define MCI_RESP0 0x30 28933+#define MCI_RESP1 0x34 28934+#define MCI_RESP2 0x38 28935+#define MCI_RESP3 0x3C 28936+#define MCI_MINTSTS 0x40 28937+#define MCI_RINTSTS 0x44 28938+#define MCI_STATUS 0x48 28939+#define MCI_FIFOTH 0x4C 28940+#define MCI_CDETECT 0x50 28941+#define MCI_WRTPRT 0x54 28942+#define MCI_GPIO 0x58 28943+#define MCI_TCBCNT 0x5C 28944+#define MCI_TBBCNT 0x60 28945+#define MCI_DEBNCE 0x64 28946+#define MCI_USRID 0x68 28947+#define MCI_VERID 0x6C 28948+#define MCI_HCON 0x70 28949+#define MCI_UHS_REG 0x74 28950+#define MCI_RESET_N 0x78 28951+#define MCI_BMOD 0x80 28952+#define MCI_DBADDR 0x88 28953+#define MCI_IDSTS 0x8C 28954+#define MCI_IDINTEN 0x90 28955+#define MCI_DSCADDR 0x94 28956+#define MCI_BUFADDR 0x98 28957+#define MCI_CARDTHRCTL 0x100 28958+#define MCI_UHS_REG_EXT 0x108 28959+ 28960+#define MCI_TUNING_CTRL 0x118 28961+ 28962+/* MCI_IDSTS(0x8c) detals */ 28963+#define CMD_LOCK_ERR (0x1 << 29) 28964+#define OWNBIT_ERR (0x1 << 28) 28965+#define QUEUE_OVERFLOW (0x1 << 27) 28966+#define RESP_CHECK_ERR (0x1 << 26) 28967+#define PACKET_INT (0x1 << 25) 28968+#define PACKET_TO_INT (0x1 << 24) 28969+#define AUTO_STOP_ERR (0x1 << 23) 28970+#define QUEUE_FULL (0x1 << 22) 28971+#define QUEUE_EMPTY (0x1 << 21) 28972+#define ADMA3_FSM_SHIFT (17) 28973+#define FSM_SHIFT (13) 28974+#define CES (0x1 << 5) 28975+#define DU (0x1 << 4) 28976+#define FBE (0x1 << 2) 28977+ 28978+/* MCI_BMOD(0x80) details */ 28979+#define BMOD_SWR (0x1 << 0) 28980+#define BURST_INCR (0x1 << 1) 28981+#define BMOD_DMA_EN (0x1 << 7) 28982+#define BURST_8 (0x2 << 8) 28983+#define BURST_16 (0x3 << 8) 28984+/* IDMAC DEST1 details */ 28985+#define DMA_BUFFER (0x2000) 28986+#define MAX_DMA_DES (20480) 28987+ 28988+/* IDMAC DEST0 details */ 28989+#define DMA_DES_OWN (1 << 31) 28990+#define DMA_DES_NEXT_DES (1 << 4) 28991+#define DMA_DES_FIRST_DES (1 << 3) 28992+#define DMA_DES_LAST_DES (1 << 2) 28993+ 28994+/* MCI_CTRL(0x00) details */ 28995+#define CTRL_RESET (1 << 0) 28996+#define FIFO_RESET (1 << 1) 28997+#define DMA_RESET (1 << 2) 28998+#define INTR_EN (1 << 4) 28999+#define USE_INTERNAL_DMA (1 << 25) 29000+ 29001+/* MCI_CLKENA(0x10) details */ 29002+#define CCLK_ENABLE (0x1 << 0) 29003+#define CCLK_LOW_POWER (0x1 << 16) 29004+ 29005+/* MCI_TIMEOUT(0x14) details: */ 29006+/* bit 31-8: data read timeout param */ 29007+#define DATA_TIMEOUT (0xffffff << 8) 29008+/* bit 7-0: response timeout param */ 29009+#define RESPONSE_TIMEOUT 0xff 29010+ 29011+/* MCI_CTYPE(0x18) details */ 29012+#define CARD_WIDTH_0 (0x1 << 16) 29013+#define CARD_WIDTH_1 (0x1 << 0) 29014+ 29015+/* MCI_INTMASK(0x24) details: 29016+ bit 16-1: mask MMC host controller each interrupt 29017+*/ 29018+#define ALL_INT_MASK 0x1ffff 29019+#define DTO_INT_MASK (0x1 << 3) 29020+#define SDIO_INT_MASK (0x1 << 16) 29021+ 29022+/* MCI_UHS_REG_EXT(0x108) details */ 29023+/* bit[19:16] sampling phase */ 29024+#define CLK_SMPL_PHS_SHIFT (16) 29025+#define CLK_SMPL_PHS_MASK (0x7 << 16) 29026+ 29027+/* bit[26:23] drv phase */ 29028+#define CLK_DRV_PHS_SHIFT (23) 29029+#define CLK_DRV_PHS_MASK (0x7 << 23) 29030+#define DEFAULT_PHASE 0x1050000 29031+ 29032+/* MCI_CMD(0x2c) details: 29033+ bit 31: cmd execute or load start param of interface clk bit 29034+*/ 29035+#define START_CMD (0x1<<31) 29036+ 29037+/* MCI_INTSTS(0x44) details */ 29038+ 29039+/* bit 16: sdio interrupt status */ 29040+#define SDIO_INT_STATUS (0x1 << 16) 29041+ 29042+/* bit 15: end-bit error (read)/write no CRC interrupt status */ 29043+#define EBE_INT_STATUS (0x1 << 15) 29044+ 29045+/* bit 14: auto command done interrupt status */ 29046+#define ACD_INT_STATUS (0x1 << 14) 29047+ 29048+/* bit 13: start bit error interrupt status */ 29049+#define SBE_INT_STATUS (0x1 << 13) 29050+ 29051+/* bit 12: hardware locked write error interrupt status */ 29052+#define HLE_INT_STATUS (0x1 << 12) 29053+ 29054+/* bit 11: FIFO underrun/overrun error interrupt status */ 29055+#define FRUN_INT_STATUS (0x1 << 11) 29056+ 29057+/* bit 10: data starvation-by-host timeout interrupt status */ 29058+#define HTO_INT_STATUS (0x1 << 10) 29059+ 29060+/* bit 10: volt_switch to 1.8v for sdxc */ 29061+#define VOLT_SWITCH_INT_STATUS (0x1 << 10) 29062+ 29063+/* bit 9: data read timeout interrupt status */ 29064+#define DRTO_INT_STATUS (0x1 << 9) 29065+ 29066+/* bit 8: response timeout interrupt status */ 29067+#define RTO_INT_STATUS (0x1 << 8) 29068+ 29069+/* bit 7: data CRC error interrupt status */ 29070+#define DCRC_INT_STATUS (0x1 << 7) 29071+ 29072+/* bit 6: response CRC error interrupt status */ 29073+#define RCRC_INT_STATUS (0x1<<6) 29074+ 29075+/* bit 5: receive FIFO data request interrupt status */ 29076+#define RXDR_INT_STATUS (0x1<<5) 29077+ 29078+/* bit 4: transmit FIFO data request interrupt status */ 29079+#define TXDR_INT_STATUS (0x1<<4) 29080+ 29081+/* bit 3: data transfer Over interrupt status */ 29082+#define DTO_INT_STATUS (0x1<<3) 29083+ 29084+/* bit 2: command done interrupt status */ 29085+#define CD_INT_STATUS (0x1<<2) 29086+ 29087+/* bit 1: response error interrupt status */ 29088+#define RE_INT_STATUS (0x1<<1) 29089+ 29090+#define CMD_INT_MASK (RTO_INT_STATUS | RCRC_INT_STATUS | RE_INT_STATUS) 29091+#define DATA_INT_MASK (DTO_INT_STATUS | DCRC_INT_STATUS \ 29092+ | SBE_INT_STATUS | EBE_INT_STATUS) 29093+ 29094+ 29095+/* MCI_RINTSTS(0x44) details:bit 16-1: clear 29096+ MMC host controller each interrupt but 29097+ hardware locked write error interrupt 29098+*/ 29099+#define ALL_INT_CLR 0x1efff 29100+#define ALL_SD_INT_CLR 0xefff 29101+ 29102+/* MCI_STATUS(0x48) details */ 29103+#define DATA_BUSY (0x1<<9) 29104+ 29105+/* MCI_FIFOTH(0x4c) details */ 29106+#define BURST_SIZE (0x6<<28) 29107+#define RX_WMARK (0x7f<<16) 29108+#define TX_WMARK (0x80) 29109+ 29110+/* MCI_CDETECT(0x50) details */ 29111+#define HIMCI_CARD0 (0x1<<0) 29112+ 29113+/* MCI_GPIO(0x58) details */ 29114+#define DTO_FIX_BYPASS (0x1<<23) 29115+#define CMD_OUT_EN_FIX_BYPASS (0x1<<8) 29116+ 29117+/* MCI_UHS_REG(0x74) details */ 29118+#define HI_SDXC_CTRL_VDD_180 (0x1<<0) 29119+#define HI_SDXC_CTRL_DDR_REG (0x1<<16) 29120+ 29121+/* MCI_RESET_N(0x78) details */ 29122+#define MMC_RST_N (0x1<<0) 29123+ 29124+/* MCI_CARDTHRCTL(0x100) details */ 29125+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 29126+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 29127+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) 29128+#define RW_THRESHOLD_SIZE (0x2000005) 29129+#else 29130+#define RW_THRESHOLD_SIZE (0x2000001) 29131+#endif 29132+ 29133+/* MCI_TUNING_CTRL(0x118) details */ 29134+#define HW_TUNING_EN (0x1 << 0) 29135+#define EDGE_CTRL (0x1 << 1) 29136+#define FOUND_EDGE (0x1 << 5) 29137+ 29138+#endif 29139diff --git a/drivers/mmc/host/mci_proc.c b/drivers/mmc/host/mci_proc.c 29140new file mode 100644 29141index 000000000..9465ad3fe 29142--- /dev/null 29143+++ b/drivers/mmc/host/mci_proc.c 29144@@ -0,0 +1,301 @@ 29145+/* 29146+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2016-2020. All rights reserved. 29147+ * Description: mci driver 29148+ * 29149+ * This program is free software; you can redistribute it and/or modify 29150+ * it under the terms of the GNU General Public License as published by 29151+ * the Free Software Foundation; either version 2 of the License, or 29152+ * (at your option) any later version. 29153+ * 29154+ * This program is distributed in the hope that it will be useful, 29155+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 29156+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29157+ * GNU General Public License for more details. 29158+ * 29159+ * You should have received a copy of the GNU General Public License 29160+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 29161+ */ 29162+ 29163+#include <linux/proc_fs.h> 29164+#include <linux/seq_file.h> 29165+#include <linux/device.h> 29166+#include <linux/io.h> 29167+#include <linux/platform_device.h> 29168+#include <linux/mmc/card.h> 29169+#include <linux/mmc/host.h> 29170+#include "../core/card.h" 29171+#include "sdhci.h" 29172+#include "mci_proc.h" 29173+ 29174+#define MCI_PARENT "mci" 29175+#define MCI_STATS_PROC "mci_info" 29176+#define MAX_CLOCK_SCALE 4 29177+ 29178+unsigned int slot_index; 29179+struct mmc_host *mci_host[MCI_SLOT_NUM] = {NULL}; 29180+static struct proc_dir_entry *proc_mci_dir; 29181+ 29182+static char *card_type[MAX_CARD_TYPE + 1] = { 29183+ "MMC card", 29184+ "SD card", 29185+ "SDIO card", 29186+ "SD combo (IO+mem) card", 29187+ "unknown" 29188+}; 29189+static char *clock_unit[MAX_CLOCK_SCALE] = { 29190+ "Hz", 29191+ "KHz", 29192+ "MHz", 29193+ "GHz" 29194+}; 29195+ 29196+#define BIT_WIDTH 32 29197+static unsigned int unstuff_bits(const u32 *resp, u32 start, u32 size) 29198+{ 29199+ const u32 mask = ((size < BIT_WIDTH) ? 1 << size : 0) - 1; 29200+ const int off = 0x3 - ((start) / BIT_WIDTH); 29201+ const int shft = (start) & 31; /* max shift value 31 */ 29202+ u32 res; 29203+ 29204+ res = resp[off] >> shft; 29205+ if (size + shft > BIT_WIDTH) 29206+ res |= resp[off - 1] << ((BIT_WIDTH - shft) % BIT_WIDTH); 29207+ res = res & mask; 29208+ 29209+ return res; 29210+} 29211+ 29212+static char *mci_get_card_type(unsigned int sd_type) 29213+{ 29214+ if (sd_type >= MAX_CARD_TYPE) 29215+ return card_type[MAX_CARD_TYPE]; 29216+ else 29217+ return card_type[sd_type]; 29218+} 29219+ 29220+static unsigned int analyze_clock_scale(unsigned int clock, 29221+ unsigned int *clock_val) 29222+{ 29223+ unsigned int scale = 0; 29224+ unsigned int tmp = clock; 29225+ 29226+ while (1) { 29227+ tmp = tmp / 1000; /* Cal freq by dividing 1000 */ 29228+ if (tmp > 0) { 29229+ *clock_val = tmp; 29230+ scale++; 29231+ } else { 29232+ break; 29233+ } 29234+ } 29235+ return scale; 29236+} 29237+ 29238+static inline int is_card_uhs(unsigned char timing) 29239+{ 29240+ return timing >= MMC_TIMING_UHS_SDR12 && 29241+ timing <= MMC_TIMING_UHS_DDR50; 29242+}; 29243+ 29244+static inline int is_card_hs(unsigned char timing) 29245+{ 29246+ return timing == MMC_TIMING_SD_HS || timing == MMC_TIMING_MMC_HS; 29247+}; 29248+ 29249+static void mci_stats_seq_printout(struct seq_file *s) 29250+{ 29251+ unsigned int index_mci; 29252+ unsigned int clock; 29253+ unsigned int clock_scale; 29254+ unsigned int clock_value = 0; 29255+ const char *type = NULL; 29256+ struct mmc_host *mmc = NULL; 29257+ const char *uhs_bus_speed_mode = ""; 29258+ static const char * const uhs_speeds[] = { 29259+ [UHS_SDR12_BUS_SPEED] = "SDR12 ", 29260+ [UHS_SDR25_BUS_SPEED] = "SDR25 ", 29261+ [UHS_SDR50_BUS_SPEED] = "SDR50 ", 29262+ [UHS_SDR104_BUS_SPEED] = "SDR104 ", 29263+ [UHS_DDR50_BUS_SPEED] = "DDR50 ", 29264+ }; 29265+ unsigned int speed_class, grade_speed_uhs; 29266+ unsigned int present; 29267+ struct card_info *info = NULL; 29268+ struct sdhci_host *host = NULL; 29269+ 29270+ for (index_mci = 0; index_mci < MCI_SLOT_NUM; index_mci++) { 29271+ mmc = mci_host[index_mci]; 29272+ if (mmc == NULL) { 29273+ seq_printf(s, "MCI%d: invalid\n", index_mci); 29274+ continue; 29275+ } else { 29276+ seq_printf(s, "MCI%d", index_mci); 29277+ } 29278+ 29279+ host = mmc_priv(mmc); 29280+ info = &host->c_info; 29281+ 29282+ present = host->mmc->ops->get_cd(host->mmc); 29283+ if (present) 29284+ seq_puts(s, ": pluged"); 29285+ else 29286+ seq_puts(s, ": unplugged"); 29287+ 29288+ if (info->card_connect != CARD_CONNECT) { 29289+ if (mmc->card_status == MMC_CARD_INIT_FAIL) 29290+ seq_puts(s, "_init_failed\n"); 29291+ else 29292+ seq_puts(s, "_disconnected\n"); 29293+ } else { 29294+ seq_puts(s, "_connected\n"); 29295+ 29296+ seq_printf(s, "\tType: %s", 29297+ mci_get_card_type(info->card_type)); 29298+ 29299+ if (info->card_state & MMC_STATE_BLOCKADDR) { 29300+ type = (info->card_state & MMC_CARD_SDXC) ? 29301+ "SDXC" : "SDHC"; 29302+ seq_printf(s, "(%s)\n", type); 29303+ } 29304+ 29305+ if (is_card_uhs(info->timing) && 29306+ info->sd_bus_speed < ARRAY_SIZE(uhs_speeds)) 29307+ uhs_bus_speed_mode = 29308+ uhs_speeds[info->sd_bus_speed]; 29309+ 29310+ seq_printf(s, "\tMode: %s %s\n", 29311+ is_card_uhs(info->timing) ? "UHS" : 29312+ is_card_hs(info->timing) ? "HS" : 29313+ (info->enhanced_strobe == true) ? "HS400ES" : 29314+ (info->timing == MMC_TIMING_MMC_HS400) ? "HS400" : 29315+ (info->timing == MMC_TIMING_MMC_HS200) ? "HS200" : 29316+ (info->timing == MMC_TIMING_MMC_DDR52) ? "DDR" : 29317+ "DS", uhs_bus_speed_mode); 29318+ 29319+ speed_class = unstuff_bits(info->ssr, 56, 8); /* 56 = 440 - 384 */ 29320+ grade_speed_uhs = unstuff_bits(info->ssr, 12, 4); /* 12 = 396 - 384 */ 29321+ seq_printf(s, "\tSpeed Class: Class %s\n", 29322+ (speed_class == 0x00) ? "0" : 29323+ (speed_class == 0x01) ? "2" : 29324+ (speed_class == 0x02) ? "4" : 29325+ (speed_class == 0x03) ? "6" : 29326+ (speed_class == 0x04) ? "10" : 29327+ "Reserved"); 29328+ seq_printf(s, "\tUhs Speed Grade: %s\n", 29329+ (grade_speed_uhs == 0x00) ? 29330+ "Less than 10MB/sec(0h)" : 29331+ (grade_speed_uhs == 0x01) ? 29332+ "10MB/sec and above(1h)" : 29333+ "Reserved"); 29334+ 29335+ clock = info->card_support_clock; 29336+ clock_scale = analyze_clock_scale(clock, &clock_value); 29337+ seq_printf(s, "\tHost work clock: %d%s\n", 29338+ clock_value, clock_unit[clock_scale]); 29339+ 29340+ clock = info->card_support_clock; 29341+ clock_scale = analyze_clock_scale(clock, &clock_value); 29342+ seq_printf(s, "\tCard support clock: %d%s\n", 29343+ clock_value, clock_unit[clock_scale]); 29344+ 29345+ clock = mmc->actual_clock; 29346+ clock_scale = analyze_clock_scale(clock, &clock_value); 29347+ seq_printf(s, "\tCard work clock: %d%s\n", 29348+ clock_value, clock_unit[clock_scale]); 29349+ 29350+ /* add card read/write error count */ 29351+ seq_printf(s, "\tCard error count: %d\n", 29352+ host->error_count); 29353+ } 29354+ } 29355+} 29356+ 29357+/* proc interface setup */ 29358+static void *mci_seq_start(struct seq_file *s, loff_t *pos) 29359+{ 29360+ /* counter is used to tracking multi proc interfaces 29361+ * We have only one interface so return zero 29362+ * pointer to start the sequence. 29363+ */ 29364+ static unsigned long counter; 29365+ 29366+ if (*pos == 0) 29367+ return &counter; 29368+ 29369+ return NULL; 29370+} 29371+ 29372+/* proc interface next */ 29373+static void *mci_seq_next(struct seq_file *s, void *v, loff_t *pos) 29374+{ 29375+ (*pos)++; 29376+ 29377+ return mci_seq_start(s, pos); 29378+} 29379+ 29380+/* define parameters where showed in proc file */ 29381+static int mci_stats_seq_show(struct seq_file *s, void *v) 29382+{ 29383+ mci_stats_seq_printout(s); 29384+ return 0; 29385+} 29386+ 29387+/* proc interface stop */ 29388+static void mci_seq_stop(struct seq_file *s, void *v) 29389+{ 29390+} 29391+ 29392+/* proc interface operation */ 29393+static const struct seq_operations mci_stats_seq_ops = { 29394+ .start = mci_seq_start, 29395+ .next = mci_seq_next, 29396+ .stop = mci_seq_stop, 29397+ .show = mci_stats_seq_show 29398+}; 29399+ 29400+/* proc file open */ 29401+static int mci_stats_proc_open(struct inode *inode, struct file *file) 29402+{ 29403+ return seq_open(file, &mci_stats_seq_ops); 29404+}; 29405+ 29406+/* proc file operation */ 29407+static const struct file_operations mci_stats_proc_ops = { 29408+ .owner = THIS_MODULE, 29409+ .open = mci_stats_proc_open, 29410+ .read = seq_read, 29411+ .release = seq_release 29412+}; 29413+ 29414+int mci_proc_init(void) 29415+{ 29416+ struct proc_dir_entry *proc_stats_entry = NULL; 29417+ 29418+ proc_mci_dir = proc_mkdir(MCI_PARENT, NULL); 29419+ if (proc_mci_dir == NULL) { 29420+ pr_err("%s: failed to create proc file %s\n", 29421+ __func__, MCI_PARENT); 29422+ return 1; 29423+ } 29424+ 29425+ proc_stats_entry = proc_create(MCI_STATS_PROC, 29426+ 0, proc_mci_dir, &mci_stats_proc_ops); 29427+ if (proc_stats_entry == NULL) { 29428+ pr_err("%s: failed to create proc file %s\n", 29429+ __func__, MCI_STATS_PROC); 29430+ return 1; 29431+ } 29432+ 29433+ return 0; 29434+} 29435+ 29436+int mci_proc_shutdown(void) 29437+{ 29438+ if (proc_mci_dir != NULL) { 29439+ remove_proc_entry(MCI_STATS_PROC, proc_mci_dir); 29440+ remove_proc_entry(MCI_PARENT, NULL); 29441+ proc_mci_dir = NULL; 29442+ } 29443+ 29444+ return 0; 29445+} 29446diff --git a/drivers/mmc/host/mci_proc.h b/drivers/mmc/host/mci_proc.h 29447new file mode 100644 29448index 000000000..459c5d767 29449--- /dev/null 29450+++ b/drivers/mmc/host/mci_proc.h 29451@@ -0,0 +1,50 @@ 29452+/* 29453+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2016-2020. All rights reserved. 29454+ * Description: mci header 29455+ * 29456+ * This program is free software; you can redistribute it and/or modify 29457+ * it under the terms of the GNU General Public License as published by 29458+ * the Free Software Foundation; either version 2 of the License, or 29459+ * (at your option) any later version. 29460+ * 29461+ * This program is distributed in the hope that it will be useful, 29462+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 29463+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29464+ * GNU General Public License for more details. 29465+ * 29466+ * You should have received a copy of the GNU General Public License 29467+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 29468+ */ 29469+ 29470+/* 29471+ * MCI connection table manager 29472+ */ 29473+#ifndef __MCI_PROC_H__ 29474+#define __MCI_PROC_H__ 29475+ 29476+#include <linux/proc_fs.h> 29477+ 29478+#define MAX_CARD_TYPE 4 29479+#define MAX_SPEED_MODE 5 29480+ 29481+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) ||\ 29482+ defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500) 29483+#define MCI_SLOT_NUM 1 29484+#elif defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 29485+#define MCI_SLOT_NUM 4 29486+#elif defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100) ||\ 29487+ defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) ||\ 29488+ defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200) ||\ 29489+ defined(CONFIG_ARCH_HI3568V100) 29490+#define MCI_SLOT_NUM 3 29491+#else 29492+#error MCI_SLOT_NUM should not be zero! 29493+#endif 29494+ 29495+extern unsigned int slot_index; 29496+extern struct mmc_host *mci_host[MCI_SLOT_NUM]; 29497+ 29498+int mci_proc_init(void); 29499+int mci_proc_shutdown(void); 29500+ 29501+#endif /* __MCI_PROC_H__ */ 29502diff --git a/drivers/mmc/host/sdhci-hisi.c b/drivers/mmc/host/sdhci-hisi.c 29503new file mode 100644 29504index 000000000..be2a903ac 29505--- /dev/null 29506+++ b/drivers/mmc/host/sdhci-hisi.c 29507@@ -0,0 +1,783 @@ 29508+/* 29509+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2017-2020. All rights reserved. 29510+ * Description: hisi sdhci driver 29511+ * 29512+ * This program is free software; you can redistribute it and/or modify 29513+ * it under the terms of the GNU General Public License as published by 29514+ * the Free Software Foundation; either version 2 of the License, or 29515+ * (at your option) any later version. 29516+ * 29517+ * This program is distributed in the hope that it will be useful, 29518+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 29519+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29520+ * GNU General Public License for more details. 29521+ * 29522+ * You should have received a copy of the GNU General Public License 29523+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 29524+ */ 29525+ 29526+#include "sdhci-hisi.h" 29527+#include "cqhci.h" 29528+#include "mci_proc.h" 29529+ 29530+int sdhci_hisi_parse_dt(struct sdhci_host *host) 29531+{ 29532+ struct sdhci_hisi_priv *priv = sdhci_get_pltfm_priv(host); 29533+ struct device_node *np = host->mmc->parent->of_node; 29534+ u32 bus_width; 29535+ int ret; 29536+ 29537+ ret = mmc_of_parse(host->mmc); 29538+ if (ret) 29539+ return ret; 29540+ 29541+#ifdef CONFIG_MMC_CQHCI 29542+ if (of_get_property(np, "mmc-cmd-queue", NULL)) 29543+ host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; 29544+#endif 29545+ if (of_get_property(np, "mmc-broken-cmd23", NULL)) 29546+ host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; 29547+ 29548+ if (of_property_read_u32(np, "bus-width", &bus_width) == 0) { 29549+ priv->bus_width = bus_width; 29550+ } else { 29551+ pr_err("%s: \"bus-width\" property is missing, assuming 1 bit.\n", 29552+ mmc_hostname(host->mmc)); 29553+ priv->bus_width = 1; 29554+ } 29555+ 29556+ if (of_get_property(np, "sdhci,1-bit-only", NULL) || 29557+ (priv->bus_width == 1)) { 29558+ priv->bus_width = 1; 29559+ host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; 29560+ } 29561+ 29562+ return 0; 29563+} 29564+ 29565+void hisi_enable_sample(struct sdhci_host *host) 29566+{ 29567+ unsigned int reg; 29568+ 29569+ reg = sdhci_readl(host, SDHCI_AT_CTRL); 29570+ reg |= SDHCI_SAMPLE_EN; 29571+ sdhci_writel(host, reg, SDHCI_AT_CTRL); 29572+} 29573+ 29574+void hisi_set_sample_phase(struct sdhci_host *host, u32 phase) 29575+{ 29576+ unsigned int reg; 29577+ 29578+ reg = sdhci_readl(host, SDHCI_AT_STAT); 29579+ reg &= ~SDHCI_PHASE_SEL_MASK; 29580+ reg |= phase; 29581+ sdhci_writel(host, reg, SDHCI_AT_STAT); 29582+} 29583+ 29584+void hisi_disable_card_clk(struct sdhci_host *host) 29585+{ 29586+ u16 clk; 29587+ 29588+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 29589+ clk &= ~SDHCI_CLOCK_CARD_EN; 29590+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 29591+} 29592+ 29593+void hisi_enable_card_clk(struct sdhci_host *host) 29594+{ 29595+ u16 clk; 29596+ 29597+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 29598+ clk |= SDHCI_CLOCK_CARD_EN; 29599+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 29600+} 29601+ 29602+void hisi_disable_internal_clk(struct sdhci_host *host) 29603+{ 29604+ u16 clk; 29605+ 29606+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 29607+ clk &= ~SDHCI_CLOCK_INT_EN; 29608+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 29609+} 29610+ 29611+void hisi_enable_internal_clk(struct sdhci_host *host) 29612+{ 29613+ unsigned int timeout = 20; 29614+ u16 clk; 29615+ 29616+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 29617+ clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_PLL_EN; 29618+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 29619+ 29620+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 29621+ while (!(clk & SDHCI_CLOCK_INT_STABLE)) { 29622+ if (timeout == 0) { 29623+ pr_err("%s: Internal clock never stabilised.\n", 29624+ __func__); 29625+ return; 29626+ } 29627+ timeout--; 29628+ udelay(1000); /* delay 1000us */ 29629+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 29630+ } 29631+} 29632+ 29633+static void hisi_select_sample_phase(struct sdhci_host *host, 29634+ unsigned int phase) 29635+{ 29636+ hisi_disable_card_clk(host); 29637+ hisi_set_sample_phase(host, phase); 29638+ hisi_wait_sample_dll_ready(host); 29639+ hisi_enable_card_clk(host); 29640+ udelay(1); 29641+} 29642+ 29643+static int hisi_send_tuning(struct sdhci_host *host, u32 opcode) 29644+{ 29645+ int count, err; 29646+ 29647+ count = 0; 29648+ do { 29649+ err = mmc_send_tuning(host->mmc, opcode, NULL); 29650+ if (err) { 29651+ mmc_abort_tuning(host->mmc, opcode); 29652+ break; 29653+ } 29654+ count++; 29655+ } while (count < MAX_TUNING_NUM); 29656+ 29657+ return err; 29658+} 29659+ 29660+static void hisi_pre_tuning(struct sdhci_host *host) 29661+{ 29662+ sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE); 29663+ sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE); 29664+ 29665+ hisi_enable_sample(host); 29666+ host->is_tuning = 1; 29667+} 29668+ 29669+static void hisi_post_tuning(struct sdhci_host *host) 29670+{ 29671+ unsigned short ctrl; 29672+ 29673+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 29674+ ctrl |= SDHCI_CTRL_TUNED_CLK; 29675+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 29676+ 29677+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 29678+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 29679+ host->is_tuning = 0; 29680+} 29681+ 29682+#ifndef SDHCI_HISI_EDGE_TUNING 29683+static int hisi_get_best_sample(u32 candidates) 29684+{ 29685+ int rise = NOT_FOUND; 29686+ int fall, i, win; 29687+ int win_max_r = NOT_FOUND; 29688+ int win_max_f = NOT_FOUND; 29689+ int end_fall = NOT_FOUND; 29690+ int found = NOT_FOUND; 29691+ int win_max = 0; 29692+ 29693+ for (i = 0; i < PHASE_SCALE; i++) { 29694+ if ((candidates & 0x3) == 0x2) 29695+ rise = (i + 1) % PHASE_SCALE; 29696+ 29697+ if ((candidates & 0x3) == 0x1) { 29698+ fall = i; 29699+ if (rise != NOT_FOUND) { 29700+ win = fall - rise + 1; 29701+ if (win > win_max) { 29702+ win_max = win; 29703+ found = (fall + rise) / 2; /* Get window center by devide 2 */ 29704+ win_max_r = rise; 29705+ win_max_f = fall; 29706+ rise = NOT_FOUND; 29707+ fall = NOT_FOUND; 29708+ } 29709+ } else { 29710+ end_fall = fall; 29711+ } 29712+ } 29713+ candidates = ror32(candidates, 1); 29714+ } 29715+ 29716+ if (end_fall != NOT_FOUND && rise != NOT_FOUND) { 29717+ fall = end_fall; 29718+ if (end_fall < rise) 29719+ end_fall += PHASE_SCALE; 29720+ 29721+ win = end_fall - rise + 1; 29722+ if (win > win_max) { 29723+ found = (rise + (win / 2)) % PHASE_SCALE; /* Get window center by devide 2 */ 29724+ win_max_r = rise; 29725+ win_max_f = fall; 29726+ } 29727+ } 29728+ 29729+ if (found != NOT_FOUND) 29730+ pr_err("valid phase shift [%d, %d] Final Phase:%d\n", 29731+ win_max_r, win_max_f, found); 29732+ 29733+ return found; 29734+} 29735+ 29736+static int sdhci_hisi_exec_tuning(struct sdhci_host *host, u32 opcode) 29737+{ 29738+ struct sdhci_hisi_priv *priv = sdhci_get_pltfm_priv(host); 29739+ unsigned int sample; 29740+ unsigned int candidates = 0; 29741+ int phase, err; 29742+ 29743+ hisi_pre_tuning(host); 29744+ 29745+ for (sample = 0; sample < PHASE_SCALE; sample++) { 29746+ hisi_select_sample_phase(host, sample); 29747+ 29748+ err = hisi_send_tuning(host, opcode); 29749+ if (err) 29750+ pr_debug("send tuning CMD%u fail! phase:%d err:%d\n", 29751+ opcode, sample, err); 29752+ else 29753+ candidates |= (0x1 << sample); 29754+ } 29755+ 29756+ pr_info("%s: tuning done! candidates 0x%X: ", 29757+ mmc_hostname(host->mmc), candidates); 29758+ 29759+ phase = hisi_get_best_sample(candidates); 29760+ if (phase == NOT_FOUND) { 29761+ phase = priv->sample_phase; 29762+ pr_err("no valid phase shift! use default %d\n", phase); 29763+ } 29764+ 29765+ priv->tuning_phase = phase; 29766+ hisi_select_sample_phase(host, phase); 29767+ hisi_post_tuning(host); 29768+ 29769+ return 0; 29770+} 29771+#else 29772+static void hisi_enable_edge_tuning(struct sdhci_host *host) 29773+{ 29774+ unsigned int reg; 29775+ 29776+ reg = sdhci_readl(host, SDHCI_MULTI_CYCLE); 29777+ reg |= SDHCI_EDGE_DETECT_EN; 29778+ sdhci_writel(host, reg, SDHCI_MULTI_CYCLE); 29779+} 29780+ 29781+static void hisi_disable_edge_tuning(struct sdhci_host *host) 29782+{ 29783+ unsigned int reg; 29784+ 29785+ reg = sdhci_readl(host, SDHCI_MULTI_CYCLE); 29786+ reg &= ~SDHCI_EDGE_DETECT_EN; 29787+ sdhci_writel(host, reg, SDHCI_MULTI_CYCLE); 29788+} 29789+ 29790+static int sdhci_hisi_exec_edge_tuning(struct sdhci_host *host, u32 opcode) 29791+{ 29792+ struct sdhci_hisi_priv *priv = sdhci_get_pltfm_priv(host); 29793+ unsigned int index, val; 29794+ unsigned int found; 29795+ unsigned int prev_found = 0; 29796+ unsigned int edge_p2f, edge_f2p, start, end; 29797+ unsigned int phase, fall, rise; 29798+ unsigned int fall_updat_flag = 0; 29799+ int err; 29800+ int prev_err = 0; 29801+ 29802+ hisi_pre_tuning(host); 29803+ hisi_enable_edge_tuning(host); 29804+ 29805+ start = 0; 29806+ end = PHASE_SCALE / EDGE_TUNING_PHASE_STEP; 29807+ 29808+ edge_p2f = start; 29809+ edge_f2p = end; 29810+ for (index = 0; index <= end; index++) { 29811+ hisi_select_sample_phase(host, index * EDGE_TUNING_PHASE_STEP); 29812+ err = hisi_send_tuning(host, opcode); 29813+ if (!err) { 29814+ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); 29815+ found = val & SDHCI_FOUND_EDGE; 29816+ } else { 29817+ found = 1; 29818+ } 29819+ 29820+ if (prev_found && !found) 29821+ edge_f2p = index; 29822+ else if (!prev_found && found) 29823+ edge_p2f = index; 29824+ 29825+ if ((edge_p2f != start) && (edge_f2p != end)) 29826+ break; 29827+ 29828+ prev_found = found; 29829+ } 29830+ 29831+ if ((edge_p2f == start) && (edge_f2p == end)) { 29832+ pr_err("%s: tuning failed! can not found edge!\n", 29833+ mmc_hostname(host->mmc)); 29834+ return -1; 29835+ } 29836+ 29837+ hisi_disable_edge_tuning(host); 29838+ 29839+ start = edge_p2f * EDGE_TUNING_PHASE_STEP; 29840+ end = edge_f2p * EDGE_TUNING_PHASE_STEP; 29841+ if (end <= start) 29842+ end += PHASE_SCALE; 29843+ 29844+ fall = start; 29845+ rise = end; 29846+ for (index = start; index <= end; index++) { 29847+ hisi_select_sample_phase(host, index % PHASE_SCALE); 29848+ err = hisi_send_tuning(host, opcode); 29849+ if (err) 29850+ pr_debug("send tuning CMD%u fail! phase:%d err:%d\n", 29851+ opcode, index, err); 29852+ 29853+ if (err && index == start) { 29854+ if (!fall_updat_flag) { 29855+ fall_updat_flag = 1; 29856+ fall = start; 29857+ } 29858+ } else if (!prev_err && err) { 29859+ if (!fall_updat_flag) { 29860+ fall_updat_flag = 1; 29861+ fall = index; 29862+ } 29863+ } 29864+ 29865+ if (prev_err && !err) 29866+ rise = index; 29867+ 29868+ if (err && index == end) 29869+ rise = end; 29870+ 29871+ prev_err = err; 29872+ } 29873+ 29874+ phase = ((fall + rise) / 2 + PHASE_SCALE / 2) % /* 2 for cal average */ 29875+ PHASE_SCALE; 29876+ 29877+ pr_info("%s: tuning done! valid phase shift [%d, %d] Final Phase:%d\n", 29878+ mmc_hostname(host->mmc), rise % PHASE_SCALE, 29879+ fall % PHASE_SCALE, phase); 29880+ 29881+ priv->tuning_phase = phase; 29882+ hisi_select_sample_phase(host, phase); 29883+ hisi_post_tuning(host); 29884+ 29885+ return 0; 29886+} 29887+#endif 29888+ 29889+static int sdhci_hisi_execute_tuning(struct sdhci_host *host, u32 opcode) 29890+{ 29891+#ifdef SDHCI_HISI_EDGE_TUNING 29892+ return sdhci_hisi_exec_edge_tuning(host, opcode); 29893+#else 29894+ return sdhci_hisi_exec_tuning(host, opcode); 29895+#endif 29896+} 29897+ 29898+static void hisi_set_emmc_card(struct sdhci_host *host) 29899+{ 29900+ unsigned int reg; 29901+ 29902+ if (host->timing == MMC_TIMING_MMC_HS || 29903+ host->timing == MMC_TIMING_MMC_DDR52 || 29904+ host->timing == MMC_TIMING_MMC_HS200 || 29905+ host->timing == MMC_TIMING_MMC_HS400) { 29906+ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); 29907+ reg |= SDHCI_CARD_IS_EMMC; 29908+ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); 29909+ } 29910+} 29911+ 29912+static void sdhci_hisi_set_uhs_signaling(struct sdhci_host *host, 29913+ unsigned int timing) 29914+{ 29915+ sdhci_set_uhs_signaling(host, timing); 29916+ host->timing = timing; 29917+ hisi_set_emmc_card(host); 29918+ hisi_set_drv_cap(host); 29919+} 29920+ 29921+static void sdhci_hisi_hw_reset(struct sdhci_host *host) 29922+{ 29923+ sdhci_writel(host, 0x0, SDHCI_EMMC_HW_RESET); 29924+ udelay(10); /* delay 10us */ 29925+ sdhci_writel(host, 0x1, SDHCI_EMMC_HW_RESET); 29926+ udelay(200); /* delay 200us */ 29927+} 29928+ 29929+/* 29930+ * This api is for wifi driver rescan the sdio device 29931+ */ 29932+int hisi_sdio_rescan(int slot) 29933+{ 29934+ struct mmc_host *mmc = NULL; 29935+ 29936+ if ((slot >= MCI_SLOT_NUM) || (slot <= 0)) { 29937+ pr_err("invalid mmc slot, please check the argument\n"); 29938+ return -EINVAL; 29939+ } 29940+ 29941+ mmc = mci_host[slot]; 29942+ if (mmc == NULL) { 29943+ pr_err("invalid mmc, please check the argument\n"); 29944+ return -EINVAL; 29945+ } 29946+ 29947+ mmc_detect_change(mmc, 0); 29948+ return 0; 29949+} 29950+EXPORT_SYMBOL_GPL(hisi_sdio_rescan); 29951+ 29952+static const struct of_device_id sdhci_hisi_match[] = { 29953+ { .compatible = "hisilicon,sdhci" }, 29954+ {}, 29955+}; 29956+ 29957+MODULE_DEVICE_TABLE(of, sdhci_hisi_match); 29958+ 29959+static struct sdhci_ops sdhci_hisi_ops = { 29960+ .platform_execute_tuning = sdhci_hisi_execute_tuning, 29961+ .reset = sdhci_reset, 29962+ .set_clock = sdhci_hisi_set_clock, 29963+ .set_bus_width = sdhci_set_bus_width, 29964+ .set_uhs_signaling = sdhci_hisi_set_uhs_signaling, 29965+ .hw_reset = sdhci_hisi_hw_reset, 29966+#if defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3559AV100) || \ 29967+ defined(CONFIG_ARCH_HI3519AV100) || defined(CONFIG_ARCH_HI3569V100) || \ 29968+ defined(CONFIG_ARCH_HI3568V100) 29969+ .start_signal_voltage_switch = sdhci_hisi_start_signal_voltage_switch, 29970+#endif 29971+ .init = sdhci_hisi_extra_init, 29972+}; 29973+ 29974+static const struct sdhci_pltfm_data sdhci_hisi_pdata = { 29975+ .ops = &sdhci_hisi_ops, 29976+ .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, 29977+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, 29978+}; 29979+ 29980+#ifdef CONFIG_MMC_CQHCI 29981+static u32 sdhci_hisi_cqhci_irq(struct sdhci_host *host, u32 intmask) 29982+{ 29983+ int cmd_error = 0; 29984+ int data_error = 0; 29985+ 29986+ if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error)) 29987+ return intmask; 29988+ 29989+ cqhci_irq(host->mmc, intmask, cmd_error, data_error); 29990+ 29991+ return 0; 29992+} 29993+ 29994+static void sdhci_hisi_controller_v4_enable(struct sdhci_host *host, int enable) 29995+{ 29996+ u16 ctrl; 29997+ 29998+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 29999+ if (enable) 30000+ ctrl |= SDHCI_CTRL_HOST_VER4_ENABLE; 30001+ else 30002+ ctrl &= ~SDHCI_CTRL_HOST_VER4_ENABLE; 30003+ 30004+ if (host->flags & SDHCI_USE_64_BIT_DMA) 30005+ ctrl |= SDHCI_CTRL_64BIT_ADDR; 30006+ 30007+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 30008+} 30009+ 30010+static void sdhci_hisi_cqe_enable(struct mmc_host *mmc) 30011+{ 30012+ struct sdhci_host *host = mmc_priv(mmc); 30013+ unsigned int timeout = 10000; 30014+ u16 reg, clk; 30015+ u8 ctrl; 30016+ 30017+ /* SW_RST_DAT */ 30018+ sdhci_reset(host, SDHCI_RESET_DATA); 30019+ 30020+ sdhci_hisi_controller_v4_enable(host, 1); 30021+ 30022+ /* Set the DMA boundary value and block size */ 30023+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary, 30024+ MMC_BLOCK_SIZE), SDHCI_BLOCK_SIZE); 30025+ 30026+ /* need to set multitransfer for cmdq */ 30027+ reg = sdhci_readw(host, SDHCI_TRANSFER_MODE); 30028+ reg |= SDHCI_TRNS_MULTI; 30029+ reg |= SDHCI_TRNS_BLK_CNT_EN; 30030+ sdhci_writew(host, reg, SDHCI_TRANSFER_MODE); 30031+ 30032+ /* ADMA2 only */ 30033+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 30034+ ctrl &= ~SDHCI_CTRL_DMA_MASK; 30035+ ctrl |= SDHCI_CTRL_ADMA32; 30036+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 30037+ 30038+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 30039+ clk |= SDHCI_CLOCK_PLL_EN; 30040+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 30041+ 30042+ while (mmc->ops->card_busy(mmc)) { 30043+ timeout--; 30044+ if (!timeout) { 30045+ pr_err("%s: wait busy timeout\n", __func__); 30046+ break; 30047+ } 30048+ udelay(1); 30049+ } 30050+ 30051+ sdhci_cqe_enable(mmc); 30052+} 30053+ 30054+static void sdhci_hisi_cqe_disable(struct mmc_host *mmc, bool recovery) 30055+{ 30056+ int timeout = 10000; 30057+ 30058+ while (mmc->ops->card_busy(mmc)) { 30059+ timeout--; 30060+ if (!timeout) { 30061+ pr_err("%s: wait busy timeout\n", __func__); 30062+ break; 30063+ } 30064+ udelay(1); 30065+ } 30066+ 30067+ sdhci_hisi_controller_v4_enable(mmc_priv(mmc), 0); 30068+ 30069+ sdhci_cqe_disable(mmc, recovery); 30070+} 30071+ 30072+static void sdhci_hisi_dumpregs(struct mmc_host *mmc) 30073+{ 30074+ sdhci_dumpregs(mmc_priv(mmc)); 30075+} 30076+ 30077+static const struct cqhci_host_ops sdhci_hisi_cqhci_ops = { 30078+ .enable = sdhci_hisi_cqe_enable, 30079+ .disable = sdhci_hisi_cqe_disable, 30080+ .dumpregs = sdhci_hisi_dumpregs, 30081+}; 30082+ 30083+static const struct sdhci_ops sdhci_hisi_cqe_ops = { 30084+ .platform_execute_tuning = sdhci_hisi_execute_tuning, 30085+ .reset = sdhci_reset, 30086+ .set_clock = sdhci_hisi_set_clock, 30087+ .set_bus_width = sdhci_set_bus_width, 30088+ .set_uhs_signaling = sdhci_hisi_set_uhs_signaling, 30089+ .hw_reset = sdhci_hisi_hw_reset, 30090+ .irq = sdhci_hisi_cqhci_irq, 30091+ .init = sdhci_hisi_extra_init, 30092+}; 30093+ 30094+static const struct sdhci_pltfm_data sdhci_hisi_cqe_pdata = { 30095+ .ops = &sdhci_hisi_cqe_ops, 30096+ .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, 30097+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, 30098+}; 30099+ 30100+static int sdhci_hisi_add_host(struct sdhci_host *host) 30101+{ 30102+ struct cqhci_host *cq_host = NULL; 30103+ bool dma64 = false; 30104+ int ret; 30105+ 30106+ if (!(host->mmc->caps2 & MMC_CAP2_CQE)) 30107+ return sdhci_add_host(host); 30108+ 30109+ ret = sdhci_setup_host(host); 30110+ if (ret) 30111+ return ret; 30112+ 30113+ cq_host = devm_kzalloc(host->mmc->parent, sizeof(*cq_host), GFP_KERNEL); 30114+ if (cq_host == NULL) { 30115+ pr_err("%s: allocate memory for CQE fail\n", __func__); 30116+ ret = -ENOMEM; 30117+ goto cleanup; 30118+ } 30119+ 30120+ cq_host->mmio = host->ioaddr + 0x180; 30121+ cq_host->ops = &sdhci_hisi_cqhci_ops; 30122+ 30123+ /* 30124+ * synopsys controller has dma 128M algin limit, 30125+ * may split the trans descriptors 30126+ */ 30127+ cq_host->quirks |= CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT; 30128+ 30129+ dma64 = host->flags & SDHCI_USE_64_BIT_DMA; 30130+ if (dma64) 30131+ cq_host->caps |= CQHCI_TASK_DESC_SZ_128; 30132+ 30133+ ret = cqhci_init(cq_host, host->mmc, dma64); 30134+ if (ret) { 30135+ pr_err("%s: CQE init fail\n", __func__); 30136+ return ret; 30137+ } 30138+ 30139+ ret = __sdhci_add_host(host); 30140+ if (ret) 30141+ return ret; 30142+ 30143+ return 0; 30144+ 30145+cleanup: 30146+ sdhci_cleanup_host(host); 30147+ return ret; 30148+} 30149+#else 30150+static int sdhci_hisi_add_host(struct sdhci_host *host) 30151+{ 30152+ return sdhci_add_host(host); 30153+} 30154+#endif 30155+ 30156+static int sdhci_hisi_probe(struct platform_device *pdev) 30157+{ 30158+ struct sdhci_host *host = NULL; 30159+ const struct sdhci_pltfm_data *pdata = NULL; 30160+ int ret; 30161+ 30162+#ifdef CONFIG_MMC_CQHCI 30163+ if (of_get_property(pdev->dev.of_node, "mmc-cmd-queue", NULL)) 30164+ pdata = &sdhci_hisi_cqe_pdata; 30165+ else 30166+ pdata = &sdhci_hisi_pdata; 30167+#else 30168+ pdata = &sdhci_hisi_pdata; 30169+#endif 30170+ host = sdhci_pltfm_init(pdev, pdata, sizeof(struct sdhci_hisi_priv)); 30171+ if (IS_ERR(host)) 30172+ return PTR_ERR(host); 30173+ 30174+ ret = sdhci_hisi_pltfm_init(pdev, host); 30175+ if (ret) 30176+ goto pltfm_free; 30177+ 30178+ if (hisi_support_runtime_pm(host)) { 30179+ pm_runtime_get_noresume(&pdev->dev); 30180+ pm_runtime_set_autosuspend_delay(&pdev->dev, HISI_MMC_AUTOSUSPEND_DELAY_MS); 30181+ pm_runtime_use_autosuspend(&pdev->dev); 30182+ pm_runtime_set_active(&pdev->dev); 30183+ pm_runtime_enable(&pdev->dev); 30184+ } 30185+ 30186+ ret = sdhci_hisi_add_host(host); 30187+ if (ret) 30188+ goto pm_runtime_disable; 30189+ 30190+ if (hisi_support_runtime_pm(host)) { 30191+ pm_runtime_mark_last_busy(&pdev->dev); 30192+ pm_runtime_put_autosuspend(&pdev->dev); 30193+ } 30194+ 30195+ return 0; 30196+ 30197+pm_runtime_disable: 30198+ if (hisi_support_runtime_pm(host)) { 30199+ pm_runtime_disable(&pdev->dev); 30200+ pm_runtime_set_suspended(&pdev->dev); 30201+ pm_runtime_put_noidle(&pdev->dev); 30202+ } 30203+ 30204+pltfm_free: 30205+ sdhci_pltfm_free(pdev); 30206+ return ret; 30207+} 30208+ 30209+static int sdhci_hisi_remove(struct platform_device *pdev) 30210+{ 30211+ struct sdhci_host *host = platform_get_drvdata(pdev); 30212+ int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) == 30213+ 0xffffffff); 30214+ 30215+ if (hisi_support_runtime_pm(host)) { 30216+ pm_runtime_get_sync(&pdev->dev); 30217+ pm_runtime_disable(&pdev->dev); 30218+ pm_runtime_put_noidle(&pdev->dev); 30219+ } 30220+ 30221+ sdhci_remove_host(host, dead); 30222+ sdhci_pltfm_free(pdev); 30223+ 30224+ return 0; 30225+} 30226+ 30227+#ifdef CONFIG_PM 30228+static int sdhci_hisi_runtime_suspend(struct device *dev) 30229+{ 30230+ struct sdhci_host *host = dev_get_drvdata(dev); 30231+ 30232+ hisi_disable_card_clk(host); 30233+ return 0; 30234+} 30235+ 30236+static int sdhci_hisi_runtime_resume(struct device *dev) 30237+{ 30238+ struct sdhci_host *host = dev_get_drvdata(dev); 30239+ 30240+ hisi_enable_card_clk(host); 30241+ return 0; 30242+} 30243+#endif 30244+ 30245+static const struct dev_pm_ops sdhci_hisi_pm_ops = { 30246+ SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, 30247+ sdhci_pltfm_resume) 30248+ 30249+ SET_RUNTIME_PM_OPS(sdhci_hisi_runtime_suspend, 30250+ sdhci_hisi_runtime_resume, 30251+ NULL) 30252+}; 30253+ 30254+static struct platform_driver sdhci_hisi_driver = { 30255+ .probe = sdhci_hisi_probe, 30256+ .remove = sdhci_hisi_remove, 30257+ .driver = { 30258+ .name = "sdhci_hisi", 30259+ .of_match_table = sdhci_hisi_match, 30260+ .pm = &sdhci_hisi_pm_ops, 30261+ }, 30262+}; 30263+ 30264+static int __init sdhci_hisi_init(void) 30265+{ 30266+ int ret; 30267+ 30268+ ret = platform_driver_register(&sdhci_hisi_driver); 30269+ if (ret) 30270+ return ret; 30271+ 30272+ ret = mci_proc_init(); 30273+ if (ret) 30274+ platform_driver_unregister(&sdhci_hisi_driver); 30275+ 30276+ return ret; 30277+} 30278+ 30279+static void __exit sdhci_hisi_exit(void) 30280+{ 30281+ mci_proc_shutdown(); 30282+ 30283+ platform_driver_unregister(&sdhci_hisi_driver); 30284+} 30285+ 30286+module_init(sdhci_hisi_init); 30287+module_exit(sdhci_hisi_exit); 30288+MODULE_DESCRIPTION("SDHCI driver for Hisilicon"); 30289+MODULE_AUTHOR("HiSilicon Technologies Co., Ltd.."); 30290+MODULE_LICENSE("GPL v2"); 30291diff --git a/drivers/mmc/host/sdhci-hisi.h b/drivers/mmc/host/sdhci-hisi.h 30292new file mode 100644 30293index 000000000..19cea6dc5 30294--- /dev/null 30295+++ b/drivers/mmc/host/sdhci-hisi.h 30296@@ -0,0 +1,126 @@ 30297+/* 30298+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2017-2020. All rights reserved. 30299+ * Description: hisi sdhci header 30300+ * 30301+ * This program is free software; you can redistribute it and/or modify 30302+ * it under the terms of the GNU General Public License as published by 30303+ * the Free Software Foundation; either version 2 of the License, or 30304+ * (at your option) any later version. 30305+ * 30306+ * This program is distributed in the hope that it will be useful, 30307+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 30308+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30309+ * GNU General Public License for more details. 30310+ * 30311+ * You should have received a copy of the GNU General Public License 30312+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 30313+ */ 30314+ 30315+#ifndef _DRIVERS_MMC_SDHCI_HISI_H 30316+#define _DRIVERS_MMC_SDHCI_HISI_H 30317+ 30318+#include <linux/delay.h> 30319+#include <linux/device.h> 30320+#include <linux/of.h> 30321+#include <linux/module.h> 30322+#include <linux/regmap.h> 30323+#include <linux/mfd/syscon.h> 30324+#include <linux/reset.h> 30325+#include <linux/mmc/host.h> 30326+#include <linux/pm_runtime.h> 30327+#include "sdhci-pltfm.h" 30328+ 30329+#define SDHCI_HISI_EDGE_TUNING /* enable edge tuning */ 30330+ 30331+#define PHASE_SCALE 32 30332+#define NOT_FOUND (-1) 30333+#define MAX_TUNING_NUM 1 30334+#define MAX_FREQ 200000000 30335+#define EDGE_TUNING_PHASE_STEP 4 30336+#define MMC_BLOCK_SIZE 512 30337+ 30338+/* Software auto suspend delay */ 30339+#define HISI_MMC_AUTOSUSPEND_DELAY_MS 50 30340+ 30341+static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) 30342+{ 30343+ return sdhci_pltfm_priv(sdhci_priv(host)); 30344+} 30345+ 30346+struct sdhci_hisi_priv { 30347+ struct reset_control *crg_rst; 30348+ struct reset_control *dll_rst; 30349+ struct reset_control *sampl_rst; 30350+ struct regmap *crg_regmap; 30351+ struct regmap *misc_regmap; 30352+ struct regmap *iocfg_regmap; 30353+ void __iomem *phy_addr; 30354+ unsigned int devid; 30355+ unsigned int drv_phase; 30356+ unsigned int sample_phase; 30357+ unsigned int tuning_phase; 30358+ unsigned int bus_width; 30359+}; 30360+ 30361+/* Hisilicon extended host controller registers. */ 30362+#define SDHCI_CTRL_HOST_VER4_ENABLE 0x1000 30363+#define SDHCI_CLOCK_PLL_EN 0x0008 30364+#define SDHCI_CTRL_64BIT_ADDR 0x2000 30365+#define SDHCI_CAN_DO_ADMA3 0x08000000 30366+ 30367+/* Hisilicon extended registers */ 30368+#define SDHCI_MSHC_CTRL 0x508 30369+#define SDHCI_CMD_CONFLIT_CHECK 0x01 30370+ 30371+#define SDHCI_AXI_MBIIU_CTRL 0x510 30372+#define SDHCI_GM_WR_OSRC_LMT_MASK (0x7 << 24) 30373+#define SDHCI_GM_WR_OSRC_LMT_SEL(x) ((x) << 24) 30374+#define SDHCI_GM_RD_OSRC_LMT_MASK (0x7 << 16) 30375+#define SDHCI_GM_RD_OSRC_LMT_SEL(x) ((x) << 16) 30376+#define SDHCI_UNDEFL_INCR_EN 0x1 30377+ 30378+#define SDHCI_EMMC_CTRL 0x52C 30379+#define SDHCI_CARD_IS_EMMC 0x0001 30380+#define SDHCI_ENH_STROBE_EN 0x0100 30381+ 30382+#define SDHCI_EMMC_HW_RESET 0x534 30383+ 30384+#define SDHCI_AT_CTRL 0x540 30385+#define SDHCI_SAMPLE_EN 0x00000010 30386+ 30387+#define SDHCI_AT_STAT 0x544 30388+#define SDHCI_PHASE_SEL_MASK 0x000000FF 30389+ 30390+#define SDHCI_MULTI_CYCLE 0x54C 30391+#define SDHCI_FOUND_EDGE (0x1 << 11) 30392+#define SDHCI_EDGE_DETECT_EN (0x1 << 8) 30393+#define SDHCI_DOUT_EN_F_EDGE (0x1 << 6) 30394+#define SDHCI_DATA_DLY_EN (0x1 << 3) 30395+#define SDHCI_CMD_DLY_EN (0x1 << 2) 30396+ 30397+void hisi_set_drv_cap(struct sdhci_host *host); 30398+void hisi_get_phase(struct sdhci_host *host); 30399+void hisi_set_drv_phase(struct sdhci_host *host, unsigned int phase); 30400+void hisi_enable_sample(struct sdhci_host *host); 30401+void hisi_set_sample_phase(struct sdhci_host *host, u32 phase); 30402+void hisi_disable_card_clk(struct sdhci_host *host); 30403+void hisi_enable_card_clk(struct sdhci_host *host); 30404+void hisi_disable_internal_clk(struct sdhci_host *host); 30405+void hisi_enable_internal_clk(struct sdhci_host *host); 30406+void hisi_enable_sample_dll_slave(struct sdhci_host *host); 30407+void hisi_wait_sample_dll_ready(struct sdhci_host *host); 30408+void hisi_wait_p4_dll_lock(struct sdhci_host *host); 30409+void hisi_wait_ds_dll_ready(struct sdhci_host *host); 30410+void hisi_wait_ds_180_dll_ready(struct sdhci_host *host); 30411+void hisi_wait_ds_dll_lock(struct sdhci_host *host); 30412+void hisi_set_ds_dll_delay(struct sdhci_host *host); 30413+void sdhci_hisi_set_clock(struct sdhci_host *host, unsigned int clk); 30414+int hisi_support_runtime_pm(struct sdhci_host *host); 30415+int sdhci_hisi_pltfm_init(struct platform_device *pdev, 30416+ struct sdhci_host *host); 30417+void sdhci_hisi_extra_init(struct sdhci_host *host); 30418+int sdhci_hisi_parse_dt(struct sdhci_host *host); 30419+int sdhci_hisi_start_signal_voltage_switch(struct sdhci_host *host, 30420+ struct mmc_ios *ios); 30421+ 30422+#endif /* _DRIVERS_MMC_SDHCI_HISI_H */ 30423diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c 30424index 07d131fac..49ee7d99b 100644 30425--- a/drivers/mmc/host/sdhci.c 30426+++ b/drivers/mmc/host/sdhci.c 30427@@ -261,7 +261,7 @@ static void sdhci_set_default_irqs(struct sdhci_host *host) 30428 SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | 30429 SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC | 30430 SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | 30431- SDHCI_INT_RESPONSE; 30432+ SDHCI_INT_RESPONSE | SDHCI_INT_AUTO_CMD_ERR; 30433 30434 if (host->tuning_mode == SDHCI_TUNING_MODE_2 || 30435 host->tuning_mode == SDHCI_TUNING_MODE_3) 30436@@ -291,8 +291,12 @@ static void sdhci_config_dma(struct sdhci_host *host) 30437 goto out; 30438 30439 /* Note if DMA Select is zero then SDMA is selected */ 30440- if (host->flags & SDHCI_USE_ADMA) 30441+ if (host->flags & SDHCI_USE_ADMA) { 30442 ctrl |= SDHCI_CTRL_ADMA32; 30443+ if (host->flags & SDHCI_USE_ADMA3) { 30444+ ctrl |= SDHCI_CTRL_ADMA3; 30445+ } 30446+ } 30447 30448 if (host->flags & SDHCI_USE_64_BIT_DMA) { 30449 /* 30450@@ -341,6 +345,9 @@ static void sdhci_init(struct sdhci_host *host, int soft) 30451 host->clock = 0; 30452 mmc->ops->set_ios(mmc, &mmc->ios); 30453 } 30454+ 30455+ if (host->ops->init) 30456+ host->ops->init(host); 30457 } 30458 30459 static void sdhci_reinit(struct sdhci_host *host) 30460@@ -478,6 +485,28 @@ static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq) 30461 del_timer(&host->timer); 30462 } 30463 30464+static void __sdhci_noadma3_set_cmd_arg(struct sdhci_host *host, struct mmc_command *cmd) 30465+{ 30466+ if (!(host->flags & SDHCI_USE_ADMA3) || !cmd->data) 30467+ sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); 30468+} 30469+ 30470+static void __sdhci_prep_adma3(struct sdhci_host *host, 30471+ struct mmc_command *cmd, int *flags) 30472+{ 30473+ if ((host->flags & SDHCI_USE_ADMA3) && cmd->data) { 30474+ sdhci_prep_adma3_desc(host, cmd, *flags); 30475+ 30476+ sdhci_writel(host, (u32)host->adma3_addr, 30477+ SDHCI_ADMA3_ID_ADDR_LOW); 30478+ if (host->flags & SDHCI_USE_64_BIT_DMA) 30479+ sdhci_writel(host, (u32)((u64)host->adma3_addr >> 32), // right shift 32 30480+ SDHCI_ADMA3_ID_ADDR_HI); 30481+ } else { 30482+ sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, *flags), SDHCI_COMMAND); 30483+ } 30484+} 30485+ 30486 static inline bool sdhci_has_requests(struct sdhci_host *host) 30487 { 30488 return host->cmd || host->data_cmd; 30489@@ -700,6 +729,60 @@ void sdhci_adma_write_desc(struct sdhci_host *host, void **desc, 30490 } 30491 EXPORT_SYMBOL_GPL(sdhci_adma_write_desc); 30492 30493+static void sdhci_write_cmd_table(u8 *desc, u32 reg, u32 attr) 30494+{ 30495+ __le32 *reg_addr = (__le32 __force *)(desc + 4); // offset 4 30496+ __le32 *attr_addr = (__le32 __force *)desc; 30497+ 30498+ attr_addr[0] = cpu_to_le32(attr); 30499+ reg_addr[0] = cpu_to_le32(reg); 30500+} 30501+ 30502+static void sdhci_write_adma3_desc(struct sdhci_host *host, u8 *desc, 30503+ dma_addr_t addr, unsigned int attr) 30504+{ 30505+ __le32 *attr_addr = (__le32 __force *)desc; 30506+ 30507+ attr_addr[0] = cpu_to_le32(attr); 30508+ 30509+ if (host->flags & SDHCI_USE_64_BIT_DMA) { 30510+ __le64 *cmd_ddr = (__le64 __force *)(desc + 4); // offset 4 30511+ cmd_ddr[0] = cpu_to_le64(addr); 30512+ } else { 30513+ __le32 *cmd_ddr = (__le32 __force *)(desc + 4); // offset 4 30514+ cmd_ddr[0] = cpu_to_le32(addr); 30515+ } 30516+} 30517+ 30518+static void sdhci_prep_adma3_desc(struct sdhci_host *host, 30519+ struct mmc_command *cmd, int flags) 30520+{ 30521+ struct mmc_data *data = cmd->data; 30522+ unsigned int ctrl_2, cmd_xfer, blksz; 30523+ u16 mode; 30524+ 30525+ blksz = SDHCI_MAKE_BLKSZ(0, data->blksz); 30526+ mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); 30527+ cmd_xfer = (SDHCI_MAKE_CMD(cmd->opcode, flags) << 16) | mode; // left shift 16 30528+ 30529+ sdhci_write_cmd_table(host->cmd_table, data->blocks, ADMA3_CMD_VALID); 30530+ sdhci_write_cmd_table(host->cmd_table + 0x8, blksz, ADMA3_CMD_VALID); // add 0x8 30531+ sdhci_write_cmd_table(host->cmd_table + 0x10, // add 0x10 30532+ cmd->arg, ADMA3_CMD_VALID); 30533+ sdhci_write_cmd_table(host->cmd_table + 0x18, // add 0x18 30534+ cmd_xfer, ADMA3_CMD_VALID); 30535+ sdhci_adma_write_desc(host, host->cmd_table + 0x20, // add 0x20 30536+ host->adma_addr, 0x0, ADMA2_LINK_VALID); 30537+ sdhci_write_adma3_desc(host, host->adma3_table, 30538+ host->cmd_addr, ADMA3_END); 30539+ 30540+ ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 30541+ ctrl_2 |= SDHCI_CTRL_HOST_VER4_ENABLE; 30542+ if (host->flags & SDHCI_USE_64_BIT_DMA) 30543+ ctrl_2 |= SDHCI_CTRL_ADDRESSING_64BIT; 30544+ sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 30545+} 30546+ 30547 static inline void __sdhci_adma_write_desc(struct sdhci_host *host, 30548 void **desc, dma_addr_t addr, 30549 int len, unsigned int cmd) 30550@@ -774,10 +857,22 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, 30551 30552 BUG_ON(len > 65536); 30553 30554- /* tran, valid */ 30555- if (len) 30556- __sdhci_adma_write_desc(host, &desc, addr, len, 30557+ if (len) { 30558+ /* work around for buffer across 128M boundary, split the buffer */ 30559+ if (((addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)) + len) > 30560+ SDHCI_DMA_BOUNDARY_SIZE) { 30561+ offset = SDHCI_DMA_BOUNDARY_SIZE - 30562+ (addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)); 30563+ sdhci_adma_write_desc(host, desc, addr, offset, 30564 ADMA2_TRAN_VALID); 30565+ desc += host->desc_sz; 30566+ addr += offset; 30567+ len -= offset; 30568+ } 30569+ /* tran, valid */ 30570+ sdhci_adma_write_desc(host, desc, addr, len, 30571+ ADMA2_TRAN_VALID); 30572+ } 30573 30574 /* 30575 * If this triggers then we have a calculation bug 30576@@ -1040,6 +1135,18 @@ static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) 30577 __sdhci_set_timeout(host, cmd); 30578 } 30579 30580+static void __sdhci_select_adma3_mode(struct sdhci_host *host, u8 *ctrl) 30581+{ 30582+ if (host->flags & SDHCI_USE_ADMA3) { 30583+ *ctrl |= SDHCI_CTRL_ADMA3; 30584+ } else { 30585+ if (host->flags & SDHCI_USE_64_BIT_DMA) 30586+ *ctrl |= SDHCI_CTRL_ADMA64; 30587+ else 30588+ *ctrl |= SDHCI_CTRL_ADMA32; 30589+ } 30590+} 30591+ 30592 static void sdhci_initialize_data(struct sdhci_host *host, 30593 struct mmc_data *data) 30594 { 30595@@ -1134,7 +1241,6 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) 30596 30597 if (host->flags & SDHCI_REQ_USE_DMA) { 30598 int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED); 30599- 30600 if (sg_cnt <= 0) { 30601 /* 30602 * This only happens when someone fed 30603@@ -1633,7 +1739,7 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) 30604 sdhci_prepare_data(host, cmd); 30605 } 30606 30607- sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); 30608+ __sdhci_noadma3_set_cmd_arg(host, cmd); 30609 30610 sdhci_set_transfer_mode(host, cmd); 30611 30612@@ -1678,7 +1784,7 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) 30613 if (host->use_external_dma) 30614 sdhci_external_dma_pre_transfer(host, cmd); 30615 30616- sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); 30617+ __sdhci_prep_adma3(host, cmd, &flags); 30618 30619 return true; 30620 } 30621@@ -1755,6 +1861,14 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd) 30622 } 30623 } 30624 30625+#define CMD_ERRORS \ 30626+ (R1_OUT_OF_RANGE | /* Command argument out of range */ \ 30627+ R1_ADDRESS_ERROR | /* Misaligned address */ \ 30628+ R1_BLOCK_LEN_ERROR | /* Transferred block length incorrect */\ 30629+ R1_WP_VIOLATION | /* Tried to write to protected block */ \ 30630+ R1_CC_ERROR | /* Card controller error */ \ 30631+ R1_ERROR) /* General/unknown error */ 30632+ 30633 static void sdhci_finish_command(struct sdhci_host *host) 30634 { 30635 struct mmc_command *cmd = host->cmd; 30636@@ -1767,6 +1881,12 @@ static void sdhci_finish_command(struct sdhci_host *host) 30637 } else { 30638 cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE); 30639 } 30640+ 30641+ if (((cmd->flags & MMC_RSP_R1) == MMC_RSP_R1) && 30642+ ((cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)) { 30643+ if ((cmd->resp[0] & CMD_ERRORS) && !host->is_tuning) 30644+ host->error_count++; 30645+ } 30646 } 30647 30648 if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd) 30649@@ -2067,6 +2187,12 @@ void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode, 30650 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 30651 if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) 30652 sdhci_runtime_pm_bus_off(host); 30653+ /* 30654+ * Controllers need an extra 100ms delay to ensure power off 30655+ * completely 30656+ */ 30657+ msleep(100); 30658+ 30659 } else { 30660 /* 30661 * Spec says that we should clear the power reg before setting 30662@@ -2388,7 +2514,9 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 30663 } 30664 30665 /* Re-enable SD Clock */ 30666- host->ops->set_clock(host, host->clock); 30667+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 30668+ clk |= SDHCI_CLOCK_CARD_EN; 30669+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 30670 } else 30671 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 30672 30673@@ -2529,6 +2657,9 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, 30674 u16 ctrl; 30675 int ret; 30676 30677+ if (host->ops->start_signal_voltage_switch) 30678+ return host->ops->start_signal_voltage_switch(host, ios); 30679+ 30680 /* 30681 * Signal Voltage Switching is only applicable for Host Controllers 30682 * v3.00 and above. 30683@@ -2966,6 +3097,34 @@ static void sdhci_card_event(struct mmc_host *mmc) 30684 spin_unlock_irqrestore(&host->lock, flags); 30685 } 30686 30687+static int sdhci_card_info_save(struct mmc_host *mmc) 30688+{ 30689+ struct mmc_card *card = mmc->card; 30690+ struct sdhci_host *host= mmc_priv(mmc); 30691+ struct card_info *c_info = &host->c_info; 30692+ 30693+ if (!card) { 30694+ memset(c_info,0,sizeof(struct card_info)); 30695+ c_info->card_connect = CARD_DISCONNECT; 30696+ goto out; 30697+ } 30698+ 30699+ c_info->card_type = card->type; 30700+ c_info->card_state = card->state; 30701+ 30702+ c_info->timing = mmc->ios.timing; 30703+ c_info->enhanced_strobe = mmc->ios.enhanced_strobe; 30704+ c_info->card_support_clock = mmc->ios.clock; 30705+ 30706+ c_info->sd_bus_speed = card->sd_bus_speed; 30707+ 30708+ memcpy(c_info->ssr, card->raw_ssr, ARRAY_SIZE(c_info->ssr)); 30709+ 30710+ c_info->card_connect = CARD_CONNECT; 30711+out: 30712+ return 0; 30713+} 30714+ 30715 static const struct mmc_host_ops sdhci_ops = { 30716 .request = sdhci_request, 30717 .post_req = sdhci_post_req, 30718@@ -2981,6 +3140,7 @@ static const struct mmc_host_ops sdhci_ops = { 30719 .execute_tuning = sdhci_execute_tuning, 30720 .card_event = sdhci_card_event, 30721 .card_busy = sdhci_card_busy, 30722+ .card_info_save = sdhci_card_info_save, 30723 }; 30724 30725 /*****************************************************************************\ 30726@@ -3039,6 +3199,9 @@ static bool sdhci_request_done(struct sdhci_host *host) 30727 host->pending_reset = false; 30728 } 30729 30730+ if (mrq->data && mrq->data->error && !host->is_tuning) 30731+ host->error_count++; 30732+ 30733 /* 30734 * Always unmap the data buffers if they were mapped by 30735 * sdhci_prepare_data() whenever we finish with a request. 30736@@ -3181,6 +3344,24 @@ static void sdhci_timeout_data_timer(struct timer_list *t) 30737 * * 30738 \*****************************************************************************/ 30739 30740+static void __sdhci_handle_auto_cmd_err(struct sdhci_host *host, u32 *intmask) 30741+{ 30742+ if (*intmask & SDHCI_INT_AUTO_CMD_ERR) { 30743+ u16 acmd_stat = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS); 30744+ if (acmd_stat & (SDHCI_AUTO_CMD12_NOT_EXEC | 30745+ SDHCI_AUTO_CMD_INDEX | 30746+ SDHCI_AUTO_CMD12_NOT_ISSUED)) 30747+ host->cmd->error = -EIO; 30748+ else if (acmd_stat & SDHCI_AUTO_CMD_TIMEOUT) 30749+ host->cmd->error = -ETIMEDOUT; 30750+ else 30751+ host->cmd->error = -EILSEQ; 30752+ 30753+ } else { 30754+ host->cmd->error = -EILSEQ; 30755+ } 30756+} 30757+ 30758 static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) 30759 { 30760 /* Handle auto-CMD12 error */ 30761@@ -3206,18 +3387,21 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) 30762 */ 30763 if (host->pending_reset) 30764 return; 30765- pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", 30766+ 30767+ /*pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", 30768 mmc_hostname(host->mmc), (unsigned)intmask); 30769- sdhci_dumpregs(host); 30770+ sdhci_dumpregs(host);*/ 30771+ 30772 return; 30773 } 30774 30775 if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | 30776- SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) { 30777+ SDHCI_INT_END_BIT | SDHCI_INT_INDEX | 30778+ SDHCI_INT_AUTO_CMD_ERR)) { 30779 if (intmask & SDHCI_INT_TIMEOUT) 30780 host->cmd->error = -ETIMEDOUT; 30781 else 30782- host->cmd->error = -EILSEQ; 30783+ __sdhci_handle_auto_cmd_err(host, &intmask); 30784 30785 /* Treat data command CRC error the same as data CRC error */ 30786 if (host->cmd->data && 30787@@ -3442,6 +3626,9 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) 30788 do { 30789 DBG("IRQ status 0x%08x\n", intmask); 30790 30791+ if ((intmask & SDHCI_INT_ERROR) && !host->is_tuning) 30792+ host->error_count++; 30793+ 30794 if (host->ops->irq) { 30795 intmask = host->ops->irq(host, intmask); 30796 if (!intmask) 30797@@ -3801,10 +3988,11 @@ void sdhci_cqe_enable(struct mmc_host *mmc) 30798 { 30799 struct sdhci_host *host = mmc_priv(mmc); 30800 unsigned long flags; 30801+#ifndef CONFIG_MMC_SDHCI_HISI 30802 u8 ctrl; 30803- 30804+#endif 30805 spin_lock_irqsave(&host->lock, flags); 30806- 30807+#ifndef CONFIG_MMC_SDHCI_HISI 30808 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 30809 ctrl &= ~SDHCI_CTRL_DMA_MASK; 30810 /* 30811@@ -3822,7 +4010,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc) 30812 30813 sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary, 512), 30814 SDHCI_BLOCK_SIZE); 30815- 30816+#endif 30817 /* Set maximum timeout */ 30818 sdhci_set_timeout(host, NULL); 30819 30820@@ -4099,6 +4287,72 @@ static void sdhci_allocate_bounce_buffer(struct sdhci_host *host) 30821 mmc_hostname(mmc), max_blocks, bounce_size); 30822 } 30823 30824+static void __sdhci_support_adma3(struct sdhci_host *host) 30825+{ 30826+ if ((host->version >= SDHCI_SPEC_400) && 30827+ (host->caps1 & SDHCI_CAN_DO_ADMA3)) 30828+ host->flags |= SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE; 30829+ 30830+ if ((host->quirks2 & SDHCI_QUIRK2_BROKEN_ADMA3) && 30831+ (host->flags & SDHCI_USE_ADMA3)) { 30832+ DBG("Disabling ADMA3 as it is marked broken\n"); 30833+ host->flags &= ~(SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE); 30834+ } 30835+} 30836+ 30837+static void __sdhci_set_dma_descriptor_size(struct sdhci_host *host) 30838+{ 30839+ if (host->flags & SDHCI_HOST_VER4_ENABLE) 30840+ host->desc_sz = 16; //descriptor size 16 30841+ else 30842+ host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; 30843+} 30844+ 30845+static void __sdhci_set_adma_cmd_table(struct sdhci_host *host, 30846+ void *buf, dma_addr_t *dma, struct mmc_host *mmc) 30847+{ 30848+ if (!(host->flags & SDHCI_USE_ADMA)) 30849+ host->flags &= ~SDHCI_USE_ADMA3; 30850+ 30851+ if (host->flags & SDHCI_USE_ADMA3) { 30852+#define MAX_CMD_NUM 32 30853+#define SDHCI_CMD_DESC_SZ 16 30854+ if (host->flags & SDHCI_USE_64_BIT_DMA) 30855+ host->adma3_desc_sz = SDHCI_ADMA3_64_DESC_SZ; 30856+ else 30857+ host->adma3_desc_sz = SDHCI_ADMA3_32_DESC_SZ; 30858+ 30859+ host->adma3_table_sz = MAX_CMD_NUM * host->adma3_desc_sz; 30860+ host->cmd_table_sz = MAX_CMD_NUM * 30861+ (SDHCI_CMD_DESC_SZ + 16); // offset 16 30862+ buf = dma_alloc_coherent(mmc_dev(mmc), host->adma3_table_sz + 30863+ host->cmd_table_sz, dma, GFP_KERNEL); 30864+ if (!buf) { 30865+ pr_warn("%s: Unable to allocate ADMA3 buffers - falling back \ 30866+ to standard DMA\n", mmc_hostname(mmc)); 30867+ host->flags &= ~SDHCI_USE_ADMA3; 30868+ } else { 30869+ host->adma3_table = buf; 30870+ host->adma3_addr = *dma; 30871+ 30872+ host->cmd_table = buf + host->adma3_desc_sz; 30873+ host->cmd_addr = *dma + host->adma3_desc_sz; 30874+ } 30875+ } 30876+} 30877+ 30878+static void __sdhci_release_adma3_cmd_table(struct sdhci_host *host, 30879+ struct mmc_host *mmc) 30880+{ 30881+ if (host->adma3_table) 30882+ dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz + 30883+ host->cmd_table_sz, host->adma3_table, 30884+ host->adma3_addr); 30885+ 30886+ host->adma3_table = NULL; 30887+ host->cmd_table = NULL; 30888+} 30889+ 30890 static inline bool sdhci_can_64bit_dma(struct sdhci_host *host) 30891 { 30892 /* 30893@@ -4180,6 +4434,8 @@ int sdhci_setup_host(struct sdhci_host *host) 30894 host->flags &= ~SDHCI_USE_ADMA; 30895 } 30896 30897+ __sdhci_support_adma3(host); 30898+ 30899 if (sdhci_can_64bit_dma(host)) 30900 host->flags |= SDHCI_USE_64_BIT_DMA; 30901 30902@@ -4258,6 +4514,7 @@ int sdhci_setup_host(struct sdhci_host *host) 30903 host->adma_table = buf + host->align_buffer_sz; 30904 host->adma_addr = dma + host->align_buffer_sz; 30905 } 30906+ __sdhci_set_adma_cmd_table(host, buf, &dma, mmc); 30907 } 30908 30909 /* 30910@@ -4506,7 +4763,6 @@ int sdhci_setup_host(struct sdhci_host *host) 30911 if (!max_current_caps && !IS_ERR(mmc->supply.vmmc)) { 30912 int curr = regulator_get_current_limit(mmc->supply.vmmc); 30913 if (curr > 0) { 30914- 30915 /* convert to SDHCI_MAX_CURRENT format */ 30916 curr = curr/1000; /* convert to mA */ 30917 curr = curr/SDHCI_MAX_CURRENT_MULTIPLIER; 30918@@ -4659,6 +4915,8 @@ int sdhci_setup_host(struct sdhci_host *host) 30919 host->adma_table = NULL; 30920 host->align_buffer = NULL; 30921 30922+ __sdhci_release_adma3_cmd_table(host, mmc); 30923+ 30924 return ret; 30925 } 30926 EXPORT_SYMBOL_GPL(sdhci_setup_host); 30927@@ -4680,6 +4938,8 @@ void sdhci_cleanup_host(struct sdhci_host *host) 30928 30929 host->adma_table = NULL; 30930 host->align_buffer = NULL; 30931+ 30932+ __sdhci_release_adma3_cmd_table(host, mmc); 30933 } 30934 EXPORT_SYMBOL_GPL(sdhci_cleanup_host); 30935 30936@@ -4729,6 +4989,7 @@ int __sdhci_add_host(struct sdhci_host *host) 30937 30938 pr_info("%s: SDHCI controller on %s [%s] using %s\n", 30939 mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), 30940+ (host->flags & SDHCI_USE_ADMA3) ? "ADMA3" : 30941 host->use_external_dma ? "External DMA" : 30942 (host->flags & SDHCI_USE_ADMA) ? 30943 (host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" : 30944@@ -4794,6 +5055,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) 30945 30946 sdhci_disable_card_detection(host); 30947 30948+ free_irq(host->irq, host); 30949+ 30950 mmc_remove_host(mmc); 30951 30952 sdhci_led_unregister(host); 30953@@ -4803,7 +5066,6 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) 30954 30955 sdhci_writel(host, 0, SDHCI_INT_ENABLE); 30956 sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); 30957- free_irq(host->irq, host); 30958 30959 del_timer_sync(&host->timer); 30960 del_timer_sync(&host->data_timer); 30961@@ -4823,6 +5085,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) 30962 30963 host->adma_table = NULL; 30964 host->align_buffer = NULL; 30965+ 30966+ __sdhci_release_adma3_cmd_table(host, mmc); 30967 } 30968 30969 EXPORT_SYMBOL_GPL(sdhci_remove_host); 30970diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h 30971index 960fed785..4688a612b 100644 30972--- a/drivers/mmc/host/sdhci.h 30973+++ b/drivers/mmc/host/sdhci.h 30974@@ -140,6 +140,7 @@ 30975 #define SDHCI_INT_CARD_INT 0x00000100 30976 #define SDHCI_INT_RETUNE 0x00001000 30977 #define SDHCI_INT_CQE 0x00004000 30978+#define SDHCI_INT_CQE 0x00004000 30979 #define SDHCI_INT_ERROR 0x00008000 30980 #define SDHCI_INT_TIMEOUT 0x00010000 30981 #define SDHCI_INT_CRC 0x00020000 30982@@ -173,10 +174,12 @@ 30983 #define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE) 30984 30985 #define SDHCI_AUTO_CMD_STATUS 0x3C 30986+#define SDHCI_AUTO_CMD12_NOT_EXEC 0x0001 30987 #define SDHCI_AUTO_CMD_TIMEOUT 0x00000002 30988 #define SDHCI_AUTO_CMD_CRC 0x00000004 30989 #define SDHCI_AUTO_CMD_END_BIT 0x00000008 30990 #define SDHCI_AUTO_CMD_INDEX 0x00000010 30991+#define SDHCI_AUTO_CMD12_NOT_ISSUED 0x0080 30992 30993 #define SDHCI_HOST_CONTROL2 0x3E 30994 #define SDHCI_CTRL_UHS_MASK 0x0007 30995@@ -185,7 +188,7 @@ 30996 #define SDHCI_CTRL_UHS_SDR50 0x0002 30997 #define SDHCI_CTRL_UHS_SDR104 0x0003 30998 #define SDHCI_CTRL_UHS_DDR50 0x0004 30999-#define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ 31000+#define SDHCI_CTRL_HS400 0x0007 /* Non-standard */ 31001 #define SDHCI_CTRL_VDD_180 0x0008 31002 #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 31003 #define SDHCI_CTRL_DRV_TYPE_B 0x0000 31004@@ -194,6 +197,9 @@ 31005 #define SDHCI_CTRL_DRV_TYPE_D 0x0030 31006 #define SDHCI_CTRL_EXEC_TUNING 0x0040 31007 #define SDHCI_CTRL_TUNED_CLK 0x0080 31008+#define SDHCI_CTRL_HOST_VER4_ENABLE 0x1000 31009+#define SDHCI_CTRL_ADDRESSING_64BIT 0x2000 31010+#define SDHCI_CTRL_ASYNC_INT_ENABLE 0x4000 31011 #define SDHCI_CMD23_ENABLE 0x0800 31012 #define SDHCI_CTRL_V4_MODE 0x1000 31013 #define SDHCI_CTRL_64BIT_ADDR 0x2000 31014@@ -217,6 +223,7 @@ 31015 #define SDHCI_CAN_VDD_180 0x04000000 31016 #define SDHCI_CAN_64BIT_V4 0x08000000 31017 #define SDHCI_CAN_64BIT 0x10000000 31018+#define SDHCI_CAN_ASYNC_INT 0x20000000 31019 31020 #define SDHCI_CAPABILITIES_1 0x44 31021 #define SDHCI_SUPPORT_SDR50 0x00000001 31022@@ -264,6 +271,9 @@ 31023 #define SDHCI_PRESET_CLKGEN_SEL BIT(10) 31024 #define SDHCI_PRESET_SDCLK_FREQ_MASK GENMASK(9, 0) 31025 31026+#define SDHCI_ADMA3_ID_ADDR_LOW 0x78 31027+#define SDHCI_ADMA3_ID_ADDR_HI 0x7C 31028+ 31029 #define SDHCI_SLOT_INT_STATUS 0xFC 31030 31031 #define SDHCI_HOST_VERSION 0xFE 31032@@ -290,6 +300,7 @@ 31033 */ 31034 #define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024) 31035 #define SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12) 31036+#define SDHCI_DMA_BOUNDARY_SIZE (0x1 << 27) 31037 31038 /* ADMA2 32-bit DMA descriptor size */ 31039 #define SDHCI_ADMA2_32_DESC_SZ 8 31040@@ -321,6 +332,12 @@ struct sdhci_adma2_32_desc { 31041 */ 31042 #define SDHCI_ADMA2_64_DESC_SZ(host) ((host)->v4_mode ? 16 : 12) 31043 31044+/* ADMA3 32-bit DMA descriptor size */ 31045+#define SDHCI_ADMA3_32_DESC_SZ 8 31046+ 31047+/* ADMA3 64-bit DMA descriptor size */ 31048+#define SDHCI_ADMA3_64_DESC_SZ 16 31049+ 31050 /* 31051 * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte 31052 * aligned. 31053@@ -335,6 +352,9 @@ struct sdhci_adma2_64_desc { 31054 #define ADMA2_TRAN_VALID 0x21 31055 #define ADMA2_NOP_END_VALID 0x3 31056 #define ADMA2_END 0x2 31057+#define ADMA2_LINK_VALID 0x31 31058+#define ADMA3_CMD_VALID 0x9 31059+#define ADMA3_END 0x3b 31060 31061 /* 31062 * Maximum segments assuming a 512KiB maximum requisition size and a minimum 31063@@ -359,6 +379,19 @@ enum sdhci_cookie { 31064 COOKIE_MAPPED, /* mapped by sdhci_prepare_data() */ 31065 }; 31066 31067+struct card_info { 31068+ unsigned int card_type; 31069+ unsigned char timing; 31070+ bool enhanced_strobe; 31071+ unsigned char card_connect; 31072+#define CARD_CONNECT 1 31073+#define CARD_DISCONNECT 0 31074+ unsigned int card_support_clock; /* clock rate */ 31075+ unsigned int card_state; /* (our) card state */ 31076+ unsigned int sd_bus_speed; 31077+ unsigned int ssr[16]; 31078+}; 31079+ 31080 struct sdhci_host { 31081 /* Data set by hardware interface driver */ 31082 const char *hw_name; /* Hardware bus name */ 31083@@ -460,6 +493,7 @@ struct sdhci_host { 31084 #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) 31085 /* Broken Clock divider zero in controller */ 31086 #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) 31087+#define SDHCI_QUIRK2_BROKEN_ADMA3 (1<<16) 31088 /* Controller has CRC in 136 bit Command Response */ 31089 #define SDHCI_QUIRK2_RSP_136_HAS_CRC (1<<16) 31090 /* 31091@@ -510,6 +544,8 @@ struct sdhci_host { 31092 #define SDHCI_SIGNALING_330 (1<<14) /* Host is capable of 3.3V signaling */ 31093 #define SDHCI_SIGNALING_180 (1<<15) /* Host is capable of 1.8V signaling */ 31094 #define SDHCI_SIGNALING_120 (1<<16) /* Host is capable of 1.2V signaling */ 31095+#define SDHCI_USE_ADMA3 (1<<17) /* Host is ADMA3 capable */ 31096+#define SDHCI_HOST_VER4_ENABLE (1<<18) /* Host version 4 enable */ 31097 31098 unsigned int version; /* SDHCI spec. version */ 31099 31100@@ -543,14 +579,21 @@ struct sdhci_host { 31101 31102 void *adma_table; /* ADMA descriptor table */ 31103 void *align_buffer; /* Bounce buffer */ 31104+ void *adma3_table; /* ADMA3 integrated descriptor table */ 31105+ void *cmd_table; /* ADMA3 command descriptor table */ 31106 31107 size_t adma_table_sz; /* ADMA descriptor table size */ 31108 size_t align_buffer_sz; /* Bounce buffer size */ 31109+ size_t adma3_table_sz; /* ADMA3 integrated descriptor table size */ 31110+ size_t cmd_table_sz; /* ADMA3 command descriptor table size */ 31111 31112 dma_addr_t adma_addr; /* Mapped ADMA descr. table */ 31113 dma_addr_t align_addr; /* Mapped bounce buffer */ 31114+ dma_addr_t adma3_addr; /* Mapped ADMA3 integrated descr. table */ 31115+ dma_addr_t cmd_addr; /* Mapped ADMA3 command descr. table */ 31116 31117 unsigned int desc_sz; /* ADMA current descriptor size */ 31118+ unsigned int adma3_desc_sz; /* ADMA3 integrated descriptor size */ 31119 unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */ 31120 31121 struct workqueue_struct *complete_wq; /* Request completion wq */ 31122@@ -606,6 +649,10 @@ struct sdhci_host { 31123 31124 u64 data_timeout; 31125 31126+ u32 is_tuning; 31127+ unsigned int error_count; 31128+ struct card_info c_info; 31129+ 31130 unsigned long private[] ____cacheline_aligned; 31131 }; 31132 31133@@ -645,6 +692,9 @@ struct sdhci_ops { 31134 void (*adma_workaround)(struct sdhci_host *host, u32 intmask); 31135 void (*card_event)(struct sdhci_host *host); 31136 void (*voltage_switch)(struct sdhci_host *host); 31137+ void (*init)(struct sdhci_host *host); 31138+ int (*start_signal_voltage_switch)(struct sdhci_host *host, 31139+ struct mmc_ios *ios); 31140 void (*adma_write_desc)(struct sdhci_host *host, void **desc, 31141 dma_addr_t addr, int len, unsigned int cmd); 31142 void (*copy_to_bounce_buffer)(struct sdhci_host *host, 31143diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile 31144index 593d0593a..cdf3ff323 100644 31145--- a/drivers/mtd/Makefile 31146+++ b/drivers/mtd/Makefile 31147@@ -26,8 +26,9 @@ obj-$(CONFIG_MTD_SWAP) += mtdswap.o 31148 nftl-objs := nftlcore.o nftlmount.o 31149 inftl-objs := inftlcore.o inftlmount.o 31150 31151-obj-y += chips/ lpddr/ maps/ devices/ nand/ tests/ 31152 31153 obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ 31154+obj-y += chips/ lpddr/ maps/ devices/ nand/ tests/ 31155+ 31156 obj-$(CONFIG_MTD_UBI) += ubi/ 31157 obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ 31158diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig 31159index 4a9aed4f0..5c3e95668 100644 31160--- a/drivers/mtd/nand/Kconfig 31161+++ b/drivers/mtd/nand/Kconfig 31162@@ -6,7 +6,32 @@ config MTD_NAND_CORE 31163 tristate 31164 31165 source "drivers/mtd/nand/onenand/Kconfig" 31166+ 31167+config MTD_SPI_NAND_HISI_BVT 31168+ tristate "Support for SPI NAND controller on Hisilicon SoCs" 31169+ depends on MTD_NAND 31170+ help 31171+ Enables support for the SPI NAND device drivers. 31172+ 31173+config HISI_NAND_ECC_STATUS_REPORT 31174+ tristate "Report the ecc status to MTD for HiSilicon Nand Driver" 31175+ depends on MTD_NAND && ARCH_HISI_BVT 31176+ default n 31177+ help 31178+ Flash Memory Controller reports the ecc status include ECC error 31179+ and ECC corrected to MTD to monitor the aging of devices. 31180+ 31181+config HISI_NAND_FS_MAY_NO_YAFFS2 31182+ bool "Remove the restraintion of 16bit ecc type on yaffs2 to HiSilicon" 31183+ depends on MFD_HISI_FMC 31184+ default n 31185+ help 31186+ The ecc type: 16bit is limited by the HiSilicon flash memory controller, 31187+ as the yaffs2 tag of hisi rootfs limits the min size of CTRL len is 28. 31188+ 31189 source "drivers/mtd/nand/raw/Kconfig" 31190+source "drivers/mtd/nand/hifmc100/Kconfig" 31191+source "drivers/mtd/nand/hifmc100_nand/Kconfig" 31192 source "drivers/mtd/nand/spi/Kconfig" 31193 31194 menu "ECC engine support" 31195diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile 31196index 981372953..4fb87a5c3 100644 31197--- a/drivers/mtd/nand/Makefile 31198+++ b/drivers/mtd/nand/Makefile 31199@@ -1,6 +1,8 @@ 31200 # SPDX-License-Identifier: GPL-2.0 31201 31202 nandcore-objs := core.o bbt.o 31203+obj-$(CONFIG_MTD_NAND_HIFMC100) += hifmc100_nand/ 31204+obj-$(CONFIG_MTD_SPI_NAND_HIFMC100) += hifmc100/ 31205 obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o 31206 31207 obj-y += onenand/ 31208diff --git a/drivers/mtd/nand/hifmc100/Kconfig b/drivers/mtd/nand/hifmc100/Kconfig 31209new file mode 100644 31210index 000000000..5b15bc8b9 31211--- /dev/null 31212+++ b/drivers/mtd/nand/hifmc100/Kconfig 31213@@ -0,0 +1,17 @@ 31214+# 31215+# hisilicon flash memory controller SPI nand device driver version 100 31216+# drivers/mtd/nand/hifmc100/Kconfig 31217+# add by hisilicon 2017.8.7 31218+# 31219+ 31220+config MTD_SPI_NAND_HIFMC100 31221+ bool "Hisilicon Flash Memory Controller v100 SPI Nand devices support" 31222+ depends on MFD_HISI_FMC && MTD_SPI_NAND_HISI_BVT 31223+ select MISC_FILESYSTEMS 31224+ select MTD_BLOCK 31225+ select YAFFS_FS 31226+ select YAFFS_YAFFS2 31227+ help 31228+ Hisilicon Flash Memory Controller version 100 is called hifmc100 for 31229+ short. The controller driver support registers and DMA transfers 31230+ while reading or writing the SPI nand flash. 31231diff --git a/drivers/mtd/nand/hifmc100/Makefile b/drivers/mtd/nand/hifmc100/Makefile 31232new file mode 100644 31233index 000000000..b1fda5de8 31234--- /dev/null 31235+++ b/drivers/mtd/nand/hifmc100/Makefile 31236@@ -0,0 +1,26 @@ 31237+# 31238+# The Flash Memory Controller v100 Device Driver for hisilicon 31239+# 31240+# Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 31241+# 31242+# This program is free software; you can redistribute it and/or modify it 31243+# under the terms of the GNU General Public License as published by the 31244+# Free Software Foundation; either version 2 of the License, or (at your 31245+# option) any later version. 31246+# 31247+# This program is distributed in the hope that it will be useful, 31248+# but WITHOUT ANY WARRANTY; without even the implied warranty of 31249+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31250+# GNU General Public License for more details. 31251+# 31252+# You should have received a copy of the GNU General Public License 31253+# along with this program. If not, see <http://www.gnu.org/licenses/>. 31254+# 31255+# 31256+ 31257+# 31258+# drivers/mtd/nand/hifmc100/Makefile 31259+# 31260+ 31261+obj-y += hifmc_spi_nand_ids.o 31262+obj-y += hifmc100.o hifmc100_os.o 31263diff --git a/drivers/mtd/nand/hifmc100/hifmc100.c b/drivers/mtd/nand/hifmc100/hifmc100.c 31264new file mode 100644 31265index 000000000..6cb12d3b6 31266--- /dev/null 31267+++ b/drivers/mtd/nand/hifmc100/hifmc100.c 31268@@ -0,0 +1,1218 @@ 31269+/* 31270+ * The Flash Memory Controller v100 Device Driver for hisilicon 31271+ * 31272+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 31273+ * 31274+ * This program is free software; you can redistribute it and/or modify it 31275+ * under the terms of the GNU General Public License as published by the 31276+ * Free Software Foundation; either version 2 of the License, or (at your 31277+ * option) any later version. 31278+ * 31279+ * This program is distributed in the hope that it will be useful, 31280+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 31281+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31282+ * GNU General Public License for more details. 31283+ * 31284+ * You should have received a copy of the GNU General Public License 31285+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 31286+ * 31287+ */ 31288+ 31289+#include <linux/kernel.h> 31290+#include <linux/module.h> 31291+#include <linux/clk.h> 31292+#include <linux/io.h> 31293+#include <linux/errno.h> 31294+#include <linux/slab.h> 31295+#include <linux/mtd/rawnand.h> 31296+#include <linux/delay.h> 31297+#include <linux/sched.h> 31298+#include <asm/setup.h> 31299+ 31300+#include "../raw/hinfc_gen.h" 31301+#include "hifmc100.h" 31302+#include <linux/mfd/hisi_fmc.h> 31303+ 31304+static void hifmc100_switch_to_spi_nand(struct hifmc_host *host) 31305+{ 31306+ u32 reg; 31307+ 31308+ reg = hifmc_readl(host, FMC_CFG); 31309+ reg &= ~FLASH_TYPE_SEL_MASK; 31310+ reg |= FMC_CFG_FLASH_SEL(FLASH_TYPE_SPI_NAND); 31311+ hifmc_writel(host, FMC_CFG, reg); 31312+} 31313+ 31314+static void hifmc100_set_str_mode(const struct hifmc_host *host) 31315+{ 31316+ u32 reg; 31317+ 31318+ reg = hifmc_readl(host, FMC_GLOBAL_CFG); 31319+ reg &= (~FMC_GLOBAL_CFG_DTR_MODE); 31320+ hifmc_writel(host, FMC_GLOBAL_CFG, reg); 31321+} 31322+ 31323+static void hifmc100_operation_config(struct hifmc_host *host, int op) 31324+{ 31325+ int ret; 31326+ unsigned long clkrate = 0; 31327+ struct hifmc_spi *spi = host->spi; 31328+ 31329+ hifmc100_switch_to_spi_nand(host); 31330+ clk_prepare_enable(host->clk); 31331+ switch (op) { 31332+ case OP_STYPE_WRITE: 31333+ clkrate = min((u_long)host->clkrate, 31334+ (u_long)CLK_FMC_TO_CRG_MHZ(spi->write->clock)); 31335+ break; 31336+ case OP_STYPE_READ: 31337+ clkrate = min((u_long)host->clkrate, 31338+ (u_long)CLK_FMC_TO_CRG_MHZ(spi->read->clock)); 31339+ break; 31340+ case OP_STYPE_ERASE: 31341+ clkrate = min((u_long)host->clkrate, 31342+ (u_long)CLK_FMC_TO_CRG_MHZ(spi->erase->clock)); 31343+ break; 31344+ default: 31345+ break; 31346+ } 31347+ 31348+ ret = clk_set_rate(host->clk, clkrate); 31349+ if (WARN_ON(ret)) { 31350+ pr_err("clk_set_rate failed: %d\n", ret); 31351+ } 31352+} 31353+ 31354+static void hifmc100_send_cmd_write(struct hifmc_host *host) 31355+{ 31356+ unsigned char pages_per_block_shift; 31357+ unsigned int reg, block_num, block_num_h, page_num; 31358+ int ret; 31359+ struct hifmc_spi *spi = host->spi; 31360+ struct nand_chip *chip = host->chip; 31361+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE 31362+ const char *op = "Reg"; 31363+#else 31364+ const char *op = "Dma"; 31365+#endif 31366+ 31367+ if (WR_DBG) { 31368+ pr_info("\n"); 31369+ } 31370+ FMC_PR(WR_DBG, "*-Start send %s page write command\n", op); 31371+ 31372+ mutex_lock(host->lock); 31373+ hifmc100_operation_config(host, OP_STYPE_WRITE); 31374+ 31375+ ret = spi->driver->wait_ready(spi); 31376+ if (ret) { 31377+ DB_MSG("Error: %s program wait ready failed! status: %#x\n", 31378+ op, ret); 31379+ goto end; 31380+ } 31381+ 31382+ ret = spi->driver->write_enable(spi); 31383+ if (ret) { 31384+ DB_MSG("Error: %s program write enable failed! ret: %#x\n", 31385+ op, ret); 31386+ goto end; 31387+ } 31388+ 31389+ reg = FMC_INT_CLR_ALL; 31390+ hifmc_writel(host, FMC_INT_CLR, reg); 31391+ FMC_PR(WR_DBG, "|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); 31392+ 31393+ reg = OP_CFG_FM_CS(host->cmd_op.cs) 31394+ | OP_CFG_MEM_IF_TYPE(spi->write->iftype) 31395+ | OP_CFG_OEN_EN; 31396+ hifmc_writel(host, FMC_OP_CFG, reg); 31397+ FMC_PR(WR_DBG, "|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 31398+ 31399+ pages_per_block_shift = chip->phys_erase_shift - chip->page_shift; 31400+ block_num = host->addr_value[1] >> pages_per_block_shift; 31401+ block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT; 31402+ reg = FMC_ADDRH_SET(block_num_h); 31403+ hifmc_writel(host, FMC_ADDRH, reg); 31404+ FMC_PR(WR_DBG, "|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); 31405+ 31406+ page_num = host->addr_value[1] - (block_num << pages_per_block_shift); 31407+ reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT) 31408+ | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT); 31409+ hifmc_writel(host, FMC_ADDRL, reg); 31410+ FMC_PR(WR_DBG, "|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 31411+ 31412+ *host->epm = 0x0000; 31413+ 31414+#ifndef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE 31415+ reg = host->dma_buffer; 31416+ hifmc_writel(host, FMC_DMA_SADDR_D0, reg); 31417+ FMC_PR(WR_DBG, "|-Set DMA_SADDR_D[0x40]%#x\n", reg); 31418+ 31419+#ifdef CONFIG_64BIT 31420+ reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32; 31421+ hifmc_writel(host, FMC_DMA_SADDRH_D0, reg); 31422+ FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg); 31423+#endif 31424+ 31425+ reg = host->dma_oob; 31426+ hifmc_writel(host, FMC_DMA_SADDR_OOB, reg); 31427+ FMC_PR(WR_DBG, "|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, reg); 31428+#ifdef CONFIG_64BIT 31429+ reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32; 31430+ hifmc_writel(host, FMC_DMA_SADDRH_OOB, reg); 31431+ FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB, 31432+ reg); 31433+#endif 31434+#endif 31435+ 31436+ reg = OP_CTRL_WR_OPCODE(spi->write->cmd) 31437+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE 31438+ | OP_CTRL_DMA_OP(OP_TYPE_REG) 31439+#else 31440+ | OP_CTRL_DMA_OP(OP_TYPE_DMA) 31441+#endif 31442+ | OP_CTRL_RW_OP(RW_OP_WRITE) 31443+ | OP_CTRL_DMA_OP_READY; 31444+ hifmc_writel(host, FMC_OP_CTRL, reg); 31445+ FMC_PR(WR_DBG, "|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg); 31446+ 31447+ FMC_DMA_WAIT_INT_FINISH(host); 31448+ 31449+end: 31450+ mutex_unlock(host->lock); 31451+ FMC_PR(WR_DBG, "*-End %s page program!\n", op); 31452+} 31453+ 31454+static void hifmc100_send_cmd_status(struct hifmc_host *host) 31455+{ 31456+ u_char status; 31457+ int ret; 31458+ unsigned char addr = STATUS_ADDR; 31459+ struct hifmc_spi *spi = NULL; 31460+ 31461+ if(host == NULL || host->spi == NULL) { 31462+ DB_MSG("Error: host or host->spi is NULL!\n"); 31463+ return; 31464+ } 31465+ spi = host->spi; 31466+ if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) { 31467+ addr = PROTECT_ADDR; 31468+ } 31469+ 31470+ ret = spi_nand_feature_op(spi, GET_OP, addr, &status); 31471+ if (ret) 31472+ return; 31473+ FMC_PR((ER_DBG || WR_DBG), "\t*-Get status[%#x]: %#x\n", addr, status); 31474+} 31475+ 31476+static void hifmc100_send_cmd_read(struct hifmc_host *host) 31477+{ 31478+ unsigned char pages_per_block_shift; 31479+ unsigned int reg, block_num, block_num_h, page_num; 31480+ struct hifmc_spi *spi = host->spi; 31481+ struct nand_chip *chip = host->chip; 31482+ int ret; 31483+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_READ 31484+ char *op = "Reg"; 31485+#else 31486+ char *op = "Dma"; 31487+#endif 31488+ 31489+ if (RD_DBG) { 31490+ pr_info("\n"); 31491+ } 31492+ FMC_PR(RD_DBG, "\t*-Start %s page read\n", op); 31493+ 31494+ if ((host->addr_value[0] == host->cache_addr_value[0]) 31495+ && (host->addr_value[1] == host->cache_addr_value[1])) { 31496+ FMC_PR(RD_DBG, "\t*-%s read cache hit, addr[%#x %#x]\n", 31497+ op, host->addr_value[1], host->addr_value[0]); 31498+ return; 31499+ } 31500+ 31501+ mutex_lock(host->lock); 31502+ hifmc100_operation_config(host, OP_STYPE_READ); 31503+ 31504+ FMC_PR(RD_DBG, "\t|-Wait ready before %s page read\n", op); 31505+ ret = spi->driver->wait_ready(spi); 31506+ if (ret) { 31507+ DB_MSG("Error: %s read wait ready fail! ret: %#x\n", op, ret); 31508+ goto end; 31509+ } 31510+ 31511+ reg = FMC_INT_CLR_ALL; 31512+ hifmc_writel(host, FMC_INT_CLR, reg); 31513+ FMC_PR(RD_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); 31514+ 31515+ if (host->cmd_op.l_cmd == NAND_CMD_READOOB) 31516+ host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_OOB); 31517+ else 31518+ host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_ALL_PAGE); 31519+ 31520+ reg = OP_CFG_FM_CS(host->cmd_op.cs) 31521+ | OP_CFG_MEM_IF_TYPE(spi->read->iftype) 31522+ | OP_CFG_DUMMY_NUM(spi->read->dummy) 31523+ | OP_CFG_OEN_EN; 31524+ hifmc_writel(host, FMC_OP_CFG, reg); 31525+ FMC_PR(RD_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 31526+ 31527+ pages_per_block_shift = chip->phys_erase_shift - chip->page_shift; 31528+ block_num = host->addr_value[1] >> pages_per_block_shift; 31529+ block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT; 31530+ 31531+ reg = FMC_ADDRH_SET(block_num_h); 31532+ hifmc_writel(host, FMC_ADDRH, reg); 31533+ FMC_PR(RD_DBG, "\t|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); 31534+ 31535+ page_num = host->addr_value[1] - (block_num << pages_per_block_shift); 31536+ reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT) 31537+ | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT); 31538+ hifmc_writel(host, FMC_ADDRL, reg); 31539+ FMC_PR(RD_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 31540+ 31541+#ifndef HIFMC100_SPI_NAND_SUPPORT_REG_READ 31542+ reg = host->dma_buffer; 31543+ hifmc_writel(host, FMC_DMA_SADDR_D0, reg); 31544+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_D0[%#x]%#x\n", FMC_DMA_SADDR_D0, reg); 31545+ 31546+#ifdef CONFIG_64BIT 31547+ reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32; 31548+ hifmc_writel(host, FMC_DMA_SADDRH_D0, reg); 31549+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg); 31550+#endif 31551+ 31552+ reg = host->dma_oob; 31553+ hifmc_writel(host, FMC_DMA_SADDR_OOB, reg); 31554+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, 31555+ reg); 31556+ 31557+#ifdef CONFIG_64BIT 31558+ reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32; 31559+ hifmc_writel(host, FMC_DMA_SADDRH_OOB, reg); 31560+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB, 31561+ reg); 31562+#endif 31563+#endif 31564+ 31565+ reg = OP_CTRL_RD_OPCODE(spi->read->cmd) | host->cmd_op.op_cfg 31566+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_READ 31567+ | OP_CTRL_DMA_OP(OP_TYPE_REG) 31568+#else 31569+ | OP_CTRL_DMA_OP(OP_TYPE_DMA) 31570+#endif 31571+ | OP_CTRL_RW_OP(RW_OP_READ) | OP_CTRL_DMA_OP_READY; 31572+ hifmc_writel(host, FMC_OP_CTRL, reg); 31573+ FMC_PR(RD_DBG, "\t|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg); 31574+ 31575+ FMC_DMA_WAIT_INT_FINISH(host); 31576+ 31577+ host->cache_addr_value[0] = host->addr_value[0]; 31578+ host->cache_addr_value[1] = host->addr_value[1]; 31579+ 31580+end: 31581+ mutex_unlock(host->lock); 31582+ FMC_PR(RD_DBG, "\t*-End %s page read\n", op); 31583+} 31584+ 31585+static void hifmc100_send_cmd_erase(struct hifmc_host *host) 31586+{ 31587+ unsigned int reg; 31588+ struct hifmc_spi *spi = host->spi; 31589+ int ret; 31590+ 31591+ if (ER_DBG) { 31592+ pr_info("\n"); 31593+ } 31594+ FMC_PR(ER_DBG, "\t*-Start send cmd erase!\n"); 31595+ 31596+ mutex_lock(host->lock); 31597+ hifmc100_operation_config(host, OP_STYPE_ERASE); 31598+ 31599+ ret = spi->driver->wait_ready(spi); 31600+ FMC_PR(ER_DBG, "\t|-Erase wait ready, ret: %#x\n", ret); 31601+ if (ret) { 31602+ DB_MSG("Error: Erase wait ready fail! status: %#x\n", ret); 31603+ goto end; 31604+ } 31605+ 31606+ ret = spi->driver->write_enable(spi); 31607+ if (ret) { 31608+ DB_MSG("Error: Erase write enable failed! ret: %#x\n", ret); 31609+ goto end; 31610+ } 31611+ 31612+ reg = FMC_INT_CLR_ALL; 31613+ hifmc_writel(host, FMC_INT_CLR, reg); 31614+ FMC_PR(ER_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); 31615+ 31616+ reg = spi->erase->cmd; 31617+ hifmc_writel(host, FMC_CMD, FMC_CMD_CMD1(reg)); 31618+ FMC_PR(ER_DBG, "\t|-Set CMD[%#x]%#x\n", FMC_CMD, reg); 31619+ 31620+ reg = FMC_ADDRL_BLOCK_H_MASK(host->addr_value[1]) 31621+ | FMC_ADDRL_BLOCK_L_MASK(host->addr_value[0]); 31622+ hifmc_writel(host, FMC_ADDRL, reg); 31623+ FMC_PR(ER_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 31624+ 31625+ reg = OP_CFG_FM_CS(host->cmd_op.cs) 31626+ | OP_CFG_MEM_IF_TYPE(spi->erase->iftype) 31627+ | OP_CFG_ADDR_NUM(STD_OP_ADDR_NUM) 31628+ | OP_CFG_DUMMY_NUM(spi->erase->dummy) 31629+ | OP_CFG_OEN_EN; 31630+ hifmc_writel(host, FMC_OP_CFG, reg); 31631+ FMC_PR(ER_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 31632+ 31633+ reg = FMC_OP_CMD1_EN 31634+ | FMC_OP_ADDR_EN 31635+ | FMC_OP_REG_OP_START; 31636+ hifmc_writel(host, FMC_OP, reg); 31637+ FMC_PR(ER_DBG, "\t|-Set OP[%#x]%#x\n", FMC_OP, reg); 31638+ 31639+ FMC_CMD_WAIT_CPU_FINISH(host); 31640+ 31641+end: 31642+ mutex_unlock(host->lock); 31643+ FMC_PR(ER_DBG, "\t*-End send cmd erase!\n"); 31644+} 31645+ 31646+void hifmc100_ecc0_switch(struct hifmc_host *host, unsigned char op) 31647+{ 31648+ unsigned int config; 31649+#if EC_DBG 31650+ unsigned int cmp_cfg; 31651+ 31652+ if(host == NULL) { 31653+ DB_MSG("Error: host is NULL!\n"); 31654+ return; 31655+ } 31656+ config = hifmc_readl(host, FMC_CFG); 31657+ FMC_PR(EC_DBG, "\t *-Get CFG[%#x]%#x\n", FMC_CFG, config); 31658+ 31659+ if (op) { 31660+ cmp_cfg = host->fmc_cfg; 31661+ } else { 31662+ cmp_cfg = host->fmc_cfg_ecc0; 31663+ } 31664+ 31665+ if (cmp_cfg != config) 31666+ DB_MSG("Warning: FMC config[%#x] is different.\n", 31667+ cmp_cfg); 31668+#endif 31669+ if(host == NULL) { 31670+ DB_MSG("Error: host is NULL!\n"); 31671+ return; 31672+ } 31673+ if (op == ENABLE) { 31674+ config = host->fmc_cfg_ecc0; 31675+ } else if (op == DISABLE) { 31676+ config = host->fmc_cfg; 31677+ } else { 31678+ DB_MSG("Error: Invalid opcode: %d\n", op); 31679+ return; 31680+ } 31681+ 31682+ hifmc_writel(host, FMC_CFG, config); 31683+ FMC_PR(EC_DBG, "\t *-Set CFG[%#x]%#x\n", FMC_CFG, config); 31684+} 31685+ 31686+static void hifmc100_send_cmd_readid(struct hifmc_host *host) 31687+{ 31688+ unsigned int reg; 31689+ 31690+ FMC_PR(BT_DBG, "\t|*-Start send cmd read ID\n"); 31691+ 31692+ hifmc100_ecc0_switch(host, ENABLE); 31693+ 31694+ reg = FMC_CMD_CMD1(SPI_CMD_RDID); 31695+ hifmc_writel(host, FMC_CMD, reg); 31696+ FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); 31697+ 31698+ reg = READ_ID_ADDR; 31699+ hifmc_writel(host, FMC_ADDRL, reg); 31700+ FMC_PR(BT_DBG, "\t||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 31701+ 31702+ reg = OP_CFG_FM_CS(host->cmd_op.cs) 31703+ | OP_CFG_ADDR_NUM(READ_ID_ADDR_NUM) 31704+ | OP_CFG_OEN_EN; 31705+ hifmc_writel(host, FMC_OP_CFG, reg); 31706+ FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 31707+ 31708+ reg = FMC_DATA_NUM_CNT(MAX_SPI_NAND_ID_LEN); 31709+ hifmc_writel(host, FMC_DATA_NUM, reg); 31710+ FMC_PR(BT_DBG, "\t||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg); 31711+ 31712+ reg = FMC_OP_CMD1_EN 31713+ | FMC_OP_ADDR_EN 31714+ | FMC_OP_READ_DATA_EN 31715+ | FMC_OP_REG_OP_START; 31716+ hifmc_writel(host, FMC_OP, reg); 31717+ FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); 31718+ 31719+ host->addr_cycle = 0x0; 31720+ 31721+ FMC_CMD_WAIT_CPU_FINISH(host); 31722+ 31723+ hifmc100_ecc0_switch(host, DISABLE); 31724+ 31725+ FMC_PR(BT_DBG, "\t|*-End read flash ID\n"); 31726+} 31727+ 31728+static void hifmc100_send_cmd_reset(struct hifmc_host *host) 31729+{ 31730+ unsigned int reg; 31731+ 31732+ FMC_PR(BT_DBG, "\t|*-Start send cmd reset\n"); 31733+ 31734+ reg = FMC_CMD_CMD1(SPI_CMD_RESET); 31735+ hifmc_writel(host, FMC_CMD, reg); 31736+ FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); 31737+ 31738+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; 31739+ hifmc_writel(host, FMC_OP_CFG, reg); 31740+ FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 31741+ 31742+ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START; 31743+ hifmc_writel(host, FMC_OP, reg); 31744+ FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); 31745+ 31746+ FMC_CMD_WAIT_CPU_FINISH(host); 31747+ 31748+ FMC_PR(BT_DBG, "\t|*-End send cmd reset\n"); 31749+} 31750+ 31751+static void hifmc100_host_init(struct hifmc_host *host) 31752+{ 31753+ unsigned int reg; 31754+ 31755+ FMC_PR(BT_DBG, "\t||*-Start SPI Nand host init\n"); 31756+ 31757+ reg = hifmc_readl(host, FMC_CFG); 31758+ if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) { 31759+ reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL); 31760+ hifmc_writel(host, FMC_CFG, reg); 31761+ FMC_PR(BT_DBG, "\t|||-Set CFG[%#x]%#x\n", FMC_CFG, reg); 31762+ } 31763+ 31764+ host->fmc_cfg = reg; 31765+ host->fmc_cfg_ecc0 = (reg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; 31766+ 31767+ reg = hifmc_readl(host, FMC_GLOBAL_CFG); 31768+ if (reg & FMC_GLOBAL_CFG_WP_ENABLE) { 31769+ reg &= ~FMC_GLOBAL_CFG_WP_ENABLE; 31770+ hifmc_writel(host, FMC_GLOBAL_CFG, reg); 31771+ } 31772+ 31773+ host->addr_cycle = 0; 31774+ host->addr_value[0] = 0; 31775+ host->addr_value[1] = 0; 31776+ host->cache_addr_value[0] = ~0; 31777+ host->cache_addr_value[1] = ~0; 31778+ 31779+ host->send_cmd_write = hifmc100_send_cmd_write; 31780+ host->send_cmd_status = hifmc100_send_cmd_status; 31781+ host->send_cmd_read = hifmc100_send_cmd_read; 31782+ host->send_cmd_erase = hifmc100_send_cmd_erase; 31783+ host->send_cmd_readid = hifmc100_send_cmd_readid; 31784+ host->send_cmd_reset = hifmc100_send_cmd_reset; 31785+#ifdef CONFIG_PM 31786+ host->suspend = hifmc100_suspend; 31787+ host->resume = hifmc100_resume; 31788+#endif 31789+ 31790+ reg = TIMING_CFG_TCSH(CS_HOLD_TIME) 31791+ | TIMING_CFG_TCSS(CS_SETUP_TIME) 31792+ | TIMING_CFG_TSHSL(CS_DESELECT_TIME); 31793+ hifmc_writel(host, FMC_SPI_TIMING_CFG, reg); 31794+ 31795+ reg = ALL_BURST_ENABLE; 31796+ hifmc_writel(host, FMC_DMA_AHB_CTRL, reg); 31797+ 31798+ FMC_PR(BT_DBG, "\t||*-End SPI Nand host init\n"); 31799+} 31800+ 31801+static unsigned char hifmc100_read_byte(struct mtd_info *mtd) 31802+{ 31803+ struct nand_chip *chip = mtd_to_nand(mtd); 31804+ struct hifmc_host *host = chip->priv; 31805+ unsigned char value; 31806+ unsigned char ret_val = 0; 31807+ 31808+ if (host->cmd_op.l_cmd == NAND_CMD_READID) { 31809+ value = hifmc_readb(host->iobase + host->offset); 31810+ host->offset++; 31811+ if (host->cmd_op.data_no == host->offset) { 31812+ host->cmd_op.l_cmd = 0; 31813+ } 31814+ return value; 31815+ } 31816+ 31817+ if (host->cmd_op.cmd == NAND_CMD_STATUS) { 31818+ value = hifmc_readl(host, FMC_STATUS); 31819+ if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) { 31820+ FMC_PR((ER_DBG || WR_DBG), "\t\tRead BP status:%#x\n", 31821+ value); 31822+ if (ANY_BP_ENABLE(value)) { 31823+ ret_val |= NAND_STATUS_WP; 31824+ } 31825+ 31826+ host->cmd_op.l_cmd = NAND_CMD_STATUS; 31827+ } 31828+ 31829+ if (!(value & STATUS_OIP_MASK)) { 31830+ ret_val |= NAND_STATUS_READY; 31831+ } 31832+ 31833+ if (value & STATUS_E_FAIL_MASK) { 31834+ FMC_PR(ER_DBG, "\t\tGet erase status: %#x\n", value); 31835+ ret_val |= NAND_STATUS_FAIL; 31836+ } 31837+ 31838+ if (value & STATUS_P_FAIL_MASK) { 31839+ FMC_PR(WR_DBG, "\t\tGet write status: %#x\n", value); 31840+ ret_val |= NAND_STATUS_FAIL; 31841+ } 31842+ 31843+ return ret_val; 31844+ } 31845+ 31846+ if (host->cmd_op.l_cmd == NAND_CMD_READOOB) { 31847+ value = hifmc_readb(host->buffer + host->pagesize + host->offset); 31848+ host->offset++; 31849+ return value; 31850+ } 31851+ 31852+ host->offset++; 31853+ 31854+ return hifmc_readb(host->buffer + host->column + host->offset - 1); 31855+} 31856+ 31857+static unsigned short hifmc100_read_word(struct mtd_info *mtd) 31858+{ 31859+ struct nand_chip *chip = mtd_to_nand(mtd); 31860+ struct hifmc_host *host = chip->priv; 31861+ 31862+ host->offset += 2; 31863+ return hifmc_readw(host->buffer + host->column + host->offset - 2); 31864+} 31865+ 31866+static void hifmc100_write_buf(struct mtd_info *mtd, 31867+ const u_char *buf, int len) 31868+{ 31869+ struct nand_chip *chip = mtd_to_nand(mtd); 31870+ struct hifmc_host *host = chip->priv; 31871+ 31872+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE 31873+ if (buf == chip->oob_poi) { 31874+ memcpy((char *)host->iobase + host->pagesize, buf, len); 31875+ } else { 31876+ memcpy((char *)host->iobase, buf, len); 31877+ } 31878+#else 31879+ if (buf == chip->oob_poi) { 31880+ memcpy((char *)(host->buffer + host->pagesize), buf, len); 31881+ } else { 31882+ memcpy((char *)host->buffer, buf, len); 31883+ } 31884+#endif 31885+ return; 31886+} 31887+ 31888+static void hifmc100_read_buf(struct mtd_info *mtd, u_char *buf, int len) 31889+{ 31890+ struct nand_chip *chip = mtd_to_nand(mtd); 31891+ struct hifmc_host *host = chip->priv; 31892+ 31893+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_READ 31894+ if (buf == chip->oob_poi) { 31895+ memcpy(buf, (char *)host->iobase + host->pagesize, len); 31896+ } else { 31897+ memcpy(buf, (char *)host->iobase, len); 31898+ } 31899+#else 31900+ if (buf == chip->oob_poi) { 31901+ memcpy(buf, (char *)host->buffer + host->pagesize, len); 31902+ } else { 31903+ memcpy(buf, (char *)host->buffer, len); 31904+ } 31905+#endif 31906+ 31907+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT 31908+ if (buf != chip->oob_poi) { 31909+ u_int reg; 31910+ u_int ecc_step = host->pagesize >> 10; 31911+ 31912+ reg = hifmc_readl(host, HIFMC100_ECC_ERR_NUM0_BUF0); 31913+ while (ecc_step) { 31914+ u_char err_num; 31915+ 31916+ err_num = GET_ECC_ERR_NUM(--ecc_step, reg); 31917+ if (err_num == 0xff) { 31918+ mtd->ecc_stats.failed++; 31919+ } else { 31920+ mtd->ecc_stats.corrected += err_num; 31921+ } 31922+ } 31923+ } 31924+#endif 31925+ 31926+ return; 31927+} 31928+ 31929+static void hifmc100_select_chip(struct mtd_info *mtd, int chipselect) 31930+{ 31931+ struct nand_chip *chip = mtd_to_nand(mtd); 31932+ struct hifmc_host *host = chip->priv; 31933+ 31934+ if (chipselect < 0) { 31935+ mutex_unlock(&fmc_switch_mutex); 31936+ return; 31937+ } 31938+ 31939+ mutex_lock(&fmc_switch_mutex); 31940+ 31941+ if (chipselect > CONFIG_SPI_NAND_MAX_CHIP_NUM) { 31942+ DB_BUG("Error: Invalid chipselect: %d\n", chipselect); 31943+ } 31944+ 31945+ if (host->mtd != mtd) { 31946+ host->mtd = mtd; 31947+ host->cmd_op.cs = chipselect; 31948+ } 31949+ 31950+ if (!(chip->options & NAND_BROKEN_XD)) { 31951+ if ((chip->state == FL_ERASING) || (chip->state == FL_WRITING)) { 31952+ host->cmd_op.l_cmd = NAND_CMD_GET_FEATURES; 31953+ } 31954+ } 31955+} 31956+ 31957+static void hifmc100_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned ctrl) 31958+{ 31959+ unsigned char cmd; 31960+ int is_cache_invalid = 1; 31961+ struct nand_chip *chip = mtd_to_nand(mtd); 31962+ struct hifmc_host *host = chip->priv; 31963+ unsigned int udat = (unsigned int)dat; 31964+ 31965+ if (ctrl & NAND_ALE) { 31966+ unsigned int addr_value = 0; 31967+ unsigned int addr_offset = 0; 31968+ 31969+ if (ctrl & NAND_CTRL_CHANGE) { 31970+ host->addr_cycle = 0x0; 31971+ host->addr_value[0] = 0x0; 31972+ host->addr_value[1] = 0x0; 31973+ } 31974+ addr_offset = host->addr_cycle << 3; 31975+ 31976+ if (host->addr_cycle >= HIFMC100_ADDR_CYCLE_MASK) { 31977+ addr_offset = (host->addr_cycle - 31978+ HIFMC100_ADDR_CYCLE_MASK) << 3; 31979+ addr_value = 1; 31980+ } 31981+ host->addr_value[addr_value] |= 31982+ ((udat & 0xff) << addr_offset); 31983+ 31984+ host->addr_cycle++; 31985+ } 31986+ 31987+ if ((ctrl & NAND_CLE) && (ctrl & NAND_CTRL_CHANGE)) { 31988+ cmd = udat & 0xff; 31989+ host->cmd_op.cmd = cmd; 31990+ switch (cmd) { 31991+ case NAND_CMD_PAGEPROG: 31992+ host->offset = 0; 31993+ host->send_cmd_write(host); 31994+ break; 31995+ 31996+ case NAND_CMD_READSTART: 31997+ is_cache_invalid = 0; 31998+ if (host->addr_value[0] == host->pagesize) { 31999+ host->cmd_op.l_cmd = NAND_CMD_READOOB; 32000+ } 32001+ host->send_cmd_read(host); 32002+ break; 32003+ 32004+ case NAND_CMD_ERASE2: 32005+ host->send_cmd_erase(host); 32006+ break; 32007+ 32008+ case NAND_CMD_READID: 32009+ memset((u_char *)(host->iobase), 0, 32010+ MAX_SPI_NAND_ID_LEN); 32011+ host->cmd_op.l_cmd = cmd; 32012+ host->cmd_op.data_no = MAX_SPI_NAND_ID_LEN; 32013+ host->send_cmd_readid(host); 32014+ break; 32015+ 32016+ case NAND_CMD_STATUS: 32017+ host->send_cmd_status(host); 32018+ break; 32019+ 32020+ case NAND_CMD_READ0: 32021+ host->cmd_op.l_cmd = cmd; 32022+ break; 32023+ 32024+ case NAND_CMD_RESET: 32025+ host->send_cmd_reset(host); 32026+ break; 32027+ 32028+ case NAND_CMD_SEQIN: 32029+ case NAND_CMD_ERASE1: 32030+ default: 32031+ break; 32032+ } 32033+ } 32034+ 32035+ if ((dat == NAND_CMD_NONE) && host->addr_cycle) { 32036+ if (host->cmd_op.cmd == NAND_CMD_SEQIN 32037+ || host->cmd_op.cmd == NAND_CMD_READ0 32038+ || host->cmd_op.cmd == NAND_CMD_READID) { 32039+ host->offset = 0x0; 32040+ host->column = (host->addr_value[0] & 0xffff); 32041+ } 32042+ } 32043+ 32044+ if (is_cache_invalid) { 32045+ host->cache_addr_value[0] = ~0; 32046+ host->cache_addr_value[1] = ~0; 32047+ } 32048+} 32049+ 32050+static int hifmc100_dev_ready(struct mtd_info *mtd) 32051+{ 32052+ unsigned int reg; 32053+ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; 32054+ struct nand_chip *chip = mtd_to_nand(mtd); 32055+ struct hifmc_host *host = chip->priv; 32056+ 32057+ do { 32058+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; 32059+ hifmc_writel(host, FMC_OP_CFG, reg); 32060+ 32061+ reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START; 32062+ hifmc_writel(host, FMC_OP, reg); 32063+ 32064+ FMC_CMD_WAIT_CPU_FINISH(host); 32065+ 32066+ reg = hifmc_readl(host, FMC_STATUS); 32067+ 32068+ if (!(reg & STATUS_OIP_MASK)) { 32069+ return NAND_STATUS_READY; 32070+ } 32071+ 32072+ cond_resched(); 32073+ } while (!time_after_eq(jiffies, deadline)); 32074+ 32075+ if (!(chip->options & NAND_SCAN_SILENT_NODEV)) { 32076+ pr_warn("Wait SPI nand ready timeout, status: %#x\n", reg); 32077+ } 32078+ 32079+ return 0; 32080+} 32081+ 32082+/* 32083+ * 'host->epm' only use the first oobfree[0] field, it looks very simple, But... 32084+ */ 32085+/* Default OOB area layout */ 32086+static int hifmc_ooblayout_ecc_default(struct mtd_info *mtd, int section, 32087+ struct mtd_oob_region *oobregion) 32088+{ 32089+ if (section) { 32090+ return -ERANGE; 32091+ } 32092+ 32093+ oobregion->length = 32; 32094+ oobregion->offset = 32; 32095+ 32096+ return 0; 32097+} 32098+ 32099+static int hifmc_ooblayout_free_default(struct mtd_info *mtd, int section, 32100+ struct mtd_oob_region *oobregion) 32101+{ 32102+ if (section) { 32103+ return -ERANGE; 32104+ } 32105+ 32106+ oobregion->length = 30; 32107+ oobregion->offset = 2; 32108+ 32109+ return 0; 32110+} 32111+ 32112+static struct mtd_ooblayout_ops hifmc_ooblayout_default_ops = { 32113+ .ecc = hifmc_ooblayout_ecc_default, 32114+ .free = hifmc_ooblayout_free_default, 32115+}; 32116+ 32117+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 32118+static int hifmc_ooblayout_ecc_4k16bit(struct mtd_info *mtd, int section, 32119+ struct mtd_oob_region *oobregion) 32120+{ 32121+ if (section) { 32122+ return -ERANGE; 32123+ } 32124+ 32125+ oobregion->length = 14; 32126+ oobregion->offset = 14; 32127+ 32128+ return 0; 32129+} 32130+ 32131+static int hifmc_ooblayout_free_4k16bit(struct mtd_info *mtd, int section, 32132+ struct mtd_oob_region *oobregion) 32133+{ 32134+ if (section) { 32135+ return -ERANGE; 32136+ } 32137+ 32138+ oobregion->length = 14; 32139+ oobregion->offset = 2; 32140+ 32141+ return 0; 32142+} 32143+ 32144+static struct mtd_ooblayout_ops hifmc_ooblayout_4k16bit_ops = { 32145+ .ecc = hifmc_ooblayout_ecc_4k16bit, 32146+ .free = hifmc_ooblayout_free_4k16bit, 32147+}; 32148+ 32149+static int hifmc_ooblayout_ecc_2k16bit(struct mtd_info *mtd, int section, 32150+ struct mtd_oob_region *oobregion) 32151+{ 32152+ if (section) { 32153+ return -ERANGE; 32154+ } 32155+ 32156+ oobregion->length = 6; 32157+ oobregion->offset = 6; 32158+ 32159+ return 0; 32160+} 32161+ 32162+static int hifmc_ooblayout_free_2k16bit(struct mtd_info *mtd, int section, 32163+ struct mtd_oob_region *oobregion) 32164+{ 32165+ if (section) { 32166+ return -ERANGE; 32167+ } 32168+ 32169+ oobregion->length = 6; 32170+ oobregion->offset = 2; 32171+ 32172+ return 0; 32173+} 32174+ 32175+static struct mtd_ooblayout_ops hifmc_ooblayout_2k16bit_ops = { 32176+ .ecc = hifmc_ooblayout_ecc_2k16bit, 32177+ .free = hifmc_ooblayout_free_2k16bit, 32178+}; 32179+#endif 32180+ 32181+static struct nand_config_info hifmc_spi_nand_config_table[] = { 32182+ {NAND_PAGE_4K, NAND_ECC_24BIT, 24, 200, &hifmc_ooblayout_default_ops}, 32183+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 32184+ {NAND_PAGE_4K, NAND_ECC_16BIT, 16, 128, &hifmc_ooblayout_4k16bit_ops}, 32185+#endif 32186+ {NAND_PAGE_4K, NAND_ECC_8BIT, 8, 128, &hifmc_ooblayout_default_ops}, 32187+ {NAND_PAGE_4K, NAND_ECC_0BIT, 0, 32, &hifmc_ooblayout_default_ops}, 32188+ {NAND_PAGE_2K, NAND_ECC_24BIT, 24, 128, &hifmc_ooblayout_default_ops}, 32189+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 32190+ {NAND_PAGE_2K, NAND_ECC_16BIT, 16, 64, &hifmc_ooblayout_2k16bit_ops}, 32191+#endif 32192+ {NAND_PAGE_2K, NAND_ECC_8BIT, 8, 64, &hifmc_ooblayout_default_ops}, 32193+ {NAND_PAGE_2K, NAND_ECC_0BIT, 0, 32, &hifmc_ooblayout_default_ops}, 32194+ {0, 0, 0, 0, NULL}, 32195+}; 32196+ 32197+/* 32198+ * Auto-sensed the page size and ecc type value. driver will try each of page 32199+ * size and ecc type one by one till flash can be read and wrote accurately. 32200+ * so the page size and ecc type is match adaptively without switch on the board 32201+ */ 32202+static struct nand_config_info *hifmc100_get_config_type_info( 32203+ struct mtd_info *mtd, struct nand_dev_t *nand_dev) 32204+{ 32205+ struct nand_config_info *best = NULL; 32206+ struct nand_chip *chip = mtd_to_nand(mtd); 32207+ struct nand_config_info *info = hifmc_spi_nand_config_table; 32208+ 32209+ nand_dev->start_type = "Auto"; 32210+ 32211+ for (; info->ooblayout_ops; info++) { 32212+ if (match_page_type_to_size(info->pagetype) != mtd->writesize) { 32213+ continue; 32214+ } 32215+ 32216+ if (mtd->oobsize < info->oobsize) { 32217+ continue; 32218+ } 32219+ 32220+ if (!best || (best->ecctype < info->ecctype)) { 32221+ best = info; 32222+ } 32223+ } 32224+ 32225+ /* All SPI NAND are small-page, SLC */ 32226+ chip->bits_per_cell = 1; 32227+ 32228+ return best; 32229+} 32230+ 32231+static void hifmc100_chip_init(struct nand_chip *chip) 32232+{ 32233+ chip->read_byte = hifmc100_read_byte; 32234+ chip->read_word = hifmc100_read_word; 32235+ chip->write_buf = hifmc100_write_buf; 32236+ chip->read_buf = hifmc100_read_buf; 32237+ 32238+ chip->select_chip = hifmc100_select_chip; 32239+ 32240+ chip->cmd_ctrl = hifmc100_cmd_ctrl; 32241+ chip->dev_ready = hifmc100_dev_ready; 32242+ 32243+ chip->chip_delay = FMC_CHIP_DELAY; 32244+ 32245+ chip->options = NAND_SKIP_BBTSCAN | NAND_BROKEN_XD 32246+ | NAND_SCAN_SILENT_NODEV; 32247+ 32248+ chip->ecc.mode = NAND_ECC_NONE; 32249+} 32250+ 32251+static void hifmc100_set_oob_info(struct mtd_info *mtd, 32252+ struct nand_config_info *info, struct nand_dev_t *nand_dev) 32253+{ 32254+ struct nand_chip *chip = mtd_to_nand(mtd); 32255+ struct hifmc_host *host = chip->priv; 32256+ struct mtd_oob_region hifmc_oobregion = {0, 0}; 32257+ if (info == NULL || mtd == NULL || nand_dev == NULL) { 32258+ DB_MSG("set oob info err!!!\n"); 32259+ return; 32260+ } 32261+ 32262+ if (info->ecctype != NAND_ECC_0BIT) { 32263+ mtd->oobsize = info->oobsize; 32264+ } 32265+ 32266+ host->oobsize = mtd->oobsize; 32267+ nand_dev->oobsize = host->oobsize; 32268+ 32269+ host->dma_oob = host->dma_buffer + host->pagesize; 32270+ host->bbm = (u_char *)(host->buffer + host->pagesize 32271+ + HIFMC_BAD_BLOCK_POS); 32272+ if(info->ooblayout_ops == NULL) { 32273+ DB_MSG("Error: info->ooblayout_ops or is NULL!\n"); 32274+ return; 32275+ } 32276+ info->ooblayout_ops->free(mtd, 0, &hifmc_oobregion); 32277+ 32278+ mtd_set_ooblayout(mtd, info->ooblayout_ops); 32279+ 32280+ /* EB bits locate in the bottom two of CTRL(30) */ 32281+ host->epm = (u_short *)(host->buffer + host->pagesize 32282+ + hifmc_oobregion.offset + 28); 32283+ 32284+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 32285+ if (best->ecctype == NAND_ECC_16BIT) { 32286+ if (host->pagesize == _2K) { 32287+ /* EB bits locate in the bottom two of CTRL(4) */ 32288+ host->epm = (u_short *)(host->buffer + host->pagesize 32289+ + hifmc_oobregion.offset + 4); 32290+ } else if (host->pagesize == _4K) { 32291+ /* EB bit locate in the bottom two of CTRL(14) */ 32292+ host->epm = (u_short *)(host->buffer + host->pagesize 32293+ + hifmc_oobregion.offset + 12); 32294+ } 32295+ } 32296+#endif 32297+} 32298+ 32299+static unsigned int hifmc100_get_ecc_reg(struct hifmc_host *host, 32300+ const struct nand_config_info *info, struct nand_dev_t *nand_dev) 32301+{ 32302+ if (info == NULL || host == NULL || nand_dev == NULL) { 32303+ DB_MSG("get ecc reg err!!!\n"); 32304+ return 0; 32305+ } 32306+ host->ecctype = info->ecctype; 32307+ nand_dev->ecctype = host->ecctype; 32308+ 32309+ return FMC_CFG_ECC_TYPE(match_ecc_type_to_reg(info->ecctype)); 32310+} 32311+ 32312+static unsigned int hifmc100_get_page_reg(struct hifmc_host *host, 32313+ const struct nand_config_info *info) 32314+{ 32315+ if (info == NULL || host == NULL) { 32316+ DB_MSG("get page reg err!!!\n"); 32317+ return 0; 32318+ } 32319+ host->pagesize = match_page_type_to_size(info->pagetype); 32320+ 32321+ return FMC_CFG_PAGE_SIZE(match_page_type_to_reg(info->pagetype)); 32322+} 32323+ 32324+static unsigned int hifmc100_get_block_reg(struct hifmc_host *host, 32325+ const struct nand_config_info *info) 32326+{ 32327+ unsigned int block_reg = 0; 32328+ unsigned int page_per_block = 0; 32329+ struct mtd_info *mtd = NULL; 32330+ 32331+ if (info == NULL || host == NULL) { 32332+ DB_MSG("get block reg err!!!\n"); 32333+ return 0; 32334+ } 32335+ 32336+ mtd = host->mtd; 32337+ if(mtd == NULL) { 32338+ DB_MSG("err:mtd is NULL!!!\n"); 32339+ return 0; 32340+ } 32341+ host->block_page_mask = ((mtd->erasesize / mtd->writesize) - 1); 32342+ page_per_block = mtd->erasesize / match_page_type_to_size(info->pagetype); 32343+ switch (page_per_block) { 32344+ case 64: 32345+ block_reg = BLOCK_SIZE_64_PAGE; 32346+ break; 32347+ case 128: 32348+ block_reg = BLOCK_SIZE_128_PAGE; 32349+ break; 32350+ case 256: 32351+ block_reg = BLOCK_SIZE_256_PAGE; 32352+ break; 32353+ case 512: 32354+ block_reg = BLOCK_SIZE_512_PAGE; 32355+ break; 32356+ default: 32357+ DB_MSG("Can't support block %#x and page %#x size\n", 32358+ mtd->erasesize, mtd->writesize); 32359+ } 32360+ 32361+ return FMC_CFG_BLOCK_SIZE(block_reg); 32362+} 32363+ 32364+static void hifmc100_set_fmc_cfg_reg(struct hifmc_host *host, 32365+ const struct nand_config_info *type_info, struct nand_dev_t *nand_dev) 32366+{ 32367+ unsigned int page_reg, ecc_reg, block_reg, reg_fmc_cfg; 32368+ 32369+ ecc_reg = hifmc100_get_ecc_reg(host, type_info, nand_dev); 32370+ page_reg = hifmc100_get_page_reg(host, type_info); 32371+ block_reg = hifmc100_get_block_reg(host, type_info); 32372+ 32373+ reg_fmc_cfg = hifmc_readl(host, FMC_CFG); 32374+ reg_fmc_cfg &= ~(PAGE_SIZE_MASK | ECC_TYPE_MASK | BLOCK_SIZE_MASK); 32375+ reg_fmc_cfg |= ecc_reg | page_reg | block_reg; 32376+ hifmc_writel(host, FMC_CFG, reg_fmc_cfg); 32377+ 32378+ /* Save value of FMC_CFG and FMC_CFG_ECC0 to turn on/off ECC */ 32379+ host->fmc_cfg = reg_fmc_cfg; 32380+ host->fmc_cfg_ecc0 = (host->fmc_cfg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; 32381+ FMC_PR(BT_DBG, "\t|-Save FMC_CFG[%#x]: %#x and FMC_CFG_ECC0: %#x\n", 32382+ FMC_CFG, host->fmc_cfg, host->fmc_cfg_ecc0); 32383+} 32384+ 32385+static int hifmc100_set_config_info(struct mtd_info *mtd, 32386+ struct nand_chip *chip, struct nand_dev_t *nand_dev) 32387+{ 32388+ struct hifmc_host *host = chip->priv; 32389+ struct nand_config_info *type_info = NULL; 32390+ 32391+ FMC_PR(BT_DBG, "\t*-Start config Block Page OOB and Ecc\n"); 32392+ 32393+ type_info = hifmc100_get_config_type_info(mtd, nand_dev); 32394+ WARN_ON(!type_info); 32395+ if (type_info == NULL) { 32396+ DB_MSG("set config info err!!!\n"); 32397+ return 0; 32398+ } 32399+ 32400+ FMC_PR(BT_DBG, "\t|-%s Config, PageSize %s EccType %s OOBSize %d\n", 32401+ nand_dev->start_type, nand_page_name(type_info->pagetype), 32402+ nand_ecc_name(type_info->ecctype), type_info->oobsize); 32403+ 32404+ /* Set the page_size, ecc_type, block_size of FMC_CFG[0x0] register */ 32405+ hifmc100_set_fmc_cfg_reg(host, type_info, nand_dev); 32406+ 32407+ hifmc100_set_oob_info(mtd, type_info, nand_dev); 32408+ 32409+ FMC_PR(BT_DBG, "\t*-End config Block Page Oob and Ecc\n"); 32410+ 32411+ return 0; 32412+} 32413+ 32414+void hifmc100_spi_nand_init(struct nand_chip *chip) 32415+{ 32416+ struct hifmc_host *host = NULL; 32417+ 32418+ if((chip == NULL) || (chip->priv == NULL)) { 32419+ DB_MSG("Error: chip or chip->priv is NULL!\n"); 32420+ return; 32421+ } 32422+ host = chip->priv; 32423+ FMC_PR(BT_DBG, "\t|*-Start hifmc100 SPI Nand init\n"); 32424+ 32425+ /* Switch SPI type to SPI nand */ 32426+ hifmc100_switch_to_spi_nand(host); 32427+ 32428+ /* hold on STR mode */ 32429+ hifmc100_set_str_mode(host); 32430+ 32431+ /* Hifmc host init */ 32432+ hifmc100_host_init(host); 32433+ host->chip = chip; 32434+ 32435+ /* Hifmc nand_chip struct init */ 32436+ hifmc100_chip_init(chip); 32437+ 32438+ hifmc_spi_nand_ids_register(); 32439+ hinfc_param_adjust = hifmc100_set_config_info; 32440+ 32441+ FMC_PR(BT_DBG, "\t|*-End hifmc100 SPI Nand init\n"); 32442+} 32443+#ifdef CONFIG_PM 32444+int hifmc100_suspend(struct platform_device *pltdev, pm_message_t state) 32445+{ 32446+ int ret; 32447+ struct hifmc_host *host = platform_get_drvdata(pltdev); 32448+ struct hifmc_spi *spi = host->spi; 32449+ 32450+ mutex_lock(host->lock); 32451+ hifmc100_switch_to_spi_nand(host); 32452+ 32453+ ret = spi->driver->wait_ready(spi); 32454+ if (ret) { 32455+ DB_MSG("Error: wait ready failed!"); 32456+ clk_disable_unprepare(host->clk); 32457+ mutex_unlock(host->lock); 32458+ return 0; 32459+ } 32460+ 32461+ clk_disable_unprepare(host->clk); 32462+ mutex_unlock(host->lock); 32463+ 32464+ return 0; 32465+} 32466+ 32467+int hifmc100_resume(struct platform_device *pltdev) 32468+{ 32469+ int cs; 32470+ struct hifmc_host *host = platform_get_drvdata(pltdev); 32471+ struct nand_chip *chip = host->chip; 32472+ 32473+ mutex_lock(host->lock); 32474+ hifmc100_switch_to_spi_nand(host); 32475+ clk_prepare_enable(host->clk); 32476+ 32477+ for (cs = 0; cs < chip->numchips; cs++) { 32478+ host->send_cmd_reset(host); 32479+ } 32480+ 32481+ hifmc100_spi_nand_config(host); 32482+ 32483+ mutex_unlock(host->lock); 32484+ return 0; 32485+} 32486+#endif 32487diff --git a/drivers/mtd/nand/hifmc100/hifmc100.h b/drivers/mtd/nand/hifmc100/hifmc100.h 32488new file mode 100644 32489index 000000000..9f169f3d5 32490--- /dev/null 32491+++ b/drivers/mtd/nand/hifmc100/hifmc100.h 32492@@ -0,0 +1,354 @@ 32493+/* 32494+ * The Flash Memory Controller v100 Device Driver for hisilicon 32495+ * 32496+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 32497+ * 32498+ * This program is free software; you can redistribute it and/or modify it 32499+ * under the terms of the GNU General Public License as published by the 32500+ * Free Software Foundation; either version 2 of the License, or (at your 32501+ * option) any later version. 32502+ * 32503+ * This program is distributed in the hope that it will be useful, 32504+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 32505+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32506+ * GNU General Public License for more details. 32507+ * 32508+ * You should have received a copy of the GNU General Public License 32509+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 32510+ * 32511+ */ 32512+ 32513+#ifndef __HIFMC100_H__ 32514+#define __HIFMC100_H__ 32515+ 32516+#include <linux/platform_device.h> 32517+#include <linux/mfd/hisi_fmc.h> 32518+ 32519+#define INFINITE (0xFFFFFFFF) 32520+ 32521+#define SPI_IF_READ_STD (0x01) 32522+#define SPI_IF_READ_FAST (0x02) 32523+#define SPI_IF_READ_DUAL (0x04) 32524+#define SPI_IF_READ_DUAL_ADDR (0x08) 32525+#define SPI_IF_READ_QUAD (0x10) 32526+#define SPI_IF_READ_QUAD_ADDR (0x20) 32527+ 32528+#define SPI_IF_WRITE_STD (0x01) 32529+#define SPI_IF_WRITE_DUAL (0x02) 32530+#define SPI_IF_WRITE_DUAL_ADDR (0x04) 32531+#define SPI_IF_WRITE_QUAD (0x08) 32532+#define SPI_IF_WRITE_QUAD_ADDR (0x10) 32533+ 32534+#define SPI_IF_ERASE_SECTOR_4K (0x01) 32535+#define SPI_IF_ERASE_SECTOR_32K (0x02) 32536+#define SPI_IF_ERASE_SECTOR_64K (0x04) 32537+#define SPI_IF_ERASE_SECTOR_128K (0x08) 32538+#define SPI_IF_ERASE_SECTOR_256K (0x10) 32539+ 32540+#define HIFMC_SPI_NAND_SUPPORT_READ (SPI_IF_READ_STD \ 32541+ | SPI_IF_READ_FAST \ 32542+ | SPI_IF_READ_DUAL \ 32543+ | SPI_IF_READ_DUAL_ADDR \ 32544+ | SPI_IF_READ_QUAD \ 32545+ | SPI_IF_READ_QUAD_ADDR) 32546+ 32547+#define HIFMC_SPI_NAND_SUPPORT_WRITE (SPI_IF_WRITE_STD | SPI_IF_WRITE_QUAD) 32548+ 32549+#define HIFMC_SPI_NAND_SUPPORT_MAX_DUMMY 8 32550+ 32551+#define SPI_CMD_READ_STD 0x03 /* Standard read cache */ 32552+#define SPI_CMD_READ_FAST 0x0B /* Higher speed read cache */ 32553+#define SPI_CMD_READ_DUAL 0x3B /* 2 IO read cache only date */ 32554+#define SPI_CMD_READ_DUAL_ADDR 0xBB /* 2 IO read cache date&addr */ 32555+#define SPI_CMD_READ_QUAD 0x6B /* 4 IO read cache only date */ 32556+#define SPI_CMD_READ_QUAD_ADDR 0xEB /* 4 IO read cache date&addr */ 32557+ 32558+#define SPI_CMD_WRITE_STD 0x02 /* Standard page program */ 32559+#define SPI_CMD_WRITE_DUAL 0xA2 /* 2 IO program only date */ 32560+#define SPI_CMD_WRITE_DUAL_ADDR 0xD2 /* 2 IO program date&addr */ 32561+#define SPI_CMD_WRITE_QUAD 0x32 /* 4 IO program only date */ 32562+#define SPI_CMD_WRITE_QUAD_ADDR 0x12 /* 4 IO program date&addr */ 32563+ 32564+#define SPI_CMD_SE_4K 0x20 /* 4KB sector Erase */ 32565+#define SPI_CMD_SE_32K 0x52 /* 32KB sector Erase */ 32566+#define SPI_CMD_SE_64K 0xD8 /* 64KB sector Erase */ 32567+#define SPI_CMD_SE_128K 0xD8 /* 128KB sector Erase */ 32568+#define SPI_CMD_SE_256K 0xD8 /* 256KB sector Erase */ 32569+ 32570+#define SET_READ_STD(_dummy_, _size_, _clk_) \ 32571+ static struct spi_op read_std_##_dummy_##_size_##_clk_ = { \ 32572+ SPI_IF_READ_STD, SPI_CMD_READ_STD, _dummy_, _size_, _clk_ } 32573+ 32574+#define SET_READ_FAST(_dummy_, _size_, _clk_) \ 32575+ static struct spi_op read_fast_##_dummy_##_size_##_clk_ = { \ 32576+ SPI_IF_READ_FAST, SPI_CMD_READ_FAST, _dummy_, _size_, _clk_ } 32577+ 32578+#define SET_READ_DUAL(_dummy_, _size_, _clk_) \ 32579+ static struct spi_op read_dual_##_dummy_##_size_##_clk_ = { \ 32580+ SPI_IF_READ_DUAL, SPI_CMD_READ_DUAL, _dummy_, _size_, _clk_ } 32581+ 32582+#define SET_READ_DUAL_ADDR(_dummy_, _size_, _clk_) \ 32583+ static struct spi_op read_dual_addr_##_dummy_##_size_##_clk_ = { \ 32584+ SPI_IF_READ_DUAL_ADDR, SPI_CMD_READ_DUAL_ADDR, _dummy_, _size_, _clk_ } 32585+ 32586+#define SET_READ_QUAD(_dummy_, _size_, _clk_) \ 32587+ static struct spi_op read_quad_##_dummy_##_size_##_clk_ = { \ 32588+ SPI_IF_READ_QUAD, SPI_CMD_READ_QUAD, _dummy_, _size_, _clk_ } 32589+ 32590+#define SET_READ_QUAD_ADDR(_dummy_, _size_, _clk_) \ 32591+ static struct spi_op read_quad_addr_##_dummy_##_size_##_clk_ = { \ 32592+ SPI_IF_READ_QUAD_ADDR, SPI_CMD_READ_QUAD_ADDR, _dummy_, _size_, _clk_ } 32593+ 32594+#define SET_WRITE_STD(_dummy_, _size_, _clk_) \ 32595+ static struct spi_op write_std_##_dummy_##_size_##_clk_ = { \ 32596+ SPI_IF_WRITE_STD, SPI_CMD_WRITE_STD, _dummy_, _size_, _clk_ } 32597+ 32598+#define SET_WRITE_DUAL(_dummy_, _size_, _clk_) \ 32599+ static struct spi_op write_dual_##_dummy_##_size_##_clk_ = { \ 32600+ SPI_IF_WRITE_DUAL, SPI_CMD_WRITE_DUAL, _dummy_, _size_, _clk_ } 32601+ 32602+#define SET_WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \ 32603+ static struct spi_op write_dual_addr_##_dummy_##_size_##_clk_ = { \ 32604+SPI_IF_WRITE_DUAL_ADDR, SPI_CMD_WRITE_DUAL_ADDR, _dummy_, _size_, _clk_ } 32605+ 32606+#define SET_WRITE_QUAD(_dummy_, _size_, _clk_) \ 32607+ static struct spi_op write_quad_##_dummy_##_size_##_clk_ = { \ 32608+ SPI_IF_WRITE_QUAD, SPI_CMD_WRITE_QUAD, _dummy_, _size_, _clk_ } 32609+ 32610+#define SET_WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \ 32611+ static struct spi_op write_quad_addr_##_dummy_##_size_##_clk_ = { \ 32612+SPI_IF_WRITE_QUAD_ADDR, SPI_CMD_WRITE_QUAD_ADDR, _dummy_, _size_, _clk_ } 32613+ 32614+#define SET_ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \ 32615+ static struct spi_op erase_sector_4k_##_dummy_##_size_##_clk_ = { \ 32616+ SPI_IF_ERASE_SECTOR_4K, SPI_CMD_SE_4K, _dummy_, _size_, _clk_ } 32617+ 32618+#define SET_ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \ 32619+ static struct spi_op erase_sector_32k_##_dummy_##_size_##_clk_ = { \ 32620+ SPI_IF_ERASE_SECTOR_32K, SPI_CMD_SE_32K, _dummy_, _size_, _clk_ } 32621+ 32622+#define SET_ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \ 32623+ static struct spi_op erase_sector_64k_##_dummy_##_size_##_clk_ = { \ 32624+ SPI_IF_ERASE_SECTOR_64K, SPI_CMD_SE_64K, _dummy_, _size_, _clk_ } 32625+ 32626+#define SET_ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \ 32627+ static struct spi_op erase_sector_128k_##_dummy_##_size_##_clk_ = { \ 32628+ SPI_IF_ERASE_SECTOR_128K, SPI_CMD_SE_128K, _dummy_, _size_, _clk_ } 32629+ 32630+#define SET_ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \ 32631+ static struct spi_op erase_sector_256k_##_dummy_##_size_##_clk_ = { \ 32632+ SPI_IF_ERASE_SECTOR_256K, SPI_CMD_SE_256K, _dummy_, _size_, _clk_ } 32633+ 32634+#define READ_STD(_dummy_, _size_, _clk_) read_std_##_dummy_##_size_##_clk_ 32635+#define READ_FAST(_dummy_, _size_, _clk_) read_fast_##_dummy_##_size_##_clk_ 32636+#define READ_DUAL(_dummy_, _size_, _clk_) read_dual_##_dummy_##_size_##_clk_ 32637+#define READ_DUAL_ADDR(_dummy_, _size_, _clk_) \ 32638+ read_dual_addr_##_dummy_##_size_##_clk_ 32639+#define READ_QUAD(_dummy_, _size_, _clk_) read_quad_##_dummy_##_size_##_clk_ 32640+#define READ_QUAD_ADDR(_dummy_, _size_, _clk_) \ 32641+ read_quad_addr_##_dummy_##_size_##_clk_ 32642+ 32643+#define WRITE_STD(_dummy_, _size_, _clk_) write_std_##_dummy_##_size_##_clk_ 32644+#define WRITE_DUAL(_dummy_, _size_, _clk_) write_dual_##_dummy_##_size_##_clk_ 32645+#define WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \ 32646+ write_dual_addr_##_dummy_##_size_##_clk_ 32647+#define WRITE_QUAD(_dummy_, _size_, _clk_) write_quad_##_dummy_##_size_##_clk_ 32648+#define WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \ 32649+ write_quad_addr_##_dummy_##_size_##_clk_ 32650+ 32651+#define ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \ 32652+ erase_sector_4k_##_dummy_##_size_##_clk_ 32653+#define ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \ 32654+ erase_sector_32k_##_dummy_##_size_##_clk_ 32655+#define ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \ 32656+ erase_sector_64k_##_dummy_##_size_##_clk_ 32657+#define ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \ 32658+ erase_sector_128k_##_dummy_##_size_##_clk_ 32659+#define ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \ 32660+ erase_sector_256k_##_dummy_##_size_##_clk_ 32661+ 32662+#define SPI_CMD_WREN 0x06 /* Write Enable */ 32663+#define SPI_CMD_WRDI 0x04 /* Write Disable */ 32664+ 32665+#define SPI_CMD_RDID 0x9F /* Read Identification */ 32666+ 32667+#define SPI_CMD_GET_FEATURES 0x0F /* Get Features */ 32668+#define SPI_CMD_SET_FEATURE 0x1F /* Set Feature */ 32669+ 32670+#define SPI_CMD_PAGE_READ 0x13 /* Page Read to Cache */ 32671+ 32672+#define SPI_CMD_RESET 0xff /* Reset the device */ 32673+ 32674+/* These macroes are for debug only, reg option is slower then dma option */ 32675+#undef HIFMC100_SPI_NAND_SUPPORT_REG_READ 32676+/* #define HIFMC100_SPI_NAND_SUPPORT_REG_READ */ 32677+ 32678+#undef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE 32679+/* #define HIFMC100_SPI_NAND_SUPPORT_REG_WRITE */ 32680+ 32681+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT 32682+#define HIFMC100_ECC_ERR_NUM0_BUF0 0xc0 32683+ 32684+#define GET_ECC_ERR_NUM(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) 32685+#endif 32686+#define REG_CNT_HIGH_BLOCK_NUM_SHIFT 10 32687+ 32688+#define REG_CNT_BLOCK_NUM_MASK 0x3ff 32689+#define REG_CNT_BLOCK_NUM_SHIFT 22 32690+ 32691+#define REG_CNT_PAGE_NUM_MASK 0x3f 32692+#define REG_CNT_PAGE_NUM_SHIFT 16 32693+ 32694+#define ERR_STR_DRIVER "Driver does not support this configure " 32695+#define ERR_STR_CHECK "Please make sure the hardware configuration is correct" 32696+#define HIFMC100_ADDR_CYCLE_MASK 0x2 32697+#define OP_STYPE_NONE 0x0 32698+#define OP_STYPE_READ 0x01 32699+#define OP_STYPE_WRITE 0x02 32700+#define OP_STYPE_ERASE 0x04 32701+#define CLK_FMC_TO_CRG_MHZ(_clk) ((_clk) * 2000000) 32702+#define MAX_SPI_OP 8 32703+/* SPI general operation parameter */ 32704+struct spi_op { 32705+ unsigned char iftype; 32706+ unsigned char cmd; 32707+ unsigned char dummy; 32708+ unsigned int size; 32709+ unsigned int clock; 32710+}; 32711+ 32712+struct spi_drv; 32713+ 32714+/* SPI interface all operation */ 32715+struct hifmc_spi { 32716+ char *name; 32717+ int chipselect; 32718+ unsigned long long chipsize; 32719+ unsigned int erasesize; 32720+#define SPI_NOR_3BYTE_ADDR_LEN 3 /* address len 3Bytes */ 32721+#define SPI_NOR_4BYTE_ADDR_LEN 4 /* address len 4Bytes for 32MB */ 32722+ unsigned int addrcycle; 32723+ 32724+ struct spi_op read[1]; 32725+ struct spi_op write[1]; 32726+ struct spi_op erase[MAX_SPI_OP]; 32727+ 32728+ void *host; 32729+ 32730+ struct spi_drv *driver; 32731+}; 32732+ 32733+/* SPI interface special operation function hook */ 32734+struct spi_drv { 32735+ int (*wait_ready)(struct hifmc_spi *spi); 32736+ int (*write_enable)(struct hifmc_spi *spi); 32737+ int (*qe_enable)(struct hifmc_spi *spi); 32738+ int (*bus_prepare)(struct hifmc_spi *spi, int op); 32739+ int (*entry_4addr)(struct hifmc_spi *spi, int en); 32740+}; 32741+ 32742+struct spi_nand_info { 32743+ char *name; 32744+ unsigned char id[MAX_SPI_NAND_ID_LEN]; 32745+ unsigned char id_len; 32746+ unsigned long long chipsize; 32747+ unsigned int erasesize; 32748+ unsigned int pagesize; 32749+ unsigned int oobsize; 32750+#define BBP_LAST_PAGE 0x01 32751+#define BBP_FIRST_PAGE 0x02 32752+ unsigned int badblock_pos; 32753+ struct spi_op *read[MAX_SPI_OP]; 32754+ struct spi_op *write[MAX_SPI_OP]; 32755+ struct spi_op *erase[MAX_SPI_OP]; 32756+ struct spi_drv *driver; 32757+}; 32758+ 32759+extern char spi_nand_feature_op(struct hifmc_spi *spi, u_char op, u_char addr, 32760+ u_char *val); 32761+ 32762+struct hifmc_host { 32763+ struct mtd_info *mtd; 32764+ struct nand_chip *chip; 32765+ struct hifmc_spi spi[CONFIG_SPI_NAND_MAX_CHIP_NUM]; 32766+ struct hifmc_cmd_op cmd_op; 32767+ 32768+ void __iomem *iobase; 32769+ void __iomem *regbase; 32770+ struct clk *clk; 32771+ u32 clkrate; 32772+ 32773+ unsigned int fmc_cfg; 32774+ unsigned int fmc_cfg_ecc0; 32775+ 32776+ unsigned int offset; 32777+ 32778+ struct device *dev; 32779+ struct mutex *lock; 32780+ 32781+ /* This is maybe an un-aligment address, only for malloc or free */ 32782+ char *buforg; 32783+ char *buffer; 32784+ 32785+#ifdef CONFIG_64BIT 32786+ unsigned long long dma_buffer; 32787+ unsigned long long dma_oob; 32788+#else 32789+ unsigned int dma_buffer; 32790+ unsigned int dma_oob; 32791+#endif 32792+ 32793+ unsigned int addr_cycle; 32794+ unsigned int addr_value[2]; 32795+ unsigned int cache_addr_value[2]; 32796+ 32797+ unsigned int column; 32798+ unsigned int block_page_mask; 32799+ 32800+ unsigned int ecctype; 32801+ unsigned int pagesize; 32802+ unsigned int oobsize; 32803+ 32804+ int add_partition; 32805+ 32806+ int need_rr_data; 32807+#define HIFMC100_READ_RETRY_DATA_LEN 128 32808+ char rr_data[HIFMC100_READ_RETRY_DATA_LEN]; 32809+ struct read_retry_t *read_retry; 32810+ 32811+ int version; 32812+ 32813+ /* BOOTROM read two bytes to detect the bad block flag */ 32814+#define HIFMC_BAD_BLOCK_POS 0 32815+ unsigned char *bbm; /* nand bad block mark */ 32816+ unsigned short *epm; /* nand empty page mark */ 32817+ 32818+ unsigned int uc_er; 32819+ 32820+ void (*send_cmd_write)(struct hifmc_host *host); 32821+ void (*send_cmd_status)(struct hifmc_host *host); 32822+ void (*send_cmd_read)(struct hifmc_host *host); 32823+ void (*send_cmd_erase)(struct hifmc_host *host); 32824+ void (*send_cmd_readid)(struct hifmc_host *host); 32825+ void (*send_cmd_reset)(struct hifmc_host *host); 32826+#ifdef CONFIG_PM 32827+ int (*suspend)(struct platform_device *pltdev, pm_message_t state); 32828+ int (*resume)(struct platform_device *pltdev); 32829+#endif 32830+}; 32831+ 32832+void hifmc100_ecc0_switch(struct hifmc_host *host, unsigned char op); 32833+ 32834+void hifmc100_spi_nand_init(struct nand_chip *chip); 32835+ 32836+extern void hifmc_spi_nand_ids_register(void); 32837+ 32838+extern void hifmc_set_nand_system_clock(struct spi_op *op, int clk_en); 32839+ 32840+#ifdef CONFIG_PM 32841+int hifmc100_suspend(struct platform_device *pltdev, pm_message_t state); 32842+int hifmc100_resume(struct platform_device *pltdev); 32843+void hifmc100_spi_nand_config(struct hifmc_host *host); 32844+#endif 32845+ 32846+#endif /* End of __HIFMC100_H__ */ 32847diff --git a/drivers/mtd/nand/hifmc100/hifmc100_os.c b/drivers/mtd/nand/hifmc100/hifmc100_os.c 32848new file mode 100644 32849index 000000000..980bfb8f6 32850--- /dev/null 32851+++ b/drivers/mtd/nand/hifmc100/hifmc100_os.c 32852@@ -0,0 +1,247 @@ 32853+/* 32854+ * The Flash Memory Controller v100 Device Driver for hisilicon 32855+ * 32856+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 32857+ * 32858+ * This program is free software; you can redistribute it and/or modify it 32859+ * under the terms of the GNU General Public License as published by the 32860+ * Free Software Foundation; either version 2 of the License, or (at your 32861+ * option) any later version. 32862+ * 32863+ * This program is distributed in the hope that it will be useful, 32864+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 32865+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32866+ * GNU General Public License for more details. 32867+ * 32868+ * You should have received a copy of the GNU General Public License 32869+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 32870+ * 32871+ */ 32872+ 32873+#include <linux/kernel.h> 32874+#include <linux/slab.h> 32875+#include <linux/delay.h> 32876+#include <linux/module.h> 32877+#include <linux/platform_device.h> 32878+#include <linux/dma-mapping.h> 32879+#include <linux/mtd/rawnand.h> 32880+#include <linux/mtd/partitions.h> 32881+#include <linux/of_platform.h> 32882+#include <linux/mfd/hisi_fmc.h> 32883+ 32884+#include <asm/setup.h> 32885+ 32886+#include "../../mtdcore.h" 32887+#include "hifmc100.h" 32888+ 32889+static int hifmc100_spi_nand_pre_probe(struct nand_chip *chip) 32890+{ 32891+ uint8_t nand_maf_id; 32892+ struct hifmc_host *host = chip->priv; 32893+ 32894+ /* Reset the chip first */ 32895+ host->send_cmd_reset(host); 32896+ udelay(1000); 32897+ 32898+ /* Check the ID */ 32899+ host->offset = 0; 32900+ memset((unsigned char *)(chip->IO_ADDR_R), 0, 0x10); 32901+ host->send_cmd_readid(host); 32902+ nand_maf_id = hifmc_readb(chip->IO_ADDR_R); 32903+ 32904+ if (nand_maf_id == 0x00 || nand_maf_id == 0xff) { 32905+ printk("Cannot found a valid SPI Nand Device\n"); 32906+ return 1; 32907+ } 32908+ 32909+ return 0; 32910+} 32911+ 32912+static int hifmc_nand_scan(struct mtd_info *mtd) 32913+{ 32914+ int result = 0; 32915+ unsigned char cs; 32916+ unsigned char chip_num = CONFIG_SPI_NAND_MAX_CHIP_NUM; 32917+ struct nand_chip *chip = mtd_to_nand(mtd); 32918+ struct hifmc_host *host = chip->priv; 32919+ 32920+ for (cs = 0; chip_num && (cs < HIFMC_MAX_CHIP_NUM); cs++) { 32921+ if (hifmc_cs_user[cs]) { 32922+ FMC_PR(BT_DBG, "\t\t*-Current CS(%d) is occupied.\n", 32923+ cs); 32924+ continue; 32925+ } 32926+ 32927+ host->cmd_op.cs = cs; 32928+ 32929+ if (hifmc100_spi_nand_pre_probe(chip)) { 32930+ return -ENODEV; 32931+ } 32932+ 32933+ FMC_PR(BT_DBG, "\t\t*-Scan SPI nand flash on CS: %d\n", cs); 32934+ if (nand_scan_with_ids(mtd, chip_num, NULL)) { 32935+ continue; 32936+ } 32937+ chip_num--; 32938+ } 32939+ 32940+ if (chip_num == CONFIG_SPI_NAND_MAX_CHIP_NUM) { 32941+ result = -ENXIO; 32942+ } else { 32943+ result = 0; 32944+ } 32945+ 32946+ return result; 32947+} 32948+ 32949+static int hisi_spi_nand_probe(struct platform_device *pltdev) 32950+{ 32951+ int len; 32952+ int result = 0; 32953+ struct hifmc_host *host = NULL; 32954+ struct nand_chip *chip = NULL; 32955+ struct mtd_info *mtd = NULL; 32956+ struct device *dev = &pltdev->dev; 32957+ struct device_node *np = NULL; 32958+ struct hisi_fmc *fmc = dev_get_drvdata(dev->parent); 32959+ 32960+ FMC_PR(BT_DBG, "\t*-Start SPI Nand flash driver probe\n"); 32961+ 32962+ if (!fmc) { 32963+ dev_err(dev, "get mfd fmc devices failed\n"); 32964+ return -ENXIO; 32965+ } 32966+ 32967+ len = sizeof(struct hifmc_host) + sizeof(struct nand_chip) + 32968+ sizeof(struct mtd_info); 32969+ host = devm_kzalloc(dev, len, GFP_KERNEL); 32970+ if (!host) { 32971+ return -ENOMEM; 32972+ } 32973+ memset((char *)host, 0, len); 32974+ 32975+ platform_set_drvdata(pltdev, host); 32976+ host->dev = &pltdev->dev; 32977+ 32978+ host->chip = chip = (struct nand_chip *)&host[1]; 32979+ host->mtd = mtd = nand_to_mtd(chip); 32980+ 32981+ host->regbase = fmc->regbase; 32982+ host->iobase = fmc->iobase; 32983+ host->clk = fmc->clk; 32984+ host->lock = &fmc->lock; 32985+ host->buffer = fmc->buffer; 32986+ host->dma_buffer = fmc->dma_buffer; 32987+ 32988+ memset((char *)host->iobase, 0xff, fmc->dma_len); 32989+ chip->IO_ADDR_R = chip->IO_ADDR_W = host->iobase; 32990+ 32991+ chip->priv = host; 32992+ 32993+ /* Set system clock */ 32994+ result = clk_prepare_enable(host->clk); 32995+ if (result) { 32996+ printk("\nclk prepare enable failed!"); 32997+ goto fail; 32998+ } 32999+ 33000+ hifmc100_spi_nand_init(chip); 33001+ 33002+ np = of_get_next_available_child(dev->of_node, NULL); 33003+ if (np == NULL) { 33004+ printk("\nof_get_next_available_child failed!"); 33005+ goto fail; 33006+ } 33007+ mtd->name = np->name; 33008+ mtd->type = MTD_NANDFLASH; 33009+ mtd->priv = chip; 33010+ mtd->owner = THIS_MODULE; 33011+ 33012+ result = of_property_read_u32(np, "spi-max-frequency", &host->clkrate); 33013+ if (result) { 33014+ printk("\nget fmc clkrate failed"); 33015+ goto fail; 33016+ } 33017+ 33018+ result = hifmc_nand_scan(mtd); 33019+ if (result) { 33020+ FMC_PR(BT_DBG, "\t|-Scan SPI Nand failed.\n"); 33021+ goto fail; 33022+ } 33023+ 33024+ result = mtd_device_register(mtd, NULL, 0); 33025+ if (!result) { 33026+ FMC_PR(BT_DBG, "\t*-End driver probe !!\n"); 33027+ return 0; 33028+ } 33029+ 33030+ result = -ENODEV; 33031+ nand_release(mtd); 33032+fail: 33033+ clk_disable_unprepare(host->clk); 33034+ DB_MSG("Error: driver probe, result: %d\n", result); 33035+ return result; 33036+} 33037+ 33038+static int hisi_spi_nand_remove(struct platform_device *pltdev) 33039+{ 33040+ struct hifmc_host *host = platform_get_drvdata(pltdev); 33041+ 33042+ if (host) { 33043+ if (host->clk) 33044+ clk_disable_unprepare(host->clk); 33045+ if (host->mtd) 33046+ nand_release(host->mtd); 33047+ } 33048+ 33049+ return 0; 33050+} 33051+ 33052+#ifdef CONFIG_PM 33053+static int hifmc100_os_suspend(struct platform_device *pltdev, 33054+ pm_message_t state) 33055+{ 33056+ struct hifmc_host *host = platform_get_drvdata(pltdev); 33057+ 33058+ if (host && host->suspend) { 33059+ return (host->suspend)(pltdev, state); 33060+ } 33061+ 33062+ return 0; 33063+} 33064+ 33065+static int hifmc100_os_resume(struct platform_device *pltdev) 33066+{ 33067+ struct hifmc_host *host = platform_get_drvdata(pltdev); 33068+ 33069+ if (host && host->resume) { 33070+ return (host->resume)(pltdev); 33071+ } 33072+ 33073+ return 0; 33074+} 33075+#endif /* End of CONFIG_PM */ 33076+ 33077+static const struct of_device_id hisi_spi_nand_dt_ids[] = { 33078+ { .compatible = "hisilicon,hisi-spi-nand" }, 33079+ { } /* sentinel */ 33080+}; 33081+MODULE_DEVICE_TABLE(of, hisi_spi_nand_dt_ids); 33082+ 33083+static struct platform_driver hisi_spi_nand_driver = { 33084+ .driver = { 33085+ .name = "hisi_spi_nand", 33086+ .of_match_table = hisi_spi_nand_dt_ids, 33087+ }, 33088+ .probe = hisi_spi_nand_probe, 33089+ .remove = hisi_spi_nand_remove, 33090+#ifdef CONFIG_PM 33091+ .suspend = hifmc100_os_suspend, 33092+ .resume = hifmc100_os_resume, 33093+#endif 33094+}; 33095+module_platform_driver(hisi_spi_nand_driver); 33096+ 33097+MODULE_LICENSE("GPL"); 33098+MODULE_AUTHOR("BVT_BSP"); 33099+MODULE_DESCRIPTION("Hisilicon Flash Memory Controller V100 SPI Nand Driver"); 33100diff --git a/drivers/mtd/nand/hifmc100/hifmc100_spi_general.c b/drivers/mtd/nand/hifmc100/hifmc100_spi_general.c 33101new file mode 100644 33102index 000000000..3b46205f3 33103--- /dev/null 33104+++ b/drivers/mtd/nand/hifmc100/hifmc100_spi_general.c 33105@@ -0,0 +1,313 @@ 33106+/* 33107+ * The Flash Memory Controller v100 Device Driver for hisilicon 33108+ * 33109+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 33110+ * 33111+ * This program is free software; you can redistribute it and/or modify it 33112+ * under the terms of the GNU General Public License as published by the 33113+ * Free Software Foundation; either version 2 of the License, or (at your 33114+ * option) any later version. 33115+ * 33116+ * This program is distributed in the hope that it will be useful, 33117+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 33118+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33119+ * GNU General Public License for more details. 33120+ * 33121+ * You should have received a copy of the GNU General Public License 33122+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 33123+ * 33124+ */ 33125+ 33126+/* 33127+ Send set/get features command to SPI Nand flash 33128+*/ 33129+char spi_nand_feature_op(struct hifmc_spi *spi, u_char op, u_char addr, 33130+ u_char *val) 33131+{ 33132+ unsigned int reg; 33133+ const char *str[] = {"Get", "Set"}; 33134+ struct hifmc_host *host = NULL; 33135+ 33136+ if (!spi) { 33137+ DB_MSG("Error: spi is NULL !\n"); 33138+ return -1; 33139+ } 33140+ host = (struct hifmc_host *)spi->host; 33141+ if (!host) { 33142+ DB_MSG("Error: host is NULL !\n"); 33143+ return -1; 33144+ } 33145+ 33146+ if ((op == GET_OP) && (STATUS_ADDR == addr)) { 33147+ if (!val) { 33148+ DB_MSG("Error: val is NULL !\n"); 33149+ return -1; 33150+ } 33151+ if (SR_DBG) { 33152+ pr_info("\n"); 33153+ } 33154+ FMC_PR(SR_DBG, "\t\t|*-Start Get Status\n"); 33155+ 33156+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; 33157+ hifmc_writel(host, FMC_OP_CFG, reg); 33158+ FMC_PR(SR_DBG, "\t\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 33159+ 33160+ reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START; 33161+ hifmc_writel(host, FMC_OP, reg); 33162+ FMC_PR(SR_DBG, "\t\t||-Set OP[%#x]%#x\n", FMC_OP, reg); 33163+ 33164+ FMC_CMD_WAIT_CPU_FINISH(host); 33165+ 33166+ *val = hifmc_readl(host, FMC_STATUS); 33167+ FMC_PR(SR_DBG, "\t\t|*-End Get Status, result: %#x\n", *val); 33168+ 33169+ return 0; 33170+ } 33171+ 33172+ FMC_PR(FT_DBG, "\t|||*-Start %s feature, addr[%#x]\n", str[op], addr); 33173+ 33174+ hifmc100_ecc0_switch(host, ENABLE); 33175+ 33176+ reg = FMC_CMD_CMD1(op ? SPI_CMD_SET_FEATURE : SPI_CMD_GET_FEATURES); 33177+ hifmc_writel(host, FMC_CMD, reg); 33178+ FMC_PR(FT_DBG, "\t||||-Set CMD[%#x]%#x\n", FMC_CMD, reg); 33179+ 33180+ hifmc_writel(host, FMC_ADDRL, addr); 33181+ FMC_PR(FT_DBG, "\t||||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, addr); 33182+ 33183+ reg = OP_CFG_FM_CS(host->cmd_op.cs) 33184+ | OP_CFG_ADDR_NUM(FEATURES_OP_ADDR_NUM) 33185+ | OP_CFG_OEN_EN; 33186+ hifmc_writel(host, FMC_OP_CFG, reg); 33187+ FMC_PR(FT_DBG, "\t||||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 33188+ 33189+ reg = FMC_DATA_NUM_CNT(FEATURES_DATA_LEN); 33190+ hifmc_writel(host, FMC_DATA_NUM, reg); 33191+ FMC_PR(FT_DBG, "\t||||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg); 33192+ 33193+ reg = FMC_OP_CMD1_EN 33194+ | FMC_OP_ADDR_EN 33195+ | FMC_OP_REG_OP_START; 33196+ 33197+ if (op == SET_OP) { 33198+ if (!val || !host->iobase) { 33199+ DB_MSG("Error: host->iobase is NULL !\n"); 33200+ return -1; 33201+ } 33202+ reg |= FMC_OP_WRITE_DATA_EN; 33203+ hifmc_writeb(*val, host->iobase); 33204+ FMC_PR(FT_DBG, "\t||||-Write IO[%#lx]%#x\n", (long)host->iobase, 33205+ *(u_char *)host->iobase); 33206+ } else { 33207+ reg |= FMC_OP_READ_DATA_EN; 33208+ } 33209+ 33210+ hifmc_writel(host, FMC_OP, reg); 33211+ FMC_PR(FT_DBG, "\t||||-Set OP[%#x]%#x\n", FMC_OP, reg); 33212+ 33213+ FMC_CMD_WAIT_CPU_FINISH(host); 33214+ 33215+ if (op == GET_OP) { 33216+ if (!val || !host->iobase) { 33217+ DB_MSG("Error: val or host->iobase is NULL !\n"); 33218+ return -1; 33219+ } 33220+ *val = hifmc_readb(host->iobase); 33221+ FMC_PR(FT_DBG, "\t||||-Read IO[%#lx]%#x\n", (long)host->iobase, 33222+ *(u_char *)host->iobase); 33223+ } 33224+ 33225+ hifmc100_ecc0_switch(host, DISABLE); 33226+ 33227+ FMC_PR(FT_DBG, "\t|||*-End %s Feature[%#x]:%#x\n", str[op], addr, *val); 33228+ 33229+ return 0; 33230+} 33231+ 33232+/* 33233+ Read status[C0H]:[0]bit OIP, judge whether the device is busy or not 33234+*/ 33235+static int spi_general_wait_ready(struct hifmc_spi *spi) 33236+{ 33237+ unsigned char status; 33238+ int ret; 33239+ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; 33240+ struct hifmc_host *host = NULL; 33241+ 33242+ if(spi == NULL || spi->host == NULL) { 33243+ DB_MSG("Error: host or host->spi is NULL!\n"); 33244+ return -1; 33245+ } 33246+ host = (struct hifmc_host *)spi->host; 33247+ 33248+ do { 33249+ ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, &status); 33250+ if (ret) 33251+ return -1; 33252+ if (!(status & STATUS_OIP_MASK)) { 33253+ if ((host->cmd_op.l_cmd == NAND_CMD_ERASE2) 33254+ && (status & STATUS_E_FAIL_MASK)) { 33255+ return status; 33256+ } 33257+ if ((host->cmd_op.l_cmd == NAND_CMD_PAGEPROG) 33258+ && (status & STATUS_P_FAIL_MASK)) { 33259+ return status; 33260+ } 33261+ return 0; 33262+ } 33263+ 33264+ cond_resched(); 33265+ } while (!time_after_eq(jiffies, deadline)); 33266+ 33267+ DB_MSG("Error: SPI Nand wait ready timeout, status: %#x\n", status); 33268+ 33269+ return 1; 33270+} 33271+ 33272+/* 33273+ Send write enable cmd to SPI Nand, status[C0H]:[2]bit WEL must be set 1 33274+*/ 33275+static int spi_general_write_enable(struct hifmc_spi *spi) 33276+{ 33277+ u_char reg; 33278+ int ret; 33279+ unsigned int regl; 33280+ struct hifmc_host *host = NULL; 33281+ if(spi == NULL || spi->host == NULL) { 33282+ DB_MSG("Error: host or host->spi is NULL!\n"); 33283+ return -1; 33284+ } 33285+ host = spi->host; 33286+ if (WE_DBG) { 33287+ pr_info("\n"); 33288+ } 33289+ FMC_PR(WE_DBG, "\t|*-Start Write Enable\n"); 33290+ 33291+ ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, ®); 33292+ if (ret) 33293+ return -1; 33294+ if (reg & STATUS_WEL_MASK) { 33295+ FMC_PR(WE_DBG, "\t||-Write Enable was opened! reg: %#x\n", 33296+ reg); 33297+ return 0; 33298+ } 33299+ 33300+ regl = hifmc_readl(host, FMC_GLOBAL_CFG); 33301+ FMC_PR(WE_DBG, "\t||-Get GLOBAL_CFG[%#x]%#x\n", FMC_GLOBAL_CFG, regl); 33302+ if (regl & FMC_GLOBAL_CFG_WP_ENABLE) { 33303+ regl &= ~FMC_GLOBAL_CFG_WP_ENABLE; 33304+ hifmc_writel(host, FMC_GLOBAL_CFG, regl); 33305+ FMC_PR(WE_DBG, "\t||-Set GLOBAL_CFG[%#x]%#x\n", 33306+ FMC_GLOBAL_CFG, regl); 33307+ } 33308+ 33309+ regl = FMC_CMD_CMD1(SPI_CMD_WREN); 33310+ hifmc_writel(host, FMC_CMD, regl); 33311+ FMC_PR(WE_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, regl); 33312+ 33313+ regl = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; 33314+ hifmc_writel(host, FMC_OP_CFG, regl); 33315+ FMC_PR(WE_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, regl); 33316+ 33317+ regl = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START; 33318+ hifmc_writel(host, FMC_OP, regl); 33319+ FMC_PR(WE_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, regl); 33320+ 33321+ FMC_CMD_WAIT_CPU_FINISH(host); 33322+ 33323+#if WE_DBG 33324+ if(!spi->driver) { 33325+ DB_MSG("Error: spi->driver is NULL!\n"); 33326+ return -1; 33327+ } 33328+ spi->driver->wait_ready(spi); 33329+ 33330+ ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, ®); 33331+ if (ret) 33332+ return -1; 33333+ if (reg & STATUS_WEL_MASK) { 33334+ FMC_PR(WE_DBG, "\t||-Write Enable success. reg: %#x\n", reg); 33335+ } else { 33336+ DB_MSG("Error: Write Enable failed! reg: %#x\n", reg); 33337+ return reg; 33338+ } 33339+#endif 33340+ 33341+ FMC_PR(WE_DBG, "\t|*-End Write Enable\n"); 33342+ return 0; 33343+} 33344+ 33345+/* 33346+ judge whether SPI Nand support QUAD read/write or not 33347+*/ 33348+static int spi_is_quad(struct hifmc_spi *spi) 33349+{ 33350+ const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; 33351+ FMC_PR(QE_DBG, "\t\t|||*-SPI read iftype: %s write iftype: %s\n", 33352+ if_str[spi->read->iftype], if_str[spi->write->iftype]); 33353+ 33354+ if ((spi->read->iftype == IF_TYPE_QUAD) 33355+ || (spi->read->iftype == IF_TYPE_QIO) 33356+ || (spi->write->iftype == IF_TYPE_QUAD) 33357+ || (spi->write->iftype == IF_TYPE_QIO)) { 33358+ return 1; 33359+ } 33360+ 33361+ return 0; 33362+} 33363+ 33364+/* 33365+ Send set features cmd to SPI Nand, feature[B0H]:[0]bit QE would be set 33366+*/ 33367+static int spi_general_qe_enable(struct hifmc_spi *spi) 33368+{ 33369+ int op; 33370+ u_char reg; 33371+ int ret; 33372+ const char *str[] = {"Disable", "Enable"}; 33373+ 33374+ if(!spi || !spi->host || !spi->driver) { 33375+ DB_MSG("Error: host or spi->host or spi->driver is NULL!\n"); 33376+ return -1; 33377+ } 33378+ FMC_PR(QE_DBG, "\t||*-Start SPI Nand flash QE\n"); 33379+ 33380+ op = spi_is_quad(spi); 33381+ 33382+ FMC_PR(QE_DBG, "\t|||*-End Quad check, SPI Nand %s Quad.\n", str[op]); 33383+ 33384+ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); 33385+ if (ret) 33386+ return -1; 33387+ FMC_PR(QE_DBG, "\t|||-Get [%#x]feature: %#x\n", FEATURE_ADDR, reg); 33388+ if ((reg & FEATURE_QE_ENABLE) == op) { 33389+ FMC_PR(QE_DBG, "\t||*-SPI Nand quad was %sd!\n", str[op]); 33390+ return op; 33391+ } 33392+ 33393+ if (op == ENABLE) { 33394+ reg |= FEATURE_QE_ENABLE; 33395+ } else { 33396+ reg &= ~FEATURE_QE_ENABLE; 33397+ } 33398+ 33399+ ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, ®); 33400+ if (ret) 33401+ return -1; 33402+ FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad\n", str[op]); 33403+ 33404+ spi->driver->wait_ready(spi); 33405+ 33406+ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); 33407+ if (ret) 33408+ return -1; 33409+ if ((reg & FEATURE_QE_ENABLE) == op) { 33410+ FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad succeed!\n", str[op]); 33411+ } else { 33412+ DB_MSG("Error: %s Quad failed! reg: %#x\n", str[op], reg); 33413+ } 33414+ 33415+ FMC_PR(QE_DBG, "\t||*-End SPI Nand %s Quad.\n", str[op]); 33416+ 33417+ return op; 33418+} 33419diff --git a/drivers/mtd/nand/hifmc100/hifmc_spi_nand_ids.c b/drivers/mtd/nand/hifmc100/hifmc_spi_nand_ids.c 33420new file mode 100644 33421index 000000000..bf963d146 33422--- /dev/null 33423+++ b/drivers/mtd/nand/hifmc100/hifmc_spi_nand_ids.c 33424@@ -0,0 +1,2457 @@ 33425+/* 33426+ * The Flash Memory Controller v100 Device Driver for hisilicon 33427+ * 33428+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 33429+ * 33430+ * This program is free software; you can redistribute it and/or modify it 33431+ * under the terms of the GNU General Public License as published by the 33432+ * Free Software Foundation; either version 2 of the License, or (at your 33433+ * option) any later version. 33434+ * 33435+ * This program is distributed in the hope that it will be useful, 33436+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 33437+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33438+ * GNU General Public License for more details. 33439+ * 33440+ * You should have received a copy of the GNU General Public License 33441+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 33442+ * 33443+ */ 33444+ 33445+#include <asm/setup.h> 33446+#include <linux/types.h> 33447+#include <linux/io.h> 33448+#include <linux/sched.h> 33449+#include <linux/printk.h> 33450+#include <linux/platform_device.h> 33451+#include <linux/mtd/rawnand.h> 33452+#include <linux/mtd/partitions.h> 33453+#include <linux/mfd/hisi_fmc.h> 33454+#include <linux/uaccess.h> 33455+ 33456+#include "../raw/hinfc_gen.h" 33457+#include "hifmc100.h" 33458+ 33459+SET_READ_STD(1, INFINITE, 24); 33460+ 33461+SET_READ_FAST(1, INFINITE, 80); 33462+SET_READ_FAST(1, INFINITE, 100); 33463+SET_READ_FAST(1, INFINITE, 104); 33464+SET_READ_FAST(1, INFINITE, 108); 33465+SET_READ_FAST(1, INFINITE, 120); 33466+SET_READ_FAST(1, INFINITE, 133); 33467+ 33468+SET_READ_DUAL(1, INFINITE, 80); 33469+SET_READ_DUAL(1, INFINITE, 100); 33470+SET_READ_DUAL(1, INFINITE, 104); 33471+SET_READ_DUAL(1, INFINITE, 108); 33472+SET_READ_DUAL(1, INFINITE, 120); 33473+SET_READ_DUAL(1, INFINITE, 133); 33474+ 33475+SET_READ_DUAL_ADDR(1, INFINITE, 40); 33476+SET_READ_DUAL_ADDR(1, INFINITE, 80); 33477+SET_READ_DUAL_ADDR(2, INFINITE, 80); 33478+SET_READ_DUAL_ADDR(1, INFINITE, 100); 33479+SET_READ_DUAL_ADDR(1, INFINITE, 104); 33480+SET_READ_DUAL_ADDR(1, INFINITE, 108); 33481+SET_READ_DUAL_ADDR(1, INFINITE, 120); 33482+SET_READ_DUAL_ADDR(2, INFINITE, 104); 33483+ 33484+SET_READ_QUAD(1, INFINITE, 80); 33485+SET_READ_QUAD(1, INFINITE, 100); 33486+SET_READ_QUAD(1, INFINITE, 104); 33487+SET_READ_QUAD(1, INFINITE, 108); 33488+SET_READ_QUAD(1, INFINITE, 120); 33489+SET_READ_QUAD(1, INFINITE, 133); 33490+ 33491+SET_READ_QUAD_ADDR(2, INFINITE, 40); 33492+SET_READ_QUAD_ADDR(1, INFINITE, 80); 33493+SET_READ_QUAD_ADDR(2, INFINITE, 80); 33494+SET_READ_QUAD_ADDR(4, INFINITE, 80); 33495+SET_READ_QUAD_ADDR(1, INFINITE, 100); 33496+SET_READ_QUAD_ADDR(1, INFINITE, 104); 33497+SET_READ_QUAD_ADDR(2, INFINITE, 104); 33498+SET_READ_QUAD_ADDR(1, INFINITE, 108); 33499+SET_READ_QUAD_ADDR(1, INFINITE, 120); 33500+SET_READ_QUAD_ADDR(4, INFINITE, 104); 33501+ 33502+SET_WRITE_STD(0, 256, 24); 33503+SET_WRITE_STD(0, 256, 75); 33504+SET_WRITE_STD(0, 256, 80); 33505+SET_WRITE_STD(0, 256, 100); 33506+SET_WRITE_STD(0, 256, 104); 33507+SET_WRITE_STD(0, 256, 133); 33508+ 33509+SET_WRITE_QUAD(0, 256, 80); 33510+SET_WRITE_QUAD(0, 256, 100); 33511+SET_WRITE_QUAD(0, 256, 104); 33512+SET_WRITE_QUAD(0, 256, 108); 33513+SET_WRITE_QUAD(0, 256, 120); 33514+SET_WRITE_QUAD(0, 256, 133); 33515+ 33516+SET_ERASE_SECTOR_128K(0, _128K, 24); 33517+SET_ERASE_SECTOR_128K(0, _128K, 75); 33518+SET_ERASE_SECTOR_128K(0, _128K, 80); 33519+SET_ERASE_SECTOR_128K(0, _128K, 104); 33520+SET_ERASE_SECTOR_128K(0, _128K, 133); 33521+ 33522+SET_ERASE_SECTOR_256K(0, _256K, 24); 33523+SET_ERASE_SECTOR_256K(0, _256K, 75); 33524+SET_ERASE_SECTOR_256K(0, _256K, 80); 33525+SET_ERASE_SECTOR_256K(0, _256K, 100); 33526+SET_ERASE_SECTOR_256K(0, _256K, 104); 33527+SET_ERASE_SECTOR_256K(0, _256K, 133); 33528+ 33529+#include "hifmc100_spi_general.c" 33530+static struct spi_drv spi_driver_general = { 33531+ .wait_ready = spi_general_wait_ready, 33532+ .write_enable = spi_general_write_enable, 33533+ .qe_enable = spi_general_qe_enable, 33534+}; 33535+ 33536+/* some spi nand flash default QUAD enable, needn't to set qe enable */ 33537+static struct spi_drv spi_driver_no_qe = { 33538+ .wait_ready = spi_general_wait_ready, 33539+ .write_enable = spi_general_write_enable, 33540+}; 33541+ 33542+#define SPI_NAND_ID_TAB_VER "2.7" 33543+ 33544+/******* SPI Nand ID Table *************************************************** 33545+ * Version Manufacturer Chip Name Size Operation 33546+ * 1.0 ESMT F50L512M41A 64MB Add 5 chip 33547+ * GD 5F1GQ4UAYIG 128MB 33548+ * GD 5F2GQ4UAYIG 256MB 33549+ * GD GD5F2GQ5UEYIG 256MB 33550+ * GD 5F4GQ4UAYIG 512MB 33551+ * GD 5F4GQ4UBYIG 512MB 33552+ * GD 5F1GQ4RB9IG 128MB 33553+ * GD 5F1GQ4UEYIHY 128MB 33554+ * 1.1 ESMT F50L1G41A 128MB Add 2 chip 33555+ * Winbond W25N01GV 128MB 33556+ * Winbond W25N02JWZEIF 256MB 33557+ * 1.2 GD 5F1GQ4UBYIG 128MB Add 2 chip 33558+ * GD 5F2GQ4U9IGR/BYIG 256MB 33559+ * GD 1.8V 5F4GQ6RE9IG 512MB 33560+ * 1.3 ATO ATO25D1GA 128MB Add 1 chip 33561+ * 1.4 MXIC MX35LF1GE4AB 128MB Add 2 chip 33562+ * MXIC MX35LF2GE4AB 256MB (SOP-16Pin) 33563+ * 1.5 Paragon PN26G01A 128MB Add 1 chip 33564+ * 1.6 All-flash AFS1GQ4UAC 128MB Add 1 chip 33565+ * 1.7 TOSHIBA TC58CVG0S3H 128MB Add 2 chip 33566+ * TOSHIBA TC58CVG2S0H 512MB 33567+ * 1.8 ALL-flash AFS2GQ4UAD 256MB Add 2 chip 33568+ * Paragon PN26G02A 256MB 33569+ * 1.9 TOSHIBA TC58CVG1S3H 256MB Add 1 chip 33570+ * 2.0 HeYangTek HYF1GQ4UAACAE 128MB Add 3 chip 33571+ * HeYangTek HYF2GQ4UAACAE 256MB 33572+ * HeYangTek HYF4GQ4UAACBE 512MB 33573+ * 2.1 Micron MT29F1G01ABA 128MB Add 5 chip 33574+ * TOSHIBA 1.8V TC58CYG0S3H 128MB 33575+ * TOSHIBA 1.8V TC58CYG1S3H 256MB 33576+ * TOSHIBA 1.8V TC58CYG2S0H 512MB 33577+ * Winbond 1.8V W25N01GWZEIG 128MB 33578+ * 2.2 Micron MT29F2G01ABA 256MB Add 1 chip 33579+ * 2.3 MXIC MX35LF2G14AC 256MB Add 1 chip 33580+ * 2.4 GD 1.8V 5F4GQ4RAYIG 512MB Add 1 chip 33581+ * 2.5 GD 1.8V 5F2GQ4RB9IGR 256MB Add 1 chip 33582+ * 2.6 MXIC 1.8V MX35UF1G14AC 128MB Add 4 chip 33583+ * MXIC 1.8V MX35UF2G14AC 256MB 33584+ * Micron 1.8V MT29F1G01ABB 128MB 33585+ * Micron 1.8V MT29F2G01ABB 256MB 33586+ * 2.7 Dosilicon DS35Q1GA-IB 128MB Add 2 chip 33587+ * Dosilicon DS35Q2GA-IB 256MB 33588+ * GD 5F1GQ4RB9IGR 128MB 33589+ * Micron MT29F4G01ADAG 512MB 3.3V Add 1 chip 33590+ * GD 1.8V 5F4GQ4RBYIG 512MB Add 1 chip 33591+ * Etron 1.8V EM78D044VCF-H 256MB 33592+ * Etron 3.3V EM73C044VCC-H 128MB 33593+ * XTX 3.3V XT26G01B 1Gbit 128MB 33594+ * Micron MT29F4G01ABBFDW 512MB 1.8V 33595+ * FM FM25S01-DND-A-G 128MB 3.3V 33596+ * FM FM25S01A 128MB 3.3V 33597+ ******************************************************************************/ 33598+struct spi_nand_info hifmc_spi_nand_flash_table[] = { 33599+ /* Micron MT29F1G01ABA 1GBit */ 33600+ { 33601+ .name = "MT29F1G01ABA", 33602+ .id = {0x2C, 0x14}, 33603+ .id_len = 2, 33604+ .chipsize = _128M, 33605+ .erasesize = _128K, 33606+ .pagesize = _2K, 33607+ .oobsize = 128, 33608+ .badblock_pos = BBP_FIRST_PAGE, 33609+ .read = { 33610+ &READ_STD(1, INFINITE, 24), 33611+ &READ_FAST(1, INFINITE, 80), 33612+ &READ_DUAL(1, INFINITE, 80), 33613+ &READ_DUAL_ADDR(1, INFINITE, 80), 33614+ &READ_QUAD(1, INFINITE, 80), 33615+ &READ_QUAD_ADDR(2, INFINITE, 80), 33616+ 0 33617+ }, 33618+ .write = { 33619+ &WRITE_STD(0, 256, 80), 33620+ &WRITE_QUAD(0, 256, 80), 33621+ 0 33622+ }, 33623+ .erase = { 33624+ &ERASE_SECTOR_128K(0, _128K, 80), 33625+ 0 33626+ }, 33627+ .driver = &spi_driver_no_qe, 33628+ }, 33629+ 33630+ /* Micron MT29F1G01ABB 1GBit 1.8V */ 33631+ { 33632+ .name = "MT29F1G01ABB", 33633+ .id = {0x2C, 0x15}, 33634+ .id_len = 2, 33635+ .chipsize = _128M, 33636+ .erasesize = _128K, 33637+ .pagesize = _2K, 33638+ .oobsize = 128, 33639+ .badblock_pos = BBP_FIRST_PAGE, 33640+ .read = { 33641+ &READ_STD(1, INFINITE, 24), 33642+ &READ_FAST(1, INFINITE, 80), 33643+ &READ_DUAL(1, INFINITE, 80), 33644+ &READ_DUAL_ADDR(1, INFINITE, 80), 33645+ &READ_QUAD(1, INFINITE, 80), 33646+ &READ_QUAD_ADDR(2, INFINITE, 80), 33647+ 0 33648+ }, 33649+ .write = { 33650+ &WRITE_STD(0, 256, 80), 33651+ &WRITE_QUAD(0, 256, 80), 33652+ 0 33653+ }, 33654+ .erase = { 33655+ &ERASE_SECTOR_128K(0, _128K, 80), 33656+ 0 33657+ }, 33658+ .driver = &spi_driver_no_qe, 33659+ }, 33660+ 33661+ /* Micron MT29F2G01ABA 2GBit */ 33662+ { 33663+ .name = "MT29F2G01ABA", 33664+ .id = {0x2C, 0x24}, 33665+ .id_len = 2, 33666+ .chipsize = _256M, 33667+ .erasesize = _128K, 33668+ .pagesize = _2K, 33669+ .oobsize = 128, 33670+ .badblock_pos = BBP_FIRST_PAGE, 33671+ .read = { 33672+ &READ_STD(1, INFINITE, 24), 33673+ &READ_FAST(1, INFINITE, 108), 33674+ &READ_DUAL(1, INFINITE, 108), 33675+ &READ_DUAL_ADDR(1, INFINITE, 108), 33676+ &READ_QUAD(1, INFINITE, 108), 33677+ &READ_QUAD_ADDR(2, INFINITE, 104), 33678+ 0 33679+ }, 33680+ .write = { 33681+ &WRITE_STD(0, 256, 80), 33682+ &WRITE_QUAD(0, 256, 108), 33683+ 0 33684+ }, 33685+ .erase = { 33686+ &ERASE_SECTOR_128K(0, _128K, 80), 33687+ 0 33688+ }, 33689+ .driver = &spi_driver_no_qe, 33690+ }, 33691+ 33692+ /* Micron MT29F2G01ABB 2GBit 1.8V */ 33693+ { 33694+ .name = "MT29F2G01ABB", 33695+ .id = {0x2C, 0x25}, 33696+ .id_len = 2, 33697+ .chipsize = _256M, 33698+ .erasesize = _128K, 33699+ .pagesize = _2K, 33700+ .oobsize = 128, 33701+ .badblock_pos = BBP_FIRST_PAGE, 33702+ .read = { 33703+ &READ_STD(1, INFINITE, 24), 33704+ &READ_FAST(1, INFINITE, 80), 33705+ &READ_DUAL(1, INFINITE, 80), 33706+ &READ_DUAL_ADDR(1, INFINITE, 80), 33707+ &READ_QUAD(1, INFINITE, 80), 33708+ &READ_QUAD_ADDR(2, INFINITE, 80), 33709+ 0 33710+ }, 33711+ .write = { 33712+ &WRITE_STD(0, 256, 80), 33713+ &WRITE_QUAD(0, 256, 80), 33714+ 0 33715+ }, 33716+ .erase = { 33717+ &ERASE_SECTOR_128K(0, _128K, 80), 33718+ 0 33719+ }, 33720+ .driver = &spi_driver_no_qe, 33721+ }, 33722+ 33723+ /* Micron MT29F4G01ADAG 4GBit 3.3V */ 33724+ { 33725+ .name = "MT29F4G01ADAG", 33726+ .id = {0x2C, 0x36}, 33727+ .id_len = 2, 33728+ .chipsize = _512M, 33729+ .erasesize = _128K, 33730+ .pagesize = _2K, 33731+ .oobsize = 128, 33732+ .badblock_pos = BBP_FIRST_PAGE, 33733+ .read = { 33734+ &READ_STD(1, INFINITE, 24), 33735+ &READ_FAST(1, INFINITE, 108), 33736+ &READ_DUAL(1, INFINITE, 108), 33737+ &READ_DUAL_ADDR(1, INFINITE, 108), 33738+ &READ_QUAD(1, INFINITE, 108), 33739+ &READ_QUAD_ADDR(2, INFINITE, 104), 33740+ 0 33741+ }, 33742+ .write = { 33743+ &WRITE_STD(0, 256, 80), 33744+ &WRITE_QUAD(0, 256, 108), 33745+ 0 33746+ }, 33747+ .erase = { 33748+ &ERASE_SECTOR_128K(0, _128K, 80), 33749+ 0 33750+ }, 33751+ .driver = &spi_driver_no_qe, 33752+ }, 33753+ 33754+ /* ESMT F50L512M41A 512Mbit */ 33755+ { 33756+ .name = "F50L512M41A", 33757+ .id = {0xC8, 0x20}, 33758+ .id_len = 2, 33759+ .chipsize = _64M, 33760+ .erasesize = _128K, 33761+ .pagesize = _2K, 33762+ .oobsize = 64, 33763+ .badblock_pos = BBP_FIRST_PAGE, 33764+ .read = { 33765+ &READ_STD(1, INFINITE, 24), 33766+ &READ_FAST(1, INFINITE, 104), 33767+ &READ_DUAL(1, INFINITE, 104), 33768+ &READ_QUAD(1, INFINITE, 104), 33769+ 0 33770+ }, 33771+ .write = { 33772+ &WRITE_STD(0, 256, 24), 33773+ &WRITE_QUAD(0, 256, 104), 33774+ 0 33775+ }, 33776+ .erase = { 33777+ &ERASE_SECTOR_128K(0, _128K, 24), 33778+ 0 33779+ }, 33780+ .driver = &spi_driver_no_qe, 33781+ }, 33782+ 33783+ /* ESMT F50L1G41A 1Gbit */ 33784+ { 33785+ .name = "F50L1G41A", 33786+ .id = {0xC8, 0x21}, 33787+ .id_len = 2, 33788+ .chipsize = _128M, 33789+ .erasesize = _128K, 33790+ .pagesize = _2K, 33791+ .oobsize = 64, 33792+ .badblock_pos = BBP_FIRST_PAGE, 33793+ .read = { 33794+ &READ_STD(1, INFINITE, 24), 33795+ &READ_FAST(1, INFINITE, 104), 33796+ &READ_DUAL(1, INFINITE, 104), 33797+ &READ_QUAD(1, INFINITE, 104), 33798+ 0 33799+ }, 33800+ .write = { 33801+ &WRITE_STD(0, 256, 24), 33802+ &WRITE_QUAD(0, 256, 104), 33803+ 0 33804+ }, 33805+ .erase = { 33806+ &ERASE_SECTOR_128K(0, _128K, 24), 33807+ 0 33808+ }, 33809+ .driver = &spi_driver_no_qe, 33810+ }, 33811+ 33812+ /* GD 3.3v GD5F1GQ5UEYIGY/GD5F1GQ5UEYIGR 1Gbit */ 33813+ { 33814+ .name = "GD5F1GQ5UEYIGY", 33815+ .id = {0xc8, 0x51}, 33816+ .id_len = 2, 33817+ .chipsize = _128M, 33818+ .erasesize = _128K, 33819+ .pagesize = _2K, 33820+ .oobsize = 128, 33821+ .badblock_pos = BBP_FIRST_PAGE, 33822+ .read = { 33823+ &READ_STD(1, INFINITE, 24), 33824+ &READ_FAST(1, INFINITE, 133), 33825+ &READ_DUAL(1, INFINITE, 133), 33826+ &READ_QUAD(1, INFINITE, 133), 33827+ 0 33828+ }, 33829+ .write = { 33830+ &WRITE_STD(0, 256, 133), 33831+ &WRITE_QUAD(0, 256, 133), 33832+ 0 33833+ }, 33834+ .erase = { 33835+ &ERASE_SECTOR_128K(0, _128K, 133), 33836+ 0 33837+ }, 33838+ .driver = &spi_driver_general, 33839+ }, 33840+ 33841+ /* ESMT F50L1G41LB-104YG2ME 1Gbit */ 33842+ { 33843+ .name = "F50L1G41LB-104YG2ME", 33844+ .id = {0xC8, 0x01, 0X7F}, 33845+ .id_len = 3, 33846+ .chipsize = _128M, 33847+ .erasesize = _128K, 33848+ .pagesize = _2K, 33849+ .oobsize = 64, 33850+ .badblock_pos = BBP_FIRST_PAGE, 33851+ .read = { 33852+ &READ_STD(1, INFINITE, 24), 33853+ &READ_FAST(1, INFINITE, 104), 33854+ &READ_DUAL(1, INFINITE, 104), 33855+ &READ_QUAD(1, INFINITE, 104), 33856+ 0 33857+ }, 33858+ .write = { 33859+ &WRITE_STD(0, 256, 104), 33860+ &WRITE_QUAD(0, 256, 104), 33861+ 0 33862+ }, 33863+ .erase = { 33864+ &ERASE_SECTOR_128K(0, _128K, 104), 33865+ 0 33866+ }, 33867+ .driver = &spi_driver_no_qe, 33868+ }, 33869+ 33870+ /* GD 3.3v GD5F1GQ4UAYIG 1Gbit */ 33871+ { 33872+ .name = "GD5F1GQ4UAYIG", 33873+ .id = {0xc8, 0xf1}, 33874+ .id_len = 2, 33875+ .chipsize = _128M, 33876+ .erasesize = _128K, 33877+ .pagesize = _2K, 33878+ .oobsize = 64, 33879+ .badblock_pos = BBP_FIRST_PAGE, 33880+ .read = { 33881+ &READ_STD(1, INFINITE, 24), 33882+ &READ_FAST(1, INFINITE, 120), 33883+ &READ_DUAL(1, INFINITE, 120), 33884+ &READ_DUAL_ADDR(1, INFINITE, 120), 33885+ &READ_QUAD(1, INFINITE, 120), 33886+ &READ_QUAD_ADDR(1, INFINITE, 120), 33887+ 0 33888+ }, 33889+ .write = { 33890+ &WRITE_STD(0, 256, 24), 33891+ &WRITE_QUAD(0, 256, 120), 33892+ 0 33893+ }, 33894+ .erase = { 33895+ &ERASE_SECTOR_128K(0, _128K, 24), 33896+ 0 33897+ }, 33898+ .driver = &spi_driver_general, 33899+ }, 33900+ 33901+ /* GD 1.8v GD5F1GQ5REYIG 1Gbit */ 33902+ { 33903+ .name = "GD5F1GQ5REYIG", 33904+ .id = {0xc8, 0x41}, 33905+ .id_len = 2, 33906+ .chipsize = _128M, 33907+ .erasesize = _128K, 33908+ .pagesize = _2K, 33909+ .oobsize = 128, 33910+ .badblock_pos = BBP_FIRST_PAGE, 33911+ .read = { 33912+ &READ_STD(1, INFINITE, 24), 33913+ &READ_FAST(1, INFINITE, 104), 33914+ &READ_DUAL(1, INFINITE, 104), 33915+ &READ_QUAD(1, INFINITE, 104), 33916+ 0 33917+ }, 33918+ .write = { 33919+ &WRITE_STD(0, 256, 24), 33920+ &WRITE_QUAD(0, 256, 104), 33921+ 0 33922+ }, 33923+ .erase = { 33924+ &ERASE_SECTOR_128K(0, _128K, 104), 33925+ 0 33926+ }, 33927+ .driver = &spi_driver_general, 33928+ }, 33929+ 33930+ /* GD 3.3v GD5F1GQ4UEYIHY 1Gbit */ 33931+ { 33932+ .name = "GD5F1GQ4UEYIHY", 33933+ .id = {0xc8, 0xd9}, 33934+ .id_len = 2, 33935+ .chipsize = _128M, 33936+ .erasesize = _128K, 33937+ .pagesize = _2K, 33938+ .oobsize = 64, 33939+ .badblock_pos = BBP_FIRST_PAGE, 33940+ .read = { 33941+ &READ_STD(1, INFINITE, 24), 33942+ &READ_FAST(1, INFINITE, 120), 33943+ &READ_DUAL(1, INFINITE, 120), 33944+ &READ_DUAL_ADDR(1, INFINITE, 120), 33945+ &READ_QUAD(1, INFINITE, 120), 33946+ &READ_QUAD_ADDR(1, INFINITE, 120), 33947+ 0 33948+ }, 33949+ .write = { 33950+ &WRITE_STD(0, 256, 104), 33951+ &WRITE_QUAD(0, 256, 120), 33952+ 0 33953+ }, 33954+ .erase = { 33955+ &ERASE_SECTOR_128K(0, _128K, 104), 33956+ 0 33957+ }, 33958+ .driver = &spi_driver_general, 33959+ }, 33960+ 33961+ /* GD 1.8v GD5F1GQ4RB9IG 1Gbit */ 33962+ { 33963+ .name = "GD5F1GQ4RB9IG", 33964+ .id = {0xc8, 0xc1}, 33965+ .id_len = 2, 33966+ .chipsize = _128M, 33967+ .erasesize = _128K, 33968+ .pagesize = _2K, 33969+ .oobsize = 128, 33970+ .badblock_pos = BBP_FIRST_PAGE, 33971+ .read = { 33972+ &READ_STD(1, INFINITE, 24), 33973+ &READ_FAST(1, INFINITE, 120), 33974+ &READ_DUAL(1, INFINITE, 120), 33975+ &READ_DUAL_ADDR(1, INFINITE, 120), 33976+ &READ_QUAD(1, INFINITE, 120), 33977+ &READ_QUAD_ADDR(1, INFINITE, 120), 33978+ 0 33979+ }, 33980+ .write = { 33981+ &WRITE_STD(0, 256, 24), 33982+ &WRITE_QUAD(0, 256, 120), 33983+ 0 33984+ }, 33985+ .erase = { 33986+ &ERASE_SECTOR_128K(0, _128K, 24), 33987+ 0 33988+ }, 33989+ .driver = &spi_driver_general, 33990+ }, 33991+ 33992+ /* GD 3.3v GD5F1GQ4UBYIG 1Gbit */ 33993+ { 33994+ .name = "GD5F1GQ4UBYIG", 33995+ .id = {0xc8, 0xd1}, 33996+ .id_len = 2, 33997+ .chipsize = _128M, 33998+ .erasesize = _128K, 33999+ .pagesize = _2K, 34000+ .oobsize = 128, 34001+ .badblock_pos = BBP_FIRST_PAGE, 34002+ .read = { 34003+ &READ_STD(1, INFINITE, 24), 34004+ &READ_FAST(1, INFINITE, 120), 34005+ &READ_DUAL(1, INFINITE, 120), 34006+ &READ_DUAL_ADDR(1, INFINITE, 120), 34007+ &READ_QUAD(1, INFINITE, 120), 34008+ &READ_QUAD_ADDR(1, INFINITE, 120), 34009+ 0 34010+ }, 34011+ .write = { 34012+ &WRITE_STD(0, 256, 24), 34013+ &WRITE_QUAD(0, 256, 120), 34014+ 0 34015+ }, 34016+ .erase = { 34017+ &ERASE_SECTOR_128K(0, _128K, 24), 34018+ 0 34019+ }, 34020+ .driver = &spi_driver_general, 34021+ }, 34022+ 34023+ /* GD 3.3v GD5F2GQ4UAYIG 2Gbit */ 34024+ { 34025+ .name = "GD5F2GQ4UAYIG", 34026+ .id = {0xc8, 0xf2}, 34027+ .id_len = 2, 34028+ .chipsize = _256M, 34029+ .erasesize = _128K, 34030+ .pagesize = _2K, 34031+ .oobsize = 64, 34032+ .badblock_pos = BBP_FIRST_PAGE, 34033+ .read = { 34034+ &READ_STD(1, INFINITE, 24), 34035+ &READ_FAST(1, INFINITE, 120), 34036+ &READ_DUAL(1, INFINITE, 120), 34037+ &READ_DUAL_ADDR(1, INFINITE, 120), 34038+ &READ_QUAD(1, INFINITE, 120), 34039+ &READ_QUAD_ADDR(1, INFINITE, 120), 34040+ 0 34041+ }, 34042+ .write = { 34043+ &WRITE_STD(0, 256, 24), 34044+ &WRITE_QUAD(0, 256, 120), 34045+ 0 34046+ }, 34047+ .erase = { 34048+ &ERASE_SECTOR_128K(0, _128K, 24), 34049+ 0 34050+ }, 34051+ .driver = &spi_driver_general, 34052+ }, 34053+ 34054+ /* GD 3.3v GD5F2GQ4U9IGR/BYIG 2Gbit */ 34055+ { 34056+ .name = "GD5F2GQ4U9IGR/BYIG", 34057+ .id = {0xc8, 0xd2}, 34058+ .id_len = 2, 34059+ .chipsize = _256M, 34060+ .erasesize = _128K, 34061+ .pagesize = _2K, 34062+ .oobsize = 128, 34063+ .badblock_pos = BBP_FIRST_PAGE, 34064+ .read = { 34065+ &READ_STD(1, INFINITE, 24), 34066+ &READ_FAST(1, INFINITE, 120), 34067+ &READ_DUAL(1, INFINITE, 120), 34068+ &READ_DUAL_ADDR(1, INFINITE, 120), 34069+ &READ_QUAD(1, INFINITE, 120), 34070+ &READ_QUAD_ADDR(1, INFINITE, 120), 34071+ 0 34072+ }, 34073+ .write = { 34074+ &WRITE_STD(0, 256, 24), 34075+ &WRITE_QUAD(0, 256, 120), 34076+ 0 34077+ }, 34078+ .erase = { 34079+ &ERASE_SECTOR_128K(0, _128K, 24), 34080+ 0 34081+ }, 34082+ .driver = &spi_driver_general, 34083+ }, 34084+ 34085+ /* GD 3.3v GD5F2GQ5UEYIG 2Gbit */ 34086+ { 34087+ .name = "GD5F2GQ5UEYIG", 34088+ .id = {0xc8, 0x52}, 34089+ .id_len = 2, 34090+ .chipsize = _256M, 34091+ .erasesize = _128K, 34092+ .pagesize = _2K, 34093+ .oobsize = 128, 34094+ .badblock_pos = BBP_FIRST_PAGE, 34095+ .read = { 34096+ &READ_STD(1, INFINITE, 24), 34097+ &READ_FAST(1, INFINITE, 104), 34098+ &READ_DUAL(1, INFINITE, 104), 34099+ &READ_DUAL_ADDR(2, INFINITE, 104), 34100+ &READ_QUAD(1, INFINITE, 104), 34101+ &READ_QUAD_ADDR(4, INFINITE, 104), 34102+ 0 34103+ }, 34104+ .write = { 34105+ &WRITE_STD(0, 256, 104), 34106+ &WRITE_QUAD(0, 256, 120), 34107+ 0 34108+ }, 34109+ .erase = { 34110+ &ERASE_SECTOR_128K(0, _128K, 104), 34111+ 0 34112+ }, 34113+ .driver = &spi_driver_general, 34114+ }, 34115+ 34116+ /* GD 1.8v GD5F2GQ5REYIG 2Gbit */ 34117+ { 34118+ .name = "GD5F2GQ5REYIG", 34119+ .id = {0xc8, 0x42}, 34120+ .id_len = 2, 34121+ .chipsize = _256M, 34122+ .erasesize = _128K, 34123+ .pagesize = _2K, 34124+ .oobsize = 128, 34125+ .badblock_pos = BBP_FIRST_PAGE, 34126+ .read = { 34127+ &READ_STD(1, INFINITE, 24), 34128+ &READ_FAST(1, INFINITE, 104), 34129+ &READ_DUAL(1, INFINITE, 104), 34130+ &READ_DUAL_ADDR(2, INFINITE, 104), 34131+ &READ_QUAD(1, INFINITE, 104), 34132+ &READ_QUAD_ADDR(4, INFINITE, 104), 34133+ 0 34134+ }, 34135+ .write = { 34136+ &WRITE_STD(0, 256, 104), 34137+ &WRITE_QUAD(0, 256, 104), 34138+ 0 34139+ }, 34140+ .erase = { 34141+ &ERASE_SECTOR_128K(0, _128K, 104), 34142+ 0 34143+ }, 34144+ .driver = &spi_driver_general, 34145+ }, 34146+ 34147+ /* GD 3.3v GD5F4GQ4UAYIG 4Gbit */ 34148+ { 34149+ .name = "GD5F4GQ4UAYIG", 34150+ .id = {0xc8, 0xf4}, 34151+ .id_len = 2, 34152+ .chipsize = _512M, 34153+ .erasesize = _128K, 34154+ .pagesize = _2K, 34155+ .oobsize = 64, 34156+ .badblock_pos = BBP_FIRST_PAGE, 34157+ .read = { 34158+ &READ_STD(1, INFINITE, 24), 34159+ &READ_FAST(1, INFINITE, 120), 34160+ &READ_DUAL(1, INFINITE, 120), 34161+ &READ_DUAL_ADDR(1, INFINITE, 120), 34162+ &READ_QUAD(1, INFINITE, 120), 34163+ &READ_QUAD_ADDR(1, INFINITE, 120), 34164+ 0 34165+ }, 34166+ .write = { 34167+ &WRITE_STD(0, 256, 24), 34168+ &WRITE_QUAD(0, 256, 120), 34169+ 0 34170+ }, 34171+ .erase = { 34172+ &ERASE_SECTOR_128K(0, _128K, 24), 34173+ 0 34174+ }, 34175+ .driver = &spi_driver_general, 34176+ }, 34177+ 34178+ /* GD 3.3v GD5F4GQ4UBYIG 4Gbit */ 34179+ { 34180+ .name = "GD5F4GQ4UBYIG", 34181+ .id = {0xc8, 0xd4}, 34182+ .id_len = 2, 34183+ .chipsize = _512M, 34184+ .erasesize = _256K, 34185+ .pagesize = _4K, 34186+ .oobsize = 256, 34187+ .badblock_pos = BBP_FIRST_PAGE, 34188+ .read = { 34189+ &READ_STD(1, INFINITE, 24), 34190+ &READ_FAST(1, INFINITE, 120), 34191+ &READ_DUAL(1, INFINITE, 120), 34192+ &READ_DUAL_ADDR(1, INFINITE, 120), 34193+ &READ_QUAD(1, INFINITE, 120), 34194+ &READ_QUAD_ADDR(1, INFINITE, 120), 34195+ 0 34196+ }, 34197+ .write = { 34198+ &WRITE_STD(0, 256, 24), 34199+ &WRITE_QUAD(0, 256, 120), 34200+ 0 34201+ }, 34202+ .erase = { 34203+ &ERASE_SECTOR_256K(0, _256K, 24), 34204+ 0 34205+ }, 34206+ .driver = &spi_driver_general, 34207+ }, 34208+ 34209+ /* GD 3.3v GD5F4GQ6UEYIG 4Gbit */ 34210+ { 34211+ .name = "GD5F4GQ6UEYIG", 34212+ .id = {0xc8, 0x55}, 34213+ .id_len = 2, 34214+ .chipsize = _512M, 34215+ .erasesize = _128K, 34216+ .pagesize = _2K, 34217+ .oobsize = 128, 34218+ .badblock_pos = BBP_FIRST_PAGE, 34219+ .read = { 34220+ &READ_STD(1, INFINITE, 24), /* 24MHz */ 34221+ &READ_FAST(1, INFINITE, 104), /* 104MHz */ 34222+ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ 34223+ &READ_DUAL_ADDR(2, INFINITE, 104), /* 104MHz */ 34224+ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ 34225+ &READ_QUAD_ADDR(4, INFINITE, 104), /* 104MHz */ 34226+ 0 34227+ }, 34228+ .write = { 34229+ &WRITE_STD(0, 256, 24), /* 24MHz */ 34230+ &WRITE_QUAD(0, 256, 104), /* 104MHz */ 34231+ 0 34232+ }, 34233+ .erase = { 34234+ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ 34235+ 0 34236+ }, 34237+ .driver = &spi_driver_general, 34238+ }, 34239+ 34240+ /* GD 1.8V GD5F1GQ4RB9IGR 1Gbit */ 34241+ { 34242+ .name = "GD5F1GQ4RB9IGR", 34243+ .id = {0xc8, 0xc1}, 34244+ .id_len = 2, 34245+ .chipsize = _128M, 34246+ .erasesize = _128K, 34247+ .pagesize = _2K, 34248+ .oobsize = 128, 34249+ .badblock_pos = BBP_FIRST_PAGE, 34250+ .read = { 34251+ &READ_STD(1, INFINITE, 24), 34252+ &READ_FAST(1, INFINITE, 104), 34253+ &READ_DUAL(1, INFINITE, 104), 34254+ &READ_DUAL_ADDR(1, INFINITE, 104), 34255+ &READ_QUAD(1, INFINITE, 104), 34256+ &READ_QUAD_ADDR(1, INFINITE, 104), 34257+ 0 34258+ }, 34259+ .write = { 34260+ &WRITE_STD(0, 256, 24), 34261+ &WRITE_QUAD(0, 256, 104), 34262+ 0 34263+ }, 34264+ .erase = { 34265+ &ERASE_SECTOR_128K(0, _128K, 24), 34266+ 0 34267+ }, 34268+ .driver = &spi_driver_general, 34269+ }, 34270+ 34271+ /* GD 1.8V GD5F2GQ4RB9IGR 2Gbit */ 34272+ { 34273+ .name = "GD5F2GQ4RB9IGR", 34274+ .id = {0xc8, 0xc2}, 34275+ .id_len = 2, 34276+ .chipsize = _256M, 34277+ .erasesize = _128K, 34278+ .pagesize = _2K, 34279+ .oobsize = 128, 34280+ .badblock_pos = BBP_FIRST_PAGE, 34281+ .read = { 34282+ &READ_STD(1, INFINITE, 24), 34283+ &READ_FAST(1, INFINITE, 104), 34284+ &READ_DUAL(1, INFINITE, 104), 34285+ &READ_DUAL_ADDR(1, INFINITE, 104), 34286+ &READ_QUAD(1, INFINITE, 104), 34287+ &READ_QUAD_ADDR(1, INFINITE, 104), 34288+ 0 34289+ }, 34290+ .write = { 34291+ &WRITE_STD(0, 256, 24), 34292+ &WRITE_QUAD(0, 256, 104), 34293+ 0 34294+ }, 34295+ .erase = { 34296+ &ERASE_SECTOR_128K(0, _128K, 24), 34297+ 0 34298+ }, 34299+ .driver = &spi_driver_general, 34300+ }, 34301+ /* GD 1.8V 5F4GQ6RE9IG 4Gbit */ 34302+ { 34303+ .name = "GD5F4GQ6RE9IG", 34304+ .id = {0xc8, 0x45}, 34305+ .id_len = 2, 34306+ .chipsize = _512M, 34307+ .erasesize = _128K, 34308+ .pagesize = _2K, 34309+ .oobsize = 128, 34310+ .badblock_pos = BBP_FIRST_PAGE, 34311+ .read = { 34312+ &READ_STD(1, INFINITE, 24), 34313+ &READ_FAST(1, INFINITE, 80), 34314+ &READ_DUAL(1, INFINITE, 80), 34315+ &READ_DUAL_ADDR(2, INFINITE, 80), 34316+ &READ_QUAD(1, INFINITE, 80), 34317+ &READ_QUAD_ADDR(4, INFINITE, 80), 34318+ 0 34319+ }, 34320+ .write = { 34321+ &WRITE_STD(0, 256, 80), 34322+ &WRITE_QUAD(0, 256, 80), 34323+ 0 34324+ }, 34325+ .erase = { 34326+ &ERASE_SECTOR_128K(0, _128K, 80), 34327+ 0 34328+ }, 34329+ .driver = &spi_driver_general, 34330+ }, 34331+ /* GD 1.8V GD5F4GQ4RAYIG 4Gbit */ 34332+ { 34333+ .name = "GD5F4GQ4RAYIG", 34334+ .id = {0xc8, 0xe4}, 34335+ .id_len = 2, 34336+ .chipsize = _512M, 34337+ .erasesize = _256K, 34338+ .pagesize = _4K, 34339+ .oobsize = 256, 34340+ .badblock_pos = BBP_FIRST_PAGE, 34341+ .read = { 34342+ &READ_STD(1, INFINITE, 24), 34343+ &READ_FAST(1, INFINITE, 104), 34344+ &READ_DUAL(1, INFINITE, 104), 34345+ &READ_DUAL_ADDR(1, INFINITE, 104), 34346+ &READ_QUAD(1, INFINITE, 104), 34347+ &READ_QUAD_ADDR(1, INFINITE, 104), 34348+ 0 34349+ }, 34350+ .write = { 34351+ &WRITE_STD(0, 256, 24), 34352+ &WRITE_QUAD(0, 256, 104), 34353+ 0 34354+ }, 34355+ .erase = { 34356+ &ERASE_SECTOR_256K(0, _256K, 24), 34357+ 0 34358+ }, 34359+ .driver = &spi_driver_general, 34360+ }, 34361+ 34362+ /* Winbond 1.8V W25N02JWZEIF 2Gbit */ 34363+ { 34364+ .name = "W25N02JWZEIF", 34365+ .id = {0xef, 0xbf, 0x22}, 34366+ .id_len = 3, 34367+ .chipsize = _256M, 34368+ .erasesize = _128K, 34369+ .pagesize = _2K, 34370+ .oobsize = 64, 34371+ .badblock_pos = BBP_FIRST_PAGE, 34372+ .read = { 34373+ &READ_STD(1, INFINITE, 24), 34374+ &READ_FAST(1, INFINITE, 120), 34375+ &READ_DUAL(1, INFINITE, 120), 34376+ &READ_DUAL_ADDR(1, INFINITE, 120), 34377+ &READ_QUAD(1, INFINITE, 120), 34378+ &READ_QUAD_ADDR(2, INFINITE, 104), 34379+ 0 34380+ }, 34381+ .write = { 34382+ &WRITE_STD(0, 256, 104), 34383+ &WRITE_QUAD(0, 256, 104), 34384+ 0 34385+ }, 34386+ .erase = { 34387+ &ERASE_SECTOR_128K(0, _128K, 104), 34388+ 0 34389+ }, 34390+ .driver = &spi_driver_general, 34391+ }, 34392+ 34393+ /* GD 1.8V 5F4GQ4RBYIG 4Gbit */ 34394+ { 34395+ .name = "5F4GQ4RBYIG", 34396+ .id = {0xc8, 0xc4}, 34397+ .id_len = 2, 34398+ .chipsize = _512M, 34399+ .erasesize = _256K, 34400+ .pagesize = _4K, 34401+ .oobsize = 256, 34402+ .badblock_pos = BBP_FIRST_PAGE, 34403+ .read = { 34404+ &READ_STD(1, INFINITE, 24), 34405+ &READ_FAST(1, INFINITE, 120), 34406+ &READ_DUAL(1, INFINITE, 120), 34407+ &READ_DUAL_ADDR(1, INFINITE, 120), 34408+ &READ_QUAD(1, INFINITE, 120), 34409+ &READ_QUAD_ADDR(1, INFINITE, 120), 34410+ 0 34411+ }, 34412+ .write = { 34413+ &WRITE_STD(0, 256, 24), 34414+ &WRITE_QUAD(0, 256, 120), 34415+ 0 34416+ }, 34417+ .erase = { 34418+ &ERASE_SECTOR_256K(0, _256K, 24), 34419+ 0 34420+ }, 34421+ .driver = &spi_driver_general, 34422+ }, 34423+ 34424+ /* Winbond W25N01GV 1Gbit 3.3V */ 34425+ { 34426+ .name = "W25N01GV", 34427+ .id = {0xef, 0xaa, 0x21}, 34428+ .id_len = 3, 34429+ .chipsize = _128M, 34430+ .erasesize = _128K, 34431+ .pagesize = _2K, 34432+ .oobsize = 64, 34433+ .badblock_pos = BBP_FIRST_PAGE, 34434+ .read = { 34435+ &READ_STD(1, INFINITE, 24), 34436+ &READ_FAST(1, INFINITE, 104), 34437+ &READ_DUAL(1, INFINITE, 104), 34438+ &READ_DUAL_ADDR(1, INFINITE, 104), 34439+ &READ_QUAD(1, INFINITE, 104), 34440+ &READ_QUAD_ADDR(2, INFINITE, 104), 34441+ 0 34442+ }, 34443+ .write = { 34444+ &WRITE_STD(0, 256, 24), 34445+ &WRITE_QUAD(0, 256, 104), 34446+ 0 34447+ }, 34448+ .erase = { 34449+ &ERASE_SECTOR_128K(0, _128K, 24), 34450+ 0 34451+ }, 34452+ .driver = &spi_driver_no_qe, 34453+ }, 34454+ 34455+ /* Winbond W25N01GWZEIG 1Gbit 1.8V */ 34456+ { 34457+ .name = "W25N01GWZEIG", 34458+ .id = {0xef, 0xba, 0x21}, 34459+ .id_len = 3, 34460+ .chipsize = _128M, 34461+ .erasesize = _128K, 34462+ .pagesize = _2K, 34463+ .oobsize = 64, 34464+ .badblock_pos = BBP_FIRST_PAGE, 34465+ .read = { 34466+ &READ_STD(1, INFINITE, 24), 34467+ &READ_FAST(1, INFINITE, 104), 34468+ &READ_DUAL(1, INFINITE, 104), 34469+ &READ_DUAL_ADDR(1, INFINITE, 104), 34470+ &READ_QUAD(1, INFINITE, 104), 34471+ &READ_QUAD_ADDR(2, INFINITE, 104), 34472+ 0 34473+ }, 34474+ .write = { 34475+ &WRITE_STD(0, 256, 24), 34476+ &WRITE_QUAD(0, 256, 80), 34477+ 0 34478+ }, 34479+ .erase = { 34480+ &ERASE_SECTOR_128K(0, _128K, 24), 34481+ 0 34482+ }, 34483+ .driver = &spi_driver_no_qe, 34484+ }, 34485+ 34486+ /* ATO ATO25D1GA 1Gbit */ 34487+ { 34488+ .name = "ATO25D1GA", 34489+ .id = {0x9b, 0x12}, 34490+ .id_len = 2, 34491+ .chipsize = _128M, 34492+ .erasesize = _128K, 34493+ .pagesize = _2K, 34494+ .oobsize = 64, 34495+ .badblock_pos = BBP_FIRST_PAGE, 34496+ .read = { 34497+ &READ_STD(1, INFINITE, 24), 34498+ &READ_FAST(1, INFINITE, 104), 34499+ &READ_QUAD(1, INFINITE, 104), 34500+ 0 34501+ }, 34502+ .write = { 34503+ &WRITE_STD(0, 256, 24), 34504+ &WRITE_QUAD(0, 256, 104), 34505+ 0 34506+ }, 34507+ .erase = { 34508+ &ERASE_SECTOR_128K(0, _128K, 24), 34509+ 0 34510+ }, 34511+ .driver = &spi_driver_general, 34512+ }, 34513+ 34514+ /* MXIC MX35LF1GE4AB 1Gbit */ 34515+ { 34516+ .name = "MX35LF1GE4AB", 34517+ .id = {0xc2, 0x12}, 34518+ .id_len = 2, 34519+ .chipsize = _128M, 34520+ .erasesize = _128K, 34521+ .pagesize = _2K, 34522+ .oobsize = 64, 34523+ .badblock_pos = BBP_FIRST_PAGE, 34524+ .read = { 34525+ &READ_STD(1, INFINITE, 24), 34526+ &READ_FAST(1, INFINITE, 104), 34527+ &READ_QUAD(1, INFINITE, 104), 34528+ 0 34529+ }, 34530+ .write = { 34531+ &WRITE_STD(0, 256, 24), 34532+ &WRITE_QUAD(0, 256, 104), 34533+ 0 34534+ }, 34535+ .erase = { 34536+ &ERASE_SECTOR_128K(0, _128K, 24), 34537+ 0 34538+ }, 34539+ .driver = &spi_driver_general, 34540+ }, 34541+ 34542+ /* MXIC MX35UF1G14AC 1Gbit 1.8V */ 34543+ { 34544+ .name = "MX35UF1G14AC", 34545+ .id = {0xc2, 0x90}, 34546+ .id_len = 2, 34547+ .chipsize = _128M, 34548+ .erasesize = _128K, 34549+ .pagesize = _2K, 34550+ .oobsize = 64, 34551+ .badblock_pos = BBP_FIRST_PAGE, 34552+ .read = { 34553+ &READ_STD(1, INFINITE, 24), 34554+ &READ_FAST(1, INFINITE, 104), 34555+ &READ_QUAD(1, INFINITE, 104), 34556+ 0 34557+ }, 34558+ .write = { 34559+ &WRITE_STD(0, 256, 24), 34560+ &WRITE_QUAD(0, 256, 104), 34561+ 0 34562+ }, 34563+ .erase = { 34564+ &ERASE_SECTOR_128K(0, _128K, 104), 34565+ 0 34566+ }, 34567+ .driver = &spi_driver_general, 34568+ }, 34569+ 34570+ /* MXIC MX35LF2GE4AB 2Gbit SOP-16Pin */ 34571+ { 34572+ .name = "MX35LF2GE4AB", 34573+ .id = {0xc2, 0x22}, 34574+ .id_len = 2, 34575+ .chipsize = _256M, 34576+ .erasesize = _128K, 34577+ .pagesize = _2K, 34578+ .oobsize = 64, 34579+ .badblock_pos = BBP_FIRST_PAGE, 34580+ .read = { 34581+ &READ_STD(1, INFINITE, 24), 34582+ &READ_FAST(1, INFINITE, 104), 34583+ &READ_QUAD(1, INFINITE, 104), 34584+ 0 34585+ }, 34586+ .write = { 34587+ &WRITE_STD(0, 256, 24), 34588+ &WRITE_QUAD(0, 256, 104), 34589+ 0 34590+ }, 34591+ .erase = { 34592+ &ERASE_SECTOR_128K(0, _128K, 24), 34593+ 0 34594+ }, 34595+ .driver = &spi_driver_general, 34596+ }, 34597+ 34598+ /* MXIC MX35LF2G14AC 2GBit */ 34599+ { 34600+ .name = "MX35LF2G14AC", 34601+ .id = {0xc2, 0x20}, 34602+ .id_len = 2, 34603+ .chipsize = _256M, 34604+ .erasesize = _128K, 34605+ .pagesize = _2K, 34606+ .oobsize = 64, 34607+ .badblock_pos = BBP_FIRST_PAGE, 34608+ .read = { 34609+ &READ_STD(1, INFINITE, 24), 34610+ &READ_FAST(1, INFINITE, 104), 34611+ &READ_QUAD(1, INFINITE, 104), 34612+ 0 34613+ }, 34614+ .write = { 34615+ &WRITE_STD(0, 256, 24), 34616+ &WRITE_QUAD(0, 256, 104), 34617+ 0 34618+ }, 34619+ .erase = { 34620+ &ERASE_SECTOR_128K(0, _128K, 24), 34621+ 0 34622+ }, 34623+ .driver = &spi_driver_general, 34624+ }, 34625+ 34626+ /* MXIC MX35UF2G14AC 2Gbit 1.8V */ 34627+ { 34628+ .name = "MX35UF2G14AC", 34629+ .id = {0xc2, 0xa0}, 34630+ .id_len = 2, 34631+ .chipsize = _256M, 34632+ .erasesize = _128K, 34633+ .pagesize = _2K, 34634+ .oobsize = 64, 34635+ .badblock_pos = BBP_FIRST_PAGE, 34636+ .read = { 34637+ &READ_STD(1, INFINITE, 24), 34638+ &READ_FAST(1, INFINITE, 104), 34639+ &READ_QUAD(1, INFINITE, 104), 34640+ 0 34641+ }, 34642+ .write = { 34643+ &WRITE_STD(0, 256, 24), 34644+ &WRITE_QUAD(0, 256, 104), 34645+ 0 34646+ }, 34647+ .erase = { 34648+ &ERASE_SECTOR_128K(0, _128K, 104), 34649+ 0 34650+ }, 34651+ .driver = &spi_driver_general, 34652+ }, 34653+ 34654+ /* Paragon PN26G01A 1Gbit */ 34655+ { 34656+ .name = "PN26G01A", 34657+ .id = {0xa1, 0xe1}, 34658+ .id_len = 2, 34659+ .chipsize = _128M, 34660+ .erasesize = _128K, 34661+ .pagesize = _2K, 34662+ .oobsize = 128, 34663+ .badblock_pos = BBP_FIRST_PAGE, 34664+ .read = { 34665+ &READ_STD(1, INFINITE, 24), 34666+ &READ_FAST(1, INFINITE, 108), 34667+ &READ_DUAL(1, INFINITE, 108), 34668+ &READ_DUAL_ADDR(1, INFINITE, 108), 34669+ &READ_QUAD(1, INFINITE, 108), 34670+ &READ_QUAD_ADDR(1, INFINITE, 108), 34671+ 0 34672+ }, 34673+ .write = { 34674+ &WRITE_STD(0, 256, 24), 34675+ &WRITE_QUAD(0, 256, 108), 34676+ 0 34677+ }, 34678+ .erase = { 34679+ &ERASE_SECTOR_128K(0, _128K, 24), 34680+ 0 34681+ }, 34682+ .driver = &spi_driver_general, 34683+ }, 34684+ 34685+ /* Paragon PN26G02A 2Gbit */ 34686+ { 34687+ .name = "PN26G02A", 34688+ .id = {0xa1, 0xe2}, 34689+ .id_len = 2, 34690+ .chipsize = _256M, 34691+ .erasesize = _128K, 34692+ .pagesize = _2K, 34693+ .oobsize = 128, 34694+ .badblock_pos = BBP_FIRST_PAGE, 34695+ .read = { 34696+ &READ_STD(1, INFINITE, 24), 34697+ &READ_FAST(1, INFINITE, 108), 34698+ &READ_DUAL(1, INFINITE, 108), 34699+ &READ_DUAL_ADDR(1, INFINITE, 108), 34700+ &READ_QUAD(1, INFINITE, 108), 34701+ &READ_QUAD_ADDR(1, INFINITE, 108), 34702+ 0 34703+ }, 34704+ .write = { 34705+ &WRITE_STD(0, 256, 24), 34706+ &WRITE_QUAD(0, 256, 108), 34707+ 0 34708+ }, 34709+ .erase = { 34710+ &ERASE_SECTOR_128K(0, _128K, 24), 34711+ 0 34712+ }, 34713+ .driver = &spi_driver_general, 34714+ }, 34715+ 34716+ /* All-flash AFS1GQ4UAC 1Gbit */ 34717+ { 34718+ .name = "AFS1GQ4UAC", 34719+ .id = {0xc1, 0x51}, 34720+ .id_len = 2, 34721+ .chipsize = _128M, 34722+ .erasesize = _128K, 34723+ .pagesize = _2K, 34724+ .oobsize = 128, 34725+ .badblock_pos = BBP_FIRST_PAGE, 34726+ .read = { 34727+ &READ_STD(1, INFINITE, 24), 34728+ &READ_FAST(1, INFINITE, 80), 34729+ &READ_DUAL(1, INFINITE, 80), 34730+ &READ_DUAL_ADDR(1, INFINITE, 80), 34731+ &READ_QUAD(1, INFINITE, 80), 34732+ &READ_QUAD_ADDR(1, INFINITE, 80), 34733+ 0 34734+ }, 34735+ .write = { 34736+ &WRITE_STD(0, 256, 24), 34737+ &WRITE_QUAD(0, 256, 80), 34738+ 0 34739+ }, 34740+ .erase = { 34741+ &ERASE_SECTOR_128K(0, _128K, 24), 34742+ 0 34743+ }, 34744+ .driver = &spi_driver_general, 34745+ }, 34746+ 34747+ /* All-flash AFS2GQ4UAD 2Gbit */ 34748+ { 34749+ .name = "AFS2GQ4UAD", 34750+ .id = {0xc1, 0x52}, 34751+ .id_len = 2, 34752+ .chipsize = _256M, 34753+ .erasesize = _128K, 34754+ .pagesize = _2K, 34755+ .oobsize = 128, 34756+ .badblock_pos = BBP_FIRST_PAGE, 34757+ .read = { 34758+ &READ_STD(1, INFINITE, 24), 34759+ &READ_FAST(1, INFINITE, 80), 34760+ &READ_DUAL(1, INFINITE, 80), 34761+ &READ_DUAL_ADDR(1, INFINITE, 80), 34762+ &READ_QUAD(1, INFINITE, 80), 34763+ &READ_QUAD_ADDR(1, INFINITE, 80), 34764+ 0 34765+ }, 34766+ .write = { 34767+ &WRITE_STD(0, 256, 24), 34768+ &WRITE_QUAD(0, 256, 80), 34769+ 0 34770+ }, 34771+ .erase = { 34772+ &ERASE_SECTOR_128K(0, _128K, 24), 34773+ 0 34774+ }, 34775+ .driver = &spi_driver_general, 34776+ }, 34777+ 34778+ /* TOSHIBA TC58CVG0S3H 1Gbit */ 34779+ { 34780+ .name = "TC58CVG0S3H", 34781+ .id = {0x98, 0xc2}, 34782+ .id_len = 2, 34783+ .chipsize = _128M, 34784+ .erasesize = _128K, 34785+ .pagesize = _2K, 34786+ .oobsize = 128, 34787+ .badblock_pos = BBP_FIRST_PAGE, 34788+ .read = { 34789+ &READ_STD(1, INFINITE, 24), 34790+ &READ_FAST(1, INFINITE, 104), 34791+ &READ_DUAL(1, INFINITE, 104), 34792+ &READ_QUAD(1, INFINITE, 104), 34793+ 0 34794+ }, 34795+ .write = { 34796+ &WRITE_STD(0, 256, 104), 34797+ 0 34798+ }, 34799+ .erase = { 34800+ &ERASE_SECTOR_128K(0, _128K, 104), 34801+ 0 34802+ }, 34803+ .driver = &spi_driver_no_qe, 34804+ }, 34805+ 34806+ { 34807+ .name = "TC58CVG0S3HRAIJ", 34808+ .id = {0x98, 0xe2, 0x40}, 34809+ .id_len = 3, 34810+ .chipsize = _128M, 34811+ .erasesize = _128K, 34812+ .pagesize = _2K, 34813+ .oobsize = 128, 34814+ .badblock_pos = BBP_FIRST_PAGE, 34815+ .read = { 34816+ &READ_STD(1, INFINITE, 24), 34817+ &READ_FAST(1, INFINITE, 133), 34818+ &READ_DUAL(1, INFINITE, 133), 34819+ &READ_QUAD(1, INFINITE, 133), 34820+ 0 34821+ }, 34822+ .write = { 34823+ &WRITE_STD(0, 256, 133), 34824+ &WRITE_QUAD(0, 256, 133), 34825+ 0 34826+ }, 34827+ .erase = { 34828+ &ERASE_SECTOR_128K(0, _128K, 133), 34829+ 0 34830+ }, 34831+ .driver = &spi_driver_no_qe, 34832+ }, 34833+ /* TOSHIBA TC58CYG0S3H 1.8V 1Gbit */ 34834+ { 34835+ .name = "TC58CYG0S3H", 34836+ .id = {0x98, 0xb2}, 34837+ .id_len = 2, 34838+ .chipsize = _128M, 34839+ .erasesize = _128K, 34840+ .pagesize = _2K, 34841+ .oobsize = 128, 34842+ .badblock_pos = BBP_FIRST_PAGE, 34843+ .read = { 34844+ &READ_STD(1, INFINITE, 24), 34845+ &READ_FAST(1, INFINITE, 104), 34846+ &READ_DUAL(1, INFINITE, 104), 34847+ &READ_QUAD(1, INFINITE, 104), 34848+ 0 34849+ }, 34850+ .write = { 34851+ &WRITE_STD(0, 256, 104), 34852+ 0 34853+ }, 34854+ .erase = { 34855+ &ERASE_SECTOR_128K(0, _128K, 104), 34856+ 0 34857+ }, 34858+ .driver = &spi_driver_no_qe, 34859+ }, 34860+ 34861+ /* TOSHIBA TC58CYG0S3HRAIJ 1.8V 1Gbit */ 34862+ { 34863+ .name = "TC58CYG0S3HRAIJ", 34864+ .id = {0x98, 0xD2, 0x40}, 34865+ .id_len = 3, 34866+ .chipsize = _128M, 34867+ .erasesize = _128K, 34868+ .pagesize = _2K, 34869+ .oobsize = 128, 34870+ .badblock_pos = BBP_FIRST_PAGE, 34871+ .read = { 34872+ &READ_STD(1, INFINITE, 24), 34873+ &READ_FAST(1, INFINITE, 133), 34874+ &READ_DUAL(1, INFINITE, 133), 34875+ &READ_QUAD(1, INFINITE, 133), 34876+ 0 34877+ }, 34878+ .write = { 34879+ &WRITE_STD(0, 256, 133), 34880+ &WRITE_QUAD(0, 256, 133), 34881+ 0 34882+ }, 34883+ .erase = { 34884+ &ERASE_SECTOR_128K(0, _128K, 133), 34885+ 0 34886+ }, 34887+ .driver = &spi_driver_no_qe, 34888+ }, 34889+ 34890+ /* TOSHIBA TC58CVG1S3H 2Gbit */ 34891+ { 34892+ .name = "TC58CVG1S3H", 34893+ .id = {0x98, 0xcb}, 34894+ .id_len = 2, 34895+ .chipsize = _256M, 34896+ .erasesize = _128K, 34897+ .pagesize = _2K, 34898+ .oobsize = 128, 34899+ .badblock_pos = BBP_FIRST_PAGE, 34900+ .read = { 34901+ &READ_STD(1, INFINITE, 24), 34902+ &READ_FAST(1, INFINITE, 104), 34903+ &READ_DUAL(1, INFINITE, 104), 34904+ &READ_QUAD(1, INFINITE, 104), 34905+ 0 34906+ }, 34907+ .write = { 34908+ &WRITE_STD(0, 256, 104), 34909+ 0 34910+ }, 34911+ .erase = { 34912+ &ERASE_SECTOR_128K(0, _128K, 104), 34913+ 0 34914+ }, 34915+ .driver = &spi_driver_no_qe, 34916+ }, 34917+ 34918+ /* TOSHIBA TC58CVG1S3HRAIJ 2Gbit */ 34919+ { 34920+ .name = "TC58CVG1S3HRAIJ", 34921+ .id = {0x98, 0xeb, 0x40}, 34922+ .id_len = 3, 34923+ .chipsize = _256M, 34924+ .erasesize = _128K, 34925+ .pagesize = _2K, 34926+ .oobsize = 128, 34927+ .badblock_pos = BBP_FIRST_PAGE, 34928+ .read = { 34929+ &READ_STD(1, INFINITE, 24), 34930+ &READ_FAST(1, INFINITE, 133), 34931+ &READ_DUAL(1, INFINITE, 133), 34932+ &READ_QUAD(1, INFINITE, 133), 34933+ 0 34934+ }, 34935+ .write = { 34936+ &WRITE_STD(0, 256, 133), 34937+ &WRITE_QUAD(0, 256, 133), 34938+ 0 34939+ }, 34940+ .erase = { 34941+ &ERASE_SECTOR_128K(0, _128K, 133), 34942+ 0 34943+ }, 34944+ .driver = &spi_driver_no_qe, 34945+ }, 34946+ 34947+ /* TOSHIBA TC58CYG1S3H 1.8V 2Gbit */ 34948+ { 34949+ .name = "TC58CYG1S3H", 34950+ .id = {0x98, 0xbb}, 34951+ .id_len = 2, 34952+ .chipsize = _256M, 34953+ .erasesize = _128K, 34954+ .pagesize = _2K, 34955+ .oobsize = 128, 34956+ .badblock_pos = BBP_FIRST_PAGE, 34957+ .read = { 34958+ &READ_STD(1, INFINITE, 24), 34959+ &READ_FAST(1, INFINITE, 104), 34960+ &READ_DUAL(1, INFINITE, 104), 34961+ &READ_QUAD(1, INFINITE, 104), 34962+ 0 34963+ }, 34964+ .write = { 34965+ &WRITE_STD(0, 256, 75), 34966+ 0 34967+ }, 34968+ .erase = { 34969+ &ERASE_SECTOR_128K(0, _128K, 75), 34970+ 0 34971+ }, 34972+ .driver = &spi_driver_no_qe, 34973+ }, 34974+ 34975+ /* TOSHIBA TC58CYG1S3HRAIJ 1.8V 2Gbit */ 34976+ { 34977+ .name = "TC58CYG1S3HRAIJ", 34978+ .id = {0x98, 0xdb, 0x40}, 34979+ .id_len = 3, 34980+ .chipsize = _256M, 34981+ .erasesize = _128K, 34982+ .pagesize = _2K, 34983+ .oobsize = 128, 34984+ .badblock_pos = BBP_FIRST_PAGE, 34985+ .read = { 34986+ &READ_STD(1, INFINITE, 24), 34987+ &READ_FAST(1, INFINITE, 133), 34988+ &READ_DUAL(1, INFINITE, 133), 34989+ &READ_QUAD(1, INFINITE, 133), 34990+ 0 34991+ }, 34992+ .write = { 34993+ &WRITE_STD(0, 256, 133), 34994+ &WRITE_QUAD(0, 256, 133), 34995+ 0 34996+ }, 34997+ .erase = { 34998+ &ERASE_SECTOR_128K(0, _128K, 133), 34999+ 0 35000+ }, 35001+ .driver = &spi_driver_no_qe, 35002+ }, 35003+ 35004+ /* TOSHIBA TC58CVG2S0H 4Gbit */ 35005+ { 35006+ .name = "TC58CVG2S0H", 35007+ .id = {0x98, 0xcd}, 35008+ .id_len = 2, 35009+ .chipsize = _512M, 35010+ .erasesize = _256K, 35011+ .pagesize = _4K, 35012+ .oobsize = 256, 35013+ .badblock_pos = BBP_FIRST_PAGE, 35014+ .read = { 35015+ &READ_STD(1, INFINITE, 24), 35016+ &READ_FAST(1, INFINITE, 104), 35017+ &READ_DUAL(1, INFINITE, 104), 35018+ &READ_QUAD(1, INFINITE, 104), 35019+ 0 35020+ }, 35021+ .write = { 35022+ &WRITE_STD(0, 256, 104), 35023+ 0 35024+ }, 35025+ .erase = { 35026+ &ERASE_SECTOR_256K(0, _256K, 104), 35027+ 0 35028+ }, 35029+ .driver = &spi_driver_no_qe, 35030+ }, 35031+ 35032+ /* TOSHIBA TC58CVG2S0HRAIJ 4Gbit */ 35033+ { 35034+ .name = "TC58CVG2S0HRAIJ", 35035+ .id = {0x98, 0xed, 0x51}, 35036+ .id_len = 3, 35037+ .chipsize = _512M, 35038+ .erasesize = _256K, 35039+ .pagesize = _4K, 35040+ .oobsize = 256, 35041+ .badblock_pos = BBP_FIRST_PAGE, 35042+ .read = { 35043+ &READ_STD(1, INFINITE, 24), 35044+ &READ_FAST(1, INFINITE, 133), 35045+ &READ_DUAL(1, INFINITE, 133), 35046+ &READ_QUAD(1, INFINITE, 133), 35047+ 0 35048+ }, 35049+ .write = { 35050+ &WRITE_STD(0, 256, 133), 35051+ &WRITE_QUAD(0, 256, 133), 35052+ 0 35053+ }, 35054+ .erase = { 35055+ &ERASE_SECTOR_256K(0, _256K, 133), 35056+ 0 35057+ }, 35058+ .driver = &spi_driver_no_qe, 35059+ }, 35060+ 35061+ /* TOSHIBA TC58CYG2S0H 1.8V 4Gbit */ 35062+ { 35063+ .name = "TC58CYG2S0H", 35064+ .id = {0x98, 0xbd}, 35065+ .id_len = 2, 35066+ .chipsize = _512M, 35067+ .erasesize = _256K, 35068+ .pagesize = _4K, 35069+ .oobsize = 256, 35070+ .badblock_pos = BBP_FIRST_PAGE, 35071+ .read = { 35072+ &READ_STD(1, INFINITE, 24), 35073+ &READ_FAST(1, INFINITE, 104), 35074+ &READ_DUAL(1, INFINITE, 104), 35075+ &READ_QUAD(1, INFINITE, 104), 35076+ 0 35077+ }, 35078+ .write = { 35079+ &WRITE_STD(0, 256, 75), 35080+ 0 35081+ }, 35082+ .erase = { 35083+ &ERASE_SECTOR_256K(0, _256K, 75), 35084+ 0 35085+ }, 35086+ .driver = &spi_driver_no_qe, 35087+ }, 35088+ 35089+ /* KIOXIA TH58CYG2S0HRAIJ 1.8V 4Gbit */ 35090+ { 35091+ .name = "TH58CYG2S0HRAIJ", 35092+ .id = {0x98, 0xdd, 0x51}, 35093+ .id_len = 3, 35094+ .chipsize = _512M, 35095+ .erasesize = _256K, 35096+ .pagesize = _4K, 35097+ .oobsize = 256, 35098+ .badblock_pos = BBP_FIRST_PAGE, 35099+ .read = { 35100+ &READ_STD(1, INFINITE, 24), /* 24MHz */ 35101+ &READ_FAST(1, INFINITE, 133), /* 133MHz */ 35102+ &READ_DUAL(1, INFINITE, 133), /* 133MHz */ 35103+ &READ_QUAD(1, INFINITE, 133), /* 133MHz */ 35104+ 0 35105+ }, 35106+ .write = { 35107+ &WRITE_STD(0, 256, 133), /* 133MHz */ 35108+ &WRITE_QUAD(0, 256, 133), /* 133MHz */ 35109+ 0 35110+ }, 35111+ .erase = { 35112+ &ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */ 35113+ 0 35114+ }, 35115+ .driver = &spi_driver_no_qe, 35116+ }, 35117+ 35118+ /* KIOXIA TH58CYG3S0H 1.8V 8Gbit */ 35119+ { 35120+ .name = "TH58CYG3S0H", 35121+ .id = {0x98, 0xd4, 0x51}, 35122+ .id_len = 3, 35123+ .chipsize = _1G, 35124+ .erasesize = _256K, 35125+ .pagesize = _4K, 35126+ .oobsize = 256, 35127+ .badblock_pos = BBP_FIRST_PAGE, 35128+ .read = { 35129+ &READ_STD(1, INFINITE, 24), /* 24MHz */ 35130+ &READ_FAST(1, INFINITE, 133), /* 133MHz */ 35131+ &READ_DUAL(1, INFINITE, 133), /* 133MHz */ 35132+ &READ_QUAD(1, INFINITE, 133), /* 133MHz */ 35133+ 0 35134+ }, 35135+ .write = { 35136+ &WRITE_STD(0, 256, 133), /* 133MHz */ 35137+ &WRITE_QUAD(0, 256, 133), /* 133MHz */ 35138+ 0 35139+ }, 35140+ .erase = { 35141+ &ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */ 35142+ 0 35143+ }, 35144+ .driver = &spi_driver_no_qe, 35145+ }, 35146+ 35147+ /* HeYangTek HYF1GQ4UAACAE 1Gbit */ 35148+ { 35149+ .name = "HYF1GQ4UAACAE", 35150+ .id = {0xc9, 0x51}, 35151+ .id_len = 2, 35152+ .chipsize = _128M, 35153+ .erasesize = _128K, 35154+ .pagesize = _2K, 35155+ .oobsize = 128, 35156+ .badblock_pos = BBP_FIRST_PAGE, 35157+ .read = { 35158+ &READ_STD(1, INFINITE, 24), 35159+ &READ_FAST(1, INFINITE, 80), 35160+ &READ_DUAL(1, INFINITE, 80), 35161+ &READ_DUAL_ADDR(1, INFINITE, 80), 35162+ &READ_QUAD(1, INFINITE, 80), 35163+ &READ_QUAD_ADDR(1, INFINITE, 80), 35164+ 0 35165+ }, 35166+ .write = { 35167+ &WRITE_STD(0, 256, 80), 35168+ &WRITE_QUAD(0, 256, 80), 35169+ 0 35170+ }, 35171+ .erase = { 35172+ &ERASE_SECTOR_128K(0, _128K, 80), 35173+ 0 35174+ }, 35175+ .driver = &spi_driver_general, 35176+ }, 35177+ 35178+ /* HeYangTek HYF2GQ4UAACAE 2Gbit */ 35179+ { 35180+ .name = "HYF2GQ4UAACAE", 35181+ .id = {0xc9, 0x52}, 35182+ .id_len = 2, 35183+ .chipsize = _256M, 35184+ .erasesize = _128K, 35185+ .pagesize = _2K, 35186+ .oobsize = 128, 35187+ .badblock_pos = BBP_FIRST_PAGE, 35188+ .read = { 35189+ &READ_STD(1, INFINITE, 24), 35190+ &READ_FAST(1, INFINITE, 80), 35191+ &READ_DUAL(1, INFINITE, 80), 35192+ &READ_DUAL_ADDR(1, INFINITE, 80), 35193+ &READ_QUAD(1, INFINITE, 80), 35194+ &READ_QUAD_ADDR(1, INFINITE, 80), 35195+ 0 35196+ }, 35197+ .write = { 35198+ &WRITE_STD(0, 256, 80), 35199+ &WRITE_QUAD(0, 256, 80), 35200+ 0 35201+ }, 35202+ .erase = { 35203+ &ERASE_SECTOR_128K(0, _128K, 80), 35204+ 0 35205+ }, 35206+ .driver = &spi_driver_general, 35207+ }, 35208+ 35209+ /* HeYangTek HYF4GQ4UAACBE 4Gbit */ 35210+ { 35211+ .name = "HYF4GQ4UAACBE", 35212+ .id = {0xc9, 0xd4}, 35213+ .id_len = 2, 35214+ .chipsize = _512M, 35215+ .erasesize = _256K, 35216+ .pagesize = _4K, 35217+ .oobsize = 256, 35218+ .badblock_pos = BBP_FIRST_PAGE, 35219+ .read = { 35220+ &READ_STD(1, INFINITE, 24), 35221+ &READ_FAST(1, INFINITE, 80), 35222+ &READ_DUAL(1, INFINITE, 80), 35223+ &READ_DUAL_ADDR(1, INFINITE, 80), 35224+ &READ_QUAD(1, INFINITE, 80), 35225+ &READ_QUAD_ADDR(1, INFINITE, 80), 35226+ 0 35227+ }, 35228+ .write = { 35229+ &WRITE_STD(0, 256, 80), 35230+ &WRITE_QUAD(0, 256, 80), 35231+ 0 35232+ }, 35233+ .erase = { 35234+ &ERASE_SECTOR_256K(0, _256K, 80), 35235+ 0 35236+ }, 35237+ .driver = &spi_driver_general, 35238+ }, 35239+ 35240+ /* Dosilicon 3.3V DS35Q1GA-IB 1Gbit */ 35241+ { 35242+ .name = "DS35Q1GA-IB", 35243+ .id = {0xe5, 0x71}, 35244+ .id_len = 2, 35245+ .chipsize = _128M, 35246+ .erasesize = _128K, 35247+ .pagesize = _2K, 35248+ .oobsize = 64, 35249+ .badblock_pos = BBP_FIRST_PAGE, 35250+ .read = { 35251+ &READ_STD(1, INFINITE, 24), 35252+ &READ_FAST(1, INFINITE, 104), 35253+ &READ_DUAL(1, INFINITE, 104), 35254+ &READ_QUAD(1, INFINITE, 104), 35255+ 0 35256+ }, 35257+ .write = { 35258+ &WRITE_STD(0, 256, 80), 35259+ &WRITE_QUAD(0, 256, 104), 35260+ 0 35261+ }, 35262+ .erase = { 35263+ &ERASE_SECTOR_128K(0, _128K, 104), 35264+ 0 35265+ }, 35266+ .driver = &spi_driver_general, 35267+ }, 35268+ 35269+ /* XTX 3.3V XT26G01B 1Gbit */ 35270+ { 35271+ .name = "XT26G01B", 35272+ .id = {0x0B, 0xF1}, 35273+ .id_len = 2, 35274+ .chipsize = _128M, 35275+ .erasesize = _128K, 35276+ .pagesize = _2K, 35277+ .oobsize = 64, 35278+ .badblock_pos = BBP_FIRST_PAGE, 35279+ .read = { 35280+ &READ_STD(1, INFINITE, 24), 35281+ &READ_FAST(1, INFINITE, 80), 35282+ &READ_DUAL(1, INFINITE, 80), 35283+ &READ_DUAL_ADDR(1, INFINITE, 80), 35284+ &READ_QUAD(1, INFINITE, 80), 35285+ &READ_QUAD_ADDR(1, INFINITE, 80), 35286+ 0 35287+ }, 35288+ .write = { 35289+ &WRITE_STD(0, 256, 80), 35290+ &WRITE_QUAD(0, 256, 80), 35291+ 0 35292+ }, 35293+ .erase = { 35294+ &ERASE_SECTOR_128K(0, _128K, 80), 35295+ 0 35296+ }, 35297+ .driver = &spi_driver_general, 35298+ }, 35299+ 35300+ /* Etron 1.8V EM78F044VCA-H 8Gbit */ 35301+ { 35302+ .name = "EM78F044VCA-H", 35303+ .id = {0xD5, 0x8D}, 35304+ .id_len = 2, 35305+ .chipsize = _512M * 2, 35306+ .erasesize = _256K, 35307+ .pagesize = _4K, 35308+ .oobsize = 256, 35309+ .badblock_pos = BBP_FIRST_PAGE, 35310+ .read = { 35311+ &READ_STD(1, INFINITE, 24), 35312+ &READ_FAST(1, INFINITE, 100), 35313+ &READ_DUAL(1, INFINITE, 100), 35314+ &READ_DUAL_ADDR(1, INFINITE, 100), 35315+ &READ_QUAD(1, INFINITE, 100), 35316+ &READ_QUAD_ADDR(1, INFINITE, 100), 35317+ 0 35318+ }, 35319+ .write = { 35320+ &WRITE_STD(0, 256, 100), 35321+ &WRITE_QUAD(0, 256, 100), 35322+ 0 35323+ }, 35324+ .erase = { 35325+ &ERASE_SECTOR_256K(0, _256K, 100), 35326+ 0 35327+ }, 35328+ .driver = &spi_driver_general, 35329+ }, 35330+ 35331+ /* Etron 1.8V EM78E044VCA-H 4Gbit */ 35332+ { 35333+ .name = "EM78E044VCA-H", 35334+ .id = {0xD5, 0x8C}, 35335+ .id_len = 2, 35336+ .chipsize = _512M, 35337+ .erasesize = _256K, 35338+ .pagesize = _4K, 35339+ .oobsize = 256, 35340+ .badblock_pos = BBP_FIRST_PAGE, 35341+ .read = { 35342+ &READ_STD(1, INFINITE, 24), 35343+ &READ_FAST(1, INFINITE, 100), 35344+ &READ_DUAL(1, INFINITE, 100), 35345+ &READ_DUAL_ADDR(1, INFINITE, 100), 35346+ &READ_QUAD(1, INFINITE, 100), 35347+ &READ_QUAD_ADDR(1, INFINITE, 100), 35348+ 0 35349+ }, 35350+ .write = { 35351+ &WRITE_STD(0, 256, 100), 35352+ &WRITE_QUAD(0, 256, 100), 35353+ 0 35354+ }, 35355+ .erase = { 35356+ &ERASE_SECTOR_256K(0, _256K, 100), 35357+ 0 35358+ }, 35359+ .driver = &spi_driver_general, 35360+ }, 35361+ 35362+ /* Etron 1.8V EM78D044VCF-H 2Gbit */ 35363+ { 35364+ .name = "EM78D044VCF-H", 35365+ .id = {0xd5, 0x81}, 35366+ .id_len = 2, 35367+ .chipsize = _256M, 35368+ .erasesize = _128K, 35369+ .pagesize = _2K, 35370+ .oobsize = 64, 35371+ .badblock_pos = BBP_FIRST_PAGE, 35372+ .read = { 35373+ &READ_STD(1, INFINITE, 24), 35374+ &READ_FAST(1, INFINITE, 104), 35375+ &READ_DUAL(1, INFINITE, 104), 35376+ &READ_DUAL_ADDR(1, INFINITE, 104), 35377+ &READ_QUAD(1, INFINITE, 104), 35378+ &READ_QUAD_ADDR(1, INFINITE, 104), 35379+ 0 35380+ }, 35381+ .write = { 35382+ &WRITE_STD(0, 256, 80), 35383+ &WRITE_QUAD(0, 256, 104), 35384+ 0 35385+ }, 35386+ .erase = { 35387+ &ERASE_SECTOR_128K(0, _128K, 104), 35388+ 0 35389+ }, 35390+ .driver = &spi_driver_general, 35391+ }, 35392+ 35393+ /* Etron 3.3V EM73C044VCC-H 1Gbit */ 35394+ { 35395+ .name = "EM73C044VCC-H", 35396+ .id = {0xd5, 0x22}, 35397+ .id_len = 2, 35398+ .chipsize = _128M, 35399+ .erasesize = _128K, 35400+ .pagesize = _2K, 35401+ .oobsize = 64, 35402+ .badblock_pos = BBP_FIRST_PAGE, 35403+ .read = { 35404+ &READ_STD(1, INFINITE, 24), 35405+ &READ_FAST(1, INFINITE, 120), 35406+ &READ_DUAL(1, INFINITE, 120), 35407+ &READ_DUAL_ADDR(1, INFINITE, 120), 35408+ &READ_QUAD(1, INFINITE, 120), 35409+ &READ_QUAD_ADDR(1, INFINITE, 120), 35410+ 0 35411+ }, 35412+ .write = { 35413+ &WRITE_STD(0, 256, 104), 35414+ &WRITE_QUAD(0, 256, 120), 35415+ 0 35416+ }, 35417+ .erase = { 35418+ &ERASE_SECTOR_128K(0, _128K, 104), 35419+ 0 35420+ }, 35421+ .driver = &spi_driver_general, 35422+ }, 35423+ 35424+ /* Micron MT29F4G01ABBFDWB 4GBit 1.8V */ 35425+ { 35426+ .name = "MT29F4G01ABBFDWB", 35427+ .id = {0x2C, 0x35}, 35428+ .id_len = 2, 35429+ .chipsize = _512M, 35430+ .erasesize = _256K, 35431+ .pagesize = _4K, 35432+ .oobsize = 256, 35433+ .badblock_pos = BBP_FIRST_PAGE, 35434+ .read = { 35435+ &READ_STD(1, INFINITE, 24), 35436+ &READ_FAST(1, INFINITE, 80), 35437+ &READ_DUAL(1, INFINITE, 80), 35438+ &READ_QUAD(1, INFINITE, 80), 35439+ 0 35440+ }, 35441+ .write = { 35442+ &WRITE_STD(0, 256, 80), 35443+ &WRITE_QUAD(0, 256, 80), 35444+ 0 35445+ }, 35446+ .erase = { 35447+ &ERASE_SECTOR_256K(0, _256K, 80), 35448+ 0 35449+ }, 35450+ .driver = &spi_driver_no_qe, 35451+ }, 35452+ 35453+ /* Dosilicon 3.3V DS35Q2GA-IB 1Gb */ 35454+ { 35455+ .name = "DS35Q2GA-IB", 35456+ .id = {0xe5, 0x72}, 35457+ .id_len = 2, 35458+ .chipsize = _256M, 35459+ .erasesize = _128K, 35460+ .pagesize = _2K, 35461+ .oobsize = 64, 35462+ .badblock_pos = BBP_FIRST_PAGE, 35463+ .read = { 35464+ &READ_STD(1, INFINITE, 24), 35465+ &READ_FAST(1, INFINITE, 104), 35466+ &READ_DUAL(1, INFINITE, 104), 35467+ &READ_QUAD(1, INFINITE, 104), 35468+ 0 35469+ }, 35470+ .write = { 35471+ &WRITE_STD(0, 256, 80), 35472+ &WRITE_QUAD(0, 256, 104), 35473+ 0 35474+ }, 35475+ .erase = { 35476+ &ERASE_SECTOR_128K(0, _128K, 104), 35477+ 0 35478+ }, 35479+ .driver = &spi_driver_general, 35480+ }, 35481+ 35482+ /* FM 3.3v FM25S01-DND-A-G 1Gbit */ 35483+ { 35484+ .name = "FM25S01-DND-A-G", 35485+ .id = {0xa1, 0xa1}, 35486+ .id_len = 2, 35487+ .chipsize = _128M, 35488+ .erasesize = _128K, 35489+ .pagesize = _2K, 35490+ .oobsize = 128, 35491+ .badblock_pos = BBP_FIRST_PAGE, 35492+ .read = { 35493+ &READ_STD(1, INFINITE, 24), /* 24MHz */ 35494+ &READ_FAST(1, INFINITE, 104), /* 104MHz */ 35495+ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ 35496+ &READ_DUAL_ADDR(1, INFINITE, 40), /* 40MHz */ 35497+ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ 35498+ &READ_QUAD_ADDR(2, INFINITE, 40), /* 40MHz */ 35499+ 0 35500+ }, 35501+ .write = { 35502+ &WRITE_STD(0, 256, 104), /* 104MHz */ 35503+ &WRITE_QUAD(0, 256, 104), /* 104MHz */ 35504+ 0 35505+ }, 35506+ .erase = { 35507+ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ 35508+ 0 35509+ }, 35510+ .driver = &spi_driver_no_qe, 35511+ }, 35512+ 35513+ /* FM 3.3v FM25S01A 1Gbit */ 35514+ { 35515+ .name = "FM25S01A", 35516+ .id = {0xa1, 0xe4}, 35517+ .id_len = 2, 35518+ .chipsize = _128M, 35519+ .erasesize = _128K, 35520+ .pagesize = _2K, 35521+ .oobsize = 64, 35522+ .badblock_pos = BBP_FIRST_PAGE, 35523+ .read = { 35524+ &READ_STD(1, INFINITE, 24), /* 104MHz */ 35525+ &READ_FAST(1, INFINITE, 104), /* 104MHz */ 35526+ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ 35527+ &READ_DUAL_ADDR(1, INFINITE, 40), /* 40MHz */ 35528+ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ 35529+ &READ_QUAD_ADDR(2, INFINITE, 40), /* 40MHz */ 35530+ 0 35531+ }, 35532+ .write = { 35533+ &WRITE_STD(0, 256, 104), /* 104MHz */ 35534+ &WRITE_QUAD(0, 256, 104), /* 104MHz */ 35535+ 0 35536+ }, 35537+ .erase = { 35538+ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ 35539+ 0 35540+ }, 35541+ .driver = &spi_driver_no_qe, 35542+ }, 35543+ 35544+ { .id_len = 0, }, 35545+}; 35546+ 35547+ 35548+static void hifmc100_spi_nand_search_rw(struct spi_nand_info *spiinfo, 35549+ struct spi_op *spiop_rw, u_int iftype, u_int max_dummy, int rw_type) 35550+{ 35551+ int ix = 0; 35552+ struct spi_op **spiop, **fitspiop; 35553+ 35554+ for (fitspiop = spiop = (rw_type ? spiinfo->write : spiinfo->read); 35555+ (*spiop) && ix < MAX_SPI_OP; spiop++, ix++) { 35556+ if (((*spiop)->iftype & iftype) 35557+ && ((*spiop)->dummy <= max_dummy) 35558+ && (*fitspiop)->iftype < (*spiop)->iftype) { 35559+ fitspiop = spiop; 35560+ } 35561+ } 35562+ memcpy(spiop_rw, (*fitspiop), sizeof(struct spi_op)); 35563+} 35564+ 35565+ 35566+static void hifmc100_spi_nand_get_erase(const struct spi_nand_info *spiinfo, 35567+ struct spi_op *spiop_erase) 35568+{ 35569+ int ix; 35570+ 35571+ spiop_erase->size = 0; 35572+ for (ix = 0; ix < MAX_SPI_OP; ix++) { 35573+ if (spiinfo->erase[ix] == NULL) { 35574+ break; 35575+ } 35576+ if (spiinfo->erasesize == spiinfo->erase[ix]->size) { 35577+ memcpy(&spiop_erase[ix], spiinfo->erase[ix], 35578+ sizeof(struct spi_op)); 35579+ break; 35580+ } 35581+ } 35582+} 35583+ 35584+ 35585+static void hifmc100_map_spi_op(struct hifmc_spi *spi) 35586+{ 35587+ unsigned char ix; 35588+ const int iftype_read[] = { 35589+ SPI_IF_READ_STD, IF_TYPE_STD, 35590+ SPI_IF_READ_FAST, IF_TYPE_STD, 35591+ SPI_IF_READ_DUAL, IF_TYPE_DUAL, 35592+ SPI_IF_READ_DUAL_ADDR, IF_TYPE_DIO, 35593+ SPI_IF_READ_QUAD, IF_TYPE_QUAD, 35594+ SPI_IF_READ_QUAD_ADDR, IF_TYPE_QIO, 35595+ 0, 0, 35596+ }; 35597+ const int iftype_write[] = { 35598+ SPI_IF_WRITE_STD, IF_TYPE_STD, 35599+ SPI_IF_WRITE_QUAD, IF_TYPE_QUAD, 35600+ 0, 0, 35601+ }; 35602+ const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; 35603+ 35604+ FMC_PR(BT_DBG, "\t||*-Start Get SPI operation iftype\n"); 35605+ 35606+ for (ix = 0; iftype_write[ix]; ix += 2) { 35607+ if (spi->write->iftype == iftype_write[ix]) { 35608+ spi->write->iftype = iftype_write[ix + 1]; 35609+ break; 35610+ } 35611+ } 35612+ FMC_PR(BT_DBG, "\t|||-Get best write iftype: %s \n", 35613+ if_str[spi->write->iftype]); 35614+ 35615+ for (ix = 0; iftype_read[ix]; ix += 2) { 35616+ if (spi->read->iftype == iftype_read[ix]) { 35617+ spi->read->iftype = iftype_read[ix + 1]; 35618+ break; 35619+ } 35620+ } 35621+ FMC_PR(BT_DBG, "\t|||-Get best read iftype: %s \n", 35622+ if_str[spi->read->iftype]); 35623+ 35624+ spi->erase->iftype = IF_TYPE_STD; 35625+ FMC_PR(BT_DBG, "\t|||-Get best erase iftype: %s \n", 35626+ if_str[spi->erase->iftype]); 35627+ 35628+ FMC_PR(BT_DBG, "\t||*-End Get SPI operation iftype \n"); 35629+} 35630+ 35631+ 35632+static void hifmc100_spi_ids_probe(struct mtd_info *mtd, 35633+ struct spi_nand_info *spi_dev) 35634+{ 35635+ u_char reg; 35636+ int ret; 35637+ struct nand_chip *chip = NULL; 35638+ struct hifmc_host *host = NULL; 35639+ struct hifmc_spi *spi = NULL; 35640+ 35641+ if(mtd == NULL || spi_dev == NULL) { 35642+ DB_MSG("Error: mtd or spi_dev is NULL!\n"); 35643+ return; 35644+ } 35645+ chip = mtd_to_nand(mtd); 35646+ if (chip == NULL || chip->priv == NULL) { 35647+ DB_MSG("Error: chip is NULL!\n"); 35648+ return; 35649+ } 35650+ host = chip->priv; 35651+ if (host->spi == NULL) { 35652+ DB_MSG("Error: host->spi is NULL!\n"); 35653+ return; 35654+ } 35655+ spi = host->spi; 35656+ FMC_PR(BT_DBG, "\t|*-Start match SPI operation & chip init\n"); 35657+ 35658+ spi->host = host; 35659+ spi->name = spi_dev->name; 35660+ spi->driver = spi_dev->driver; 35661+ if(!spi->driver) { 35662+ DB_MSG("Error: host->driver is NULL!\n"); 35663+ return; 35664+ } 35665+ 35666+ hifmc100_spi_nand_search_rw(spi_dev, spi->read, 35667+ HIFMC_SPI_NAND_SUPPORT_READ, 35668+ HIFMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_READ); 35669+ FMC_PR(BT_DBG, "\t||-Save spi->read op cmd:%#x\n", spi->read->cmd); 35670+ 35671+ hifmc100_spi_nand_search_rw(spi_dev, spi->write, 35672+ HIFMC_SPI_NAND_SUPPORT_WRITE, 35673+ HIFMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_WRITE); 35674+ FMC_PR(BT_DBG, "\t||-Save spi->write op cmd:%#x\n", spi->write->cmd); 35675+ 35676+ hifmc100_spi_nand_get_erase(spi_dev, spi->erase); 35677+ FMC_PR(BT_DBG, "\t||-Save spi->erase op cmd:%#x\n", spi->erase->cmd); 35678+ 35679+ hifmc100_map_spi_op(spi); 35680+ 35681+ if (spi->driver->qe_enable) { 35682+ spi->driver->qe_enable(spi); 35683+ } 35684+ 35685+ /* Disable write protection */ 35686+ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, ®); 35687+ if (ret) 35688+ return; 35689+ FMC_PR(BT_DBG, "\t||-Get protect status[%#x]: %#x\n", PROTECT_ADDR, 35690+ reg); 35691+ if (ANY_BP_ENABLE(reg)) { 35692+ reg &= ~ALL_BP_MASK; 35693+ ret = spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, ®); 35694+ if (ret) 35695+ return; 35696+ FMC_PR(BT_DBG, "\t||-Set [%#x]FT %#x\n", PROTECT_ADDR, reg); 35697+ 35698+ spi->driver->wait_ready(spi); 35699+ 35700+ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, ®); 35701+ if (ret) 35702+ return; 35703+ FMC_PR(BT_DBG, "\t||-Check BP disable result: %#x\n", reg); 35704+ if (ANY_BP_ENABLE(reg)) { 35705+ DB_MSG("Error: Write protection disable failed!\n"); 35706+ } 35707+ } 35708+ 35709+ /* Disable chip internal ECC */ 35710+ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); 35711+ if (ret) 35712+ return; 35713+ FMC_PR(BT_DBG, "\t||-Get feature status[%#x]: %#x\n", FEATURE_ADDR, 35714+ reg); 35715+ if (reg & FEATURE_ECC_ENABLE) { 35716+ reg &= ~FEATURE_ECC_ENABLE; 35717+ ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, ®); 35718+ if (ret) 35719+ return; 35720+ FMC_PR(BT_DBG, "\t||-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg); 35721+ 35722+ spi->driver->wait_ready(spi); 35723+ 35724+ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); 35725+ if (ret) 35726+ return; 35727+ FMC_PR(BT_DBG, "\t||-Check internal ECC disable result: %#x\n", 35728+ reg); 35729+ if (reg & FEATURE_ECC_ENABLE) { 35730+ DB_MSG("Error: Chip internal ECC disable failed!\n"); 35731+ } 35732+ } 35733+ 35734+ hifmc_cs_user[host->cmd_op.cs]++; 35735+ 35736+ FMC_PR(BT_DBG, "\t|*-End match SPI operation & chip init\n"); 35737+} 35738+ 35739+static struct nand_flash_dev spi_nand_dev; 35740+ 35741+static struct nand_flash_dev *spi_nand_get_flash_info(struct mtd_info *mtd, 35742+ unsigned char *id) 35743+{ 35744+ unsigned char ix; 35745+ int len = 0; 35746+ char buffer[100]; 35747+ struct nand_chip *chip = mtd_to_nand(mtd); 35748+ struct hifmc_host *host = chip->priv; 35749+ struct spi_nand_info *spi_dev = hifmc_spi_nand_flash_table; 35750+ struct nand_flash_dev *type = &spi_nand_dev; 35751+ 35752+ FMC_PR(BT_DBG, "\t*-Start find SPI Nand flash\n"); 35753+ 35754+ len = sprintf(buffer, "SPI Nand(cs %d) ID: %#x %#x", 35755+ host->cmd_op.cs, id[0], id[1]); 35756+ 35757+ for (; spi_dev->id_len; spi_dev++) { 35758+ if (!access_ok(VERIFY_READ, id, spi_dev->id_len)) { 35759+ DB_MSG("err:spi_nand_get_flash_info access_ok fail\n"); 35760+ return NULL; 35761+ } 35762+ if (memcmp(id, spi_dev->id, spi_dev->id_len)) { 35763+ continue; 35764+ } 35765+ 35766+ for (ix = 2; ix < spi_dev->id_len; ix++) { 35767+ if((spi_dev->id_len <= MAX_SPI_NAND_ID_LEN)) { 35768+ len += sprintf(buffer + len, " %#x", id[ix]); 35769+ } 35770+ } 35771+ pr_info("%s\n", buffer); 35772+ 35773+ FMC_PR(BT_DBG, "\t||-CS(%d) found SPI Nand: %s\n", 35774+ host->cmd_op.cs, spi_dev->name); 35775+ 35776+ type->name = spi_dev->name; 35777+ memcpy(type->id, spi_dev->id, spi_dev->id_len); 35778+ type->pagesize = spi_dev->pagesize; 35779+ type->chipsize = (unsigned int)(spi_dev->chipsize >> 20); 35780+ type->erasesize = spi_dev->erasesize; 35781+ type->id_len = spi_dev->id_len; 35782+ type->oobsize = spi_dev->oobsize; 35783+ FMC_PR(BT_DBG, "\t|-Save struct nand_flash_dev info\n"); 35784+ 35785+ mtd->oobsize = spi_dev->oobsize; 35786+ mtd->erasesize = spi_dev->erasesize; 35787+ mtd->writesize = spi_dev->pagesize; 35788+ chip->chipsize = spi_dev->chipsize; 35789+ 35790+ hifmc100_spi_ids_probe(mtd, spi_dev); 35791+ 35792+ FMC_PR(BT_DBG, "\t*-Found SPI nand: %s\n", spi_dev->name); 35793+ 35794+ return type; 35795+ } 35796+ 35797+ FMC_PR(BT_DBG, "\t*-Not found SPI nand flash, %s\n", buffer); 35798+ 35799+ return NULL; 35800+} 35801+ 35802+ 35803+void hifmc_spi_nand_ids_register(void) 35804+{ 35805+ pr_info("SPI Nand ID Table Version %s\n", SPI_NAND_ID_TAB_VER); 35806+ get_spi_nand_flash_type_hook = spi_nand_get_flash_info; 35807+} 35808+ 35809+#ifdef CONFIG_PM 35810+ 35811+void hifmc100_spi_nand_config(struct hifmc_host *host) 35812+{ 35813+ u_char reg; 35814+ int ret; 35815+ struct hifmc_spi *spi = NULL; 35816+ static const char *str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; 35817+ 35818+ if((host == NULL) || (host->spi == NULL)) { 35819+ DB_MSG("Error: host or host->spi is NULL!\n"); 35820+ return; 35821+ } 35822+ spi = host->spi; 35823+ /* judge whether support QUAD read/write or not, set it if yes */ 35824+ FMC_PR(PM_DBG, "\t|-SPI read iftype: %s write iftype: %s\n", 35825+ str[spi->read->iftype], str[spi->write->iftype]); 35826+ 35827+ if (spi->driver->qe_enable) { 35828+ spi->driver->qe_enable(spi); 35829+ } 35830+ 35831+ /* Disable write protection */ 35832+ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, ®); 35833+ if (ret) 35834+ return; 35835+ FMC_PR(PM_DBG, "\t|-Get protect status[%#x]: %#x\n", PROTECT_ADDR, 35836+ reg); 35837+ if (ANY_BP_ENABLE(reg)) { 35838+ reg &= ~ALL_BP_MASK; 35839+ ret = spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, ®); 35840+ if (ret) 35841+ return; 35842+ FMC_PR(PM_DBG, "\t|-Set [%#x]FT %#x\n", PROTECT_ADDR, reg); 35843+ 35844+ spi->driver->wait_ready(spi); 35845+ 35846+ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, ®); 35847+ if (ret) 35848+ return; 35849+ FMC_PR(PM_DBG, "\t|-Check BP disable result: %#x\n", reg); 35850+ if (ANY_BP_ENABLE(reg)) { 35851+ DB_MSG("Error: Write protection disable failed!\n"); 35852+ } 35853+ } 35854+ 35855+ /* Disable chip internal ECC */ 35856+ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); 35857+ if (ret) 35858+ return; 35859+ FMC_PR(PM_DBG, "\t|-Get feature status[%#x]: %#x\n", FEATURE_ADDR, 35860+ reg); 35861+ if (reg & FEATURE_ECC_ENABLE) { 35862+ reg &= ~FEATURE_ECC_ENABLE; 35863+ ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, ®); 35864+ if (ret) 35865+ return; 35866+ FMC_PR(PM_DBG, "\t|-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg); 35867+ 35868+ spi->driver->wait_ready(spi); 35869+ 35870+ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); 35871+ if (ret) 35872+ return; 35873+ FMC_PR(PM_DBG, "\t|-Check internal ECC disable result: %#x\n", 35874+ reg); 35875+ if (reg & FEATURE_ECC_ENABLE) { 35876+ DB_MSG("Error: Chip internal ECC disable failed!\n"); 35877+ } 35878+ } 35879+} 35880+ 35881+#endif /* CONFIG_PM */ 35882diff --git a/drivers/mtd/nand/hifmc100_nand/Kconfig b/drivers/mtd/nand/hifmc100_nand/Kconfig 35883new file mode 100644 35884index 000000000..188c9a77a 35885--- /dev/null 35886+++ b/drivers/mtd/nand/hifmc100_nand/Kconfig 35887@@ -0,0 +1,50 @@ 35888+# 35889+# drivers/mtd/nand/hifmc100_nand/Kconfig 35890+# add by hisilicon 2017.10.26 35891+# 35892+ 35893+menuconfig MTD_NAND_HIFMC100 35894+ bool "Hisilicon Flash Memory Controller v100 Nand devices support" 35895+ depends on MFD_HISI_FMC && !MTD_SPI_NAND_HISI_BVT 35896+ select MISC_FILESYSTEMS 35897+ select MTD_BLOCK 35898+ select YAFFS_FS 35899+ select YAFFS_YAFFS2 35900+ help 35901+ Hisilicon Flash Memory Controller version 100 is called hifmc100 for 35902+ short. The controller support DMA transfers while reading or writing 35903+ the Nand flash. 35904+ 35905+if MTD_NAND_HIFMC100 35906+ 35907+config HIFMC100_NAND_EDO_MODE 35908+ bool "the Extended Data Out(EDO) mode" 35909+ help 35910+ In Extended data out (EDO), a new data cycle is started while the data 35911+ output of the previous cycle is still active. This process of cycle 35912+ overlapping, called pipelining, increases processing speed by about 35913+ 10 nanoseconds per cycle,increasing computer performance by about 5 35914+ percent compared to performance using FMP. 35915+ 35916+config RW_H_WIDTH 35917+ int "the width of Read/Write HIGH Hold Time (0 to 15)" 35918+ range 0 15 35919+ default 10 if (ARCH_HI3559AV100 || ARCH_HI3569V100) 35920+ help 35921+ the Read/Write HIGH Hold Time of nand flash 35922+ 35923+config R_L_WIDTH 35924+ int "the Read pulse width (0 to 15)" 35925+ range 0 15 35926+ default 10 if (ARCH_HI3559AV100 || ARCH_HI3569V100) 35927+ help 35928+ the Read/Write LOW Hold Time of nand flash 35929+ 35930+config W_L_WIDTH 35931+ int "the Write pulse width (0 to 15)" 35932+ range 0 15 35933+ default 10 if (ARCH_HI3559AV100 || ARCH_HI3569V100) 35934+ help 35935+ the Read/Write LOW Hold Time of nand flash 35936+ 35937+endif # End of MTD_NAND_HIFMC100 35938diff --git a/drivers/mtd/nand/hifmc100_nand/Makefile b/drivers/mtd/nand/hifmc100_nand/Makefile 35939new file mode 100644 35940index 000000000..623363cfc 35941--- /dev/null 35942+++ b/drivers/mtd/nand/hifmc100_nand/Makefile 35943@@ -0,0 +1,26 @@ 35944+# 35945+# The Flash Memory Controller v100 Device Driver for hisilicon 35946+# 35947+# Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 35948+# 35949+# This program is free software; you can redistribute it and/or modify it 35950+# under the terms of the GNU General Public License as published by the 35951+# Free Software Foundation; either version 2 of the License, or (at your 35952+# option) any later version. 35953+# 35954+# This program is distributed in the hope that it will be useful, 35955+# but WITHOUT ANY WARRANTY; without even the implied warranty of 35956+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35957+# GNU General Public License for more details. 35958+# 35959+# You should have received a copy of the GNU General Public License 35960+# along with this program. If not, see <http://www.gnu.org/licenses/>. 35961+# 35962+# 35963+ 35964+# 35965+# drivers/mtd/nand/hifmc100_nand/Makefile 35966+# 35967+ 35968+obj-y += hifmc_nand_spl_ids.o 35969+obj-y += hifmc100_nand.o hifmc100_nand_os.o 35970diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.c b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.c 35971new file mode 100644 35972index 000000000..5c08d4beb 35973--- /dev/null 35974+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.c 35975@@ -0,0 +1,1170 @@ 35976+/* 35977+ * The Flash Memory Controller v100 Device Driver for hisilicon 35978+ * 35979+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 35980+ * 35981+ * This program is free software; you can redistribute it and/or modify it 35982+ * under the terms of the GNU General Public License as published by the 35983+ * Free Software Foundation; either version 2 of the License, or (at your 35984+ * option) any later version. 35985+ * 35986+ * This program is distributed in the hope that it will be useful, 35987+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 35988+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35989+ * GNU General Public License for more details. 35990+ * 35991+ * You should have received a copy of the GNU General Public License 35992+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 35993+ * 35994+ */ 35995+ 35996+#include <linux/io.h> 35997+#include <linux/compiler.h> 35998+#include <linux/delay.h> 35999+#include <linux/printk.h> 36000+#include <linux/clk.h> 36001+#include <linux/mfd/hisi_fmc.h> 36002+ 36003+#include "../raw/hinfc_gen.h" 36004+#include "hifmc100_nand_os.h" 36005+#include "hifmc100_nand.h" 36006+ 36007+#include <mach/platform.h> 36008+ 36009+static void hifmc100_dma_transfer(struct hifmc_host *host, unsigned int todev) 36010+{ 36011+ unsigned int reg = (unsigned int)host->dma_buffer; 36012+ char *op = todev ? "write" : "read"; 36013+ 36014+ FMC_PR(DMA_DB, "\t\t *-Start %s page dma transfer\n", op); 36015+ 36016+ hifmc_writel(host, FMC_DMA_SADDR_D0, reg); 36017+ FMC_PR(DMA_DB, "\t\t |-Set ADDR0[%#x]%#x\n", FMC_DMA_SADDR_D0, reg); 36018+ 36019+#ifdef CONFIG_64BIT 36020+ reg = (unsigned int)((host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32); 36021+ hifmc_writel(host, FMC_DMA_SADDRH_D0, reg); 36022+ FMC_PR(DMA_DB, "\t\t |-Set ADDRH0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg); 36023+#endif 36024+ 36025+ reg += FMC_DMA_ADDR_OFFSET; 36026+ hifmc_writel(host, FMC_DMA_SADDR_D1, reg); 36027+ FMC_PR(DMA_DB, "\t\t |-Set ADDR1[%#x]%#x\n", FMC_DMA_SADDR_D1, reg); 36028+ 36029+ reg += FMC_DMA_ADDR_OFFSET; 36030+ hifmc_writel(host, FMC_DMA_SADDR_D2, reg); 36031+ FMC_PR(DMA_DB, "\t\t |-Set ADDR2[%#x]%#x\n", FMC_DMA_SADDR_D2, reg); 36032+ 36033+ reg += FMC_DMA_ADDR_OFFSET; 36034+ hifmc_writel(host, FMC_DMA_SADDR_D3, reg); 36035+ FMC_PR(DMA_DB, "\t\t |-Set ADDR3[%#x]%#x\n", FMC_DMA_SADDR_D3, reg); 36036+ 36037+ reg = host->dma_oob; 36038+ hifmc_writel(host, FMC_DMA_SADDR_OOB, reg); 36039+ FMC_PR(DMA_DB, "\t\t |-Set OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, reg); 36040+ 36041+#ifdef CONFIG_64BIT 36042+ reg = (unsigned int)((host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32); 36043+ hifmc_writel(host, FMC_DMA_SADDRH_OOB, reg); 36044+ FMC_PR(DMA_DB, "\t\t |-Set ADDRH0[%#x]%#x\n", FMC_DMA_SADDRH_OOB, reg); 36045+#endif 36046+ 36047+ if (host->ecctype == NAND_ECC_0BIT) { 36048+ hifmc_writel(host, FMC_DMA_LEN, FMC_DMA_LEN_SET(host->oobsize)); 36049+ FMC_PR(DMA_DB, "\t\t |-Set LEN[%#x]%#x\n", FMC_DMA_LEN, reg); 36050+ } 36051+ reg = FMC_OP_READ_DATA_EN | FMC_OP_WRITE_DATA_EN; 36052+ hifmc_writel(host, FMC_OP, reg); 36053+ FMC_PR(DMA_DB, "\t\t |-Set OP[%#x]%#x\n", FMC_OP, reg); 36054+ 36055+ reg = FMC_DMA_AHB_CTRL_DMA_PP_EN | 36056+ FMC_DMA_AHB_CTRL_BURST16_EN | 36057+ FMC_DMA_AHB_CTRL_BURST8_EN | 36058+ FMC_DMA_AHB_CTRL_BURST4_EN; 36059+ hifmc_writel(host, FMC_DMA_AHB_CTRL, reg); 36060+ FMC_PR(DMA_DB, "\t\t |-Set AHBCTRL[%#x]%#x\n", FMC_DMA_AHB_CTRL, reg); 36061+ 36062+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | 36063+ OP_CFG_ADDR_NUM(host->addr_cycle); 36064+ hifmc_writel(host, FMC_OP_CFG, reg); 36065+ FMC_PR(DMA_DB, "\t\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 36066+ 36067+ reg = OP_CTRL_DMA_OP_READY; 36068+ if (todev) { 36069+ reg |= OP_CTRL_RW_OP(todev); 36070+ } 36071+ hifmc_writel(host, FMC_OP_CTRL, reg); 36072+ FMC_PR(DMA_DB, "\t\t |-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg); 36073+ 36074+ FMC_DMA_WAIT_CPU_FINISH(host); 36075+ 36076+ FMC_PR(DMA_DB, "\t\t *-End %s page dma transfer\n", op); 36077+ 36078+ return; 36079+} 36080+ 36081+ 36082+static void hifmc100_send_cmd_write(struct hifmc_host *host) 36083+{ 36084+ unsigned int reg; 36085+ 36086+ FMC_PR(WR_DBG, "\t|*-Start send page programme cmd\n"); 36087+ 36088+ if (*host->bbm != 0xFF && *host->bbm != 0x00) { 36089+ pr_info("WARNING: attempt to write an invalid bbm. " \ 36090+ "page: 0x%08x, mark: 0x%02x,\n", 36091+ GET_PAGE_INDEX(host), *host->bbm); 36092+ } 36093+ 36094+ host->enable_ecc_randomizer(host, ENABLE, ENABLE); 36095+ 36096+ reg = host->addr_value[1]; 36097+ hifmc_writel(host, FMC_ADDRH, reg); 36098+ FMC_PR(WR_DBG, "\t||-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); 36099+ 36100+ reg = host->addr_value[0] & 0xffff0000; 36101+ hifmc_writel(host, FMC_ADDRL, reg); 36102+ FMC_PR(WR_DBG, "\t||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 36103+ 36104+ reg = FMC_CMD_CMD2(NAND_CMD_PAGEPROG) | FMC_CMD_CMD1(NAND_CMD_SEQIN); 36105+ hifmc_writel(host, FMC_CMD, reg); 36106+ FMC_PR(WR_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); 36107+ 36108+ *host->epm = 0x0000; 36109+ 36110+ hifmc100_dma_transfer(host, RW_OP_WRITE); 36111+ 36112+ FMC_PR(WR_DBG, "\t|*-End send page read cmd\n"); 36113+} 36114+ 36115+ 36116+static void hifmc100_send_cmd_read(struct hifmc_host *host) 36117+{ 36118+ unsigned int reg; 36119+ 36120+ FMC_PR(RD_DBG, "\t*-Start send page read cmd\n"); 36121+ 36122+ if ((host->addr_value[0] == host->cache_addr_value[0]) && 36123+ (host->addr_value[1] == host->cache_addr_value[1])) { 36124+ FMC_PR(RD_DBG, "\t*-Cache hit! addr1[%#x], addr0[%#x]\n", 36125+ host->addr_value[1], host->addr_value[0]); 36126+ return; 36127+ } 36128+ 36129+ host->page_status = 0; 36130+ 36131+ host->enable_ecc_randomizer(host, ENABLE, ENABLE); 36132+ 36133+ reg = FMC_INT_CLR_ALL; 36134+ hifmc_writel(host, FMC_INT_CLR, reg); 36135+ FMC_PR(RD_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); 36136+ 36137+ reg = host->nand_cfg; 36138+ hifmc_writel(host, FMC_CFG, reg); 36139+ FMC_PR(RD_DBG, "\t|-Set CFG[%#x]%#x\n", FMC_CFG, reg); 36140+ 36141+ reg = host->addr_value[1]; 36142+ hifmc_writel(host, FMC_ADDRH, reg); 36143+ FMC_PR(RD_DBG, "\t|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); 36144+ 36145+ reg = host->addr_value[0] & 0xffff0000; 36146+ hifmc_writel(host, FMC_ADDRL, reg); 36147+ FMC_PR(RD_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 36148+ 36149+ reg = FMC_CMD_CMD2(NAND_CMD_READSTART) | FMC_CMD_CMD1(NAND_CMD_READ0); 36150+ hifmc_writel(host, FMC_CMD, reg); 36151+ FMC_PR(RD_DBG, "\t|-Set CMD[%#x]%#x\n", FMC_CMD, reg); 36152+ 36153+ hifmc100_dma_transfer(host, RW_OP_READ); 36154+ 36155+ if (hifmc_readl(host, FMC_INT) & FMC_INT_ERR_INVALID) { 36156+ host->page_status |= HIFMC100_PS_UC_ECC; 36157+ } 36158+ 36159+ host->cache_addr_value[0] = host->addr_value[0]; 36160+ host->cache_addr_value[1] = host->addr_value[1]; 36161+ 36162+ FMC_PR(RD_DBG, "\t*-End send page read cmd\n"); 36163+} 36164+ 36165+ 36166+static void hifmc100_send_cmd_erase(struct hifmc_host *host) 36167+{ 36168+ unsigned int reg; 36169+ 36170+ FMC_PR(ER_DBG, "\t *-Start send cmd erase\n"); 36171+ 36172+ /* Don't case the read retry config */ 36173+ host->enable_ecc_randomizer(host, DISABLE, DISABLE); 36174+ 36175+ reg = host->addr_value[0]; 36176+ hifmc_writel(host, FMC_ADDRL, reg); 36177+ FMC_PR(ER_DBG, "\t |-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 36178+ 36179+ reg = FMC_CMD_CMD2(NAND_CMD_ERASE2) | FMC_CMD_CMD1(NAND_CMD_ERASE1); 36180+ hifmc_writel(host, FMC_CMD, reg); 36181+ FMC_PR(ER_DBG, "\t |-Set CMD[%#x]%#x\n", FMC_CMD, reg); 36182+ 36183+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | 36184+ OP_CFG_ADDR_NUM(host->addr_cycle); 36185+ hifmc_writel(host, FMC_OP_CFG, reg); 36186+ FMC_PR(ER_DBG, "\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 36187+ 36188+ /* need to config WAIT_READY_EN */ 36189+ reg = FMC_OP_WAIT_READY_EN | 36190+ FMC_OP_CMD1_EN | 36191+ FMC_OP_CMD2_EN | 36192+ FMC_OP_ADDR_EN | 36193+ FMC_OP_REG_OP_START; 36194+ hifmc_writel(host, FMC_OP, reg); 36195+ FMC_PR(ER_DBG, "\t |-Set OP[%#x]%#x\n", FMC_OP, reg); 36196+ 36197+ FMC_CMD_WAIT_CPU_FINISH(host); 36198+ 36199+ FMC_PR(ER_DBG, "\t |*-End send cmd erase\n"); 36200+} 36201+ 36202+ 36203+static void hifmc100_ecc_randomizer(struct hifmc_host *host, int ecc_en, 36204+ int randomizer_en) 36205+{ 36206+ unsigned int old_reg, reg; 36207+ unsigned int change = 0; 36208+ char *ecc_op = ecc_en ? "Quit" : "Enter"; 36209+ char *rand_op = randomizer_en ? "Enable" : "Disable"; 36210+ 36211+ if (IS_NAND_RANDOM(host)) { 36212+ reg = old_reg = hifmc_readl(host, FMC_GLOBAL_CFG); 36213+ if (randomizer_en) { 36214+ reg |= FMC_GLOBAL_CFG_RANDOMIZER_EN; 36215+ } else { 36216+ reg &= ~FMC_GLOBAL_CFG_RANDOMIZER_EN; 36217+ } 36218+ 36219+ if (old_reg != reg) { 36220+ FMC_PR(EC_DBG, "\t |*-Start %s randomizer\n", rand_op); 36221+ FMC_PR(EC_DBG, "\t ||-Get global CFG[%#x]%#x\n", 36222+ FMC_GLOBAL_CFG, old_reg); 36223+ hifmc_writel(host, FMC_GLOBAL_CFG, reg); 36224+ FMC_PR(EC_DBG, "\t ||-Set global CFG[%#x]%#x\n", 36225+ FMC_GLOBAL_CFG, reg); 36226+ change++; 36227+ } 36228+ } 36229+ 36230+ old_reg = hifmc_readl(host, FMC_CFG); 36231+ reg = (ecc_en ? host->nand_cfg : host->nand_cfg_ecc0); 36232+ 36233+ if (old_reg != reg) { 36234+ FMC_PR(EC_DBG, "\t |%s-Start %s ECC0 mode\n", change ? "|" : "*", 36235+ ecc_op); 36236+ FMC_PR(EC_DBG, "\t ||-Get CFG[%#x]%#x\n", FMC_CFG, old_reg); 36237+ hifmc_writel(host, FMC_CFG, reg); 36238+ FMC_PR(EC_DBG, "\t ||-Set CFG[%#x]%#x\n", FMC_CFG, reg); 36239+ change++; 36240+ } 36241+ 36242+ if (EC_DBG && change) { 36243+ FMC_PR(EC_DBG, "\t |*-End randomizer and ECC0 mode config\n"); 36244+ } 36245+} 36246+ 36247+ 36248+static void hifmc100_send_cmd_status(struct hifmc_host *host) 36249+{ 36250+ unsigned int regval; 36251+ 36252+ host->enable_ecc_randomizer(host, DISABLE, DISABLE); 36253+ 36254+ regval = OP_CFG_FM_CS(host->cmd_op.cs); 36255+ hifmc_writel(host, FMC_OP_CFG, regval); 36256+ 36257+ regval = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START; 36258+ hifmc_writel(host, FMC_OP, regval); 36259+ 36260+ FMC_CMD_WAIT_CPU_FINISH(host); 36261+} 36262+ 36263+ 36264+static void hifmc100_send_cmd_readid(struct hifmc_host *host) 36265+{ 36266+ unsigned int reg; 36267+ 36268+ FMC_PR(BT_DBG, "\t *-Start read nand flash ID\n"); 36269+ 36270+ host->enable_ecc_randomizer(host, DISABLE, DISABLE); 36271+ 36272+ reg = FMC_DATA_NUM_CNT(host->cmd_op.data_no); 36273+ hifmc_writel(host, FMC_DATA_NUM, reg); 36274+ FMC_PR(BT_DBG, "\t |-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg); 36275+ 36276+ reg = FMC_CMD_CMD1(NAND_CMD_READID); 36277+ hifmc_writel(host, FMC_CMD, reg); 36278+ FMC_PR(BT_DBG, "\t |-Set CMD[%#x]%#x\n", FMC_CMD, reg); 36279+ 36280+ reg = 0; 36281+ hifmc_writel(host, FMC_ADDRL, reg); 36282+ FMC_PR(BT_DBG, "\t |-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); 36283+ 36284+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | 36285+ OP_CFG_ADDR_NUM(READ_ID_ADDR_NUM); 36286+ hifmc_writel(host, FMC_OP_CFG, reg); 36287+ FMC_PR(BT_DBG, "\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 36288+ 36289+ reg = FMC_OP_CMD1_EN | 36290+ FMC_OP_ADDR_EN | 36291+ FMC_OP_READ_DATA_EN | 36292+ FMC_OP_REG_OP_START; 36293+ hifmc_writel(host, FMC_OP, reg); 36294+ FMC_PR(BT_DBG, "\t |-Set OP[%#x]%#x\n", FMC_OP, reg); 36295+ 36296+ host->addr_cycle = 0x0; 36297+ 36298+ FMC_CMD_WAIT_CPU_FINISH(host); 36299+ 36300+ FMC_PR(BT_DBG, "\t *-End read nand flash ID\n"); 36301+} 36302+ 36303+ 36304+static void hifmc100_send_cmd_reset(struct hifmc_host *host) 36305+{ 36306+ unsigned int reg; 36307+ 36308+ FMC_PR(BT_DBG, "\t *-Start reset nand flash\n"); 36309+ 36310+ reg = FMC_CMD_CMD1(NAND_CMD_RESET); 36311+ hifmc_writel(host, FMC_CMD, reg); 36312+ FMC_PR(BT_DBG, "\t |-Set CMD[%#x]%#x\n", FMC_CMD, reg); 36313+ 36314+ reg = OP_CFG_FM_CS(host->cmd_op.cs); 36315+ hifmc_writel(host, FMC_OP_CFG, reg); 36316+ FMC_PR(BT_DBG, "\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); 36317+ 36318+ reg = FMC_OP_CMD1_EN | 36319+ FMC_OP_WAIT_READY_EN | 36320+ FMC_OP_REG_OP_START; 36321+ hifmc_writel(host, FMC_OP, reg); 36322+ FMC_PR(BT_DBG, "\t |-Set OP[%#x]%#x\n", FMC_OP, reg); 36323+ 36324+ FMC_CMD_WAIT_CPU_FINISH(host); 36325+ 36326+ FMC_PR(BT_DBG, "\t *-End reset nand flash\n"); 36327+} 36328+ 36329+ 36330+static unsigned char hifmc100_read_byte(struct mtd_info *mtd) 36331+{ 36332+ unsigned char value = 0; 36333+ struct nand_chip *chip = mtd_to_nand(mtd); 36334+ struct hifmc_host *host = chip->priv; 36335+ 36336+ if (host->cmd_op.l_cmd == NAND_CMD_READID) { 36337+ value = hifmc_readb((void __iomem *)(chip->IO_ADDR_R + host->offset)); 36338+ host->offset++; 36339+ if (host->cmd_op.data_no == host->offset) { 36340+ host->cmd_op.l_cmd = 0; 36341+ } 36342+ return value; 36343+ } 36344+ 36345+ if (host->cmd_op.cmd == NAND_CMD_STATUS) { 36346+ value = hifmc_readl(host, FMC_STATUS); 36347+ if (host->cmd_op.l_cmd == NAND_CMD_ERASE1) { 36348+ FMC_PR(ER_DBG, "\t*-Erase WP status: %#x\n", value); 36349+ } 36350+ if (host->cmd_op.l_cmd == NAND_CMD_PAGEPROG) { 36351+ FMC_PR(WR_DBG, "\t*-Write WP status: %#x\n", value); 36352+ } 36353+ return value; 36354+ } 36355+ 36356+ if (host->cmd_op.l_cmd == NAND_CMD_READOOB) { 36357+ value = hifmc_readb((void __iomem *)(host->buffer + 36358+ host->pagesize + host->offset)); 36359+ host->offset++; 36360+ return value; 36361+ } 36362+ 36363+ host->offset++; 36364+ 36365+ return hifmc_readb((void __iomem *)(host->buffer + host->column + 36366+ host->offset - 1)); 36367+} 36368+ 36369+ 36370+static unsigned short hifmc100_read_word(struct mtd_info *mtd) 36371+{ 36372+ struct nand_chip *chip = mtd_to_nand(mtd); 36373+ struct hifmc_host *host = chip->priv; 36374+ 36375+ host->offset += 2; 36376+ return hifmc_readw(host->buffer + host->column + host->offset - 2); 36377+} 36378+ 36379+ 36380+static void hifmc100_write_buf(struct mtd_info *mtd, 36381+ const u_char *buf, int len) 36382+{ 36383+ struct nand_chip *chip = mtd_to_nand(mtd); 36384+ struct hifmc_host *host = chip->priv; 36385+ 36386+#ifdef HIFMC100_NAND_SUPPORT_REG_WRITE 36387+ if (buf == chip->oob_poi) { 36388+ memcpy((char *)host->iobase + host->pagesize, buf, len); 36389+ } else { 36390+ memcpy((char *)host->iobase, buf, len); 36391+ } 36392+#else 36393+ if (buf == chip->oob_poi) { 36394+ memcpy((char *)host->buffer + host->pagesize, buf, len); 36395+ } else { 36396+ memcpy((char *)host->buffer, buf, len); 36397+ } 36398+#endif 36399+ return; 36400+} 36401+ 36402+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT 36403+ 36404+static void hifmc100_ecc_err_num_count(struct mtd_info *mtd, 36405+ u_int ecc_st, u_int reg) 36406+{ 36407+ u_char err_num; 36408+ 36409+ if (ecc_st > 4) { 36410+ ecc_st = 4; 36411+ } 36412+ 36413+ while (ecc_st) { 36414+ err_num = GET_ECC_ERR_NUM(--ecc_st, reg); 36415+ if (err_num == 0xff) { 36416+ mtd->ecc_stats.failed++; 36417+ } else { 36418+ mtd->ecc_stats.corrected += err_num; 36419+ } 36420+ } 36421+} 36422+#endif 36423+ 36424+ 36425+static void hifmc100_read_buf(struct mtd_info *mtd, u_char *buf, int len) 36426+{ 36427+ struct nand_chip *chip = mtd_to_nand(mtd); 36428+ struct hifmc_host *host = chip->priv; 36429+ 36430+#ifdef HIFMC100_NAND_SUPPORT_REG_READ 36431+ if (buf == chip->oob_poi) { 36432+ memcpy(buf, (char *)host->iobase + host->pagesize, len); 36433+ } else { 36434+ memcpy(buf, (char *)host->iobase, len); 36435+ } 36436+#else 36437+ if (buf == chip->oob_poi) { 36438+ memcpy(buf, (char *)host->buffer + host->pagesize, len); 36439+ } else { 36440+ memcpy(buf, (char *)host->buffer, len); 36441+ } 36442+#endif 36443+ 36444+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT 36445+ if (buf != chip->oob_poi) { 36446+ u_int reg; 36447+ u_int ecc_step = host->pagesize >> 10; 36448+ 36449+ /* 2K or 4K or 8K(1) or 16K(1-1) pagesize */ 36450+ reg = hifmc_readl(host, HIFMC100_ECC_ERR_NUM0_BUF0); 36451+ hifmc100_ecc_err_num_count(mtd, ecc_step, reg); 36452+ 36453+ if (ecc_step > 4) { 36454+ /* 8K(2) or 16K(1-2) pagesize */ 36455+ reg = hifmc_readl(host, HIFMC100_ECC_ERR_NUM1_BUF0); 36456+ hifmc100_ecc_err_num_count(mtd, ecc_step, reg); 36457+ if (ecc_step > 8) { 36458+ /* 16K(2-1) pagesize */ 36459+ reg = hifmc_readl(host, 36460+ HIFMC100_ECC_ERR_NUM0_BUF1); 36461+ hifmc100_ecc_err_num_count(mtd, ecc_step, reg); 36462+ /* 16K(2-2) pagesize */ 36463+ reg = hifmc_readl(host, 36464+ HIFMC100_ECC_ERR_NUM1_BUF1); 36465+ hifmc100_ecc_err_num_count(mtd, ecc_step, reg); 36466+ } 36467+ } 36468+ } 36469+#endif 36470+ 36471+ return; 36472+} 36473+ 36474+ 36475+static void hifmc100_select_chip(struct mtd_info *mtd, int chipselect) 36476+{ 36477+ struct nand_chip *chip = mtd_to_nand(mtd); 36478+ struct hifmc_host *host = chip->priv; 36479+ 36480+ if (chipselect < 0) { 36481+ mutex_unlock(&fmc_switch_mutex); 36482+ return; 36483+ } 36484+ 36485+ mutex_lock(&fmc_switch_mutex); 36486+ 36487+ if (chipselect > CONFIG_HIFMC100_MAX_NAND_CHIP) { 36488+ DB_BUG("Error: Invalid chip select: %d\n", chipselect); 36489+ } 36490+ 36491+ host->cmd_op.cs = chipselect; 36492+ if (host->mtd != mtd) { 36493+ host->mtd = mtd; 36494+ } 36495+ 36496+ switch (chip->state) { 36497+ case FL_ERASING: 36498+ host->cmd_op.l_cmd = NAND_CMD_ERASE1; 36499+ if (ER_DBG) { 36500+ pr_info("\n"); 36501+ } 36502+ FMC_PR(ER_DBG, "\t*-Erase chip: %d\n", chipselect); 36503+ break; 36504+ case FL_WRITING: 36505+ host->cmd_op.l_cmd = NAND_CMD_PAGEPROG; 36506+ if (WR_DBG) { 36507+ pr_info("\n"); 36508+ } 36509+ FMC_PR(WR_DBG, "\t*-Write chip: %d\n", chipselect); 36510+ break; 36511+ case FL_READING: 36512+ host->cmd_op.l_cmd = NAND_CMD_READ0; 36513+ if (RD_DBG) { 36514+ pr_info("\n"); 36515+ } 36516+ FMC_PR(RD_DBG, "\t*-Read chip: %d\n", chipselect); 36517+ break; 36518+ default: 36519+ break; 36520+ } 36521+} 36522+ 36523+ 36524+static void hifmc100_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned ctrl) 36525+{ 36526+ unsigned char cmd; 36527+ int is_cache_invalid = 1; 36528+ struct nand_chip *chip = mtd_to_nand(mtd); 36529+ struct hifmc_host *host = chip->priv; 36530+ 36531+ if (ctrl & NAND_ALE) { 36532+ unsigned int addr_value = 0; 36533+ unsigned int addr_offset = 0; 36534+ 36535+ if (ctrl & NAND_CTRL_CHANGE) { 36536+ host->addr_cycle = 0x0; 36537+ host->addr_value[0] = 0x0; 36538+ host->addr_value[1] = 0x0; 36539+ } 36540+ addr_offset = host->addr_cycle << 3; 36541+ 36542+ if (host->addr_cycle >= HIFMC100_ADDR_CYCLE_MASK) { 36543+ addr_offset = (host->addr_cycle - 36544+ HIFMC100_ADDR_CYCLE_MASK) << 3; 36545+ addr_value = 1; 36546+ } 36547+ 36548+ host->addr_value[addr_value] |= 36549+ (((unsigned int)dat & 0xff) << addr_offset); 36550+ 36551+ host->addr_cycle++; 36552+ } 36553+ 36554+ if ((ctrl & NAND_CLE) && (ctrl & NAND_CTRL_CHANGE)) { 36555+ cmd = (unsigned int)dat & 0xff; 36556+ host->cmd_op.cmd = cmd; 36557+ switch (cmd) { 36558+ case NAND_CMD_PAGEPROG: 36559+ host->offset = 0; 36560+ host->send_cmd_pageprog(host); 36561+ break; 36562+ 36563+ case NAND_CMD_READSTART: 36564+ is_cache_invalid = 0; 36565+ if (host->addr_value[0] == host->pagesize) { 36566+ host->cmd_op.l_cmd = NAND_CMD_READOOB; 36567+ } 36568+ host->send_cmd_readstart(host); 36569+ break; 36570+ 36571+ case NAND_CMD_ERASE2: 36572+ host->cmd_op.l_cmd = cmd; 36573+ host->send_cmd_erase(host); 36574+ break; 36575+ 36576+ case NAND_CMD_READID: 36577+ memset((u_char *)(chip->IO_ADDR_R), 0, MAX_NAND_ID_LEN); 36578+ host->cmd_op.l_cmd = cmd; 36579+ host->cmd_op.data_no = MAX_NAND_ID_LEN; 36580+ host->send_cmd_readid(host); 36581+ break; 36582+ 36583+ case NAND_CMD_STATUS: 36584+ host->send_cmd_status(host); 36585+ break; 36586+ 36587+ case NAND_CMD_READ0: 36588+ host->cmd_op.l_cmd = cmd; 36589+ break; 36590+ 36591+ case NAND_CMD_RESET: 36592+ host->send_cmd_reset(host); 36593+ break; 36594+ 36595+ case NAND_CMD_SEQIN: 36596+ case NAND_CMD_ERASE1: 36597+ default: 36598+ break; 36599+ } 36600+ } 36601+ 36602+ /* pass pagesize and ecctype to kernel when startup. */ 36603+ host->enable_ecc_randomizer(host, ENABLE, ENABLE); 36604+ 36605+ if ((dat == NAND_CMD_NONE) && host->addr_cycle) { 36606+ if (host->cmd_op.cmd == NAND_CMD_SEQIN || 36607+ host->cmd_op.cmd == NAND_CMD_READ0 || 36608+ host->cmd_op.cmd == NAND_CMD_READID) { 36609+ host->offset = 0x0; 36610+ host->column = (host->addr_value[0] & 0xffff); 36611+ } 36612+ } 36613+ 36614+ if (is_cache_invalid) { 36615+ host->cache_addr_value[0] = ~0; 36616+ host->cache_addr_value[1] = ~0; 36617+ } 36618+} 36619+ 36620+ 36621+static int hifmc100_dev_ready(struct mtd_info *mtd) 36622+{ 36623+ return 0x1; 36624+} 36625+ 36626+ 36627+/* 36628+ * 'host->epm' only use the first oobfree[0] field, it looks very simple, But... 36629+ */ 36630+static int hifmc_ooblayout_ecc_default(struct mtd_info *mtd, int section, 36631+ struct mtd_oob_region *oobregion) 36632+{ 36633+ if (section) { 36634+ return -ERANGE; 36635+ } 36636+ 36637+ oobregion->length = 32; 36638+ oobregion->offset = 32; 36639+ 36640+ return 0; 36641+} 36642+ 36643+static int hifmc_ooblayout_free_default(struct mtd_info *mtd, int section, 36644+ struct mtd_oob_region *oobregion) 36645+{ 36646+ if (section) { 36647+ return -ERANGE; 36648+ } 36649+ 36650+ oobregion->length = 30; 36651+ oobregion->offset = 2; 36652+ 36653+ return 0; 36654+} 36655+ 36656+static struct mtd_ooblayout_ops hifmc_ooblayout_default_ops = { 36657+ .ecc = hifmc_ooblayout_ecc_default, 36658+ .free = hifmc_ooblayout_free_default, 36659+}; 36660+ 36661+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 36662+static int hifmc_ooblayout_ecc_4k16bit(struct mtd_info *mtd, int section, 36663+ struct mtd_oob_region *oobregion) 36664+{ 36665+ if (section) { 36666+ return -ERANGE; 36667+ } 36668+ 36669+ oobregion->length = 14; 36670+ oobregion->offset = 14; 36671+ 36672+ return 0; 36673+} 36674+ 36675+static int hifmc_ooblayout_free_4k16bit(struct mtd_info *mtd, int section, 36676+ struct mtd_oob_region *oobregion) 36677+{ 36678+ if (section) { 36679+ return -ERANGE; 36680+ } 36681+ 36682+ oobregion->length = 14; 36683+ oobregion->offset = 2; 36684+ 36685+ return 0; 36686+} 36687+tatic struct mtd_ooblayout_ops hifmc_ooblayout_4k16bit_ops = { 36688+ .ecc = hifmc_ooblayout_ecc_4k16bit, 36689+ .free = hifmc_ooblayout_free_4k16bit, 36690+}; 36691+ 36692+static int hifmc_ooblayout_ecc_2k16bit(struct mtd_info *mtd, int section, 36693+ struct mtd_oob_region *oobregion) 36694+{ 36695+ if (section) { 36696+ return -ERANGE; 36697+ } 36698+ 36699+ oobregion->length = 6; 36700+ oobregion->offset = 6; 36701+ 36702+ return 0; 36703+} 36704+ 36705+static int hifmc_ooblayout_free_2k16bit(struct mtd_info *mtd, int section, 36706+ struct mtd_oob_region *oobregion) 36707+{ 36708+ if (section) { 36709+ return -ERANGE; 36710+ } 36711+ 36712+ oobregion->length = 6; 36713+ oobregion->offset = 2; 36714+ 36715+ return 0; 36716+} 36717+ 36718+static struct mtd_ooblayout_ops hifmc_ooblayout_2k16bit_ops = { 36719+ .ecc = hifmc_ooblayout_ecc_2k16bit, 36720+ .free = hifmc_ooblayout_free_2k16bit, 36721+}; 36722+#endif 36723+ 36724+/* ecc/pagesize get from NAND controller */ 36725+static struct nand_config_info hifmc100_nand_hw_auto_config_table[] = { 36726+ {NAND_PAGE_16K, NAND_ECC_64BIT, 64, 1824, &hifmc_ooblayout_default_ops}, /* 1824 */ 36727+ {NAND_PAGE_16K, NAND_ECC_40BIT, 40, 1200, &hifmc_ooblayout_default_ops}, /* 1152 */ 36728+ {NAND_PAGE_16K, NAND_ECC_0BIT, 0, 32, &hifmc_ooblayout_default_ops}, 36729+ 36730+ {NAND_PAGE_8K, NAND_ECC_64BIT, 64, 928, &hifmc_ooblayout_default_ops}, /* 928 */ 36731+ {NAND_PAGE_8K, NAND_ECC_40BIT, 40, 600, &hifmc_ooblayout_default_ops}, /* 592 */ 36732+ {NAND_PAGE_8K, NAND_ECC_24BIT, 24, 368, &hifmc_ooblayout_default_ops}, /* 368 */ 36733+ {NAND_PAGE_8K, NAND_ECC_0BIT, 0, 32, &hifmc_ooblayout_default_ops}, 36734+ 36735+ {NAND_PAGE_4K, NAND_ECC_24BIT, 24, 200, &hifmc_ooblayout_default_ops}, /* 200 */ 36736+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 36737+ {NAND_PAGE_4K, NAND_ECC_16BIT, 16, 128, &hifmc_ooblayout_4k16bit_ops}, /* 128 */ 36738+#endif 36739+ {NAND_PAGE_4K, NAND_ECC_8BIT, 8, 128, &hifmc_ooblayout_default_ops}, /* 88 */ 36740+ {NAND_PAGE_4K, NAND_ECC_0BIT, 0, 32, &hifmc_ooblayout_default_ops}, 36741+ 36742+ {NAND_PAGE_2K, NAND_ECC_24BIT, 24, 128, &hifmc_ooblayout_default_ops}, /* 116 */ 36743+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 36744+ {NAND_PAGE_2K, NAND_ECC_16BIT, 16, 64, &hifmc_ooblayout_2k16bit_ops}, /* 64 */ 36745+#endif 36746+ {NAND_PAGE_2K, NAND_ECC_8BIT, 8, 64, &hifmc_ooblayout_default_ops}, /* 60 */ 36747+ {NAND_PAGE_2K, NAND_ECC_0BIT, 0, 32, &hifmc_ooblayout_default_ops}, 36748+ 36749+ {0, 0, 0, 0, NULL}, 36750+}; 36751+ 36752+ 36753+/* 36754+ * 0 - This NAND NOT support randomizer 36755+ * 1 - This NAND support randomizer. 36756+ */ 36757+static int hifmc100_nand_support_randomizer(u_int pageisze, u_int ecctype) 36758+{ 36759+ switch (pageisze) { 36760+ case _8K: 36761+ return (ecctype >= NAND_ECC_24BIT && ecctype <= NAND_ECC_80BIT); 36762+ case _16K: 36763+ return (ecctype >= NAND_ECC_40BIT && ecctype <= NAND_ECC_80BIT); 36764+ case _32K: 36765+ return (ecctype >= NAND_ECC_40BIT && ecctype <= NAND_ECC_80BIT); 36766+ default: 36767+ return 0; 36768+ } 36769+} 36770+ 36771+ 36772+/* used the best correct arithmetic. */ 36773+static struct nand_config_info *hifmc100_get_config_type_info( 36774+ struct mtd_info *mtd, struct nand_dev_t *nand_dev) 36775+{ 36776+ struct nand_config_info *best = NULL; 36777+ struct nand_chip *chip = mtd_to_nand(mtd); 36778+ struct hifmc_host *host = chip->priv; 36779+ struct nand_config_info *info = hifmc100_nand_hw_auto_config_table; 36780+ 36781+ nand_dev->start_type = "Auto"; 36782+ nand_dev->flags |= (IS_NANDC_HW_AUTO(host) | IS_NANDC_CONFIG_DONE(host)); 36783+ 36784+ for (; info->ooblayout_ops; info++) { 36785+ if (match_page_type_to_size(info->pagetype) != mtd->writesize) { 36786+ continue; 36787+ } 36788+ 36789+ if (mtd->oobsize < info->oobsize) { 36790+ continue; 36791+ } 36792+ 36793+ if (!best || (best->ecctype < info->ecctype)) { 36794+ best = info; 36795+ } 36796+ } 36797+ 36798+ return best; 36799+} 36800+ 36801+ 36802+static unsigned int hifmc100_get_ecc_reg(struct hifmc_host *host, 36803+ const struct nand_config_info *info, struct nand_dev_t *nand_dev) 36804+{ 36805+ host->ecctype = info->ecctype; 36806+ FMC_PR(BT_DBG, "\t |-Save best EccType %d(%s)\n", host->ecctype, 36807+ match_ecc_type_to_str(info->ecctype)); 36808+ 36809+ nand_dev->ecctype = host->ecctype; 36810+ 36811+ return FMC_CFG_ECC_TYPE(match_ecc_type_to_reg(info->ecctype)); 36812+} 36813+ 36814+ 36815+static unsigned int hifmc100_get_page_reg(struct hifmc_host *host, 36816+ const struct nand_config_info *info) 36817+{ 36818+ host->pagesize = match_page_type_to_size(info->pagetype); 36819+ FMC_PR(BT_DBG, "\t |-Save best PageSize %d(%s)\n", host->pagesize, 36820+ match_page_type_to_str(info->pagetype)); 36821+ 36822+ return FMC_CFG_PAGE_SIZE(match_page_type_to_reg(info->pagetype)); 36823+} 36824+ 36825+ 36826+static unsigned int hifmc100_get_block_reg(struct hifmc_host *host, 36827+ const struct nand_config_info *info) 36828+{ 36829+ unsigned int block_reg = 0; 36830+ unsigned int page_per_block; 36831+ struct mtd_info *mtd = host->mtd; 36832+ 36833+ host->block_page_mask = ((mtd->erasesize / mtd->writesize) - 1); 36834+ page_per_block = mtd->erasesize / match_page_type_to_size(info->pagetype); 36835+ switch (page_per_block) { 36836+ case 64: 36837+ block_reg = BLOCK_SIZE_64_PAGE; 36838+ break; 36839+ case 128: 36840+ block_reg = BLOCK_SIZE_128_PAGE; 36841+ break; 36842+ case 256: 36843+ block_reg = BLOCK_SIZE_256_PAGE; 36844+ break; 36845+ case 512: 36846+ block_reg = BLOCK_SIZE_512_PAGE; 36847+ break; 36848+ default: 36849+ DB_MSG("Can't support block %#x and page %#x size\n", 36850+ mtd->erasesize, mtd->writesize); 36851+ } 36852+ 36853+ return FMC_CFG_BLOCK_SIZE(block_reg); 36854+} 36855+ 36856+ 36857+static void hifmc100_set_fmc_cfg_reg(struct hifmc_host *host, 36858+ const struct nand_config_info *type_info, struct nand_dev_t *nand_dev) 36859+{ 36860+ unsigned int page_reg, ecc_reg, block_reg, reg_fmc_cfg; 36861+ 36862+ ecc_reg = hifmc100_get_ecc_reg(host, type_info, nand_dev); 36863+ page_reg = hifmc100_get_page_reg(host, type_info); 36864+ block_reg = hifmc100_get_block_reg(host, type_info); 36865+ 36866+ if (hifmc100_nand_support_randomizer(host->pagesize, host->ecctype)) { 36867+ host->flags |= IS_NAND_RANDOM(nand_dev); 36868+ } 36869+ 36870+ /* 36871+ * Check if hardware enable randomizer PIN, But NAND does not need 36872+ * randomizer. We will notice user. 36873+ */ 36874+ if (IS_NAND_RANDOM(host) && 36875+ !hifmc100_nand_support_randomizer(host->pagesize, 36876+ host->ecctype)) { 36877+ DB_BUG(ERSTR_HARDWARE 36878+ "This NAND flash does not support `randomizer`, " 36879+ "Please don't configure hardware randomizer PIN."); 36880+ } 36881+ /* Save value of FMC_CFG and FMC_CFG_ECC0 to turn on/off ECC */ 36882+ reg_fmc_cfg = hifmc_readl(host, FMC_CFG); 36883+ reg_fmc_cfg &= ~(PAGE_SIZE_MASK | ECC_TYPE_MASK | BLOCK_SIZE_MASK); 36884+ reg_fmc_cfg |= ecc_reg | page_reg | block_reg; 36885+ host->nand_cfg = reg_fmc_cfg; 36886+ host->nand_cfg_ecc0 = (host->nand_cfg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; 36887+ FMC_PR(BT_DBG, "\t|-Save FMC_CFG[%#x]: %#x and FMC_CFG_ECC0: %#x\n", 36888+ FMC_CFG, host->nand_cfg, host->nand_cfg_ecc0); 36889+ 36890+ /* pass pagesize and ecctype to kernel when spiflash startup. */ 36891+ host->enable_ecc_randomizer(host, ENABLE, ENABLE); 36892+ 36893+ /* 36894+ * If it want to support the 'read retry' feature, the 'randomizer' 36895+ * feature must be support first. 36896+ */ 36897+ host->read_retry = NULL; 36898+ 36899+ if (host->read_retry && !IS_NAND_RANDOM(host)) { 36900+ DB_BUG(ERSTR_HARDWARE 36901+ "This Nand flash need to enable 'randomizer' feature. " 36902+ "Please configure hardware randomizer PIN."); 36903+ } 36904+} 36905+ 36906+ 36907+static void hifmc100_set_oob_info(struct mtd_info *mtd, 36908+ struct nand_config_info *info, struct nand_dev_t *nand_dev) 36909+{ 36910+ int buffer_len; 36911+ struct nand_chip *chip = mtd_to_nand(mtd); 36912+ struct hifmc_host *host = chip->priv; 36913+ struct mtd_oob_region hifmc_oobregion = {0, 0}; 36914+ 36915+ if (info->ecctype != NAND_ECC_0BIT) { 36916+ mtd->oobsize = info->oobsize; 36917+ } 36918+ mtd->oobavail = HIFMC100_NAND_OOBSIZE_FOR_YAFFS; 36919+ 36920+ host->oobsize = mtd->oobsize; 36921+ 36922+ buffer_len = host->pagesize + host->oobsize; 36923+ 36924+ memset(host->buffer, 0xff, buffer_len); 36925+ host->dma_oob = host->dma_buffer + host->pagesize; 36926+ 36927+ host->bbm = (unsigned char *)(host->buffer + host->pagesize + 36928+ HIFMC100_BAD_BLOCK_POS); 36929+ 36930+ info->ooblayout_ops->free(mtd, 0, &hifmc_oobregion); 36931+ 36932+ mtd_set_ooblayout(mtd, info->ooblayout_ops); 36933+ 36934+ /* EB bits locate in the bottom two of CTRL(30) */ 36935+ host->epm = (u_short *)(host->buffer + host->pagesize + 36936+ hifmc_oobregion.offset + 28); 36937+ 36938+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 36939+ if (best->ecctype == NAND_ECC_16BIT) { 36940+ if (host->pagesize == _2K) { 36941+ /* EB bits locate in the bottom two of CTRL(4) */ 36942+ host->epm = (u_short *)(host->buffer + host->pagesize + 36943+ hifmc_oobregion.offset + 4); 36944+ } else if (host->pagesize == _4K) { 36945+ /* EB bit locate in the bottom two of CTRL(14) */ 36946+ host->epm = (u_short *)(host->buffer + host->pagesize + 36947+ hifmc_oobregion.offset + 12); 36948+ } 36949+ } 36950+#endif 36951+} 36952+ 36953+static int hifmc100_set_config_info(struct mtd_info *mtd, 36954+ struct nand_chip *chip, struct nand_dev_t *dev) 36955+{ 36956+ struct hifmc_host *host = chip->priv; 36957+ struct nand_dev_t *nand_dev = dev; 36958+ struct nand_config_info *type_info = NULL; 36959+ 36960+ FMC_PR(BT_DBG, "\t*-Start config Block Page OOB and Ecc\n"); 36961+ 36962+ type_info = hifmc100_get_config_type_info(mtd, nand_dev); 36963+ WARN_ON(!type_info); 36964+ 36965+ FMC_PR(BT_DBG, "\t|-%s Config, PageSize %s EccType %s OobSize %d\n", 36966+ nand_dev->start_type, nand_page_name(type_info->pagetype), 36967+ nand_ecc_name(type_info->ecctype), type_info->oobsize); 36968+ 36969+ /* Set the page_size, ecc_type, block_size of FMC_CFG[0x0] register */ 36970+ hifmc100_set_fmc_cfg_reg(host, type_info, nand_dev); 36971+ 36972+ hifmc100_set_oob_info(mtd, type_info, nand_dev); 36973+ 36974+ if (mtd->writesize > NAND_MAX_PAGESIZE || 36975+ mtd->oobsize > NAND_MAX_OOBSIZE) { 36976+ DB_BUG(ERSTR_DRIVER 36977+ "Driver does not support this Nand Flash. Please " \ 36978+ "increase NAND_MAX_PAGESIZE and NAND_MAX_OOBSIZE.\n"); 36979+ } 36980+ 36981+ /* Some Nand Flash devices have subpage structure */ 36982+ if (mtd->writesize != host->pagesize) { 36983+ unsigned int shift = 0; 36984+ unsigned int writesize = mtd->writesize; 36985+ 36986+ while (writesize > host->pagesize) { 36987+ writesize >>= 1; 36988+ shift++; 36989+ } 36990+ chip->chipsize = chip->chipsize >> shift; 36991+ mtd->erasesize = mtd->erasesize >> shift; 36992+ mtd->writesize = host->pagesize; 36993+ pr_info("Nand divide into 1/%u\n", (1 << shift)); 36994+ } 36995+ 36996+ FMC_PR(BT_DBG, "\t*-End config Block Page Oob and Ecc\n"); 36997+ 36998+ return 0; 36999+} 37000+ 37001+ 37002+static void hifmc100_chip_init(struct nand_chip *chip) 37003+{ 37004+ struct hifmc_host *host = chip->priv; 37005+ 37006+ memset((char *)chip->IO_ADDR_R, 0xff, host->dma_len); 37007+ 37008+ chip->read_byte = hifmc100_read_byte; 37009+ chip->read_word = hifmc100_read_word; 37010+ chip->write_buf = hifmc100_write_buf; 37011+ chip->read_buf = hifmc100_read_buf; 37012+ 37013+ chip->select_chip = hifmc100_select_chip; 37014+ 37015+ chip->cmd_ctrl = hifmc100_cmd_ctrl; 37016+ chip->dev_ready = hifmc100_dev_ready; 37017+ 37018+ chip->chip_delay = FMC_CHIP_DELAY; 37019+ 37020+ chip->options = NAND_NEED_READRDY | NAND_BROKEN_XD | 37021+ NAND_SKIP_BBTSCAN; 37022+ 37023+ chip->ecc.mode = NAND_ECC_NONE; 37024+} 37025+ 37026+ 37027+static int hifmc100_host_init(struct hifmc_host *host) 37028+{ 37029+ unsigned int reg, flash_type; 37030+ 37031+ FMC_PR(BT_DBG, "\t *-Start nand host init\n"); 37032+ 37033+ reg = hifmc_readl(host, FMC_CFG); 37034+ FMC_PR(BT_DBG, "\t |-Read FMC CFG[%#x]%#x\n", FMC_CFG, reg); 37035+ flash_type = GET_SPI_FLASH_TYPE(reg); 37036+ if (flash_type != FLASH_TYPE_NAND) { 37037+ DB_MSG("Error: Flash type isn't Nand flash. reg[%#x]\n", reg); 37038+ reg |= FMC_CFG_FLASH_SEL(FLASH_TYPE_NAND); 37039+ FMC_PR(BT_DBG, "\t |-Change flash type to Nand flash\n"); 37040+ } 37041+ 37042+ if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) { 37043+ reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL); 37044+ FMC_PR(BT_DBG, "\t |-Controller enter normal mode\n"); 37045+ } 37046+ hifmc_writel(host, FMC_CFG, reg); 37047+ FMC_PR(BT_DBG, "\t |-Set CFG[%#x]%#x\n", FMC_CFG, reg); 37048+ 37049+ host->nand_cfg = reg; 37050+ host->nand_cfg_ecc0 = (reg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; 37051+ 37052+ reg = hifmc_readl(host, FMC_GLOBAL_CFG); 37053+ FMC_PR(BT_DBG, "\t |-Read global CFG[%#x]%#x\n", FMC_GLOBAL_CFG, reg); 37054+ if (reg & FMC_GLOBAL_CFG_RANDOMIZER_EN) { 37055+ host->flags &= ~NAND_RANDOMIZER; 37056+ FMC_PR(BT_DBG, "\t |-Default disable randomizer\n"); 37057+ reg &= ~FMC_GLOBAL_CFG_RANDOMIZER_EN; 37058+ hifmc_writel(host, FMC_GLOBAL_CFG, reg); 37059+ FMC_PR(BT_DBG, "\t |-Set global CFG[%#x]%#x\n", FMC_GLOBAL_CFG, reg); 37060+ } 37061+ 37062+#ifdef CONFIG_HIFMC100_NAND_EDO_MODE 37063+ /* enable EDO node */ 37064+ reg = hifmc_readl(host, FMC_GLOBAL_CFG); 37065+ hifmc_writel(host, FMC_GLOBAL_CFG, SET_NAND_EDO_MODE_EN(reg)); 37066+#endif 37067+ 37068+ host->addr_cycle = 0; 37069+ host->addr_value[0] = 0; 37070+ host->addr_value[1] = 0; 37071+ host->cache_addr_value[0] = ~0; 37072+ host->cache_addr_value[1] = ~0; 37073+ 37074+ host->send_cmd_pageprog = hifmc100_send_cmd_write; 37075+ host->send_cmd_status = hifmc100_send_cmd_status; 37076+ host->send_cmd_readstart = hifmc100_send_cmd_read; 37077+ host->send_cmd_erase = hifmc100_send_cmd_erase; 37078+ host->send_cmd_readid = hifmc100_send_cmd_readid; 37079+ host->send_cmd_reset = hifmc100_send_cmd_reset; 37080+ 37081+ /* 37082+ * check if start from nand. 37083+ * This register REG_SYSSTAT is set in start.S 37084+ * When start in NAND (Auto), the ECC/PAGESIZE driver don't detect. 37085+ */ 37086+ host->flags |= NANDC_HW_AUTO; 37087+ 37088+ if (GET_SYS_BOOT_MODE(reg) == BOOT_FROM_NAND) { 37089+ host->flags |= NANDC_CONFIG_DONE; 37090+ FMC_PR(BT_DBG, "\t |-Auto config pagesize and ecctype\n"); 37091+ } 37092+ 37093+ host->enable_ecc_randomizer = hifmc100_ecc_randomizer; 37094+ 37095+ FMC_PR(BT_DBG, "\t *-End nand host init\n"); 37096+ 37097+ return 0; 37098+} 37099+ 37100+ 37101+int hifmc100_nand_init(struct nand_chip *chip) 37102+{ 37103+ struct hifmc_host *host = chip->priv; 37104+ 37105+ /* enable and set system clock */ 37106+ clk_prepare_enable(host->clk); 37107+ 37108+ /* fmc ip version check */ 37109+ host->version = hifmc_readl(host, FMC_VERSION); 37110+ if (host->version != HIFMC_VER_100) { 37111+ return -EFAULT; 37112+ } 37113+ pr_info("Found Flash Memory Controller v100 Nand Driver\n"); 37114+ 37115+ /* hifmc host init */ 37116+ if (hifmc100_host_init(host)) { 37117+ DB_MSG("Error: Nand host init failed!\n"); 37118+ return -EFAULT; 37119+ } 37120+ host->chip = chip; 37121+ 37122+ hifmc_writel(host, 37123+ FMC_PND_PWIDTH_CFG, 37124+ PWIDTH_CFG_RW_HCNT(CONFIG_RW_H_WIDTH) | 37125+ PWIDTH_CFG_R_LCNT(CONFIG_R_L_WIDTH) | 37126+ PWIDTH_CFG_W_LCNT(CONFIG_W_L_WIDTH)); 37127+ 37128+ /* hifmc nand_chip struct init */ 37129+ hifmc100_chip_init(chip); 37130+ 37131+ hifmc_spl_ids_register(); 37132+ hinfc_param_adjust = hifmc100_set_config_info; 37133+ 37134+ return 0; 37135+} 37136+ 37137+#ifdef CONFIG_PM 37138+ 37139+void hifmc100_nand_config(const struct hifmc_host *host) 37140+{ 37141+ /* enable system clock */ 37142+ clk_prepare_enable(host->clk); 37143+ FMC_PR(PM_DBG, "\t |-enable system clock\n"); 37144+} 37145+#endif /* CONFIG_PM */ 37146diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.h b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.h 37147new file mode 100644 37148index 000000000..fba2f43ba 37149--- /dev/null 37150+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.h 37151@@ -0,0 +1,151 @@ 37152+/* 37153+ * The Flash Memory Controller v100 Device Driver for hisilicon 37154+ * 37155+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 37156+ * 37157+ * This program is free software; you can redistribute it and/or modify it 37158+ * under the terms of the GNU General Public License as published by the 37159+ * Free Software Foundation; either version 2 of the License, or (at your 37160+ * option) any later version. 37161+ * 37162+ * This program is distributed in the hope that it will be useful, 37163+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 37164+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37165+ * GNU General Public License for more details. 37166+ * 37167+ * You should have received a copy of the GNU General Public License 37168+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 37169+ * 37170+ */ 37171+ 37172+#ifndef __HIFMC100_NAND_H__ 37173+#define __HIFMC100_NAND_H__ 37174+ 37175+#include <linux/mfd/hisi_fmc.h> 37176+ 37177+/******************************************************************************/ 37178+/* These macroes are for debug only, reg option is slower then dma option */ 37179+#undef HIFMC100_NAND_SUPPORT_REG_READ 37180+/* #define HIFMC100_NAND_SUPPORT_REG_READ */ 37181+ 37182+#undef HIFMC100_NAND_SUPPORT_REG_WRITE 37183+/* #define HIFMC100_NAND_SUPPORT_REG_WRITE */ 37184+ 37185+/*****************************************************************************/ 37186+#define HIFMC100_ECC_ERR_NUM0_BUF0 0xc0 37187+#define HIFMC100_ECC_ERR_NUM1_BUF0 0xc4 37188+#define HIFMC100_ECC_ERR_NUM0_BUF1 0xc8 37189+#define HIFMC100_ECC_ERR_NUM1_BUF1 0xcc 37190+ 37191+#define GET_ECC_ERR_NUM(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) 37192+ 37193+/*****************************************************************************/ 37194+#define NAND_MAX_PAGESIZE 32768 37195+#define NAND_MAX_OOBSIZE 4800 37196+ 37197+#define CONFIG_SUPPORT_YAFFS 37198+#define HIFMC100_NAND_OOBSIZE_FOR_YAFFS 32 37199+ 37200+/*****************************************************************************/ 37201+#define REG_CNT_HIGH_BLOCK_NUM_SHIFT 10 37202+ 37203+#define REG_CNT_BLOCK_NUM_MASK 0x3ff 37204+#define REG_CNT_BLOCK_NUM_SHIFT 22 37205+ 37206+#define REG_CNT_PAGE_NUM_MASK 0x3f 37207+#define REG_CNT_PAGE_NUM_SHIFT 16 37208+ 37209+/*****************************************************************************/ 37210+#define HIFMC100_ADDR_CYCLE_MASK 0x4 37211+#define NAND_EDO_MODE_SHIFT 9 37212+#define NAND_EDO_MODE_MASK (1<<NAND_EDO_MODE_SHIFT) 37213+#define SET_NAND_EDO_MODE_EN(reg) ((reg) | NAND_EDO_MODE_MASK) 37214+/*****************************************************************************/ 37215+struct hifmc_host { 37216+ struct nand_chip *chip; 37217+ struct mtd_info *mtd; 37218+ 37219+ struct hifmc_cmd_op cmd_op; 37220+ void __iomem *regbase; 37221+ void __iomem *iobase; 37222+ 37223+ /* Controller config option nand flash */ 37224+ unsigned int nand_cfg; 37225+ unsigned int nand_cfg_ecc0; 37226+ 37227+ unsigned int offset; 37228+ 37229+ struct device *dev; 37230+ 37231+ /* This is maybe an un-aligment address, only for malloc or free */ 37232+ char *buforg; 37233+ char *buffer; 37234+ 37235+#ifdef CONFIG_64BIT 37236+ unsigned long long dma_buffer; 37237+ unsigned long long dma_oob; 37238+#else 37239+ unsigned int dma_buffer; 37240+ unsigned int dma_oob; 37241+#endif 37242+ unsigned int dma_len; 37243+ 37244+ unsigned int addr_cycle; 37245+ unsigned int addr_value[2]; 37246+ unsigned int cache_addr_value[2]; 37247+ 37248+ unsigned int column; 37249+ unsigned int block_page_mask; 37250+ 37251+ unsigned int ecctype; 37252+ unsigned int pagesize; 37253+ unsigned int oobsize; 37254+ 37255+ int need_rr_data; 37256+#define HIFMC100_READ_RETRY_DATA_LEN 128 37257+ char rr_data[HIFMC100_READ_RETRY_DATA_LEN]; 37258+ int version; 37259+ int add_partition; 37260+ 37261+ /* BOOTROM read two bytes to detect the bad block flag */ 37262+#define HIFMC100_BAD_BLOCK_POS 0 37263+ unsigned char *bbm; /* nand bad block mark */ 37264+ unsigned short *epm; /* nand empty page mark */ 37265+ unsigned int flags; 37266+ 37267+#define HIFMC100_PS_UC_ECC 0x01 /* page has ecc error */ 37268+#define HIFMC100_PS_BAD_BLOCK 0x02 /* bad block */ 37269+#define HIFMC100_PS_EMPTY_PAGE 0x04 /* page is empty */ 37270+#define HIFMC100_PS_EPM_ERROR 0x0100 /* empty page mark word has error. */ 37271+#define HIFMC100_PS_BBM_ERROR 0x0200 /* bad block mark word has error. */ 37272+ unsigned int page_status; 37273+ 37274+ struct clk *clk; 37275+ 37276+ void (*send_cmd_pageprog)(struct hifmc_host *host); 37277+ void (*send_cmd_status)(struct hifmc_host *host); 37278+ void (*send_cmd_readstart)(struct hifmc_host *host); 37279+ void (*send_cmd_erase)(struct hifmc_host *host); 37280+ void (*send_cmd_readid)(struct hifmc_host *host); 37281+ void (*send_cmd_reset)(struct hifmc_host *host); 37282+ void (*enable)(int enable); 37283+ 37284+ void (*enable_ecc_randomizer)(struct hifmc_host *host, 37285+ int ecc_en, int randomizer_en); 37286+ 37287+ void (*detect_ecc)(struct hifmc_host *host); 37288+ 37289+ struct read_retry_t *read_retry; 37290+}; 37291+ 37292+extern struct nand_dev_t g_nand_dev; 37293+ 37294+int hifmc100_nand_init(struct nand_chip *chip); 37295+ 37296+extern void hifmc_spl_ids_register(void); 37297+ 37298+#ifdef CONFIG_PM 37299+void hifmc100_nand_config(const struct hifmc_host *host); 37300+#endif 37301+ 37302+#endif /* End of __HIFMC100_NAND_H__ */ 37303diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.c b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.c 37304new file mode 100644 37305index 000000000..0849cd3cb 37306--- /dev/null 37307+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.c 37308@@ -0,0 +1,180 @@ 37309+/* 37310+ * The Flash Memory Controller v100 Device Driver for hisilicon 37311+ * 37312+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 37313+ * 37314+ * This program is free software; you can redistribute it and/or modify it 37315+ * under the terms of the GNU General Public License as published by the 37316+ * Free Software Foundation; either version 2 of the License, or (at your 37317+ * option) any later version. 37318+ * 37319+ * This program is distributed in the hope that it will be useful, 37320+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 37321+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37322+ * GNU General Public License for more details. 37323+ * 37324+ * You should have received a copy of the GNU General Public License 37325+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 37326+ * 37327+ */ 37328+ 37329+#include <linux/of_platform.h> 37330+ 37331+#include "hifmc100_nand_os.h" 37332+#include "hifmc100_nand.h" 37333+#include <linux/mfd/hisi_fmc.h> 37334+ 37335+static inline int mtd_has_partitions(void) 37336+{ 37337+ return 1; 37338+} 37339+ 37340+static int hisi_nand_os_probe(struct platform_device *pltdev) 37341+{ 37342+ int len; 37343+ int result = 0; 37344+ struct hifmc_host *host = NULL; 37345+ struct nand_chip *chip = NULL; 37346+ struct mtd_info *mtd = NULL; 37347+ int nr_parts = 0; 37348+ struct mtd_partition *parts = NULL; 37349+ struct device *dev = &pltdev->dev; 37350+ struct device_node *np = NULL; 37351+ struct hisi_fmc *fmc = dev_get_drvdata(dev->parent); 37352+ 37353+ if (!fmc) { 37354+ dev_err(dev, "get mfd fmc devices failed\n"); 37355+ return -ENXIO; 37356+ } 37357+ 37358+ len = sizeof(struct hifmc_host) + sizeof(struct nand_chip) 37359+ + sizeof(struct mtd_info); 37360+ host = devm_kzalloc(dev, len, GFP_KERNEL); 37361+ if (!host) { 37362+ return -ENOMEM; 37363+ } 37364+ memset((char *)host, 0, len); 37365+ platform_set_drvdata(pltdev, host); 37366+ 37367+ host->dev = &pltdev->dev; 37368+ host->chip = chip = (struct nand_chip *)&host[1]; 37369+ host->mtd = mtd = nand_to_mtd(chip); 37370+ host->regbase = fmc->regbase; 37371+ host->iobase = fmc->iobase; 37372+ host->clk = fmc->clk; 37373+ chip->IO_ADDR_R = chip->IO_ADDR_W = host->iobase; 37374+ host->buffer = fmc->buffer; 37375+ host->dma_buffer = fmc->dma_buffer; 37376+ host->dma_len = fmc->dma_len; 37377+ 37378+ /* hifmc Nand host init */ 37379+ chip->priv = host; 37380+ result = hifmc100_nand_init(chip); 37381+ if (result) { 37382+ DB_MSG("Error: host init failed! result: %d\n", result); 37383+ goto fail; 37384+ } 37385+ 37386+ np = of_get_next_available_child(dev->of_node, NULL); 37387+ mtd->name = np->name; 37388+ mtd->type = MTD_NANDFLASH; 37389+ mtd->priv = chip; 37390+ mtd->flags = MTD_CAP_NANDFLASH; 37391+ mtd->owner = THIS_MODULE; 37392+ 37393+ if (nand_scan(mtd, CONFIG_HIFMC100_MAX_NAND_CHIP)) { 37394+ result = -ENXIO; 37395+ goto fail; 37396+ } 37397+ 37398+ result = mtd_device_register(host->mtd, parts, nr_parts); 37399+ if (result) { 37400+ kfree(parts); 37401+ parts = NULL; 37402+ } 37403+ 37404+ return (result == 1) ? -ENODEV : 0; 37405+ 37406+fail: 37407+ clk_disable_unprepare(host->clk); 37408+ nand_release(mtd); 37409+ return result; 37410+} 37411+ 37412+static int hisi_nand_os_remove(struct platform_device *pltdev) 37413+{ 37414+ struct hifmc_host *host = platform_get_drvdata(pltdev); 37415+ 37416+ clk_disable_unprepare(host->clk); 37417+ nand_release(host->mtd); 37418+ 37419+ return 0; 37420+} 37421+ 37422+#ifdef CONFIG_PM 37423+static int hifmc100_nand_os_suspend(struct platform_device *pltdev, 37424+ pm_message_t state) 37425+{ 37426+ struct hifmc_host *host = platform_get_drvdata(pltdev); 37427+ struct device *dev = &pltdev->dev; 37428+ if (!host || !host->clk) { 37429+ dev_err(dev,"host or host->clk is null err\n"); 37430+ return 0; 37431+ } 37432+ 37433+ while ((hifmc_readl(host, FMC_OP) & FMC_OP_REG_OP_START)) { 37434+ _cond_resched(); 37435+ } 37436+ 37437+ while ((hifmc_readl(host, FMC_OP_CTRL) & OP_CTRL_DMA_OP_READY)) { 37438+ _cond_resched(); 37439+ } 37440+ 37441+ clk_disable_unprepare(host->clk); 37442+ FMC_PR(PM_DBG, "\t|-disable system clock\n"); 37443+ return 0; 37444+} 37445+ 37446+static int hifmc100_nand_os_resume(struct platform_device *pltdev) 37447+{ 37448+ int cs; 37449+ struct hifmc_host *host = platform_get_drvdata(pltdev); 37450+ struct nand_chip *chip = NULL; 37451+ 37452+ if (!host) { 37453+ return 0; 37454+ } 37455+ chip = host->chip; 37456+ 37457+ for (cs = 0; cs < chip->numchips; cs++) { 37458+ host->send_cmd_reset(host); 37459+ } 37460+ 37461+ hifmc100_nand_config(host); 37462+ return 0; 37463+} 37464+#endif /* CONFIG_PM */ 37465+ 37466+static const struct of_device_id hisi_nand_dt_ids[] = { 37467+ { .compatible = "hisilicon,hisi_nand" }, 37468+ { } /* sentinel */ 37469+}; 37470+MODULE_DEVICE_TABLE(of, hisi_nand_dt_ids); 37471+ 37472+static struct platform_driver hisi_nand_driver = { 37473+ .driver = { 37474+ .name = "hisi_nand", 37475+ .of_match_table = hisi_nand_dt_ids, 37476+ }, 37477+ .probe = hisi_nand_os_probe, 37478+ .remove = hisi_nand_os_remove, 37479+#ifdef CONFIG_PM 37480+ .suspend = hifmc100_nand_os_suspend, 37481+ .resume = hifmc100_nand_os_resume, 37482+#endif 37483+}; 37484+module_platform_driver(hisi_nand_driver); 37485+ 37486+MODULE_LICENSE("GPL"); 37487+MODULE_AUTHOR("BVT_BSP"); 37488+MODULE_DESCRIPTION("Hisilicon Flash Memory Controller V100 Nand Driver"); 37489diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.h b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.h 37490new file mode 100644 37491index 000000000..a27813530 37492--- /dev/null 37493+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.h 37494@@ -0,0 +1,72 @@ 37495+/* 37496+ * The Flash Memory Controller v100 Device Driver for hisilicon 37497+ * 37498+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 37499+ * 37500+ * This program is free software; you can redistribute it and/or modify it 37501+ * under the terms of the GNU General Public License as published by the 37502+ * Free Software Foundation; either version 2 of the License, or (at your 37503+ * option) any later version. 37504+ * 37505+ * This program is distributed in the hope that it will be useful, 37506+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 37507+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37508+ * GNU General Public License for more details. 37509+ * 37510+ * You should have received a copy of the GNU General Public License 37511+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 37512+ * 37513+ */ 37514+ 37515+#ifndef __HIFMC100_NAND_OS_H__ 37516+#define __HIFMC100_NAND_OS_H__ 37517+ 37518+#include <linux/init.h> 37519+#include <linux/module.h> 37520+#include <linux/mtd/mtd.h> 37521+#include <linux/mtd/nand.h> 37522+#include <linux/mtd/rawnand.h> 37523+#include <linux/mtd/partitions.h> 37524+#include <linux/delay.h> 37525+#include <linux/dma-mapping.h> 37526+#include <linux/sched.h> 37527+#include <asm/errno.h> 37528+#include <asm/setup.h> 37529+#include <linux/io.h> 37530+#include <linux/version.h> 37531+#include <linux/kernel.h> 37532+#include <linux/platform_device.h> 37533+ 37534+#include <linux/resource.h> 37535+#include <linux/clk.h> 37536+#include <linux/clkdev.h> 37537+ 37538+#if (KERNEL_VERSION(3, 4, 5) <= LINUX_VERSION_CODE) 37539+#include "../../mtdcore.h" 37540+#endif 37541+ 37542+ 37543+#define DEFAULT_NAND_PAGESIZE 2048 37544+#define DEFAULT_NAND_OOBSIZE 64 37545+ 37546+#define NAND_BUFFER_LEN (DEFAULT_NAND_PAGESIZE + DEFAULT_NAND_OOBSIZE) 37547+ 37548+ 37549+#ifndef CONFIG_RW_H_WIDTH 37550+#define CONFIG_RW_H_WIDTH (10) 37551+#warning NOT config CONFIG_RW_H_WIDTH, used default value, maybe invalid. 37552+#endif 37553+ 37554+#ifndef CONFIG_R_L_WIDTH 37555+#define CONFIG_R_L_WIDTH (10) 37556+#warning NOT config CONFIG_R_L_WIDTH, used default value, maybe invalid. 37557+#endif 37558+ 37559+#ifndef CONFIG_W_L_WIDTH 37560+#define CONFIG_W_L_WIDTH (10) 37561+#warning NOT config CONFIG_W_L_WIDTH, used default value, maybe invalid. 37562+#endif 37563+ 37564+extern void hifmc100_nand_controller_enable(int enable); 37565+ 37566+#endif /* End of __HIFMC100_NAND_OS_H__ */ 37567diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc_nand_spl_ids.c b/drivers/mtd/nand/hifmc100_nand/hifmc_nand_spl_ids.c 37568new file mode 100644 37569index 000000000..b03510a44 37570--- /dev/null 37571+++ b/drivers/mtd/nand/hifmc100_nand/hifmc_nand_spl_ids.c 37572@@ -0,0 +1,982 @@ 37573+/* 37574+ * The Flash Memory Controller v100 Device Driver for hisilicon 37575+ * 37576+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 37577+ * 37578+ * This program is free software; you can redistribute it and/or modify it 37579+ * under the terms of the GNU General Public License as published by the 37580+ * Free Software Foundation; either version 2 of the License, or (at your 37581+ * option) any later version. 37582+ * 37583+ * This program is distributed in the hope that it will be useful, 37584+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 37585+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37586+ * GNU General Public License for more details. 37587+ * 37588+ * You should have received a copy of the GNU General Public License 37589+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 37590+ * 37591+ */ 37592+ 37593+#include <asm/setup.h> 37594+#include <linux/mtd/nand.h> 37595+#include <linux/mfd/hisi_fmc.h> 37596+#include <linux/uaccess.h> 37597+ 37598+#include "../raw/hinfc_gen.h" 37599+#include "hifmc100_nand.h" 37600+ 37601+ 37602+#define _768K (_256K + _512K) 37603+ 37604+ 37605+struct nand_flash_special_dev { 37606+ unsigned char id[8]; 37607+ int length; /* length of id. */ 37608+ unsigned long long chipsize; 37609+ struct nand_flash_dev *(*probe)(unsigned char *id); 37610+ char *name; 37611+ 37612+ unsigned long pagesize; 37613+ unsigned long erasesize; 37614+ unsigned long oobsize; 37615+ unsigned long options; 37616+ unsigned int read_retry_type; 37617+ 37618+#define BBP_LAST_PAGE 0x01 37619+#define BBP_FIRST_PAGE 0x02 37620+ unsigned int badblock_pos; 37621+ int flags; 37622+}; 37623+ 37624+ 37625+/* this is nand probe function. */ 37626+ 37627+ 37628+static struct nand_flash_dev *hynix_probe_v02(unsigned char *id) 37629+{ 37630+ struct nand_flash_dev *type = &g_nand_dev.flash_dev; 37631+ 37632+ int pagesizes[] = {_2K, _4K, _8K, 0}; 37633+ int oobsizes[] = {128, 224, 448, 0, 0, 0, 0, 0}; 37634+ int blocksizes[] = {_128K, _256K, _512K, _768K, _1M, _2M, 0, 0}; 37635+ 37636+ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); 37637+ int oobtype = (((id[3] >> 2) & 0x03) | ((id[3] >> 4) & 0x04)); 37638+ 37639+ type->options = 0; 37640+ type->pagesize = pagesizes[(id[3] & 0x03)]; 37641+ type->erasesize = blocksizes[blocktype]; 37642+ type->oobsize = oobsizes[oobtype]; 37643+ 37644+ return type; 37645+} 37646+ 37647+ 37648+static struct nand_flash_dev *samsung_probe_v02(unsigned char *id) 37649+{ 37650+ struct nand_flash_dev *type = &g_nand_dev.flash_dev; 37651+ 37652+ int pagesizes[] = {_2K, _4K, _8K, 0}; 37653+ int oobsizes[] = {0, 128, 218, 400, 436, 0, 0, 0}; 37654+ int blocksizes[] = {_128K, _256K, _512K, _1M, 0, 0, 0, 0}; 37655+ 37656+ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); 37657+ int oobtype = (((id[3] >> 4) & 0x04) | ((id[3] >> 2) & 0x03)); 37658+ 37659+ type->options = 0; 37660+ type->pagesize = pagesizes[(id[3] & 0x03)]; 37661+ type->erasesize = blocksizes[blocktype]; 37662+ type->oobsize = oobsizes[oobtype]; 37663+ 37664+ return type; 37665+} 37666+ 37667+#define DRV_VERSION "1.40" 37668+ 37669+/* 37670+ * samsung: 27nm need randomizer, 21nm need read retry; 37671+ * micron: 25nm need read retry, datasheet will explain read retry. 37672+ * toshaba 32nm need randomizer, 24nm need read retry. 37673+ * hynix: 2xnm need read retry. 37674+ * 37675+ * The special nand flash ID table version 1.39 37676+ * 37677+ * manufactory | type | name | ecc_type | version_tag 37678+ * Micron | MLC | MT29F64G08CBABA | 40bit/1k | 1.36 37679+ * Micron | MLC | MT29F32G08CBADA | 40bit/1k | 37680+ * Micron | SLC | MT29F8G08ABxBA | 4bit/512 | 37681+ * Micron | MLC | MT29F16G08CBABx | 12bit/512 | 37682+ * Micron | MLC | MT29F16G08CBACA | 24bit/1k | 37683+ * Micron | MLC | MT29F32G08CBACA | 24bit/1k | 37684+ * Micron | MLC | MT29F64G08CxxAA | 24bit/1k | 37685+ * Micron | MLC | MT29F256G08CJAAA | 24bit/1k | 2CE 37686+ * Micron | MLC | MT29F256G08CMCBB | 24bit/1k | 37687+ * Micron | SLC | MT29F8G08ABACA | 8bit/512 | 37688+ * Micron | SLC | MT29F4G08ABAEA | 8bit/512 | 37689+ * Micron | SLC | MT29F2G08ABAFA | 8bit/512 | 37690+ * Micron | SLC | MT29F16G08ABACA | 8bit/512 | 37691+ * Toshiba | MLC | TC58NVG4D2FTA00 | 24bit/1k | 37692+ * Toshiba | MLC | TH58NVG6D2FTA20 | 24bit/1k | 2CE 37693+ * Toshiba | MLC | TC58NVG5D2HTA00 | 40bit/1k | 37694+ * Toshiba | MLC | TC58NVG6D2GTA00 | 40bit/1k | 37695+ * Toshiba | MLC | TC58NVG6DCJTA00 | | 37696+ * Toshiba | MLC | TC58TEG5DCJTA00 | | 37697+ * Toshiba | SLC | TC58NVG0S3HTA00 | 8bit/512 | 37698+ * Toshiba | SLC | TC58NVG1S3HTA00 | 8bit/512 | 37699+ * Toshiba | SLC | TC58NVG1S3ETA00 | 4bit/512 | 37700+ * Toshiba | SLC | TC58NVG3S0FTA00 | 4bit/512 | 37701+ * Toshiba | SLC | TC58NVG2S0FTA00 | 4bit/512 | 37702+ * Toshiba | SLC | TH58NVG2S3HTA00 | 4bit/512 | 37703+ * Toshiba | TLC | TC58NVG5T2JTA00 | 60bit/1k | 37704+ * Toshiba | TLC | TC58TEG5DCKTAx0 | 60bit/1k | 37705+ * Toshiba | MLC | Tx58TEGxDDKTAx0 | | 37706+ * Samsung | MLC | K9LB(HC/PD/MD)G08U0(1)D | 8bit/512B | 37707+ * Samsung | MLC | K9GAG08U0E | 24bit/1KB | 37708+ * Samsung | MLC | K9LBG08U0E | 24bit/1KB | 37709+ * Samsung | MLC | K9G8G08U0C | 24bit/1KB | 37710+ * Samsung | MLC | K9GAG08U0F | 24bit/1KB | 37711+ * Samsung | MLC | K9LBG08U0M | | 37712+ * Samsung | MLC | K9GBG08U0A | 24bit/1KB | 37713+ * Samsung | MLC | K9GBG08U0B | 40bit/1KB | 37714+ * Hynix | MLC | H27UAG8T2A | | 37715+ * Hynix | MLC | H27UAG8T2B | | 37716+ * Hynix | MLC | H27UBG8T2A | | 37717+ * Hynix | MLC | H27UBG8T2BTR | 24bit/1KB | 37718+ * Hynix | MLC | H27UCG8T2A | 40bit/1KB | 37719+ * Hynix | MLC | H27UBG8T2C | 40bit/1KB | 37720+ * MISC | MLC | P1UAGA30AT-GCA | 8bit/512 | 37721+ * MISC | MLC | PSU8GA30AT-GIA/ASU8GA30IT-G30CA | 4bit/512 | 37722+ * MISC | SLC | PSU2GA30AT | 1bit/512 | 1.36 37723+ * Toshiba | SLC | TC58NVG2S0HTA00 | 24bit/1K | 1.37 37724+ * Toshiba | SLC | TC58NVG3S0HTA00 | 24bit/1K | 1.37 37725+ * Micron | SLC | MT29F2G08ABAEA | 4bit/512 | 37726+ * Spansion | SLC | S34ML02G200TFI000 | 24bit/1K | 37727+ * Spansion | SLC | S34ML04G200TFI000 | 24bit/1K | 1.38 37728+ * MXIC Macronix| SLC | MX30UF2G18AC 1.8V | 4bit/512 | 1.39 37729+ * Spansion | SLC | S34MS01G200TFI00 1.8V | 4bit/512 | 1.40 37730+ * Spansion | SLC | S34MS02G200TFI00 1.8V | 24bit/1K | 1.40 37731+ * Spansion | SLC | S34MS04G200TFI00 1.8V | 24bit/1K | 1.40 37732+ * 37733+ */ 37734+static struct nand_flash_special_dev nand_flash_special_table[] = { 37735+ 37736+ /************************* 1.8V MXIC Macronix **************************/ 37737+ { /* SLC 4bit/512 1.8V */ 37738+ .name = "MX30UF2G18AC", 37739+ .id = {0xC2, 0xAA, 0x90, 0x15, 0x06}, 37740+ .length = 5, 37741+ .chipsize = _256M, 37742+ .probe = NULL, 37743+ .pagesize = _2K, 37744+ .erasesize = _128K, 37745+ .oobsize = 64, 37746+ .options = 0, 37747+ .read_retry_type = NAND_RR_NONE, 37748+ .badblock_pos = BBP_FIRST_PAGE, 37749+ .flags = 0, 37750+ }, 37751+ 37752+ /****************************** Spansion *******************************/ 37753+ 37754+ { /* SLC S34ML02G200TFI000 */ 37755+ .name = "S34ML02G200TFI000", 37756+ .id = {0x01, 0xDA, 0x90, 0x95, 0x46, 0x00, 0x00, 0x00}, 37757+ .length = 5, 37758+ .chipsize = _256M, 37759+ .probe = NULL, 37760+ .pagesize = _2K, 37761+ .erasesize = _128K, 37762+ .oobsize = 128, 37763+ .options = 0, 37764+ .read_retry_type = NAND_RR_NONE, 37765+ .badblock_pos = BBP_FIRST_PAGE, 37766+ .flags = 0, 37767+ }, 37768+ 37769+ { /* SLC S34ML04G200TFI000 */ 37770+ .name = "S34ML04G200TFI000", 37771+ .id = {0x01, 0xDC, 0x90, 0x95, 0x56, 0x00, 0x00, 0x00}, 37772+ .length = 5, 37773+ .chipsize = _512M, 37774+ .probe = NULL, 37775+ .pagesize = _2K, 37776+ .erasesize = _128K, 37777+ .oobsize = 128, 37778+ .options = 0, 37779+ .read_retry_type = NAND_RR_NONE, 37780+ .badblock_pos = BBP_FIRST_PAGE, 37781+ .flags = 0, 37782+ }, 37783+ 37784+ { /* SLC S34MS02G200TFI00 1.8V */ 37785+ .name = "S34MS02G200TFI00", 37786+ .id = {0x01, 0xAA, 0x90, 0x15, 0x46, 0x00, 0x00, 0x00}, 37787+ .length = 5, 37788+ .chipsize = _256M, 37789+ .probe = NULL, 37790+ .pagesize = _2K, 37791+ .erasesize = _128K, 37792+ .oobsize = 128, 37793+ .options = 0, 37794+ .read_retry_type = NAND_RR_NONE, 37795+ .badblock_pos = BBP_FIRST_PAGE, 37796+ .flags = 0, 37797+ }, 37798+ 37799+ { /* SLC S34MS04G200TFI00 1.8V */ 37800+ .name = "S34MS04G200TFI00", 37801+ .id = {0x01, 0xAC, 0x90, 0x15, 0x56, 0x00, 0x00, 0x00}, 37802+ .length = 5, 37803+ .chipsize = _512M, 37804+ .probe = NULL, 37805+ .pagesize = _2K, 37806+ .erasesize = _128K, 37807+ .oobsize = 128, 37808+ .options = 0, 37809+ .read_retry_type = NAND_RR_NONE, 37810+ .badblock_pos = BBP_FIRST_PAGE, 37811+ .flags = 0, 37812+ }, 37813+ 37814+ /****************************** Micron *******************************/ 37815+ 37816+ { /* MLC 40bit/1k */ 37817+ .name = "MT29F64G08CBABA", 37818+ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 37819+ .length = 8, 37820+ .chipsize = _8G, 37821+ .probe = NULL, 37822+ .pagesize = _8K, 37823+ .erasesize = _2M, 37824+ .oobsize = 744, 37825+ .options = 0, 37826+ .read_retry_type = NAND_RR_MICRON, 37827+ .badblock_pos = BBP_FIRST_PAGE, 37828+ .flags = NAND_RANDOMIZER | NAND_CHIP_MICRON, 37829+ }, 37830+ { /* MLC 40bit/1k */ 37831+ .name = "MT29F32G08CBADA", 37832+ .id = {0x2C, 0x44, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 37833+ .length = 8, 37834+ .chipsize = _4G, 37835+ .probe = NULL, 37836+ .pagesize = _8K, 37837+ .erasesize = _2M, 37838+ .oobsize = 744, 37839+ .options = 0, 37840+ .read_retry_type = NAND_RR_MICRON, 37841+ .badblock_pos = BBP_FIRST_PAGE, 37842+ .flags = NAND_RANDOMIZER, 37843+ }, 37844+ { /* SLC 4bit/512 */ 37845+ .name = "MT29F8G08ABxBA", 37846+ .id = {0x2C, 0x38, 0x00, 0x26, 0x85, 0x00, 0x00, 0x00}, 37847+ .length = 8, 37848+ .chipsize = _1G, 37849+ .probe = NULL, 37850+ .pagesize = _4K, 37851+ .erasesize = _512K, 37852+ .oobsize = 224, 37853+ .options = 0, 37854+ .read_retry_type = NAND_RR_NONE, 37855+ .badblock_pos = BBP_FIRST_PAGE, 37856+ .flags = 0, 37857+ }, 37858+ { /* MLC 12bit/512 */ 37859+ .name = "MT29F16G08CBABx", 37860+ .id = {0x2C, 0x48, 0x04, 0x46, 0x85, 0x00, 0x00, 0x00}, 37861+ .length = 8, 37862+ .chipsize = _2G, 37863+ .probe = NULL, 37864+ .pagesize = _4K, 37865+ .erasesize = _1M, 37866+ .oobsize = 224, 37867+ .options = 0, 37868+ .read_retry_type = NAND_RR_NONE, 37869+ .badblock_pos = BBP_FIRST_PAGE, 37870+ .flags = 0, 37871+ }, 37872+ { /* MLC 24bit/1k */ 37873+ .name = "MT29F16G08CBACA", 37874+ .id = {0x2C, 0x48, 0x04, 0x4A, 0xA5, 0x00, 0x00, 0x00}, 37875+ .length = 8, 37876+ .chipsize = _2G, 37877+ .probe = NULL, 37878+ .pagesize = _4K, 37879+ .erasesize = _1M, 37880+ .oobsize = 224, 37881+ .options = 0, 37882+ .read_retry_type = NAND_RR_NONE, 37883+ .badblock_pos = BBP_FIRST_PAGE, 37884+ .flags = 0, 37885+ }, 37886+ { /* MLC 24bit/1k */ 37887+ .name = "MT29F32G08CBACA", 37888+ .id = {0x2C, 0x68, 0x04, 0x4A, 0xA9, 0x00, 0x00, 0x00}, 37889+ .length = 8, 37890+ .chipsize = _4G, 37891+ .probe = NULL, 37892+ .pagesize = _4K, 37893+ .erasesize = _1M, 37894+ .oobsize = 224, 37895+ .options = 0, 37896+ .read_retry_type = NAND_RR_NONE, 37897+ .badblock_pos = BBP_FIRST_PAGE, 37898+ .flags = 0, 37899+ }, 37900+ { /* MLC 24bit/1k */ 37901+ .name = "MT29F64G08CxxAA", 37902+ .id = {0x2C, 0x88, 0x04, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 37903+ .length = 8, 37904+ .chipsize = _8G, 37905+ .probe = NULL, 37906+ .pagesize = _8K, 37907+ .erasesize = _2M, 37908+ .oobsize = 448, 37909+ .options = 0, 37910+ .read_retry_type = NAND_RR_NONE, 37911+ .badblock_pos = BBP_FIRST_PAGE, 37912+ .flags = NAND_RANDOMIZER, 37913+ }, 37914+ { /* MLC 24bit/1k 2CE */ 37915+ .name = "MT29F256G08CJAAA", 37916+ .id = {0x2C, 0xA8, 0x05, 0xCB, 0xA9, 0x00, 0x00, 0x00}, 37917+ .length = 8, 37918+ .chipsize = _16G, 37919+ .probe = NULL, 37920+ .pagesize = _8K, 37921+ .erasesize = _2M, 37922+ .oobsize = 448, 37923+ .options = 0, 37924+ .read_retry_type = NAND_RR_NONE, 37925+ .badblock_pos = BBP_FIRST_PAGE, 37926+ .flags = NAND_RANDOMIZER, 37927+ }, 37928+ { /* MLC 40bit/1k */ 37929+ .name = "MT29F256G08CMCBB", 37930+ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 37931+ .length = 8, 37932+ .chipsize = _8G, 37933+ .probe = NULL, 37934+ .pagesize = _8K, 37935+ .erasesize = _2M, 37936+ .oobsize = 744, 37937+ .options = 0, 37938+ .read_retry_type = NAND_RR_NONE, 37939+ .badblock_pos = BBP_FIRST_PAGE, 37940+ .flags = 0, 37941+ }, 37942+ { /* SLC 8bit/512 */ 37943+ .name = "MT29F8G08ABACA", 37944+ .id = {0x2C, 0xD3, 0x90, 0xA6, 0x64, 0x00, 0x00, 0x00}, 37945+ .length = 5, 37946+ .chipsize = _1G, 37947+ .probe = NULL, 37948+ .pagesize = _4K, 37949+ .erasesize = _256K, 37950+ .oobsize = 224, 37951+ .options = 0, 37952+ .read_retry_type = NAND_RR_NONE, 37953+ .badblock_pos = BBP_FIRST_PAGE, 37954+ .flags = 0, 37955+ }, 37956+ { /* SLC 8bit/512 */ 37957+ .name = "MT29F4G08ABAEA", 37958+ .id = {0x2C, 0xDC, 0x90, 0xA6, 0x54, 0x00, 0x00, 0x00}, 37959+ .length = 5, 37960+ .chipsize = _512M, 37961+ .probe = NULL, 37962+ .pagesize = _4K, 37963+ .erasesize = _256K, 37964+ .oobsize = 224, 37965+ .options = 0, 37966+ .read_retry_type = NAND_RR_NONE, 37967+ .badblock_pos = BBP_FIRST_PAGE, 37968+ .flags = 0, 37969+ }, 37970+ { /* SLC 8bit/512 */ 37971+ .name = "MT29F2G08ABAFA", 37972+ .id = {0x2C, 0xDA, 0x90, 0x95, 0x04, 0x00, 0x00, 0x00}, 37973+ .length = 5, 37974+ .chipsize = _256M, 37975+ .probe = NULL, 37976+ .pagesize = _2K, 37977+ .erasesize = _128K, 37978+ .oobsize = 224, 37979+ .options = 0, 37980+ .read_retry_type = NAND_RR_NONE, 37981+ .badblock_pos = BBP_FIRST_PAGE, 37982+ .flags = 0, 37983+ }, 37984+ { /* SLC MT29F2G08ABAEA */ 37985+ .name = "MT29F2G08ABAEA", 37986+ .id = {0x2C, 0xDA, 0x90, 0x95, 0x06, 0x00, 0x00, 0x00}, 37987+ .length = 5, 37988+ .chipsize = _256M, 37989+ .probe = NULL, 37990+ .pagesize = _2K, 37991+ .erasesize = _128K, 37992+ .oobsize = 64, 37993+ .options = 0, 37994+ .read_retry_type = NAND_RR_NONE, 37995+ .badblock_pos = BBP_FIRST_PAGE, 37996+ .flags = 0, 37997+ }, 37998+ { /* SLC 8bit/512 */ 37999+ .name = "MT29F16G08ABACA", 38000+ .id = {0x2C, 0x48, 0x00, 0x26, 0xA9, 0x00, 0x00, 0x00}, 38001+ .length = 5, 38002+ .chipsize = _2G, 38003+ .probe = NULL, 38004+ .pagesize = _4K, 38005+ .erasesize = _512K, 38006+ .oobsize = 224, 38007+ .options = 0, 38008+ .read_retry_type = NAND_RR_NONE, 38009+ .badblock_pos = BBP_FIRST_PAGE, 38010+ .flags = 0, 38011+ }, 38012+ 38013+ /****************************** Toshaba *******************************/ 38014+ 38015+ { /* MLC 24bit/1k 32nm */ 38016+ .name = "TC58NVG4D2FTA00", 38017+ .id = {0x98, 0xD5, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, 38018+ .length = 6, 38019+ .chipsize = _2G, 38020+ .probe = NULL, 38021+ .pagesize = _8K, 38022+ .erasesize = _1M, 38023+ .oobsize = 448, 38024+ .options = 0, 38025+ .read_retry_type = NAND_RR_NONE, 38026+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38027+ .flags = 0, 38028+ }, 38029+ { /* MLC 24bit/1k 32nm 2CE */ 38030+ .name = "TH58NVG6D2FTA20", 38031+ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, 38032+ .length = 6, 38033+ .chipsize = _4G, 38034+ .probe = NULL, 38035+ .pagesize = _8K, 38036+ .erasesize = _1M, 38037+ .oobsize = 448, 38038+ .options = 0, 38039+ .read_retry_type = NAND_RR_NONE, 38040+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38041+ .flags = 0, 38042+ }, 38043+ { /* MLC 40bit/1k 24nm */ 38044+ .name = "TC58NVG5D2HTA00 24nm", 38045+ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x56, 0x08, 0x00}, 38046+ .length = 6, 38047+ .chipsize = _4G, 38048+ .probe = NULL, 38049+ .pagesize = _8K, 38050+ .erasesize = _1M, 38051+ .oobsize = 640, 38052+ .options = 0, 38053+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 38054+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38055+ .flags = NAND_RANDOMIZER, 38056+ }, 38057+ { /* MLC 40bit/1k */ 38058+ .name = "TC58NVG6D2GTA00", 38059+ .id = {0x98, 0xDE, 0x94, 0x82, 0x76, 0x00, 0x00, 0x00}, 38060+ .length = 5, 38061+ .chipsize = _8G, 38062+ .probe = NULL, 38063+ .pagesize = _8K, 38064+ .erasesize = _2M, 38065+ .oobsize = 640, 38066+ .options = 0, 38067+ .read_retry_type = NAND_RR_NONE, 38068+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38069+ .flags = 0, 38070+ }, 38071+ { /* MLC 19nm */ 38072+ .name = "TC58NVG6DCJTA00 19nm", 38073+ .id = {0x98, 0xDE, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, 38074+ .length = 8, 38075+ .chipsize = _8G, 38076+ .probe = NULL, 38077+ .pagesize = _16K, 38078+ .erasesize = _4M, 38079+ .oobsize = 1280, 38080+ .options = 0, 38081+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 38082+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38083+ .flags = NAND_RANDOMIZER, 38084+ }, 38085+ { /* MLC 19nm */ 38086+ .name = "TC58TEG5DCJTA00 19nm", 38087+ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, 38088+ .length = 6, 38089+ .chipsize = _4G, 38090+ .probe = NULL, 38091+ .pagesize = _16K, 38092+ .erasesize = _4M, 38093+ .oobsize = 1280, 38094+ .options = 0, 38095+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 38096+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38097+ .flags = NAND_RANDOMIZER | NAND_CHIP_TOSHIBA_TOGGLE_10, 38098+ }, 38099+ { /* SLC 8bit/512 */ 38100+ .name = "TC58NVG0S3HTA00", 38101+ .id = {0x98, 0xF1, 0x80, 0x15, 0x72, 0x00, 0x00, 0x00}, 38102+ .length = 5, 38103+ .chipsize = _128M, 38104+ .probe = NULL, 38105+ .pagesize = _2K, 38106+ .erasesize = _128K, 38107+ .oobsize = 128, 38108+ .options = 0, 38109+ .read_retry_type = NAND_RR_NONE, 38110+ /* 38111+ * Datasheet: read one column of any page in each block. If the 38112+ * data of the column is 00 (Hex), define the block as a bad 38113+ * block. 38114+ */ 38115+ .badblock_pos = BBP_FIRST_PAGE, 38116+ .flags = 0, 38117+ }, 38118+ { /* SLC 8bit/512 */ 38119+ .name = "TC58NVG1S3HTA00", 38120+ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x16, 0x08, 0x00}, 38121+ .length = 7, 38122+ .chipsize = _256M, 38123+ .probe = NULL, 38124+ .pagesize = _2K, 38125+ .erasesize = _128K, 38126+ .oobsize = 128, 38127+ .options = 0, 38128+ .read_retry_type = NAND_RR_NONE, 38129+ .badblock_pos = BBP_FIRST_PAGE, 38130+ .flags = 0, 38131+ }, 38132+ { /* SLC 4bit/512 */ 38133+ .name = "TC58NVG1S3ETA00", 38134+ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x14, 0x03, 0x00}, 38135+ .length = 7, 38136+ .chipsize = _256M, 38137+ .probe = NULL, 38138+ .pagesize = _2K, 38139+ .erasesize = _128K, 38140+ .oobsize = 64, 38141+ .options = 0, 38142+ .read_retry_type = NAND_RR_NONE, 38143+ .badblock_pos = BBP_FIRST_PAGE, 38144+ .flags = 0, 38145+ }, 38146+ { /* SLC 4bit/512 */ 38147+ .name = "TC58NVG3S0FTA00", 38148+ .id = {0x98, 0xD3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08}, 38149+ .length = 8, 38150+ .chipsize = _1G, 38151+ .probe = NULL, 38152+ .pagesize = _4K, 38153+ .erasesize = _256K, 38154+ .oobsize = 232, 38155+ .options = 0, 38156+ .read_retry_type = NAND_RR_NONE, 38157+ .badblock_pos = BBP_FIRST_PAGE, 38158+ .flags = 0, 38159+ }, 38160+ { /* SLC 24bit/1k */ 38161+ .name = "TC58NVG3S0HTA00", 38162+ .id = {0x98, 0xD3, 0x91, 0x26, 0x76, 0x16, 0x08, 0x00}, 38163+ .length = 8, 38164+ .chipsize = _1G, 38165+ .probe = NULL, 38166+ .pagesize = _4K, 38167+ .erasesize = _256K, 38168+ .oobsize = 256, 38169+ .options = 0, 38170+ .read_retry_type = NAND_RR_NONE, 38171+ .badblock_pos = BBP_FIRST_PAGE, 38172+ .flags = 0, 38173+ }, 38174+ { /* SLC 24bit/1k */ 38175+ .name = "TC58NVG2S0HTA00", 38176+ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00}, 38177+ .length = 8, 38178+ .chipsize = _512M, 38179+ .probe = NULL, 38180+ .pagesize = _4K, 38181+ .erasesize = _256K, 38182+ .oobsize = 256, 38183+ .options = 0, 38184+ .read_retry_type = NAND_RR_NONE, 38185+ .badblock_pos = BBP_FIRST_PAGE, 38186+ .flags = 0, 38187+ }, 38188+ { /* SLC 4bit/512 */ 38189+ .name = "TC58NVG2S0FTA00", 38190+ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08}, 38191+ .length = 8, 38192+ .chipsize = _512M, 38193+ .probe = NULL, 38194+ .pagesize = _4K, 38195+ .erasesize = _256K, 38196+ .oobsize = 224, 38197+ .options = 0, 38198+ .read_retry_type = NAND_RR_NONE, 38199+ .badblock_pos = BBP_FIRST_PAGE, 38200+ .flags = 0, 38201+ }, 38202+ { /* SLC 4bit/512 */ 38203+ .name = "TH58NVG2S3HTA00", 38204+ .id = {0x98, 0xDC, 0x91, 0x15, 0x76}, 38205+ .length = 5, 38206+ .chipsize = _512M, 38207+ .probe = NULL, 38208+ .pagesize = _2K, 38209+ .erasesize = _128K, 38210+ .oobsize = 128, 38211+ .options = 0, 38212+ .read_retry_type = NAND_RR_NONE, 38213+ .badblock_pos = BBP_FIRST_PAGE, 38214+ .flags = 0, 38215+ }, 38216+ { /* TLC 60bit/1k 19nm */ 38217+ .name = "TC58NVG5T2JTA00 19nm TLC", 38218+ /* datasheet says 6 ids id data, but really has 8 ids. */ 38219+ .id = {0x98, 0xD7, 0x98, 0x92, 0x72, 0x57, 0x08, 0x10}, 38220+ .length = 6, 38221+ .chipsize = _4G, 38222+ .probe = NULL, 38223+ .pagesize = _8K, 38224+ .erasesize = _4M, 38225+ .oobsize = 1024, 38226+ .options = 0, 38227+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 38228+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38229+ .flags = NAND_RANDOMIZER, 38230+ }, 38231+ { /* TLC 60bit/1k 19nm */ 38232+ .name = "TC58TEG5DCKTAx0 19nm MLC", 38233+ /* datasheet says 6 ids id data, but really has 8 ids. */ 38234+ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x50, 0x08, 0x04}, 38235+ .length = 6, 38236+ .chipsize = _4G, 38237+ .probe = NULL, 38238+ .pagesize = _16K, 38239+ .erasesize = _4M, 38240+ .oobsize = 1280, 38241+ .options = 0, 38242+ .read_retry_type = NAND_RR_TOSHIBA_19nm, 38243+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38244+ .flags = NAND_RANDOMIZER, 38245+ }, 38246+ { 38247+ .name = "Tx58TEGxDDKTAx0 19nm MLC", 38248+ .id = {0x98, 0xDE, 0x94, 0x93, 0x76, 0x50}, 38249+ .length = 6, 38250+ .chipsize = _4G, 38251+ .probe = NULL, 38252+ .pagesize = _16K, 38253+ .erasesize = _4M, 38254+ .oobsize = 1280, 38255+ .options = 0, 38256+ .read_retry_type = NAND_RR_TOSHIBA_19nm, 38257+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38258+ .flags = NAND_RANDOMIZER, 38259+ }, 38260+ /******************************* Samsung ******************************/ 38261+ { /* MLC 8bit/512B */ 38262+ .name = "K9LB(HC/PD/MD)G08U0(1)D", 38263+ .id = {0xEC, 0xD7, 0xD5, 0x29, 0x38, 0x41, 0x00, 0x00}, 38264+ .length = 6, 38265+ .chipsize = _4G, 38266+ .probe = samsung_probe_v02, 38267+ .read_retry_type = NAND_RR_NONE, 38268+ .badblock_pos = BBP_LAST_PAGE, 38269+ .flags = 0, 38270+ }, 38271+ { /* MLC 24bit/1KB */ 38272+ .name = "K9GAG08U0E", 38273+ .id = {0xEC, 0xD5, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, 38274+ .length = 6, 38275+ .chipsize = _2G, 38276+ .probe = samsung_probe_v02, 38277+ .read_retry_type = NAND_RR_NONE, 38278+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38279+ .flags = 0, 38280+ }, 38281+ { /* MLC 24bit/1KB */ 38282+ .name = "K9LBG08U0E", 38283+ .id = {0xEC, 0xD7, 0xC5, 0x72, 0x54, 0x42, 0x00, 0x00}, 38284+ .length = 6, 38285+ .chipsize = _4G, 38286+ .probe = samsung_probe_v02, 38287+ .read_retry_type = NAND_RR_NONE, 38288+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38289+ .flags = 0, 38290+ }, 38291+ { /* MLC 24bit/1KB */ 38292+ .name = "K9G8G08U0C", 38293+ .id = {0xEC, 0xD3, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, 38294+ .length = 6, 38295+ .chipsize = _1G, 38296+ .probe = samsung_probe_v02, 38297+ .read_retry_type = NAND_RR_NONE, 38298+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38299+ .flags = 0, 38300+ }, 38301+ { /* MLC 24bit/1k */ 38302+ .name = "K9GAG08U0F", 38303+ .id = {0xEC, 0xD5, 0x94, 0x76, 0x54, 0x43, 0x00, 0x00}, 38304+ .length = 6, 38305+ .chipsize = _2G, 38306+ .probe = NULL, 38307+ .pagesize = _8K, 38308+ .erasesize = _1M, 38309+ .oobsize = 512, 38310+ .options = 0, 38311+ .read_retry_type = NAND_RR_NONE, 38312+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38313+ .flags = 0, 38314+ }, 38315+ { /* MLC */ 38316+ .name = "K9LBG08U0M", 38317+ .id = {0xEC, 0xD7, 0x55, 0xB6, 0x78, 0x00, 0x00, 0x00}, 38318+ .length = 5, 38319+ .chipsize = _4G, 38320+ .probe = NULL, 38321+ .pagesize = _4K, 38322+ .erasesize = _512K, 38323+ .oobsize = 128, 38324+ .options = 0, 38325+ .read_retry_type = NAND_RR_NONE, 38326+ .badblock_pos = BBP_LAST_PAGE, 38327+ .flags = 0, 38328+ }, 38329+ { /* MLC 24bit/1k */ 38330+ .name = "K9GBG08U0A 20nm", 38331+ .id = {0xEC, 0xD7, 0x94, 0x7A, 0x54, 0x43, 0x00, 0x00}, 38332+ .length = 6, 38333+ .chipsize = _4G, 38334+ .probe = NULL, 38335+ .pagesize = _8K, 38336+ .erasesize = _1M, 38337+ .oobsize = 640, 38338+ .options = 0, 38339+ .read_retry_type = NAND_RR_SAMSUNG, 38340+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38341+ .flags = NAND_RANDOMIZER, 38342+ }, 38343+ { /* MLC 40bit/1k */ 38344+ .name = "K9GBG08U0B", 38345+ .id = {0xEC, 0xD7, 0x94, 0x7E, 0x64, 0x44, 0x00, 0x00}, 38346+ .length = 6, 38347+ .chipsize = _4G, 38348+ .probe = NULL, 38349+ .pagesize = _8K, 38350+ .erasesize = _1M, 38351+ .oobsize = 1024, 38352+ .options = 0, 38353+ .read_retry_type = NAND_RR_SAMSUNG, 38354+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38355+ .flags = NAND_RANDOMIZER, 38356+ }, 38357+ 38358+ /*********************************** Hynix ****************************/ 38359+ { /* MLC */ 38360+ .name = "H27UAG8T2A", 38361+ .id = { 0xAD, 0xD5, 0x94, 0x25, 0x44, 0x41, }, 38362+ .length = 6, 38363+ .chipsize = _2G, 38364+ .probe = hynix_probe_v02, 38365+ .read_retry_type = NAND_RR_NONE, 38366+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38367+ .flags = 0, 38368+ }, 38369+ { /* MLC */ 38370+ .name = "H27UAG8T2B", 38371+ .id = { 0xAD, 0xD5, 0x94, 0x9A, 0x74, 0x42, }, 38372+ .length = 6, 38373+ .chipsize = _2G, 38374+ .probe = hynix_probe_v02, 38375+ .read_retry_type = NAND_RR_NONE, 38376+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38377+ .flags = 0, 38378+ }, 38379+ { /* MLC */ 38380+ .name = "H27UBG8T2A", 38381+ .id = { 0xAD, 0xD7, 0x94, 0x9A, 0x74, 0x42, }, 38382+ .length = 6, 38383+ .chipsize = _4G, 38384+ .probe = hynix_probe_v02, 38385+ .read_retry_type = NAND_RR_NONE, 38386+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38387+ .flags = 0, 38388+ }, 38389+ { 38390+ .name = "H27UBG8T2BTR 26nm", 38391+ .id = { 0xAD, 0xD7, 0x94, 0xDA, 0x74, 0xC3, }, 38392+ .length = 6, 38393+ .chipsize = _4G, 38394+ .probe = NULL, 38395+ .pagesize = _8K, 38396+ .erasesize = _2M, 38397+ .oobsize = 640, 38398+ .options = 0, 38399+ .read_retry_type = NAND_RR_HYNIX_BG_BDIE, 38400+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38401+ .flags = NAND_RANDOMIZER, 38402+ }, 38403+ { /* MLC 40bit/1k */ 38404+ .name = "H27UCG8T2A", 38405+ .id = { 0xAD, 0xDE, 0x94, 0xDA, 0x74, 0xC4, }, 38406+ .length = 6, 38407+ .chipsize = _8G, 38408+ .probe = NULL, 38409+ .pagesize = _8K, 38410+ .erasesize = _2M, 38411+ .oobsize = 640, 38412+ .options = 0, 38413+ .read_retry_type = NAND_RR_HYNIX_CG_ADIE, 38414+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38415+ .flags = NAND_RANDOMIZER, 38416+ }, 38417+ { /* MLC 40bit/1k */ 38418+ .name = "H27UBG8T2C", 38419+ .id = { 0xAD, 0xD7, 0x94, 0x91, 0x60, 0x44, }, 38420+ .length = 6, 38421+ .chipsize = _4G, 38422+ .probe = NULL, 38423+ .pagesize = _8K, 38424+ .erasesize = _2M, 38425+ .oobsize = 640, 38426+ .options = 0, 38427+ .read_retry_type = NAND_RR_HYNIX_BG_CDIE, 38428+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38429+ .flags = NAND_RANDOMIZER, 38430+ }, 38431+ 38432+ /********************** MISC ******************************************/ 38433+ { /* MLC 8bit/512 */ 38434+ .name = "P1UAGA30AT-GCA", 38435+ .id = { 0xC8, 0xD5, 0x14, 0x29, 0x34, 0x01, }, 38436+ .length = 6, 38437+ .chipsize = _2G, 38438+ .probe = NULL, 38439+ .pagesize = _4K, 38440+ .erasesize = _512K, 38441+ .oobsize = 218, 38442+ .options = 0, 38443+ .read_retry_type = NAND_RR_NONE, 38444+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38445+ .flags = 0, 38446+ }, 38447+ { /* MLC 4bit/512 */ 38448+ /* 38449+ * PowerFlash ASU8GA30IT-G30CA ID and MIRA PSU8GA30AT-GIA ID are 38450+ * the same ID 38451+ */ 38452+ .name = "PSU8GA30AT-GIA/ASU8GA30IT-G30CA", 38453+ .id = { 0xC8, 0xD3, 0x90, 0x19, 0x34, 0x01, }, 38454+ .length = 6, 38455+ .chipsize = _1G, 38456+ .probe = NULL, 38457+ .pagesize = _4K, 38458+ .erasesize = _256K, 38459+ .oobsize = 218, 38460+ .options = 0, 38461+ .read_retry_type = NAND_RR_NONE, 38462+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38463+ .flags = 0, 38464+ }, 38465+ { /* SLC 1bit/512 */ 38466+ .name = "PSU2GA30AT", 38467+ .id = { 0x7F, 0x7F, 0x7F, 0x7F, 0xC8, 0xDA, 0x00, 0x15, }, 38468+ .length = 8, 38469+ .chipsize = _256M, 38470+ .probe = NULL, 38471+ .pagesize = _2K, 38472+ .erasesize = _128K, 38473+ .oobsize = 64, 38474+ .options = 0, 38475+ .read_retry_type = NAND_RR_NONE, 38476+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 38477+ .flags = 0, 38478+ }, 38479+ {{0}, 0, 0, 0, 0, 0, 0, 0, 0}, 38480+}; 38481+ 38482+struct nand_dev_t g_nand_dev; 38483+ 38484+struct nand_flash_dev *hifmc_get_spl_flash_type(struct mtd_info *mtd, 38485+ unsigned char *id) 38486+{ 38487+ struct nand_chip *chip = mtd_to_nand(mtd); 38488+ struct nand_flash_special_dev *spl_dev = nand_flash_special_table; 38489+ struct nand_flash_dev *type = &g_nand_dev.flash_dev; 38490+ struct nand_dev_t *nand_dev = &g_nand_dev; 38491+ 38492+ FMC_PR(BT_DBG, "\t *-Start find special nand flash\n"); 38493+ 38494+ pr_info("Nand ID: %#X %#X %#X %#X %#X %#X %#X %#X\n", id[0], id[1], 38495+ id[2], id[3], id[4], id[5], id[6], id[7]); 38496+ 38497+ for (; spl_dev->length; spl_dev++) { 38498+ if (!access_ok(VERIFY_READ, id, spl_dev->length)) { 38499+ pr_info("err: access_ok verify fail\n"); 38500+ return NULL; 38501+ } 38502+ if (memcmp(id, spl_dev->id, spl_dev->length)) { 38503+ continue; 38504+ } 38505+ 38506+ FMC_PR(BT_DBG, "\t |-Found special Nand flash: %s\n", 38507+ spl_dev->name); 38508+ 38509+ if (spl_dev->probe) { 38510+ type = spl_dev->probe(id); 38511+ } else { 38512+ type->options = spl_dev->options; 38513+ type->pagesize = spl_dev->pagesize; 38514+ type->erasesize = spl_dev->erasesize; 38515+ type->oobsize = spl_dev->oobsize; 38516+ } 38517+ 38518+ type->name = spl_dev->name; 38519+ type->id_len = spl_dev->length; 38520+ memcpy(type->id, id, type->id_len); 38521+ type->chipsize = (unsigned int)(spl_dev->chipsize >> 20); 38522+ FMC_PR(BT_DBG, "\t |-Save struct nand_flash_dev info\n"); 38523+ 38524+ memcpy(nand_dev->ids, id, MAX_NAND_ID_LEN); 38525+ nand_dev->oobsize = type->oobsize; 38526+ nand_dev->flags = spl_dev->flags; 38527+ nand_dev->read_retry_type = spl_dev->read_retry_type; 38528+ FMC_PR(BT_DBG, "\t |-Save struct nand_dev_t information\n"); 38529+ 38530+ mtd->oobsize = spl_dev->oobsize; 38531+ mtd->erasesize = spl_dev->erasesize; 38532+ mtd->writesize = spl_dev->pagesize; 38533+ chip->chipsize = spl_dev->chipsize; 38534+ mtd->size = spl_dev->chipsize; 38535+ 38536+ return type; 38537+ } 38538+ nand_dev->read_retry_type = NAND_RR_NONE; 38539+ 38540+ chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); 38541+ chip->read_byte(mtd); 38542+ chip->read_byte(mtd); 38543+ 38544+ FMC_PR(BT_DBG, "\t *-Not found special nand flash\n"); 38545+ 38546+ return NULL; 38547+} 38548+ 38549+ 38550+void hifmc_spl_ids_register(void) 38551+{ 38552+ pr_info("Special NAND id table Version %s\n", DRV_VERSION); 38553+ get_spi_nand_flash_type_hook = hifmc_get_spl_flash_type; 38554+} 38555diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile 38556index 2930f5b90..7817ec61d 100644 38557--- a/drivers/mtd/nand/raw/Makefile 38558+++ b/drivers/mtd/nand/raw/Makefile 38559@@ -59,7 +59,7 @@ obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o 38560 obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o 38561 obj-$(CONFIG_MTD_NAND_ARASAN) += arasan-nand-controller.o 38562 38563-nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o 38564+nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o hinfc_gen.o hinfc_spl_ids.o match_table.o 38565 nand-objs += nand_onfi.o 38566 nand-objs += nand_jedec.o 38567 nand-objs += nand_amd.o 38568diff --git a/drivers/mtd/nand/raw/hinfc_gen.c b/drivers/mtd/nand/raw/hinfc_gen.c 38569new file mode 100644 38570index 000000000..127edd6b4 38571--- /dev/null 38572+++ b/drivers/mtd/nand/raw/hinfc_gen.c 38573@@ -0,0 +1,237 @@ 38574+/* 38575+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 38576+ * 38577+ * This program is free software; you can redistribute it and/or modify it 38578+ * under the terms of the GNU General Public License as published by the 38579+ * Free Software Foundation; either version 2 of the License, or (at your 38580+ * option) any later version. 38581+ * 38582+ * This program is distributed in the hope that it will be useful, 38583+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 38584+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 38585+ * GNU General Public License for more details. 38586+ * 38587+ * You should have received a copy of the GNU General Public License 38588+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 38589+ * 38590+ */ 38591+ 38592+#include <linux/mfd/hisi_fmc.h> 38593+#include "match_table.h" 38594+#include "hinfc_gen.h" 38595+ 38596+struct nand_flash_dev *(*get_spi_nand_flash_type_hook)(struct mtd_info *mtd, 38597+ unsigned char *id) = NULL; 38598+ 38599+static struct match_t match_ecc[] = { 38600+ MATCH_SET_TYPE_DATA(NAND_ECC_NONE, "none"), 38601+ MATCH_SET_TYPE_DATA(NAND_ECC_0BIT, "none"), 38602+ MATCH_SET_TYPE_DATA(NAND_ECC_1BIT_512, "1bit/512"), 38603+ MATCH_SET_TYPE_DATA(NAND_ECC_4BIT, "4bit/512"), 38604+ MATCH_SET_TYPE_DATA(NAND_ECC_4BIT_512, "4bit/512"), 38605+ MATCH_SET_TYPE_DATA(NAND_ECC_4BYTE, "4byte/1k"), 38606+ MATCH_SET_TYPE_DATA(NAND_ECC_8BIT, "4bit/512"), 38607+ MATCH_SET_TYPE_DATA(NAND_ECC_8BIT_512, "8bit/512"), 38608+ MATCH_SET_TYPE_DATA(NAND_ECC_8BYTE, "8byte/1k"), 38609+ MATCH_SET_TYPE_DATA(NAND_ECC_13BIT, "13bit/1k"), 38610+ MATCH_SET_TYPE_DATA(NAND_ECC_16BIT, "8bit/512"), 38611+ MATCH_SET_TYPE_DATA(NAND_ECC_18BIT, "18bit/1k"), 38612+ MATCH_SET_TYPE_DATA(NAND_ECC_24BIT, "24bit/1k"), 38613+ MATCH_SET_TYPE_DATA(NAND_ECC_27BIT, "27bit/1k"), 38614+ MATCH_SET_TYPE_DATA(NAND_ECC_32BIT, "32bit/1k"), 38615+ MATCH_SET_TYPE_DATA(NAND_ECC_40BIT, "40bit/1k"), 38616+ MATCH_SET_TYPE_DATA(NAND_ECC_41BIT, "41bit/1k"), 38617+ MATCH_SET_TYPE_DATA(NAND_ECC_48BIT, "48bit/1k"), 38618+ MATCH_SET_TYPE_DATA(NAND_ECC_60BIT, "60bit/1k"), 38619+ MATCH_SET_TYPE_DATA(NAND_ECC_72BIT, "72bit/1k"), 38620+ MATCH_SET_TYPE_DATA(NAND_ECC_80BIT, "80bit/1k"), 38621+}; 38622+ 38623+const char *nand_ecc_name(int type) 38624+{ 38625+ return (char *)match_type_to_data(match_ecc, ARRAY_SIZE(match_ecc), 38626+ type, "unknown"); 38627+} 38628+ 38629+char *get_ecctype_str(enum ecc_type ecctype) 38630+{ 38631+ static char *ecctype_string[] = { 38632+ "None", "1bit/512Byte", "4bits/512Byte", "8bits/512Byte", 38633+ "24bits/1K", "40bits/1K", "unknown", "unknown" 38634+ }; 38635+ return ecctype_string[(ecctype & 0x07)]; 38636+} 38637+ 38638+static struct match_type_str page2name[] = { 38639+ { NAND_PAGE_512B, "512" }, 38640+ { NAND_PAGE_2K, "2K" }, 38641+ { NAND_PAGE_4K, "4K" }, 38642+ { NAND_PAGE_8K, "8K" }, 38643+ { NAND_PAGE_16K, "16K" }, 38644+ { NAND_PAGE_32K, "32K" }, 38645+}; 38646+ 38647+const char *nand_page_name(int type) 38648+{ 38649+ return type2str(page2name, ARRAY_SIZE(page2name), type, "unknown"); 38650+} 38651+ 38652+char *get_pagesize_str(enum page_type pagetype) 38653+{ 38654+ static char *pagesize_str[] = { 38655+ "512", "2K", "4K", "8K", "16K", "unknown", 38656+ "unknown", "unknown" 38657+ }; 38658+ return pagesize_str[(pagetype & 0x07)]; 38659+} 38660+ 38661+static struct match_reg_type page2size[] = { 38662+ { _512B, NAND_PAGE_512B }, 38663+ { _2K, NAND_PAGE_2K }, 38664+ { _4K, NAND_PAGE_4K }, 38665+ { _8K, NAND_PAGE_8K }, 38666+ { _16K, NAND_PAGE_16K }, 38667+ { _32K, NAND_PAGE_32K }, 38668+}; 38669+ 38670+unsigned int get_pagesize(enum page_type pagetype) 38671+{ 38672+ unsigned int pagesize[] = { 38673+ _512B, _2K, _4K, _8K, _16K, 0, 0, 0 38674+ }; 38675+ return pagesize[(pagetype & 0x07)]; 38676+} 38677+ 38678+int nandpage_size2type(int size) 38679+{ 38680+ return reg2type(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K); 38681+} 38682+ 38683+int nandpage_type2size(int size) 38684+{ 38685+ return type2reg(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K); 38686+} 38687+ 38688+char *nand_dbgfs_options; 38689+ 38690+static int __init dbgfs_options_setup(char *s) 38691+{ 38692+ nand_dbgfs_options = s; 38693+ return 1; 38694+} 38695+__setup("nanddbgfs=", dbgfs_options_setup); 38696+ 38697+int get_bits(unsigned int n) 38698+{ 38699+ int loop; 38700+ int ret = 0; 38701+ 38702+ if (!n) 38703+ return 0; 38704+ 38705+ if (n > 0xFFFF) 38706+ loop = n > 0xFFFFFF ? 32 : 24; 38707+ else 38708+ loop = n > 0xFF ? 16 : 8; 38709+ 38710+ while (loop-- > 0 && n) { 38711+ if (n & 1) 38712+ ret++; 38713+ n >>= 1; 38714+ } 38715+ return ret; 38716+} 38717+ 38718+#define et_ecc_none 0x00 38719+#define et_ecc_4bit 0x02 38720+#define et_ecc_8bit 0x03 38721+#define et_ecc_24bit1k 0x04 38722+#define et_ecc_40bit1k 0x05 38723+#define et_ecc_64bit1k 0x06 38724+ 38725+static struct match_reg_type ecc_yaffs_type_t[] = { 38726+ {et_ecc_none, NAND_ECC_0BIT}, 38727+ {et_ecc_4bit, NAND_ECC_8BIT}, 38728+ {et_ecc_8bit, NAND_ECC_16BIT}, 38729+ {et_ecc_24bit1k, NAND_ECC_24BIT}, 38730+ {et_ecc_40bit1k, NAND_ECC_40BIT}, 38731+ {et_ecc_64bit1k, NAND_ECC_64BIT} 38732+}; 38733+ 38734+unsigned char match_ecc_type_to_yaffs(unsigned char type) 38735+{ 38736+ return type2reg(ecc_yaffs_type_t, ARRAY_SIZE(ecc_yaffs_type_t), type, 38737+ et_ecc_4bit); 38738+} 38739+ 38740+static struct match_t page_table[] = { 38741+ {NAND_PAGE_2K, PAGE_SIZE_2KB, "2K"}, 38742+ {NAND_PAGE_4K, PAGE_SIZE_4KB, "4K"}, 38743+ {NAND_PAGE_8K, PAGE_SIZE_8KB, "8K"}, 38744+ {NAND_PAGE_16K, PAGE_SIZE_16KB, "16K"}, 38745+}; 38746+ 38747+unsigned char match_page_reg_to_type(unsigned char reg) 38748+{ 38749+ return match_reg_to_type(page_table, ARRAY_SIZE(page_table), reg, 38750+ NAND_PAGE_2K); 38751+} 38752+ 38753+unsigned char match_page_type_to_reg(unsigned char type) 38754+{ 38755+ return match_type_to_reg(page_table, ARRAY_SIZE(page_table), type, 38756+ PAGE_SIZE_2KB); 38757+} 38758+ 38759+const char *match_page_type_to_str(unsigned char type) 38760+{ 38761+ return match_type_to_data(page_table, ARRAY_SIZE(page_table), type, 38762+ "unknown"); 38763+} 38764+ 38765+static struct match_t ecc_table[] = { 38766+ {NAND_ECC_0BIT, ECC_TYPE_0BIT, "none"}, 38767+ {NAND_ECC_8BIT, ECC_TYPE_8BIT, "4bit/512"}, 38768+ {NAND_ECC_16BIT, ECC_TYPE_16BIT, "8bit/512"}, 38769+ {NAND_ECC_24BIT, ECC_TYPE_24BIT, "24bit/1K"}, 38770+ {NAND_ECC_28BIT, ECC_TYPE_28BIT, "28bit/1K"}, 38771+ {NAND_ECC_40BIT, ECC_TYPE_40BIT, "40bit/1K"}, 38772+ {NAND_ECC_64BIT, ECC_TYPE_64BIT, "64bit/1K"}, 38773+}; 38774+ 38775+unsigned char match_ecc_reg_to_type(unsigned char reg) 38776+{ 38777+ return match_reg_to_type(ecc_table, ARRAY_SIZE(ecc_table), reg, 38778+ NAND_ECC_8BIT); 38779+} 38780+ 38781+unsigned char match_ecc_type_to_reg(unsigned char type) 38782+{ 38783+ return match_type_to_reg(ecc_table, ARRAY_SIZE(ecc_table), type, 38784+ ECC_TYPE_8BIT); 38785+} 38786+ 38787+const char *match_ecc_type_to_str(unsigned char type) 38788+{ 38789+ return match_type_to_data(ecc_table, ARRAY_SIZE(ecc_table), type, 38790+ "unknown"); 38791+} 38792+ 38793+static struct match_t page_type_size_table[] = { 38794+ {NAND_PAGE_2K, _2K, NULL}, 38795+ {NAND_PAGE_4K, _4K, NULL}, 38796+ {NAND_PAGE_8K, _8K, NULL}, 38797+ {NAND_PAGE_16K, _16K, NULL}, 38798+}; 38799+ 38800+unsigned char match_page_size_to_type(unsigned int size) 38801+{ 38802+ return match_reg_to_type(page_type_size_table, 38803+ ARRAY_SIZE(page_type_size_table), size, NAND_PAGE_2K); 38804+} 38805+ 38806+unsigned int match_page_type_to_size(unsigned char type) 38807+{ 38808+ return match_type_to_reg(page_type_size_table, 38809+ ARRAY_SIZE(page_type_size_table), type, _2K); 38810+} 38811\ No newline at end of file 38812diff --git a/drivers/mtd/nand/raw/hinfc_gen.h b/drivers/mtd/nand/raw/hinfc_gen.h 38813new file mode 100644 38814index 000000000..673ab8361 38815--- /dev/null 38816+++ b/drivers/mtd/nand/raw/hinfc_gen.h 38817@@ -0,0 +1,281 @@ 38818+/* 38819+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 38820+ * 38821+ * This program is free software; you can redistribute it and/or modify it 38822+ * under the terms of the GNU General Public License as published by the 38823+ * Free Software Foundation; either version 2 of the License, or (at your 38824+ * option) any later version. 38825+ * 38826+ * This program is distributed in the hope that it will be useful, 38827+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 38828+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 38829+ * GNU General Public License for more details. 38830+ * 38831+ * You should have received a copy of the GNU General Public License 38832+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 38833+ * 38834+ */ 38835+ 38836+#ifndef __HINFC_GEN_H__ 38837+#define __HINFC_GEN_H__ 38838+ 38839+#include <linux/mtd/mtd.h> 38840+#include <linux/mtd/rawnand.h> 38841+#include <linux/string_helpers.h> 38842+#include <asm/setup.h> 38843+#include <linux/module.h> 38844+ 38845+#define HINFC_VER_300 (0x300) 38846+#define HINFC_VER_301 (0x301) 38847+#define HINFC_VER_310 (0x310) 38848+#define HINFC_VER_504 (0x504) 38849+#define HINFC_VER_505 (0x505) 38850+#define HINFC_VER_600 (0x600) 38851+#define HINFC_VER_610 (0x610) 38852+#define HINFC_VER_620 (0x620) 38853+ 38854+#define HISNFC_VER_100 (0x400) 38855+ 38856+#define NAND_PAGE_512B 0 38857+#define NAND_PAGE_1K 1 38858+#define NAND_PAGE_2K 2 38859+#define NAND_PAGE_4K 3 38860+#define NAND_PAGE_8K 4 38861+#define NAND_PAGE_16K 5 38862+#define NAND_PAGE_32K 6 38863+ 38864+#define NAND_ECC_NONE 0 38865+#define NAND_ECC_0BIT 0 38866+#define NAND_ECC_1BIT 1 38867+#define NAND_ECC_1BIT_512 1 38868+#define NAND_ECC_4BIT 2 38869+#define NAND_ECC_4BIT_512 2 38870+#define NAND_ECC_4BYTE 2 38871+#define NAND_ECC_8BIT 2 38872+#define NAND_ECC_8BIT_512 3 38873+#define NAND_ECC_8BYTE 3 38874+#define NAND_ECC_13BIT 4 38875+#define NAND_ECC_16BIT 5 38876+#define NAND_ECC_18BIT 6 38877+#define NAND_ECC_24BIT 7 38878+#define NAND_ECC_27BIT 8 38879+#define NAND_ECC_28BIT 9 38880+#define NAND_ECC_32BIT 10 38881+#define NAND_ECC_40BIT 11 38882+#define NAND_ECC_41BIT 12 38883+#define NAND_ECC_42BIT 13 38884+#define NAND_ECC_48BIT 14 38885+#define NAND_ECC_60BIT 15 38886+#define NAND_ECC_64BIT 16 38887+#define NAND_ECC_72BIT 17 38888+#define NAND_ECC_80BIT 18 38889+ 38890+enum ecc_type { 38891+ et_ecc_none = 0x00, 38892+ et_ecc_1bit = 0x01, 38893+ et_ecc_4bit = 0x02, 38894+ et_ecc_8bit = 0x03, 38895+ et_ecc_24bit1k = 0x04, 38896+ et_ecc_40bit1k = 0x05, 38897+ et_ecc_64bit1k = 0x06, 38898+}; 38899+ 38900+enum page_type { 38901+ pt_pagesize_512 = 0x00, 38902+ pt_pagesize_2K = 0x01, 38903+ pt_pagesize_4K = 0x02, 38904+ pt_pagesize_8K = 0x03, 38905+ pt_pagesize_16K = 0x04, 38906+}; 38907+ 38908+struct nand_config_info { 38909+ unsigned int pagetype; 38910+ unsigned int ecctype; 38911+ unsigned int ecc_strength; 38912+ unsigned int oobsize; 38913+ struct mtd_ooblayout_ops *ooblayout_ops; 38914+}; 38915+ 38916+struct hinfc_host; 38917+ 38918+struct nand_sync { 38919+#define SET_NAND_SYNC_TYPE(_mfr, _onfi, _version) \ 38920+ ((((_mfr) & 0xFF) << 16) | (((_version) & 0xFF) << 8) \ 38921+ | ((_onfi) & 0xFF)) 38922+ 38923+#define GET_NAND_SYNC_TYPE_MFR(_type) (((_type) >> 16) & 0xFF) 38924+#define GET_NAND_SYNC_TYPE_VER(_type) (((_type) >> 8) & 0xFF) 38925+#define GET_NAND_SYNC_TYPE_INF(_type) ((_type) & 0xFF) 38926+ 38927+#define NAND_TYPE_ONFI_23_MICRON \ 38928+ SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x23) 38929+#define NAND_TYPE_ONFI_30_MICRON \ 38930+ SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x30) 38931+#define NAND_TYPE_TOGGLE_TOSHIBA \ 38932+ SET_NAND_SYNC_TYPE(NAND_MFR_TOSHIBA, 0, 0) 38933+#define NAND_TYPE_TOGGLE_SAMSUNG \ 38934+ SET_NAND_SYNC_TYPE(NAND_MFR_SAMSUNG, 0, 0) 38935+ 38936+#define NAND_TYPE_TOGGLE_10 SET_NAND_SYNC_TYPE(0, 0, 0x10) 38937+#define NAND_TYPE_ONFI_30 SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x30) 38938+#define NAND_TYPE_ONFI_23 SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x23) 38939+ 38940+ int type; 38941+ int (*enable)(struct nand_chip *chip); 38942+ int (*disable)(struct nand_chip *chip); 38943+}; 38944+ 38945+struct read_retry_t { 38946+ int type; 38947+ int count; 38948+ int (*set_rr_param)(struct hinfc_host *host, int param); 38949+ int (*get_rr_param)(struct hinfc_host *host); 38950+ int (*reset_rr_param)(struct hinfc_host *host); 38951+}; 38952+ 38953+struct ecc_info_t { 38954+ int pagesize; 38955+ int ecctype; 38956+ int threshold; 38957+ int section; 38958+ void (*dump)(struct hinfc_host *host, unsigned char ecc[], 38959+ int *max_bitsflag); 38960+}; 38961+ 38962+struct nand_dev_t { 38963+ struct nand_flash_dev flash_dev; 38964+ 38965+ char *start_type; 38966+ unsigned char ids[8]; 38967+ int oobsize; 38968+ int ecctype; 38969+ 38970+ /* (Controller) support ecc/page detect, driver don't need detect */ 38971+#define NANDC_HW_AUTO 0x01 38972+ /* (Controller) support ecc/page detect, 38973+ * and current ecc/page config finish */ 38974+#define NANDC_CONFIG_DONE 0x02 38975+ /* (Controller) is sync, default is async */ 38976+#define NANDC_IS_SYNC_BOOT 0x04 38977+ 38978+/* (NAND) need randomizer */ 38979+#define NAND_RANDOMIZER 0x10 38980+/* (NAND) is ONFI interface, combine with sync/async symble */ 38981+#define NAND_IS_ONFI 0x20 38982+/* (NAND) support async and sync, such micron onfi, toshiba toggle 1.0 */ 38983+#define NAND_MODE_SYNC_ASYNC 0x40 38984+/* (NAND) support only sync, such samsung sync. */ 38985+#define NAND_MODE_ONLY_SYNC 0x80 38986+ 38987+#define NAND_CHIP_MICRON (NAND_MODE_SYNC_ASYNC | NAND_IS_ONFI) 38988+/* This NAND is async, or sync/async, default is async mode, 38989+ * toggle1.0 interface */ 38990+#define NAND_CHIP_TOSHIBA_TOGGLE_10 (NAND_MODE_SYNC_ASYNC) 38991+/* This NAND is only sync mode, toggle2.0 interface */ 38992+#define NAND_CHIP_TOSHIBA_TOGGLE_20 (NAND_MODE_ONLY_SYNC) 38993+/* This NAND is only sync mode */ 38994+#define NAND_CHIP_SAMSUNG (NAND_MODE_ONLY_SYNC) 38995+ 38996+ unsigned int flags; 38997+ 38998+#define NAND_RR_NONE 0x00 38999+#define NAND_RR_HYNIX_BG_BDIE 0x10 39000+#define NAND_RR_HYNIX_BG_CDIE 0x11 39001+#define NAND_RR_HYNIX_CG_ADIE 0x12 39002+#define NAND_RR_MICRON 0x20 39003+#define NAND_RR_SAMSUNG 0x30 39004+#define NAND_RR_TOSHIBA_24nm 0x40 39005+#define NAND_RR_TOSHIBA_19nm 0x41 39006+ int read_retry_type; 39007+}; 39008+ 39009+ 39010+#define IS_NANDC_HW_AUTO(_host) ((_host)->flags & NANDC_HW_AUTO) 39011+#define IS_NANDC_CONFIG_DONE(_host) ((_host)->flags & NANDC_CONFIG_DONE) 39012+#define IS_NANDC_SYNC_BOOT(_host) ((_host)->flags & NANDC_IS_SYNC_BOOT) 39013+ 39014+#define IS_NAND_RANDOM(_dev) ((_dev)->flags & NAND_RANDOMIZER) 39015+#define IS_NAND_ONLY_SYNC(_dev) ((_dev)->flags & NAND_MODE_ONLY_SYNC) 39016+#define IS_NAND_SYNC_ASYNC(_dev) ((_dev)->flags & NAND_MODE_SYNC_ASYNC) 39017+#define IS_NAND_ONFI(_dev) ((_dev)->flags & NAND_IS_ONFI) 39018+ 39019+#define ERSTR_HARDWARE "Hardware configuration error. " 39020+#define ERSTR_DRIVER "Driver does not support. " 39021+ 39022+#define ENABLE 1 39023+#define DISABLE 0 39024+ 39025+char *get_ecctype_str(enum ecc_type ecctype); 39026+ 39027+char *get_pagesize_str(enum page_type pagetype); 39028+ 39029+unsigned int get_pagesize(enum page_type pagetype); 39030+ 39031+const char *nand_ecc_name(int type); 39032+ 39033+const char *nand_page_name(int type); 39034+ 39035+int nandpage_size2type(int size); 39036+ 39037+int nandpage_type2size(int size); 39038+ 39039+extern int (*hinfc_param_adjust)(struct mtd_info *mtd, struct nand_chip *chip, 39040+ struct nand_dev_t *nand_dev); 39041+ 39042+extern struct nand_flash_dev *(*nand_get_flash_type_func)(struct mtd_info *mtd, 39043+ struct nand_chip *chip, 39044+ struct nand_dev_t *spinand_dev_t); 39045+ 39046+extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook) 39047+(struct mtd_info *mtd, unsigned char *id); 39048+ 39049+extern int (*hinfc_param_adjust)(struct mtd_info *, 39050+ struct nand_chip *, struct nand_dev_t *); 39051+ 39052+struct nand_flash_dev *hinfc_get_flash_type(struct mtd_info *mtd, 39053+ struct nand_chip *chip, 39054+ u8 *id_data, int *busw); 39055+ 39056+extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook) 39057+(struct mtd_info *mtd, unsigned char *id); 39058+ 39059+void hinfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip); 39060+ 39061+void hinfc_show_info(struct mtd_info *mtd, const char *vendor, char *chipname); 39062+ 39063+void hinfc_show_chipsize(struct nand_chip *chip); 39064+ 39065+int get_bits(unsigned int n); 39066+ 39067+#define hinfc_pr_msg(_fmt, arg...) printk(_fmt, ##arg) 39068+ 39069+#define hinfc_pr_bug(fmt, args...) do { \ 39070+ printk("%s(%d): bug " fmt, __FILE__, __LINE__, ##args); \ 39071+ while (1) \ 39072+ ; \ 39073+} while (0) 39074+ 39075+#define PR_MSG(_fmt, arg...) \ 39076+ printk(_fmt, ##arg) 39077+ 39078+extern char *nand_dbgfs_options; 39079+ 39080+extern unsigned char match_page_reg_to_type(unsigned char reg); 39081+ 39082+extern unsigned char match_page_type_to_reg(unsigned char type); 39083+ 39084+extern const char *match_page_type_to_str(unsigned char type); 39085+ 39086+extern unsigned char match_ecc_reg_to_type(unsigned char reg); 39087+ 39088+extern unsigned char match_ecc_type_to_reg(unsigned char type); 39089+ 39090+extern const char *match_ecc_type_to_str(unsigned char type); 39091+ 39092+extern unsigned char match_page_size_to_type(unsigned int size); 39093+ 39094+extern unsigned int match_page_type_to_size(unsigned char type); 39095+ 39096+const char *nand_ecc_name(int type); 39097+ 39098+#endif /* End of __HINFC_GEN_H__ */ 39099\ No newline at end of file 39100diff --git a/drivers/mtd/nand/raw/hinfc_spl_ids.c b/drivers/mtd/nand/raw/hinfc_spl_ids.c 39101new file mode 100644 39102index 000000000..0fd7db974 39103--- /dev/null 39104+++ b/drivers/mtd/nand/raw/hinfc_spl_ids.c 39105@@ -0,0 +1,970 @@ 39106+/* 39107+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 39108+ * 39109+ * This program is free software; you can redistribute it and/or modify it 39110+ * under the terms of the GNU General Public License as published by the 39111+ * Free Software Foundation; either version 2 of the License, or (at your 39112+ * option) any later version. 39113+ * 39114+ * This program is distributed in the hope that it will be useful, 39115+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 39116+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 39117+ * GNU General Public License for more details. 39118+ * 39119+ * You should have received a copy of the GNU General Public License 39120+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 39121+ * 39122+ */ 39123+ 39124+#include <linux/mtd/mtd.h> 39125+#include <linux/mfd/hisi_fmc.h> 39126+#include "hinfc_gen.h" 39127+ 39128+struct nand_flash_special_dev { 39129+ unsigned char id[8]; 39130+ int length; /* length of id. */ 39131+ unsigned long long chipsize; 39132+ struct nand_flash_dev *(*probe)(struct nand_dev_t *nand_dev); 39133+ char *name; 39134+ 39135+ unsigned long pagesize; 39136+ unsigned long erasesize; 39137+ unsigned long oobsize; 39138+ unsigned long options; 39139+ unsigned int read_retry_type; 39140+ 39141+#define BBP_LAST_PAGE 0x01 39142+#define BBP_FIRST_PAGE 0x02 39143+ unsigned int badblock_pos; 39144+ unsigned int flags; 39145+}; 39146+ 39147+ 39148+/* this is nand probe function. */ 39149+ 39150+ 39151+static struct nand_flash_dev *hynix_probe_v02( 39152+ struct nand_dev_t *nand_dev) 39153+{ 39154+ unsigned char *id = nand_dev->ids; 39155+ struct nand_flash_dev *type = &nand_dev->flash_dev; 39156+ 39157+ int pagesizes[] = {SZ_2K, SZ_4K, SZ_8K, 0}; 39158+ int oobsizes[] = {128, 224, 448, 0, 0, 0, 0, 0}; 39159+ int blocksizes[] = {SZ_128K, SZ_256K, SZ_512K, 39160+ (SZ_256K + SZ_512K), SZ_1M, SZ_2M, 0, 0 39161+ }; 39162+ 39163+ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); 39164+ int oobtype = (((id[3] >> 2) & 0x03) | ((id[3] >> 4) & 0x04)); 39165+ 39166+ type->options = 0; 39167+ type->pagesize = pagesizes[(id[3] & 0x03)]; 39168+ type->erasesize = blocksizes[blocktype]; 39169+ nand_dev->oobsize = oobsizes[oobtype]; 39170+ 39171+ return type; 39172+} 39173+ 39174+ 39175+static struct nand_flash_dev *samsung_probe_v02( 39176+ struct nand_dev_t *nand_dev) 39177+{ 39178+ unsigned char *id = nand_dev->ids; 39179+ struct nand_flash_dev *type = &nand_dev->flash_dev; 39180+ 39181+ int pagesizes[] = {SZ_2K, SZ_4K, SZ_8K, 0}; 39182+ int oobsizes[] = {0, 128, 218, 400, 436, 0, 0, 0}; 39183+ int blocksizes[] = {SZ_128K, SZ_256K, SZ_512K, SZ_1M, 0, 0, 0, 0}; 39184+ 39185+ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); 39186+ int oobtype = (((id[3] >> 4) & 0x04) | ((id[3] >> 2) & 0x03)); 39187+ 39188+ type->options = 0; 39189+ type->pagesize = pagesizes[(id[3] & 0x03)]; 39190+ type->erasesize = blocksizes[blocktype]; 39191+ nand_dev->oobsize = oobsizes[oobtype]; 39192+ 39193+ return type; 39194+} 39195+ 39196+ 39197+#define DRV_VERSION "1.38" 39198+ 39199+ 39200+/* 39201+ * samsung: 27nm need randomizer, 21nm need read retry; 39202+ * micron: 25nm need read retry, datasheet will explain read retry. 39203+ * toshaba 32nm need randomizer, 24nm need read retry. 39204+ * hynix: 2xnm need read retry. 39205+ * 39206+ * The special nand flash ID table version 1.37 39207+ * 39208+ * manufactory | type | name | ecc_type | version_tag 39209+ * Micron | MLC | MT29F64G08CBABA | 40bit/1k | 1.36 39210+ * Micron | MLC | MT29F32G08CBADA | 40bit/1k | 39211+ * Micron | SLC | MT29F8G08ABxBA | 4bit/512 | 39212+ * Micron | MLC | MT29F16G08CBABx | 12bit/512 | 39213+ * Micron | MLC | MT29F16G08CBACA | 24bit/1k | 39214+ * Micron | MLC | MT29F32G08CBACA | 24bit/1k | 39215+ * Micron | MLC | MT29F64G08CxxAA | 24bit/1k | 39216+ * Micron | MLC | MT29F256G08CJAAA | 24bit/1k | 2CE 39217+ * Micron | MLC | MT29F256G08CMCBB | 24bit/1k | 39218+ * Micron | SLC | MT29F8G08ABACA | 8bit/512 | 39219+ * Micron | SLC | MT29F4G08ABAEA | 8bit/512 | 39220+ * Micron | SLC | MT29F2G08ABAFA | 8bit/512 | 39221+ * Micron | SLC | MT29F16G08ABACA | 8bit/512 | 39222+ * Toshiba | MLC | TC58NVG4D2FTA00 | 24bit/1k | 39223+ * Toshiba | MLC | TH58NVG6D2FTA20 | 24bit/1k | 2CE 39224+ * Toshiba | MLC | TC58NVG5D2HTA00 | 40bit/1k | 39225+ * Toshiba | MLC | TC58NVG6D2GTA00 | 40bit/1k | 39226+ * Toshiba | MLC | TC58NVG6DCJTA00 | | 39227+ * Toshiba | MLC | TC58TEG5DCJTA00 | | 39228+ * Toshiba | SLC | TC58NVG0S3HTA00 | 8bit/512 | 39229+ * Toshiba | SLC | TC58NVG1S3HTA00 | 8bit/512 | 39230+ * Toshiba | SLC | TC58NVG1S3ETA00 | 4bit/512 | 39231+ * Toshiba | SLC | TC58NVG3S0FTA00 | 4bit/512 | 39232+ * Toshiba | SLC | TC58NVG2S0FTA00 | 4bit/512 | 39233+ * Toshiba | SLC | TH58NVG2S3HTA00 | 4bit/512 | 39234+ * Toshiba | TLC | TC58NVG5T2JTA00 | 60bit/1k | 39235+ * Toshiba | TLC | TC58TEG5DCKTAx0 | 60bit/1k | 39236+ * Toshiba | MLC | Tx58TEGxDDKTAx0 | | 39237+ * Samsung | MLC | K9LB(HC/PD/MD)G08U0(1)D | 8bit/512B | 39238+ * Samsung | MLC | K9GAG08U0E | 24bit/1KB | 39239+ * Samsung | MLC | K9LBG08U0E | 24bit/1KB | 39240+ * Samsung | MLC | K9G8G08U0C | 24bit/1KB | 39241+ * Samsung | MLC | K9GAG08U0F | 24bit/1KB | 39242+ * Samsung | MLC | K9LBG08U0M | | 39243+ * Samsung | MLC | K9GBG08U0A | 24bit/1KB | 39244+ * Samsung | MLC | K9GBG08U0B | 40bit/1KB | 39245+ * Hynix | MLC | H27UAG8T2A | | 39246+ * Hynix | MLC | H27UAG8T2B | | 39247+ * Hynix | MLC | H27UBG8T2A | | 39248+ * Hynix | MLC | H27UBG8T2BTR | 24bit/1KB | 39249+ * Hynix | MLC | H27UCG8T2A | 40bit/1KB | 39250+ * Hynix | MLC | H27UBG8T2C | 40bit/1KB | 39251+ * MISC | MLC | P1UAGA30AT-GCA | 8bit/512 | 39252+ * MISC | MLC | PSU8GA30AT-GIA/ASU8GA30IT-G30CA | 4bit/512 | 39253+ * MISC | SLC | PSU2GA30AT | 1bit/512 | 1.36 39254+ * Toshiba | SLC | TC58NVG2S0HTA00 | 24bit/1K | 1.37 39255+ * Toshiba | SLC | TC58NVG3S0HTA00 | 24bit/1K | 1.37 39256+ * Micron | SLC | MT29F2G08ABAEA | 4bit/512 | 39257+ * Spansion | SLC | S34ML02G200TFI000 | 24bit/1K | 39258+ * Spansion | SLC | S34ML04G200TFI000 | 24bit/1K | 1.38 39259+ * 39260+ */ 39261+ 39262+static struct nand_flash_special_dev nand_flash_special_dev[] = { 39263+ 39264+/****************************** Spansion *******************************/ 39265+ 39266+ { /* SLC S34ML02G200TFI000 */ 39267+ .name = "S34ML02G200TFI000", 39268+ .id = {0x01, 0xDA, 0x90, 0x95, 0x46, 0x00, 0x00, 0x00}, 39269+ .length = 5, 39270+ .chipsize = _256M, 39271+ .probe = NULL, 39272+ .pagesize = SZ_2K, 39273+ .erasesize = SZ_128K, 39274+ .oobsize = 128, 39275+ .options = 0, 39276+ .read_retry_type = NAND_RR_NONE, 39277+ .badblock_pos = BBP_FIRST_PAGE, 39278+ .flags = 0, 39279+ }, 39280+ 39281+ { /* SLC S34ML04G200TFI000 */ 39282+ .name = "S34ML04G200TFI000", 39283+ .id = {0x01, 0xDC, 0x90, 0x95, 0x56, 0x00, 0x00, 0x00}, 39284+ .length = 5, 39285+ .chipsize = _512M, 39286+ .probe = NULL, 39287+ .pagesize = SZ_2K, 39288+ .erasesize = SZ_128K, 39289+ .oobsize = 128, 39290+ .options = 0, 39291+ .read_retry_type = NAND_RR_NONE, 39292+ .badblock_pos = BBP_FIRST_PAGE, 39293+ .flags = 0, 39294+ }, 39295+ 39296+ /****************************** Micron *******************************/ 39297+ { /* MLC 40bit/1k */ 39298+ .name = "MT29F64G08CBABA", 39299+ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 39300+ .length = 8, 39301+ .chipsize = _8G, 39302+ .probe = NULL, 39303+ .pagesize = SZ_8K, 39304+ .erasesize = SZ_2M, 39305+ .oobsize = 744, 39306+ .options = 0, 39307+ .read_retry_type = NAND_RR_MICRON, 39308+ .badblock_pos = BBP_FIRST_PAGE, 39309+ .flags = NAND_RANDOMIZER | NAND_CHIP_MICRON, 39310+ }, 39311+ { /* MLC 40bit/1k */ 39312+ .name = "MT29F32G08CBADA", 39313+ .id = {0x2C, 0x44, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 39314+ .length = 8, 39315+ .chipsize = _4G, 39316+ .probe = NULL, 39317+ .pagesize = SZ_8K, 39318+ .erasesize = SZ_2M, 39319+ .oobsize = 744, 39320+ .options = 0, 39321+ .read_retry_type = NAND_RR_MICRON, 39322+ .badblock_pos = BBP_FIRST_PAGE, 39323+ .flags = NAND_RANDOMIZER, 39324+ }, 39325+ { /* SLC 4bit/512 */ 39326+ .name = "MT29F8G08ABxBA", 39327+ .id = {0x2C, 0x38, 0x00, 0x26, 0x85, 0x00, 0x00, 0x00}, 39328+ .length = 8, 39329+ .chipsize = SZ_1G, 39330+ .probe = NULL, 39331+ .pagesize = SZ_4K, 39332+ .erasesize = SZ_512K, 39333+ .oobsize = 224, 39334+ .options = 0, 39335+ .read_retry_type = NAND_RR_NONE, 39336+ .badblock_pos = BBP_FIRST_PAGE, 39337+ .flags = 0, 39338+ }, 39339+ { /* MLC 12bit/512 */ 39340+ .name = "MT29F16G08CBABx", 39341+ .id = {0x2C, 0x48, 0x04, 0x46, 0x85, 0x00, 0x00, 0x00}, 39342+ .length = 8, 39343+ .chipsize = SZ_2G, 39344+ .probe = NULL, 39345+ .pagesize = SZ_4K, 39346+ .erasesize = SZ_1M, 39347+ .oobsize = 224, 39348+ .options = 0, 39349+ .read_retry_type = NAND_RR_NONE, 39350+ .badblock_pos = BBP_FIRST_PAGE, 39351+ .flags = 0, 39352+ }, 39353+ { /* MLC 24bit/1k */ 39354+ .name = "MT29F16G08CBACA", 39355+ .id = {0x2C, 0x48, 0x04, 0x4A, 0xA5, 0x00, 0x00, 0x00}, 39356+ .length = 8, 39357+ .chipsize = SZ_2G, 39358+ .probe = NULL, 39359+ .pagesize = SZ_4K, 39360+ .erasesize = SZ_1M, 39361+ .oobsize = 224, 39362+ .options = 0, 39363+ .read_retry_type = NAND_RR_NONE, 39364+ .badblock_pos = BBP_FIRST_PAGE, 39365+ .flags = 0, 39366+ }, 39367+ { /* MLC 24bit/1k */ 39368+ .name = "MT29F32G08CBACA", 39369+ .id = {0x2C, 0x68, 0x04, 0x4A, 0xA9, 0x00, 0x00, 0x00}, 39370+ .length = 8, 39371+ .chipsize = _4G, 39372+ .probe = NULL, 39373+ .pagesize = SZ_4K, 39374+ .erasesize = SZ_1M, 39375+ .oobsize = 224, 39376+ .options = 0, 39377+ .read_retry_type = NAND_RR_NONE, 39378+ .badblock_pos = BBP_FIRST_PAGE, 39379+ .flags = 0, 39380+ }, 39381+ { /* MLC 24bit/1k */ 39382+ .name = "MT29F64G08CxxAA", 39383+ .id = {0x2C, 0x88, 0x04, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 39384+ .length = 8, 39385+ .chipsize = _8G, 39386+ .probe = NULL, 39387+ .pagesize = SZ_8K, 39388+ .erasesize = SZ_2M, 39389+ .oobsize = 448, 39390+ .options = 0, 39391+ .read_retry_type = NAND_RR_NONE, 39392+ .badblock_pos = BBP_FIRST_PAGE, 39393+ .flags = 0, 39394+ }, 39395+ { /* MLC 24bit/1k 2CE */ 39396+ .name = "MT29F256G08CJAAA", 39397+ .id = {0x2C, 0xA8, 0x05, 0xCB, 0xA9, 0x00, 0x00, 0x00}, 39398+ .length = 8, 39399+ .chipsize = _16G, 39400+ .probe = NULL, 39401+ .pagesize = SZ_8K, 39402+ .erasesize = SZ_2M, 39403+ .oobsize = 448, 39404+ .options = 0, 39405+ .read_retry_type = NAND_RR_NONE, 39406+ .badblock_pos = BBP_FIRST_PAGE, 39407+ .flags = 0, 39408+ }, 39409+ { /* MLC 40bit/1k */ 39410+ .name = "MT29F256G08CMCBB", 39411+ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, 39412+ .length = 8, 39413+ .chipsize = _8G, 39414+ .probe = NULL, 39415+ .pagesize = SZ_8K, 39416+ .erasesize = SZ_2M, 39417+ .oobsize = 744, 39418+ .options = 0, 39419+ .read_retry_type = NAND_RR_NONE, 39420+ .badblock_pos = BBP_FIRST_PAGE, 39421+ .flags = 0, 39422+ }, 39423+ { /* SLC 8bit/512 */ 39424+ .name = "MT29F8G08ABACA", 39425+ .id = {0x2C, 0xD3, 0x90, 0xA6, 0x64, 0x00, 0x00, 0x00}, 39426+ .length = 5, 39427+ .chipsize = SZ_1G, 39428+ .probe = NULL, 39429+ .pagesize = SZ_4K, 39430+ .erasesize = SZ_256K, 39431+ .oobsize = 224, 39432+ .options = 0, 39433+ .read_retry_type = NAND_RR_NONE, 39434+ .badblock_pos = BBP_FIRST_PAGE, 39435+ .flags = 0, 39436+ }, 39437+ { /* SLC 8bit/512 */ 39438+ .name = "MT29F4G08ABAEA", 39439+ .id = {0x2C, 0xDC, 0x90, 0xA6, 0x54, 0x00, 0x00, 0x00}, 39440+ .length = 5, 39441+ .chipsize = SZ_512M, 39442+ .probe = NULL, 39443+ .pagesize = SZ_4K, 39444+ .erasesize = SZ_256K, 39445+ .oobsize = 224, 39446+ .options = 0, 39447+ .read_retry_type = NAND_RR_NONE, 39448+ .badblock_pos = BBP_FIRST_PAGE, 39449+ .flags = 0, 39450+ }, 39451+ { /* SLC 8bit/512 */ 39452+ .name = "MT29F2G08ABAFA", 39453+ .id = {0x2C, 0xDA, 0x90, 0x95, 0x04, 0x00, 0x00, 0x00}, 39454+ .length = 5, 39455+ .chipsize = SZ_256M, 39456+ .probe = NULL, 39457+ .pagesize = SZ_2K, 39458+ .erasesize = SZ_128K, 39459+ .oobsize = 224, 39460+ .options = 0, 39461+ .read_retry_type = NAND_RR_NONE, 39462+ .badblock_pos = BBP_FIRST_PAGE, 39463+ .flags = 0, 39464+ }, 39465+ { /* SLC MT29F2G08ABAEA */ 39466+ .name = "MT29F2G08ABAEA", 39467+ .id = {0x2C, 0xDA, 0x90, 0x95, 0x06, 0x00, 0x00, 0x00}, 39468+ .length = 5, 39469+ .chipsize = _256M, 39470+ .probe = NULL, 39471+ .pagesize = SZ_2K, 39472+ .erasesize = SZ_128K, 39473+ .oobsize = 64, 39474+ .options = 0, 39475+ .read_retry_type = NAND_RR_NONE, 39476+ .badblock_pos = BBP_FIRST_PAGE, 39477+ .flags = 0, 39478+ }, 39479+ { /* SLC 8bit/512 */ 39480+ .name = "MT29F16G08ABACA", 39481+ .id = {0x2C, 0x48, 0x00, 0x26, 0xA9, 0x00, 0x00, 0x00}, 39482+ .length = 5, 39483+ .chipsize = SZ_2G, 39484+ .probe = NULL, 39485+ .pagesize = SZ_4K, 39486+ .erasesize = SZ_512K, 39487+ .oobsize = 224, 39488+ .options = 0, 39489+ .read_retry_type = NAND_RR_NONE, 39490+ .badblock_pos = BBP_FIRST_PAGE, 39491+ .flags = 0, 39492+ }, 39493+ 39494+/****************************** Toshaba *******************************/ 39495+ 39496+ { /* MLC 24bit/1k 32nm */ 39497+ .name = "TC58NVG4D2FTA00", 39498+ .id = {0x98, 0xD5, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, 39499+ .length = 6, 39500+ .chipsize = SZ_2G, 39501+ .probe = NULL, 39502+ .pagesize = SZ_8K, 39503+ .erasesize = SZ_1M, 39504+ .oobsize = 448, 39505+ .options = 0, 39506+ .read_retry_type = NAND_RR_NONE, 39507+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39508+ .flags = 0, 39509+ }, 39510+ { /* MLC 24bit/1k 32nm 2CE */ 39511+ .name = "TH58NVG6D2FTA20", 39512+ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, 39513+ .length = 6, 39514+ .chipsize = _4G, 39515+ .probe = NULL, 39516+ .pagesize = SZ_8K, 39517+ .erasesize = SZ_1M, 39518+ .oobsize = 448, 39519+ .options = 0, 39520+ .read_retry_type = NAND_RR_NONE, 39521+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39522+ .flags = 0, 39523+ }, 39524+ { /* MLC 40bit/1k 24nm */ 39525+ .name = "TC58NVG5D2HTA00 24nm", 39526+ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x56, 0x08, 0x00}, 39527+ .length = 6, 39528+ .chipsize = _4G, 39529+ .probe = NULL, 39530+ .pagesize = SZ_8K, 39531+ .erasesize = SZ_1M, 39532+ .oobsize = 640, 39533+ .options = 0, 39534+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 39535+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39536+ .flags = NAND_RANDOMIZER, 39537+ }, 39538+ { /* MLC 40bit/1k */ 39539+ .name = "TC58NVG6D2GTA00", 39540+ .id = {0x98, 0xDE, 0x94, 0x82, 0x76, 0x00, 0x00, 0x00}, 39541+ .length = 5, 39542+ .chipsize = _8G, 39543+ .probe = NULL, 39544+ .pagesize = SZ_8K, 39545+ .erasesize = SZ_2M, 39546+ .oobsize = 640, 39547+ .options = 0, 39548+ .read_retry_type = NAND_RR_NONE, 39549+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39550+ .flags = 0, 39551+ }, 39552+ { /* MLC 19nm */ 39553+ .name = "TC58NVG6DCJTA00 19nm", 39554+ .id = {0x98, 0xDE, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, 39555+ .length = 8, 39556+ .chipsize = _8G, 39557+ .probe = NULL, 39558+ .pagesize = SZ_16K, 39559+ .erasesize = SZ_4M, 39560+ .oobsize = 1280, 39561+ .options = 0, 39562+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 39563+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39564+ .flags = NAND_RANDOMIZER, 39565+ }, 39566+ { /* MLC 19nm */ 39567+ .name = "TC58TEG5DCJTA00 19nm", 39568+ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, 39569+ .length = 6, 39570+ .chipsize = _4G, 39571+ .probe = NULL, 39572+ .pagesize = SZ_16K, 39573+ .erasesize = SZ_4M, 39574+ .oobsize = 1280, 39575+ .options = 0, 39576+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 39577+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39578+ .flags = NAND_RANDOMIZER | NAND_CHIP_TOSHIBA_TOGGLE_10, 39579+ }, 39580+ { /* SLC 8bit/512 */ 39581+ .name = "TC58NVG0S3HTA00", 39582+ .id = {0x98, 0xF1, 0x80, 0x15, 0x72, 0x00, 0x00, 0x00}, 39583+ .length = 5, 39584+ .chipsize = SZ_128M, 39585+ .probe = NULL, 39586+ .pagesize = SZ_2K, 39587+ .erasesize = SZ_128K, 39588+ .oobsize = 128, 39589+ .options = 0, 39590+ .read_retry_type = NAND_RR_NONE, 39591+ /* 39592+ * Datasheet: read one column of any page in each block. If the 39593+ * data of the column is 00 (Hex), define the block as a bad 39594+ * block. 39595+ */ 39596+ .badblock_pos = BBP_FIRST_PAGE, 39597+ .flags = 0, 39598+ }, 39599+ { /* SLC 8bit/512 */ 39600+ .name = "TC58NVG1S3HTA00", 39601+ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x16, 0x08, 0x00}, 39602+ .length = 7, 39603+ .chipsize = SZ_256M, 39604+ .probe = NULL, 39605+ .pagesize = SZ_2K, 39606+ .erasesize = SZ_128K, 39607+ .oobsize = 128, 39608+ .options = 0, 39609+ .read_retry_type = NAND_RR_NONE, 39610+ .badblock_pos = BBP_FIRST_PAGE, 39611+ .flags = 0, 39612+ }, 39613+ { /* SLC 4bit/512 */ 39614+ .name = "TC58NVG1S3ETA00", 39615+ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x14, 0x03, 0x00}, 39616+ .length = 7, 39617+ .chipsize = SZ_256M, 39618+ .probe = NULL, 39619+ .pagesize = SZ_2K, 39620+ .erasesize = SZ_128K, 39621+ .oobsize = 64, 39622+ .options = 0, 39623+ .read_retry_type = NAND_RR_NONE, 39624+ .badblock_pos = BBP_FIRST_PAGE, 39625+ .flags = 0, 39626+ }, 39627+ { /* SLC 4bit/512 */ 39628+ .name = "TC58NVG3S0FTA00", 39629+ .id = {0x98, 0xD3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08}, 39630+ .length = 8, 39631+ .chipsize = SZ_1G, 39632+ .probe = NULL, 39633+ .pagesize = SZ_4K, 39634+ .erasesize = SZ_256K, 39635+ .oobsize = 232, 39636+ .options = 0, 39637+ .read_retry_type = NAND_RR_NONE, 39638+ .badblock_pos = BBP_FIRST_PAGE, 39639+ .flags = 0, 39640+ }, 39641+ { /* SLC 4bit/512 */ 39642+ .name = "TC58NVG3S0HTA00", 39643+ .id = {0x98, 0xD3, 0x91, 0x26, 0x76, 0x16, 0x08, 0x00}, 39644+ .length = 8, 39645+ .chipsize = SZ_1G, 39646+ .probe = NULL, 39647+ .pagesize = SZ_4K, 39648+ .erasesize = SZ_256K, 39649+ .oobsize = 256, 39650+ .options = 0, 39651+ .read_retry_type = NAND_RR_NONE, 39652+ .badblock_pos = BBP_FIRST_PAGE, 39653+ .flags = 0, 39654+ }, 39655+ { /* SLC 24bit/1k */ 39656+ .name = "TC58NVG2S0HTA00", 39657+ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00}, 39658+ .length = 8, 39659+ .chipsize = SZ_512M, 39660+ .probe = NULL, 39661+ .pagesize = SZ_4K, 39662+ .erasesize = SZ_256K, 39663+ .oobsize = 256, 39664+ .options = 0, 39665+ .read_retry_type = NAND_RR_NONE, 39666+ .badblock_pos = BBP_FIRST_PAGE, 39667+ .flags = 0, 39668+ }, 39669+ { /* SLC 4bit/512 */ 39670+ .name = "TC58NVG2S0FTA00", 39671+ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08}, 39672+ .length = 8, 39673+ .chipsize = SZ_512M, 39674+ .probe = NULL, 39675+ .pagesize = SZ_4K, 39676+ .erasesize = SZ_256K, 39677+ .oobsize = 224, 39678+ .options = 0, 39679+ .read_retry_type = NAND_RR_NONE, 39680+ .badblock_pos = BBP_FIRST_PAGE, 39681+ .flags = 0, 39682+ }, 39683+ { /* SLC 4bit/512 */ 39684+ .name = "TH58NVG2S3HTA00", 39685+ .id = {0x98, 0xDC, 0x91, 0x15, 0x76}, 39686+ .length = 5, 39687+ .chipsize = SZ_512M, 39688+ .probe = NULL, 39689+ .pagesize = SZ_2K, 39690+ .erasesize = SZ_128K, 39691+ .oobsize = 128, 39692+ .options = 0, 39693+ .read_retry_type = NAND_RR_NONE, 39694+ .badblock_pos = BBP_FIRST_PAGE, 39695+ .flags = 0, 39696+ }, 39697+ { /* TLC 60bit/1k 19nm */ 39698+ .name = "TC58NVG5T2JTA00 19nm TLC", 39699+ .id = {0x98, 0xD7, 0x98, 0x92, 0x72, 0x57, 0x08, 0x10}, 39700+ .length = 6, 39701+ .chipsize = _4G, 39702+ .probe = NULL, 39703+ .pagesize = SZ_8K, 39704+ .erasesize = SZ_4M, 39705+ .oobsize = 1024, 39706+ .options = 0, 39707+ .read_retry_type = NAND_RR_TOSHIBA_24nm, 39708+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39709+ .flags = NAND_RANDOMIZER, 39710+ }, 39711+ { /* TLC 60bit/1k 19nm */ 39712+ .name = "TC58TEG5DCKTAx0 19nm MLC", 39713+ /* datasheet says 6 ids id data, but really has 8 ids. */ 39714+ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x50, 0x08, 0x04}, 39715+ .length = 6, 39716+ .chipsize = _4G, 39717+ .probe = NULL, 39718+ .pagesize = SZ_16K, 39719+ .erasesize = SZ_4M, 39720+ .oobsize = 1280, 39721+ .options = 0, 39722+ .read_retry_type = NAND_RR_TOSHIBA_19nm, 39723+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39724+ .flags = NAND_RANDOMIZER, 39725+ }, 39726+ { 39727+ .name = "Tx58TEGxDDKTAx0 19nm MLC", 39728+ .id = {0x98, 0xDE, 0x94, 0x93, 0x76, 0x50}, 39729+ .length = 6, 39730+ .chipsize = _4G, 39731+ .probe = NULL, 39732+ .pagesize = SZ_16K, 39733+ .erasesize = SZ_4M, 39734+ .oobsize = 1280, 39735+ .options = 0, 39736+ .read_retry_type = NAND_RR_TOSHIBA_19nm, 39737+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39738+ .flags = NAND_RANDOMIZER, 39739+ }, 39740+/******************************* Samsung ******************************/ 39741+ { /* MLC 8bit/512B */ 39742+ .name = "K9LB(HC/PD/MD)G08U0(1)D", 39743+ .id = {0xEC, 0xD7, 0xD5, 0x29, 0x38, 0x41, 0x00, 0x00}, 39744+ .length = 6, 39745+ .chipsize = _4G, 39746+ .probe = samsung_probe_v02, 39747+ .read_retry_type = NAND_RR_NONE, 39748+ .badblock_pos = BBP_LAST_PAGE, 39749+ .flags = 0, 39750+ }, 39751+ { /* MLC 24bit/1KB */ 39752+ .name = "K9GAG08U0E", 39753+ .id = {0xEC, 0xD5, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, 39754+ .length = 6, 39755+ .chipsize = SZ_2G, 39756+ .probe = samsung_probe_v02, 39757+ .read_retry_type = NAND_RR_NONE, 39758+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39759+ .flags = 0, 39760+ }, 39761+ { /* MLC 24bit/1KB */ 39762+ .name = "K9LBG08U0E", 39763+ .id = {0xEC, 0xD7, 0xC5, 0x72, 0x54, 0x42, 0x00, 0x00}, 39764+ .length = 6, 39765+ .chipsize = _4G, 39766+ .probe = samsung_probe_v02, 39767+ .read_retry_type = NAND_RR_NONE, 39768+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39769+ .flags = 0, 39770+ }, 39771+ { /* MLC 24bit/1KB */ 39772+ .name = "K9G8G08U0C", 39773+ .id = {0xEC, 0xD3, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, 39774+ .length = 6, 39775+ .chipsize = SZ_1G, 39776+ .probe = samsung_probe_v02, 39777+ .read_retry_type = NAND_RR_NONE, 39778+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39779+ .flags = 0, 39780+ }, 39781+ { /* MLC 24bit/1k */ 39782+ .name = "K9GAG08U0F", 39783+ .id = {0xEC, 0xD5, 0x94, 0x76, 0x54, 0x43, 0x00, 0x00}, 39784+ .length = 6, 39785+ .chipsize = SZ_2G, 39786+ .probe = NULL, 39787+ .pagesize = SZ_8K, 39788+ .erasesize = SZ_1M, 39789+ .oobsize = 512, 39790+ .options = 0, 39791+ .read_retry_type = NAND_RR_NONE, 39792+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39793+ .flags = 0, 39794+ }, 39795+ { /* MLC */ 39796+ .name = "K9LBG08U0M", 39797+ .id = {0xEC, 0xD7, 0x55, 0xB6, 0x78, 0x00, 0x00, 0x00}, 39798+ .length = 5, 39799+ .chipsize = _4G, 39800+ .probe = NULL, 39801+ .pagesize = SZ_4K, 39802+ .erasesize = SZ_512K, 39803+ .oobsize = 128, 39804+ .options = 0, 39805+ .read_retry_type = NAND_RR_NONE, 39806+ .badblock_pos = BBP_LAST_PAGE, 39807+ .flags = 0, 39808+ }, 39809+ { /* MLC 24bit/1k */ 39810+ .name = "K9GBG08U0A 20nm", 39811+ .id = {0xEC, 0xD7, 0x94, 0x7A, 0x54, 0x43, 0x00, 0x00}, 39812+ .length = 6, 39813+ .chipsize = _4G, 39814+ .probe = NULL, 39815+ .pagesize = SZ_8K, 39816+ .erasesize = SZ_1M, 39817+ .oobsize = 640, 39818+ .options = 0, 39819+ .read_retry_type = NAND_RR_SAMSUNG, 39820+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39821+ .flags = NAND_RANDOMIZER, 39822+ }, 39823+ { /* MLC 40bit/1k */ 39824+ .name = "K9GBG08U0B", 39825+ .id = {0xEC, 0xD7, 0x94, 0x7E, 0x64, 0x44, 0x00, 0x00}, 39826+ .length = 6, 39827+ .chipsize = _4G, 39828+ .probe = NULL, 39829+ .pagesize = SZ_8K, 39830+ .erasesize = SZ_1M, 39831+ .oobsize = 1024, 39832+ .options = 0, 39833+ .read_retry_type = NAND_RR_SAMSUNG, 39834+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39835+ .flags = NAND_RANDOMIZER, 39836+ }, 39837+ 39838+/*********************************** Hynix ****************************/ 39839+ { /* MLC */ 39840+ .name = "H27UAG8T2A", 39841+ .id = { 0xAD, 0xD5, 0x94, 0x25, 0x44, 0x41, }, 39842+ .length = 6, 39843+ .chipsize = SZ_2G, 39844+ .probe = hynix_probe_v02, 39845+ .read_retry_type = NAND_RR_NONE, 39846+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39847+ .flags = 0, 39848+ }, 39849+ { /* MLC */ 39850+ .name = "H27UAG8T2B", 39851+ .id = { 0xAD, 0xD5, 0x94, 0x9A, 0x74, 0x42, }, 39852+ .length = 6, 39853+ .chipsize = SZ_2G, 39854+ .probe = hynix_probe_v02, 39855+ .read_retry_type = NAND_RR_NONE, 39856+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39857+ .flags = 0, 39858+ }, 39859+ { /* MLC */ 39860+ .name = "H27UBG8T2A", 39861+ .id = { 0xAD, 0xD7, 0x94, 0x9A, 0x74, 0x42, }, 39862+ .length = 6, 39863+ .chipsize = _4G, 39864+ .probe = hynix_probe_v02, 39865+ .read_retry_type = NAND_RR_NONE, 39866+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39867+ .flags = 0, 39868+ }, 39869+ { 39870+ .name = "H27UBG8T2BTR 26nm", 39871+ .id = { 0xAD, 0xD7, 0x94, 0xDA, 0x74, 0xC3, }, 39872+ .length = 6, 39873+ .chipsize = _4G, 39874+ .probe = NULL, 39875+ .pagesize = SZ_8K, 39876+ .erasesize = SZ_2M, 39877+ .oobsize = 640, 39878+ .options = 0, 39879+ .read_retry_type = NAND_RR_HYNIX_BG_BDIE, 39880+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39881+ .flags = NAND_RANDOMIZER, 39882+ }, 39883+ { /* MLC 40bit/1k */ 39884+ .name = "H27UCG8T2A", 39885+ .id = { 0xAD, 0xDE, 0x94, 0xDA, 0x74, 0xC4, }, 39886+ .length = 6, 39887+ .chipsize = _8G, 39888+ .probe = NULL, 39889+ .pagesize = SZ_8K, 39890+ .erasesize = SZ_2M, 39891+ .oobsize = 640, 39892+ .options = 0, 39893+ .read_retry_type = NAND_RR_HYNIX_CG_ADIE, 39894+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39895+ .flags = NAND_RANDOMIZER, 39896+ }, 39897+ { /* MLC 40bit/1k */ 39898+ .name = "H27UBG8T2C", 39899+ .id = { 0xAD, 0xD7, 0x94, 0x91, 0x60, 0x44, }, 39900+ .length = 6, 39901+ .chipsize = _4G, 39902+ .probe = NULL, 39903+ .pagesize = SZ_8K, 39904+ .erasesize = SZ_2M, 39905+ .oobsize = 640, 39906+ .options = 0, 39907+ .read_retry_type = NAND_RR_HYNIX_BG_CDIE, 39908+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39909+ .flags = NAND_RANDOMIZER, 39910+ }, 39911+ 39912+/********************** MISC ******************************************/ 39913+ { /* MLC 8bit/512 */ 39914+ .name = "P1UAGA30AT-GCA", 39915+ .id = { 0xC8, 0xD5, 0x14, 0x29, 0x34, 0x01, }, 39916+ .length = 6, 39917+ .chipsize = SZ_2G, 39918+ .probe = NULL, 39919+ .pagesize = SZ_4K, 39920+ .erasesize = SZ_512K, 39921+ .oobsize = 218, 39922+ .options = 0, 39923+ .read_retry_type = NAND_RR_NONE, 39924+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39925+ .flags = 0, 39926+ }, 39927+ { /* MLC 4bit/512 */ 39928+ /* 39929+ * PowerFlash ASU8GA30IT-G30CA ID and MIRA PSU8GA30AT-GIA ID are 39930+ * the same ID 39931+ */ 39932+ .name = "PSU8GA30AT-GIA/ASU8GA30IT-G30CA", 39933+ .id = { 0xC8, 0xD3, 0x90, 0x19, 0x34, 0x01, }, 39934+ .length = 6, 39935+ .chipsize = SZ_1G, 39936+ .probe = NULL, 39937+ .pagesize = SZ_4K, 39938+ .erasesize = SZ_256K, 39939+ .oobsize = 218, 39940+ .options = 0, 39941+ .read_retry_type = NAND_RR_NONE, 39942+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39943+ .flags = 0, 39944+ }, 39945+ { /* SLC 1bit/512 */ 39946+ .name = "PSU2GA30AT", 39947+ .id = { 0x7F, 0x7F, 0x7F, 0x7F, 0xC8, 0xDA, 0x00, 0x15, }, 39948+ .length = 8, 39949+ .chipsize = SZ_256M, 39950+ .probe = NULL, 39951+ .pagesize = SZ_2K, 39952+ .erasesize = SZ_128K, 39953+ .oobsize = 64, 39954+ .options = 0, 39955+ .read_retry_type = NAND_RR_NONE, 39956+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, 39957+ .flags = 0, 39958+ }, 39959+ {{0}, 0, 0, 0, 0, 0, 0, 0, 0}, 39960+}; 39961+ 39962+#define NUM_OF_SPECIAL_DEVICE \ 39963+ (sizeof(nand_flash_special_dev) / sizeof(struct nand_flash_special_dev)) 39964+ 39965+int (*hinfc_param_adjust)(struct mtd_info *, struct nand_chip *, 39966+ struct nand_dev_t *) = NULL; 39967+ 39968+static struct nand_dev_t __nand_dev; 39969+ 39970+ 39971+static struct nand_flash_dev *hinfc_nand_probe(struct mtd_info *mtd, 39972+ struct nand_chip *chip, 39973+ struct nand_dev_t *nand_dev) 39974+{ 39975+ struct nand_flash_special_dev *spl_dev = NULL; 39976+ unsigned char *byte = nand_dev->ids; 39977+ struct nand_flash_dev *type = &nand_dev->flash_dev; 39978+ 39979+ hinfc_pr_msg("Nand ID: 0x%02X 0x%02X 0x%02X 0x%02X", 39980+ byte[0], byte[1], byte[2], byte[3]); 39981+ hinfc_pr_msg(" 0x%02X 0x%02X 0x%02X 0x%02X\n", 39982+ byte[4], byte[5], byte[6], byte[7]); 39983+ 39984+ for (spl_dev = nand_flash_special_dev; spl_dev->length; spl_dev++) { 39985+ if (memcmp(byte, spl_dev->id, spl_dev->length)) 39986+ continue; 39987+ 39988+ hinfc_pr_msg("The Special NAND id table Version: %s\n", DRV_VERSION); 39989+ 39990+ if (spl_dev->probe) { 39991+ type = spl_dev->probe(nand_dev); 39992+ } else { 39993+ type->options = spl_dev->options; 39994+ type->pagesize = spl_dev->pagesize; 39995+ type->erasesize = spl_dev->erasesize; 39996+ nand_dev->oobsize = spl_dev->oobsize; 39997+ } 39998+ 39999+ nand_dev->read_retry_type = spl_dev->read_retry_type; 40000+ nand_dev->flags = spl_dev->flags; 40001+ 40002+ type->id[1] = byte[1]; 40003+ type->chipsize = (unsigned long)(spl_dev->chipsize >> 20); 40004+ type->name = spl_dev->name; 40005+ return type; 40006+ } 40007+ nand_dev->read_retry_type = NAND_RR_NONE; 40008+ 40009+ return NULL; 40010+} 40011+ 40012+ 40013+struct nand_flash_dev *hinfc_get_flash_type(struct mtd_info *mtd, 40014+ struct nand_chip *chip, 40015+ u8 *id_data, int *busw) 40016+{ 40017+ struct nand_flash_dev *type = NULL; 40018+ struct nand_dev_t *nand_dev = &__nand_dev; 40019+ 40020+ memset(nand_dev, 0, sizeof(struct nand_dev_t)); 40021+ memcpy(nand_dev->ids, id_data, 8); 40022+ 40023+ if (!hinfc_nand_probe(mtd, chip, nand_dev)) 40024+ return NULL; 40025+ 40026+ type = &nand_dev->flash_dev; 40027+ 40028+ if (!mtd->name) 40029+ mtd->name = type->name; 40030+ 40031+ chip->chipsize = (uint64_t)type->chipsize << 20; 40032+ mtd->erasesize = type->erasesize; 40033+ mtd->writesize = type->pagesize; 40034+ mtd->oobsize = nand_dev->oobsize; 40035+ *busw = (type->options & NAND_BUSWIDTH_16); 40036+ 40037+ return type; 40038+} 40039+ 40040+ 40041+void hinfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip) 40042+{ 40043+ struct nand_dev_t *nand_dev = &__nand_dev; 40044+ 40045+ if (!nand_dev->oobsize) 40046+ nand_dev->oobsize = mtd->oobsize; 40047+ 40048+ if (hinfc_param_adjust) 40049+ hinfc_param_adjust(mtd, chip, nand_dev); 40050+} 40051+ 40052+ 40053+void hinfc_show_info(struct mtd_info *mtd, const char *vendor, char *chipname) 40054+{ 40055+ struct nand_dev_t *nand_dev = &__nand_dev; 40056+ 40057+ if (IS_NAND_RANDOM(nand_dev)) 40058+ hinfc_pr_msg("Randomizer \n"); 40059+ 40060+ if (nand_dev->read_retry_type != NAND_RR_NONE) 40061+ hinfc_pr_msg("Read-Retry \n"); 40062+ 40063+ if (nand_dev->start_type) 40064+ hinfc_pr_msg("Nand(%s): ", nand_dev->start_type); 40065+ else 40066+ hinfc_pr_msg("Nand: "); 40067+ 40068+ hinfc_pr_msg("OOB:%dB ", nand_dev->oobsize); 40069+ hinfc_pr_msg("ECC:%s ", nand_ecc_name(nand_dev->ecctype)); 40070+} 40071+ 40072+ 40073+void hinfc_show_chipsize(struct nand_chip *chip) 40074+{ 40075+} 40076diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h 40077index 012876e14..be6bb9c30 100644 40078--- a/drivers/mtd/nand/raw/internals.h 40079+++ b/drivers/mtd/nand/raw/internals.h 40080@@ -17,8 +17,12 @@ 40081 * NAND Flash Manufacturer ID Codes 40082 */ 40083 #define NAND_MFR_AMD 0x01 40084-#define NAND_MFR_ATO 0x9b 40085 #define NAND_MFR_EON 0x92 40086+#define NAND_MFR_WINBOND 0xef 40087+#define NAND_MFR_ATO 0x9b 40088+#define NAND_MFR_MXIC 0xc2 40089+#define NAND_MFR_ALL_FLASH 0xc1 40090+#define NAND_MFR_PARAGON 0xa1 40091 #define NAND_MFR_ESMT 0xc8 40092 #define NAND_MFR_FUJITSU 0x04 40093 #define NAND_MFR_HYNIX 0xad 40094@@ -32,7 +36,10 @@ 40095 #define NAND_MFR_STMICRO 0x20 40096 /* Kioxia is new name of Toshiba memory. */ 40097 #define NAND_MFR_TOSHIBA 0x98 40098-#define NAND_MFR_WINBOND 0xef 40099+#define NAND_MFR_GD_ESMT 0xc8 40100+#define NAND_MFR_HEYANGTEK 0xc9 40101+#define NAND_MFR_DOSILICON 0xe5 40102+#define NAND_MFR_FIDELIX 0xf8 40103 40104 /** 40105 * struct nand_manufacturer_ops - NAND Manufacturer operations 40106diff --git a/drivers/mtd/nand/raw/match_table.c b/drivers/mtd/nand/raw/match_table.c 40107new file mode 100644 40108index 000000000..6bad75f97 40109--- /dev/null 40110+++ b/drivers/mtd/nand/raw/match_table.c 40111@@ -0,0 +1,102 @@ 40112+/****************************************************************************** 40113+ * COPYRIGHT (C) Hisilicon.2013 40114+ * All rights reserved. 40115+ * *** 40116+ * Create by Hisilicon 2013-08-15 40117+ * 40118+ *****************************************************************************/ 40119+ 40120+#include <linux/string.h> 40121+#include "match_table.h" 40122+ 40123+int reg2type(struct match_reg_type *table, int length, int reg, int def) 40124+{ 40125+ while (length-- > 0) { 40126+ if (table->reg == reg) { 40127+ return table->type; 40128+ } 40129+ table++; 40130+ } 40131+ return def; 40132+} 40133+ 40134+int type2reg(struct match_reg_type *table, int length, int type, int def) 40135+{ 40136+ while (length-- > 0) { 40137+ if (table->type == type) { 40138+ return table->reg; 40139+ } 40140+ table++; 40141+ } 40142+ return def; 40143+} 40144+ 40145+int str2type(struct match_type_str *table, int length, const char *str, 40146+ int size, int def) 40147+{ 40148+ while (length-- > 0) { 40149+ if (!strncmp(table->str, str, size)) { 40150+ return table->type; 40151+ } 40152+ table++; 40153+ } 40154+ return def; 40155+} 40156+ 40157+const char *type2str(struct match_type_str *table, int length, int type, 40158+ const char *def) 40159+{ 40160+ while (length-- > 0) { 40161+ if (table->type == type) { 40162+ return table->str; 40163+ } 40164+ table++; 40165+ } 40166+ return def; 40167+} 40168+ 40169+int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def) 40170+{ 40171+ while (nr_table-- > 0) { 40172+ if (table->reg == reg) { 40173+ return table->type; 40174+ } 40175+ table++; 40176+ } 40177+ return def; 40178+} 40179+ 40180+int match_type_to_reg(struct match_t *table, int nr_table, int type, int def) 40181+{ 40182+ while (nr_table-- > 0) { 40183+ if (table->type == type) { 40184+ return table->reg; 40185+ } 40186+ table++; 40187+ } 40188+ return def; 40189+} 40190+ 40191+int match_data_to_type(struct match_t *table, int nr_table, const char *data, 40192+ int size, int def) 40193+{ 40194+ while (nr_table-- > 0) { 40195+ if (!memcmp(table->data, data, size)) { 40196+ return table->type; 40197+ } 40198+ table++; 40199+ } 40200+ return def; 40201+} 40202+ 40203+void *match_type_to_data(struct match_t *table, int nr_table, int type, 40204+ void *def) 40205+{ 40206+ while (nr_table-- > 0) { 40207+ if (table->type == type) { 40208+ return table->data; 40209+ } 40210+ table++; 40211+ } 40212+ return def; 40213+} 40214diff --git a/drivers/mtd/nand/raw/match_table.h b/drivers/mtd/nand/raw/match_table.h 40215new file mode 100644 40216index 000000000..9c5f0af09 40217--- /dev/null 40218+++ b/drivers/mtd/nand/raw/match_table.h 40219@@ -0,0 +1,51 @@ 40220+/****************************************************************************** 40221+ * COPYRIGHT (C) Hisilicon 2013 40222+ * All rights reserved. 40223+ * *** 40224+ * Create by Hisilicon 2013-08-15 40225+ * 40226+ *****************************************************************************/ 40227+#ifndef __MATCH_TABLE_H__ 40228+#define __MATCH_TABLE_H__ 40229+ 40230+struct match_reg_type { 40231+ int reg; 40232+ int type; 40233+}; 40234+ 40235+struct match_type_str { 40236+ int type; 40237+ const char *str; 40238+}; 40239+ 40240+struct match_t { 40241+ int type; 40242+ int reg; 40243+ void *data; 40244+}; 40245+ 40246+#define MATCH_SET_TYPE_REG(_type, _reg) {(_type), (_reg), (void *)0} 40247+#define MATCH_SET_TYPE_DATA(_type, _data) {(_type), 0, (void *)(_data)} 40248+#define MATCH_SET(_type, _reg, _data) {(_type), (_reg), (void *)(_data)} 40249+ 40250+int reg2type(struct match_reg_type *table, int length, int reg, int def); 40251+ 40252+int type2reg(struct match_reg_type *table, int length, int type, int def); 40253+ 40254+int str2type(struct match_type_str *table, int length, const char *str, 40255+ int size, int def); 40256+ 40257+const char *type2str(struct match_type_str *table, int length, int type, 40258+ const char *def); 40259+ 40260+int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def); 40261+ 40262+int match_type_to_reg(struct match_t *table, int nr_table, int type, int def); 40263+ 40264+int match_data_to_type(struct match_t *table, int nr_table, const char *data, 40265+ int size, int def); 40266+ 40267+void *match_type_to_data(struct match_t *table, int nr_table, int type, 40268+ void *def); 40269+ 40270+#endif /* End of __MATCH_TABLE_H__ */ 40271diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c 40272index 1f0d542d5..e2f2d86e3 100644 40273--- a/drivers/mtd/nand/raw/nand_base.c 40274+++ b/drivers/mtd/nand/raw/nand_base.c 40275@@ -44,6 +44,7 @@ 40276 #include <linux/of.h> 40277 #include <linux/gpio/consumer.h> 40278 40279+#include "hinfc_gen.h" 40280 #include "internals.h" 40281 40282 static int nand_pairing_dist3_get_info(struct mtd_info *mtd, int page, 40283@@ -3968,6 +3969,10 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to, 40284 int ret; 40285 int oob_required = oob ? 1 : 0; 40286 40287+#ifdef CONFIG_ARCH_HISI_BVT 40288+ oob_required = 1; 40289+#endif 40290+ 40291 ops->retlen = 0; 40292 if (!writelen) 40293 return 0; 40294@@ -4695,7 +4700,8 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) 40295 const struct nand_manufacturer_desc *manufacturer_desc; 40296 struct mtd_info *mtd = nand_to_mtd(chip); 40297 struct nand_memory_organization *memorg; 40298- int busw, ret; 40299+ int busw = 0; 40300+ int ret = 0; 40301 u8 *id_data = chip->id.data; 40302 u8 maf_id, dev_id; 40303 u64 targetsize; 40304@@ -4752,6 +4758,30 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) 40305 manufacturer_desc = nand_get_manufacturer_desc(maf_id); 40306 chip->manufacturer.desc = manufacturer_desc; 40307 40308+#ifdef CONFIG_ARCH_HISI_BVT 40309+ 40310+#ifndef CONFIG_MTD_SPI_NAND_HISI_BVT 40311+ /* Parallel Nand Flash */ 40312+ 40313+ /* The 3rd id byte holds MLC / multichip data */ 40314+ chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]); 40315+#endif 40316+ 40317+ if (get_spi_nand_flash_type_hook) 40318+ type = get_spi_nand_flash_type_hook(mtd, id_data); 40319+ 40320+ if (type) 40321+ goto ident_done; 40322+#ifdef CONFIG_MTD_SPI_NAND_HISI_BVT 40323+ else { 40324+ pr_info("This device[%02x,%02x] cannot found in spi nand id table!!\n", 40325+ maf_id, dev_id); 40326+ return -ENODEV; 40327+ } 40328+#endif 40329+ 40330+#endif /* endif CONFIG_ARCH_HISI_BVT */ 40331+ 40332 if (!type) 40333 type = nand_flash_ids; 40334 40335@@ -4816,12 +4846,16 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) 40336 memorg->pages_per_eraseblock); 40337 40338 ident_done: 40339+#ifdef CONFIG_ARCH_HISI_BVT 40340+ hinfc_nand_param_adjust(mtd, chip); 40341+#endif 40342 if (!mtd->name) 40343 mtd->name = chip->parameters.model; 40344 40345 if (chip->options & NAND_BUSWIDTH_AUTO) { 40346 WARN_ON(busw & NAND_BUSWIDTH_16); 40347 nand_set_defaults(chip); 40348+ printk("NAND_BUSWIDTH_AUTO,line:%d",__LINE__); 40349 } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { 40350 /* 40351 * Check, if buswidth is correct. Hardware drivers should set 40352@@ -4869,6 +4903,10 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) 40353 pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", 40354 (int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", 40355 mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); 40356+ 40357+ /* Print ecc type and ecc mode about hisilicon flash controller */ 40358+ hinfc_show_info(mtd, nand_manufacturer_name(manufacturer_desc), type->name); 40359+ 40360 return 0; 40361 40362 free_detect_allocation: 40363diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c 40364index b9945791a..e59b4f017 100644 40365--- a/drivers/mtd/nand/raw/nand_ids.c 40366+++ b/drivers/mtd/nand/raw/nand_ids.c 40367@@ -172,6 +172,11 @@ static const struct nand_manufacturer_desc nand_manufacturer_descs[] = { 40368 {NAND_MFR_AMD, "AMD/Spansion", &amd_nand_manuf_ops}, 40369 {NAND_MFR_ATO, "ATO"}, 40370 {NAND_MFR_EON, "Eon"}, 40371+ {NAND_MFR_WINBOND, "Winbond"}, 40372+ {NAND_MFR_ATO, "ATO"}, 40373+ {NAND_MFR_MXIC, "MXIC"}, 40374+ {NAND_MFR_ALL_FLASH, "All-flash"}, 40375+ {NAND_MFR_PARAGON, "Paragon"}, 40376 {NAND_MFR_ESMT, "ESMT", &esmt_nand_manuf_ops}, 40377 {NAND_MFR_FUJITSU, "Fujitsu"}, 40378 {NAND_MFR_HYNIX, "Hynix", &hynix_nand_manuf_ops}, 40379@@ -184,7 +189,10 @@ static const struct nand_manufacturer_desc nand_manufacturer_descs[] = { 40380 {NAND_MFR_SANDISK, "SanDisk"}, 40381 {NAND_MFR_STMICRO, "ST Micro"}, 40382 {NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops}, 40383- {NAND_MFR_WINBOND, "Winbond"}, 40384+ {NAND_MFR_HEYANGTEK, "HeYangTek"}, 40385+ {NAND_MFR_DOSILICON, "Dosilicon"}, 40386+ {NAND_MFR_FIDELIX, "Fidelix/Dosi"}, /* Fidelix was purchased by Dosilicon */ 40387+ {0x0, "Unknown"} 40388 }; 40389 40390 /** 40391diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig 40392index 5c0e0ec2e..bffa9c1a6 100644 40393--- a/drivers/mtd/spi-nor/controllers/Kconfig 40394+++ b/drivers/mtd/spi-nor/controllers/Kconfig 40395@@ -10,11 +10,12 @@ config SPI_ASPEED_SMC 40396 the host firmware. The implementation only supports SPI NOR. 40397 40398 config SPI_HISI_SFC 40399- tristate "Hisilicon FMC SPI NOR Flash Controller(SFC)" 40400- depends on ARCH_HISI || COMPILE_TEST 40401- depends on HAS_IOMEM 40402+ tristate "Hisilicon FMCV100 SPI-NOR Flash Controller(SFC)" 40403+ depends on ARCH_HISI || ARCH_HISI_BVT || COMPILE_TEST 40404+ depends on HAS_IOMEM && HAS_DMA 40405 help 40406- This enables support for HiSilicon FMC SPI NOR flash controller. 40407+ This enables support for hisilicon flash memory contrller ver100 40408+ (FMCV100)- SPI-NOR flash controller. 40409 40410 config SPI_NXP_SPIFI 40411 tristate "NXP SPI Flash Interface (SPIFI)" 40412@@ -62,3 +63,31 @@ config SPI_INTEL_SPI_PLATFORM 40413 40414 To compile this driver as a module, choose M here: the module 40415 will be called intel-spi-platform. 40416+ 40417+config MTD_SPI_IDS 40418+ bool "SPI Flash Timing Cycles Probe Function" 40419+ default n 40420+ help 40421+ This option enables hisfc300/hisfc350 used spi flash timing cylces 40422+ probe function. 40423+ If your use hisfc300 and hisfc350, this function should be select. 40424+ 40425+config CLOSE_SPI_8PIN_4IO 40426+ bool "Close SPI device Quad SPI mode for some 8PIN chip" 40427+ default y if ARCH_HISI_BVT 40428+ help 40429+ Hifmcv100 and Hisfcv350 support Quad SPI mode and Quad&addr SPI mode. 40430+ But some 8PIN chip does not support this mode when HOLD/IO3 PIN 40431+ was used by reset operation. 40432+ Usually, your should not config this option. 40433+ 40434+config HISI_SPI_BLOCK_PROTECT 40435+ bool "Hisilicon Spi Nor Device BP(Block Protect) Support" 40436+ depends on SPI_HISI_SFC 40437+ default y if SPI_HISI_SFC 40438+ help 40439+ HISI SFC supports BP(Block Protect) feature to preestablish a series 40440+ area to avoid writing and erasing, except to reading. With this macro 40441+ definition we can get the BP info which was setted before. The 40442+ BOTTOM/TOP bit is setted to BOTTOM, it means the lock area starts 40443+ from 0 address. 40444diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig 40445index 44f9279cd..cf0b370d0 100644 40446--- a/drivers/net/ethernet/hisilicon/Kconfig 40447+++ b/drivers/net/ethernet/hisilicon/Kconfig 40448@@ -137,4 +137,6 @@ config HNS3_ENET 40449 40450 endif #HNS3 40451 40452+source "drivers/net/ethernet/hisilicon/higmac/Kconfig" 40453+ 40454 endif # NET_VENDOR_HISILICON 40455diff --git a/drivers/net/ethernet/hisilicon/Makefile b/drivers/net/ethernet/hisilicon/Makefile 40456index 7f76d4120..95598fffc 100644 40457--- a/drivers/net/ethernet/hisilicon/Makefile 40458+++ b/drivers/net/ethernet/hisilicon/Makefile 40459@@ -8,4 +8,5 @@ obj-$(CONFIG_HIP04_ETH) += hip04_eth.o 40460 obj-$(CONFIG_HNS_MDIO) += hns_mdio.o 40461 obj-$(CONFIG_HNS) += hns/ 40462 obj-$(CONFIG_HNS3) += hns3/ 40463-obj-$(CONFIG_HISI_FEMAC) += hisi_femac.o 40464+obj-$(CONFIG_HISI_FEMAC) += hisi-femac/ 40465+obj-$(CONFIG_HIETH_GMAC) += higmac/ 40466diff --git a/drivers/net/ethernet/hisilicon/higmac/Kconfig b/drivers/net/ethernet/hisilicon/higmac/Kconfig 40467new file mode 100644 40468index 000000000..97b173e00 40469--- /dev/null 40470+++ b/drivers/net/ethernet/hisilicon/higmac/Kconfig 40471@@ -0,0 +1,106 @@ 40472+# 40473+# higmac family network device configuration 40474+# 40475+ 40476+menuconfig HIETH_GMAC 40477+ tristate "hieth gmac family network device support" 40478+ select PHYLIB 40479+ select RESET_CONTROLLER 40480+ help 40481+ This selects the hieth gmac family network device. 40482+ The gigabit switch fabric (GSF) receives and transmits data over Ethernet 40483+ ports at 10/100/1000 Mbit/s in full-duplex or half-duplex mode. 40484+ The Ethernet port exchanges data with the CPU port, and supports 40485+ the energy efficient Ethernet (EEE) and wake on LAN (WoL) functions. 40486+ 40487+if HIETH_GMAC 40488+ 40489+config HIGMAC_DDR_64BIT 40490+ bool "higmac ddr width 64 bit" 40491+ depends on ARM64 40492+ default n 40493+ help 40494+ This define the higmac supports DDR width 64 bit. 40495+ In the newest version, the DDR size may be 8G. 40496+ But in old version, the higmac only supports DDR width 32 bit. 40497+ The default value is false. 40498+ 40499+config HIGMAC_DESC_4WORD 40500+ bool "higmac descriptor size is 4 words" 40501+ default y 40502+ help 40503+ This define the size of higmac descriptor structure. 40504+ In the newest version, descriptor size is 4 words. 40505+ But in some old version, the size is 8 words. 40506+ The default value is true. 40507+ 40508+config HIGMAC_RXCSUM 40509+ bool "higmac Receive checksumming offload supported" 40510+ default y 40511+ help 40512+ This indicate MAC support Receive checksumming offload. 40513+ Support IPv4 and IPv6, tcp and udp. 40514+ The default value is enabled. 40515+ If old version MAC does not support, disable this option please. 40516+ 40517+config RX_FLOW_CTRL_SUPPORT 40518+ bool "rx flow ctrl supported" 40519+ default y 40520+ help 40521+ Rx flow ctrl supported, default is enabled. 40522+ When we received pause frame, 40523+ we will stop transmiting data frame for some time. 40524+ The stopping time is the time filled in pause frame. 40525+ 40526+config TX_FLOW_CTRL_SUPPORT 40527+ bool "tx flow ctrl supported" 40528+ default y 40529+ help 40530+ Tx flow ctrl supported, default is enabled. 40531+ When we has no buffer to receive packet, 40532+ we will send pause frame. 40533+ When buffer is available, we will send zero-quanta pause frame. 40534+ 40535+config TX_FLOW_CTRL_PAUSE_TIME 40536+ hex "tx flow ctrl pause time" 40537+ default "0xFFFF" 40538+ help 40539+ The pause time filled in the sending pause frame. 40540+ The unit is the time for transmiting 512 bit data. 40541+ This value is 16 bit, so its value is 0x0000~0xFFFF. 40542+ The default value is 0xFFFF. 40543+ 40544+config TX_FLOW_CTRL_PAUSE_INTERVAL 40545+ hex "tx flow ctrl pause interval" 40546+ default "0xFFFF" 40547+ help 40548+ The interval time for sending pause frame. 40549+ When the remainint amount of receive queue is below tx flow ctrl active threshold, 40550+ we will wait this time to transmiting pause frame. 40551+ The unit is the time for transmiting 512 bit data. 40552+ This value is 16 bit, so its value is 0x0000~0xFFFF. 40553+ The default value is 0xFFFF. 40554+ 40555+config TX_FLOW_CTRL_ACTIVE_THRESHOLD 40556+ int "tx flow ctrl active threshold" 40557+ default "16" 40558+ range 1 127 40559+ help 40560+ The threshold for activing tx flow ctrl. 40561+ When the left amount of receive queue descriptors is below this threshold, 40562+ hardware will send pause frame immediately. 40563+ We advise this value is set smaller than 64. Too bigger is not a good choice. 40564+ This value must be smaller than tx flow ctrl deactive threshold. 40565+ 40566+config TX_FLOW_CTRL_DEACTIVE_THRESHOLD 40567+ int "tx flow ctrl deactive threshold" 40568+ default "32" 40569+ range 1 127 40570+ help 40571+ The threshold for deactiving tx flow ctrl. 40572+ When the left amount of receive queue descriptors is above or equal with this threshold, 40573+ hardware will exit flow control state. 40574+ We advise this value is set smaller than 64. Too bigger is not a good choice. 40575+ This value must be larger than tx flow ctrl active threshold. 40576+ 40577+endif # HIETH_GMAC 40578diff --git a/drivers/net/ethernet/hisilicon/higmac/Makefile b/drivers/net/ethernet/hisilicon/higmac/Makefile 40579new file mode 100644 40580index 000000000..b19e27d42 40581--- /dev/null 40582+++ b/drivers/net/ethernet/hisilicon/higmac/Makefile 40583@@ -0,0 +1,2 @@ 40584+obj-$(CONFIG_HIETH_GMAC) += hieth-gmac.o 40585+hieth-gmac-objs := board.o higmac.o pm.o util.o autoeee/autoeee.o autoeee/phy_id_table.o 40586diff --git a/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.c b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.c 40587new file mode 100644 40588index 000000000..05c2b6205 40589--- /dev/null 40590+++ b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.c 40591@@ -0,0 +1,162 @@ 40592+/* 40593+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 40594+ * Description: Higmac driver autoeee process 40595+ * Author: KTP_BSP 40596+ * Create: 2018-10-08 40597+ */ 40598+ 40599+#include "autoeee.h" 40600+#include "../higmac.h" 40601+#include <linux/phy.h> 40602+#include <linux/micrel_phy.h> 40603+ 40604+static u32 set_link_stat(struct higmac_netdev_local const *ld) 40605+{ 40606+ u32 link_stat = 0; 40607+ 40608+ switch (ld->phy->speed) { 40609+ case SPEED_10: 40610+ link_stat |= HIGMAC_SPD_10M; 40611+ break; 40612+ case SPEED_100: 40613+ link_stat |= HIGMAC_SPD_100M; 40614+ break; 40615+ case SPEED_1000: 40616+ link_stat |= HIGMAC_SPD_1000M; 40617+ break; 40618+ default: 40619+ break; 40620+ } 40621+ return link_stat; 40622+} 40623+ 40624+static void set_eee_clk(struct higmac_netdev_local const *ld, u32 phy_id) 40625+{ 40626+ u32 v; 40627+ 40628+ if ((phy_id & REALTEK_PHY_MASK) == REALTEK_PHY_ID_8211E) { 40629+ v = readl(ld->gmac_iobase + EEE_CLK); 40630+ v &= ~MASK_EEE_CLK; 40631+ v |= BIT_DISABLE_TX_CLK; 40632+ writel(v, ld->gmac_iobase + EEE_CLK); 40633+ } else if ((phy_id & MICREL_PHY_ID_MASK) == PHY_ID_KSZ9031) { 40634+ v = readl(ld->gmac_iobase + EEE_CLK); 40635+ v &= ~MASK_EEE_CLK; 40636+ v |= (BIT_DISABLE_TX_CLK | BIT_PHY_KSZ9031); 40637+ writel(v, ld->gmac_iobase + EEE_CLK); 40638+ } 40639+} 40640+ 40641+static void enable_eee(struct higmac_netdev_local const *ld) 40642+{ 40643+ u32 v; 40644+ 40645+ /* EEE_1us: 0x7c for 125M */ 40646+ writel(0x7c, ld->gmac_iobase + 40647+ EEE_TIME_CLK_CNT); 40648+ writel(0x1e0400, ld->gmac_iobase + EEE_TIMER); 40649+ 40650+ v = readl(ld->gmac_iobase + EEE_LINK_STATUS); 40651+ v |= 0x3 << 1; /* auto EEE and ... */ 40652+ v |= BIT_PHY_LINK_STATUS; /* phy linkup */ 40653+ writel(v, ld->gmac_iobase + EEE_LINK_STATUS); 40654+ 40655+ v = readl(ld->gmac_iobase + EEE_ENABLE); 40656+ v |= BIT_EEE_ENABLE; /* enable EEE */ 40657+ writel(v, ld->gmac_iobase + EEE_ENABLE); 40658+} 40659+ 40660+static void set_phy_eee_mode(struct higmac_netdev_local const *ld) 40661+{ 40662+ u32 v; 40663+ if (netif_msg_wol(ld)) 40664+ pr_info("enter phy-EEE mode\n"); 40665+ 40666+ v = readl(ld->gmac_iobase + EEE_ENABLE); 40667+ v &= ~BIT_EEE_ENABLE; /* disable auto-EEE */ 40668+ writel(v, ld->gmac_iobase + EEE_ENABLE); 40669+} 40670+ 40671+void init_autoeee(struct higmac_netdev_local *ld) 40672+{ 40673+ int phy_id; 40674+ int eee_available, lp_eee_capable; 40675+ u32 v, link_stat; 40676+ struct phy_info *phy_info = NULL; 40677+ if (ld == NULL || ld->eee_init == NULL || ld->phy == NULL) 40678+ return; 40679+ phy_id = ld->phy->phy_id; 40680+ if (ld->eee_init != NULL) 40681+ goto eee_init; 40682+ 40683+ phy_info = phy_search_ids(phy_id); 40684+ if (phy_info == NULL) 40685+ goto not_support; 40686+ 40687+ eee_available = phy_info->eee_available; 40688+ if (netif_msg_wol(ld) && phy_info->name != NULL) 40689+ pr_info("fit phy_id:0x%x, phy_name:%s, eee:%d\n", 40690+ phy_info->phy_id, phy_info->name, eee_available); 40691+ 40692+ if (!eee_available) 40693+ goto not_support; 40694+ 40695+ if (eee_available == PHY_EEE) { 40696+ set_phy_eee_mode(ld); 40697+ return; 40698+ } 40699+ 40700+ ld->eee_init = phy_info->eee_init; 40701+eee_init: 40702+ link_stat = set_link_stat(ld); 40703+ 40704+ lp_eee_capable = ld->eee_init(ld->phy); 40705+ if (lp_eee_capable < 0) 40706+ return; 40707+ 40708+ if (ld->phy->link) { 40709+ if (((u32)lp_eee_capable) & link_stat) { 40710+ set_eee_clk(ld, phy_id); 40711+ enable_eee(ld); 40712+ 40713+ if (netif_msg_wol(ld)) 40714+ pr_info("enter auto-EEE mode\n"); 40715+ } else { 40716+ if (netif_msg_wol(ld)) 40717+ pr_info("link partner not support EEE\n"); 40718+ } 40719+ } else { 40720+ v = readl(ld->gmac_iobase + EEE_LINK_STATUS); 40721+ v &= ~(BIT_PHY_LINK_STATUS); /* phy linkdown */ 40722+ writel(v, ld->gmac_iobase + EEE_LINK_STATUS); 40723+ } 40724+ 40725+ return; 40726+ 40727+not_support: 40728+ ld->eee_init = NULL; 40729+ if (netif_msg_wol(ld)) 40730+ pr_info("non-EEE mode\n"); 40731+} 40732+ 40733+void eee_phy_linkdown(struct higmac_netdev_local const *ld) 40734+{ 40735+ u32 v; 40736+ if (ld == NULL) 40737+ return; 40738+ v = readl(ld->gmac_iobase + EEE_LINK_STATUS); 40739+ /* update phy link state */ 40740+ v &= ~BIT_PHY_LINK_STATUS; 40741+ writel(v, ld->gmac_iobase + EEE_LINK_STATUS); 40742+} 40743+ 40744+void eee_phy_linkup(struct higmac_netdev_local const *ld) 40745+{ 40746+ u32 v; 40747+ if (ld == NULL) 40748+ return; 40749+ v = readl(ld->gmac_iobase + EEE_LINK_STATUS); 40750+ /* update phy link state */ 40751+ v |= BIT_PHY_LINK_STATUS; 40752+ writel(v, ld->gmac_iobase + EEE_LINK_STATUS); 40753+} 40754diff --git a/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.h b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.h 40755new file mode 100644 40756index 000000000..30cbb9799 40757--- /dev/null 40758+++ b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.h 40759@@ -0,0 +1,52 @@ 40760+/* 40761+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 40762+ * Description: autoeee head file 40763+ * Author: KTP_BSP 40764+ * Create: 2018-10-08 40765+ */ 40766+ 40767+#ifndef _AUTO_EEE_H 40768+#define _AUTO_EEE_H 40769+ 40770+#include "../higmac.h" 40771+ 40772+#define NO_EEE 0 40773+#define MAC_EEE 1 40774+#define PHY_EEE 2 40775+#define PARTNER_EEE 2 40776+ 40777+struct phy_info { 40778+ char *name; 40779+ int phy_id; 40780+ char eee_available; /* eee support by this phy */ 40781+ int (*eee_init)(struct phy_device *phy_dev); 40782+}; 40783+ 40784+/* GMAC register definition */ 40785+#define EEE_CLK 0x800 40786+#define MASK_EEE_CLK (0x3 << 20) 40787+#define BIT_DISABLE_TX_CLK BIT(21) 40788+#define BIT_PHY_KSZ9031 BIT(20) 40789+#define EEE_ENABLE 0x808 40790+#define BIT_EEE_ENABLE BIT(0) 40791+#define EEE_TIMER 0x80C 40792+#define EEE_LINK_STATUS 0x810 40793+#define BIT_PHY_LINK_STATUS BIT(0) 40794+#define EEE_TIME_CLK_CNT 0x814 40795+ 40796+/* ----------------------------phy register-------------------------------*/ 40797+/* MMD: MDIO Manageable Device */ 40798+#define MACR 0x0D 40799+#define MAADR 0x0E 40800+#define EEE_DEV 0x3 40801+#define EEE_CAPABILITY 0x14 40802+#define EEELPAR_DEV 0x7 40803+#define EEELPAR 0x3D /* EEE link partner ability register */ 40804+#define EEE_ADVERTISE 0x3c 40805+#define LP_1000BASE_EEE BIT(2) 40806+#define LP_100BASE_EEE BIT(1) 40807+ 40808+struct phy_info *phy_search_ids(int phy_id); 40809+void init_autoeee(struct higmac_netdev_local *ld); 40810+ 40811+#endif 40812diff --git a/drivers/net/ethernet/hisilicon/higmac/autoeee/phy_id_table.c b/drivers/net/ethernet/hisilicon/higmac/autoeee/phy_id_table.c 40813new file mode 100644 40814index 000000000..d98bbf1f0 40815--- /dev/null 40816+++ b/drivers/net/ethernet/hisilicon/higmac/autoeee/phy_id_table.c 40817@@ -0,0 +1,184 @@ 40818+/* 40819+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 40820+ * Description: Higmac phy id table 40821+ * Author: KTP_BSP 40822+ * Create: 2018-10-08 40823+ */ 40824+ 40825+#include "../higmac.h" 40826+#include "autoeee.h" 40827+#include <linux/delay.h> 40828+#include <linux/kernel.h> 40829+#include <linux/phy.h> 40830+ 40831+struct phy_info phy_info_table[]; 40832+ 40833+struct phy_info *phy_search_ids(int phy_id) 40834+{ 40835+ int i; 40836+ struct phy_info *fit_info = NULL; 40837+ 40838+ for (i = 0; phy_info_table[i].name; i++) { 40839+ if (phy_id == phy_info_table[i].phy_id) { 40840+ fit_info = &phy_info_table[i]; 40841+ break; 40842+ } 40843+ } 40844+ 40845+ return fit_info; 40846+} 40847+ 40848+static inline int phy_mmd_read(struct phy_device *phy_dev, 40849+ u32 mmd_device, u32 regnum) 40850+{ 40851+ phy_write(phy_dev, MACR, mmd_device); /* function = 00 address */ 40852+ phy_write(phy_dev, MAADR, regnum); 40853+ phy_write(phy_dev, MACR, 0x4000 | mmd_device); /* function = 01 data */ 40854+ 40855+ return phy_read(phy_dev, MAADR); 40856+} 40857+ 40858+static inline int phy_mmd_write(struct phy_device *phy_dev, u32 mmd_device, 40859+ u32 regnum, u16 val) 40860+{ 40861+ phy_write(phy_dev, MACR, mmd_device); /* function = 00 address */ 40862+ phy_write(phy_dev, MAADR, regnum); 40863+ phy_write(phy_dev, MACR, 0x4000 | mmd_device); /* function = 01 data */ 40864+ 40865+ return phy_write(phy_dev, MAADR, val); 40866+} 40867+ 40868+static int smsc_lan8740_init(struct phy_device *phy_dev) 40869+{ 40870+ static int first_time = 0; 40871+ int v; 40872+ u32 eee_type = 0; 40873+ 40874+ if (!first_time) { 40875+ /* Realtek LAN 8740 start to enable eee */ 40876+ int eee_lan; 40877+ 40878+ eee_lan = phy_read(phy_dev, 0x10); 40879+ if (eee_lan < 0) 40880+ return eee_lan; 40881+ eee_lan = (u32)eee_lan | 0x4; 40882+ phy_write(phy_dev, 0x10, eee_lan); 40883+ eee_lan = phy_read(phy_dev, 0x10); 40884+ if (eee_lan < 0) 40885+ return eee_lan; 40886+ /* auto negotiate after enable eee */ 40887+ eee_lan = phy_read(phy_dev, 0x0); 40888+ if (eee_lan < 0) 40889+ return eee_lan; 40890+ eee_lan = (u32)eee_lan | 0x200; 40891+ phy_write(phy_dev, 0x0, eee_lan); 40892+ first_time = 1; 40893+ } 40894+ 40895+ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); 40896+ if ((u32)v & LP_1000BASE_EEE) 40897+ eee_type |= HIGMAC_SPD_1000M; 40898+ if ((u32)v & LP_100BASE_EEE) 40899+ eee_type |= HIGMAC_SPD_100M; 40900+ 40901+ return (int)eee_type; 40902+} 40903+ 40904+#define RTL8211EG_MAC 0 40905+#if RTL8211EG_MAC 40906+static int rtl8211eg_mac_init(struct phy_device *phy_dev) 40907+{ 40908+ static int first_time = 0; 40909+ /* Realtek 8211EG start reset to change eee to mac */ 40910+ int v; 40911+ u32 eee_type = 0; 40912+ 40913+ if (!first_time) { 40914+ int tmp; 40915+ 40916+ phy_write(phy_dev, 0x1f, 0x0); 40917+ phy_write(phy_dev, MII_BMCR, BMCR_RESET); /* reset phy */ 40918+ do { /* wait phy restart over */ 40919+ udelay(1); 40920+ tmp = phy_read(phy_dev, MII_BMSR); 40921+ /* no need to wait AN finished */ 40922+ tmp &= (BMSR_ANEGCOMPLETE | BMSR_ANEGCAPABLE); 40923+ } while (!tmp); 40924+ 40925+ phy_write(phy_dev, 0x1f, 0x7); 40926+ phy_write(phy_dev, 0x1e, 0x20); 40927+ phy_write(phy_dev, 0x1b, 0xa03a); 40928+ phy_write(phy_dev, 0x1f, 0x0); 40929+ 40930+ first_time = 1; 40931+ } 40932+ 40933+ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); 40934+ if ((u32)v & LP_1000BASE_EEE) 40935+ eee_type |= HIGMAC_SPD_1000M; 40936+ if ((u32)v & LP_100BASE_EEE) 40937+ eee_type |= HIGMAC_SPD_100M; 40938+ 40939+ return (int)eee_type; 40940+} 40941+#else 40942+static int rtl8211eg_init(struct phy_device *phy_dev) 40943+{ 40944+ u32 eee_type = 0; 40945+ u32 v; 40946+ 40947+ v = (u32)phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); 40948+ if (v & LP_1000BASE_EEE) 40949+ eee_type |= HIGMAC_SPD_1000M; 40950+ if (v & LP_100BASE_EEE) 40951+ eee_type |= HIGMAC_SPD_100M; 40952+ 40953+ return (int)eee_type; 40954+} 40955+#endif 40956+ 40957+static int festa_v200_init(struct phy_device *phy_dev) 40958+{ 40959+ static int first_time_init = 0; 40960+ int v; 40961+ u32 eee_type = 0; 40962+ 40963+ if (!first_time_init) { 40964+ /* EEE_CAPABILITY register: support 100M-BaseT */ 40965+ v = phy_mmd_read(phy_dev, EEE_DEV, EEE_CAPABILITY); 40966+ phy_mmd_write(phy_dev, EEE_DEV, EEE_CAPABILITY, 40967+ ((u32)v) | BIT(1)); 40968+ 40969+ /* EEE_ADVERTISEMENT register: advertising 100M-BaseT */ 40970+ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEE_ADVERTISE); 40971+ phy_mmd_write(phy_dev, EEELPAR_DEV, EEE_ADVERTISE, 40972+ ((u32)v) | BIT(1)); 40973+ 40974+ v = phy_read(phy_dev, MII_BMCR); 40975+ if (v < 0) 40976+ return v; 40977+ v = (u32)v | (BMCR_ANENABLE | BMCR_ANRESTART); 40978+ phy_write(phy_dev, MII_BMCR, v); /* auto-neg restart */ 40979+ 40980+ first_time_init = 1; 40981+ } 40982+ 40983+ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); 40984+ if ((u32)v & LP_1000BASE_EEE) 40985+ eee_type |= HIGMAC_SPD_1000M; 40986+ if ((u32)v & LP_100BASE_EEE) 40987+ eee_type |= HIGMAC_SPD_100M; 40988+ 40989+ return (int)eee_type; 40990+} 40991+ 40992+struct phy_info phy_info_table[] = { 40993+ /* phy_name phy_id eee_available phy_driver */ 40994+ {"SMSC LAN8740", 0x0007c110, MAC_EEE, &smsc_lan8740_init}, 40995+#if RTL8211EG_MAC 40996+ {"Realtek 8211EG", 0x001cc915, MAC_EEE, &rtl8211eg_mac_init}, 40997+#else 40998+ {"Realtek 8211EG", 0x001cc915, PHY_EEE, &rtl8211eg_init}, 40999+#endif 41000+ {"Festa V200", HISILICON_PHY_ID_FESTAV200, MAC_EEE, &festa_v200_init}, 41001+}; 41002diff --git a/drivers/net/ethernet/hisilicon/higmac/board.c b/drivers/net/ethernet/hisilicon/higmac/board.c 41003new file mode 100644 41004index 000000000..b7a1d879d 41005--- /dev/null 41006+++ b/drivers/net/ethernet/hisilicon/higmac/board.c 41007@@ -0,0 +1,118 @@ 41008+/* 41009+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 41010+ * Description: Higmac driver board file 41011+ * Author: KTP_BSP 41012+ * Create: 2018-10-08 41013+ */ 41014+ 41015+#include <linux/clk.h> 41016+#include <linux/kernel.h> 41017+#include <linux/reset.h> 41018+#include "higmac.h" 41019+ 41020+void higmac_mac_core_reset(struct higmac_netdev_local *priv) 41021+{ 41022+ /* undo reset */ 41023+ if (priv == NULL || priv->port_rst == NULL) 41024+ return; 41025+ reset_control_deassert(priv->port_rst); 41026+ usleep_range(50, 60); /* wait 50~60us */ 41027+ 41028+ /* soft reset mac port */ 41029+ reset_control_assert(priv->port_rst); 41030+ usleep_range(50, 60); /* wait 50~60us */ 41031+ /* undo reset */ 41032+ reset_control_deassert(priv->port_rst); 41033+} 41034+ 41035+void higmac_hw_internal_phy_reset(struct higmac_netdev_local *priv) 41036+{ 41037+} 41038+ 41039+void higmac_hw_phy_reset(struct higmac_netdev_local *priv) 41040+{ 41041+ if (priv == NULL) 41042+ return; 41043+ if (priv->internal_phy) 41044+ higmac_hw_internal_phy_reset(priv); 41045+ else 41046+ higmac_hw_external_phy_reset(priv); 41047+} 41048+ 41049+void higmac_hw_external_phy_reset(struct higmac_netdev_local *priv) 41050+{ 41051+ if (priv == NULL) 41052+ return; 41053+ if (priv->phy_rst != NULL) { 41054+ /* write 0 to cancel reset */ 41055+ reset_control_deassert(priv->phy_rst); 41056+ msleep(50); /* wait 50ms */ 41057+ 41058+ /* HIFONE or 98cv200 use CRG register to reset phy */ 41059+ /* RST_BIT, write 0 to reset phy, write 1 to cancel reset */ 41060+ reset_control_assert(priv->phy_rst); 41061+ 41062+ /* 41063+ * delay some time to ensure reset ok, 41064+ * this depends on PHY hardware feature 41065+ */ 41066+ msleep(50); /* wait 50ms */ 41067+ 41068+ /* write 0 to cancel reset */ 41069+ reset_control_deassert(priv->phy_rst); 41070+ /* delay some time to ensure later MDIO access */ 41071+ msleep(50); /* wait 50ms */ 41072+ } 41073+} 41074+ 41075+void higmac_internal_phy_clk_disable(struct higmac_netdev_local const *priv) 41076+{ 41077+} 41078+ 41079+void higmac_internal_phy_clk_enable(struct higmac_netdev_local const *priv) 41080+{ 41081+} 41082+ 41083+void higmac_hw_all_clk_disable(struct higmac_netdev_local *priv) 41084+{ 41085+ /* 41086+ * If macif clock is enabled when suspend, we should 41087+ * disable it here. 41088+ * Because when resume, PHY will link up again and 41089+ * macif clock will be enabled too. If we don't disable 41090+ * macif clock in suspend, macif clock will be enabled twice. 41091+ */ 41092+ if (priv == NULL || priv->clk == NULL || priv->netdev == NULL || priv->macif_clk == NULL) 41093+ return; 41094+ 41095+ if (priv->netdev->flags & IFF_UP) 41096+ clk_disable_unprepare(priv->macif_clk); 41097+ 41098+ /* 41099+ * This is called in suspend, when net device is down, 41100+ * MAC clk is disabled. 41101+ * So we need to judge whether MAC clk is enabled, 41102+ * otherwise kernel will WARNING if clk disable twice. 41103+ */ 41104+ if (priv->netdev->flags & IFF_UP) 41105+ clk_disable_unprepare(priv->clk); 41106+ 41107+ if (priv->internal_phy) 41108+ higmac_internal_phy_clk_disable(priv); 41109+} 41110+ 41111+void higmac_hw_all_clk_enable(struct higmac_netdev_local *priv) 41112+{ 41113+ if (priv == NULL || priv->netdev == NULL || priv->clk == NULL) 41114+ return; 41115+ 41116+ if (priv->internal_phy) 41117+ higmac_internal_phy_clk_enable(priv); 41118+ 41119+ if (priv->netdev->flags & IFF_UP) 41120+ clk_prepare_enable(priv->macif_clk); 41121+ 41122+ /* If net device is down when suspend, we should not enable MAC clk. */ 41123+ if (priv->netdev->flags & IFF_UP) 41124+ clk_prepare_enable(priv->clk); 41125+} 41126diff --git a/drivers/net/ethernet/hisilicon/higmac/higmac.c b/drivers/net/ethernet/hisilicon/higmac/higmac.c 41127new file mode 100644 41128index 000000000..e77712344 41129--- /dev/null 41130+++ b/drivers/net/ethernet/hisilicon/higmac/higmac.c 41131@@ -0,0 +1,2645 @@ 41132+/* 41133+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 41134+ * Description: Higmac driver main process 41135+ * Author: KTP_BSP 41136+ * Create: 2018-10-08 41137+ */ 41138+ 41139+#include "higmac.h" 41140+#include "util.h" 41141+#include "autoeee/autoeee.h" 41142+#include "sockioctl.h" 41143+#include "pm.h" 41144+ 41145+#include <linux/kernel.h> 41146+#include <linux/errno.h> 41147+#include <linux/unistd.h> 41148+#include <linux/interrupt.h> 41149+#include <linux/delay.h> 41150+#include <linux/netdevice.h> 41151+#include <linux/etherdevice.h> 41152+#include <linux/skbuff.h> 41153+#include <linux/spinlock.h> 41154+#include <linux/mm.h> 41155+#include <linux/mii.h> 41156+#include <linux/ethtool.h> 41157+#include <linux/phy.h> 41158+#include <linux/dma-mapping.h> 41159+#include <linux/workqueue.h> 41160+#include <linux/device.h> 41161+#include <linux/atomic.h> 41162+#include <linux/platform_device.h> 41163+#include <linux/capability.h> 41164+#include <linux/time.h> 41165+#include <asm/setup.h> 41166+#include <linux/proc_fs.h> 41167+#include <linux/module.h> 41168+ 41169+#include <linux/circ_buf.h> 41170+#include <linux/of_net.h> 41171+#include <linux/of_mdio.h> 41172+#include <linux/clk.h> 41173+#include <linux/reset.h> 41174+ 41175+#define has_tso_cap(hw_cap) ((((hw_cap) >> 28) & 0x3) == VER_TSO) 41176+#define has_rxhash_cap(hw_cap) ((hw_cap) & BIT(30)) 41177+#define has_rss_cap(hw_cap) ((hw_cap) & BIT(31)) 41178+ 41179+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) 41180+static int debug = -1; 41181+module_param(debug, int, 0000); 41182+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); 41183+ 41184+static void higmac_set_desc_depth(struct higmac_netdev_local const *priv, 41185+ u32 rx, u32 tx) 41186+{ 41187+ u32 reg, val; 41188+ int i; 41189+ 41190+ writel(BITS_RX_FQ_DEPTH_EN, priv->gmac_iobase + RX_FQ_REG_EN); 41191+ val = readl(priv->gmac_iobase + RX_FQ_DEPTH); 41192+ val &= ~Q_ADDR_HI8_MASK; 41193+ val |= rx << DESC_WORD_SHIFT; 41194+ writel(val, priv->gmac_iobase + RX_FQ_DEPTH); 41195+ writel(0, priv->gmac_iobase + RX_FQ_REG_EN); 41196+ 41197+ writel(BITS_RX_BQ_DEPTH_EN, priv->gmac_iobase + RX_BQ_REG_EN); 41198+ val = readl(priv->gmac_iobase + RX_BQ_DEPTH); 41199+ val &= ~Q_ADDR_HI8_MASK; 41200+ val |= rx << DESC_WORD_SHIFT; 41201+ writel(val, priv->gmac_iobase + RX_BQ_DEPTH); 41202+ for (i = 1; i < priv->num_rxqs; i++) { 41203+ reg = rx_bq_depth_queue(i); 41204+ val = readl(priv->gmac_iobase + reg); 41205+ val &= ~Q_ADDR_HI8_MASK; 41206+ val |= rx << DESC_WORD_SHIFT; 41207+ writel(val, priv->gmac_iobase + reg); 41208+ } 41209+ writel(0, priv->gmac_iobase + RX_BQ_REG_EN); 41210+ 41211+ writel(BITS_TX_BQ_DEPTH_EN, priv->gmac_iobase + TX_BQ_REG_EN); 41212+ val = readl(priv->gmac_iobase + TX_BQ_DEPTH); 41213+ val &= ~Q_ADDR_HI8_MASK; 41214+ val |= tx << DESC_WORD_SHIFT; 41215+ writel(val, priv->gmac_iobase + TX_BQ_DEPTH); 41216+ writel(0, priv->gmac_iobase + TX_BQ_REG_EN); 41217+ 41218+ writel(BITS_TX_RQ_DEPTH_EN, priv->gmac_iobase + TX_RQ_REG_EN); 41219+ val = readl(priv->gmac_iobase + TX_RQ_DEPTH); 41220+ val &= ~Q_ADDR_HI8_MASK; 41221+ val |= tx << DESC_WORD_SHIFT; 41222+ writel(val, priv->gmac_iobase + TX_RQ_DEPTH); 41223+ writel(0, priv->gmac_iobase + TX_RQ_REG_EN); 41224+} 41225+ 41226+static void higmac_set_rx_fq(struct higmac_netdev_local const *priv, 41227+ dma_addr_t phy_addr) 41228+{ 41229+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41230+ u32 val; 41231+#endif 41232+ writel(BITS_RX_FQ_START_ADDR_EN, priv->gmac_iobase + RX_FQ_REG_EN); 41233+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41234+ val = readl(priv->gmac_iobase + RX_FQ_DEPTH); 41235+ val &= Q_ADDR_HI8_MASK; 41236+ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; 41237+ writel(val, priv->gmac_iobase + RX_FQ_DEPTH); 41238+#endif 41239+ writel((u32)phy_addr, priv->gmac_iobase + RX_FQ_START_ADDR); 41240+ writel(0, priv->gmac_iobase + RX_FQ_REG_EN); 41241+} 41242+ 41243+static void higmac_set_rx_bq(struct higmac_netdev_local const *priv, 41244+ dma_addr_t phy_addr) 41245+{ 41246+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41247+ u32 val; 41248+#endif 41249+ writel(BITS_RX_BQ_START_ADDR_EN, priv->gmac_iobase + RX_BQ_REG_EN); 41250+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41251+ val = readl(priv->gmac_iobase + RX_BQ_DEPTH); 41252+ val &= Q_ADDR_HI8_MASK; 41253+ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; 41254+ writel(val, priv->gmac_iobase + RX_BQ_DEPTH); 41255+#endif 41256+ writel((u32)phy_addr, priv->gmac_iobase + RX_BQ_START_ADDR); 41257+ writel(0, priv->gmac_iobase + RX_BQ_REG_EN); 41258+} 41259+ 41260+static void higmac_set_tx_bq(struct higmac_netdev_local const *priv, 41261+ dma_addr_t phy_addr) 41262+{ 41263+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41264+ u32 val; 41265+#endif 41266+ writel(BITS_TX_BQ_START_ADDR_EN, priv->gmac_iobase + TX_BQ_REG_EN); 41267+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41268+ val = readl(priv->gmac_iobase + TX_BQ_DEPTH); 41269+ val &= Q_ADDR_HI8_MASK; 41270+ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; 41271+ writel(val, priv->gmac_iobase + TX_BQ_DEPTH); 41272+#endif 41273+ writel((u32)phy_addr, priv->gmac_iobase + TX_BQ_START_ADDR); 41274+ writel(0, priv->gmac_iobase + TX_BQ_REG_EN); 41275+} 41276+ 41277+static void higmac_set_tx_rq(struct higmac_netdev_local const *priv, 41278+ dma_addr_t phy_addr) 41279+{ 41280+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41281+ u32 val; 41282+#endif 41283+ writel(BITS_TX_RQ_START_ADDR_EN, priv->gmac_iobase + TX_RQ_REG_EN); 41284+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41285+ val = readl(priv->gmac_iobase + TX_RQ_DEPTH); 41286+ val &= Q_ADDR_HI8_MASK; 41287+ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; 41288+ writel(val, priv->gmac_iobase + TX_RQ_DEPTH); 41289+#endif 41290+ writel((u32)phy_addr, priv->gmac_iobase + TX_RQ_START_ADDR); 41291+ writel(0, priv->gmac_iobase + TX_RQ_REG_EN); 41292+} 41293+ 41294+static void higmac_hw_set_desc_addr(struct higmac_netdev_local const *priv) 41295+{ 41296+ u32 reg; 41297+ int i; 41298+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41299+ u32 val; 41300+#endif 41301+ 41302+ higmac_set_rx_fq(priv, priv->RX_FQ.phys_addr); 41303+ higmac_set_rx_bq(priv, priv->RX_BQ.phys_addr); 41304+ higmac_set_tx_rq(priv, priv->TX_RQ.phys_addr); 41305+ higmac_set_tx_bq(priv, priv->TX_BQ.phys_addr); 41306+ 41307+ for (i = 1; i < priv->num_rxqs; i++) { 41308+ reg = rx_bq_start_addr_queue(i); 41309+ writel(BITS_RX_BQ_START_ADDR_EN, 41310+ priv->gmac_iobase + RX_BQ_REG_EN); 41311+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41312+ val = readl(priv->gmac_iobase + reg); 41313+ val &= Q_ADDR_HI8_MASK; 41314+ val |= ((priv->pool[BASE_QUEUE_NUMS + i].phys_addr) >> REG_BIT_WIDTH) << 41315+ Q_ADDR_HI8_OFFSET; 41316+ writel(val, priv->gmac_iobase + reg); 41317+#endif 41318+ /* pool 3 add i */ 41319+ writel((u32)(priv->pool[BASE_QUEUE_NUMS + i].phys_addr), 41320+ priv->gmac_iobase + reg); 41321+ writel(0, priv->gmac_iobase + RX_BQ_REG_EN); 41322+ } 41323+} 41324+ 41325+static void higmac_set_rss_cap(struct higmac_netdev_local const *priv) 41326+{ 41327+ u32 val = 0; 41328+ 41329+ if (priv->has_rxhash_cap) 41330+ val |= BIT_RXHASH_CAP; 41331+ if (priv->has_rss_cap) 41332+ val |= BIT_RSS_CAP; 41333+ writel(val, priv->gmac_iobase + HW_CAP_EN); 41334+} 41335+ 41336+/* config AXI bus burst and outstanding for better performance */ 41337+static void higmac_axi_bus_cfg(struct higmac_netdev_local *priv) 41338+{ 41339+ if (!priv->axi_bus_cfg_base) 41340+ return; 41341+ 41342+#if defined(CONFIG_ARCH_HI3519) || defined(CONFIG_ARCH_HI3519V101) || \ 41343+ defined(CONFIG_ARCH_HI3559) || defined(CONFIG_ARCH_HI3556) || \ 41344+ defined(CONFIG_ARCH_HI3516AV200) 41345+ if (!(readl(priv->axi_bus_cfg_base) >> BURST_OUTSTANDING_OFFSET)) 41346+ writel(BURST4_OUTSTANDING1, priv->axi_bus_cfg_base); 41347+#elif defined(CONFIG_ARCH_HI3521A) || defined(CONFIG_ARCH_HI3531A) 41348+ writel(BURST4_OUTSTANDING1, priv->axi_bus_cfg_base); 41349+#endif 41350+} 41351+ 41352+static void higmac_hw_init(struct higmac_netdev_local *priv) 41353+{ 41354+ u32 val; 41355+ u32 reg; 41356+ int i; 41357+ 41358+ higmac_axi_bus_cfg(priv); 41359+ 41360+ /* disable and clear all interrupts */ 41361+ writel(0, priv->gmac_iobase + ENA_PMU_INT); 41362+ writel(~0, priv->gmac_iobase + RAW_PMU_INT); 41363+ 41364+ for (i = 1; i < priv->num_rxqs; i++) { 41365+ reg = rss_ena_int_queue(i); 41366+ writel(0, priv->gmac_iobase + reg); 41367+ } 41368+ writel(~0, priv->gmac_iobase + RSS_RAW_PMU_INT); 41369+ 41370+ /* enable CRC erro packets filter */ 41371+ val = readl(priv->gmac_iobase + REC_FILT_CONTROL); 41372+ val |= BIT_CRC_ERR_PASS; 41373+ writel(val, priv->gmac_iobase + REC_FILT_CONTROL); 41374+ 41375+ /* set tx min packet length */ 41376+ val = readl(priv->gmac_iobase + CRF_MIN_PACKET); 41377+ val &= ~BIT_MASK_TX_MIN_LEN; 41378+ val |= ETH_HLEN << BIT_OFFSET_TX_MIN_LEN; 41379+ writel(val, priv->gmac_iobase + CRF_MIN_PACKET); 41380+ 41381+ /* fix bug for udp and ip error check */ 41382+ writel(CONTROL_WORD_CONFIG, priv->gmac_iobase + CONTROL_WORD); 41383+ 41384+ writel(0, priv->gmac_iobase + COL_SLOT_TIME); 41385+ 41386+ writel(DUPLEX_HALF, priv->gmac_iobase + MAC_DUPLEX_HALF_CTRL); 41387+ 41388+ /* interrupt when rcv packets >= RX_BQ_INT_THRESHOLD */ 41389+ val = RX_BQ_INT_THRESHOLD | 41390+ (TX_RQ_INT_THRESHOLD << BITS_OFFSET_TX_RQ_IN_TH); 41391+ writel(val, priv->gmac_iobase + IN_QUEUE_TH); 41392+ 41393+ /* RX_BQ/TX_RQ in timeout threshold */ 41394+ writel(0x10000, priv->gmac_iobase + RX_BQ_IN_TIMEOUT_TH); 41395+ 41396+ writel(0x18000, priv->gmac_iobase + TX_RQ_IN_TIMEOUT_TH); 41397+ 41398+ higmac_set_desc_depth(priv, RX_DESC_NUM, TX_DESC_NUM); 41399+} 41400+ 41401+static inline void higmac_irq_enable(struct higmac_netdev_local *ld) 41402+{ 41403+ if (ld == NULL) 41404+ return; 41405+ writel(RX_BQ_IN_INT | RX_BQ_IN_TIMEOUT_INT 41406+ | TX_RQ_IN_INT | TX_RQ_IN_TIMEOUT_INT, 41407+ ld->gmac_iobase + ENA_PMU_INT); 41408+} 41409+ 41410+static void higmac_irq_enable_queue(struct higmac_netdev_local *ld, 41411+ int rxq_id) 41412+{ 41413+ if (rxq_id) { 41414+ u32 reg; 41415+ 41416+ reg = rss_ena_int_queue(rxq_id); 41417+ writel(~0, ld->gmac_iobase + reg); 41418+ } else { 41419+ higmac_irq_enable(ld); 41420+ } 41421+} 41422+ 41423+static inline void higmac_irq_enable_all_queue(struct higmac_netdev_local *ld) 41424+{ 41425+ int i; 41426+ if (ld == NULL) 41427+ return; 41428+ for (i = 0; i < ld->num_rxqs; i++) 41429+ higmac_irq_enable_queue(ld, i); 41430+} 41431+ 41432+static inline void higmac_irq_disable(struct higmac_netdev_local const *ld) 41433+{ 41434+ if (ld == NULL) 41435+ return; 41436+ writel(0, ld->gmac_iobase + ENA_PMU_INT); 41437+} 41438+ 41439+static void higmac_irq_disable_queue(struct higmac_netdev_local const *ld, 41440+ int rxq_id) 41441+{ 41442+ if (rxq_id) { 41443+ u32 reg; 41444+ 41445+ reg = rss_ena_int_queue(rxq_id); 41446+ writel(0, ld->gmac_iobase + reg); 41447+ } else { 41448+ higmac_irq_disable(ld); 41449+ } 41450+} 41451+ 41452+static inline void higmac_irq_disable_all_queue(struct higmac_netdev_local const *ld) 41453+{ 41454+ int i; 41455+ if (ld == NULL) 41456+ return; 41457+ for (i = 0; i < ld->num_rxqs; i++) 41458+ higmac_irq_disable_queue(ld, i); 41459+} 41460+ 41461+static bool higmac_queue_irq_disabled(struct higmac_netdev_local *ld, 41462+ int rxq_id) 41463+{ 41464+ u32 reg, val; 41465+ 41466+ if (rxq_id) 41467+ reg = rss_ena_int_queue(rxq_id); 41468+ else 41469+ reg = ENA_PMU_INT; 41470+ val = readl(ld->gmac_iobase + reg); 41471+ 41472+ return !val; 41473+} 41474+ 41475+static inline void higmac_hw_desc_enable(struct higmac_netdev_local const *ld) 41476+{ 41477+ if (ld == NULL) 41478+ return; 41479+ writel(0xF, ld->gmac_iobase + DESC_WR_RD_ENA); 41480+} 41481+ 41482+static inline void higmac_hw_desc_disable(struct higmac_netdev_local const *ld) 41483+{ 41484+ if (ld == NULL) 41485+ return; 41486+ writel(0, ld->gmac_iobase + DESC_WR_RD_ENA); 41487+} 41488+ 41489+static inline void higmac_port_enable(struct higmac_netdev_local const *ld) 41490+{ 41491+ if (ld == NULL) 41492+ return; 41493+ writel(BITS_TX_EN | BITS_RX_EN, ld->gmac_iobase + PORT_EN); 41494+} 41495+ 41496+static inline void higmac_port_disable(struct higmac_netdev_local const *ld) 41497+{ 41498+ if (ld != NULL) { 41499+ writel(0, ld->gmac_iobase + PORT_EN); 41500+ } 41501+} 41502+ 41503+/* set gmac's multicast list, here we setup gmac's mc filter */ 41504+static void higmac_gmac_multicast_list(struct net_device const *dev) 41505+{ 41506+ struct higmac_netdev_local *ld = netdev_priv(dev); 41507+ unsigned int rec_filter; 41508+ 41509+ rec_filter = readl(ld->gmac_iobase + REC_FILT_CONTROL); 41510+ /* 41511+ * when set gmac in promisc mode 41512+ * a. dev in IFF_PROMISC mode 41513+ */ 41514+ if ((dev->flags & IFF_PROMISC)) { 41515+ /* promisc mode.received all pkgs. */ 41516+ rec_filter &= ~(BIT_BC_DROP_EN | BIT_MC_MATCH_EN | 41517+ BIT_UC_MATCH_EN); 41518+ } else { 41519+ /* drop uc pkgs with field 'DA' not match our's */ 41520+ rec_filter |= BIT_UC_MATCH_EN; 41521+ 41522+ if (dev->flags & IFF_BROADCAST) /* no broadcast */ 41523+ rec_filter &= ~BIT_BC_DROP_EN; 41524+ else 41525+ rec_filter |= BIT_BC_DROP_EN; 41526+ 41527+ if (netdev_mc_empty(dev) || !(dev->flags & IFF_MULTICAST)) { 41528+ /* haven't join any mc group */ 41529+ writel(0, ld->gmac_iobase + PORT_MC_ADDR_LOW); 41530+ writel(0, ld->gmac_iobase + PORT_MC_ADDR_HIGH); 41531+ rec_filter |= BIT_MC_MATCH_EN; 41532+ } else if (netdev_mc_count(dev) == 1 && 41533+ (dev->flags & IFF_MULTICAST)) { 41534+ struct netdev_hw_addr *ha = NULL; 41535+ unsigned int d; 41536+ 41537+ netdev_for_each_mc_addr(ha, dev) { 41538+ d = (ha->addr[0] << 8) | (ha->addr[1]); /* shift left 8bits */ 41539+ writel(d, ld->gmac_iobase + PORT_MC_ADDR_HIGH); 41540+ /* addr2 3 shift left 24 16 bits */ 41541+ d = (ha->addr[2] << 24) | (ha->addr[3] << 16) | 41542+ (ha->addr[4] << 8) | (ha->addr[5]); /* a4 << 8 | a5 */ 41543+ writel(d, ld->gmac_iobase + PORT_MC_ADDR_LOW); 41544+ } 41545+ rec_filter |= BIT_MC_MATCH_EN; 41546+ } else { 41547+ rec_filter &= ~BIT_MC_MATCH_EN; 41548+ } 41549+ } 41550+ writel(rec_filter, ld->gmac_iobase + REC_FILT_CONTROL); 41551+} 41552+ 41553+/* 41554+ * the func stop the hw desc and relaim the software skb resource 41555+ * before reusing the gmac, you'd better reset the gmac 41556+ */ 41557+void higmac_reclaim_rx_tx_resource(struct higmac_netdev_local *ld) 41558+{ 41559+ unsigned long rxflags, txflags; 41560+ int rd_offset, wr_offset; 41561+ int i; 41562+ if (ld == NULL) 41563+ return; 41564+ higmac_irq_disable_all_queue(ld); 41565+ higmac_hw_desc_disable(ld); 41566+ writel(STOP_RX_TX, ld->gmac_iobase + STOP_CMD); 41567+ 41568+ spin_lock_irqsave(&ld->rxlock, rxflags); 41569+ /* RX_BQ: logic write pointer */ 41570+ wr_offset = readl(ld->gmac_iobase + RX_BQ_WR_ADDR); 41571+ /* RX_BQ: software read pointer */ 41572+ rd_offset = readl(ld->gmac_iobase + RX_BQ_RD_ADDR); 41573+ /* prevent to reclaim skb in rx bottom half */ 41574+ writel(wr_offset, ld->gmac_iobase + RX_BQ_RD_ADDR); 41575+ 41576+ for (i = 1; i < ld->num_rxqs; i++) { 41577+ u32 rx_bq_wr_reg, rx_bq_rd_reg; 41578+ 41579+ rx_bq_wr_reg = rx_bq_wr_addr_queue(i); 41580+ rx_bq_rd_reg = rx_bq_rd_addr_queue(i); 41581+ 41582+ wr_offset = readl(ld->gmac_iobase + rx_bq_wr_reg); 41583+ writel(wr_offset, ld->gmac_iobase + rx_bq_rd_reg); 41584+ } 41585+ 41586+ /* RX_FQ: software write pointer */ 41587+ wr_offset = readl(ld->gmac_iobase + RX_FQ_WR_ADDR); 41588+ /* RX_FQ: logic read pointer */ 41589+ rd_offset = readl(ld->gmac_iobase + RX_FQ_RD_ADDR); 41590+ if (!rd_offset) 41591+ rd_offset = (RX_DESC_NUM - 1) << DESC_BYTE_SHIFT; 41592+ else 41593+ rd_offset -= DESC_SIZE; 41594+ /* stop to feed hw desc */ 41595+ writel(rd_offset, ld->gmac_iobase + RX_FQ_WR_ADDR); 41596+ 41597+ for (i = 0; i < ld->RX_FQ.count; i++) { 41598+ if (!ld->RX_FQ.skb[i]) 41599+ ld->RX_FQ.skb[i] = SKB_MAGIC; 41600+ } 41601+ spin_unlock_irqrestore(&ld->rxlock, rxflags); 41602+ 41603+ /* 41604+ * no need to wait pkts in TX_RQ finish to free all skb, 41605+ * because higmac_xmit_reclaim is in the tx_lock, 41606+ */ 41607+ spin_lock_irqsave(&ld->txlock, txflags); 41608+ /* TX_RQ: logic write */ 41609+ wr_offset = readl(ld->gmac_iobase + TX_RQ_WR_ADDR); 41610+ /* TX_RQ: software read */ 41611+ rd_offset = readl(ld->gmac_iobase + TX_RQ_RD_ADDR); 41612+ /* stop to reclaim tx skb */ 41613+ writel(wr_offset, ld->gmac_iobase + TX_RQ_RD_ADDR); 41614+ 41615+ /* TX_BQ: logic read */ 41616+ rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR); 41617+ if (!rd_offset) 41618+ rd_offset = (TX_DESC_NUM - 1) << DESC_BYTE_SHIFT; 41619+ else 41620+ rd_offset -= DESC_SIZE; 41621+ /* stop software tx skb */ 41622+ writel(rd_offset, ld->gmac_iobase + TX_BQ_WR_ADDR); 41623+ 41624+ for (i = 0; i < ld->TX_BQ.count; i++) { 41625+ if (!ld->TX_BQ.skb[i]) 41626+ ld->TX_BQ.skb[i] = SKB_MAGIC; 41627+ } 41628+ spin_unlock_irqrestore(&ld->txlock, txflags); 41629+} 41630+ 41631+static void higmac_monitor_func(struct timer_list *t); 41632+static void higmac_set_multicast_list(struct net_device *dev); 41633+ 41634+static void higmac_hw_set_mac_addr(struct net_device *dev) 41635+{ 41636+ struct higmac_netdev_local *priv = netdev_priv(dev); 41637+ unsigned char *mac = dev->dev_addr; 41638+ u32 val; 41639+ 41640+ val = mac[1] | (mac[0] << 8); /* shift left 8 bits */ 41641+ writel(val, priv->gmac_iobase + STATION_ADDR_HIGH); 41642+ /* mac 2 3 4 5 shift left 24 16 8 0 bits */ 41643+ val = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24); 41644+ writel(val, priv->gmac_iobase + STATION_ADDR_LOW); 41645+} 41646+ 41647+static u32 higmac_rx_refill(struct higmac_netdev_local *priv); 41648+ 41649+static void higmac_free_rx_skb(struct higmac_netdev_local *ld) 41650+{ 41651+ struct sk_buff *skb = NULL; 41652+ int i; 41653+ 41654+ for (i = 0; i < ld->RX_FQ.count; i++) { 41655+ skb = ld->RX_FQ.skb[i]; 41656+ if (skb != NULL) { 41657+ ld->rx_skb[i] = NULL; 41658+ ld->RX_FQ.skb[i] = NULL; 41659+ if (skb == SKB_MAGIC) 41660+ continue; 41661+ dev_kfree_skb_any(skb); 41662+ /* 41663+ * need to unmap the skb here 41664+ * but there is no way to get the dma_addr here, 41665+ * and unmap(TO_DEVICE) ops do nothing in fact, 41666+ * so we ignore to call 41667+ * dma_unmap_single(dev, dma_addr, skb->len, 41668+ * DMA_TO_DEVICE) 41669+ */ 41670+ } 41671+ } 41672+} 41673+ 41674+static void higmac_free_tx_skb(struct higmac_netdev_local *ld) 41675+{ 41676+ struct sk_buff *skb = NULL; 41677+ int i; 41678+ 41679+ for (i = 0; i < ld->TX_BQ.count; i++) { 41680+ skb = ld->TX_BQ.skb[i]; 41681+ if (skb != NULL) { 41682+ ld->tx_skb[i] = NULL; 41683+ ld->TX_BQ.skb[i] = NULL; 41684+ if (skb == SKB_MAGIC) 41685+ continue; 41686+ dev_kfree_skb_any(skb); 41687+ /* unmap the skb */ 41688+ } 41689+ } 41690+} 41691+ 41692+/* reset and re-config gmac */ 41693+void higmac_restart(struct higmac_netdev_local *ld) 41694+{ 41695+ unsigned long rxflags, txflags; 41696+ if (ld == NULL || ld->netdev == NULL) 41697+ return; 41698+ /* restart hw engine now */ 41699+ higmac_mac_core_reset(ld); 41700+ 41701+ spin_lock_irqsave(&ld->rxlock, rxflags); 41702+ spin_lock_irqsave(&ld->txlock, txflags); 41703+ 41704+ higmac_free_rx_skb(ld); 41705+ higmac_free_tx_skb(ld); 41706+ 41707+ pmt_reg_restore(ld); 41708+ higmac_hw_init(ld); 41709+ higmac_hw_set_mac_addr(ld->netdev); 41710+ higmac_hw_set_desc_addr(ld); 41711+ 41712+ /* we don't set macif here, it will be set in adjust_link */ 41713+ if (ld->netdev->flags & IFF_UP) { 41714+ /* 41715+ * when resume, only do the following operations 41716+ * when dev is up before suspend. 41717+ */ 41718+ higmac_rx_refill(ld); 41719+ higmac_set_multicast_list(ld->netdev); 41720+ 41721+ higmac_hw_desc_enable(ld); 41722+ higmac_port_enable(ld); 41723+ higmac_irq_enable_all_queue(ld); 41724+ } 41725+ spin_unlock_irqrestore(&ld->txlock, txflags); 41726+ spin_unlock_irqrestore(&ld->rxlock, rxflags); 41727+} 41728+ 41729+static int higmac_net_set_mac_address(struct net_device *dev, void *p) 41730+{ 41731+ int ret; 41732+ 41733+ ret = eth_mac_addr(dev, p); 41734+ if (!ret) 41735+ higmac_hw_set_mac_addr(dev); 41736+ 41737+ return ret; 41738+} 41739+ 41740+#define HIGMAC_LINK_CHANGE_PROTECT 41741+#define HIGMAC_MAC_TX_RESET_IN_LINKUP 41742+ 41743+#ifdef HIGMAC_LINK_CHANGE_PROTECT 41744+#define HIGMAC_MS_TO_NS 1000000ULL 41745+#define HIGMAC_FLUSH_WAIT_TIME (100*HIGMAC_MS_TO_NS) 41746+/* protect code */ 41747+static void higmac_linkup_flush(struct higmac_netdev_local *ld) 41748+{ 41749+ int tx_bq_wr_offset, tx_bq_rd_offset; 41750+ unsigned long long time_limit, time_now; 41751+ 41752+ time_now = sched_clock(); 41753+ time_limit = time_now + HIGMAC_FLUSH_WAIT_TIME; 41754+ 41755+ do { 41756+ tx_bq_wr_offset = readl(ld->gmac_iobase + TX_BQ_WR_ADDR); 41757+ tx_bq_rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR); 41758+ 41759+ time_now = sched_clock(); 41760+ if (unlikely((long long)time_now - 41761+ (long long)time_limit >= 0)) 41762+ break; 41763+ } while (tx_bq_rd_offset != tx_bq_wr_offset); 41764+ 41765+ mdelay(1); 41766+} 41767+#endif 41768+ 41769+#ifdef HIGMAC_MAC_TX_RESET_IN_LINKUP 41770+static void higmac_mac_tx_state_engine_reset(struct higmac_netdev_local *priv) 41771+{ 41772+ u32 val; 41773+ 41774+ val = readl(priv->gmac_iobase + MAC_CLEAR); 41775+ val |= BIT_TX_SOFT_RESET; 41776+ writel(val, priv->gmac_iobase + MAC_CLEAR); 41777+ 41778+ mdelay(5); /* wait 5ms */ 41779+ 41780+ val = readl(priv->gmac_iobase + MAC_CLEAR); 41781+ val &= ~BIT_TX_SOFT_RESET; 41782+ writel(val, priv->gmac_iobase + MAC_CLEAR); 41783+} 41784+#endif 41785+ 41786+static void higmac_adjust_link(struct net_device *dev) 41787+{ 41788+ struct higmac_netdev_local *priv = NULL; 41789+ struct phy_device *phy = NULL; 41790+ bool link_status_changed = false; 41791+ if (dev == NULL) 41792+ return; 41793+ priv = netdev_priv(dev); 41794+ if (priv == NULL || priv->phy == NULL) 41795+ return; 41796+ phy = priv->phy; 41797+ if (phy->link) { 41798+ if ((priv->old_speed != phy->speed) || 41799+ (priv->old_duplex != phy->duplex)) { 41800+#ifdef HIGMAC_LINK_CHANGE_PROTECT 41801+ unsigned long txflags; 41802+ 41803+ spin_lock_irqsave(&priv->txlock, txflags); 41804+ 41805+ higmac_linkup_flush(priv); 41806+#endif 41807+ higmac_config_port(dev, phy->speed, phy->duplex); 41808+#ifdef HIGMAC_MAC_TX_RESET_IN_LINKUP 41809+ higmac_mac_tx_state_engine_reset(priv); 41810+#endif 41811+#ifdef HIGMAC_LINK_CHANGE_PROTECT 41812+ spin_unlock_irqrestore(&priv->txlock, txflags); 41813+#endif 41814+ higmac_set_flow_ctrl_state(priv, phy->pause); 41815+ 41816+ if (priv->autoeee) 41817+ init_autoeee(priv); 41818+ 41819+ link_status_changed = true; 41820+ priv->old_link = 1; 41821+ priv->old_speed = phy->speed; 41822+ priv->old_duplex = phy->duplex; 41823+ } 41824+ } else if (priv->old_link) { 41825+ link_status_changed = true; 41826+ priv->old_link = 0; 41827+ priv->old_speed = SPEED_UNKNOWN; 41828+ priv->old_duplex = DUPLEX_UNKNOWN; 41829+ } 41830+ 41831+ if (link_status_changed && netif_msg_link(priv)) 41832+ phy_print_status(phy); 41833+} 41834+ 41835+int higmac_tx_avail(struct higmac_netdev_local const *ld) 41836+{ 41837+ unsigned int tx_bq_wr_offset, tx_bq_rd_offset; 41838+ if (ld == NULL) 41839+ return -ENOMEM; 41840+ tx_bq_wr_offset = readl(ld->gmac_iobase + TX_BQ_WR_ADDR); 41841+ tx_bq_rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR); 41842+ 41843+ return (tx_bq_rd_offset >> DESC_BYTE_SHIFT) + TX_DESC_NUM - 41844+ (tx_bq_wr_offset >> DESC_BYTE_SHIFT) - 1; 41845+} 41846+ 41847+static int higmac_init_sg_desc_queue(struct higmac_netdev_local *ld) 41848+{ 41849+ ld->sg_count = ld->TX_BQ.count + HIGMAC_SG_DESC_ADD; 41850+ if (has_cap_cci(ld->hw_cap)) { 41851+ ld->dma_sg_desc = kmalloc_array(ld->sg_count, 41852+ sizeof(struct sg_desc), 41853+ GFP_KERNEL); 41854+ if (ld->dma_sg_desc) 41855+ ld->dma_sg_phy = virt_to_phys(ld->dma_sg_desc); 41856+ } else { 41857+ ld->dma_sg_desc = (struct sg_desc *)dma_alloc_coherent(ld->dev, 41858+ ld->sg_count * sizeof(struct sg_desc), 41859+ &ld->dma_sg_phy, GFP_KERNEL); 41860+ } 41861+ 41862+ if (!ld->dma_sg_desc) { 41863+ pr_err("alloc sg desc dma error!\n"); 41864+ return -ENOMEM; 41865+ } 41866+#ifdef HIGMAC_TSO_DEBUG 41867+ pr_info("Higmac dma_sg_phy: 0x%pK\n", (void *)(uintptr_t)ld->dma_sg_phy); 41868+#endif 41869+ 41870+ ld->sg_head = 0; 41871+ ld->sg_tail = 0; 41872+ 41873+ return 0; 41874+} 41875+ 41876+static void higmac_destroy_sg_desc_queue(struct higmac_netdev_local *ld) 41877+{ 41878+ if (ld->dma_sg_desc) { 41879+ if (has_cap_cci(ld->hw_cap)) 41880+ kfree(ld->dma_sg_desc); 41881+ else 41882+ dma_free_coherent(ld->dev, 41883+ ld->sg_count * sizeof(struct sg_desc), 41884+ ld->dma_sg_desc, ld->dma_sg_phy); 41885+ ld->dma_sg_desc = NULL; 41886+ } 41887+} 41888+ 41889+static bool higmac_rx_fq_empty(struct higmac_netdev_local const *priv) 41890+{ 41891+ u32 start, end; 41892+ 41893+ start = readl(priv->gmac_iobase + RX_FQ_WR_ADDR); 41894+ end = readl(priv->gmac_iobase + RX_FQ_RD_ADDR); 41895+ if (start == end) 41896+ return true; 41897+ else 41898+ return false; 41899+} 41900+ 41901+static bool higmac_rxq_has_packets(struct higmac_netdev_local const *priv, int rxq_id) 41902+{ 41903+ u32 rx_bq_rd_reg, rx_bq_wr_reg; 41904+ u32 start, end; 41905+ 41906+ rx_bq_rd_reg = rx_bq_rd_addr_queue(rxq_id); 41907+ rx_bq_wr_reg = rx_bq_wr_addr_queue(rxq_id); 41908+ 41909+ start = readl(priv->gmac_iobase + rx_bq_rd_reg); 41910+ end = readl(priv->gmac_iobase + rx_bq_wr_reg); 41911+ if (start == end) 41912+ return false; 41913+ else 41914+ return true; 41915+} 41916+ 41917+static void higmac_monitor_func(struct timer_list *t) 41918+{ 41919+ struct higmac_netdev_local *ld = from_timer(ld, t, monitor); 41920+ struct net_device *dev = NULL; 41921+ u32 refill_cnt; 41922+ 41923+ if (ld == NULL) { 41924+ higmac_trace(HIGMAC_NORMAL_LEVEL, "ld is null"); 41925+ return; 41926+ } 41927+ 41928+ if (ld->netdev == NULL) { 41929+ higmac_trace(HIGMAC_NORMAL_LEVEL, "ld->netdev is null"); 41930+ return; 41931+ } 41932+ dev_hold(ld->netdev); 41933+ dev = ld->netdev; 41934+ if (!netif_running(dev)) { 41935+ dev_put(dev); 41936+ higmac_trace(HIGMAC_NORMAL_LEVEL, "network driver is stopped"); 41937+ return; 41938+ } 41939+ dev_put(dev); 41940+ 41941+ spin_lock(&ld->rxlock); 41942+ refill_cnt = higmac_rx_refill(ld); 41943+ if (!refill_cnt && higmac_rx_fq_empty(ld)) { 41944+ int rxq_id; 41945+ 41946+ for (rxq_id = 0; rxq_id < ld->num_rxqs; rxq_id++) { 41947+ if (higmac_rxq_has_packets(ld, rxq_id)) 41948+ napi_schedule(&ld->q_napi[rxq_id].napi); 41949+ } 41950+ } 41951+ spin_unlock(&ld->rxlock); 41952+ 41953+ ld->monitor.expires = jiffies + HIGMAC_MONITOR_TIMER; 41954+ mod_timer(&ld->monitor, ld->monitor.expires); 41955+} 41956+ 41957+static u32 higmac_rx_refill(struct higmac_netdev_local *priv) 41958+{ 41959+ struct higmac_desc *desc = NULL; 41960+ struct sk_buff *skb = NULL; 41961+ struct cyclic_queue_info dma_info; 41962+ u32 len = HIETH_MAX_FRAME_SIZE; 41963+ dma_addr_t addr; 41964+ u32 refill_cnt = 0; 41965+ u32 i; 41966+ /* software write pointer */ 41967+ dma_info.start = dma_cnt(readl(priv->gmac_iobase + RX_FQ_WR_ADDR)); 41968+ /* logic read pointer */ 41969+ dma_info.end = dma_cnt(readl(priv->gmac_iobase + RX_FQ_RD_ADDR)); 41970+ dma_info.num = CIRC_SPACE(dma_info.start, dma_info.end, RX_DESC_NUM); 41971+ 41972+ for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) { 41973+ if (priv->RX_FQ.skb[dma_info.pos] || priv->rx_skb[dma_info.pos]) 41974+ break; 41975+ 41976+ skb = netdev_alloc_skb_ip_align(priv->netdev, len); 41977+ if (unlikely(skb == NULL)) 41978+ break; 41979+ 41980+ if (!has_cap_cci(priv->hw_cap)) { 41981+ addr = dma_map_single(priv->dev, skb->data, len, 41982+ DMA_FROM_DEVICE); 41983+ if (dma_mapping_error(priv->dev, addr)) { 41984+ dev_kfree_skb_any(skb); 41985+ break; 41986+ } 41987+ } else { 41988+ addr = virt_to_phys(skb->data); 41989+ } 41990+ 41991+ desc = priv->RX_FQ.desc + dma_info.pos; 41992+ desc->data_buff_addr = (u32)addr; 41993+#if defined(CONFIG_HIGMAC_DDR_64BIT) 41994+ desc->reserve31 = addr >> REG_BIT_WIDTH; 41995+#endif 41996+ priv->RX_FQ.skb[dma_info.pos] = skb; 41997+ priv->rx_skb[dma_info.pos] = skb; 41998+ 41999+ desc->buffer_len = len - 1; 42000+ desc->data_len = 0; 42001+ desc->fl = 0; 42002+ desc->descvid = DESC_VLD_FREE; 42003+ desc->skb_id = dma_info.pos; 42004+ 42005+ refill_cnt++; 42006+ dma_info.pos = dma_ring_incr(dma_info.pos, RX_DESC_NUM); 42007+ } 42008+ 42009+ /* 42010+ * This barrier is important here. It is required to ensure 42011+ * the ARM CPU flushes it's DMA write buffers before proceeding 42012+ * to the next instruction, to ensure that GMAC will see 42013+ * our descriptor changes in memory 42014+ */ 42015+ higmac_sync_barrier(); 42016+ 42017+ if (dma_info.pos != dma_info.start) 42018+ writel(dma_byte(dma_info.pos), priv->gmac_iobase + RX_FQ_WR_ADDR); 42019+ 42020+ return refill_cnt; 42021+} 42022+ 42023+static void higmac_rx_skbput(struct net_device *dev, struct sk_buff *skb, 42024+ struct higmac_desc *desc, int rxq_id) 42025+{ 42026+ struct higmac_netdev_local *ld = netdev_priv(dev); 42027+ dma_addr_t addr; 42028+ u32 len; 42029+ int ret; 42030+ 42031+ len = desc->data_len; 42032+ 42033+ if (!has_cap_cci(ld->hw_cap)) { 42034+ addr = desc->data_buff_addr; 42035+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42036+ addr |= (dma_addr_t)(desc->reserve31) << REG_BIT_WIDTH; 42037+#endif 42038+ dma_unmap_single(ld->dev, addr, HIETH_MAX_FRAME_SIZE, 42039+ DMA_FROM_DEVICE); 42040+ } 42041+ 42042+ skb_put(skb, len); 42043+ if (skb->len > HIETH_MAX_FRAME_SIZE) { 42044+ netdev_err(dev, "rcv len err, len = %d\n", skb->len); 42045+ dev->stats.rx_errors++; 42046+ dev->stats.rx_length_errors++; 42047+ dev_kfree_skb_any(skb); 42048+ return; 42049+ } 42050+ 42051+ skb->protocol = eth_type_trans(skb, dev); 42052+ skb->ip_summed = CHECKSUM_NONE; 42053+ 42054+#if defined(CONFIG_HIGMAC_RXCSUM) 42055+ ret = higmac_rx_checksum(dev, skb, desc); 42056+ if (unlikely(ret)) { 42057+ return; 42058+ } 42059+#endif 42060+ if ((dev->features & NETIF_F_RXHASH) && desc->has_hash) 42061+ skb_set_hash(skb, desc->rxhash, desc->l3_hash ? 42062+ PKT_HASH_TYPE_L3 : PKT_HASH_TYPE_L4); 42063+ 42064+ skb_record_rx_queue(skb, rxq_id); 42065+ 42066+ napi_gro_receive(&ld->q_napi[rxq_id].napi, skb); 42067+ dev->stats.rx_packets++; 42068+ dev->stats.rx_bytes += len; 42069+} 42070+ 42071+static int higmac_rx_skb(struct net_device *dev, struct higmac_desc *desc, 42072+ u16 skb_id, int rxq_id) 42073+{ 42074+ struct higmac_netdev_local *ld = netdev_priv(dev); 42075+ struct sk_buff *skb = NULL; 42076+ 42077+ spin_lock(&ld->rxlock); 42078+ skb = ld->rx_skb[skb_id]; 42079+ if (unlikely(skb == NULL)) { 42080+ spin_unlock(&ld->rxlock); 42081+ netdev_err(dev, "inconsistent rx_skb\n"); 42082+ return -1; 42083+ } 42084+ 42085+ /* data consistent check */ 42086+ if (unlikely(skb != ld->RX_FQ.skb[skb_id])) { 42087+ netdev_err(dev, "desc->skb(0x%p),RX_FQ.skb[%d](0x%p)\n", 42088+ skb, skb_id, ld->RX_FQ.skb[skb_id]); 42089+ if (ld->RX_FQ.skb[skb_id] == SKB_MAGIC) { 42090+ spin_unlock(&ld->rxlock); 42091+ return 0; 42092+ } 42093+ WARN_ON(1); 42094+ } else { 42095+ ld->RX_FQ.skb[skb_id] = NULL; 42096+ } 42097+ spin_unlock(&ld->rxlock); 42098+ 42099+ higmac_rx_skbput(dev, skb, desc, rxq_id); 42100+ return 0; 42101+} 42102+ 42103+static int higmac_rx(struct net_device *dev, int limit, int rxq_id) 42104+{ 42105+ struct higmac_netdev_local *ld = netdev_priv(dev); 42106+ struct higmac_desc *desc = NULL; 42107+ struct cyclic_queue_info dma_info; 42108+ u32 rx_bq_rd_reg, rx_bq_wr_reg; 42109+ u16 skb_id; 42110+ u32 i; 42111+ 42112+ rx_bq_rd_reg = rx_bq_rd_addr_queue(rxq_id); 42113+ rx_bq_wr_reg = rx_bq_wr_addr_queue(rxq_id); 42114+ 42115+ /* software read pointer */ 42116+ dma_info.start = dma_cnt(readl(ld->gmac_iobase + rx_bq_rd_reg)); 42117+ /* logic write pointer */ 42118+ dma_info.end = dma_cnt(readl(ld->gmac_iobase + rx_bq_wr_reg)); 42119+ dma_info.num = CIRC_CNT(dma_info.end, dma_info.start, RX_DESC_NUM); 42120+ if (dma_info.num > limit) 42121+ dma_info.num = limit; 42122+ 42123+ /* ensure get updated desc */ 42124+ rmb(); 42125+ for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) { 42126+ if (rxq_id) 42127+ desc = ld->pool[BASE_QUEUE_NUMS + rxq_id].desc + dma_info.pos; 42128+ else 42129+ desc = ld->RX_BQ.desc + dma_info.pos; 42130+ skb_id = desc->skb_id; 42131+ 42132+ if (unlikely(higmac_rx_skb(dev, desc, skb_id, rxq_id))) 42133+ break; 42134+ 42135+ spin_lock(&ld->rxlock); 42136+ ld->rx_skb[skb_id] = NULL; 42137+ spin_unlock(&ld->rxlock); 42138+ dma_info.pos = dma_ring_incr(dma_info.pos, RX_DESC_NUM); 42139+ } 42140+ 42141+ if (dma_info.pos != dma_info.start) 42142+ writel(dma_byte(dma_info.pos), ld->gmac_iobase + rx_bq_rd_reg); 42143+ 42144+ spin_lock(&ld->rxlock); 42145+ higmac_rx_refill(ld); 42146+ spin_unlock(&ld->rxlock); 42147+ 42148+ return dma_info.num; 42149+} 42150+ 42151+#ifdef HIGMAC_TSO_DEBUG 42152+unsigned int id_send; 42153+unsigned int id_free; 42154+struct send_pkt_info pkt_rec[MAX_RECORD]; 42155+#endif 42156+ 42157+static int higmac_check_tx_err(struct higmac_netdev_local *ld, 42158+ struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos) 42159+{ 42160+ unsigned int tx_err = tx_bq_desc->tx_err; 42161+ 42162+ if (unlikely(tx_err & ERR_ALL)) { 42163+ struct sg_desc *desc_cur = NULL; 42164+ int *sg_word = NULL; 42165+ int i; 42166+ 42167+ WARN((tx_err & ERR_ALL), 42168+ "TX ERR: desc1=0x%x, desc2=0x%x, desc5=0x%x\n", 42169+ tx_bq_desc->data_buff_addr, 42170+ tx_bq_desc->desc1.val, tx_bq_desc->tx_err); 42171+ 42172+ desc_cur = ld->dma_sg_desc + ld->TX_BQ.sg_desc_offset[desc_pos]; 42173+ sg_word = (int *)desc_cur; 42174+ for (i = 0; i < sizeof(struct sg_desc) / sizeof(int); i++) 42175+ pr_err("%s,%d: sg_desc word[%d]=0x%x\n", 42176+ __func__, __LINE__, i, sg_word[i]); 42177+ 42178+ return -1; 42179+ } 42180+ 42181+ return 0; 42182+} 42183+ 42184+static void higmac_xmit_release_gso_sg(struct higmac_netdev_local *ld, 42185+ struct higmac_tso_desc *tx_rq_desc, unsigned int desc_pos) 42186+{ 42187+ struct sg_desc *desc_cur = NULL; 42188+ int nfrags = tx_rq_desc->desc1.tx.nfrags_num; 42189+ unsigned int desc_offset; 42190+ dma_addr_t addr; 42191+ size_t len; 42192+ int i; 42193+ 42194+ desc_offset = ld->TX_BQ.sg_desc_offset[desc_pos]; 42195+ WARN_ON(desc_offset != ld->sg_tail); 42196+ desc_cur = ld->dma_sg_desc + desc_offset; 42197+ 42198+ addr = desc_cur->linear_addr; 42199+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42200+ addr |= (dma_addr_t)(desc_cur->reserv3 >> 42201+ SG_DESC_HI8_OFFSET) << 42202+ REG_BIT_WIDTH; 42203+#endif 42204+ len = desc_cur->linear_len; 42205+ dma_unmap_single(ld->dev, addr, len, DMA_TO_DEVICE); 42206+ for (i = 0; i < nfrags; i++) { 42207+ addr = desc_cur->frags[i].addr; 42208+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42209+ addr |= (dma_addr_t) 42210+ (desc_cur->frags[i].reserved >> 42211+ SG_DESC_HI8_OFFSET) << 42212+ REG_BIT_WIDTH; 42213+#endif 42214+ len = desc_cur->frags[i].size; 42215+ dma_unmap_page(ld->dev, addr, len, 42216+ DMA_TO_DEVICE); 42217+ } 42218+} 42219+ 42220+static int higmac_xmit_release_gso(struct higmac_netdev_local *ld, 42221+ struct higmac_tso_desc *tx_rq_desc, unsigned int desc_pos) 42222+{ 42223+ int pkt_type; 42224+ int nfrags = tx_rq_desc->desc1.tx.nfrags_num; 42225+ dma_addr_t addr; 42226+ size_t len; 42227+ 42228+ if (unlikely(higmac_check_tx_err(ld, tx_rq_desc, desc_pos) < 0)) { 42229+ /* dev_close */ 42230+ higmac_irq_disable_all_queue(ld); 42231+ higmac_hw_desc_disable(ld); 42232+ 42233+ netif_carrier_off(ld->netdev); 42234+ netif_stop_queue(ld->netdev); 42235+ 42236+ phy_stop(ld->phy); 42237+ del_timer_sync(&ld->monitor); 42238+ return -1; 42239+ } 42240+ 42241+ if (tx_rq_desc->desc1.tx.tso_flag || nfrags) 42242+ pkt_type = PKT_SG; 42243+ else 42244+ pkt_type = PKT_NORMAL; 42245+ 42246+ if (pkt_type == PKT_NORMAL) { 42247+ if (!has_cap_cci(ld->hw_cap)) { 42248+ addr = tx_rq_desc->data_buff_addr; 42249+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42250+ addr |= (dma_addr_t)(tx_rq_desc->reserve_desc2 & 42251+ TX_DESC_HI8_MASK) << 42252+ REG_BIT_WIDTH; 42253+#endif 42254+ len = tx_rq_desc->desc1.tx.data_len; 42255+ dma_unmap_single(ld->dev, addr, len, DMA_TO_DEVICE); 42256+ } 42257+ } else { 42258+ if (!has_cap_cci(ld->hw_cap)) 42259+ higmac_xmit_release_gso_sg(ld, tx_rq_desc, desc_pos); 42260+ 42261+ ld->sg_tail = (ld->sg_tail + 1) % ld->sg_count; 42262+ } 42263+ 42264+#ifdef HIGMAC_TSO_DEBUG 42265+ if (id_free >= MAX_RECORD) 42266+ id_free = 0; 42267+ pkt_rec[id_free].status = 0; 42268+ id_free++; 42269+#endif 42270+ 42271+ return 0; 42272+} 42273+ 42274+static int higmac_xmit_reclaim_release(struct net_device *dev, 42275+ struct sk_buff *skb, struct higmac_desc *desc, u32 pos) 42276+{ 42277+ struct higmac_netdev_local *priv = netdev_priv(dev); 42278+ struct higmac_tso_desc *tso_desc = NULL; 42279+ dma_addr_t addr; 42280+ 42281+ if (priv->tso_supported) { 42282+ tso_desc = (struct higmac_tso_desc *)desc; 42283+ return higmac_xmit_release_gso(priv, tso_desc, pos); 42284+ } else if (!has_cap_cci(priv->hw_cap)) { 42285+ addr = desc->data_buff_addr; 42286+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42287+ addr |= (dma_addr_t)(desc->rxhash & TX_DESC_HI8_MASK) << 42288+ REG_BIT_WIDTH; 42289+#endif 42290+ dma_unmap_single(priv->dev, addr, skb->len, DMA_TO_DEVICE); 42291+ } 42292+ return 0; 42293+} 42294+ 42295+static void higmac_xmit_reclaim(struct net_device *dev) 42296+{ 42297+ struct sk_buff *skb = NULL; 42298+ struct higmac_desc *desc = NULL; 42299+ struct higmac_netdev_local *priv = netdev_priv(dev); 42300+ unsigned int bytes_compl = 0; 42301+ unsigned int pkts_compl = 0; 42302+ struct cyclic_queue_info dma_info; 42303+ u32 i; 42304+ 42305+ spin_lock(&priv->txlock); 42306+ 42307+ /* software read */ 42308+ dma_info.start = dma_cnt(readl(priv->gmac_iobase + TX_RQ_RD_ADDR)); 42309+ /* logic write */ 42310+ dma_info.end = dma_cnt(readl(priv->gmac_iobase + TX_RQ_WR_ADDR)); 42311+ dma_info.num = CIRC_CNT(dma_info.end, dma_info.start, TX_DESC_NUM); 42312+ 42313+ for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) { 42314+ skb = priv->tx_skb[dma_info.pos]; 42315+ if (unlikely(skb == NULL)) { 42316+ netdev_err(dev, "inconsistent tx_skb\n"); 42317+ break; 42318+ } 42319+ 42320+ if (skb != priv->TX_BQ.skb[dma_info.pos]) { 42321+ netdev_err(dev, "wired, tx skb[%d](%p) != skb(%p)\n", 42322+ dma_info.pos, priv->TX_BQ.skb[dma_info.pos], skb); 42323+ if (priv->TX_BQ.skb[dma_info.pos] == SKB_MAGIC) 42324+ goto next; 42325+ } 42326+ 42327+ pkts_compl++; 42328+ bytes_compl += skb->len; 42329+ desc = priv->TX_RQ.desc + dma_info.pos; 42330+ if (higmac_xmit_reclaim_release(dev, skb, desc, dma_info.pos) < 0) 42331+ break; 42332+ 42333+ priv->TX_BQ.skb[dma_info.pos] = NULL; 42334+next: 42335+ priv->tx_skb[dma_info.pos] = NULL; 42336+ dev_consume_skb_any(skb); 42337+ dma_info.pos = dma_ring_incr(dma_info.pos, TX_DESC_NUM); 42338+ } 42339+ 42340+ if (dma_info.pos != dma_info.start) 42341+ writel(dma_byte(dma_info.pos), priv->gmac_iobase + TX_RQ_RD_ADDR); 42342+ 42343+ if (pkts_compl || bytes_compl) 42344+ netdev_completed_queue(dev, pkts_compl, bytes_compl); 42345+ 42346+ if (unlikely(netif_queue_stopped(priv->netdev)) && pkts_compl) 42347+ netif_wake_queue(priv->netdev); 42348+ 42349+ spin_unlock(&priv->txlock); 42350+} 42351+ 42352+static int higmac_poll(struct napi_struct *napi, int budget) 42353+{ 42354+ struct higmac_napi *q_napi = container_of(napi, 42355+ struct higmac_napi, napi); 42356+ struct higmac_netdev_local *priv = q_napi->ndev_priv; 42357+ int work_done = 0; 42358+ int num; 42359+ u32 ints; 42360+ u32 raw_int_reg, raw_int_mask; 42361+ 42362+ dev_hold(priv->netdev); 42363+ if (q_napi->rxq_id) { 42364+ raw_int_reg = RSS_RAW_PMU_INT; 42365+ raw_int_mask = def_int_mask_queue((u32)q_napi->rxq_id); 42366+ } else { 42367+ raw_int_reg = RAW_PMU_INT; 42368+ raw_int_mask = DEF_INT_MASK; 42369+ } 42370+ 42371+ do { 42372+ if (!q_napi->rxq_id) 42373+ higmac_xmit_reclaim(priv->netdev); 42374+ num = higmac_rx(priv->netdev, budget - work_done, q_napi->rxq_id); 42375+ work_done += num; 42376+ if (work_done >= budget) 42377+ break; 42378+ 42379+ ints = readl(priv->gmac_iobase + raw_int_reg); 42380+ ints &= raw_int_mask; 42381+ writel(ints, priv->gmac_iobase + raw_int_reg); 42382+ } while (ints || higmac_rxq_has_packets(priv, q_napi->rxq_id)); 42383+ 42384+ if (work_done < budget) { 42385+ napi_complete(napi); 42386+ higmac_irq_enable_queue(priv, q_napi->rxq_id); 42387+ } 42388+ 42389+ dev_put(priv->netdev); 42390+ return work_done; 42391+} 42392+ 42393+static irqreturn_t higmac_interrupt(int irq, void *dev_id) 42394+{ 42395+ struct higmac_napi *q_napi = (struct higmac_napi *)dev_id; 42396+ struct higmac_netdev_local *ld = q_napi->ndev_priv; 42397+ u32 ints; 42398+ u32 raw_int_reg, raw_int_mask; 42399+ 42400+ if (higmac_queue_irq_disabled(ld, q_napi->rxq_id)) 42401+ return IRQ_NONE; 42402+ 42403+ if (q_napi->rxq_id) { 42404+ raw_int_reg = RSS_RAW_PMU_INT; 42405+ raw_int_mask = def_int_mask_queue((u32)q_napi->rxq_id); 42406+ } else { 42407+ raw_int_reg = RAW_PMU_INT; 42408+ raw_int_mask = DEF_INT_MASK; 42409+ } 42410+ 42411+ ints = readl(ld->gmac_iobase + raw_int_reg); 42412+ ints &= raw_int_mask; 42413+ writel(ints, ld->gmac_iobase + raw_int_reg); 42414+ 42415+ if (likely(ints || higmac_rxq_has_packets(ld, q_napi->rxq_id))) { 42416+ higmac_irq_disable_queue(ld, q_napi->rxq_id); 42417+ napi_schedule(&q_napi->napi); 42418+ } 42419+ 42420+ return IRQ_HANDLED; 42421+} 42422+ 42423+static int higmac_xmit_gso_sg_frag(struct higmac_netdev_local *ld, 42424+ struct sk_buff *skb, struct sg_desc *desc_cur, 42425+ struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos) 42426+{ 42427+ int nfrags = skb_shinfo(skb)->nr_frags; 42428+ dma_addr_t addr; 42429+ dma_addr_t dma_addr; 42430+ phys_addr_t phys_addr; 42431+ int i, ret; 42432+ 42433+ for (i = 0; i < nfrags; i++) { 42434+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 42435+ int len = frag->size; 42436+ 42437+ if (!has_cap_cci(ld->hw_cap)) { 42438+ dma_addr = skb_frag_dma_map(ld->dev, frag, 0, 42439+ len, DMA_TO_DEVICE); 42440+ ret = dma_mapping_error(ld->dev, dma_addr); 42441+ if (unlikely(ret)) { 42442+ pr_err("skb frag DMA Mapping fail"); 42443+ return -EFAULT; 42444+ } 42445+ desc_cur->frags[i].addr = (u32)dma_addr; 42446+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42447+ desc_cur->frags[i].reserved = 42448+ (dma_addr >> REG_BIT_WIDTH) << 42449+ SG_DESC_HI8_OFFSET; 42450+#endif 42451+ } else { 42452+ phys_addr = 42453+ page_to_phys(skb_frag_page(frag)) + frag->page_offset; 42454+ desc_cur->frags[i].addr = (u32)phys_addr; 42455+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42456+ desc_cur->frags[i].reserved = 42457+ (phys_addr >> REG_BIT_WIDTH) << 42458+ SG_DESC_HI8_OFFSET; 42459+#endif 42460+ } 42461+ desc_cur->frags[i].size = len; 42462+ } 42463+ 42464+ addr = ld->dma_sg_phy + ld->sg_head * sizeof(struct sg_desc); 42465+ tx_bq_desc->data_buff_addr = (u32)addr; 42466+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42467+ tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) & 42468+ TX_DESC_HI8_MASK; 42469+#endif 42470+ ld->TX_BQ.sg_desc_offset[desc_pos] = ld->sg_head; 42471+ 42472+ ld->sg_head = (ld->sg_head + 1) % ld->sg_count; 42473+ 42474+ return 0; 42475+} 42476+ 42477+static int higmac_xmit_gso_sg(struct higmac_netdev_local *ld, 42478+ struct sk_buff *skb, 42479+ struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos) 42480+{ 42481+ struct sg_desc *desc_cur = NULL; 42482+ dma_addr_t dma_addr; 42483+ phys_addr_t phys_addr; 42484+ int ret; 42485+ 42486+ if (unlikely(((ld->sg_head + 1) % ld->sg_count) == ld->sg_tail)) { 42487+ /* SG pkt, but sg desc all used */ 42488+ pr_err("WARNING: sg desc all used.\n"); 42489+ return -EBUSY; 42490+ } 42491+ 42492+ desc_cur = ld->dma_sg_desc + ld->sg_head; 42493+ 42494+ /* deal with ipv6_id */ 42495+ if (tx_bq_desc->desc1.tx.tso_flag && 42496+ tx_bq_desc->desc1.tx.ip_ver == PKT_IPV6 && 42497+ tx_bq_desc->desc1.tx.prot_type == PKT_UDP) 42498+ desc_cur->ipv6_id = ntohl(skb_shinfo(skb)->ip6_frag_id); 42499+ 42500+ desc_cur->total_len = skb->len; 42501+ desc_cur->linear_len = skb_headlen(skb); 42502+ if (!has_cap_cci(ld->hw_cap)) { 42503+ dma_addr = dma_map_single(ld->dev, skb->data, 42504+ desc_cur->linear_len, 42505+ DMA_TO_DEVICE); 42506+ ret = dma_mapping_error(ld->dev, dma_addr); 42507+ if (unlikely(ret)) { 42508+ pr_err("DMA Mapping fail"); 42509+ return -EFAULT; 42510+ } 42511+ desc_cur->linear_addr = (u32)dma_addr; 42512+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42513+ desc_cur->reserv3 = (dma_addr >> REG_BIT_WIDTH) << 42514+ SG_DESC_HI8_OFFSET; 42515+#endif 42516+ } else { 42517+ phys_addr = virt_to_phys(skb->data); 42518+ desc_cur->linear_addr = (u32)phys_addr; 42519+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42520+ desc_cur->reserv3 = (phys_addr >> REG_BIT_WIDTH) << 42521+ SG_DESC_HI8_OFFSET; 42522+#endif 42523+ } 42524+ 42525+ ret = higmac_xmit_gso_sg_frag(ld, skb, desc_cur, tx_bq_desc, desc_pos); 42526+ if (unlikely(ret)) 42527+ return ret; 42528+ 42529+ return 0; 42530+} 42531+ 42532+static int higmac_xmit_gso(struct higmac_netdev_local *ld, struct sk_buff *skb, 42533+ struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos) 42534+{ 42535+ int pkt_type = PKT_NORMAL; 42536+ int nfrags = skb_shinfo(skb)->nr_frags; 42537+ dma_addr_t addr; 42538+ int ret; 42539+ 42540+ if (skb_is_gso(skb) || nfrags) 42541+ pkt_type = PKT_SG; /* TSO pkt or SG pkt */ 42542+ 42543+ ret = higmac_check_hw_capability(skb); 42544+ if (unlikely(ret)) 42545+ return ret; 42546+ 42547+ ret = higmac_get_pkt_info(ld, skb, tx_bq_desc); 42548+ if (unlikely(ret)) 42549+ return ret; 42550+ 42551+ if (pkt_type == PKT_NORMAL) { 42552+ if (!has_cap_cci(ld->hw_cap)) { 42553+ addr = dma_map_single(ld->dev, skb->data, skb->len, DMA_TO_DEVICE); 42554+ ret = dma_mapping_error(ld->dev, addr); 42555+ if (unlikely(ret)) { 42556+ pr_err("Normal Packet DMA Mapping fail.\n"); 42557+ return -EFAULT; 42558+ } 42559+ tx_bq_desc->data_buff_addr = (u32)addr; 42560+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42561+ tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) & 42562+ TX_DESC_HI8_MASK; 42563+#endif 42564+ } else { 42565+ addr = virt_to_phys(skb->data); 42566+ tx_bq_desc->data_buff_addr = (u32)addr; 42567+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42568+ tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) & 42569+ TX_DESC_HI8_MASK; 42570+#endif 42571+ } 42572+ } else { 42573+ ret = higmac_xmit_gso_sg(ld, skb, tx_bq_desc, desc_pos); 42574+ if (unlikely(ret)) 42575+ return ret; 42576+ } 42577+ 42578+#ifdef HIGMAC_TSO_DEBUG 42579+ if (id_send >= MAX_RECORD) 42580+ id_send = 0; 42581+ memcpy(&pkt_rec[id_send].desc, tx_bq_desc, sizeof(struct higmac_tso_desc)); 42582+ pkt_rec[id_send].status = 1; 42583+ id_send++; 42584+#endif 42585+ return 0; 42586+} 42587+ 42588+static netdev_tx_t higmac_net_xmit(struct sk_buff *skb, struct net_device *dev); 42589+ 42590+static netdev_tx_t higmac_sw_gso(struct higmac_netdev_local *ld, 42591+ struct sk_buff *skb) 42592+{ 42593+ struct sk_buff *segs = NULL; 42594+ struct sk_buff *curr_skb = NULL; 42595+ int ret; 42596+ int gso_segs = skb_shinfo(skb)->gso_segs; 42597+ if (gso_segs == 0 && skb_shinfo(skb)->gso_size != 0) 42598+ gso_segs = DIV_ROUND_UP(skb->len, skb_shinfo(skb)->gso_size); 42599+ 42600+ /* Estimate the number of fragments in the worst case */ 42601+ if (unlikely(higmac_tx_avail(ld) < gso_segs)) { 42602+ netif_stop_queue(ld->netdev); 42603+ if (higmac_tx_avail(ld) < gso_segs) { 42604+ ld->netdev->stats.tx_dropped++; 42605+ ld->netdev->stats.tx_fifo_errors++; 42606+ return NETDEV_TX_BUSY; 42607+ } 42608+ netif_wake_queue(ld->netdev); 42609+ } 42610+ 42611+ segs = skb_gso_segment(skb, ld->netdev->features & ~(NETIF_F_CSUM_MASK | 42612+ NETIF_F_SG | NETIF_F_GSO_SOFTWARE)); 42613+ if (IS_ERR_OR_NULL(segs)) 42614+ goto drop; 42615+ 42616+ do { 42617+ curr_skb = segs; 42618+ segs = segs->next; 42619+ curr_skb->next = NULL; 42620+ ret = higmac_net_xmit(curr_skb, ld->netdev); 42621+ if (unlikely(ret != NETDEV_TX_OK)) 42622+ pr_err_once("higmac_net_xmit error ret=%d\n", ret); 42623+ } while (segs != NULL); 42624+ 42625+ dev_kfree_skb_any(skb); 42626+ return NETDEV_TX_OK; 42627+ 42628+drop: 42629+ dev_kfree_skb_any(skb); 42630+ ld->netdev->stats.tx_dropped++; 42631+ return NETDEV_TX_OK; 42632+} 42633+ 42634+static int higmac_net_xmit_normal(struct sk_buff *skb, struct net_device *dev, 42635+ struct higmac_desc *desc, u32 pos) 42636+{ 42637+ struct higmac_netdev_local *ld = netdev_priv(dev); 42638+ dma_addr_t addr; 42639+ 42640+ if (!has_cap_cci(ld->hw_cap)) { 42641+ addr = dma_map_single(ld->dev, skb->data, skb->len, DMA_TO_DEVICE); 42642+ if (unlikely(dma_mapping_error(ld->dev, addr))) { 42643+ dev_kfree_skb_any(skb); 42644+ dev->stats.tx_dropped++; 42645+ ld->tx_skb[pos] = NULL; 42646+ ld->TX_BQ.skb[pos] = NULL; 42647+ return -1; 42648+ } 42649+ desc->data_buff_addr = (u32)addr; 42650+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42651+ desc->rxhash = (addr >> REG_BIT_WIDTH) & TX_DESC_HI8_MASK; 42652+#endif 42653+ } else { 42654+ addr = virt_to_phys(skb->data); 42655+ desc->data_buff_addr = (u32)addr; 42656+#if defined(CONFIG_HIGMAC_DDR_64BIT) 42657+ desc->rxhash = (addr >> REG_BIT_WIDTH) & TX_DESC_HI8_MASK; 42658+#endif 42659+ } 42660+ desc->buffer_len = HIETH_MAX_FRAME_SIZE - 1; 42661+ desc->data_len = skb->len; 42662+ desc->fl = DESC_FL_FULL; 42663+ desc->descvid = DESC_VLD_BUSY; 42664+ 42665+ return 0; 42666+} 42667+ 42668+static int higmac_check_skb_len(struct sk_buff *skb, struct net_device *dev) 42669+{ 42670+ if (skb->len < ETH_HLEN) { 42671+ dev_kfree_skb_any(skb); 42672+ dev->stats.tx_errors++; 42673+ dev->stats.tx_dropped++; 42674+ return -1; 42675+ } 42676+ return 0; 42677+} 42678+ 42679+static netdev_tx_t higmac_net_xmit(struct sk_buff *skb, struct net_device *dev) 42680+{ 42681+ struct higmac_netdev_local *ld = netdev_priv(dev); 42682+ struct higmac_desc *desc = NULL; 42683+ unsigned long txflags; 42684+ int ret; 42685+ u32 pos; 42686+ 42687+ if (unlikely(higmac_check_skb_len(skb, dev) < 0)) 42688+ return NETDEV_TX_OK; 42689+ 42690+ /* 42691+ * if adding higmac_xmit_reclaim here, iperf tcp client 42692+ * performance will be affected, from 550M(avg) to 513M~300M 42693+ */ 42694+ 42695+ /* software write pointer */ 42696+ pos = dma_cnt(readl(ld->gmac_iobase + TX_BQ_WR_ADDR)); 42697+ 42698+ spin_lock_irqsave(&ld->txlock, txflags); 42699+ 42700+ if (unlikely(ld->tx_skb[pos] || ld->TX_BQ.skb[pos])) { 42701+ dev->stats.tx_dropped++; 42702+ dev->stats.tx_fifo_errors++; 42703+ netif_stop_queue(dev); 42704+ spin_unlock_irqrestore(&ld->txlock, txflags); 42705+ 42706+ return NETDEV_TX_BUSY; 42707+ } 42708+ 42709+ ld->TX_BQ.skb[pos] = skb; 42710+ ld->tx_skb[pos] = skb; 42711+ 42712+ desc = ld->TX_BQ.desc + pos; 42713+ 42714+ if (ld->tso_supported) { 42715+ ret = higmac_xmit_gso(ld, skb, (struct higmac_tso_desc *)desc, pos); 42716+ if (unlikely(ret < 0)) { 42717+ ld->tx_skb[pos] = NULL; 42718+ ld->TX_BQ.skb[pos] = NULL; 42719+ spin_unlock_irqrestore(&ld->txlock, txflags); 42720+ 42721+ if (ret == -ENOTSUPP) 42722+ return higmac_sw_gso(ld, skb); 42723+ 42724+ dev_kfree_skb_any(skb); 42725+ dev->stats.tx_dropped++; 42726+ return NETDEV_TX_OK; 42727+ } 42728+ } else { 42729+ ret = higmac_net_xmit_normal(skb, dev, desc, pos); 42730+ if (unlikely(ret < 0)) { 42731+ spin_unlock_irqrestore(&ld->txlock, txflags); 42732+ return NETDEV_TX_OK; 42733+ } 42734+ } 42735+ 42736+ /* 42737+ * This barrier is important here. It is required to ensure 42738+ * the ARM CPU flushes it's DMA write buffers before proceeding 42739+ * to the next instruction, to ensure that GMAC will see 42740+ * our descriptor changes in memory 42741+ */ 42742+ higmac_sync_barrier(); 42743+ pos = dma_ring_incr(pos, TX_DESC_NUM); 42744+ writel(dma_byte(pos), ld->gmac_iobase + TX_BQ_WR_ADDR); 42745+ 42746+ netif_trans_update(dev); 42747+ dev->stats.tx_packets++; 42748+ dev->stats.tx_bytes += skb->len; 42749+ netdev_sent_queue(dev, skb->len); 42750+ 42751+ spin_unlock_irqrestore(&ld->txlock, txflags); 42752+ 42753+ return NETDEV_TX_OK; 42754+} 42755+ 42756+void higmac_enable_napi(struct higmac_netdev_local *priv) 42757+{ 42758+ struct higmac_napi *q_napi = NULL; 42759+ int i; 42760+ if (priv == NULL) 42761+ return; 42762+ for (i = 0; i < priv->num_rxqs; i++) { 42763+ q_napi = &priv->q_napi[i]; 42764+ napi_enable(&q_napi->napi); 42765+ } 42766+} 42767+ 42768+void higmac_disable_napi(struct higmac_netdev_local *priv) 42769+{ 42770+ struct higmac_napi *q_napi = NULL; 42771+ int i; 42772+ if (priv == NULL) 42773+ return; 42774+ for (i = 0; i < priv->num_rxqs; i++) { 42775+ q_napi = &priv->q_napi[i]; 42776+ napi_disable(&q_napi->napi); 42777+ } 42778+} 42779+ 42780+static int higmac_net_open(struct net_device *dev) 42781+{ 42782+ struct higmac_netdev_local *ld = netdev_priv(dev); 42783+ unsigned long flags; 42784+ 42785+ clk_prepare_enable(ld->macif_clk); 42786+ clk_prepare_enable(ld->clk); 42787+ 42788+ /* 42789+ * If we configure mac address by 42790+ * "ifconfig ethX hw ether XX:XX:XX:XX:XX:XX", 42791+ * the ethX must be down state and mac core clock is disabled 42792+ * which results the mac address has not been configured 42793+ * in mac core register. 42794+ * So we must set mac address again here, 42795+ * because mac core clock is enabled at this time 42796+ * and we can configure mac address to mac core register. 42797+ */ 42798+ higmac_hw_set_mac_addr(dev); 42799+ 42800+ /* 42801+ * We should use netif_carrier_off() here, 42802+ * because the default state should be off. 42803+ * And this call should before phy_start(). 42804+ */ 42805+ netif_carrier_off(dev); 42806+ higmac_enable_napi(ld); 42807+ phy_start(ld->phy); 42808+ 42809+ higmac_hw_desc_enable(ld); 42810+ higmac_port_enable(ld); 42811+ higmac_irq_enable_all_queue(ld); 42812+ 42813+ spin_lock_irqsave(&ld->rxlock, flags); 42814+ higmac_rx_refill(ld); 42815+ spin_unlock_irqrestore(&ld->rxlock, flags); 42816+ 42817+ ld->monitor.expires = jiffies + HIGMAC_MONITOR_TIMER; 42818+ mod_timer(&ld->monitor, ld->monitor.expires); 42819+ 42820+ netif_start_queue(dev); 42821+ 42822+ return 0; 42823+} 42824+ 42825+static int higmac_net_close(struct net_device *dev) 42826+{ 42827+ struct higmac_netdev_local *ld = netdev_priv(dev); 42828+ 42829+ higmac_irq_disable_all_queue(ld); 42830+ higmac_hw_desc_disable(ld); 42831+ 42832+ higmac_disable_napi(ld); 42833+ 42834+ netif_carrier_off(dev); 42835+ netif_stop_queue(dev); 42836+ 42837+ phy_stop(ld->phy); 42838+ del_timer_sync(&ld->monitor); 42839+ 42840+ clk_disable_unprepare(ld->clk); 42841+ clk_disable_unprepare(ld->macif_clk); 42842+ 42843+ return 0; 42844+} 42845+ 42846+static void higmac_net_timeout(struct net_device *dev) 42847+{ 42848+ dev->stats.tx_errors++; 42849+ 42850+ pr_err("tx timeout!\n"); 42851+} 42852+ 42853+static void higmac_set_multicast_list(struct net_device *dev) 42854+{ 42855+ higmac_gmac_multicast_list(dev); 42856+} 42857+ 42858+static void higmac_enable_rxcsum_drop(struct higmac_netdev_local const *ld, 42859+ bool drop) 42860+{ 42861+ unsigned int v; 42862+ 42863+ v = readl(ld->gmac_iobase + TSO_COE_CTRL); 42864+ if (drop) 42865+ v |= COE_ERR_DROP; 42866+ else 42867+ v &= ~COE_ERR_DROP; 42868+ writel(v, ld->gmac_iobase + TSO_COE_CTRL); 42869+} 42870+ 42871+static int higmac_set_features(struct net_device *dev, 42872+ netdev_features_t features) 42873+{ 42874+ struct higmac_netdev_local *ld = netdev_priv(dev); 42875+ netdev_features_t changed = dev->features ^ features; 42876+ 42877+ if (changed & NETIF_F_RXCSUM) { 42878+ if (features & NETIF_F_RXCSUM) 42879+ higmac_enable_rxcsum_drop(ld, true); 42880+ else 42881+ higmac_enable_rxcsum_drop(ld, false); 42882+ } 42883+ 42884+ return 0; 42885+} 42886+ 42887+static struct net_device_stats *higmac_net_get_stats(struct net_device *dev) 42888+{ 42889+ return &dev->stats; 42890+} 42891+ 42892+static const struct ethtool_ops hieth_ethtools_ops = { 42893+ .get_drvinfo = higmac_get_drvinfo, 42894+ .get_link = higmac_get_link, 42895+ .get_settings = higmac_get_settings, 42896+ .set_settings = higmac_set_settings, 42897+ .get_pauseparam = higmac_get_pauseparam, 42898+ .set_pauseparam = higmac_set_pauseparam, 42899+ .get_msglevel = higmac_ethtool_getmsglevel, 42900+ .set_msglevel = higmac_ethtool_setmsglevel, 42901+ .get_rxfh_key_size = higmac_get_rxfh_key_size, 42902+ .get_rxfh_indir_size = higmac_get_rxfh_indir_size, 42903+ .get_rxfh = higmac_get_rxfh, 42904+ .set_rxfh = higmac_set_rxfh, 42905+ .get_rxnfc = higmac_get_rxnfc, 42906+ .set_rxnfc = higmac_set_rxnfc, 42907+}; 42908+ 42909+static const struct net_device_ops hieth_netdev_ops = { 42910+ .ndo_open = higmac_net_open, 42911+ .ndo_stop = higmac_net_close, 42912+ .ndo_start_xmit = higmac_net_xmit, 42913+ .ndo_tx_timeout = higmac_net_timeout, 42914+ .ndo_set_rx_mode = higmac_set_multicast_list, 42915+ .ndo_set_features = higmac_set_features, 42916+ .ndo_do_ioctl = higmac_ioctl, 42917+ .ndo_set_mac_address = higmac_net_set_mac_address, 42918+ .ndo_change_mtu = eth_change_mtu, 42919+ .ndo_get_stats = higmac_net_get_stats, 42920+}; 42921+ 42922+static int higmac_of_get_param(struct higmac_netdev_local *ld, 42923+ struct device_node const *node) 42924+{ 42925+ /* get auto eee */ 42926+ ld->autoeee = of_property_read_bool(node, "autoeee"); 42927+ /* get internal flag */ 42928+ ld->internal_phy = 42929+ of_property_read_bool(node, "internal-phy"); 42930+ 42931+ return 0; 42932+} 42933+ 42934+static void higmac_destroy_hw_desc_queue(struct higmac_netdev_local *priv) 42935+{ 42936+ int i; 42937+ 42938+ for (i = 0; i < QUEUE_NUMS + RSS_NUM_RXQS - 1; i++) { 42939+ if (priv->pool[i].desc) { 42940+ if (has_cap_cci(priv->hw_cap)) 42941+ kfree(priv->pool[i].desc); 42942+ else 42943+ dma_free_coherent(priv->dev, priv->pool[i].size, 42944+ priv->pool[i].desc, 42945+ priv->pool[i].phys_addr); 42946+ priv->pool[i].desc = NULL; 42947+ } 42948+ } 42949+ 42950+ kfree(priv->RX_FQ.skb); 42951+ kfree(priv->TX_BQ.skb); 42952+ priv->RX_FQ.skb = NULL; 42953+ priv->TX_BQ.skb = NULL; 42954+ 42955+ if (priv->tso_supported) { 42956+ kfree(priv->TX_BQ.sg_desc_offset); 42957+ priv->TX_BQ.sg_desc_offset = NULL; 42958+ } 42959+ 42960+ kfree(priv->tx_skb); 42961+ priv->tx_skb = NULL; 42962+ 42963+ kfree(priv->rx_skb); 42964+ priv->rx_skb = NULL; 42965+} 42966+ 42967+static int higmac_init_desc_queue_mem(struct higmac_netdev_local *priv) 42968+{ 42969+ priv->RX_FQ.skb = kzalloc(priv->RX_FQ.count 42970+ * sizeof(struct sk_buff *), GFP_KERNEL); 42971+ if (!priv->RX_FQ.skb) 42972+ return -ENOMEM; 42973+ 42974+ priv->rx_skb = kzalloc(priv->RX_FQ.count 42975+ * sizeof(struct sk_buff *), GFP_KERNEL); 42976+ if (priv->rx_skb == NULL) 42977+ return -ENOMEM; 42978+ 42979+ priv->TX_BQ.skb = kzalloc(priv->TX_BQ.count 42980+ * sizeof(struct sk_buff *), GFP_KERNEL); 42981+ if (!priv->TX_BQ.skb) 42982+ return -ENOMEM; 42983+ 42984+ priv->tx_skb = kzalloc(priv->TX_BQ.count 42985+ * sizeof(struct sk_buff *), GFP_KERNEL); 42986+ if (priv->tx_skb == NULL) 42987+ return -ENOMEM; 42988+ 42989+ if (priv->tso_supported) { 42990+ priv->TX_BQ.sg_desc_offset = kzalloc(priv->TX_BQ.count 42991+ * sizeof(int), GFP_KERNEL); 42992+ if (!priv->TX_BQ.sg_desc_offset) 42993+ return -ENOMEM; 42994+ } 42995+ 42996+ return 0; 42997+} 42998+ 42999+static int higmac_init_hw_desc_queue(struct higmac_netdev_local *priv) 43000+{ 43001+ struct device *dev = NULL; 43002+ struct higmac_desc *virt_addr = NULL; 43003+ dma_addr_t phys_addr = 0; 43004+ int size, i; 43005+ if (priv == NULL || priv->dev == NULL) 43006+ return -EINVAL; 43007+ dev = priv->dev; 43008+ if (dev == NULL) 43009+ return -EINVAL; 43010+ priv->RX_FQ.count = RX_DESC_NUM; 43011+ priv->RX_BQ.count = RX_DESC_NUM; 43012+ priv->TX_BQ.count = TX_DESC_NUM; 43013+ priv->TX_RQ.count = TX_DESC_NUM; 43014+ 43015+ for (i = 1; i < RSS_NUM_RXQS; i++) 43016+ priv->pool[BASE_QUEUE_NUMS + i].count = RX_DESC_NUM; 43017+ 43018+ for (i = 0; i < (QUEUE_NUMS + RSS_NUM_RXQS - 1); i++) { 43019+ size = priv->pool[i].count * sizeof(struct higmac_desc); 43020+ if (has_cap_cci(priv->hw_cap)) { 43021+ virt_addr = kmalloc(size, GFP_KERNEL); 43022+ if (virt_addr != NULL) { 43023+ memset(virt_addr, 0, size); 43024+ phys_addr = virt_to_phys(virt_addr); 43025+ } 43026+ } else { 43027+ virt_addr = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); 43028+ if (virt_addr != NULL) 43029+ memset(virt_addr, 0, size); 43030+ } 43031+ if (virt_addr == NULL) 43032+ goto error_free_pool; 43033+ 43034+ priv->pool[i].size = size; 43035+ priv->pool[i].desc = virt_addr; 43036+ priv->pool[i].phys_addr = phys_addr; 43037+ } 43038+ 43039+ if (higmac_init_desc_queue_mem(priv) == -ENOMEM) 43040+ goto error_free_pool; 43041+ 43042+ higmac_hw_set_desc_addr(priv); 43043+ if (has_cap_cci(priv->hw_cap)) 43044+ pr_info("higmac: ETH MAC supporte CCI.\n"); 43045+ 43046+ return 0; 43047+ 43048+error_free_pool: 43049+ higmac_destroy_hw_desc_queue(priv); 43050+ 43051+ return -ENOMEM; 43052+} 43053+ 43054+void higmac_init_napi(struct higmac_netdev_local *priv) 43055+{ 43056+ struct higmac_napi *q_napi = NULL; 43057+ int i; 43058+ if (priv == NULL || priv->netdev == NULL) 43059+ return; 43060+ for (i = 0; i < priv->num_rxqs; i++) { 43061+ q_napi = &priv->q_napi[i]; 43062+ q_napi->rxq_id = i; 43063+ q_napi->ndev_priv = priv; 43064+ netif_napi_add(priv->netdev, &q_napi->napi, higmac_poll, 43065+ NAPI_POLL_WEIGHT); 43066+ } 43067+} 43068+ 43069+void higmac_destroy_napi(struct higmac_netdev_local *priv) 43070+{ 43071+ struct higmac_napi *q_napi = NULL; 43072+ int i; 43073+ if (priv == NULL) 43074+ return; 43075+ for (i = 0; i < priv->num_rxqs; i++) { 43076+ q_napi = &priv->q_napi[i]; 43077+ netif_napi_del(&q_napi->napi); 43078+ } 43079+} 43080+ 43081+int higmac_request_irqs(struct platform_device *pdev, 43082+ struct higmac_netdev_local *priv) 43083+{ 43084+ struct device *dev = NULL; 43085+ int ret; 43086+ int i; 43087+ if (pdev == NULL || priv == NULL || priv->dev == NULL || pdev->name == NULL) 43088+ return -ENOMEM; 43089+ 43090+ dev = priv->dev; 43091+ for (i = 0; i < priv->num_rxqs; i++) { 43092+ ret = platform_get_irq(pdev, i); 43093+ if (ret < 0) { 43094+ dev_err(dev, "No irq[%d] resource, ret=%d\n", i, ret); 43095+ return ret; 43096+ } 43097+ priv->irq[i] = ret; 43098+ 43099+ ret = devm_request_irq(dev, priv->irq[i], higmac_interrupt, 43100+ IRQF_SHARED, pdev->name, 43101+ &priv->q_napi[i]); 43102+ if (ret) { 43103+ dev_err(dev, "devm_request_irq failed, ret=%d\n", ret); 43104+ return ret; 43105+ } 43106+ } 43107+ 43108+ return 0; 43109+} 43110+ 43111+static int higmac_dev_probe_res(struct platform_device *pdev, 43112+ struct higmac_netdev_local *priv) 43113+{ 43114+ struct device *dev = &pdev->dev; 43115+ struct net_device *ndev = priv->netdev; 43116+ struct resource *res = NULL; 43117+ int ret; 43118+ 43119+ res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_GMAC_IOBASE); 43120+ priv->gmac_iobase = devm_ioremap_resource(dev, res); 43121+ if (IS_ERR(priv->gmac_iobase)) { 43122+ ret = PTR_ERR(priv->gmac_iobase); 43123+ return ret; 43124+ } 43125+ 43126+ res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_MACIF_IOBASE); 43127+ priv->macif_base = devm_ioremap_resource(dev, res); 43128+ if (IS_ERR(priv->macif_base)) { 43129+ ret = PTR_ERR(priv->macif_base); 43130+ return ret; 43131+ } 43132+ 43133+ /* only for some chip to fix AXI bus burst and outstanding config */ 43134+ res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_AXI_BUS_CFG_IOBASE); 43135+ priv->axi_bus_cfg_base = devm_ioremap_resource(dev, res); 43136+ if (IS_ERR(priv->axi_bus_cfg_base)) 43137+ priv->axi_bus_cfg_base = NULL; 43138+ 43139+ priv->port_rst = devm_reset_control_get(dev, HIGMAC_PORT_RST_NAME); 43140+ if (IS_ERR(priv->port_rst)) { 43141+ ret = PTR_ERR(priv->port_rst); 43142+ return ret; 43143+ } 43144+ 43145+ priv->macif_rst = devm_reset_control_get(dev, HIGMAC_MACIF_RST_NAME); 43146+ if (IS_ERR(priv->macif_rst)) { 43147+ ret = PTR_ERR(priv->macif_rst); 43148+ return ret; 43149+ } 43150+ 43151+ priv->phy_rst = devm_reset_control_get(dev, HIGMAC_PHY_RST_NAME); 43152+ if (IS_ERR(priv->phy_rst)) 43153+ priv->phy_rst = NULL; 43154+ 43155+ priv->clk = devm_clk_get(&pdev->dev, HIGMAC_MAC_CLK_NAME); 43156+ if (IS_ERR(priv->clk)) { 43157+ netdev_err(ndev, "failed to get clk\n"); 43158+ ret = -ENODEV; 43159+ return ret; 43160+ } 43161+ 43162+ ret = clk_prepare_enable(priv->clk); 43163+ if (ret < 0) { 43164+ netdev_err(ndev, "failed to enable clk %d\n", ret); 43165+ return ret; 43166+ } 43167+ return 0; 43168+} 43169+ 43170+static int higmac_dev_macif_clk(struct platform_device *pdev, 43171+ struct higmac_netdev_local *priv, struct net_device *ndev) 43172+{ 43173+ int ret; 43174+ 43175+ priv->macif_clk = devm_clk_get(&pdev->dev, HIGMAC_MACIF_CLK_NAME); 43176+ if (IS_ERR(priv->macif_clk)) 43177+ priv->macif_clk = NULL; 43178+ 43179+ if (priv->macif_clk != NULL) { 43180+ ret = clk_prepare_enable(priv->macif_clk); 43181+ if (ret < 0) { 43182+ netdev_err(ndev, "failed enable macif_clk %d\n", ret); 43183+ return ret; 43184+ } 43185+ } 43186+ return 0; 43187+} 43188+ 43189+static int higmac_dev_probe_init(struct platform_device *pdev, 43190+ struct higmac_netdev_local *priv, struct net_device *ndev) 43191+{ 43192+ int ret; 43193+ 43194+ higmac_init_napi(priv); 43195+ spin_lock_init(&priv->rxlock); 43196+ spin_lock_init(&priv->txlock); 43197+ spin_lock_init(&priv->pmtlock); 43198+ 43199+ /* init netdevice */ 43200+ ndev->irq = priv->irq[0]; 43201+ ndev->watchdog_timeo = 3 * HZ; /* 3HZ */ 43202+ ndev->netdev_ops = &hieth_netdev_ops; 43203+ ndev->ethtool_ops = &hieth_ethtools_ops; 43204+ 43205+ if (priv->has_rxhash_cap) 43206+ ndev->hw_features |= NETIF_F_RXHASH; 43207+ if (priv->has_rss_cap) 43208+ ndev->hw_features |= NETIF_F_NTUPLE; 43209+ if (priv->tso_supported) 43210+ ndev->hw_features |= NETIF_F_SG | 43211+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 43212+ NETIF_F_TSO | NETIF_F_TSO6; 43213+ 43214+#if defined(CONFIG_HIGMAC_RXCSUM) 43215+ ndev->hw_features |= NETIF_F_RXCSUM; 43216+ higmac_enable_rxcsum_drop(priv, true); 43217+#endif 43218+ 43219+ ndev->features |= ndev->hw_features; 43220+ ndev->features |= NETIF_F_HIGHDMA | NETIF_F_GSO; 43221+ ndev->vlan_features |= ndev->features; 43222+ 43223+ timer_setup(&priv->monitor, higmac_monitor_func, 0); 43224+ 43225+ device_set_wakeup_capable(priv->dev, 1); 43226+ /* 43227+ * when we can let phy powerdown? 43228+ * In some mode, we don't want phy powerdown, 43229+ * so I set wakeup enable all the time 43230+ */ 43231+ device_set_wakeup_enable(priv->dev, 1); 43232+ 43233+ priv->wol_enable = false; 43234+ 43235+ priv->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); 43236+ 43237+#if defined(CONFIG_HIGMAC_DDR_64BIT) 43238+ if (!has_cap_cci(priv->hw_cap)) { 43239+ struct device *dev = &pdev->dev; 43240+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); /* 64bit */ 43241+ if (ret) { 43242+ pr_err("dma set mask 64 failed! ret=%d", ret); 43243+ return ret; 43244+ } 43245+ } 43246+#endif 43247+ 43248+ /* init hw desc queue */ 43249+ ret = higmac_init_hw_desc_queue(priv); 43250+ if (ret) 43251+ return ret; 43252+ 43253+ return 0; 43254+} 43255+ 43256+static int higmac_dev_probe_phy(struct platform_device *pdev, 43257+ struct higmac_netdev_local *priv, struct net_device *ndev, 43258+ bool fixed_link) 43259+{ 43260+ int ret; 43261+ 43262+ /* phy fix here?? other way ??? */ 43263+ higmac_phy_register_fixups(); 43264+ 43265+ priv->phy = of_phy_connect(ndev, priv->phy_node, 43266+ &higmac_adjust_link, 0, priv->phy_mode); 43267+ if (priv->phy == NULL || priv->phy->drv == NULL) { 43268+ ret = -ENODEV; 43269+ return ret; 43270+ } 43271+ 43272+ /* If the phy_id is all zero and not fixed link, there is no device there */ 43273+ if ((priv->phy->phy_id == 0) && !fixed_link) { 43274+ pr_info("phy %d not found\n", priv->phy->mdio.addr); 43275+ ret = -ENODEV; 43276+ return ret; 43277+ } 43278+ 43279+ pr_info("attached PHY %d to driver %s, PHY_ID=0x%x\n", 43280+ priv->phy->mdio.addr, priv->phy->drv->name, priv->phy->phy_id); 43281+ 43282+ /* Stop Advertising 1000BASE Capability if interface is not RGMII */ 43283+ if ((priv->phy_mode == PHY_INTERFACE_MODE_MII) || 43284+ (priv->phy_mode == PHY_INTERFACE_MODE_RMII)) { 43285+ priv->phy->advertising &= ~(SUPPORTED_1000baseT_Half | 43286+ SUPPORTED_1000baseT_Full); 43287+ 43288+ /* 43289+ * Internal FE phy's reg BMSR bit8 is wrong, make the kernel 43290+ * believe it has the 1000base Capability, so fix it here 43291+ */ 43292+ if (priv->phy->phy_id == HISILICON_PHY_ID_FESTAV200) 43293+ priv->phy->supported &= ~(ADVERTISED_1000baseT_Full | 43294+ ADVERTISED_1000baseT_Half); 43295+ } 43296+ 43297+ higmac_set_flow_ctrl_args(priv); 43298+ higmac_set_flow_ctrl_params(priv); 43299+ priv->phy->supported |= SUPPORTED_Pause; 43300+ if (priv->flow_ctrl) 43301+ priv->phy->advertising |= SUPPORTED_Pause; 43302+ 43303+ if (priv->autoeee) 43304+ init_autoeee(priv); 43305+ 43306+ ret = higmac_request_irqs(pdev, priv); 43307+ if (ret) 43308+ return ret; 43309+ 43310+ return 0; 43311+} 43312+ 43313+static void higmac_set_hw_cap(struct platform_device *pdev, 43314+ struct higmac_netdev_local *priv) 43315+{ 43316+ unsigned int hw_cap; 43317+ 43318+ hw_cap = readl(priv->gmac_iobase + CRF_MIN_PACKET); 43319+ priv->tso_supported = has_tso_cap(hw_cap); 43320+ priv->has_rxhash_cap = has_rxhash_cap(hw_cap); 43321+ priv->has_rss_cap = has_rss_cap(hw_cap); 43322+ 43323+ higmac_set_rss_cap(priv); 43324+ higmac_get_rss_key(priv); 43325+ if (priv->has_rss_cap) { 43326+ priv->rss_info.ind_tbl_size = RSS_INDIRECTION_TABLE_SIZE; 43327+ higmac_get_rss(priv); 43328+ } 43329+ 43330+ if (priv->has_rxhash_cap) { 43331+ priv->rss_info.hash_cfg = DEF_HASH_CFG; 43332+ higmac_config_hash_policy(priv); 43333+ } 43334+} 43335+ 43336+static void higmac_set_mac_addr(struct net_device *ndev, 43337+ struct device_node *node) 43338+{ 43339+ const char *mac_addr = NULL; 43340+ 43341+ mac_addr = of_get_mac_address(node); 43342+ if (mac_addr != NULL) 43343+ ether_addr_copy(ndev->dev_addr, mac_addr); 43344+ if (!is_valid_ether_addr(ndev->dev_addr)) { 43345+ eth_hw_addr_random(ndev); 43346+ netdev_warn(ndev, "using random MAC address %pM\n", 43347+ ndev->dev_addr); 43348+ } 43349+ 43350+ higmac_hw_set_mac_addr(ndev); 43351+} 43352+ 43353+static int higmac_phy_init(struct device *dev, struct net_device *ndev, 43354+ struct higmac_netdev_local *priv, struct device_node *node, bool *fixed_link) 43355+{ 43356+ int ret; 43357+ 43358+ /* 43359+ * phy reset, should be early than "of_mdiobus_register". 43360+ * becausue "of_mdiobus_register" will read PHY register by MDIO. 43361+ */ 43362+ higmac_hw_phy_reset(priv); 43363+ 43364+ higmac_of_get_param(priv, node); 43365+ 43366+ ret = of_get_phy_mode(node); 43367+ if (ret < 0) { 43368+ netdev_err(ndev, "not find phy-mode\n"); 43369+ return ret; 43370+ } 43371+ priv->phy_mode = ret; 43372+ 43373+ priv->phy_node = of_parse_phandle(node, "phy-handle", 0); 43374+ if (priv->phy_node == NULL) { 43375+ /* check if a fixed-link is defined in device-tree */ 43376+ if (of_phy_is_fixed_link(node)) { 43377+ ret = of_phy_register_fixed_link(node); 43378+ if (ret < 0) { 43379+ dev_err(dev, "cannot register fixed PHY %d\n", ret); 43380+ return ret; 43381+ } 43382+ 43383+ /* 43384+ * In the case of a fixed PHY, the DT node associated 43385+ * to the PHY is the Ethernet MAC DT node. 43386+ */ 43387+ priv->phy_node = of_node_get(node); 43388+ *fixed_link = true; 43389+ } else { 43390+ netdev_err(ndev, "not find phy-handle\n"); 43391+ ret = -EINVAL; 43392+ return ret; 43393+ } 43394+ } 43395+ return 0; 43396+} 43397+ 43398+static int higmac_dev_probe_device(struct platform_device *pdev, 43399+ struct net_device **p_ndev, struct higmac_netdev_local **p_priv) 43400+{ 43401+ struct device *dev = &pdev->dev; 43402+ struct device_node *node = dev->of_node; 43403+ struct net_device *ndev = NULL; 43404+ struct higmac_netdev_local *priv = NULL; 43405+ int num_rxqs; 43406+ 43407+ higmac_verify_flow_ctrl_args(); 43408+ 43409+ if (of_device_is_compatible(node, "hisilicon,higmac-v5")) 43410+ num_rxqs = RSS_NUM_RXQS; 43411+ else 43412+ num_rxqs = 1; 43413+ 43414+ ndev = alloc_etherdev_mqs(sizeof(struct higmac_netdev_local), 1, 43415+ num_rxqs); 43416+ if (ndev == NULL) 43417+ return -ENOMEM; 43418+ 43419+ platform_set_drvdata(pdev, ndev); 43420+ SET_NETDEV_DEV(ndev, dev); 43421+ 43422+ priv = netdev_priv(ndev); 43423+ priv->dev = dev; 43424+ dev_hold(ndev); 43425+ priv->netdev = ndev; 43426+ priv->num_rxqs = num_rxqs; 43427+ 43428+ if (of_device_is_compatible(node, "hisilicon,higmac-v3")) 43429+ priv->hw_cap |= HW_CAP_CCI; 43430+ 43431+ *p_ndev = ndev; 43432+ *p_priv = priv; 43433+ return 0; 43434+} 43435+ 43436+static int higmac_dev_probe_queue(struct platform_device *pdev, 43437+ struct higmac_netdev_local *priv, struct net_device *ndev, bool fixed_link) 43438+{ 43439+ int ret; 43440+ 43441+ ret = higmac_dev_probe_init(pdev, priv, ndev); 43442+ if (ret) 43443+ goto _error_hw_desc_queue; 43444+ 43445+ if (priv->tso_supported) { 43446+ ret = higmac_init_sg_desc_queue(priv); 43447+ if (ret) 43448+ goto _error_sg_desc_queue; 43449+ } 43450+ 43451+ /* register netdevice */ 43452+ ret = register_netdev(priv->netdev); 43453+ if (ret) { 43454+ pr_err("register_ndev failed!"); 43455+ goto _error_sg_desc_queue; 43456+ } 43457+ 43458+ /* 43459+ * reset queue here to make BQL only reset once. 43460+ * if we put netdev_reset_queue() in higmac_net_open(), 43461+ * the BQL will be reset when ifconfig eth0 down and up, 43462+ * but the tx ring is not cleared before. 43463+ * As a result, the NAPI poll will call netdev_completed_queue() 43464+ * and BQL throw a bug. 43465+ */ 43466+ netdev_reset_queue(ndev); 43467+ 43468+ clk_disable_unprepare(priv->clk); 43469+ if (priv->macif_clk != NULL) 43470+ clk_disable_unprepare(priv->macif_clk); 43471+ 43472+ pr_info("ETH: %s, phy_addr=%d\n", 43473+ phy_modes(priv->phy_mode), priv->phy->mdio.addr); 43474+ 43475+ dev_put(ndev); 43476+ return ret; 43477+ 43478+_error_sg_desc_queue: 43479+ if (priv->tso_supported) 43480+ higmac_destroy_sg_desc_queue(priv); 43481+_error_hw_desc_queue: 43482+ higmac_destroy_hw_desc_queue(priv); 43483+ higmac_destroy_napi(priv); 43484+ 43485+ return ret; 43486+} 43487+ 43488+static int higmac_dev_probe(struct platform_device *pdev) 43489+{ 43490+ struct device *dev = &pdev->dev; 43491+ struct device_node *node = dev->of_node; 43492+ struct net_device *ndev = NULL; 43493+ struct higmac_netdev_local *priv = NULL; 43494+ int ret; 43495+ bool fixed_link = false; 43496+ 43497+ ret = higmac_dev_probe_device(pdev, &ndev, &priv); 43498+ if (ret) 43499+ return ret; 43500+ 43501+ ret = higmac_dev_probe_res(pdev, priv); 43502+ if (ret) 43503+ goto out_free_netdev; 43504+ 43505+ ret = higmac_dev_macif_clk(pdev, priv, ndev); 43506+ if (ret) 43507+ goto out_clk_disable; 43508+ 43509+ higmac_mac_core_reset(priv); 43510+ 43511+ ret = higmac_phy_init(dev, ndev, priv, node, &fixed_link); 43512+ if (ret) 43513+ goto out_macif_clk_disable; 43514+ 43515+ higmac_set_mac_addr(ndev, node); 43516+ higmac_set_hw_cap(pdev, priv); 43517+ 43518+ /* init hw controller */ 43519+ higmac_hw_init(priv); 43520+ 43521+ ret = higmac_dev_probe_phy(pdev, priv, ndev, fixed_link); 43522+ if (ret) { 43523+ if (priv->phy == NULL) 43524+ goto out_phy_node; 43525+ else 43526+ goto out_phy_disconnect; 43527+ } 43528+ 43529+ ret = higmac_dev_probe_queue(pdev, priv, ndev, fixed_link); 43530+ if (ret) 43531+ goto out_phy_disconnect; 43532+ 43533+ return ret; 43534+ 43535+out_phy_disconnect: 43536+ phy_disconnect(priv->phy); 43537+out_phy_node: 43538+ of_node_put(priv->phy_node); 43539+out_macif_clk_disable: 43540+ if (priv->macif_clk != NULL) 43541+ clk_disable_unprepare(priv->macif_clk); 43542+out_clk_disable: 43543+ clk_disable_unprepare(priv->clk); 43544+out_free_netdev: 43545+ dev_put(ndev); 43546+ free_netdev(ndev); 43547+ 43548+ return ret; 43549+} 43550+ 43551+static int higmac_dev_remove(struct platform_device *pdev) 43552+{ 43553+ struct net_device *ndev = platform_get_drvdata(pdev); 43554+ struct higmac_netdev_local *priv = netdev_priv(ndev); 43555+ 43556+ /* stop the gmac and free all resource */ 43557+ del_timer_sync(&priv->monitor); 43558+ higmac_destroy_napi(priv); 43559+ 43560+ unregister_netdev(ndev); 43561+ 43562+ higmac_reclaim_rx_tx_resource(priv); 43563+ higmac_free_rx_skb(priv); 43564+ higmac_free_tx_skb(priv); 43565+ 43566+ if (priv->tso_supported) 43567+ higmac_destroy_sg_desc_queue(priv); 43568+ higmac_destroy_hw_desc_queue(priv); 43569+ 43570+ phy_disconnect(priv->phy); 43571+ of_node_put(priv->phy_node); 43572+ 43573+ free_netdev(ndev); 43574+ 43575+ higmac_phy_unregister_fixups(); 43576+ 43577+ return 0; 43578+} 43579+ 43580+#ifdef CONFIG_PM 43581+static void higmac_disable_irq(struct higmac_netdev_local *priv) 43582+{ 43583+ int i; 43584+ 43585+ for (i = 0; i < priv->num_rxqs; i++) 43586+ disable_irq(priv->irq[i]); 43587+} 43588+ 43589+static void higmac_enable_irq(struct higmac_netdev_local *priv) 43590+{ 43591+ int i; 43592+ 43593+ for (i = 0; i < priv->num_rxqs; i++) 43594+ enable_irq(priv->irq[i]); 43595+} 43596+ 43597+int higmac_dev_suspend(struct platform_device *pdev, pm_message_t state) 43598+{ 43599+ struct net_device *ndev = platform_get_drvdata(pdev); 43600+ struct higmac_netdev_local *priv = netdev_priv(ndev); 43601+ 43602+ higmac_disable_irq(priv); 43603+ /* 43604+ * If support Wake on LAN, we should not disconnect phy 43605+ * because it will call phy_suspend to power down phy. 43606+ */ 43607+ if (!priv->wol_enable) 43608+ phy_disconnect(priv->phy); 43609+ del_timer_sync(&priv->monitor); 43610+ /* 43611+ * If suspend when netif is not up, the napi_disable will run into 43612+ * dead loop and dpm_drv_timeout will give warning. 43613+ */ 43614+ if (netif_running(ndev)) 43615+ higmac_disable_napi(priv); 43616+ netif_device_detach(ndev); 43617+ 43618+ netif_carrier_off(ndev); 43619+ 43620+ /* 43621+ * If netdev is down, MAC clock is disabled. 43622+ * So if we want to reclaim MAC rx and tx resource, 43623+ * we must first enable MAC clock and then disable it. 43624+ */ 43625+ if (!(ndev->flags & IFF_UP)) 43626+ clk_prepare_enable(priv->clk); 43627+ 43628+ higmac_reclaim_rx_tx_resource(priv); 43629+ 43630+ if (!(ndev->flags & IFF_UP)) 43631+ clk_disable_unprepare(priv->clk); 43632+ 43633+ pmt_enter(priv); 43634+ 43635+ if (!priv->wol_enable) { 43636+ /* 43637+ * if no WOL, then poweroff 43638+ * no need to call genphy_resume() in resume, 43639+ * because we reset everything 43640+ */ 43641+ genphy_suspend(priv->phy); /* power down phy */ 43642+ msleep(20); /* wait 20ms */ 43643+ higmac_hw_all_clk_disable(priv); 43644+ } 43645+ 43646+ return 0; 43647+} 43648+EXPORT_SYMBOL(higmac_dev_suspend); 43649+ 43650+int higmac_dev_resume(struct platform_device *pdev) 43651+{ 43652+ struct net_device *ndev = platform_get_drvdata(pdev); 43653+ struct higmac_netdev_local *priv = netdev_priv(ndev); 43654+ int ret; 43655+ 43656+ /* 43657+ * If we support Wake on LAN, we doesn't call clk_disable. 43658+ * But when we resume, the uboot may off mac clock and reset phy 43659+ * by re-write the mac CRG register. 43660+ * So we first call clk_disable, and then clk_enable. 43661+ */ 43662+ if (priv->wol_enable) 43663+ higmac_hw_all_clk_disable(priv); 43664+ 43665+ higmac_hw_all_clk_enable(priv); 43666+ /* internal FE_PHY: enable clk and reset */ 43667+ higmac_hw_phy_reset(priv); 43668+ 43669+ /* 43670+ * If netdev is down, MAC clock is disabled. 43671+ * So if we want to restart MAC and re-initialize it, 43672+ * we must first enable MAC clock and then disable it. 43673+ */ 43674+ if (!(ndev->flags & IFF_UP)) 43675+ clk_prepare_enable(priv->clk); 43676+ 43677+ /* power on gmac */ 43678+ higmac_restart(priv); 43679+ 43680+ /* 43681+ * If support WoL, we didn't disconnect phy. 43682+ * But when we resume, we reset PHY, so we want to 43683+ * call phy_connect to make phy_fixup excuted. 43684+ * This is important for internal PHY fix. 43685+ */ 43686+ if (priv->wol_enable) 43687+ phy_disconnect(priv->phy); 43688+ 43689+ ret = phy_connect_direct(ndev, priv->phy, higmac_adjust_link, 43690+ priv->phy_mode); 43691+ if (ret) 43692+ return ret; 43693+ 43694+ /* 43695+ * If we suspend and resume when net device is down, 43696+ * some operations are unnecessary. 43697+ */ 43698+ if (ndev->flags & IFF_UP) { 43699+ priv->monitor.expires = jiffies + HIGMAC_MONITOR_TIMER; 43700+ mod_timer(&priv->monitor, priv->monitor.expires); 43701+ priv->old_link = 0; 43702+ priv->old_speed = SPEED_UNKNOWN; 43703+ priv->old_duplex = DUPLEX_UNKNOWN; 43704+ } 43705+ if (netif_running(ndev)) 43706+ higmac_enable_napi(priv); 43707+ netif_device_attach(ndev); 43708+ if (ndev->flags & IFF_UP) 43709+ phy_start(priv->phy); 43710+ higmac_enable_irq(priv); 43711+ 43712+ pmt_exit(priv); 43713+ 43714+ if (!(ndev->flags & IFF_UP)) 43715+ clk_disable_unprepare(priv->clk); 43716+ 43717+ return 0; 43718+} 43719+EXPORT_SYMBOL(higmac_dev_resume); 43720+#else 43721+#define higmac_dev_suspend NULL 43722+#define higmac_dev_resume NULL 43723+#endif 43724+ 43725+static const struct of_device_id higmac_of_match[] = { 43726+ { .compatible = "hisilicon,higmac", }, 43727+ { .compatible = "hisilicon,higmac-v1", }, 43728+ { .compatible = "hisilicon,higmac-v2", }, 43729+ { .compatible = "hisilicon,higmac-v3", }, 43730+ { .compatible = "hisilicon,higmac-v4", }, 43731+ { .compatible = "hisilicon,higmac-v5", }, 43732+ { }, 43733+}; 43734+ 43735+MODULE_DEVICE_TABLE(of, higmac_of_match); 43736+ 43737+static struct platform_driver higmac_dev_driver = { 43738+ .probe = higmac_dev_probe, 43739+ .remove = higmac_dev_remove, 43740+ .suspend = higmac_dev_suspend, 43741+ .resume = higmac_dev_resume, 43742+ .driver = { 43743+ .owner = THIS_MODULE, 43744+ .name = HIGMAC_DRIVER_NAME, 43745+ .of_match_table = higmac_of_match, 43746+ }, 43747+}; 43748+ 43749+#include "proc_dev.c" 43750+ 43751+static int __init higmac_init(void) 43752+{ 43753+ int ret; 43754+ 43755+ ret = platform_driver_register(&higmac_dev_driver); 43756+ if (ret) 43757+ return ret; 43758+ 43759+ higmac_proc_create(); 43760+ 43761+ return 0; 43762+} 43763+ 43764+static void __exit higmac_exit(void) 43765+{ 43766+ platform_driver_unregister(&higmac_dev_driver); 43767+ 43768+ higmac_proc_destroy(); 43769+} 43770+ 43771+module_init(higmac_init); 43772+module_exit(higmac_exit); 43773+ 43774+MODULE_AUTHOR("Hisilicon"); 43775+MODULE_DESCRIPTION("Hisilicon double GMAC driver, base on driver higmacv200"); 43776+MODULE_LICENSE("GPL v2"); 43777diff --git a/drivers/net/ethernet/hisilicon/higmac/higmac.h b/drivers/net/ethernet/hisilicon/higmac/higmac.h 43778new file mode 100644 43779index 000000000..2e26d8064 43780--- /dev/null 43781+++ b/drivers/net/ethernet/hisilicon/higmac/higmac.h 43782@@ -0,0 +1,603 @@ 43783+/* 43784+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 43785+ * Description: Higmac driver main process head file 43786+ * Author: KTP_BSP 43787+ * Create: 2018-10-08 43788+ */ 43789+ 43790+#ifndef __HIGMAC_HIGMAC_H__ 43791+#define __HIGMAC_HIGMAC_H__ 43792+ 43793+#include <linux/kernel.h> 43794+#include <linux/delay.h> 43795+#include <linux/netdevice.h> 43796+#include <linux/list.h> 43797+#include <linux/phy.h> 43798+#include <linux/io.h> 43799+#include <linux/interrupt.h> 43800+ 43801+#define STATION_ADDR_LOW 0x0000 43802+#define STATION_ADDR_HIGH 0x0004 43803+#define MAC_DUPLEX_HALF_CTRL 0x0008 43804+ 43805+#define PORT_MODE 0x0040 43806+ 43807+#define PORT_EN 0x0044 43808+#define BITS_TX_EN BIT(2) 43809+#define BITS_RX_EN BIT(1) 43810+ 43811+#define FC_TX_TIMER 0x001C 43812+ 43813+#define PAUSE_THR 0x0038 43814+ 43815+#define PAUSE_EN 0x0048 43816+#define BIT_RX_FDFC BIT(0) 43817+#define BIT_TX_FDFC BIT(1) 43818+ 43819+#define RX_PAUSE_EN 0x02A4 43820+#define BIT_RX_FQ_PAUSE_EN BIT(0) 43821+#define BIT_RX_BQ_PAUSE_EN BIT(1) 43822+ 43823+#define CRF_TX_PAUSE 0x0340 43824+ 43825+#define BITS_Q_PAUSE_TH_OFFSET 16 43826+#define BITS_Q_PAUSE_TH_MASK 0xFFFF 43827+ 43828+#define REC_FILT_CONTROL 0x0064 43829+#define BIT_CRC_ERR_PASS BIT(5) 43830+#define BIT_PAUSE_FRM_PASS BIT(4) 43831+#define BIT_VLAN_DROP_EN BIT(3) 43832+#define BIT_BC_DROP_EN BIT(2) 43833+#define BIT_MC_MATCH_EN BIT(1) 43834+#define BIT_UC_MATCH_EN BIT(0) 43835+ 43836+#define PORT_MC_ADDR_LOW 0x0068 43837+#define PORT_MC_ADDR_HIGH 0x006C 43838+#define MAC_CLEAR 0x0070 43839+#define BIT_TX_SOFT_RESET BIT(0) 43840+ 43841+#define MODE_CHANGE_EN 0x01b4 43842+#define BIT_MODE_CHANGE_EN BIT(0) 43843+ 43844+#define COL_SLOT_TIME 0x01c0 43845+ 43846+#define CRF_MIN_PACKET 0x0210 43847+#define BIT_OFFSET_TX_MIN_LEN 8 43848+#define BIT_MASK_TX_MIN_LEN GENMASK(13, 8) 43849+ 43850+#define CONTROL_WORD 0x0214 43851+#define CONTROL_WORD_CONFIG 0x640 43852+ 43853+#define TSO_COE_CTRL 0x02e8 43854+#define BIT_COE_IPHDR_DROP BIT(4) 43855+#define BIT_COE_PAYLOAD_DROP BIT(5) 43856+#define BIT_COE_IPV6_UDP_ZERO_DROP BIT(6) 43857+#define COE_ERR_DROP (BIT_COE_IPHDR_DROP | \ 43858+ BIT_COE_PAYLOAD_DROP | \ 43859+ BIT_COE_IPV6_UDP_ZERO_DROP) 43860+ 43861+#define RX_FQ_START_ADDR 0x0500 43862+#define RX_FQ_DEPTH 0x0504 43863+#define REG_BIT_WIDTH 32 43864+#define Q_ADDR_HI8_OFFSET 24 43865+#define Q_ADDR_HI8_MASK (BIT(Q_ADDR_HI8_OFFSET) - 1) 43866+#define TX_DESC_HI8_MASK 0xff 43867+#define SG_DESC_HI8_OFFSET 8 43868+#define RX_FQ_WR_ADDR 0x0508 43869+#define BITS_RX_FQ_WR_ADDR mk_bits(0, 21) 43870+#define RX_FQ_RD_ADDR 0x050c 43871+#define BITS_RX_FQ_RD_ADDR mk_bits(0, 21) 43872+#define RX_FQ_VLDDESC_CNT 0x0510 43873+#define BITS_RX_FQ_VLDDESC_CNT mk_bits(0, 16) 43874+#define RX_FQ_ALEMPTY_TH 0x0514 43875+#define BITS_RX_FQ_ALEMPTY_TH mk_bits(0, 16) 43876+#define RX_FQ_REG_EN 0x0518 43877+#define BITS_RX_FQ_START_ADDR_EN BIT(2) 43878+#define BITS_RX_FQ_DEPTH_EN BIT(1) 43879+#define BITS_RX_FQ_RD_ADDR_EN mk_bits(0, 1) 43880+#define RX_FQ_ALFULL_TH 0x051c 43881+#define BITS_RX_FQ_ALFULL_TH mk_bits(0, 16) 43882+ 43883+#define RX_BQ_START_ADDR 0x0520 43884+#define RX_BQ_DEPTH 0x0524 43885+#define RX_BQ_WR_ADDR 0x0528 43886+#define RX_BQ_RD_ADDR 0x052c 43887+#define RX_BQ_FREE_DESC_CNT 0x0530 43888+#define BITS_RX_BQ_FREE_DESC_CNT mk_bits(0, 16) 43889+#define RX_BQ_ALEMPTY_TH 0x0534 43890+#define BITS_RX_BQ_ALEMPTY_TH mk_bits(0, 16) 43891+#define RX_BQ_REG_EN 0x0538 43892+#define BITS_RX_BQ_START_ADDR_EN BIT(2) 43893+#define BITS_RX_BQ_DEPTH_EN BIT(1) 43894+#define BITS_RX_BQ_WR_ADDR_EN mk_bits(0, 1) 43895+#define RX_BQ_ALFULL_TH 0x053c 43896+#define BITS_RX_BQ_ALFULL_TH mk_bits(0, 16) 43897+ 43898+#define TX_BQ_START_ADDR 0x0580 43899+#define TX_BQ_DEPTH 0x0584 43900+#define TX_BQ_WR_ADDR 0x0588 43901+#define BITS_TX_BQ_WR_ADDR mk_bits(0, 21) 43902+#define TX_BQ_RD_ADDR 0x058c 43903+#define BITS_TX_BQ_RD_ADDR mk_bits(0, 21) 43904+#define TX_BQ_VLDDESC_CNT 0x0590 43905+#define BITS_TX_BQ_VLDDESC_CNT mk_bits(0, 16) 43906+#define TX_BQ_ALEMPTY_TH 0x0594 43907+#define BITS_TX_BQ_ALEMPTY_TH mk_bits(0, 16) 43908+#define TX_BQ_REG_EN 0x0598 43909+#define BITS_TX_BQ_START_ADDR_EN BIT(2) 43910+#define BITS_TX_BQ_DEPTH_EN BIT(1) 43911+#define BITS_TX_BQ_RD_ADDR_EN mk_bits(0, 1) 43912+#define TX_BQ_ALFULL_TH 0x059c 43913+#define BITS_TX_BQ_ALFULL_TH mk_bits(0, 16) 43914+ 43915+#define TX_RQ_START_ADDR 0x05a0 43916+#define TX_RQ_DEPTH 0x05a4 43917+#define TX_RQ_WR_ADDR 0x05a8 43918+#define BITS_TX_RQ_WR_ADDR mk_bits(0, 21) 43919+#define TX_RQ_RD_ADDR 0x05ac 43920+#define BITS_TX_RQ_RD_ADDR mk_bits(0, 21) 43921+#define TX_RQ_FREE_DESC_CNT 0x05b0 43922+#define BITS_TX_RQ_FREE_DESC_CNT mk_bits(0, 16) 43923+#define TX_RQ_ALEMPTY_TH 0x05b4 43924+#define BITS_TX_RQ_ALEMPTY_TH mk_bits(0, 16) 43925+#define TX_RQ_REG_EN 0x05b8 43926+#define BITS_TX_RQ_START_ADDR_EN BIT(2) 43927+#define BITS_TX_RQ_DEPTH_EN BIT(1) 43928+#define BITS_TX_RQ_WR_ADDR_EN mk_bits(0, 1) 43929+#define TX_RQ_ALFULL_TH 0x05bc 43930+#define BITS_TX_RQ_ALFULL_TH mk_bits(0, 16) 43931+ 43932+#define RAW_PMU_INT 0x05c0 43933+#define ENA_PMU_INT 0x05c4 43934+ 43935+#define DESC_WR_RD_ENA 0x05CC 43936+ 43937+#define IN_QUEUE_TH 0x05d8 43938+#define BITS_OFFSET_TX_RQ_IN_TH 16 43939+ 43940+#define RX_BQ_IN_TIMEOUT_TH 0x05E0 43941+ 43942+#define TX_RQ_IN_TIMEOUT_TH 0x05e4 43943+ 43944+#define STOP_CMD 0x05e8 43945+#define BITS_TX_STOP_EN BIT(1) 43946+#define BITS_RX_STOP_EN BIT(0) 43947+#define STOP_RX_TX (BITS_TX_STOP_EN | BITS_RX_STOP_EN) 43948+ 43949+#define RSS_IND_TBL 0x0c0c 43950+#define BIT_IND_TBL_READY BIT(13) 43951+#define BIT_IND_TLB_WR BIT(12) 43952+#define RSS_RAW_PMU_INT 0x0c10 43953+#define RSS_QUEUE1_START_ADDR 0x0c20 43954+#define rx_bq_start_addr_queue(i) (RSS_QUEUE1_START_ADDR + \ 43955+ ((i) - 1) * 0x10) 43956+#define RSS_QUEUE1_DEPTH 0x0c24 43957+#define RX_BQ_WR_ADDR_QUEUE1 0x0c28 43958+#define RX_BQ_RD_ADDR_QUEUE1 0x0c2c 43959+#define RSS_QUEUE1_ENA_INT 0x0c90 43960+#define rss_ena_int_queue(i) (RSS_QUEUE1_ENA_INT + ((i) - 1) * 0x4) 43961+#define rx_bq_depth_queue(i) (RSS_QUEUE1_DEPTH + ((i) - 1) * 0x10) 43962+#define rx_bq_wr_addr_queue(i) ((i) ? (RX_BQ_WR_ADDR_QUEUE1 + \ 43963+ ((i) - 1) * 0x10) : RX_BQ_WR_ADDR) 43964+#define rx_bq_rd_addr_queue(i) ((i) ? (RX_BQ_RD_ADDR_QUEUE1 + \ 43965+ ((i) - 1) * 0x10) : RX_BQ_RD_ADDR) 43966+ 43967+#define def_int_mask_queue(i) (0x3 << (2 * ((i) - 1))) 43968+ 43969+/* AXI burst and outstanding config */ 43970+#define BURST_OUTSTANDING_REG 0x3014 43971+#define BURST4_OUTSTANDING1 0x81ff 43972+#define BURST_OUTSTANDING_OFFSET 16 43973+ 43974+#define GMAC_SPEED_1000 0x05 43975+#define GMAC_SPEED_100 0x01 43976+#define GMAC_SPEED_10 0x00 43977+ 43978+#define IPV4_HEAD_LENGTH 0x5 43979+ 43980+enum higmac_tx_err { 43981+ ERR_NONE = 0, 43982+ ERR_DESC_CFG = (1 << 0), 43983+ ERR_DATA_LEN = (1 << 1), 43984+ ERR_DESC_NFRAG_NUM = (1 << 2), /* bit2 */ 43985+ ERR_DESC_IP_HDR_LEN = (1 << 3), /* bit3 */ 43986+ ERR_DESC_PROT_HDR_LEN = (1 << 4), /* bit4 */ 43987+ ERR_DESC_MTU = (1 << 5), /* bit5 */ 43988+ ERR_LINK_SGPKT_LEN = (1 << 8), /* bit8 */ 43989+ ERR_LINK_TSOPKT_LINEAR = (1 << 9), /* bit9 */ 43990+ ERR_LINK_NFRAG_LEN = (1 << 10), /* bit10 */ 43991+ ERR_LINK_TOTAL_LEN = (1 << 11), /* bit11 */ 43992+ ERR_HDR_TCP_BCMC = (1 << 12), /* bit12 */ 43993+ ERR_HDR_UDP_BC = (1 << 13), /* bit13 */ 43994+ ERR_HDR_VLAN_IP_TYPE = (1 << 14), /* bit14 */ 43995+ ERR_HDR_IP_TYPE = (1 << 15), /* bit15 */ 43996+ ERR_HDR_IP_VERSION = (1 << 16), /* bit16 */ 43997+ ERR_HDR_IP_HDR_LEN = (1 << 17), /* bit17 */ 43998+ ERR_HDR_IP_TOTAL_LEN = (1 << 18), /* bit18 */ 43999+ ERR_HDR_IPV6_TTL_PROT = (1 << 19), /* bit19 */ 44000+ ERR_HDR_IPV4_OFFSET = (1 << 20), /* bit20 */ 44001+ ERR_HDR_IPV4_TTL_PROT = (1 << 21), /* bit21 */ 44002+ ERR_HDR_UDP_LEN = (1 << 22), /* bit22 */ 44003+ ERR_HDR_TCP_LEN = (1 << 23), /* bit23 */ 44004+ ERR_DESC = (ERR_DESC_CFG | ERR_DATA_LEN | 44005+ ERR_DESC_NFRAG_NUM | ERR_DESC_IP_HDR_LEN | 44006+ ERR_DESC_PROT_HDR_LEN | ERR_DESC_MTU), 44007+ ERR_LINK = (ERR_LINK_SGPKT_LEN | ERR_LINK_TSOPKT_LINEAR | 44008+ ERR_LINK_NFRAG_LEN | ERR_LINK_TOTAL_LEN), 44009+ ERR_HDR = (ERR_HDR_TCP_BCMC | ERR_HDR_UDP_BC | 44010+ ERR_HDR_VLAN_IP_TYPE | ERR_HDR_IP_TYPE | 44011+ ERR_HDR_IP_VERSION | ERR_HDR_IP_HDR_LEN | 44012+ ERR_HDR_IP_TOTAL_LEN | ERR_HDR_IPV6_TTL_PROT | 44013+ ERR_HDR_IPV4_OFFSET | ERR_HDR_IPV4_TTL_PROT | 44014+ ERR_HDR_UDP_LEN | ERR_HDR_TCP_LEN), 44015+ ERR_ALL = (ERR_DESC | ERR_LINK | ERR_HDR), 44016+}; 44017+ 44018+#define HIGMAC_DRIVER_NAME "hi_gmac_v200" 44019+ 44020+#define HIGMAC_MAC_CLK_NAME "higmac_clk" 44021+#define HIGMAC_MACIF_CLK_NAME "macif_clk" 44022+ 44023+#define HIGMAC_PORT_RST_NAME "port_reset" 44024+#define HIGMAC_MACIF_RST_NAME "macif_reset" 44025+#define HIGMAC_PHY_RST_NAME "phy_reset" 44026+ 44027+#define HIGMAC_TSO_DEBUG 44028+ 44029+#include "tso.h" 44030+ 44031+#if defined(CONFIG_ARCH_HI3519) || defined(CONFIG_ARCH_HI3519V101) || \ 44032+ defined(CONFIG_ARCH_HI3516AV200) 44033+#ifdef readl 44034+#undef readl 44035+#undef readl_relaxed 44036+#undef writel 44037+#undef writel_relaxed 44038+#define readl hi_readl 44039+#define readl_relaxed hi_readl_relaxed 44040+#define writel hi_writel 44041+#define writel_relaxed hi_writel_relaxed 44042+#endif /* readl */ 44043+#endif /* defined(CONFIG_ARCH_HI3519) || defined(CONFIG_HI3519V101) */ 44044+ 44045+#define HIGMAC_IOSIZE 0x1000 44046+#define HIGMAC_OFFSET (HIGMAC_IOSIZE) 44047+ 44048+#define RX_BQ_IN_INT BIT(17) 44049+#define TX_RQ_IN_INT BIT(19) 44050+#define RX_BQ_IN_TIMEOUT_INT BIT(28) 44051+#define TX_RQ_IN_TIMEOUT_INT BIT(29) 44052+ 44053+#define DEF_INT_MASK (RX_BQ_IN_INT | RX_BQ_IN_TIMEOUT_INT | \ 44054+ TX_RQ_IN_INT | TX_RQ_IN_TIMEOUT_INT) 44055+ 44056+/* write or read descriptor need memory barrier */ 44057+#define higmac_sync_barrier() do { isb(); smp_mb(); } while (0) 44058+ 44059+#define HISILICON_PHY_ID_FESTAV200 0x20669823 44060+#define PHY_ID_KSZ8051MNL 0x00221550 44061+#define PHY_ID_KSZ8081RNB 0x00221560 44062+#define PHY_ID_UNKNOWN 0x00221513 44063+#define DEFAULT_PHY_MASK 0xfffffff0 44064+#define REALTEK_PHY_ID_8211E 0x001cc915 44065+#define REALTEK_PHY_MASK 0x001fffff 44066+ 44067+enum { 44068+ GMAC_PORT0, 44069+ GMAC_PORT1, 44070+ GMAC_MAX_PORT, 44071+}; 44072+ 44073+enum { 44074+ MEM_GMAC_IOBASE, 44075+ MEM_MACIF_IOBASE, 44076+ MEM_AXI_BUS_CFG_IOBASE, 44077+ MEM_FWD_IOBASE, 44078+ MEM_CTRL_IOBASE, 44079+}; 44080+ 44081+#define HIGMAC_LINKED BIT(0) 44082+#define HIGMAC_DUP_FULL BIT(1) 44083+#define HIGMAC_SPD_10M BIT(2) 44084+#define HIGMAC_SPD_100M BIT(3) 44085+#define HIGMAC_SPD_1000M BIT(4) 44086+/* Flow Control defines */ 44087+#define FLOW_OFF 0 44088+#define FLOW_RX 1 44089+#define FLOW_TX 2 44090+#define FLOW_AUTO (FLOW_TX | FLOW_RX) 44091+ 44092+#define RX_BQ_INT_THRESHOLD 0x40 44093+#define TX_RQ_INT_THRESHOLD 0x20 44094+ 44095+#define HIGMAC_MONITOR_TIMER (msecs_to_jiffies(200)) 44096+ 44097+#define HIETH_MAX_FRAME_SIZE (1600 + 128) 44098+#define SKB_SIZE (HIETH_MAX_FRAME_SIZE) 44099+ 44100+#define DESC_VLD_FREE 0 44101+#define DESC_VLD_BUSY 1 44102+ 44103+#define DESC_FL_FIRST 2 44104+#define DESC_FL_MID 0 44105+#define DESC_FL_LAST 1 44106+#define DESC_FL_FULL 3 44107+ 44108+#if defined(CONFIG_HIGMAC_DESC_4WORD) 44109+#define DESC_WORD_SHIFT 2 44110+#else 44111+#define DESC_WORD_SHIFT 3 44112+#endif 44113+#define DESC_BYTE_SHIFT (DESC_WORD_SHIFT + 2) 44114+#define DESC_WORD_CNT (1 << DESC_WORD_SHIFT) 44115+#define DESC_SIZE (1 << DESC_BYTE_SHIFT) 44116+ 44117+#define RX_DESC_NUM 1024 44118+#define TX_DESC_NUM 1024 44119+ 44120+/* DMA descriptor ring helpers */ 44121+#define dma_ring_incr(n, s) (((n) + 1) & ((s) - 1)) 44122+#define dma_cnt(n) ((n) >> DESC_BYTE_SHIFT) 44123+#define dma_byte(n) ((n) << DESC_BYTE_SHIFT) 44124+ 44125+#define RSS_HASH_KEY_SIZE 4 44126+#define RSS_INDIRECTION_TABLE_SIZE 128 44127+#define RSS_NUM_RXQS 4 44128+ 44129+#define HW_CAP_TSO BIT(0) 44130+#define HW_CAP_RXCSUM BIT(1) 44131+#define HW_CAP_CCI BIT(2) 44132+#define has_cap_tso(hw_cap) ((hw_cap) & HW_CAP_TSO) 44133+#define has_cap_rxcsum(hw_cap) ((hw_cap) & HW_CAP_RXCSUM) 44134+#define has_cap_cci(hw_cap) ((hw_cap) & HW_CAP_CCI) 44135+ 44136+#if defined(CONFIG_HIGMAC_DESC_4WORD) 44137+struct higmac_desc { 44138+ unsigned int data_buff_addr; 44139+ 44140+ unsigned int buffer_len : 11; 44141+#if defined(CONFIG_HIGMAC_RXCSUM) 44142+ unsigned int reserve2 : 1; 44143+ unsigned int payload_csum_err : 1; 44144+ unsigned int header_csum_err : 1; 44145+ unsigned int payload_csum_done : 1; 44146+ unsigned int header_csum_done : 1; 44147+#else 44148+ unsigned int reserve2 : 5; 44149+#endif 44150+ unsigned int data_len : 11; 44151+ unsigned int reserve1 : 2; 44152+ unsigned int fl : 2; 44153+ unsigned int descvid : 1; 44154+ 44155+ unsigned int rxhash; 44156+ unsigned int reserve3 : 8; 44157+ unsigned int l3_hash : 1; 44158+ unsigned int has_hash : 1; 44159+ unsigned int skb_id : 14; 44160+ unsigned int reserve31 : 8; 44161+}; 44162+ 44163+struct higmac_tso_desc { 44164+ unsigned int data_buff_addr; 44165+ union { 44166+ struct { 44167+ unsigned int prot_hdr_len : 4; 44168+ unsigned int ip_hdr_len : 4; 44169+ unsigned int prot_type : 1; 44170+ unsigned int ip_ver : 1; 44171+ unsigned int vlan_flag : 1; 44172+ unsigned int nfrags_num : 5; 44173+ unsigned int data_len : 11; 44174+ unsigned int reservel : 1; 44175+ unsigned int tso_flag : 1; 44176+ unsigned int coe_flag : 1; 44177+ unsigned int sg_flag : 1; 44178+ unsigned int hw_own : 1; 44179+ } tx; 44180+ unsigned int val; 44181+ } desc1; 44182+ unsigned int reserve_desc2; 44183+ unsigned int tx_err; 44184+}; 44185+#else 44186+struct higmac_desc { 44187+ unsigned int data_buff_addr; 44188+ 44189+ unsigned int buffer_len : 11; 44190+#if defined(CONFIG_HIGMAC_RXCSUM) 44191+ unsigned int reserve2 : 1; 44192+ unsigned int payload_csum_err : 1; 44193+ unsigned int header_csum_err : 1; 44194+ unsigned int payload_csum_done : 1; 44195+#else 44196+ unsigned int reserve2 : 5; 44197+#endif 44198+ unsigned int data_len : 11; 44199+ unsigned int reserve1 : 2; 44200+ unsigned int fl : 2; 44201+ unsigned int descvid : 1; 44202+ 44203+ unsigned int rxhash; 44204+ unsigned int reserve3 : 8; 44205+ unsigned int l3_hash : 1; 44206+ unsigned int has_hash : 1; 44207+ unsigned int skb_id : 14; 44208+ unsigned int reserve31 : 8; 44209+ 44210+ unsigned int reserve4; 44211+ unsigned int reserve5; 44212+ unsigned int reserve6; 44213+ unsigned int reserve7; 44214+}; 44215+ 44216+struct higmac_tso_desc { 44217+ unsigned int data_buff_addr; 44218+ union { 44219+ struct { 44220+ unsigned int prot_hdr_len : 4; 44221+ unsigned int ip_hdr_len : 4; 44222+ unsigned int prot_type : 1; 44223+ unsigned int ip_ver : 1; 44224+ unsigned int vlan_flag : 1; 44225+ unsigned int nfrags_num : 5; 44226+ unsigned int data_len : 11; 44227+ unsigned int reservel : 1; 44228+ unsigned int tso_flag : 1; 44229+ unsigned int coe_flag : 1; 44230+ unsigned int sg_flag : 1; 44231+ unsigned int hw_own : 1; 44232+ } tx; 44233+ unsigned int val; 44234+ } desc1; 44235+ unsigned int reserve_desc2; 44236+ unsigned int reserve3; 44237+ 44238+ unsigned int tx_err; 44239+ unsigned int reserve5; 44240+ unsigned int reserve6; 44241+ unsigned int reserve7; 44242+}; 44243+#endif 44244+ 44245+#define SKB_MAGIC ((struct sk_buff *)0x5a) 44246+ 44247+struct higmac_napi { 44248+ struct napi_struct napi; 44249+ struct higmac_netdev_local *ndev_priv; 44250+ int rxq_id; 44251+}; 44252+ 44253+struct higmac_rss_info { 44254+ u32 hash_cfg; 44255+ u32 ind_tbl_size; 44256+ u8 ind_tbl[RSS_INDIRECTION_TABLE_SIZE]; 44257+ u8 key[RSS_HASH_KEY_SIZE]; 44258+}; 44259+ 44260+#define QUEUE_NUMS 4 44261+#define BASE_QUEUE_NUMS 3 44262+ 44263+struct higmac_netdev_local { 44264+#define HIGMAC_SG_DESC_ADD 64U 44265+ struct sg_desc *dma_sg_desc ____cacheline_aligned; 44266+ dma_addr_t dma_sg_phy; 44267+ unsigned int sg_head; 44268+ unsigned int sg_tail; 44269+ unsigned int sg_count; 44270+ 44271+ void __iomem *gmac_iobase; 44272+ void __iomem *macif_base; 44273+ void __iomem *axi_bus_cfg_base; 44274+ int index; /* 0 -- mac0, 1 -- mac1 */ 44275+ 44276+ u32 hw_cap; 44277+ bool tso_supported; 44278+ bool has_rxhash_cap; 44279+ bool has_rss_cap; 44280+ int num_rxqs; 44281+ struct higmac_napi q_napi[RSS_NUM_RXQS]; 44282+ int irq[RSS_NUM_RXQS]; 44283+ struct higmac_rss_info rss_info; 44284+ 44285+ struct reset_control *port_rst; 44286+ struct reset_control *macif_rst; 44287+ struct reset_control *phy_rst; 44288+ 44289+ struct { 44290+ struct higmac_desc *desc; 44291+ dma_addr_t phys_addr; 44292+ int *sg_desc_offset; 44293+ /* how many desc in the desc pool */ 44294+ unsigned int count; 44295+ struct sk_buff **skb; 44296+ unsigned int size; 44297+ } pool[QUEUE_NUMS + RSS_NUM_RXQS - 1]; 44298+#define RX_FQ pool[0] 44299+#define RX_BQ pool[1] 44300+#define TX_BQ pool[2] 44301+#define TX_RQ pool[3] 44302+ 44303+ struct sk_buff **tx_skb; 44304+ struct sk_buff **rx_skb; 44305+ 44306+ struct device *dev; 44307+ struct net_device *netdev; 44308+ struct clk *clk; 44309+ struct clk *macif_clk; 44310+ 44311+ struct higmac_adapter *adapter; 44312+ 44313+ struct timer_list monitor; 44314+ 44315+ char phy_name[MII_BUS_ID_SIZE]; 44316+ struct phy_device *phy; 44317+ struct device_node *phy_node; 44318+ phy_interface_t phy_mode; 44319+ bool autoeee; 44320+ bool internal_phy; 44321+ int (*eee_init)(struct phy_device *phy_dev); 44322+ 44323+ unsigned int flow_ctrl; 44324+ unsigned int pause; 44325+ unsigned int pause_interval; 44326+ unsigned int flow_ctrl_active_threshold; 44327+ unsigned int flow_ctrl_deactive_threshold; 44328+ 44329+ int old_link; 44330+ int old_speed; 44331+ int old_duplex; 44332+ 44333+ /* receive packet lock */ 44334+ spinlock_t rxlock; 44335+ /* transmit packet lock */ 44336+ spinlock_t txlock; 44337+ /* power management lock */ 44338+ spinlock_t pmtlock; 44339+ 44340+ int dev_state; /* INIT/OPEN/CLOSE */ 44341+ char pm_state; 44342+ bool wol_enable; 44343+ u32 msg_enable; 44344+#define INIT 0 /* init gmac */ 44345+#define OPEN 1 /* power on gmac */ 44346+#define CLOSE 2 /* power off gmac */ 44347+}; 44348+ 44349+enum tso_version { 44350+ VER_NO_TSO = 0x0, 44351+ VER_BYTE_SPLICE = 0x1, 44352+ VER_SG_COE = 0x2, 44353+ VER_TSO = 0x3, 44354+}; 44355+ 44356+#ifdef HIGMAC_TSO_DEBUG 44357+#define MAX_RECORD 100 44358+struct send_pkt_info { 44359+ struct higmac_tso_desc desc; 44360+ int status; 44361+}; 44362+#endif 44363+ 44364+struct cyclic_queue_info { 44365+ u32 start; 44366+ u32 end; 44367+ u32 num; 44368+ u32 pos; 44369+}; 44370+ 44371+int higmac_tx_avail(struct higmac_netdev_local const *ld); 44372+ 44373+/* board related func */ 44374+void higmac_mac_core_reset(struct higmac_netdev_local *priv); 44375+void higmac_hw_internal_phy_reset(struct higmac_netdev_local *priv); 44376+void higmac_hw_external_phy_reset(struct higmac_netdev_local *priv); 44377+void higmac_internal_phy_clk_disable(struct higmac_netdev_local const *priv); 44378+void higmac_internal_phy_clk_enable(struct higmac_netdev_local const *priv); 44379+void higmac_hw_all_clk_disable(struct higmac_netdev_local *priv); 44380+void higmac_hw_all_clk_enable(struct higmac_netdev_local *priv); 44381+ 44382+/* board independent func */ 44383+void higmac_hw_phy_reset(struct higmac_netdev_local *priv); 44384+ 44385+#endif 44386diff --git a/drivers/net/ethernet/hisilicon/higmac/pm.c b/drivers/net/ethernet/hisilicon/higmac/pm.c 44387new file mode 100644 44388index 000000000..4ad8e7c0c 44389--- /dev/null 44390+++ b/drivers/net/ethernet/hisilicon/higmac/pm.c 44391@@ -0,0 +1,341 @@ 44392+/* 44393+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 44394+ * Description: Higmac driver pm process 44395+ * Author: KTP_BSP 44396+ * Create: 2018-10-08 44397+ */ 44398+ 44399+#include <linux/crc16.h> 44400+#include "pm.h" 44401+ 44402+struct pm_reg_config pm_reg_config_backup; 44403+ 44404+static void init_crc_table(void); 44405+static unsigned short compute_crc(const char *message, int nbytes); 44406+static unsigned short calculate_crc16(const char *buf, unsigned int mask) 44407+{ 44408+ char data[N]; 44409+ int i; 44410+ int len = 0; 44411+ 44412+ memset(data, 0, sizeof(data)); 44413+ 44414+ for (i = 0; i < N; i++) { 44415+ if (mask & 0x1) 44416+ data[len++] = buf[i]; 44417+ 44418+ mask >>= 1; 44419+ } 44420+ 44421+ return compute_crc(data, len); 44422+} 44423+ 44424+/* use this func in config pm func */ 44425+void _pmt_reg_backup(struct higmac_netdev_local const *ld) 44426+{ 44427+ if (ld == NULL) 44428+ return; 44429+ pm_reg_config_backup.pmt_ctrl = readl(ld->gmac_iobase + PMT_CTRL); 44430+ pm_reg_config_backup.pmt_mask0 = readl(ld->gmac_iobase + PMT_MASK0); 44431+ pm_reg_config_backup.pmt_mask1 = readl(ld->gmac_iobase + PMT_MASK1); 44432+ pm_reg_config_backup.pmt_mask2 = readl(ld->gmac_iobase + PMT_MASK2); 44433+ pm_reg_config_backup.pmt_mask3 = readl(ld->gmac_iobase + PMT_MASK3); 44434+ pm_reg_config_backup.pmt_cmd = readl(ld->gmac_iobase + PMT_CMD); 44435+ pm_reg_config_backup.pmt_offset = readl(ld->gmac_iobase + PMT_OFFSET); 44436+ pm_reg_config_backup.pmt_crc1_0 = readl(ld->gmac_iobase + PMT_CRC1_0); 44437+ pm_reg_config_backup.pmt_crc3_2 = readl(ld->gmac_iobase + PMT_CRC3_2); 44438+} 44439+ 44440+#define PM_SET 1 44441+#define PM_CLEAR 0 44442+ 44443+static void pmt_config_filter(struct pm_config const *config, 44444+ struct higmac_netdev_local const *ld) 44445+{ 44446+ unsigned int v; 44447+ unsigned int cmd = 0; 44448+ unsigned int offset = 0; 44449+ unsigned short crc[FILTERS] = { 0 }; 44450+ int reg_mask; 44451+ unsigned int i; 44452+ 44453+ /* 44454+ * filter.valid mask.valid mask_bytes effect 44455+ * 0 * * no use the filter 44456+ * 1 0 * all pkts can wake-up(non-exist) 44457+ * 1 1 0 all pkts can wake-up 44458+ * 1 1 !0 normal filter 44459+ */ 44460+ /* setup filter */ 44461+ for (i = 0; i < FILTERS; i++) { 44462+ if (config->filter[i].valid) { 44463+ if (config->filter[i].offset < PM_FILTER_OFFSET_MIN) 44464+ continue; 44465+ /* high 8 bits offset and low 8 bits valid bit */ 44466+ offset |= config->filter[i].offset << (i * 8); 44467+ cmd |= BIT(i * 8); /* valid bit8 */ 44468+ /* mask offset 4i */ 44469+ reg_mask = PMT_MASK0 + (i * 4); 44470+ 44471+ /* 44472+ * for logic, mask valid bit(bit31) must set to 0, 44473+ * 0 is enable 44474+ */ 44475+ v = config->filter[i].mask_bytes; 44476+ v &= ~BIT(31); /* bit31 */ 44477+ writel(v, ld->gmac_iobase + reg_mask); 44478+ 44479+ /* crc */ 44480+ crc[i] = calculate_crc16(config->filter[i].value, v); 44481+ if (i <= 1) { /* for filter0 and filter 1 */ 44482+ v = readl(ld->gmac_iobase + PMT_CRC1_0); 44483+ v &= ~(0xFFFF << (16 * i)); /* 16 bits mask */ 44484+ v |= crc[i] << (16 * i); /* 16 bits mask */ 44485+ writel(v, ld->gmac_iobase + PMT_CRC1_0); 44486+ } else { /* filter2 and filter3 */ 44487+ v = readl(ld->gmac_iobase + PMT_CRC3_2); 44488+ v &= ~(0xFFFF << (16 * (i - 2))); /* filer 2 3, 16 bits mask */ 44489+ v |= crc[i] << (16 * (i - 2)); /* filer 2 3, 16 bits mask */ 44490+ writel(v, ld->gmac_iobase + PMT_CRC3_2); 44491+ } 44492+ } 44493+ } 44494+ 44495+ if (cmd) { 44496+ writel(offset, ld->gmac_iobase + PMT_OFFSET); 44497+ writel(cmd, ld->gmac_iobase + PMT_CMD); 44498+ } 44499+} 44500+ 44501+int pmt_config_gmac(struct pm_config const *config, struct higmac_netdev_local *ld) 44502+{ 44503+ unsigned int v; 44504+ unsigned long flags; 44505+ 44506+ if (ld == NULL || config == NULL) 44507+ return -EINVAL; 44508+ 44509+ spin_lock_irqsave(&ld->pmtlock, flags); 44510+ if (config->wakeup_pkts_enable) { 44511+ /* disable wakeup_pkts_enable before reconfig? */ 44512+ v = readl(ld->gmac_iobase + PMT_CTRL); 44513+ v &= ~BIT(2); /* bit2 */ 44514+ writel(v, ld->gmac_iobase + PMT_CTRL); /* any side effect? */ 44515+ } else { 44516+ goto config_ctrl; 44517+ } 44518+ 44519+ pmt_config_filter(config, ld); 44520+ 44521+config_ctrl: 44522+ v = 0; 44523+ if (config->uc_pkts_enable) 44524+ v |= BIT(9); /* bit9 uc pkts wakeup */ 44525+ if (config->wakeup_pkts_enable) 44526+ v |= BIT(2); /* bit2 use filter framework */ 44527+ if (config->magic_pkts_enable) 44528+ v |= BIT(1); /* magic pkts wakeup */ 44529+ 44530+ v |= 0x3 << 5; /* set bit5 bit6, clear irq status */ 44531+ writel(v, ld->gmac_iobase + PMT_CTRL); 44532+ 44533+ _pmt_reg_backup(ld); 44534+ 44535+ spin_unlock_irqrestore(&ld->pmtlock, flags); 44536+ 44537+ return 0; 44538+} 44539+ 44540+/* pmt_config will overwrite pre-config */ 44541+int pmt_config(struct net_device const *ndev, struct pm_config const *config) 44542+{ 44543+ static int init; 44544+ int ret; 44545+ struct higmac_netdev_local *priv = netdev_priv(ndev); 44546+ 44547+ if (!init) 44548+ init_crc_table(); 44549+ 44550+ ret = pmt_config_gmac(config, priv); 44551+ if (ret) 44552+ return ret; 44553+ 44554+ priv->pm_state = PM_SET; 44555+ priv->wol_enable = true; 44556+ device_set_wakeup_enable(priv->dev, 1); 44557+ 44558+ return 0; 44559+} 44560+ 44561+bool pmt_enter(struct higmac_netdev_local *ld) 44562+{ 44563+ int pm = false; 44564+ unsigned long flags; 44565+ if (ld == NULL) 44566+ return -EINVAL; 44567+ spin_lock_irqsave(&ld->pmtlock, flags); 44568+ if (ld->pm_state == PM_SET) { 44569+ unsigned int v; 44570+ 44571+ v = readl(ld->gmac_iobase + PMT_CTRL); 44572+ v |= BIT(0); /* enter power down */ 44573+ v |= BIT(3); /* bit3, enable wakeup irq */ 44574+ v |= 0x3 << 5; /* set bit5 bit6, clear irq status */ 44575+ writel(v, ld->gmac_iobase + PMT_CTRL); 44576+ 44577+ ld->pm_state = PM_CLEAR; 44578+ pm = true; 44579+ } 44580+ spin_unlock_irqrestore(&ld->pmtlock, flags); 44581+ return pm; 44582+} 44583+ 44584+void pmt_exit(struct higmac_netdev_local *ld) 44585+{ 44586+ unsigned int v; 44587+ unsigned long flags; 44588+ if (ld == NULL) 44589+ return; 44590+ /* logic auto exit power down mode */ 44591+ spin_lock_irqsave(&ld->pmtlock, flags); 44592+ 44593+ v = readl(ld->gmac_iobase + PMT_CTRL); 44594+ v &= ~BIT(0); /* enter power down */ 44595+ v &= ~BIT(3); /* bit3, enable wakeup irq */ 44596+ 44597+ v |= 0x3 << 5; /* set bit5 bit6, clear irq status */ 44598+ writel(v, ld->gmac_iobase + PMT_CTRL); 44599+ 44600+ spin_unlock_irqrestore(&ld->pmtlock, flags); 44601+ 44602+ ld->wol_enable = false; 44603+} 44604+ 44605+void pmt_reg_restore(struct higmac_netdev_local *ld) 44606+{ 44607+ unsigned int v; 44608+ unsigned long flags; 44609+ if (ld == NULL) 44610+ return; 44611+ spin_lock_irqsave(&ld->pmtlock, flags); 44612+ v = pm_reg_config_backup.pmt_mask0; 44613+ writel(v, ld->gmac_iobase + PMT_MASK0); 44614+ 44615+ v = pm_reg_config_backup.pmt_mask1; 44616+ writel(v, ld->gmac_iobase + PMT_MASK1); 44617+ 44618+ v = pm_reg_config_backup.pmt_mask2; 44619+ writel(v, ld->gmac_iobase + PMT_MASK2); 44620+ 44621+ v = pm_reg_config_backup.pmt_mask3; 44622+ writel(v, ld->gmac_iobase + PMT_MASK3); 44623+ 44624+ v = pm_reg_config_backup.pmt_cmd; 44625+ writel(v, ld->gmac_iobase + PMT_CMD); 44626+ 44627+ v = pm_reg_config_backup.pmt_offset; 44628+ writel(v, ld->gmac_iobase + PMT_OFFSET); 44629+ 44630+ v = pm_reg_config_backup.pmt_crc1_0; 44631+ writel(v, ld->gmac_iobase + PMT_CRC1_0); 44632+ 44633+ v = pm_reg_config_backup.pmt_crc3_2; 44634+ writel(v, ld->gmac_iobase + PMT_CRC3_2); 44635+ 44636+ v = pm_reg_config_backup.pmt_ctrl; 44637+ writel(v, ld->gmac_iobase + PMT_CTRL); 44638+ spin_unlock_irqrestore(&ld->pmtlock, flags); 44639+} 44640+ 44641+/* ========the following code copy from Synopsys DWC_gmac_crc_example.c====== */ 44642+#define CRC16 /* Change it to CRC16 for CRC16 Computation */ 44643+ 44644+#if defined(CRC16) 44645+#define CRC_NAME "CRC-16" 44646+#define POLYNOMIAL 0x8005 44647+#define INITIAL_REMAINDER 0xFFFF 44648+#define FINAL_XOR_VALUE 0x0000 44649+#define REVERSE_DATA 44650+#undef REVERSE_REMAINDER 44651+#endif 44652+ 44653+#define WIDTH (8 * sizeof(unsigned short)) 44654+#define TOPBIT BIT(WIDTH - 1) 44655+ 44656+#ifdef REVERSE_DATA 44657+#undef REVERSE_DATA 44658+#define reverse_data(X) ((unsigned char)reverse((X), 8)) 44659+#else 44660+#undef REVERSE_DATA 44661+#define reverse_data(X) (X) 44662+#endif 44663+ 44664+#ifdef REVERSE_REMAINDER 44665+#undef REVERSE_REMAINDER 44666+#define reverse_remainder(X) ((unsigned short)reverse((X), WIDTH)) 44667+#else 44668+#undef REVERSE_REMAINDER 44669+#define reverse_remainder(X) (X) 44670+#endif 44671+ 44672+#define CRC_TABLE_LEN 256 44673+static unsigned short crc_table[CRC_TABLE_LEN]; 44674+ 44675+static unsigned int reverse(unsigned int data, unsigned char nbits) 44676+{ 44677+ unsigned int reversed = 0x00000000; 44678+ unsigned char bit; 44679+ 44680+ /* Reverse the data about the center bit. */ 44681+ for (bit = 0; bit < nbits; ++bit) { 44682+ /* If the LSB bit is set, set the reflection of it. */ 44683+ if (data & 0x01) 44684+ reversed |= BIT((nbits - 1) - bit); 44685+ 44686+ data = (data >> 1); 44687+ } 44688+ return reversed; 44689+} 44690+ 44691+/* This Initializes the partial CRC look up table */ 44692+static void init_crc_table(void) 44693+{ 44694+ unsigned short remainder; 44695+ unsigned int dividend; 44696+ unsigned char bit; 44697+ 44698+ /* Compute the remainder of each possible dividend. */ 44699+ for (dividend = 0; dividend < CRC_TABLE_LEN; ++dividend) { 44700+ /* Start with the dividend followed by zeros, WIDTH - 8. */ 44701+ remainder = (unsigned short)(dividend << (WIDTH - 8)); 44702+ 44703+ /* Perform modulo-2 division, a bit at a time for 8 times. */ 44704+ for (bit = 8; bit > 0; --bit) { 44705+ /* Try to divide the current data bit. */ 44706+ if (remainder & TOPBIT) 44707+ remainder = (remainder << 1) ^ POLYNOMIAL; 44708+ else 44709+ remainder = (remainder << 1); 44710+ } 44711+ 44712+ /* Store the result into the table. */ 44713+ crc_table[dividend] = remainder; 44714+ } 44715+} 44716+ 44717+static unsigned short compute_crc(const char *message, int nbytes) 44718+{ 44719+ unsigned short remainder = INITIAL_REMAINDER; 44720+ int byte; 44721+ unsigned char data; 44722+ 44723+ /* Divide the message by the polynomial, a byte at a time. */ 44724+ for (byte = 0; byte < nbytes; ++byte) { 44725+ /* high 8 bits */ 44726+ data = reverse_data(message[byte]) ^ (remainder >> (WIDTH - 8)); 44727+ remainder = crc_table[data] ^ (remainder << 8); /* shift left 8 bits */ 44728+ } 44729+ 44730+ /* The final remainder is the CRC. */ 44731+ return (reverse_remainder(remainder) ^ FINAL_XOR_VALUE); 44732+} 44733diff --git a/drivers/net/ethernet/hisilicon/higmac/pm.h b/drivers/net/ethernet/hisilicon/higmac/pm.h 44734new file mode 100644 44735index 000000000..e54ced46c 44736--- /dev/null 44737+++ b/drivers/net/ethernet/hisilicon/higmac/pm.h 44738@@ -0,0 +1,59 @@ 44739+/* 44740+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 44741+ * Description: Higmac driver pm head file 44742+ * Author: KTP_BSP 44743+ * Create: 2020-05-19 44744+ */ 44745+ 44746+#ifndef __HIGMAC_PM_H__ 44747+#define __HIGMAC_PM_H__ 44748+ 44749+#include "higmac.h" 44750+ 44751+#define N 31 44752+#define FILTERS 4 44753+#define PM_FILTER_OFFSET_MIN 12 44754+struct pm_config { 44755+ unsigned char index; /* bit0--eth0 bit1--eth1 */ 44756+ unsigned char uc_pkts_enable; 44757+ unsigned char magic_pkts_enable; 44758+ unsigned char wakeup_pkts_enable; 44759+ struct { 44760+ unsigned int mask_bytes : N; 44761+ unsigned int reserved : 1; /* userspace ignore this bit */ 44762+ unsigned char offset; /* >= 12 */ 44763+ unsigned char value[N]; /* byte string */ 44764+ unsigned char valid; /* valid filter */ 44765+ } filter[FILTERS]; 44766+}; 44767+ 44768+struct pm_reg_config { 44769+ unsigned int pmt_ctrl; 44770+ unsigned int pmt_mask0; 44771+ unsigned int pmt_mask1; 44772+ unsigned int pmt_mask2; 44773+ unsigned int pmt_mask3; 44774+ unsigned int pmt_cmd; 44775+ unsigned int pmt_offset; 44776+ unsigned int pmt_crc1_0; 44777+ unsigned int pmt_crc3_2; 44778+}; 44779+ 44780+#define PMT_CTRL 0xa00 44781+#define PMT_MASK0 0xa04 44782+#define PMT_MASK1 0xa08 44783+#define PMT_MASK2 0xa0c 44784+#define PMT_MASK3 0xa10 44785+#define PMT_CMD 0xa14 44786+#define PMT_OFFSET 0xa18 44787+#define PMT_CRC1_0 0xa1c 44788+#define PMT_CRC3_2 0xa20 44789+#define MASK_INVALID_BIT BIT(31) 44790+ 44791+ 44792+int pmt_config(struct net_device const *ndev, struct pm_config const *config); 44793+bool pmt_enter(struct higmac_netdev_local *ld); 44794+void pmt_exit(struct higmac_netdev_local *ld); 44795+void pmt_reg_restore(struct higmac_netdev_local *ld); 44796+ 44797+#endif 44798\ No newline at end of file 44799diff --git a/drivers/net/ethernet/hisilicon/higmac/proc_dev.c b/drivers/net/ethernet/hisilicon/higmac/proc_dev.c 44800new file mode 100644 44801index 000000000..efb654fb4 44802--- /dev/null 44803+++ b/drivers/net/ethernet/hisilicon/higmac/proc_dev.c 44804@@ -0,0 +1,119 @@ 44805+/* 44806+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 44807+ * Description: Higmac driver proc dev process 44808+ * Author: KTP_BSP 44809+ * Create: 2018-10-08 44810+ */ 44811+ 44812+#include "sockioctl.h" 44813+#include "pm.h" 44814+ 44815+/* debug code */ 44816+static int set_suspend(int eth_n) 44817+{ 44818+ return 0; 44819+} 44820+ 44821+/* debug code */ 44822+static int set_resume(int eth_n) 44823+{ 44824+ return 0; 44825+} 44826+ 44827+static int hw_states_read(struct seq_file *m, void *v) 44828+{ 44829+ return 0; 44830+} 44831+ 44832+static struct proc_dir_entry *higmac_proc_root; 44833+ 44834+static int proc_open_hw_states_read(struct inode *inode, struct file *file) 44835+{ 44836+ return single_open(file, hw_states_read, PDE_DATA(inode)); 44837+} 44838+ 44839+static struct proc_file { 44840+ char *name; 44841+ const struct file_operations ops; 44842+ 44843+} proc_file[] = { 44844+ { 44845+ .name = "hw_stats", 44846+ .ops = { 44847+ .open = proc_open_hw_states_read, 44848+ .read = seq_read, 44849+ .llseek = seq_lseek, 44850+ .release = single_release, 44851+ }, 44852+ } 44853+}; 44854+ 44855+/* 44856+ * /proc/higmac/ 44857+ * |---hw_stats 44858+ * |---skb_pools 44859+ */ 44860+void higmac_proc_create(void) 44861+{ 44862+ int i; 44863+ 44864+ higmac_proc_root = proc_mkdir("higmac", NULL); 44865+ if (higmac_proc_root == NULL) 44866+ return; 44867+ 44868+ for (i = 0; i < ARRAY_SIZE(proc_file); i++) { 44869+ struct proc_dir_entry *entry; 44870+ 44871+ entry = proc_create(proc_file[i].name, 0, higmac_proc_root, 44872+ &proc_file[i].ops); 44873+ if (entry == NULL) 44874+ pr_err("failed to create %s\n", proc_file[i].name); 44875+ } 44876+} 44877+ 44878+void higmac_proc_destroy(void) 44879+{ 44880+ int i; 44881+ 44882+ for (i = 0; i < ARRAY_SIZE(proc_file); i++) 44883+ remove_proc_entry(proc_file[i].name, higmac_proc_root); 44884+ 44885+ remove_proc_entry("higmac", NULL); 44886+} 44887+ 44888+int higmac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) 44889+{ 44890+ struct higmac_netdev_local *priv = NULL; 44891+ struct pm_config config; 44892+ int val = 0; 44893+ if (ndev == NULL || rq == NULL) 44894+ return -EINVAL; 44895+ priv = netdev_priv(ndev); 44896+ switch (cmd) { 44897+ case SIOCSETPM: 44898+ if (rq->ifr_data == NULL || 44899+ copy_from_user(&config, rq->ifr_data, sizeof(config))) 44900+ return -EFAULT; 44901+ return pmt_config(ndev, &config); 44902+ 44903+ case SIOCSETSUSPEND: 44904+ if (rq->ifr_data == NULL || copy_from_user(&val, rq->ifr_data, sizeof(val))) 44905+ return -EFAULT; 44906+ return set_suspend(val); 44907+ 44908+ case SIOCSETRESUME: 44909+ if (rq->ifr_data == NULL || copy_from_user(&val, rq->ifr_data, sizeof(val))) 44910+ return -EFAULT; 44911+ return set_resume(val); 44912+ 44913+ default: 44914+ if (!netif_running(ndev)) 44915+ return -EINVAL; 44916+ 44917+ if (priv->phy == NULL) 44918+ return -EINVAL; 44919+ 44920+ return phy_mii_ioctl(priv->phy, rq, cmd); 44921+ } 44922+ return 0; 44923+} 44924diff --git a/drivers/net/ethernet/hisilicon/higmac/sockioctl.h b/drivers/net/ethernet/hisilicon/higmac/sockioctl.h 44925new file mode 100644 44926index 000000000..349f0f215 44927--- /dev/null 44928+++ b/drivers/net/ethernet/hisilicon/higmac/sockioctl.h 44929@@ -0,0 +1,19 @@ 44930+/* 44931+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 44932+ * Description: Higmac driver sockioctl head file 44933+ * Author: KTP_BSP 44934+ * Create: 2018-10-08 44935+ */ 44936+ 44937+#ifndef __HIGMAC_SOCKIOCTL_H__ 44938+#define __HIGMAC_SOCKIOCTL_H__ 44939+ 44940+#include <linux/sockios.h> 44941+ 44942+#define SIOCSETPM (SIOCDEVPRIVATE + 4) /* set pmt wake up config */ 44943+#define SIOCSETSUSPEND (SIOCDEVPRIVATE + 5) /* call dev->suspend, debug */ 44944+#define SIOCSETRESUME (SIOCDEVPRIVATE + 6) /* call dev->resume, debug */ 44945+ 44946+int higmac_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd); 44947+ 44948+#endif 44949diff --git a/drivers/net/ethernet/hisilicon/higmac/tso.h b/drivers/net/ethernet/hisilicon/higmac/tso.h 44950new file mode 100644 44951index 000000000..6c78d1d45 44952--- /dev/null 44953+++ b/drivers/net/ethernet/hisilicon/higmac/tso.h 44954@@ -0,0 +1,59 @@ 44955+/* 44956+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 44957+ * Description: Higmac driver tso head file 44958+ * Author: KTP_BSP 44959+ * Create: 2018-10-08 44960+ */ 44961+ 44962+#ifndef __HIGMAC_TSO_H__ 44963+#define __HIGMAC_TSO_H__ 44964+ 44965+#define SG_FLAG BIT(30) 44966+#define COE_FLAG BIT(29) 44967+#define TSO_FLAG BIT(28) 44968+#define VLAN_FLAG BIT(10) 44969+#define IPV6_FLAG BIT(9) 44970+#define UDP_FLAG BIT(8) 44971+ 44972+#define PKT_IPV6_HDR_LEN 10 44973+#define PKT_UDP_HDR_LEN 2 44974+#define WORD_TO_BYTE 4 44975+enum { 44976+ PKT_NORMAL, 44977+ PKT_SG 44978+}; 44979+ 44980+enum { 44981+ PKT_IPV4, 44982+ PKT_IPV6 44983+}; 44984+ 44985+enum { 44986+ PKT_TCP, 44987+ PKT_UDP 44988+}; 44989+ 44990+struct frags_info { 44991+ /* Word(2*i+2) */ 44992+ u32 addr; 44993+ /* Word(2*i+3) */ 44994+ u32 size : 16; 44995+ u32 reserved : 16; 44996+}; 44997+ 44998+struct sg_desc { 44999+ /* Word0 */ 45000+ u32 total_len : 17; 45001+ u32 reserv : 15; 45002+ /* Word1 */ 45003+ u32 ipv6_id; 45004+ /* Word2 */ 45005+ u32 linear_addr; 45006+ /* Word3 */ 45007+ u32 linear_len : 16; 45008+ u32 reserv3 : 16; 45009+ /* MAX_SKB_FRAGS is 18 */ 45010+ struct frags_info frags[18]; 45011+}; 45012+ 45013+#endif 45014diff --git a/drivers/net/ethernet/hisilicon/higmac/util.c b/drivers/net/ethernet/hisilicon/higmac/util.c 45015new file mode 100644 45016index 000000000..eae79af52 45017--- /dev/null 45018+++ b/drivers/net/ethernet/hisilicon/higmac/util.c 45019@@ -0,0 +1,975 @@ 45020+/* 45021+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 45022+ * Description: Higmac driver util file 45023+ * Author: KTP_BSP 45024+ * Create: 2020-05-19 45025+ */ 45026+ 45027+#include <linux/kernel.h> 45028+#include <linux/if_vlan.h> 45029+#include <linux/ip.h> 45030+#include <net/ipv6.h> 45031+#include <linux/reset.h> 45032+#include "util.h" 45033+ 45034+static unsigned int flow_ctrl_en = FLOW_OFF; 45035+static int tx_flow_ctrl_pause_time = CONFIG_TX_FLOW_CTRL_PAUSE_TIME; 45036+static int tx_flow_ctrl_pause_interval = CONFIG_TX_FLOW_CTRL_PAUSE_INTERVAL; 45037+static int tx_flow_ctrl_active_threshold = CONFIG_TX_FLOW_CTRL_ACTIVE_THRESHOLD; 45038+static int tx_flow_ctrl_deactive_threshold = 45039+ CONFIG_TX_FLOW_CTRL_DEACTIVE_THRESHOLD; 45040+ 45041+void higmac_trace(int level, const char *fmt, ...) 45042+{ 45043+ if (level >= HIGMAC_TRACE_LEVEL) { 45044+ va_list args; 45045+ va_start(args, fmt); 45046+ printk("higmac_trace:"); 45047+ printk(fmt, args); 45048+ printk("\n"); 45049+ va_end(args); 45050+ } 45051+} 45052+ 45053+void higmac_config_port(struct net_device const *dev, u32 speed, u32 duplex) 45054+{ 45055+ struct higmac_netdev_local *priv = netdev_priv(dev); 45056+ u32 val; 45057+ 45058+ switch (priv->phy_mode) { 45059+ case PHY_INTERFACE_MODE_RGMII: 45060+ if (speed == SPEED_1000) 45061+ val = RGMII_SPEED_1000; 45062+ else if (speed == SPEED_100) 45063+ val = RGMII_SPEED_100; 45064+ else 45065+ val = RGMII_SPEED_10; 45066+ break; 45067+ case PHY_INTERFACE_MODE_MII: 45068+ if (speed == SPEED_100) 45069+ val = MII_SPEED_100; 45070+ else 45071+ val = MII_SPEED_10; 45072+ break; 45073+ case PHY_INTERFACE_MODE_RMII: 45074+ if (speed == SPEED_100) 45075+ val = RMII_SPEED_100; 45076+ else 45077+ val = RMII_SPEED_10; 45078+ break; 45079+ default: 45080+ netdev_warn(dev, "not supported mode\n"); 45081+ val = MII_SPEED_10; 45082+ break; 45083+ } 45084+ 45085+ if (duplex) 45086+ val |= GMAC_FULL_DUPLEX; 45087+ 45088+ reset_control_assert(priv->macif_rst); 45089+ writel_relaxed(val, priv->macif_base); 45090+ reset_control_deassert(priv->macif_rst); 45091+ 45092+ writel_relaxed(BIT_MODE_CHANGE_EN, priv->gmac_iobase + MODE_CHANGE_EN); 45093+ if (speed == SPEED_1000) 45094+ val = GMAC_SPEED_1000; 45095+ else if (speed == SPEED_100) 45096+ val = GMAC_SPEED_100; 45097+ else 45098+ val = GMAC_SPEED_10; 45099+ writel_relaxed(val, priv->gmac_iobase + PORT_MODE); 45100+ writel_relaxed(0, priv->gmac_iobase + MODE_CHANGE_EN); 45101+ writel_relaxed(duplex, priv->gmac_iobase + MAC_DUPLEX_HALF_CTRL); 45102+} 45103+ 45104+int higmac_rx_checksum(struct net_device *dev, struct sk_buff *skb, 45105+ struct higmac_desc const *desc) 45106+{ 45107+ int hdr_csum_done, payload_csum_done; 45108+ int hdr_csum_err, payload_csum_err; 45109+ if (skb == NULL || desc == NULL || dev == NULL) 45110+ return -EINVAL; 45111+ if (dev->features & NETIF_F_RXCSUM) { 45112+ hdr_csum_done = desc->header_csum_done; 45113+ payload_csum_done = desc->payload_csum_done; 45114+ hdr_csum_err = desc->header_csum_err; 45115+ payload_csum_err = desc->payload_csum_err; 45116+ 45117+ if (hdr_csum_done && payload_csum_done) { 45118+ if (unlikely(hdr_csum_err || payload_csum_err)) { 45119+ dev->stats.rx_errors++; 45120+ dev->stats.rx_crc_errors++; 45121+ dev_kfree_skb_any(skb); 45122+ return -1; 45123+ } else { 45124+ skb->ip_summed = CHECKSUM_UNNECESSARY; 45125+ } 45126+ } 45127+ } 45128+ return 0; 45129+} 45130+ 45131+void higmac_verify_flow_ctrl_args(void) 45132+{ 45133+#if defined(CONFIG_TX_FLOW_CTRL_SUPPORT) 45134+ flow_ctrl_en |= FLOW_TX; 45135+#endif 45136+#if defined(CONFIG_RX_FLOW_CTRL_SUPPORT) 45137+ flow_ctrl_en |= FLOW_RX; 45138+#endif 45139+ if (tx_flow_ctrl_active_threshold < FC_ACTIVE_MIN || 45140+ tx_flow_ctrl_active_threshold > FC_ACTIVE_MAX) 45141+ tx_flow_ctrl_active_threshold = FC_ACTIVE_DEFAULT; 45142+ 45143+ if (tx_flow_ctrl_deactive_threshold < FC_DEACTIVE_MIN || 45144+ tx_flow_ctrl_deactive_threshold > FC_DEACTIVE_MAX) 45145+ tx_flow_ctrl_deactive_threshold = FC_DEACTIVE_DEFAULT; 45146+ 45147+ if (tx_flow_ctrl_active_threshold >= tx_flow_ctrl_deactive_threshold) { 45148+ tx_flow_ctrl_active_threshold = FC_ACTIVE_DEFAULT; 45149+ tx_flow_ctrl_deactive_threshold = FC_DEACTIVE_DEFAULT; 45150+ } 45151+ 45152+ if (tx_flow_ctrl_pause_time < 0 || 45153+ tx_flow_ctrl_pause_time > FC_PAUSE_TIME_MAX) 45154+ tx_flow_ctrl_pause_time = FC_PAUSE_TIME_DEFAULT; 45155+ 45156+ if (tx_flow_ctrl_pause_interval < 0 || 45157+ tx_flow_ctrl_pause_interval > FC_PAUSE_TIME_MAX) 45158+ tx_flow_ctrl_pause_interval = FC_PAUSE_INTERVAL_DEFAULT; 45159+ 45160+ /* 45161+ * pause interval should not bigger than pause time, 45162+ * but should not too smaller to avoid sending too many pause frame. 45163+ */ 45164+ if ((tx_flow_ctrl_pause_interval > tx_flow_ctrl_pause_time) || 45165+ (tx_flow_ctrl_pause_interval < ((unsigned int)tx_flow_ctrl_pause_time >> 1))) 45166+ tx_flow_ctrl_pause_interval = tx_flow_ctrl_pause_time; 45167+} 45168+ 45169+void higmac_set_flow_ctrl_args(struct higmac_netdev_local *ld) 45170+{ 45171+ if (ld == NULL) 45172+ return; 45173+ ld->flow_ctrl = flow_ctrl_en; 45174+ ld->pause = tx_flow_ctrl_pause_time; 45175+ ld->pause_interval = tx_flow_ctrl_pause_interval; 45176+ ld->flow_ctrl_active_threshold = tx_flow_ctrl_active_threshold; 45177+ ld->flow_ctrl_deactive_threshold = tx_flow_ctrl_deactive_threshold; 45178+} 45179+ 45180+void higmac_set_flow_ctrl_params(struct higmac_netdev_local const *ld) 45181+{ 45182+ unsigned int rx_fq_empty_th; 45183+ unsigned int rx_fq_full_th; 45184+ unsigned int rx_bq_empty_th; 45185+ unsigned int rx_bq_full_th; 45186+ unsigned int rec_filter; 45187+ if (ld == NULL) 45188+ return; 45189+ writel(ld->pause, ld->gmac_iobase + FC_TX_TIMER); 45190+ writel(ld->pause_interval, ld->gmac_iobase + PAUSE_THR); 45191+ 45192+ rx_fq_empty_th = readl(ld->gmac_iobase + RX_FQ_ALEMPTY_TH); 45193+ rx_fq_empty_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); 45194+ rx_fq_empty_th |= (ld->flow_ctrl_active_threshold << 45195+ BITS_Q_PAUSE_TH_OFFSET); 45196+ writel(rx_fq_empty_th, ld->gmac_iobase + RX_FQ_ALEMPTY_TH); 45197+ 45198+ rx_fq_full_th = readl(ld->gmac_iobase + RX_FQ_ALFULL_TH); 45199+ rx_fq_full_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); 45200+ rx_fq_full_th |= (ld->flow_ctrl_deactive_threshold << 45201+ BITS_Q_PAUSE_TH_OFFSET); 45202+ writel(rx_fq_full_th, ld->gmac_iobase + RX_FQ_ALFULL_TH); 45203+ 45204+ rx_bq_empty_th = readl(ld->gmac_iobase + RX_BQ_ALEMPTY_TH); 45205+ rx_bq_empty_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); 45206+ rx_bq_empty_th |= (ld->flow_ctrl_active_threshold << 45207+ BITS_Q_PAUSE_TH_OFFSET); 45208+ writel(rx_bq_empty_th, ld->gmac_iobase + RX_BQ_ALEMPTY_TH); 45209+ 45210+ rx_bq_full_th = readl(ld->gmac_iobase + RX_BQ_ALFULL_TH); 45211+ rx_bq_full_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); 45212+ rx_bq_full_th |= (ld->flow_ctrl_deactive_threshold << 45213+ BITS_Q_PAUSE_TH_OFFSET); 45214+ writel(rx_bq_full_th, ld->gmac_iobase + RX_BQ_ALFULL_TH); 45215+ 45216+ writel(0, ld->gmac_iobase + CRF_TX_PAUSE); 45217+ 45218+ rec_filter = readl(ld->gmac_iobase + REC_FILT_CONTROL); 45219+ rec_filter |= BIT_PAUSE_FRM_PASS; 45220+ writel(rec_filter, ld->gmac_iobase + REC_FILT_CONTROL); 45221+} 45222+ 45223+void higmac_set_flow_ctrl_state(struct higmac_netdev_local const *ld, int pause) 45224+{ 45225+ unsigned int flow_rx_q_en; 45226+ unsigned int flow; 45227+ if (ld == NULL) 45228+ return; 45229+ flow_rx_q_en = readl(ld->gmac_iobase + RX_PAUSE_EN); 45230+ flow_rx_q_en &= ~(BIT_RX_FQ_PAUSE_EN | BIT_RX_BQ_PAUSE_EN); 45231+ if (pause && (ld->flow_ctrl & FLOW_TX)) 45232+ flow_rx_q_en |= (BIT_RX_FQ_PAUSE_EN | BIT_RX_BQ_PAUSE_EN); 45233+ writel(flow_rx_q_en, ld->gmac_iobase + RX_PAUSE_EN); 45234+ 45235+ flow = readl(ld->gmac_iobase + PAUSE_EN); 45236+ flow &= ~(BIT_RX_FDFC | BIT_TX_FDFC); 45237+ if (pause) { 45238+ if (ld->flow_ctrl & FLOW_RX) 45239+ flow |= BIT_RX_FDFC; 45240+ if (ld->flow_ctrl & FLOW_TX) 45241+ flow |= BIT_TX_FDFC; 45242+ } 45243+ writel(flow, ld->gmac_iobase + PAUSE_EN); 45244+} 45245+ 45246+static __be16 higmac_get_l3_proto(struct sk_buff *skb) 45247+{ 45248+ __be16 l3_proto; 45249+ 45250+ l3_proto = skb->protocol; 45251+ if (skb->protocol == htons(ETH_P_8021Q)) 45252+ l3_proto = vlan_get_protocol(skb); 45253+ 45254+ return l3_proto; 45255+} 45256+ 45257+static unsigned int higmac_get_l4_proto(struct sk_buff *skb) 45258+{ 45259+ __be16 l3_proto; 45260+ unsigned int l4_proto = IPPROTO_MAX; 45261+ 45262+ l3_proto = higmac_get_l3_proto(skb); 45263+ if (l3_proto == htons(ETH_P_IP)) 45264+ l4_proto = ip_hdr(skb)->protocol; 45265+ else if (l3_proto == htons(ETH_P_IPV6)) 45266+ l4_proto = ipv6_hdr(skb)->nexthdr; 45267+ 45268+ return l4_proto; 45269+} 45270+ 45271+static inline bool higmac_skb_is_ipv6(struct sk_buff *skb) 45272+{ 45273+ return (higmac_get_l3_proto(skb) == htons(ETH_P_IPV6)); 45274+} 45275+ 45276+static inline bool higmac_skb_is_udp(struct sk_buff *skb) 45277+{ 45278+ return (higmac_get_l4_proto(skb) == IPPROTO_UDP); 45279+} 45280+ 45281+static int higmac_check_hw_capability_for_udp(struct sk_buff const *skb) 45282+{ 45283+ struct ethhdr *eth; 45284+ 45285+ /* hardware can't dea with UFO broadcast packet */ 45286+ eth = (struct ethhdr *)(skb->data); 45287+ if (skb_is_gso(skb) && is_broadcast_ether_addr(eth->h_dest)) 45288+ return -ENOTSUPP; 45289+ 45290+ return 0; 45291+} 45292+ 45293+static int higmac_check_hw_capability_for_ipv6(struct sk_buff *skb) 45294+{ 45295+ unsigned int l4_proto; 45296+ 45297+ l4_proto = ipv6_hdr(skb)->nexthdr; 45298+ if ((l4_proto != IPPROTO_TCP) && (l4_proto != IPPROTO_UDP)) { 45299+ /* 45300+ * when IPv6 next header is not tcp or udp, 45301+ * it means that IPv6 next header is extension header. 45302+ * Hardware can't deal with this case, 45303+ * so do checksumming by software or do GSO by software. 45304+ */ 45305+ if (skb_is_gso(skb)) 45306+ return -ENOTSUPP; 45307+ 45308+ if (skb->ip_summed == CHECKSUM_PARTIAL && 45309+ skb_checksum_help(skb)) 45310+ return -EFAULT; 45311+ } 45312+ 45313+ return 0; 45314+} 45315+ 45316+static inline bool higmac_skb_is_ipv4_with_options(struct sk_buff *skb) 45317+{ 45318+ return ((higmac_get_l3_proto(skb) == htons(ETH_P_IP)) && 45319+ (ip_hdr(skb)->ihl > IPV4_HEAD_LENGTH)); 45320+} 45321+ 45322+int higmac_check_hw_capability(struct sk_buff *skb) 45323+{ 45324+ int ret; 45325+ 45326+ /* 45327+ * if tcp_mtu_probe() use (2 * tp->mss_cache) as probe_size, 45328+ * the linear data length will be larger than 2048, 45329+ * the MAC can't handle it, so let the software do it. 45330+ */ 45331+ if (skb == NULL) 45332+ return -EINVAL; 45333+ if (skb_is_gso(skb) && (skb_headlen(skb) > 2048)) /* 2048(2k) */ 45334+ return -ENOTSUPP; 45335+ 45336+ if (higmac_skb_is_ipv6(skb)) { 45337+ ret = higmac_check_hw_capability_for_ipv6(skb); 45338+ if (ret) 45339+ return ret; 45340+ } 45341+ 45342+ if (higmac_skb_is_udp(skb)) { 45343+ ret = higmac_check_hw_capability_for_udp(skb); 45344+ if (ret) 45345+ return ret; 45346+ } 45347+ 45348+ if (((skb->ip_summed == CHECKSUM_PARTIAL) || skb_is_gso(skb)) && 45349+ higmac_skb_is_ipv4_with_options(skb)) 45350+ return -ENOTSUPP; 45351+ 45352+ return 0; 45353+} 45354+ 45355+static void higmac_do_udp_checksum(struct sk_buff *skb) 45356+{ 45357+ int offset; 45358+ __wsum csum; 45359+ __sum16 udp_csum; 45360+ 45361+ offset = skb_checksum_start_offset(skb); 45362+ WARN_ON(offset >= skb_headlen(skb)); 45363+ csum = skb_checksum(skb, offset, skb->len - offset, 0); 45364+ 45365+ offset += skb->csum_offset; 45366+ WARN_ON(offset + sizeof(__sum16) > skb_headlen(skb)); 45367+ udp_csum = csum_fold(csum); 45368+ if (udp_csum == 0) 45369+ udp_csum = CSUM_MANGLED_0; 45370+ 45371+ *(__sum16 *)(skb->data + offset) = udp_csum; 45372+ 45373+ skb->ip_summed = CHECKSUM_NONE; 45374+} 45375+ 45376+static int higmac_get_pkt_info_l3l4(struct higmac_tso_desc *tx_bq_desc, 45377+ struct sk_buff *skb, unsigned int *l4_proto, unsigned int *max_mss, 45378+ unsigned char *coe_enable) 45379+{ 45380+ __be16 l3_proto; /* level 3 protocol */ 45381+ int max_data_len = skb->len - ETH_HLEN; 45382+ 45383+ l3_proto = skb->protocol; 45384+ if (skb->protocol == htons(ETH_P_8021Q)) { 45385+ l3_proto = vlan_get_protocol(skb); 45386+ tx_bq_desc->desc1.tx.vlan_flag = 1; 45387+ max_data_len -= VLAN_HLEN; 45388+ } 45389+ 45390+ if (l3_proto == htons(ETH_P_IP)) { 45391+ struct iphdr *iph; 45392+ 45393+ iph = ip_hdr(skb); 45394+ tx_bq_desc->desc1.tx.ip_ver = PKT_IPV4; 45395+ tx_bq_desc->desc1.tx.ip_hdr_len = iph->ihl; 45396+ 45397+ if ((max_data_len >= GSO_MAX_SIZE) && 45398+ (ntohs(iph->tot_len) <= (iph->ihl << 2))) /* shift left 2 */ 45399+ iph->tot_len = htons(GSO_MAX_SIZE - 1); 45400+ 45401+ *max_mss -= iph->ihl * WORD_TO_BYTE; 45402+ *l4_proto = iph->protocol; 45403+ } else if (l3_proto == htons(ETH_P_IPV6)) { 45404+ tx_bq_desc->desc1.tx.ip_ver = PKT_IPV6; 45405+ tx_bq_desc->desc1.tx.ip_hdr_len = PKT_IPV6_HDR_LEN; 45406+ *max_mss -= PKT_IPV6_HDR_LEN * WORD_TO_BYTE; 45407+ *l4_proto = ipv6_hdr(skb)->nexthdr; 45408+ } else { 45409+ *coe_enable = 0; 45410+ } 45411+ 45412+ if (*l4_proto == IPPROTO_TCP) { 45413+ tx_bq_desc->desc1.tx.prot_type = PKT_TCP; 45414+ if (tcp_hdr(skb)->doff < sizeof(struct tcphdr) / WORD_TO_BYTE) 45415+ return -EFAULT; 45416+ tx_bq_desc->desc1.tx.prot_hdr_len = tcp_hdr(skb)->doff; 45417+ *max_mss -= tcp_hdr(skb)->doff * WORD_TO_BYTE; 45418+ } else if (*l4_proto == IPPROTO_UDP) { 45419+ tx_bq_desc->desc1.tx.prot_type = PKT_UDP; 45420+ tx_bq_desc->desc1.tx.prot_hdr_len = PKT_UDP_HDR_LEN; 45421+ if (l3_proto == htons(ETH_P_IPV6)) 45422+ *max_mss -= sizeof(struct frag_hdr); 45423+ } else { 45424+ *coe_enable = 0; 45425+ } 45426+ 45427+ return 0; 45428+} 45429+ 45430+int higmac_get_pkt_info(struct higmac_netdev_local *ld, 45431+ struct sk_buff *skb, struct higmac_tso_desc *tx_bq_desc) 45432+{ 45433+ int nfrags; 45434+ unsigned int l4_proto = IPPROTO_MAX; 45435+ unsigned int max_mss = ETH_DATA_LEN; 45436+ unsigned char coe_enable = 0; 45437+ int ret; 45438+ if (skb == NULL || tx_bq_desc == NULL) 45439+ return -EINVAL; 45440+ 45441+ nfrags = skb_shinfo(skb)->nr_frags; 45442+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) 45443+ coe_enable = 1; 45444+ 45445+ tx_bq_desc->desc1.val = 0; 45446+ 45447+ if (skb_is_gso(skb)) { 45448+ tx_bq_desc->desc1.tx.tso_flag = 1; 45449+ tx_bq_desc->desc1.tx.sg_flag = 1; 45450+ } else if (nfrags) { 45451+ tx_bq_desc->desc1.tx.sg_flag = 1; 45452+ } 45453+ 45454+ ret = higmac_get_pkt_info_l3l4(tx_bq_desc, skb, &l4_proto, &max_mss, 45455+ &coe_enable); 45456+ if (ret < 0) 45457+ return ret; 45458+ 45459+ if (skb_is_gso(skb)) 45460+ tx_bq_desc->desc1.tx.data_len = 45461+ (skb_shinfo(skb)->gso_size > max_mss) ? max_mss : 45462+ skb_shinfo(skb)->gso_size; 45463+ else 45464+ tx_bq_desc->desc1.tx.data_len = skb->len; 45465+ 45466+ if (coe_enable && skb_is_gso(skb) && (l4_proto == IPPROTO_UDP)) 45467+ higmac_do_udp_checksum(skb); 45468+ 45469+ if (coe_enable) 45470+ tx_bq_desc->desc1.tx.coe_flag = 1; 45471+ 45472+ tx_bq_desc->desc1.tx.nfrags_num = nfrags; 45473+ 45474+ tx_bq_desc->desc1.tx.hw_own = DESC_VLD_BUSY; 45475+ return 0; 45476+} 45477+ 45478+void higmac_get_drvinfo(struct net_device *net_dev, 45479+ struct ethtool_drvinfo *info) 45480+{ 45481+ if (info == NULL) 45482+ return; 45483+ strncpy(info->driver, "higmac driver", sizeof(info->driver)); 45484+ strncpy(info->version, "higmac v200", sizeof(info->version)); 45485+ strncpy(info->bus_info, "platform", sizeof(info->bus_info)); 45486+} 45487+ 45488+unsigned int higmac_get_link(struct net_device *net_dev) 45489+{ 45490+ struct higmac_netdev_local *ld = netdev_priv(net_dev); 45491+ 45492+ return ld->phy->link ? HIGMAC_LINKED : 0; 45493+} 45494+ 45495+int higmac_get_settings(struct net_device *net_dev, 45496+ struct ethtool_cmd *cmd) 45497+{ 45498+ struct higmac_netdev_local *ld = netdev_priv(net_dev); 45499+ 45500+ if (ld->phy != NULL) 45501+ return phy_ethtool_gset(ld->phy, cmd); 45502+ 45503+ return -EINVAL; 45504+} 45505+ 45506+int higmac_set_settings(struct net_device *net_dev, 45507+ struct ethtool_cmd *cmd) 45508+{ 45509+ struct higmac_netdev_local *ld = netdev_priv(net_dev); 45510+ 45511+ if (!capable(CAP_NET_ADMIN)) 45512+ return -EPERM; 45513+ 45514+ if (ld->phy != NULL) 45515+ return phy_ethtool_sset(ld->phy, cmd); 45516+ 45517+ return -EINVAL; 45518+} 45519+ 45520+void higmac_get_pauseparam(struct net_device *net_dev, 45521+ struct ethtool_pauseparam *pause) 45522+{ 45523+ struct higmac_netdev_local *ld = NULL; 45524+ if (net_dev == NULL || pause == NULL) 45525+ return; 45526+ ld = netdev_priv(net_dev); 45527+ 45528+ pause->rx_pause = 0; 45529+ pause->tx_pause = 0; 45530+ pause->autoneg = ld->phy->autoneg; 45531+ 45532+ if (ld->flow_ctrl & FLOW_RX) 45533+ pause->rx_pause = 1; 45534+ if (ld->flow_ctrl & FLOW_TX) 45535+ pause->tx_pause = 1; 45536+} 45537+ 45538+int higmac_set_pauseparam(struct net_device *net_dev, 45539+ struct ethtool_pauseparam *pause) 45540+{ 45541+ struct higmac_netdev_local *ld = netdev_priv(net_dev); 45542+ struct phy_device *phy = ld->phy; 45543+ unsigned int new_pause = FLOW_OFF; 45544+ 45545+ if (pause == NULL) 45546+ return -ENOMEM; 45547+ 45548+ if (pause->rx_pause) 45549+ new_pause |= FLOW_RX; 45550+ if (pause->tx_pause) 45551+ new_pause |= FLOW_TX; 45552+ 45553+ if (new_pause != ld->flow_ctrl) 45554+ ld->flow_ctrl = new_pause; 45555+ 45556+ higmac_set_flow_ctrl_state(ld, phy->pause); 45557+ phy->advertising &= ~SUPPORTED_Pause; 45558+ if (ld->flow_ctrl) 45559+ phy->advertising |= SUPPORTED_Pause; 45560+ 45561+ if (phy->autoneg) { 45562+ if (netif_running(net_dev)) 45563+ return phy_start_aneg(phy); 45564+ } 45565+ 45566+ return 0; 45567+} 45568+ 45569+u32 higmac_ethtool_getmsglevel(struct net_device *ndev) 45570+{ 45571+ struct higmac_netdev_local *priv = netdev_priv(ndev); 45572+ 45573+ return priv->msg_enable; 45574+} 45575+ 45576+void higmac_ethtool_setmsglevel(struct net_device *ndev, u32 level) 45577+{ 45578+ struct higmac_netdev_local *priv = netdev_priv(ndev); 45579+ 45580+ priv->msg_enable = level; 45581+} 45582+ 45583+u32 higmac_get_rxfh_key_size(struct net_device *ndev) 45584+{ 45585+ return RSS_HASH_KEY_SIZE; 45586+} 45587+ 45588+u32 higmac_get_rxfh_indir_size(struct net_device *ndev) 45589+{ 45590+ struct higmac_netdev_local *priv = netdev_priv(ndev); 45591+ 45592+ return priv->rss_info.ind_tbl_size; 45593+} 45594+ 45595+int higmac_get_rxfh(struct net_device *ndev, u32 *indir, u8 *hkey, 45596+ u8 *hfunc) 45597+{ 45598+ struct higmac_netdev_local *priv = netdev_priv(ndev); 45599+ struct higmac_rss_info *rss = &priv->rss_info; 45600+ 45601+ if (hfunc != NULL) 45602+ *hfunc = ETH_RSS_HASH_TOP; 45603+ 45604+ if (hkey != NULL) 45605+ memcpy(hkey, rss->key, RSS_HASH_KEY_SIZE); 45606+ 45607+ if (indir != NULL) { 45608+ int i; 45609+ 45610+ for (i = 0; i < rss->ind_tbl_size; i++) 45611+ indir[i] = rss->ind_tbl[i]; 45612+ } 45613+ 45614+ return 0; 45615+} 45616+ 45617+void higmac_get_rss_key(struct higmac_netdev_local *priv) 45618+{ 45619+ struct higmac_rss_info *rss = NULL; 45620+ u32 hkey; 45621+ if (priv == NULL) 45622+ return; 45623+ rss = &priv->rss_info; 45624+ hkey = readl(priv->gmac_iobase + RSS_HASH_KEY); 45625+ *((u32 *)rss->key) = hkey; 45626+} 45627+ 45628+static void higmac_set_rss_key(struct higmac_netdev_local *priv) 45629+{ 45630+ struct higmac_rss_info *rss = &priv->rss_info; 45631+ 45632+ writel(*((u32 *)rss->key), priv->gmac_iobase + RSS_HASH_KEY); 45633+} 45634+ 45635+static int higmac_wait_rss_ready(struct higmac_netdev_local const *priv) 45636+{ 45637+ void __iomem *base = priv->gmac_iobase; 45638+ int i; 45639+ const int timeout = 10000; 45640+ 45641+ for (i = 0; !(readl(base + RSS_IND_TBL) & BIT_IND_TBL_READY); i++) { 45642+ if (i == timeout) { 45643+ netdev_err(priv->netdev, "wait rss ready timeout!\n"); 45644+ return -ETIMEDOUT; 45645+ } 45646+ usleep_range(10, 20); /* wait 10~20us */ 45647+ } 45648+ 45649+ return 0; 45650+} 45651+ 45652+static void higmac_config_rss(struct higmac_netdev_local *priv) 45653+{ 45654+ struct higmac_rss_info *rss = NULL; 45655+ u32 rss_val; 45656+ unsigned int i; 45657+ if (priv == NULL) 45658+ return; 45659+ rss = &priv->rss_info; 45660+ for (i = 0; i < rss->ind_tbl_size; i++) { 45661+ if (higmac_wait_rss_ready(priv) != 0) 45662+ break; 45663+ rss_val = BIT_IND_TLB_WR | (rss->ind_tbl[i] << 8) | i; /* shift 8 */ 45664+ writel(rss_val, priv->gmac_iobase + RSS_IND_TBL); 45665+ } 45666+} 45667+ 45668+void higmac_get_rss(struct higmac_netdev_local *priv) 45669+{ 45670+ struct higmac_rss_info *rss = NULL; 45671+ u32 rss_val; 45672+ int i; 45673+ if (priv == NULL) 45674+ return; 45675+ rss = &priv->rss_info; 45676+ for (i = 0; i < rss->ind_tbl_size; i++) { 45677+ if (higmac_wait_rss_ready(priv) != 0) 45678+ break; 45679+ writel(i, priv->gmac_iobase + RSS_IND_TBL); 45680+ if (higmac_wait_rss_ready(priv) != 0) 45681+ break; 45682+ rss_val = readl(priv->gmac_iobase + RSS_IND_TBL); 45683+ rss->ind_tbl[i] = (rss_val >> 10) & 0x3; /* right shift 10 */ 45684+ } 45685+} 45686+ 45687+int higmac_set_rxfh(struct net_device *ndev, const u32 *indir, 45688+ const u8 *hkey, const u8 hfunc) 45689+{ 45690+ struct higmac_netdev_local *priv = netdev_priv(ndev); 45691+ struct higmac_rss_info *rss = &priv->rss_info; 45692+ 45693+ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) 45694+ return -EOPNOTSUPP; 45695+ 45696+ if (indir != NULL) { 45697+ int i; 45698+ 45699+ for (i = 0; i < rss->ind_tbl_size; i++) 45700+ rss->ind_tbl[i] = indir[i]; 45701+ } 45702+ 45703+ if (hkey != NULL) { 45704+ memcpy(rss->key, hkey, RSS_HASH_KEY_SIZE); 45705+ higmac_set_rss_key(priv); 45706+ } 45707+ 45708+ higmac_config_rss(priv); 45709+ 45710+ return 0; 45711+} 45712+ 45713+static void higmac_get_rss_hash(struct ethtool_rxnfc *info, u32 hash_cfg, 45714+ u32 l3_hash_en, u32 l4_hash_en, u32 vlan_hash_en) 45715+{ 45716+ if (hash_cfg & l3_hash_en) 45717+ info->data |= RXH_IP_SRC | RXH_IP_DST; 45718+ if (hash_cfg & l4_hash_en) 45719+ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 45720+ if (hash_cfg & vlan_hash_en) 45721+ info->data |= RXH_VLAN; 45722+} 45723+ 45724+static int higmac_get_rss_hash_opts(struct higmac_netdev_local const *priv, 45725+ struct ethtool_rxnfc *info) 45726+{ 45727+ u32 hash_cfg = priv->rss_info.hash_cfg; 45728+ 45729+ info->data = 0; 45730+ 45731+ switch (info->flow_type) { 45732+ case TCP_V4_FLOW: 45733+ higmac_get_rss_hash(info, hash_cfg, TCPV4_L3_HASH_EN, TCPV4_L4_HASH_EN, 45734+ TCPV4_VLAN_HASH_EN); 45735+ break; 45736+ case TCP_V6_FLOW: 45737+ higmac_get_rss_hash(info, hash_cfg, TCPV6_L3_HASH_EN, TCPV6_L4_HASH_EN, 45738+ TCPV6_VLAN_HASH_EN); 45739+ break; 45740+ case UDP_V4_FLOW: 45741+ higmac_get_rss_hash(info, hash_cfg, UDPV4_L3_HASH_EN, UDPV4_L4_HASH_EN, 45742+ UDPV4_VLAN_HASH_EN); 45743+ break; 45744+ case UDP_V6_FLOW: 45745+ higmac_get_rss_hash(info, hash_cfg, UDPV6_L3_HASH_EN, UDPV6_L4_HASH_EN, 45746+ UDPV6_VLAN_HASH_EN); 45747+ break; 45748+ case IPV4_FLOW: 45749+ higmac_get_rss_hash(info, hash_cfg, IPV4_L3_HASH_EN, 0, 45750+ IPV4_VLAN_HASH_EN); 45751+ break; 45752+ case IPV6_FLOW: 45753+ higmac_get_rss_hash(info, hash_cfg, IPV6_L3_HASH_EN, 0, 45754+ IPV6_VLAN_HASH_EN); 45755+ break; 45756+ default: 45757+ return -EINVAL; 45758+ } 45759+ 45760+ return 0; 45761+} 45762+ 45763+int higmac_get_rxnfc(struct net_device *ndev, 45764+ struct ethtool_rxnfc *info, u32 *rules) 45765+{ 45766+ struct higmac_netdev_local *priv = netdev_priv(ndev); 45767+ int ret = -EOPNOTSUPP; 45768+ if (info == NULL) 45769+ return -EINVAL; 45770+ switch (info->cmd) { 45771+ case ETHTOOL_GRXRINGS: 45772+ info->data = priv->num_rxqs; 45773+ ret = 0; 45774+ break; 45775+ case ETHTOOL_GRXFH: 45776+ return higmac_get_rss_hash_opts(priv, info); 45777+ default: 45778+ break; 45779+ } 45780+ return ret; 45781+} 45782+ 45783+void higmac_config_hash_policy(struct higmac_netdev_local const *priv) 45784+{ 45785+ if (priv == NULL) 45786+ return; 45787+ writel(priv->rss_info.hash_cfg, priv->gmac_iobase + RSS_HASH_CONFIG); 45788+} 45789+ 45790+static int higmac_set_tcp_udp_hash_cfg(struct ethtool_rxnfc const *info, 45791+ u32 *hash_cfg, u32 l4_mask, u32 vlan_mask) 45792+{ 45793+ switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 45794+ case 0: // all bits is 0 45795+ *hash_cfg &= ~l4_mask; 45796+ break; 45797+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 45798+ *hash_cfg |= l4_mask; 45799+ break; 45800+ default: 45801+ return -EINVAL; 45802+ } 45803+ if (info->data & RXH_VLAN) 45804+ *hash_cfg |= vlan_mask; 45805+ else 45806+ *hash_cfg &= ~vlan_mask; 45807+ return 0; 45808+} 45809+ 45810+static int higmac_ip_hash_cfg(struct ethtool_rxnfc const *info, 45811+ u32 *hash_cfg, u32 vlan_mask) 45812+{ 45813+ if (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) 45814+ return -EINVAL; 45815+ if (info->data & RXH_VLAN) 45816+ *hash_cfg |= vlan_mask; 45817+ else 45818+ *hash_cfg &= ~vlan_mask; 45819+ return 0; 45820+} 45821+ 45822+static int higmac_set_rss_hash_opts(struct higmac_netdev_local *priv, 45823+ struct ethtool_rxnfc const *info) 45824+{ 45825+ u32 hash_cfg; 45826+ if (priv == NULL || priv->netdev == NULL) 45827+ return -EINVAL; 45828+ hash_cfg = priv->rss_info.hash_cfg; 45829+ netdev_info(priv->netdev, "Set RSS flow type = %d, data = %lld\n", 45830+ info->flow_type, info->data); 45831+ 45832+ if (!(info->data & RXH_IP_SRC) || !(info->data & RXH_IP_DST)) 45833+ return -EINVAL; 45834+ 45835+ switch (info->flow_type) { 45836+ case TCP_V4_FLOW: 45837+ if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg, 45838+ TCPV4_L4_HASH_EN, TCPV4_VLAN_HASH_EN) == -EINVAL) 45839+ return -EINVAL; 45840+ break; 45841+ case TCP_V6_FLOW: 45842+ if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg, 45843+ TCPV6_L4_HASH_EN, TCPV6_VLAN_HASH_EN) == -EINVAL) 45844+ return -EINVAL; 45845+ break; 45846+ case UDP_V4_FLOW: 45847+ if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg, 45848+ UDPV4_L4_HASH_EN, UDPV4_L4_HASH_EN) == -EINVAL) 45849+ return -EINVAL; 45850+ break; 45851+ case UDP_V6_FLOW: 45852+ if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg, 45853+ UDPV6_L4_HASH_EN, UDPV6_L4_HASH_EN) == -EINVAL) 45854+ return -EINVAL; 45855+ break; 45856+ case IPV4_FLOW: 45857+ if (higmac_ip_hash_cfg(info, &hash_cfg, 45858+ IPV4_VLAN_HASH_EN) == -EINVAL) 45859+ return -EINVAL; 45860+ break; 45861+ break; 45862+ case IPV6_FLOW: 45863+ if (higmac_ip_hash_cfg(info, &hash_cfg, 45864+ IPV6_VLAN_HASH_EN) == -EINVAL) 45865+ return -EINVAL; 45866+ break; 45867+ default: 45868+ return -EINVAL; 45869+ } 45870+ 45871+ priv->rss_info.hash_cfg = hash_cfg; 45872+ higmac_config_hash_policy(priv); 45873+ 45874+ return 0; 45875+} 45876+ 45877+int higmac_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *info) 45878+{ 45879+ struct higmac_netdev_local *priv = netdev_priv(ndev); 45880+ if (info == NULL) 45881+ return -EINVAL; 45882+ switch (info->cmd) { 45883+ case ETHTOOL_SRXFH: 45884+ return higmac_set_rss_hash_opts(priv, info); 45885+ default: 45886+ break; 45887+ } 45888+ return -EOPNOTSUPP; 45889+} 45890+ 45891+static int ksz8051mnl_phy_fix(struct phy_device *phy_dev) 45892+{ 45893+ u32 v; 45894+ int ret; 45895+ 45896+ if (phy_dev->interface != PHY_INTERFACE_MODE_RMII) 45897+ return 0; 45898+ 45899+ ret = phy_read(phy_dev, 0x1F); 45900+ if (ret < 0) 45901+ return ret; 45902+ v = ret; 45903+ v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */ 45904+ phy_write(phy_dev, 0x1F, v); 45905+ 45906+ ret = phy_read(phy_dev, 0x16); 45907+ if (ret < 0) 45908+ return ret; 45909+ v = ret; 45910+ v |= (1 << 1); /* set phy RMII override; */ 45911+ phy_write(phy_dev, 0x16, v); 45912+ 45913+ return 0; 45914+} 45915+ 45916+static int ksz8081rnb_phy_fix(struct phy_device *phy_dev) 45917+{ 45918+ u32 v; 45919+ int ret; 45920+ 45921+ if (phy_dev->interface != PHY_INTERFACE_MODE_RMII) 45922+ return 0; 45923+ 45924+ ret = phy_read(phy_dev, 0x1F); 45925+ if (ret < 0) 45926+ return ret; 45927+ v = ret; 45928+ v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */ 45929+ phy_write(phy_dev, 0x1F, v); 45930+ 45931+ return 0; 45932+} 45933+ 45934+static int unknown_phy_fix(struct phy_device *phy_dev) 45935+{ 45936+ u32 v; 45937+ int ret; 45938+ 45939+ if (phy_dev->interface != PHY_INTERFACE_MODE_RMII) 45940+ return 0; 45941+ 45942+ ret = phy_read(phy_dev, 0x1F); 45943+ if (ret < 0) 45944+ return ret; 45945+ v = ret; 45946+ v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */ 45947+ phy_write(phy_dev, 0x1F, v); 45948+ 45949+ return 0; 45950+} 45951+ 45952+static int rtl8211e_phy_fix(struct phy_device *phy_dev) 45953+{ 45954+ u32 v; 45955+ int ret; 45956+ 45957+ /* select Extension page */ 45958+ phy_write(phy_dev, 0x1f, 0x7); 45959+ /* switch ExtPage 164 */ 45960+ phy_write(phy_dev, 0x1e, 0xa4); 45961+ 45962+ /* config RGMII rx pin io driver max */ 45963+ ret = phy_read(phy_dev, 0x1c); 45964+ if (ret < 0) 45965+ return ret; 45966+ v = ret; 45967+ v = (v & 0xff03) | 0xfc; 45968+ phy_write(phy_dev, 0x1c, v); 45969+ 45970+ /* select to page 0 */ 45971+ phy_write(phy_dev, 0x1f, 0); 45972+ 45973+ return 0; 45974+} 45975+ 45976+void higmac_phy_register_fixups(void) 45977+{ 45978+ phy_register_fixup_for_uid(PHY_ID_UNKNOWN, DEFAULT_PHY_MASK, 45979+ unknown_phy_fix); 45980+ phy_register_fixup_for_uid(PHY_ID_KSZ8051MNL, DEFAULT_PHY_MASK, 45981+ ksz8051mnl_phy_fix); 45982+ phy_register_fixup_for_uid(PHY_ID_KSZ8081RNB, DEFAULT_PHY_MASK, 45983+ ksz8081rnb_phy_fix); 45984+ phy_register_fixup_for_uid(REALTEK_PHY_ID_8211E, REALTEK_PHY_MASK, 45985+ rtl8211e_phy_fix); 45986+} 45987+ 45988+void higmac_phy_unregister_fixups(void) 45989+{ 45990+ phy_unregister_fixup_for_uid(PHY_ID_UNKNOWN, DEFAULT_PHY_MASK); 45991+ phy_unregister_fixup_for_uid(PHY_ID_KSZ8051MNL, DEFAULT_PHY_MASK); 45992+ phy_unregister_fixup_for_uid(PHY_ID_KSZ8081RNB, DEFAULT_PHY_MASK); 45993+ phy_unregister_fixup_for_uid(REALTEK_PHY_ID_8211E, REALTEK_PHY_MASK); 45994+} 45995diff --git a/drivers/net/ethernet/hisilicon/higmac/util.h b/drivers/net/ethernet/hisilicon/higmac/util.h 45996new file mode 100644 45997index 000000000..ca1c99bb5 45998--- /dev/null 45999+++ b/drivers/net/ethernet/hisilicon/higmac/util.h 46000@@ -0,0 +1,102 @@ 46001+/* 46002+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 46003+ * Description: Higmac driver util head file 46004+ * Author: KTP_BSP 46005+ * Create: 2018-10-08 46006+ */ 46007+ 46008+#ifndef __HIGMAC_UTIL_H__ 46009+#define __HIGMAC_UTIL_H__ 46010+ 46011+#include "higmac.h" 46012+ 46013+#define HIGMAC_TRACE_LEVEL 10 46014+#define HIGMAC_NORMAL_LEVEL 7 46015+ 46016+#define mk_bits(shift, nbits) ((((shift) & 0x1F) << 16) | ((nbits) & 0x3F)) 46017+ 46018+#define FC_ACTIVE_MIN 1 46019+#define FC_ACTIVE_DEFAULT 16 46020+#define FC_ACTIVE_MAX 127 46021+#define FC_DEACTIVE_MIN 1 46022+#define FC_DEACTIVE_DEFAULT 32 46023+#define FC_DEACTIVE_MAX 127 46024+ 46025+#define FC_PAUSE_TIME_DEFAULT 0xFFFF 46026+#define FC_PAUSE_INTERVAL_DEFAULT 0xFFFF 46027+#define FC_PAUSE_TIME_MAX 0xFFFF 46028+ 46029+#define HW_CAP_EN 0x0c00 46030+#define BIT_RSS_CAP BIT(0) 46031+#define BIT_RXHASH_CAP BIT(1) 46032+#define RSS_HASH_KEY 0x0c04 46033+#define RSS_HASH_CONFIG 0x0c08 46034+#define TCPV4_L3_HASH_EN BIT(0) 46035+#define TCPV4_L4_HASH_EN BIT(1) 46036+#define TCPV4_VLAN_HASH_EN BIT(2) 46037+#define UDPV4_L3_HASH_EN BIT(4) 46038+#define UDPV4_L4_HASH_EN BIT(5) 46039+#define UDPV4_VLAN_HASH_EN BIT(6) 46040+#define IPV4_L3_HASH_EN BIT(8) 46041+#define IPV4_VLAN_HASH_EN BIT(9) 46042+#define TCPV6_L3_HASH_EN BIT(12) 46043+#define TCPV6_L4_HASH_EN BIT(13) 46044+#define TCPV6_VLAN_HASH_EN BIT(14) 46045+#define UDPV6_L3_HASH_EN BIT(16) 46046+#define UDPV6_L4_HASH_EN BIT(17) 46047+#define UDPV6_VLAN_HASH_EN BIT(18) 46048+#define IPV6_L3_HASH_EN BIT(20) 46049+#define IPV6_VLAN_HASH_EN BIT(21) 46050+#define DEF_HASH_CFG 0x377377 46051+ 46052+#define RGMII_SPEED_1000 0x2c 46053+#define RGMII_SPEED_100 0x2f 46054+#define RGMII_SPEED_10 0x2d 46055+#define MII_SPEED_100 0x0f 46056+#define MII_SPEED_10 0x0d 46057+#define RMII_SPEED_100 0x8f 46058+#define RMII_SPEED_10 0x8d 46059+#define GMAC_FULL_DUPLEX BIT(4) 46060+ 46061+void higmac_trace(int level, const char *fmt, ...); 46062+ 46063+void higmac_config_port(struct net_device const *dev, u32 speed, u32 duplex); 46064+int higmac_rx_checksum(struct net_device *dev, struct sk_buff *skb, 46065+ struct higmac_desc const *desc); 46066+void higmac_verify_flow_ctrl_args(void); 46067+void higmac_set_flow_ctrl_args(struct higmac_netdev_local *ld); 46068+ 46069+int higmac_check_hw_capability(struct sk_buff *skb); 46070+int higmac_get_pkt_info(struct higmac_netdev_local *ld, 46071+ struct sk_buff *skb, struct higmac_tso_desc *tx_bq_desc); 46072+ 46073+void higmac_get_drvinfo(struct net_device *net_dev, 46074+ struct ethtool_drvinfo *info); 46075+unsigned int higmac_get_link(struct net_device *net_dev); 46076+int higmac_get_settings(struct net_device *net_dev, struct ethtool_cmd *cmd); 46077+int higmac_set_settings(struct net_device *net_dev, struct ethtool_cmd *cmd); 46078+void higmac_get_pauseparam(struct net_device *net_dev, 46079+ struct ethtool_pauseparam *pause); 46080+int higmac_set_pauseparam(struct net_device *net_dev, 46081+ struct ethtool_pauseparam *pause); 46082+u32 higmac_ethtool_getmsglevel(struct net_device *ndev); 46083+void higmac_ethtool_setmsglevel(struct net_device *ndev, u32 level); 46084+u32 higmac_get_rxfh_key_size(struct net_device *ndev); 46085+u32 higmac_get_rxfh_indir_size(struct net_device *ndev); 46086+int higmac_get_rxfh(struct net_device *ndev, u32 *indir, u8 *hkey, u8 *hfunc); 46087+int higmac_set_rxfh(struct net_device *ndev, const u32 *indir, 46088+ const u8 *hkey, const u8 hfunc); 46089+int higmac_get_rxnfc(struct net_device *ndev, 46090+ struct ethtool_rxnfc *info, u32 *rules); 46091+int higmac_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *info); 46092+ 46093+void higmac_get_rss_key(struct higmac_netdev_local *priv); 46094+void higmac_get_rss(struct higmac_netdev_local *priv); 46095+void higmac_config_hash_policy(struct higmac_netdev_local const *priv); 46096+ 46097+void higmac_set_flow_ctrl_state(struct higmac_netdev_local const *ld, int pause); 46098+void higmac_set_flow_ctrl_params(struct higmac_netdev_local const *ld); 46099+ 46100+void higmac_phy_register_fixups(void); 46101+void higmac_phy_unregister_fixups(void); 46102+#endif 46103diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/Makefile b/drivers/net/ethernet/hisilicon/hisi-femac/Makefile 46104new file mode 100644 46105index 000000000..bfad94751 46106--- /dev/null 46107+++ b/drivers/net/ethernet/hisilicon/hisi-femac/Makefile 46108@@ -0,0 +1,6 @@ 46109+# 46110+# Makefile for the HISILICON Fast Ethernet network device drivers. 46111+# 46112+ 46113+obj-$(CONFIG_HISI_FEMAC) += hisi-femac.o 46114+hisi-femac-objs := hisi_femac.o phy_fix.o util.o 46115diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v115_2c02.h b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v115_2c02.h 46116new file mode 100644 46117index 000000000..6c00c71a0 46118--- /dev/null 46119+++ b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v115_2c02.h 46120@@ -0,0 +1,191 @@ 46121+/* 46122+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 46123+ * Description: Hieth driver festa_s28v115_2c02 phy fixup paramters 46124+ * Author: KTP_BSP 46125+ * Create: 2018-10-08 46126+ */ 46127+ 46128+#ifndef __HIETH_FESTA_S28V115_2C02_H__ 46129+#define __HIETH_FESTA_S28V115_2C02_H__ 46130+ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, 46131+ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, 46132+ 0x3402, 0x2C, 0x3403, 0x02, 0x3404, 0xFD, 46133+ 0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0xF6, 46134+ 0x3408, 0x36, 0x3409, 0x18, 0x340A, 0x26, 46135+ 0x340B, 0x05, 0x340C, 0xC6, 0x340D, 0x01, 46136+ 0x340E, 0xF7, 0x340F, 0x36, 0x3410, 0x18, 46137+ 0x3411, 0xCC, 0x3412, 0x35, 0x3413, 0x9F, 46138+ 0x3414, 0x1A, 0x3415, 0xB3, 0x3416, 0x00, 46139+ 0x3417, 0xD2, 0x3418, 0x27, 0x3419, 0x09, 46140+ 0x341A, 0xFD, 0x341B, 0x00, 0x341C, 0xD2, 46141+ 0x341D, 0x7F, 0x341E, 0x01, 0x341F, 0xBF, 46142+ 0x3420, 0x7F, 0x3421, 0x01, 0x3422, 0xB1, 46143+ 0x3423, 0x39, 0x3424, 0x3C, 0x3425, 0x3C, 46144+ 0x3426, 0x30, 0x3427, 0xF6, 0x3428, 0x30, 46145+ 0x3429, 0x55, 0x342A, 0xC0, 0x342B, 0x07, 46146+ 0x342C, 0x18, 0x342D, 0xFE, 0x342E, 0x30, 46147+ 0x342F, 0x4C, 0x3430, 0x18, 0x3431, 0x3A, 46148+ 0x3432, 0x18, 0x3433, 0xE6, 0x3434, 0x00, 46149+ 0x3435, 0x5C, 0x3436, 0xE7, 0x3437, 0x01, 46150+ 0x3438, 0xC1, 0x3439, 0x07, 0x343A, 0x23, 46151+ 0x343B, 0x04, 0x343C, 0xC6, 0x343D, 0x07, 46152+ 0x343E, 0xE7, 0x343F, 0x01, 0x3440, 0x58, 46153+ 0x3441, 0x58, 0x3442, 0x58, 0x3443, 0x58, 46154+ 0x3444, 0x58, 0x3445, 0xE7, 0x3446, 0x00, 46155+ 0x3447, 0xF6, 0x3448, 0x20, 0x3449, 0x04, 46156+ 0x344A, 0xC4, 0x344B, 0x1F, 0x344C, 0xEA, 46157+ 0x344D, 0x00, 0x344E, 0xF7, 0x344F, 0x20, 46158+ 0x3450, 0x04, 0x3451, 0x38, 0x3452, 0x38, 46159+ 0x3453, 0x39, 0x3454, 0x3C, 0x3455, 0x37, 46160+ 0x3456, 0x36, 0x3457, 0x30, 0x3458, 0x1A, 46161+ 0x3459, 0xEE, 0x345A, 0x00, 0x345B, 0x18, 46162+ 0x345C, 0xE6, 0x345D, 0x00, 0x345E, 0x26, 46163+ 0x345F, 0x1C, 0x3460, 0xF6, 0x3461, 0x00, 46164+ 0x3462, 0x5C, 0x3463, 0xC5, 0x3464, 0x04, 46165+ 0x3465, 0x27, 0x3466, 0x06, 0x3467, 0xCC, 46166+ 0x3468, 0x36, 0x3469, 0x12, 0x346A, 0xBD, 46167+ 0x346B, 0xF0, 0x346C, 0xA5, 0x346D, 0xF6, 46168+ 0x346E, 0x00, 0x346F, 0x47, 0x3470, 0xC4, 46169+ 0x3471, 0xF3, 0x3472, 0xF7, 0x3473, 0x00, 46170+ 0x3474, 0x47, 0x3475, 0xC6, 0x3476, 0x01, 46171+ 0x3477, 0x1A, 0x3478, 0xEE, 0x3479, 0x00, 46172+ 0x347A, 0x20, 0x347B, 0x10, 0x347C, 0x5A, 46173+ 0x347D, 0x26, 0x347E, 0x14, 0x347F, 0xF6, 46174+ 0x3480, 0x00, 0x3481, 0x46, 0x3482, 0x4F, 46175+ 0x3483, 0xC4, 0x3484, 0x0C, 0x3485, 0x83, 46176+ 0x3486, 0x00, 0x3487, 0x08, 0x3488, 0x26, 46177+ 0x3489, 0x05, 0x348A, 0xC6, 0x348B, 0x02, 46178+ 0x348C, 0x18, 0x348D, 0xE7, 0x348E, 0x00, 46179+ 0x348F, 0x5F, 0x3490, 0x38, 0x3491, 0x38, 46180+ 0x3492, 0x39, 0x3493, 0xF6, 0x3494, 0x00, 46181+ 0x3495, 0x5C, 0x3496, 0xC5, 0x3497, 0x04, 46182+ 0x3498, 0x27, 0x3499, 0x06, 0x349A, 0xCC, 46183+ 0x349B, 0x36, 0x349C, 0x08, 0x349D, 0xBD, 46184+ 0x349E, 0xF0, 0x349F, 0xA5, 0x34A0, 0xF6, 46185+ 0x34A1, 0x00, 0x34A2, 0x47, 0x34A3, 0xC4, 46186+ 0x34A4, 0xF3, 0x34A5, 0xCA, 0x34A6, 0x08, 46187+ 0x34A7, 0xF7, 0x34A8, 0x00, 0x34A9, 0x47, 46188+ 0x34AA, 0x18, 0x34AB, 0xFE, 0x34AC, 0x00, 46189+ 0x34AD, 0xB6, 0x34AE, 0x18, 0x34AF, 0xAD, 46190+ 0x34B0, 0x00, 0x34B1, 0xBD, 0x34B2, 0x34, 46191+ 0x34B3, 0x24, 0x34B4, 0xF6, 0x34B5, 0x1E, 46192+ 0x34B6, 0x05, 0x34B7, 0xC5, 0x34B8, 0x02, 46193+ 0x34B9, 0x27, 0x34BA, 0x0A, 0x34BB, 0xF6, 46194+ 0x34BC, 0x1E, 0x34BD, 0x07, 0x34BE, 0xC5, 46195+ 0x34BF, 0x02, 0x34C0, 0x27, 0x34C1, 0x03, 46196+ 0x34C2, 0xBD, 0x34C3, 0xC0, 0x34C4, 0x33, 46197+ 0x34C5, 0xF6, 0x34C6, 0x31, 0x34C7, 0x1F, 46198+ 0x34C8, 0x37, 0x34C9, 0xC6, 0x34CA, 0x52, 46199+ 0x34CB, 0xBD, 0x34CC, 0xDC, 0x34CD, 0x53, 46200+ 0x34CE, 0x31, 0x34CF, 0xF6, 0x34D0, 0x00, 46201+ 0x34D1, 0x41, 0x34D2, 0xC5, 0x34D3, 0x10, 46202+ 0x34D4, 0x26, 0x34D5, 0x04, 0x34D6, 0x13, 46203+ 0x34D7, 0x23, 0x34D8, 0x40, 0x34D9, 0x0D, 46204+ 0x34DA, 0xBD, 0x34DB, 0x93, 0x34DC, 0xCE, 46205+ 0x34DD, 0x1A, 0x34DE, 0xEE, 0x34DF, 0x00, 46206+ 0x34E0, 0x18, 0x34E1, 0x6F, 0x34E2, 0x00, 46207+ 0x34E3, 0xC6, 0x34E4, 0x04, 0x34E5, 0x20, 46208+ 0x34E6, 0xA9, 0x34E7, 0x1A, 0x34E8, 0xEE, 46209+ 0x34E9, 0x00, 0x34EA, 0x18, 0x34EB, 0x6F, 46210+ 0x34EC, 0x00, 0x34ED, 0xC6, 0x34EE, 0x01, 46211+ 0x34EF, 0x20, 0x34F0, 0x9F, 0x34F1, 0x3C, 46212+ 0x34F2, 0x37, 0x34F3, 0x36, 0x34F4, 0x30, 46213+ 0x34F5, 0x1A, 0x34F6, 0xEE, 0x34F7, 0x00, 46214+ 0x34F8, 0x18, 0x34F9, 0xE6, 0x34FA, 0x00, 46215+ 0x34FB, 0x26, 0x34FC, 0x49, 0x34FD, 0xF6, 46216+ 0x34FE, 0x00, 0x34FF, 0x5C, 0x3500, 0xC5, 46217+ 0x3501, 0x04, 0x3502, 0x27, 0x3503, 0x06, 46218+ 0x3504, 0xCC, 0x3505, 0x35, 0x3506, 0xFC, 46219+ 0x3507, 0xBD, 0x3508, 0xF0, 0x3509, 0xA5, 46220+ 0x350A, 0xC6, 0x350B, 0x52, 0x350C, 0xBD, 46221+ 0x350D, 0xDC, 0x350E, 0xF3, 0x350F, 0x5D, 46222+ 0x3510, 0x27, 0x3511, 0x03, 0x3512, 0xBD, 46223+ 0x3513, 0xC0, 0x3514, 0x22, 0x3515, 0xF6, 46224+ 0x3516, 0x00, 0x3517, 0x46, 0x3518, 0xC5, 46225+ 0x3519, 0x0C, 0x351A, 0x26, 0x351B, 0x0A, 46226+ 0x351C, 0x1A, 0x351D, 0xEE, 0x351E, 0x00, 46227+ 0x351F, 0x18, 0x3520, 0x6F, 0x3521, 0x00, 46228+ 0x3522, 0xC6, 0x3523, 0x07, 0x3524, 0x20, 46229+ 0x3525, 0x1D, 0x3526, 0xFC, 0x3527, 0x30, 46230+ 0x3528, 0x0C, 0x3529, 0xBD, 0x352A, 0x93, 46231+ 0x352B, 0x19, 0x352C, 0xBD, 0x352D, 0x9F, 46232+ 0x352E, 0x0B, 0x352F, 0xC6, 0x3530, 0x02, 46233+ 0x3531, 0x37, 0x3532, 0xC6, 0x3533, 0x51, 46234+ 0x3534, 0xBD, 0x3535, 0xDC, 0x3536, 0x53, 46235+ 0x3537, 0x31, 0x3538, 0x7F, 0x3539, 0x02, 46236+ 0x353A, 0x07, 0x353B, 0xC6, 0x353C, 0x02, 46237+ 0x353D, 0x1A, 0x353E, 0xEE, 0x353F, 0x00, 46238+ 0x3540, 0x18, 0x3541, 0xE7, 0x3542, 0x00, 46239+ 0x3543, 0x38, 0x3544, 0x38, 0x3545, 0x39, 46240+ 0x3546, 0xC6, 0x3547, 0x52, 0x3548, 0xBD, 46241+ 0x3549, 0xDC, 0x354A, 0xF3, 0x354B, 0x5D, 46242+ 0x354C, 0x27, 0x354D, 0x03, 0x354E, 0xBD, 46243+ 0x354F, 0xC0, 0x3550, 0x22, 0x3551, 0xF6, 46244+ 0x3552, 0x00, 0x3553, 0x46, 0x3554, 0xC5, 46245+ 0x3555, 0x0C, 0x3556, 0x26, 0x3557, 0x0A, 46246+ 0x3558, 0x1A, 0x3559, 0xEE, 0x355A, 0x00, 46247+ 0x355B, 0x18, 0x355C, 0x6F, 0x355D, 0x00, 46248+ 0x355E, 0xC6, 0x355F, 0x07, 0x3560, 0x20, 46249+ 0x3561, 0xE1, 0x3562, 0xC6, 0x3563, 0x51, 46250+ 0x3564, 0xBD, 0x3565, 0xDC, 0x3566, 0xF3, 46251+ 0x3567, 0x5D, 0x3568, 0x26, 0x3569, 0x04, 46252+ 0x356A, 0xC6, 0x356B, 0x02, 0x356C, 0x20, 46253+ 0x356D, 0xD5, 0x356E, 0xF6, 0x356F, 0x00, 46254+ 0x3570, 0x41, 0x3571, 0xC5, 0x3572, 0x10, 46255+ 0x3573, 0x26, 0x3574, 0x20, 0x3575, 0xF6, 46256+ 0x3576, 0x02, 0x3577, 0x07, 0x3578, 0xC1, 46257+ 0x3579, 0x02, 0x357A, 0x24, 0x357B, 0x19, 46258+ 0x357C, 0x18, 0x357D, 0xFE, 0x357E, 0x02, 46259+ 0x357F, 0x08, 0x3580, 0x18, 0x3581, 0xAD, 46260+ 0x3582, 0x00, 0x3583, 0xF6, 0x3584, 0x02, 46261+ 0x3585, 0x06, 0x3586, 0x27, 0x3587, 0x0D, 46262+ 0x3588, 0xC6, 0x3589, 0x02, 0x358A, 0x37, 46263+ 0x358B, 0xC6, 0x358C, 0x51, 0x358D, 0xBD, 46264+ 0x358E, 0xDC, 0x358F, 0x53, 0x3590, 0x31, 46265+ 0x3591, 0xC6, 0x3592, 0x02, 0x3593, 0x20, 46266+ 0x3594, 0xAE, 0x3595, 0x1A, 0x3596, 0xEE, 46267+ 0x3597, 0x00, 0x3598, 0x18, 0x3599, 0x6F, 46268+ 0x359A, 0x00, 0x359B, 0xC6, 0x359C, 0x03, 46269+ 0x359D, 0x20, 0x359E, 0xA4, 0x359F, 0xF6, 46270+ 0x35A0, 0x01, 0x35A1, 0xBF, 0x35A2, 0xC1, 46271+ 0x35A3, 0x08, 0x35A4, 0x24, 0x35A5, 0x55, 46272+ 0x35A6, 0xBD, 0x35A7, 0xF6, 0x35A8, 0xD3, 46273+ 0x35A9, 0x35, 0x35AA, 0xBA, 0x35AB, 0x35, 46274+ 0x35AC, 0xC2, 0x35AD, 0x35, 0x35AE, 0xCA, 46275+ 0x35AF, 0x35, 0x35B0, 0xD2, 0x35B1, 0x35, 46276+ 0x35B2, 0xDA, 0x35B3, 0x35, 0x35B4, 0xE2, 46277+ 0x35B5, 0x35, 0x35B6, 0xEA, 0x35B7, 0x35, 46278+ 0x35B8, 0xF2, 0x35B9, 0x39, 0x35BA, 0xCC, 46279+ 0x35BB, 0x01, 0x35BC, 0xB1, 0x35BD, 0xBD, 46280+ 0x35BE, 0x34, 0x35BF, 0x54, 0x35C0, 0x20, 46281+ 0x35C1, 0x36, 0x35C2, 0xCC, 0x35C3, 0x01, 46282+ 0x35C4, 0xB1, 0x35C5, 0xBD, 0x35C6, 0xC1, 46283+ 0x35C7, 0x52, 0x35C8, 0x20, 0x35C9, 0x2E, 46284+ 0x35CA, 0xCC, 0x35CB, 0x01, 0x35CC, 0xB1, 46285+ 0x35CD, 0xBD, 0x35CE, 0x34, 0x35CF, 0xF1, 46286+ 0x35D0, 0x20, 0x35D1, 0x26, 0x35D2, 0xCC, 46287+ 0x35D3, 0x01, 0x35D4, 0xB1, 0x35D5, 0xBD, 46288+ 0x35D6, 0xC3, 0x35D7, 0x9A, 0x35D8, 0x20, 46289+ 0x35D9, 0x1E, 0x35DA, 0xCC, 0x35DB, 0x01, 46290+ 0x35DC, 0xB1, 0x35DD, 0xBD, 0x35DE, 0xC4, 46291+ 0x35DF, 0x39, 0x35E0, 0x20, 0x35E1, 0x16, 46292+ 0x35E2, 0xCC, 0x35E3, 0x01, 0x35E4, 0xB1, 46293+ 0x35E5, 0xBD, 0x35E6, 0xC5, 0x35E7, 0x0B, 46294+ 0x35E8, 0x20, 0x35E9, 0x0E, 0x35EA, 0xCC, 46295+ 0x35EB, 0x01, 0x35EC, 0xB1, 0x35ED, 0xBD, 46296+ 0x35EE, 0xC6, 0x35EF, 0x3A, 0x35F0, 0x20, 46297+ 0x35F1, 0x06, 0x35F2, 0xCC, 0x35F3, 0x01, 46298+ 0x35F4, 0xB1, 0x35F5, 0xBD, 0x35F6, 0xC7, 46299+ 0x35F7, 0xC2, 0x35F8, 0xF7, 0x35F9, 0x01, 46300+ 0x35FA, 0xBF, 0x35FB, 0x39, 0x35FC, 0x43, 46301+ 0x35FD, 0x3A, 0x35FE, 0x41, 0x35FF, 0x44, 46302+ 0x3600, 0x54, 0x3601, 0x5F, 0x3602, 0x41, 46303+ 0x3603, 0x54, 0x3604, 0x4E, 0x3605, 0x0A, 46304+ 0x3606, 0x0D, 0x3607, 0x00, 0x3608, 0x43, 46305+ 0x3609, 0x3A, 0x360A, 0x45, 0x360B, 0x6E, 46306+ 0x360C, 0x5F, 0x360D, 0x53, 0x360E, 0x74, 46307+ 0x360F, 0x0A, 0x3610, 0x0D, 0x3611, 0x00, 46308+ 0x3612, 0x43, 0x3613, 0x3A, 0x3614, 0x49, 46309+ 0x3615, 0x0A, 0x3616, 0x0D, 0x3617, 0x00, 46310+ 0x3618, 0x00, 0x3400, 0x01, 0x33f8, 0x01 46311+#endif 46312\ No newline at end of file 46313diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v202_2e01.h b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v202_2e01.h 46314new file mode 100644 46315index 000000000..758d79688 46316--- /dev/null 46317+++ b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v202_2e01.h 46318@@ -0,0 +1,84 @@ 46319+/* 46320+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 46321+ * Description: Hieth driver festa_s28v202_2e01 phy fixup paramters 46322+ * Author: KTP_BSP 46323+ * Create: 2020-05-11 46324+ */ 46325+ 46326+#ifndef __HIETH_FESTA_S28V202_2E01_H__ 46327+#define __HIETH_FESTA_S28V202_2E01_H__ 46328+ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, 46329+ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, 46330+ 0x3402, 0x2E, 0x3403, 0x01, 0x3404, 0xFD, 46331+ 0x3405, 0xFF, 0x3406, 0xF2, 0x3407, 0x4F, 46332+ 0x3408, 0xFD, 0x3409, 0xFF, 0x340A, 0xF0, 46333+ 0x340B, 0xF6, 0x340C, 0x34, 0x340D, 0xD7, 46334+ 0x340E, 0x26, 0x340F, 0x05, 0x3410, 0xC6, 46335+ 0x3411, 0x01, 0x3412, 0xF7, 0x3413, 0x34, 46336+ 0x3414, 0xD7, 0x3415, 0xF6, 0x3416, 0x08, 46337+ 0x3417, 0x00, 0x3418, 0xF7, 0x3419, 0x34, 46338+ 0x341A, 0xD8, 0x341B, 0xC6, 0x341C, 0x01, 46339+ 0x341D, 0xF7, 0x341E, 0x08, 0x341F, 0x00, 46340+ 0x3420, 0x20, 0x3421, 0x0F, 0x3422, 0xCC, 46341+ 0x3423, 0x34, 0x3424, 0x3F, 0x3425, 0x1A, 46342+ 0x3426, 0xB3, 0x3427, 0x00, 0x3428, 0xCC, 46343+ 0x3429, 0x27, 0x342A, 0x03, 0x342B, 0xFD, 46344+ 0x342C, 0x00, 0x342D, 0xCC, 0x342E, 0x78, 46345+ 0x342F, 0x08, 0x3430, 0x00, 0x3431, 0xF6, 46346+ 0x3432, 0x08, 0x3433, 0x00, 0x3434, 0xC1, 46347+ 0x3435, 0x02, 0x3436, 0x26, 0x3437, 0xEA, 46348+ 0x3438, 0xF6, 0x3439, 0x34, 0x343A, 0xD8, 46349+ 0x343B, 0xF7, 0x343C, 0x08, 0x343D, 0x00, 46350+ 0x343E, 0x39, 0x343F, 0xBD, 0x3440, 0xF7, 46351+ 0x3441, 0xFA, 0x3442, 0x08, 0x3443, 0xCC, 46352+ 0x3444, 0x20, 0x3445, 0xA1, 0x3446, 0xED, 46353+ 0x3447, 0x05, 0x3448, 0xC6, 0x3449, 0xA4, 46354+ 0x344A, 0xED, 0x344B, 0x03, 0x344C, 0xBD, 46355+ 0x344D, 0x8B, 0x344E, 0x82, 0x344F, 0xE7, 46356+ 0x3450, 0x07, 0x3451, 0xC0, 0x3452, 0x02, 46357+ 0x3453, 0x27, 0x3454, 0x11, 0x3455, 0x5A, 46358+ 0x3456, 0x27, 0x3457, 0x0E, 0x3458, 0x5A, 46359+ 0x3459, 0x27, 0x345A, 0x39, 0x345B, 0x5A, 46360+ 0x345C, 0x27, 0x345D, 0x36, 0x345E, 0x5A, 46361+ 0x345F, 0x27, 0x3460, 0x51, 0x3461, 0x5A, 46362+ 0x3462, 0x27, 0x3463, 0x4E, 0x3464, 0x20, 46363+ 0x3465, 0x6D, 0x3466, 0x18, 0x3467, 0xFE, 46364+ 0x3468, 0x30, 0x3469, 0x1E, 0x346A, 0xF6, 46365+ 0x346B, 0x30, 0x346C, 0x22, 0x346D, 0x18, 46366+ 0x346E, 0x3A, 0x346F, 0x18, 0x3470, 0xE6, 46367+ 0x3471, 0x00, 0x3472, 0x58, 0x3473, 0x58, 46368+ 0x3474, 0xE7, 0x3475, 0x02, 0x3476, 0x1A, 46369+ 0x3477, 0xEE, 0x3478, 0x05, 0x3479, 0x18, 46370+ 0x347A, 0xE6, 0x347B, 0x00, 0x347C, 0xC4, 46371+ 0x347D, 0x03, 0x347E, 0xEA, 0x347F, 0x02, 46372+ 0x3480, 0x18, 0x3481, 0xE7, 0x3482, 0x00, 46373+ 0x3483, 0x1A, 0x3484, 0xEE, 0x3485, 0x03, 46374+ 0x3486, 0x18, 0x3487, 0xE6, 0x3488, 0x00, 46375+ 0x3489, 0xC4, 0x348A, 0x1F, 0x348B, 0xCA, 46376+ 0x348C, 0xC0, 0x348D, 0x18, 0x348E, 0xE7, 46377+ 0x348F, 0x00, 0x3490, 0xC6, 0x3491, 0x09, 46378+ 0x3492, 0x20, 0x3493, 0x3A, 0x3494, 0x1A, 46379+ 0x3495, 0xEE, 0x3496, 0x05, 0x3497, 0x18, 46380+ 0x3498, 0xE6, 0x3499, 0x00, 0x349A, 0xC4, 46381+ 0x349B, 0x03, 0x349C, 0xCA, 0x349D, 0x54, 46382+ 0x349E, 0x18, 0x349F, 0xE7, 0x34A0, 0x00, 46383+ 0x34A1, 0x1A, 0x34A2, 0xEE, 0x34A3, 0x03, 46384+ 0x34A4, 0x18, 0x34A5, 0xE6, 0x34A6, 0x00, 46385+ 0x34A7, 0xC4, 0x34A8, 0x1F, 0x34A9, 0xCA, 46386+ 0x34AA, 0x20, 0x34AB, 0x18, 0x34AC, 0xE7, 46387+ 0x34AD, 0x00, 0x34AE, 0xC6, 0x34AF, 0x74, 46388+ 0x34B0, 0x20, 0x34B1, 0x1C, 0x34B2, 0x1A, 46389+ 0x34B3, 0xEE, 0x34B4, 0x05, 0x34B5, 0x18, 46390+ 0x34B6, 0xE6, 0x34B7, 0x00, 0x34B8, 0xC4, 46391+ 0x34B9, 0x03, 0x34BA, 0xCA, 0x34BB, 0x48, 46392+ 0x34BC, 0x18, 0x34BD, 0xE7, 0x34BE, 0x00, 46393+ 0x34BF, 0x1A, 0x34C0, 0xEE, 0x34C1, 0x03, 46394+ 0x34C2, 0x18, 0x34C3, 0xE6, 0x34C4, 0x00, 46395+ 0x34C5, 0xC4, 0x34C6, 0x1F, 0x34C7, 0xCA, 46396+ 0x34C8, 0x20, 0x34C9, 0x18, 0x34CA, 0xE7, 46397+ 0x34CB, 0x00, 0x34CC, 0xC6, 0x34CD, 0x52, 46398+ 0x34CE, 0x18, 0x34CF, 0x08, 0x34D0, 0x18, 46399+ 0x34D1, 0xE7, 0x34D2, 0x00, 0x34D3, 0xAE, 46400+ 0x34D4, 0x00, 0x34D5, 0x38, 0x34D6, 0x39, 46401+ 0x34D7, 0x00, 0x3400, 0x01, 0x33f8, 0x01 46402+#endif 46403diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/festa_v272_2723.h b/drivers/net/ethernet/hisilicon/hisi-femac/festa_v272_2723.h 46404new file mode 100644 46405index 000000000..edb9d53bb 46406--- /dev/null 46407+++ b/drivers/net/ethernet/hisilicon/hisi-femac/festa_v272_2723.h 46408@@ -0,0 +1,44 @@ 46409+/* 46410+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 46411+ * Description: Hieth driver festa_v272_2723 phy fixup paramters 46412+ * Author: KTP_BSP 46413+ * Create: 2018-10-08 46414+ */ 46415+ 46416+#ifndef __HIETH_FESTA_V272_2723_H__ 46417+#define __HIETH_FESTA_V272_2723_H__ 46418+ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, 46419+ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, 46420+ 0x3402, 0x27, 0x3403, 0x23, 0x3404, 0xFD, 46421+ 0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0x20, 46422+ 0x3408, 0x00, 0x3409, 0x3C, 0x340A, 0x3C, 46423+ 0x340B, 0x30, 0x340C, 0xF6, 0x340D, 0x00, 46424+ 0x340E, 0x4A, 0x340F, 0xC4, 0x3410, 0x7F, 46425+ 0x3411, 0xE7, 0x3412, 0x01, 0x3413, 0xF6, 46426+ 0x3414, 0x01, 0x3415, 0xBE, 0x3416, 0xC1, 46427+ 0x3417, 0x02, 0x3418, 0x27, 0x3419, 0x0E, 46428+ 0x341A, 0xE6, 0x341B, 0x01, 0x341C, 0xC1, 46429+ 0x341D, 0x14, 0x341E, 0x27, 0x341F, 0x08, 46430+ 0x3420, 0xC1, 0x3421, 0x18, 0x3422, 0x25, 46431+ 0x3423, 0x09, 0x3424, 0xC1, 0x3425, 0x1B, 46432+ 0x3426, 0x22, 0x3427, 0x05, 0x3428, 0xC6, 46433+ 0x3429, 0x5C, 0x342A, 0xF7, 0x342B, 0x20, 46434+ 0x342C, 0xA1, 0x342D, 0xF6, 0x342E, 0x01, 46435+ 0x342F, 0xBF, 0x3430, 0xC1, 0x3431, 0x01, 46436+ 0x3432, 0x26, 0x3433, 0x29, 0x3434, 0xF6, 46437+ 0x3435, 0x30, 0x3436, 0x55, 0x3437, 0xC0, 46438+ 0x3438, 0x05, 0x3439, 0xE7, 0x343A, 0x01, 46439+ 0x343B, 0xC1, 0x343C, 0x13, 0x343D, 0x23, 46440+ 0x343E, 0x04, 0x343F, 0xC6, 0x3440, 0x13, 46441+ 0x3441, 0xE7, 0x3442, 0x01, 0x3443, 0x18, 46442+ 0x3444, 0xFE, 0x3445, 0x30, 0x3446, 0x4C, 46443+ 0x3447, 0x18, 0x3448, 0x3A, 0x3449, 0x18, 46444+ 0x344A, 0xE6, 0x344B, 0x00, 0x344C, 0x58, 46445+ 0x344D, 0x58, 0x344E, 0x58, 0x344F, 0x58, 46446+ 0x3450, 0x58, 0x3451, 0xE7, 0x3452, 0x00, 46447+ 0x3453, 0xF6, 0x3454, 0x20, 0x3455, 0x04, 46448+ 0x3456, 0xC4, 0x3457, 0x1F, 0x3458, 0xEA, 46449+ 0x3459, 0x00, 0x345A, 0xF7, 0x345B, 0x20, 46450+ 0x345C, 0x04, 0x345D, 0x38, 0x345E, 0x38, 46451+ 0x345F, 0x39, 0x3400, 0x01, 0x33f8, 0x01 46452+#endif 46453\ No newline at end of file 46454diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.c b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.c 46455new file mode 100644 46456index 000000000..48815a2d6 46457--- /dev/null 46458+++ b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.c 46459@@ -0,0 +1,1588 @@ 46460+/* 46461+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 46462+ * Description: Hieth driver main process file 46463+ * Author: KTP_BSP 46464+ * Create: 2018-10-08 46465+ */ 46466+ 46467+#include <linux/circ_buf.h> 46468+#include <linux/clk.h> 46469+#include <linux/etherdevice.h> 46470+#include <linux/if_ether.h> 46471+#include <linux/interrupt.h> 46472+#include <linux/module.h> 46473+#include <linux/of_mdio.h> 46474+#include <linux/of_net.h> 46475+#include <linux/platform_device.h> 46476+#include <linux/reset.h> 46477+#include <linux/tcp.h> 46478+#include <net/protocol.h> 46479+ 46480+#include "phy_fix.h" 46481+#include "hisi_femac.h" 46482+#include "util.h" 46483+ 46484+static void hisi_femac_irq_enable(const struct hisi_femac_priv *priv, u32 irqs) 46485+{ 46486+ u32 val; 46487+ 46488+ val = readl(priv->glb_base + GLB_IRQ_ENA); 46489+ writel(val | irqs, priv->glb_base + GLB_IRQ_ENA); 46490+} 46491+ 46492+static void hisi_femac_irq_disable(const struct hisi_femac_priv *priv, u32 irqs) 46493+{ 46494+ u32 val; 46495+ 46496+ val = readl(priv->glb_base + GLB_IRQ_ENA); 46497+ writel(val & (~irqs), priv->glb_base + GLB_IRQ_ENA); 46498+} 46499+ 46500+#ifdef CONFIG_FEPHY_OPT 46501+static u32 highflag = 0; 46502+static u32 lowflag = 0; 46503+static void hisi_femac_trim_phy(struct phy_device *phy_dev, u32 val) 46504+{ 46505+ u32 val1; 46506+ /* 32 pieces of data */ 46507+ int table[32] = {0x11, 0x10, 0x10, 0xf, 0xe, 0xd, 0xd, 0xc, 46508+ 0xb, 0xa, 0xa, 0x9, 0x8, 0x7, 0x7, 0x6, 46509+ 0x5, 0x5, 0x4, 0x3, 0x2, 0x2, 0x1, 0x0, 46510+ 0x3f, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a 46511+ }; 46512+ 46513+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE); 46514+ phy_write(phy_dev, MII_EXPMD, val); 46515+ val &= 0x1f; 46516+ val1 = table[val]; 46517+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE); 46518+ val = (u32)phy_read(phy_dev, MII_EXPMD); 46519+ val = (val1 << 2) | (val & 0x3); /* shift left 2 bits */ 46520+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE); 46521+ phy_write(phy_dev, MII_EXPMD, val); 46522+} 46523+ 46524+static void hisi_femac_trim(const struct net_device *dev) 46525+{ 46526+ struct phy_device *phy_dev = NULL; 46527+ int temp; 46528+ u32 val; 46529+ 46530+ phy_dev = dev->phydev; 46531+ if (phy_dev == NULL) { 46532+ pr_err("get phy device failed \n"); 46533+ return; 46534+ } 46535+ 46536+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE); 46537+ val = (u32)phy_read(phy_dev, MII_EXPMD); 46538+ temp = regval_to_temp(val); 46539+ if ((temp > HIGH_TEMP) && (highflag == 0)) { 46540+ highflag = 1; 46541+ if ((val & 0x1f) > 1) 46542+ val = (val & 0xe0) | ((val & 0x1f) - 1); 46543+ else 46544+ return; 46545+ hisi_femac_trim_phy(phy_dev, val); 46546+ } 46547+ if ((temp < NORMAL_TEMP1) && (highflag == 1)) { 46548+ highflag = 0; 46549+ if ((val & 0x1f) < 0x1f) 46550+ val = (val & 0xe0) | ((val & 0x1f) + 1); 46551+ else 46552+ return; 46553+ hisi_femac_trim_phy(phy_dev, val); 46554+ } 46555+ if ((temp > NORMAL_TEMP2) && (lowflag == 0)) { 46556+ lowflag = 1; 46557+ if ((val & 0x1f) > 1) 46558+ val = (val & 0xe0) | ((val & 0x1f) - 1); 46559+ else 46560+ return; 46561+ hisi_femac_trim_phy(phy_dev, val); 46562+ } 46563+ if ((temp < LOW_TEMP) && (lowflag == 1)) { 46564+ lowflag = 0; 46565+ if ((val & 0x1f) < 0x1f) 46566+ val = (val & 0xe0) | ((val & 0x1f) + 1); 46567+ else 46568+ return; 46569+ hisi_femac_trim_phy(phy_dev, val); 46570+ } 46571+} 46572+ 46573+static void hisi_femac_watchdog(struct work_struct *work) 46574+{ 46575+ struct delayed_work *dwork = to_delayed_work(work); 46576+ struct hisi_femac_priv *priv = container_of(dwork, struct hisi_femac_priv, 46577+ watchdog_queue); 46578+ void __iomem *sys_reg_addr; 46579+ struct net_device *dev = NULL; 46580+ u32 val; 46581+ 46582+ dev = priv->ndev; 46583+ if (dev == NULL) { 46584+ pr_err("get net device failed \n"); 46585+ return; 46586+ } 46587+ 46588+ sys_reg_addr = (void __iomem *)ioremap_nocache(SYS_REG_ADDR, 0x100); 46589+ if (!sys_reg_addr) { 46590+ pr_err("iomap failed \n"); 46591+ return; 46592+ } 46593+ val = readl(sys_reg_addr + MISC_CTRL45); 46594+ if ((val >> 30) != 0x3) { /* bit[30 31] */ 46595+ val |= TSENSOR_EN; 46596+ writel(val, sys_reg_addr + MISC_CTRL45); 46597+ mdelay(10); /* wait 10ms */ 46598+ } 46599+ val = readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT0; 46600+ /* high 16bit */ 46601+ val += (readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT1) >> 16; 46602+ val += readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT2; 46603+ /* high 16bit */ 46604+ val += (readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT3) >> 16; 46605+ val = val / 4; /* average value of the 4 values */ 46606+ if (val < LOW_TEM_VALUE || val > HIGH_TEM_VALUE) { 46607+ goto out; 46608+ } 46609+ hisi_femac_trim(dev); 46610+out: 46611+ iounmap(sys_reg_addr); 46612+ schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER); 46613+} 46614+#endif 46615+ 46616+static void hisi_femac_tx_sg_dma_unmap(const struct hisi_femac_priv *priv, 46617+ const struct sk_buff *skb, unsigned int pos) 46618+{ 46619+ struct tx_desc *desc_cur; 46620+ dma_addr_t addr; 46621+ u32 len; 46622+ int i; 46623+ 46624+ desc_cur = priv->tx_ring.desc + pos; 46625+ 46626+ addr = desc_cur->linear_addr; 46627+ len = desc_cur->linear_len; 46628+ dma_unmap_single(priv->dev, addr, len, DMA_TO_DEVICE); 46629+ 46630+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 46631+ addr = desc_cur->frags[i].addr; 46632+ len = desc_cur->frags[i].size; 46633+ dma_unmap_page(priv->dev, addr, len, DMA_TO_DEVICE); 46634+ } 46635+} 46636+ 46637+static void hisi_femac_tx_dma_unmap(const struct hisi_femac_priv *priv, 46638+ const struct sk_buff *skb, unsigned int pos) 46639+{ 46640+ if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) { 46641+ dma_addr_t dma_addr; 46642+ 46643+ dma_addr = priv->txq.dma_phys[pos]; 46644+ dma_unmap_single(priv->dev, dma_addr, skb->len, DMA_TO_DEVICE); 46645+ } else { 46646+ hisi_femac_tx_sg_dma_unmap(priv, skb, pos); 46647+ } 46648+} 46649+ 46650+static void hisi_femac_xmit_reclaim(struct net_device *dev) 46651+{ 46652+ struct sk_buff *skb = NULL; 46653+ struct hisi_femac_priv *priv = netdev_priv(dev); 46654+ struct hisi_femac_queue *txq = &priv->txq; 46655+ unsigned int bytes_compl = 0; 46656+ unsigned int pkts_compl = 0; 46657+ u32 val; 46658+ 46659+ netif_tx_lock(dev); 46660+ 46661+ val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK; 46662+ while (val < priv->tx_fifo_used_cnt) { 46663+ skb = txq->skb[txq->tail]; 46664+ if (unlikely(skb == NULL)) { 46665+ netdev_err(dev, "xmitq_cnt_inuse=%d, tx_fifo_used=%d\n", 46666+ val, priv->tx_fifo_used_cnt); 46667+ break; 46668+ } 46669+ hisi_femac_tx_dma_unmap(priv, skb, txq->tail); 46670+ pkts_compl++; 46671+ bytes_compl += skb->len; 46672+ dev_kfree_skb_any(skb); 46673+ 46674+ priv->tx_fifo_used_cnt--; 46675+ 46676+ val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK; 46677+ txq->skb[txq->tail] = NULL; 46678+ txq->tail = (txq->tail + 1) % txq->num; 46679+ } 46680+ 46681+ netdev_completed_queue(dev, pkts_compl, bytes_compl); 46682+ 46683+ if (unlikely(netif_queue_stopped(dev)) && pkts_compl) 46684+ netif_wake_queue(dev); 46685+ 46686+ netif_tx_unlock(dev); 46687+} 46688+ 46689+static void hisi_femac_get_tso_err_info(const struct hisi_femac_priv *priv) 46690+{ 46691+ unsigned int reg_addr, reg_tx_info, reg_tx_err; 46692+ unsigned int sg_index; 46693+ struct tx_desc *sg_desc = NULL; 46694+ int *sg_word = NULL; 46695+ int i; 46696+ 46697+ reg_addr = readl(priv->port_base + TSO_DBG_ADDR); 46698+ reg_tx_info = readl(priv->port_base + TSO_DBG_TX_INFO); 46699+ reg_tx_err = readl(priv->port_base + TSO_DBG_TX_ERR); 46700+ 46701+ WARN(1, "tx err=0x%x, tx_info=0x%x, addr=0x%x\n", 46702+ reg_tx_err, reg_tx_info, reg_addr); 46703+ 46704+ sg_index = (reg_addr - priv->tx_ring.dma_phys) / sizeof(struct tx_desc); 46705+ sg_desc = priv->tx_ring.desc + sg_index; 46706+ sg_word = (int *)sg_desc; 46707+ for (i = 0; i < sizeof(struct tx_desc) / sizeof(int); i++) 46708+ pr_err("%s,%d: sg_desc word[%d]=0x%x\n", 46709+ __func__, __LINE__, i, sg_word[i]); 46710+ 46711+ /* restart MAC to transmit next packet */ 46712+ hisi_femac_irq_disable(priv, INT_TX_ERR); 46713+ /* 46714+ * If we need allow netcard transmit packet again. 46715+ * we should readl TSO_DBG_STATE and enable irq. 46716+ */ 46717+} 46718+ 46719+static netdev_tx_t hisi_femac_net_xmit(struct sk_buff *skb, 46720+ struct net_device *dev); 46721+ 46722+static netdev_tx_t hisi_femac_sw_gso(struct sk_buff *skb, 46723+ struct net_device *dev) 46724+{ 46725+ struct sk_buff *segs = NULL; 46726+ struct sk_buff *curr_skb = NULL; 46727+ netdev_features_t features = dev->features; 46728+ 46729+ features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 46730+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO); 46731+ segs = skb_gso_segment(skb, features); 46732+ if (IS_ERR_OR_NULL(segs)) { 46733+ goto drop; 46734+ } 46735+ 46736+ do { 46737+ curr_skb = segs; 46738+ segs = segs->next; 46739+ curr_skb->next = NULL; 46740+ if (hisi_femac_net_xmit(curr_skb, dev)) { 46741+ dev_kfree_skb(curr_skb); 46742+ while (segs != NULL) { 46743+ curr_skb = segs; 46744+ segs = segs->next; 46745+ curr_skb->next = NULL; 46746+ dev_kfree_skb_any(curr_skb); 46747+ } 46748+ goto drop; 46749+ } 46750+ } while (segs != NULL); 46751+ 46752+ dev_kfree_skb_any(skb); 46753+ return NETDEV_TX_OK; 46754+ 46755+drop: 46756+ dev_kfree_skb_any(skb); 46757+ dev->stats.tx_dropped++; 46758+ return NETDEV_TX_OK; 46759+} 46760+ 46761+static int hisi_femac_fill_sg_desc(const struct hisi_femac_priv *priv, 46762+ const struct sk_buff *skb, unsigned int pos) 46763+{ 46764+ struct tx_desc *desc_cur; 46765+ dma_addr_t addr; 46766+ int ret; 46767+ int i; 46768+ 46769+ desc_cur = priv->tx_ring.desc + pos; 46770+ 46771+ desc_cur->ipv6_id = ntohl(skb_shinfo(skb)->ip6_frag_id); 46772+ 46773+ desc_cur->total_len = skb->len; 46774+ addr = dma_map_single(priv->dev, skb->data, skb_headlen(skb), 46775+ DMA_TO_DEVICE); 46776+ if (unlikely(dma_mapping_error(priv->dev, addr))) { 46777+ return -EINVAL; 46778+ } 46779+ desc_cur->linear_addr = addr; 46780+ desc_cur->linear_len = skb_headlen(skb); 46781+ 46782+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 46783+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 46784+ int len = frag->bv_len; 46785+ 46786+ addr = skb_frag_dma_map(priv->dev, frag, 0, len, DMA_TO_DEVICE); 46787+ ret = dma_mapping_error(priv->dev, addr); 46788+ if (unlikely(ret)) { 46789+ return -EINVAL; 46790+ } 46791+ desc_cur->frags[i].addr = addr; 46792+ desc_cur->frags[i].size = len; 46793+ } 46794+ 46795+ return 0; 46796+} 46797+ 46798+static void hisi_femac_adjust_link(struct net_device *dev) 46799+{ 46800+ struct hisi_femac_priv *priv = netdev_priv(dev); 46801+ struct phy_device *phy = dev->phydev; 46802+ u32 status = 0; 46803+ 46804+ if (phy->link) 46805+ status |= MAC_PORTSET_LINKED; 46806+ if (phy->duplex == DUPLEX_FULL) 46807+ status |= MAC_PORTSET_DUPLEX_FULL; 46808+ if (phy->speed == SPEED_100) 46809+ status |= MAC_PORTSET_SPEED_100M; 46810+ 46811+ if ((status != priv->link_status) && 46812+ ((status | priv->link_status) & MAC_PORTSET_LINKED)) { 46813+ writel(status, priv->port_base + MAC_PORTSET); 46814+ priv->link_status = status; 46815+ phy_print_status(phy); 46816+ 46817+ priv->tx_pause_en = phy->pause; 46818+ hisi_femac_set_flow_ctrl(priv); 46819+ } 46820+} 46821+ 46822+static void hisi_femac_rx_refill(struct hisi_femac_priv *priv) 46823+{ 46824+ struct hisi_femac_queue *rxq = &priv->rxq; 46825+ struct sk_buff *skb = NULL; 46826+ u32 pos; 46827+ u32 len; 46828+ dma_addr_t addr; 46829+ u32 alloc_rxbuf_align; 46830+ int reserve_room; 46831+ 46832+ pos = rxq->head; 46833+ while (readl(priv->port_base + ADDRQ_STAT) & BIT_RX_READY) { 46834+ if (!CIRC_SPACE(pos, rxq->tail, rxq->num)) { 46835+ break; 46836+ } 46837+ if (unlikely(rxq->skb[pos])) { 46838+ netdev_err(priv->ndev, "err skb[%d]=%p\n", 46839+ pos, rxq->skb[pos]); 46840+ break; 46841+ } 46842+ len = MAX_FRAME_SIZE + RXBUF_ADDR_ALIGN_SIZE; 46843+ skb = netdev_alloc_skb_ip_align(priv->ndev, len); 46844+ if (unlikely(skb == NULL)) { 46845+ break; 46846+ } 46847+ 46848+ alloc_rxbuf_align = ((uintptr_t)skb->data - NET_IP_ALIGN) & 46849+ (RXBUF_ADDR_ALIGN_SIZE - 1); 46850+ if (alloc_rxbuf_align) { 46851+ reserve_room = RXBUF_ADDR_ALIGN_SIZE - 46852+ alloc_rxbuf_align; 46853+ len -= reserve_room; 46854+ skb_reserve(skb, reserve_room); 46855+ } 46856+ 46857+ addr = dma_map_single(priv->dev, skb->data, len, 46858+ DMA_FROM_DEVICE); 46859+ if (dma_mapping_error(priv->dev, addr)) { 46860+ dev_kfree_skb_any(skb); 46861+ break; 46862+ } 46863+ rxq->dma_phys[pos] = addr; 46864+ rxq->skb[pos] = skb; 46865+ writel(addr, priv->port_base + IQ_ADDR); 46866+ pos = (pos + 1) % rxq->num; 46867+ } 46868+ rxq->head = pos; 46869+} 46870+ 46871+#ifdef FEMAC_RX_REFILL_IN_IRQ 46872+static void hisi_femac_recv_queue(struct net_device *dev, struct sk_buff *skb, 46873+ u32 rx_pkt_info) 46874+{ 46875+ struct hisi_femac_priv *priv = netdev_priv(dev); 46876+ int hdr_csum_done, hdr_csum_err; 46877+ int payload_csum_done, payload_csum_err; 46878+ 46879+ skb->ip_summed = CHECKSUM_NONE; 46880+ if (dev->features & NETIF_F_RXCSUM) { 46881+ hdr_csum_done = 46882+ (rx_pkt_info >> BITS_HEADER_DONE_OFFSET) & 46883+ BITS_HEADER_DONE_MASK; 46884+ payload_csum_done = 46885+ (rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) & 46886+ BITS_PAYLOAD_DONE_MASK; 46887+ hdr_csum_err = 46888+ (rx_pkt_info >> BITS_HEADER_ERR_OFFSET) & 46889+ BITS_HEADER_ERR_MASK; 46890+ payload_csum_err = 46891+ (rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) & 46892+ BITS_PAYLOAD_ERR_MASK; 46893+ 46894+ if (hdr_csum_done && payload_csum_done) { 46895+ if (unlikely(hdr_csum_err)) { 46896+ dev->stats.rx_errors++; 46897+ dev->stats.rx_crc_errors++; 46898+ dev_kfree_skb_any(skb); 46899+ return; 46900+ } else if (!payload_csum_err) { 46901+ skb->ip_summed = CHECKSUM_UNNECESSARY; 46902+ } 46903+ } 46904+ } 46905+ skb_queue_tail(&priv->rx_head, skb); 46906+} 46907+ 46908+static void hisi_femac_pre_receive(struct net_device *dev) 46909+{ 46910+ struct hisi_femac_priv *priv = netdev_priv(dev); 46911+ struct hisi_femac_queue *rxq = &priv->rxq; 46912+ struct sk_buff *skb = NULL; 46913+ u32 rx_pkt_info, pos, len; 46914+ unsigned long rxflags; 46915+ 46916+ spin_lock_irqsave(&priv->rxlock, rxflags); 46917+ pos = rxq->tail; 46918+ while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) { 46919+ rx_pkt_info = readl(priv->port_base + IQFRM_DES); 46920+ len = rx_pkt_info & RX_FRAME_LEN_MASK; 46921+ len -= ETH_FCS_LEN; 46922+ 46923+ /* tell hardware we will deal with this packet */ 46924+ writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW); 46925+ 46926+ skb = rxq->skb[pos]; 46927+ if (unlikely(skb == NULL)) { 46928+ netdev_err(dev, "rx skb NULL. pos=%d\n", pos); 46929+ break; 46930+ } 46931+ rxq->skb[pos] = NULL; 46932+ 46933+ dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE, 46934+ DMA_FROM_DEVICE); 46935+ skb_put(skb, len); 46936+ if (unlikely(skb->len > MAX_FRAME_SIZE)) { 46937+ netdev_err(dev, "rcv len err, len = %d\n", skb->len); 46938+ dev->stats.rx_errors++; 46939+ dev->stats.rx_length_errors++; 46940+ dev_kfree_skb_any(skb); 46941+ goto next; 46942+ } 46943+ 46944+ hisi_femac_recv_queue(dev, skb, rx_pkt_info); 46945+next: 46946+ pos = (pos + 1) % rxq->num; 46947+ } 46948+ rxq->tail = pos; 46949+ 46950+ hisi_femac_rx_refill(priv); 46951+ spin_unlock_irqrestore(&priv->rxlock, rxflags); 46952+} 46953+ 46954+static u32 hisi_femac_rx(struct net_device *dev, int limit) 46955+{ 46956+ struct hisi_femac_priv *priv = netdev_priv(dev); 46957+ struct sk_buff *skb = skb_dequeue(&priv->rx_head); 46958+ u32 rx_pkts_num = 0; 46959+ 46960+ while (skb != NULL) { 46961+ skb->protocol = eth_type_trans(skb, dev); 46962+ napi_gro_receive(&priv->napi, skb); 46963+ dev->stats.rx_packets++; 46964+ dev->stats.rx_bytes += skb->len; 46965+ rx_pkts_num++; 46966+ 46967+ if (rx_pkts_num >= limit) { 46968+ break; 46969+ } 46970+ skb = skb_dequeue(&priv->rx_head); 46971+ } 46972+ 46973+ return rx_pkts_num; 46974+} 46975+#else 46976+static int hisi_femac_recv_queue(struct net_device *dev, struct sk_buff *skb, 46977+ u32 rx_pkt_info) 46978+{ 46979+ struct hisi_femac_priv *priv = netdev_priv(dev); 46980+ int hdr_csum_done, hdr_csum_err; 46981+ int payload_csum_done, payload_csum_err; 46982+ 46983+ skb->ip_summed = CHECKSUM_NONE; 46984+ if (dev->features & NETIF_F_RXCSUM) { 46985+ hdr_csum_done = 46986+ (rx_pkt_info >> BITS_HEADER_DONE_OFFSET) & 46987+ BITS_HEADER_DONE_MASK; 46988+ payload_csum_done = 46989+ (rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) & 46990+ BITS_PAYLOAD_DONE_MASK; 46991+ hdr_csum_err = 46992+ (rx_pkt_info >> BITS_HEADER_ERR_OFFSET) & 46993+ BITS_HEADER_ERR_MASK; 46994+ payload_csum_err = 46995+ (rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) & 46996+ BITS_PAYLOAD_ERR_MASK; 46997+ 46998+ if (hdr_csum_done && payload_csum_done) { 46999+ if (unlikely(hdr_csum_err)) { 47000+ dev->stats.rx_errors++; 47001+ dev->stats.rx_crc_errors++; 47002+ dev_kfree_skb_any(skb); 47003+ return -1; 47004+ } else if (!payload_csum_err) { 47005+ skb->ip_summed = CHECKSUM_UNNECESSARY; 47006+ } 47007+ } 47008+ } 47009+ return 0; 47010+} 47011+ 47012+static u32 hisi_femac_rx(struct net_device *dev, int limit) 47013+{ 47014+ struct hisi_femac_priv *priv = netdev_priv(dev); 47015+ struct hisi_femac_queue *rxq = &priv->rxq; 47016+ struct sk_buff *skb; 47017+ u32 rx_pkt_info, pos, len; 47018+ u32 rx_pkts_num = 0; 47019+ 47020+ pos = rxq->tail; 47021+ while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) { 47022+ rx_pkt_info = readl(priv->port_base + IQFRM_DES); 47023+ len = rx_pkt_info & RX_FRAME_LEN_MASK; 47024+ len -= ETH_FCS_LEN; 47025+ 47026+ /* tell hardware we will deal with this packet */ 47027+ writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW); 47028+ 47029+ rx_pkts_num++; 47030+ 47031+ skb = rxq->skb[pos]; 47032+ if (unlikely(!skb)) { 47033+ netdev_err(dev, "rx skb NULL. pos=%d\n", pos); 47034+ break; 47035+ } 47036+ rxq->skb[pos] = NULL; 47037+ 47038+ dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE, 47039+ DMA_FROM_DEVICE); 47040+ skb_put(skb, len); 47041+ if (unlikely(skb->len > MAX_FRAME_SIZE)) { 47042+ netdev_err(dev, "rcv len err, len = %d\n", skb->len); 47043+ dev->stats.rx_errors++; 47044+ dev->stats.rx_length_errors++; 47045+ dev_kfree_skb_any(skb); 47046+ goto next; 47047+ } 47048+ 47049+ if (hisi_femac_recv_queue(dev, skb, rx_pkt_info) < 0) 47050+ goto next; 47051+ 47052+ skb->protocol = eth_type_trans(skb, dev); 47053+ napi_gro_receive(&priv->napi, skb); 47054+ dev->stats.rx_packets++; 47055+ dev->stats.rx_bytes += len; 47056+next: 47057+ pos = (pos + 1) % rxq->num; 47058+ if (rx_pkts_num >= limit) { 47059+ break; 47060+ } 47061+ } 47062+ rxq->tail = pos; 47063+ 47064+ hisi_femac_rx_refill(priv); 47065+ 47066+ return rx_pkts_num; 47067+} 47068+#endif 47069+ 47070+static int hisi_femac_poll(struct napi_struct *napi, int budget) 47071+{ 47072+ struct hisi_femac_priv *priv = container_of(napi, 47073+ struct hisi_femac_priv, napi); 47074+ struct net_device *dev = priv->ndev; 47075+ int work_done = 0; 47076+ int task = budget; 47077+ u32 ints, num; 47078+ 47079+ do { 47080+#ifdef FEMAC_RX_REFILL_IN_IRQ 47081+ hisi_femac_pre_receive(dev); 47082+#endif 47083+ hisi_femac_xmit_reclaim(dev); 47084+ num = hisi_femac_rx(dev, task); 47085+ work_done += num; 47086+ task -= num; 47087+ if (work_done >= budget) { 47088+ break; 47089+ } 47090+ 47091+ ints = readl(priv->glb_base + GLB_IRQ_RAW); 47092+ writel(ints & DEF_INT_MASK, 47093+ priv->glb_base + GLB_IRQ_RAW); 47094+ } while (ints & DEF_INT_MASK); 47095+ 47096+ if (work_done < budget) { 47097+ napi_complete(napi); 47098+ hisi_femac_irq_enable(priv, DEF_INT_MASK & 47099+ (~IRQ_INT_TX_PER_PACKET)); 47100+ } 47101+ 47102+ return work_done; 47103+} 47104+ 47105+static irqreturn_t hisi_femac_interrupt(int irq, void *dev_id) 47106+{ 47107+ u32 ints; 47108+ struct net_device *dev = (struct net_device *)dev_id; 47109+ struct hisi_femac_priv *priv = netdev_priv(dev); 47110+ 47111+ ints = readl(priv->glb_base + GLB_IRQ_RAW); 47112+ if (likely(ints & DEF_INT_MASK)) { 47113+#ifdef FEMAC_RX_REFILL_IN_IRQ 47114+ hisi_femac_pre_receive(dev); 47115+#endif 47116+ writel(ints & DEF_INT_MASK, 47117+ priv->glb_base + GLB_IRQ_RAW); 47118+ hisi_femac_irq_disable(priv, DEF_INT_MASK); 47119+ napi_schedule(&priv->napi); 47120+ } 47121+ 47122+ if (has_tso_cap(priv->hw_cap) && unlikely(ints & INT_TX_ERR)) 47123+ hisi_femac_get_tso_err_info(priv); 47124+ 47125+ return IRQ_HANDLED; 47126+} 47127+ 47128+static int hisi_femac_init_tx_descriptor_ring(struct hisi_femac_priv *priv) 47129+{ 47130+ priv->tx_ring.desc = (struct tx_desc *)dma_alloc_coherent(priv->dev, 47131+ TXQ_NUM * sizeof(struct tx_desc), &priv->tx_ring.dma_phys, GFP_KERNEL); 47132+ if (!priv->tx_ring.desc) { 47133+ return -ENOMEM; 47134+ } 47135+ 47136+ return 0; 47137+} 47138+ 47139+static void hisi_femac_destroy_tx_descriptor_ring(struct hisi_femac_priv *priv) 47140+{ 47141+ if (priv->tx_ring.desc) 47142+ dma_free_coherent(priv->dev, TXQ_NUM * sizeof(struct tx_desc), 47143+ priv->tx_ring.desc, priv->tx_ring.dma_phys); 47144+ priv->tx_ring.desc = NULL; 47145+} 47146+ 47147+static int hisi_femac_init_queue(struct device *dev, 47148+ struct hisi_femac_queue *queue, unsigned int num) 47149+{ 47150+ queue->skb = devm_kcalloc(dev, num, sizeof(struct sk_buff *), GFP_KERNEL); 47151+ if (queue->skb == NULL) { 47152+ return -ENOMEM; 47153+ } 47154+ 47155+ queue->dma_phys = devm_kcalloc(dev, num, sizeof(dma_addr_t), GFP_KERNEL); 47156+ if (queue->dma_phys == NULL) { 47157+ return -ENOMEM; 47158+ } 47159+ 47160+ queue->num = num; 47161+ queue->head = 0; 47162+ queue->tail = 0; 47163+ 47164+ return 0; 47165+} 47166+ 47167+static int hisi_femac_init_tx_and_rx_queues(struct hisi_femac_priv *priv) 47168+{ 47169+ int ret; 47170+ 47171+ ret = hisi_femac_init_queue(priv->dev, &priv->txq, TXQ_NUM); 47172+ if (ret) { 47173+ return ret; 47174+ } 47175+ 47176+ ret = hisi_femac_init_queue(priv->dev, &priv->rxq, RXQ_NUM); 47177+ if (ret) { 47178+ return ret; 47179+ } 47180+ 47181+ priv->tx_fifo_used_cnt = 0; 47182+ 47183+ return 0; 47184+} 47185+ 47186+static void hisi_femac_free_skb_rings(struct hisi_femac_priv *priv) 47187+{ 47188+ struct hisi_femac_queue *txq = &priv->txq; 47189+ struct hisi_femac_queue *rxq = &priv->rxq; 47190+ struct sk_buff *skb = NULL; 47191+ dma_addr_t dma_addr; 47192+ u32 pos; 47193+ 47194+ pos = rxq->tail; 47195+ while (pos != rxq->head) { 47196+ skb = rxq->skb[pos]; 47197+ if (unlikely(skb == NULL)) { 47198+ netdev_err(priv->ndev, "NULL rx skb. pos=%d, head=%d\n", 47199+ pos, rxq->head); 47200+ pos = (pos + 1) % rxq->num; 47201+ continue; 47202+ } 47203+ 47204+ dma_addr = rxq->dma_phys[pos]; 47205+ dma_unmap_single(priv->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE); 47206+ 47207+ dev_kfree_skb_any(skb); 47208+ rxq->skb[pos] = NULL; 47209+ pos = (pos + 1) % rxq->num; 47210+ } 47211+ rxq->tail = pos; 47212+ 47213+ pos = txq->tail; 47214+ while (pos != txq->head) { 47215+ skb = txq->skb[pos]; 47216+ if (unlikely(skb == NULL)) { 47217+ netdev_err(priv->ndev, "NULL tx skb. pos=%d, head=%d\n", 47218+ pos, txq->head); 47219+ pos = (pos + 1) % txq->num; 47220+ continue; 47221+ } 47222+ hisi_femac_tx_dma_unmap(priv, skb, pos); 47223+ dev_kfree_skb_any(skb); 47224+ txq->skb[pos] = NULL; 47225+ pos = (pos + 1) % txq->num; 47226+ } 47227+ txq->tail = pos; 47228+ priv->tx_fifo_used_cnt = 0; 47229+} 47230+ 47231+static int hisi_femac_set_hw_mac_addr(const struct hisi_femac_priv *priv, 47232+ const unsigned char *mac) 47233+{ 47234+ u32 reg; 47235+ 47236+ reg = mac[1] | (mac[0] << 8); /* mac0 is high 8 bits */ 47237+ writel(reg, priv->glb_base + GLB_HOSTMAC_H16); 47238+ /* addr2 [24 31] addr3 [16 23] addr4 [8 15] addr5 [0 7] */ 47239+ reg = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24); 47240+ writel(reg, priv->glb_base + GLB_HOSTMAC_L32); 47241+ 47242+ return 0; 47243+} 47244+ 47245+static int hisi_femac_port_reset(const struct hisi_femac_priv *priv) 47246+{ 47247+ u32 val; 47248+ 47249+ val = readl(priv->glb_base + GLB_SOFT_RESET); 47250+ val |= SOFT_RESET_ALL; 47251+ writel(val, priv->glb_base + GLB_SOFT_RESET); 47252+ 47253+ usleep_range(500, 800); /* wait 500-800us */ 47254+ 47255+ val &= ~SOFT_RESET_ALL; 47256+ writel(val, priv->glb_base + GLB_SOFT_RESET); 47257+ 47258+ return 0; 47259+} 47260+ 47261+static int hisi_femac_net_open(struct net_device *dev) 47262+{ 47263+ struct hisi_femac_priv *priv = netdev_priv(dev); 47264+ 47265+ hisi_femac_set_hw_mac_addr(priv, dev->dev_addr); 47266+ /* 47267+ * clear interrupts will drop the first packet MAC have received, 47268+ * so do it before refill the rx free skbs. 47269+ */ 47270+ writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW); 47271+ hisi_femac_rx_refill(priv); 47272+ 47273+ netif_carrier_off(dev); 47274+ netdev_reset_queue(dev); 47275+ netif_start_queue(dev); 47276+ napi_enable(&priv->napi); 47277+ 47278+ priv->link_status = 0; 47279+ if (dev->phydev) 47280+ phy_start(dev->phydev); 47281+ 47282+ hisi_femac_irq_enable(priv, IRQ_ENA_ALL | IRQ_ENA_PORT0 | DEF_INT_MASK); 47283+ if (has_tso_cap(priv->hw_cap)) 47284+ hisi_femac_irq_enable(priv, INT_TX_ERR); 47285+ 47286+ return 0; 47287+} 47288+ 47289+static void hisi_femac_port_init(struct hisi_femac_priv *priv); 47290+ 47291+static int hisi_femac_net_close(struct net_device *dev) 47292+{ 47293+ struct hisi_femac_priv *priv = netdev_priv(dev); 47294+ 47295+ hisi_femac_irq_disable(priv, IRQ_ENA_PORT0); 47296+ 47297+ if (dev->phydev) 47298+ phy_stop(dev->phydev); 47299+ 47300+ netif_stop_queue(dev); 47301+ napi_disable(&priv->napi); 47302+ 47303+ /* 47304+ * reset MAC port first before free skb rings 47305+ * to prevent potential risk of use-after-free. 47306+ */ 47307+ hisi_femac_port_reset(priv); 47308+ hisi_femac_port_init(priv); 47309+ 47310+ priv->tx_pause_en = false; 47311+ hisi_femac_set_flow_ctrl(priv); 47312+ hisi_femac_free_skb_rings(priv); 47313+#ifdef FEMAC_RX_REFILL_IN_IRQ 47314+ skb_queue_purge(&priv->rx_head); 47315+#endif 47316+ 47317+ return 0; 47318+} 47319+ 47320+static bool hisi_femac_net_isready(struct net_device *dev) 47321+{ 47322+ struct hisi_femac_priv *priv = netdev_priv(dev); 47323+ struct hisi_femac_queue *txq = &priv->txq; 47324+ u32 val; 47325+ 47326+ val = readl(priv->port_base + ADDRQ_STAT); 47327+ val &= BIT_TX_READY; 47328+ if (!val) { 47329+ hisi_femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET); 47330+ dev->stats.tx_dropped++; 47331+ dev->stats.tx_fifo_errors++; 47332+ netif_stop_queue(dev); 47333+ return false; 47334+ } 47335+ 47336+ if (unlikely(!CIRC_SPACE(txq->head, txq->tail, 47337+ txq->num))) { 47338+ hisi_femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET); 47339+ dev->stats.tx_dropped++; 47340+ dev->stats.tx_fifo_errors++; 47341+ netif_stop_queue(dev); 47342+ return false; 47343+ } 47344+ 47345+ return true; 47346+} 47347+ 47348+static netdev_tx_t hisi_femac_net_xmit(struct sk_buff *skb, 47349+ struct net_device *dev) 47350+{ 47351+ struct hisi_femac_priv *priv = netdev_priv(dev); 47352+ struct hisi_femac_queue *txq = &priv->txq; 47353+ dma_addr_t addr; 47354+ int ret; 47355+ u32 pkt_info; 47356+ 47357+ if (!hisi_femac_net_isready(dev)) 47358+ return NETDEV_TX_BUSY; 47359+ 47360+ ret = hisi_femac_check_hw_capability(skb); 47361+ if (unlikely(ret)) { 47362+ if (ret == -ENOTSUPP) 47363+ return hisi_femac_sw_gso(skb, dev); 47364+ 47365+ dev_kfree_skb_any(skb); 47366+ dev->stats.tx_dropped++; 47367+ return NETDEV_TX_OK; 47368+ } 47369+ 47370+ pkt_info = hisi_femac_get_pkt_info(skb); 47371+ 47372+ if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) { 47373+ addr = dma_map_single(priv->dev, skb->data, 47374+ skb->len, DMA_TO_DEVICE); 47375+ if (unlikely(dma_mapping_error(priv->dev, addr))) { 47376+ dev_kfree_skb_any(skb); 47377+ dev->stats.tx_dropped++; 47378+ return NETDEV_TX_OK; 47379+ } 47380+ } else { 47381+ ret = hisi_femac_fill_sg_desc(priv, skb, txq->head); 47382+ if (unlikely(ret)) { 47383+ dev_kfree_skb_any(skb); 47384+ dev->stats.tx_dropped++; 47385+ return NETDEV_TX_OK; 47386+ } 47387+ 47388+ addr = priv->tx_ring.dma_phys + 47389+ txq->head * sizeof(struct tx_desc); 47390+ 47391+ /* Ensure desc info writen to memory before config hardware */ 47392+ wmb(); 47393+ } 47394+ txq->dma_phys[txq->head] = addr; 47395+ 47396+ skb_tx_timestamp(skb); 47397+ 47398+ txq->skb[txq->head] = skb; 47399+ txq->head = (txq->head + 1) % txq->num; 47400+ 47401+ writel(addr, priv->port_base + EQ_ADDR); 47402+ writel(pkt_info, priv->port_base + EQFRM_LEN); 47403+ 47404+ priv->tx_fifo_used_cnt++; 47405+ 47406+ dev->stats.tx_packets++; 47407+ dev->stats.tx_bytes += skb->len; 47408+ netdev_sent_queue(dev, skb->len); 47409+ 47410+ return NETDEV_TX_OK; 47411+} 47412+ 47413+static int hisi_femac_set_mac_address(struct net_device *dev, void *p) 47414+{ 47415+ struct hisi_femac_priv *priv = netdev_priv(dev); 47416+ struct sockaddr *skaddr = p; 47417+ 47418+ if (!is_valid_ether_addr(skaddr->sa_data)) { 47419+ return -EADDRNOTAVAIL; 47420+ } 47421+ 47422+ memcpy(dev->dev_addr, skaddr->sa_data, dev->addr_len); 47423+ dev->addr_assign_type &= ~NET_ADDR_RANDOM; 47424+ 47425+ hisi_femac_set_hw_mac_addr(priv, dev->dev_addr); 47426+ 47427+ return 0; 47428+} 47429+ 47430+static void hisi_femac_enable_hw_addr_filter(const struct hisi_femac_priv *priv, 47431+ unsigned int reg_n, bool enable) 47432+{ 47433+ u32 val; 47434+ 47435+ val = readl(priv->glb_base + glb_mac_h16(reg_n)); 47436+ if (enable) { 47437+ val |= BIT_MACFLT_ENA; 47438+ } else { 47439+ val &= ~BIT_MACFLT_ENA; 47440+ } 47441+ writel(val, priv->glb_base + glb_mac_h16(reg_n)); 47442+} 47443+ 47444+static void hisi_femac_set_hw_addr_filter(const struct hisi_femac_priv *priv, 47445+ const unsigned char *addr, unsigned int reg_n) 47446+{ 47447+ unsigned int high, low; 47448+ u32 val; 47449+ 47450+ high = glb_mac_h16(reg_n); 47451+ low = glb_mac_l32(reg_n); 47452+ /* addr2 [24 31] addr3 [16 23] addr4 [8 15] addr5 [0 7] */ 47453+ val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; 47454+ writel(val, priv->glb_base + low); 47455+ 47456+ val = readl(priv->glb_base + high); 47457+ val &= ~MACFLT_HI16_MASK; 47458+ val |= ((addr[0] << 8) | addr[1]); /* addr0 is high 8 bits */ 47459+ val |= (BIT_MACFLT_ENA | BIT_MACFLT_FW2CPU); 47460+ writel(val, priv->glb_base + high); 47461+} 47462+ 47463+static void hisi_femac_set_promisc_mode(const struct hisi_femac_priv *priv, 47464+ bool promisc_mode) 47465+{ 47466+ u32 val; 47467+ 47468+ val = readl(priv->glb_base + GLB_FWCTRL); 47469+ if (promisc_mode) { 47470+ val |= FWCTRL_FWALL2CPU; 47471+ } else { 47472+ val &= ~FWCTRL_FWALL2CPU; 47473+ } 47474+ writel(val, priv->glb_base + GLB_FWCTRL); 47475+} 47476+ 47477+/* Handle multiple multicast addresses (perfect filtering) */ 47478+static void hisi_femac_set_mc_addr_filter(const struct hisi_femac_priv *priv) 47479+{ 47480+ struct net_device *dev = priv->ndev; 47481+ u32 val; 47482+ 47483+ val = readl(priv->glb_base + GLB_MACTCTRL); 47484+ if ((netdev_mc_count(dev) > MAX_MULTICAST_ADDRESSES) || 47485+ (dev->flags & IFF_ALLMULTI)) { 47486+ val |= MACTCTRL_MULTI2CPU; 47487+ } else { 47488+ int reg = MAX_UNICAST_ADDRESSES; 47489+ int i; 47490+ struct netdev_hw_addr *ha = NULL; 47491+ 47492+ for (i = reg; i < MAX_MAC_FILTER_NUM; i++) 47493+ hisi_femac_enable_hw_addr_filter(priv, i, false); 47494+ 47495+ netdev_for_each_mc_addr(ha, dev) { 47496+ hisi_femac_set_hw_addr_filter(priv, ha->addr, reg); 47497+ reg++; 47498+ } 47499+ val &= ~MACTCTRL_MULTI2CPU; 47500+ } 47501+ writel(val, priv->glb_base + GLB_MACTCTRL); 47502+} 47503+ 47504+/* Handle multiple unicast addresses (perfect filtering) */ 47505+static void hisi_femac_set_uc_addr_filter(const struct hisi_femac_priv *priv) 47506+{ 47507+ struct net_device *dev = priv->ndev; 47508+ u32 val; 47509+ 47510+ val = readl(priv->glb_base + GLB_MACTCTRL); 47511+ if (netdev_uc_count(dev) > MAX_UNICAST_ADDRESSES) { 47512+ val |= MACTCTRL_UNI2CPU; 47513+ } else { 47514+ int reg = 0; 47515+ int i; 47516+ struct netdev_hw_addr *ha = NULL; 47517+ 47518+ for (i = reg; i < MAX_UNICAST_ADDRESSES; i++) 47519+ hisi_femac_enable_hw_addr_filter(priv, i, false); 47520+ 47521+ netdev_for_each_uc_addr(ha, dev) { 47522+ hisi_femac_set_hw_addr_filter(priv, ha->addr, reg); 47523+ reg++; 47524+ } 47525+ val &= ~MACTCTRL_UNI2CPU; 47526+ } 47527+ writel(val, priv->glb_base + GLB_MACTCTRL); 47528+} 47529+ 47530+static void hisi_femac_net_set_rx_mode(struct net_device *dev) 47531+{ 47532+ struct hisi_femac_priv *priv = netdev_priv(dev); 47533+ 47534+ if (dev->flags & IFF_PROMISC) { 47535+ hisi_femac_set_promisc_mode(priv, true); 47536+ } else { 47537+ hisi_femac_set_promisc_mode(priv, false); 47538+ hisi_femac_set_mc_addr_filter(priv); 47539+ hisi_femac_set_uc_addr_filter(priv); 47540+ } 47541+} 47542+ 47543+static int hisi_femac_net_ioctl(struct net_device *dev, 47544+ struct ifreq *ifreq, int cmd) 47545+{ 47546+ if (!netif_running(dev)) { 47547+ return -EINVAL; 47548+ } 47549+ 47550+ if (!dev->phydev) { 47551+ return -EINVAL; 47552+ } 47553+ 47554+ return phy_mii_ioctl(dev->phydev, ifreq, cmd); 47555+} 47556+ 47557+static const struct ethtool_ops hisi_femac_ethtools_ops = { 47558+ .get_link = ethtool_op_get_link, 47559+ .get_link_ksettings = phy_ethtool_get_link_ksettings, 47560+ .set_link_ksettings = phy_ethtool_set_link_ksettings, 47561+ .get_pauseparam = hisi_femac_get_pauseparam, 47562+ .set_pauseparam = hisi_femac_set_pauseparam, 47563+ .get_ts_info = ethtool_op_get_ts_info, 47564+}; 47565+ 47566+static const struct net_device_ops hisi_femac_netdev_ops = { 47567+ .ndo_open = hisi_femac_net_open, 47568+ .ndo_stop = hisi_femac_net_close, 47569+ .ndo_start_xmit = hisi_femac_net_xmit, 47570+ .ndo_do_ioctl = hisi_femac_net_ioctl, 47571+ .ndo_set_mac_address = hisi_femac_set_mac_address, 47572+ .ndo_set_rx_mode = hisi_femac_net_set_rx_mode, 47573+ .ndo_set_features = hisi_femac_set_features, 47574+}; 47575+ 47576+static void hisi_femac_verify_flow_ctrl_args(struct hisi_femac_priv *priv) 47577+{ 47578+ if (priv->tx_pause_active_thresh < FC_ACTIVE_MIN || 47579+ priv->tx_pause_active_thresh > FC_ACTIVE_MAX) 47580+ priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT; 47581+ 47582+ if (priv->tx_pause_deactive_thresh < FC_DEACTIVE_MIN || 47583+ priv->tx_pause_deactive_thresh > FC_DEACTIVE_MAX) 47584+ priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT; 47585+ 47586+ if (priv->tx_pause_active_thresh >= priv->tx_pause_deactive_thresh) { 47587+ priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT; 47588+ priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT; 47589+ } 47590+} 47591+ 47592+static void hisi_femac_core_reset(const struct hisi_femac_priv *priv) 47593+{ 47594+ reset_control_assert(priv->mac_rst); 47595+ reset_control_deassert(priv->mac_rst); 47596+} 47597+ 47598+static void hisi_femac_phy_reset(const struct hisi_femac_priv *priv) 47599+{ 47600+ /* 47601+ * To make sure PHY hardware reset success, 47602+ * we must keep PHY in deassert state first and 47603+ * then complete the hardware reset operation 47604+ */ 47605+ reset_control_deassert(priv->phy_rst); 47606+ hisi_femac_sleep_us(priv->phy_reset_delays[PRE_DELAY]); 47607+ 47608+ reset_control_assert(priv->phy_rst); 47609+ /* 47610+ * delay some time to ensure reset ok, 47611+ * this depends on PHY hardware feature 47612+ */ 47613+ hisi_femac_sleep_us(priv->phy_reset_delays[PULSE]); 47614+ reset_control_deassert(priv->phy_rst); 47615+ /* delay some time to ensure later MDIO access */ 47616+ hisi_femac_sleep_us(priv->phy_reset_delays[POST_DELAY]); 47617+} 47618+ 47619+static void hisi_femac_port_init(struct hisi_femac_priv *priv) 47620+{ 47621+ u32 val; 47622+ 47623+ /* MAC gets link status info and phy mode by software config */ 47624+ val = MAC_PORTSEL_STAT_CPU; 47625+ if (priv->ndev->phydev->interface == PHY_INTERFACE_MODE_RMII) 47626+ val |= MAC_PORTSEL_RMII; 47627+ writel(val, priv->port_base + MAC_PORTSEL); 47628+ 47629+ /* clear all interrupt status */ 47630+ writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW); 47631+ hisi_femac_irq_disable(priv, IRQ_ENA_PORT0_MASK | IRQ_ENA_PORT0); 47632+ 47633+ if (has_tso_cap(priv->hw_cap)) { 47634+ /* enable TSO debug for error handle */ 47635+ val = readl(priv->port_base + TSO_DBG_EN); 47636+ val |= BITS_TSO_DBG_EN; 47637+ writel(val, priv->port_base + TSO_DBG_EN); 47638+ } 47639+ 47640+ val = readl(priv->glb_base + GLB_FWCTRL); 47641+ val &= ~(FWCTRL_VLAN_ENABLE | FWCTRL_FWALL2CPU); 47642+ val |= FWCTRL_FW2CPU_ENA; 47643+ writel(val, priv->glb_base + GLB_FWCTRL); 47644+ 47645+ val = readl(priv->glb_base + GLB_MACTCTRL); 47646+ val |= (MACTCTRL_BROAD2CPU | MACTCTRL_MACT_ENA); 47647+ writel(val, priv->glb_base + GLB_MACTCTRL); 47648+ 47649+ val = readl(priv->port_base + MAC_SET); 47650+ val &= ~MAX_FRAME_SIZE_MASK; 47651+ val |= MAX_FRAME_SIZE; 47652+ writel(val, priv->port_base + MAC_SET); 47653+ 47654+ val = RX_COALESCED_TIMER | 47655+ (RX_COALESCED_FRAMES << RX_COALESCED_FRAME_OFFSET); 47656+ writel(val, priv->port_base + RX_COALESCE_SET); 47657+ 47658+ val = (HW_RX_FIFO_DEPTH << RX_DEPTH_OFFSET) | HW_TX_FIFO_DEPTH; 47659+ writel(val, priv->port_base + QLEN_SET); 47660+ 47661+ hisi_femac_set_flow_ctrl(priv); 47662+} 47663+ 47664+static int hisi_femac_drv_res(struct platform_device *pdev, 47665+ struct hisi_femac_priv *priv) 47666+{ 47667+ struct resource *res = NULL; 47668+ struct device *dev = &pdev->dev; 47669+ struct device_node *node = dev->of_node; 47670+ int ret; 47671+ 47672+ if (of_device_is_compatible(node, "hisilicon,hisi-femac-v2")) 47673+ priv->hw_cap |= HW_CAP_TSO | HW_CAP_RXCSUM; 47674+ 47675+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 47676+ priv->port_base = devm_ioremap_resource(dev, res); 47677+ if (IS_ERR(priv->port_base)) { 47678+ ret = PTR_ERR(priv->port_base); 47679+ return ret; 47680+ } 47681+ 47682+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 47683+ priv->glb_base = devm_ioremap_resource(dev, res); 47684+ if (IS_ERR(priv->glb_base)) { 47685+ ret = PTR_ERR(priv->glb_base); 47686+ return ret; 47687+ } 47688+ 47689+ priv->clk = devm_clk_get(&pdev->dev, NULL); 47690+ if (IS_ERR(priv->clk)) { 47691+ dev_err(dev, "failed to get clk\n"); 47692+ ret = -ENODEV; 47693+ return ret; 47694+ } 47695+ 47696+ ret = clk_prepare_enable(priv->clk); 47697+ if (ret) { 47698+ dev_err(dev, "failed to enable clk %d\n", ret); 47699+ return ret; 47700+ } 47701+ return 0; 47702+} 47703+ 47704+static int hisi_femac_drv_mac(struct platform_device *pdev, 47705+ struct hisi_femac_priv *priv) 47706+{ 47707+ struct device *dev = &pdev->dev; 47708+ struct device_node *node = dev->of_node; 47709+ const char *mac_addr = NULL; 47710+ struct net_device *ndev = priv->ndev; 47711+ 47712+ priv->mac_rst = devm_reset_control_get(dev, "mac"); 47713+ if (IS_ERR(priv->mac_rst)) 47714+ return PTR_ERR(priv->mac_rst); 47715+ 47716+ hisi_femac_core_reset(priv); 47717+ 47718+ mac_addr = of_get_mac_address(node); 47719+ if (!IS_ERR(mac_addr)) 47720+ ether_addr_copy(ndev->dev_addr, mac_addr); 47721+ if (!is_valid_ether_addr(ndev->dev_addr)) { 47722+ eth_hw_addr_random(ndev); 47723+ dev_warn(dev, "using random MAC address %pM\n", 47724+ ndev->dev_addr); 47725+ } 47726+ return 0; 47727+} 47728+ 47729+static struct phy_device *hisi_femac_drv_phy(struct platform_device *pdev, 47730+ struct hisi_femac_priv *priv, int *ret) 47731+{ 47732+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 47733+ __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; 47734+ __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising) = { 0, }; 47735+ struct device *dev = &pdev->dev; 47736+ struct device_node *node = dev->of_node; 47737+ struct phy_device *phy = NULL; 47738+ 47739+ priv->phy_rst = devm_reset_control_get(dev, "phy"); 47740+ if (IS_ERR(priv->phy_rst)) { 47741+ priv->phy_rst = NULL; 47742+ } else { 47743+ *ret = of_property_read_u32_array(node, PHY_RESET_DELAYS_PROPERTY, 47744+ priv->phy_reset_delays, DELAYS_NUM); 47745+ if (*ret) 47746+ return phy; 47747+ hisi_femac_phy_reset(priv); 47748+ } 47749+ 47750+ phy_register_fixups(); 47751+ 47752+ phy = of_phy_get_and_connect(priv->ndev, node, hisi_femac_adjust_link); 47753+ if (phy == NULL) { 47754+ /* check if a fixed-link is defined in device-tree */ 47755+ if (of_phy_is_fixed_link(node)) { 47756+ *ret = of_phy_register_fixed_link(node); 47757+ if (*ret < 0) { 47758+ dev_err(dev, "cannot regitster fixed link phy %d \n", *ret); 47759+ return phy; 47760+ } 47761+ /* 47762+ * In case of a fixed link phy, the DT node associated 47763+ * to the phy is the Ethernet MAC DT node. 47764+ */ 47765+ phy_interface_t iface = PHY_INTERFACE_MODE_NA; 47766+ of_get_phy_mode(node, &iface); 47767+ phy = of_phy_connect(priv->ndev, of_node_get(node), &hisi_femac_adjust_link, 0, 47768+ iface); 47769+ if (phy == NULL) { 47770+ dev_err(dev, "fixed_link didnot connect successfully.\n"); 47771+ return phy; 47772+ } 47773+ } else { 47774+ dev_err(dev, "connect to PHY failed!\n"); 47775+ *ret = -ENODEV; 47776+ return phy; 47777+ } 47778+ } 47779+ 47780+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising); 47781+ linkmode_or(phy->advertising, phy->advertising, advertising); 47782+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, supported); 47783+ linkmode_or(phy->supported, phy->supported, supported); 47784+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mask); 47785+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, mask); 47786+ linkmode_andnot(phy->advertising, phy->advertising, mask); 47787+ 47788+ phy_attached_print(phy, "phy_id=0x%.8lx, phy_mode=%s\n", 47789+ (unsigned long)phy->phy_id, phy_modes(phy->interface)); 47790+ 47791+ return phy; 47792+} 47793+ 47794+static void hisi_femac_drv_napi(struct platform_device *pdev, 47795+ struct hisi_femac_priv *priv) 47796+{ 47797+ struct net_device *ndev = priv->ndev; 47798+ 47799+ ndev->watchdog_timeo = 6 * HZ; /* 6HZ */ 47800+ ndev->priv_flags |= IFF_UNICAST_FLT; 47801+ ndev->netdev_ops = &hisi_femac_netdev_ops; 47802+ ndev->ethtool_ops = &hisi_femac_ethtools_ops; 47803+ netif_napi_add(ndev, &priv->napi, hisi_femac_poll, FEMAC_POLL_WEIGHT); 47804+ 47805+#ifdef CONFIG_FEPHY_OPT 47806+ INIT_DELAYED_WORK(&priv->watchdog_queue, hisi_femac_watchdog); 47807+ schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER); 47808+#endif 47809+ 47810+ if (has_tso_cap(priv->hw_cap)) 47811+ ndev->hw_features |= NETIF_F_SG | 47812+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 47813+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO; 47814+ 47815+ if (has_rxcsum_cap(priv->hw_cap)) 47816+ ndev->hw_features |= NETIF_F_RXCSUM; 47817+ ndev->features |= ndev->hw_features; 47818+ ndev->vlan_features |= ndev->features; 47819+ 47820+ device_set_wakeup_capable(priv->dev, true); 47821+ device_set_wakeup_enable(priv->dev, true); 47822+ 47823+ priv->tx_pause_en = true; 47824+ priv->tx_pause_active_thresh = TX_FLOW_CTRL_ACTIVE_THRESHOLD; 47825+ priv->tx_pause_deactive_thresh = TX_FLOW_CTRL_DEACTIVE_THRESHOLD; 47826+ 47827+ hisi_femac_verify_flow_ctrl_args(priv); 47828+ 47829+ hisi_femac_port_init(priv); 47830+ 47831+ if (has_rxcsum_cap(priv->hw_cap)) 47832+ hisi_femac_enable_rxcsum_drop(priv, true); 47833+} 47834+ 47835+static int hisi_femac_drv_queues(struct platform_device *pdev, 47836+ struct hisi_femac_priv *priv) 47837+{ 47838+ int ret; 47839+ 47840+#ifdef FEMAC_RX_REFILL_IN_IRQ 47841+ skb_queue_head_init(&priv->rx_head); 47842+ spin_lock_init(&priv->rxlock); 47843+#endif 47844+ ret = hisi_femac_init_tx_and_rx_queues(priv); 47845+ if (ret) 47846+ return ret; 47847+ 47848+ if (has_tso_cap(priv->hw_cap)) { 47849+ ret = hisi_femac_init_tx_descriptor_ring(priv); 47850+ if (ret) 47851+ return ret; 47852+ } 47853+ return 0; 47854+} 47855+ 47856+static int hisi_femac_drv_register(struct platform_device *pdev, 47857+ struct hisi_femac_priv *priv) 47858+{ 47859+ struct device *dev = &pdev->dev; 47860+ struct net_device *ndev = priv->ndev; 47861+ int ret; 47862+ 47863+ ndev->irq = platform_get_irq(pdev, 0); 47864+ if (ndev->irq <= 0) { 47865+ dev_err(dev, "No irq resource\n"); 47866+ ret = -ENODEV; 47867+ return ret; 47868+ } 47869+ 47870+ ret = devm_request_irq(dev, ndev->irq, hisi_femac_interrupt, 47871+ IRQF_SHARED, pdev->name, ndev); 47872+ if (ret) { 47873+ dev_err(dev, "devm_request_irq %d failed!\n", ndev->irq); 47874+ return ret; 47875+ } 47876+ 47877+ ret = register_netdev(ndev); 47878+ if (ret) { 47879+ dev_err(dev, "register_netdev failed!\n"); 47880+ return ret; 47881+ } 47882+ return 0; 47883+} 47884+ 47885+static int hisi_femac_drv_probe(struct platform_device *pdev) 47886+{ 47887+ struct device *dev = &pdev->dev; 47888+ struct net_device *ndev = NULL; 47889+ struct hisi_femac_priv *priv = NULL; 47890+ struct phy_device *phy = NULL; 47891+ int ret; 47892+ 47893+ ndev = alloc_etherdev(sizeof(*priv)); 47894+ if (ndev == NULL) 47895+ return -ENOMEM; 47896+ 47897+ platform_set_drvdata(pdev, ndev); 47898+ SET_NETDEV_DEV(ndev, &pdev->dev); 47899+ 47900+ priv = netdev_priv(ndev); 47901+ priv->dev = dev; 47902+ priv->ndev = ndev; 47903+ 47904+ ret = hisi_femac_drv_res(pdev, priv); 47905+ if (ret) 47906+ goto out_free_netdev; 47907+ 47908+ ret = hisi_femac_drv_mac(pdev, priv); 47909+ if (ret) 47910+ goto out_disable_clk; 47911+ 47912+ phy = hisi_femac_drv_phy(pdev, priv, &ret); 47913+ if (phy == NULL) 47914+ goto out_disable_clk; 47915+ 47916+ hisi_femac_drv_napi(pdev, priv); 47917+ 47918+ ret = hisi_femac_drv_queues(pdev, priv); 47919+ if (ret) 47920+ goto out_disconnect_phy; 47921+ 47922+ ret = hisi_femac_drv_register(pdev, priv); 47923+ if (ret) 47924+ goto out_destroy_descriptor; 47925+ 47926+ return ret; 47927+ 47928+out_destroy_descriptor: 47929+ if (has_tso_cap(priv->hw_cap)) 47930+ hisi_femac_destroy_tx_descriptor_ring(priv); 47931+out_disconnect_phy: 47932+ netif_napi_del(&priv->napi); 47933+ phy_disconnect(phy); 47934+out_disable_clk: 47935+ clk_disable_unprepare(priv->clk); 47936+out_free_netdev: 47937+ free_netdev(ndev); 47938+ 47939+ return ret; 47940+} 47941+ 47942+static int hisi_femac_drv_remove(struct platform_device *pdev) 47943+{ 47944+ struct net_device *ndev = platform_get_drvdata(pdev); 47945+ struct hisi_femac_priv *priv = netdev_priv(ndev); 47946+ 47947+ netif_napi_del(&priv->napi); 47948+ unregister_netdev(ndev); 47949+ if (has_tso_cap(priv->hw_cap)) 47950+ hisi_femac_destroy_tx_descriptor_ring(priv); 47951+ 47952+ phy_disconnect(ndev->phydev); 47953+#ifdef CONFIG_FEPHY_OPT 47954+ cancel_delayed_work_sync(&priv->watchdog_queue); 47955+#endif 47956+ clk_disable_unprepare(priv->clk); 47957+ free_netdev(ndev); 47958+ 47959+ phy_unregister_fixups(); 47960+ 47961+ return 0; 47962+} 47963+ 47964+#ifdef CONFIG_PM 47965+static int hisi_femac_drv_suspend(struct platform_device *pdev, 47966+ pm_message_t state) 47967+{ 47968+ struct net_device *ndev = platform_get_drvdata(pdev); 47969+ struct hisi_femac_priv *priv = netdev_priv(ndev); 47970+ 47971+ disable_irq(ndev->irq); 47972+ if (netif_running(ndev)) { 47973+ hisi_femac_net_close(ndev); 47974+ netif_device_detach(ndev); 47975+ } 47976+ 47977+ clk_disable_unprepare(priv->clk); 47978+ 47979+ return 0; 47980+} 47981+ 47982+static int hisi_femac_drv_resume(struct platform_device *pdev) 47983+{ 47984+ struct net_device *ndev = platform_get_drvdata(pdev); 47985+ struct hisi_femac_priv *priv = netdev_priv(ndev); 47986+ 47987+ clk_prepare_enable(priv->clk); 47988+ if (priv->phy_rst != NULL) 47989+ hisi_femac_phy_reset(priv); 47990+ 47991+ if (netif_running(ndev)) { 47992+ hisi_femac_port_init(priv); 47993+ hisi_femac_net_open(ndev); 47994+ netif_device_attach(ndev); 47995+ } 47996+ enable_irq(ndev->irq); 47997+ 47998+ return 0; 47999+} 48000+#endif 48001+ 48002+static const struct of_device_id hisi_femac_match[] = { 48003+ { 48004+ .compatible = "hisilicon,hisi-femac-v1", 48005+ }, 48006+ { 48007+ .compatible = "hisilicon,hisi-femac-v2", 48008+ }, 48009+ { 48010+ .compatible = "hisilicon,hi3516cv500-femac", 48011+ }, 48012+ { 48013+ .compatible = "hisilicon,hi3516cv300-femac", 48014+ }, 48015+ { 48016+ .compatible = "hisilicon,hi3536dv100-femac", 48017+ }, 48018+ { 48019+ .compatible = "hisilicon,hi3556v200-femac", 48020+ }, 48021+ { 48022+ .compatible = "hisilicon,hi3559v200-femac", 48023+ }, 48024+ {}, 48025+}; 48026+ 48027+MODULE_DEVICE_TABLE(of, hisi_femac_match); 48028+ 48029+static struct platform_driver hisi_femac_driver = { 48030+ .driver = { 48031+ .name = "hisi-femac", 48032+ .of_match_table = hisi_femac_match, 48033+ }, 48034+ .probe = hisi_femac_drv_probe, 48035+ .remove = hisi_femac_drv_remove, 48036+#ifdef CONFIG_PM 48037+ .suspend = hisi_femac_drv_suspend, 48038+ .resume = hisi_femac_drv_resume, 48039+#endif 48040+}; 48041+ 48042+module_platform_driver(hisi_femac_driver); 48043+ 48044+MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC driver"); 48045+MODULE_AUTHOR("Hisilicon"); 48046+MODULE_LICENSE("GPL v2"); 48047+MODULE_ALIAS("platform:hisi-femac"); 48048diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.h b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.h 48049new file mode 100644 48050index 000000000..5e260ad18 48051--- /dev/null 48052+++ b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.h 48053@@ -0,0 +1,269 @@ 48054+/* 48055+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 48056+ * Description: Hieth driver femac head file 48057+ * Author: KTP_BSP 48058+ * Create: 2020-05-19 48059+ */ 48060+ 48061+#ifndef __HIETH_HISI_FEMAC_H__ 48062+#define __HIETH_HISI_FEMAC_H__ 48063+ 48064+/* MAC control register list */ 48065+#define MAC_PORTSEL 0x0200 48066+#define MAC_PORTSEL_STAT_CPU BIT(0) 48067+#define MAC_PORTSEL_RMII BIT(1) 48068+#define MAC_PORTSET 0x0208 48069+#define MAC_PORTSET_DUPLEX_FULL BIT(0) 48070+#define MAC_PORTSET_LINKED BIT(1) 48071+#define MAC_PORTSET_SPEED_100M BIT(2) 48072+#define MAC_SET 0x0210 48073+#define MAX_FRAME_SIZE 1600 48074+#define MAX_FRAME_SIZE_MASK GENMASK(10, 0) 48075+#define BIT_PAUSE_EN BIT(18) 48076+#define RX_COALESCE_SET 0x0340 48077+#define RX_COALESCED_FRAME_OFFSET 24 48078+#define RX_COALESCED_FRAMES 8 48079+#define RX_COALESCED_TIMER 0x74 48080+#define QLEN_SET 0x0344 48081+#define RX_DEPTH_OFFSET 8 48082+#define MAX_HW_FIFO_DEPTH 64 48083+#define HW_TX_FIFO_DEPTH 12 48084+#define HW_RX_FIFO_DEPTH (MAX_HW_FIFO_DEPTH - HW_TX_FIFO_DEPTH) 48085+#define FC_LEVEL 0x0348 48086+#define BITS_FC_ACTIVE_THR_OFFSET 8 48087+#define FC_DEACTIVE_THR_MASK GENMASK(5, 0) 48088+#define FC_ACTIVE_THR_MASK GENMASK(13, 8) 48089+#define BIT_FC_EN BIT(14) 48090+#define IQFRM_DES 0x0354 48091+#define RX_FRAME_LEN_MASK GENMASK(11, 0) 48092+#define BITS_PAYLOAD_ERR_OFFSET 28 48093+#define BITS_PAYLOAD_ERR_MASK 0x1 48094+#define BITS_HEADER_ERR_OFFSET 29 48095+#define BITS_HEADER_ERR_MASK 0x1 48096+#define BITS_PAYLOAD_DONE_OFFSET 30 48097+#define BITS_PAYLOAD_DONE_MASK 0x1 48098+#define BITS_HEADER_DONE_OFFSET 31 48099+#define BITS_HEADER_DONE_MASK 0x1 48100+#define IQ_ADDR 0x0358 48101+#define EQ_ADDR 0x0360 48102+#define EQFRM_LEN 0x0364 48103+#define ADDRQ_STAT 0x036C 48104+#define TX_CNT_INUSE_MASK GENMASK(5, 0) 48105+#define BIT_TX_READY BIT(24) 48106+#define BIT_RX_READY BIT(25) 48107+#define RX_COE_CTRL 0x0380 48108+#define BIT_COE_IPV6_UDP_ZERO_DROP BIT(13) 48109+#define BIT_COE_PAYLOAD_DROP BIT(14) 48110+#define BIT_COE_IPHDR_DROP BIT(15) 48111+#define COE_ERR_DROP (BIT_COE_IPHDR_DROP | \ 48112+ BIT_COE_PAYLOAD_DROP | \ 48113+ BIT_COE_IPV6_UDP_ZERO_DROP) 48114+#define TSO_DBG_EN 0x03A4 48115+#define BITS_TSO_DBG_EN BIT(31) 48116+#define TSO_DBG_STATE 0x03A8 48117+#define TSO_DBG_ADDR 0x03AC 48118+#define TSO_DBG_TX_INFO 0x03B0 48119+#define TSO_DBG_TX_ERR 0x03B4 48120+/* global control register list */ 48121+#define GLB_HOSTMAC_L32 0x0000 48122+#define GLB_HOSTMAC_H16 0x0004 48123+#define GLB_SOFT_RESET 0x0008 48124+#define SOFT_RESET_ALL BIT(0) 48125+#define GLB_FWCTRL 0x0010 48126+#define FWCTRL_VLAN_ENABLE BIT(0) 48127+#define FWCTRL_FW2CPU_ENA BIT(5) 48128+#define FWCTRL_FWALL2CPU BIT(7) 48129+#define GLB_MACTCTRL 0x0014 48130+#define MACTCTRL_UNI2CPU BIT(1) 48131+#define MACTCTRL_MULTI2CPU BIT(3) 48132+#define MACTCTRL_BROAD2CPU BIT(5) 48133+#define MACTCTRL_MACT_ENA BIT(7) 48134+#define GLB_IRQ_STAT 0x0030 48135+#define GLB_IRQ_ENA 0x0034 48136+#define IRQ_ENA_PORT0_MASK GENMASK(7, 0) 48137+#define IRQ_ENA_PORT0 BIT(18) 48138+#define IRQ_ENA_ALL BIT(19) 48139+#define GLB_IRQ_RAW 0x0038 48140+#define IRQ_INT_RX_RDY BIT(0) 48141+#define IRQ_INT_TX_PER_PACKET BIT(1) 48142+#define IRQ_INT_TX_FIFO_EMPTY BIT(6) 48143+#define IRQ_INT_MULTI_RXRDY BIT(7) 48144+#define INT_TX_ERR BIT(8) 48145+#define DEF_INT_MASK (IRQ_INT_MULTI_RXRDY | \ 48146+ IRQ_INT_TX_PER_PACKET | \ 48147+ IRQ_INT_TX_FIFO_EMPTY) 48148+#define GLB_MAC_L32_BASE 0x0100 48149+#define GLB_MAC_H16_BASE 0x0104 48150+#define MACFLT_HI16_MASK GENMASK(15, 0) 48151+#define BIT_MACFLT_ENA BIT(17) 48152+#define BIT_MACFLT_FW2CPU BIT(21) 48153+#define glb_mac_h16(reg) (GLB_MAC_H16_BASE + ((reg) * 0x8)) 48154+#define glb_mac_l32(reg) (GLB_MAC_L32_BASE + ((reg) * 0x8)) 48155+#define MAX_MAC_FILTER_NUM 8 48156+#define MAX_UNICAST_ADDRESSES 2 48157+#define MAX_MULTICAST_ADDRESSES (MAX_MAC_FILTER_NUM - MAX_UNICAST_ADDRESSES) 48158+/* software tx and rx queue number, should be power of 2 */ 48159+#define TXQ_NUM 64 48160+#define RXQ_NUM 128 48161+#define FEMAC_POLL_WEIGHT 64 48162+#define HW_CAP_TSO BIT(0) 48163+#define HW_CAP_RXCSUM BIT(1) 48164+#define has_tso_cap(hw_cap) ((hw_cap) & HW_CAP_TSO) 48165+#define has_rxcsum_cap(hw_cap) ((hw_cap) & HW_CAP_RXCSUM) 48166+#define RXBUF_ADDR_ALIGN_SIZE 64UL 48167+/* UDP header len is 2 word */ 48168+#define UDP_HDR_LEN 2 48169+/* IPv6 header len is 10 word */ 48170+#define IPV6_HDR_LEN 10 48171+#define WORD_TO_BYTE 4 48172+ 48173+#define BIT_OFFSET_NFRAGS_NUM 11 48174+#define BIT_OFFSET_PROT_HEADER_LEN 16 48175+#define BIT_OFFSET_IP_HEADER_LEN 20 48176+#define BIT_FLAG_SG BIT(26) 48177+#define BIT_FLAG_TXCSUM BIT(27) 48178+#define BIT_FLAG_UDP BIT(28) 48179+#define BIT_FLAG_IPV6 BIT(29) 48180+#define BIT_FLAG_VLAN BIT(30) 48181+#define BIT_FLAG_TSO BIT(31) 48182+ 48183+#define PHY_RESET_DELAYS_PROPERTY "hisilicon,phy-reset-delays-us" 48184+ 48185+/* 48186+ * The threshold for activing tx flow ctrl. 48187+ * When the left amount of receive queue descriptors is below this threshold, 48188+ * hardware will send pause frame immediately. 48189+ * We advise this value is set between 1 and 10. 48190+ * Too bigger is not a good choice. 48191+ * This value must be smaller than tx flow ctrl deactive threshold. 48192+ */ 48193+#define TX_FLOW_CTRL_ACTIVE_THRESHOLD 3 48194+/* 48195+ * The threshold for deactiving tx flow ctrl. 48196+ * When the left amount of receive queue descriptors is 48197+ * above or equal with this threshold, 48198+ * hardware will exit flow control state. 48199+ * We advise this value is set between 1 and 10. 48200+ * Too bigger is not a good choice. 48201+ * This value must be larger than tx flow ctrl active threshold. 48202+ */ 48203+#define TX_FLOW_CTRL_DEACTIVE_THRESHOLD 5 48204+#define FC_ACTIVE_MIN 1 48205+#define FC_ACTIVE_DEFAULT 3 48206+#define FC_ACTIVE_MAX 31 48207+#define FC_DEACTIVE_MIN 1 48208+#define FC_DEACTIVE_DEFAULT 5 48209+#define FC_DEACTIVE_MAX 31 48210+ 48211+#if (defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) || defined(CONFIG_ARCH_HI3516DV200)) 48212+#define CONFIG_FEPHY_OPT 48213+#endif 48214+ 48215+#ifdef CONFIG_FEPHY_OPT 48216+/* FEPHY register list */ 48217+ 48218+#define SYS_REG_ADDR 0x12028000 48219+#define FEPHY_TRIM_CACHE 0x3022 48220+#define FEPHY_TRIM_VALUE 0x20a1 48221+#define LOW_TEM_VALUE 117 48222+#define HIGH_TEM_VALUE 915 48223+#define LINK_STATUS 0x4 48224+#define IS_LINK 0X4 48225+#define SPEED_STATUS 0x18 48226+#define SPEED_100M 0x8 48227+#define LINK_AN_SR 0x11 48228+#define MISC_CTRL45 0x00B4 48229+#define MISC_CTRL47 0x00BC 48230+#define MISC_CTRL48 0x00C0 48231+#define TSENSOR_RESULT0 0x3ff 48232+#define TSENSOR_RESULT1 0x3ff0000 48233+#define TSENSOR_RESULT2 0x3ff 48234+#define TSENSOR_RESULT3 0x3ff0000 48235+#define TSENSOR_EN 0xc3200000 48236+#define HIGH_TEMP 100 48237+#define NORMAL_TEMP1 90 48238+#define NORMAL_TEMP2 20 48239+#define LOW_TEMP 10 48240+#define TSENSOR_LIMIT 0xfffff 48241+#define regval_to_temp(val) ((val - 117) * 165 / 798 - 40) 48242+#define FEPHY_OPT_TIMER (30 * HZ) 48243+#endif 48244+ 48245+enum phy_reset_delays { 48246+ PRE_DELAY, 48247+ PULSE, 48248+ POST_DELAY, 48249+ DELAYS_NUM, 48250+}; 48251+ 48252+struct hisi_femac_queue { 48253+ struct sk_buff **skb; 48254+ dma_addr_t *dma_phys; 48255+ unsigned int num; 48256+ unsigned int head; 48257+ unsigned int tail; 48258+}; 48259+ 48260+struct hisi_femac_tx_desc_ring { 48261+ struct tx_desc *desc; 48262+ dma_addr_t dma_phys; 48263+}; 48264+ 48265+#define FEMAC_RX_REFILL_IN_IRQ 48266+ 48267+struct hisi_femac_priv { 48268+ void __iomem *port_base; 48269+ void __iomem *glb_base; 48270+ struct clk *clk; 48271+ struct reset_control *mac_rst; 48272+ struct reset_control *phy_rst; 48273+ u32 phy_reset_delays[DELAYS_NUM]; 48274+ u32 link_status; 48275+ 48276+#ifdef CONFIG_FEPHY_OPT 48277+ struct delayed_work watchdog_queue; 48278+#endif 48279+ struct device *dev; 48280+ struct net_device *ndev; 48281+ 48282+ u32 hw_cap; 48283+ struct hisi_femac_queue txq; 48284+ struct hisi_femac_queue rxq; 48285+#ifdef FEMAC_RX_REFILL_IN_IRQ 48286+ struct sk_buff_head rx_head; 48287+ spinlock_t rxlock; 48288+#endif 48289+ struct hisi_femac_tx_desc_ring tx_ring; 48290+ u32 tx_fifo_used_cnt; 48291+ struct napi_struct napi; 48292+ 48293+ /* 802.3x flow control */ 48294+ bool tx_pause_en; 48295+ u32 tx_pause_active_thresh; 48296+ u32 tx_pause_deactive_thresh; 48297+}; 48298+ 48299+struct frags_info { 48300+ /* Word(2*i+2) */ 48301+ u32 addr; 48302+ /* Word(2*i+3) */ 48303+ u32 size : 16; 48304+ u32 reserved : 16; 48305+}; 48306+ 48307+struct tx_desc { 48308+ /* Word0 */ 48309+ u32 total_len : 17; 48310+ u32 reserv : 15; 48311+ /* Word1 */ 48312+ u32 ipv6_id; 48313+ /* Word2 */ 48314+ u32 linear_addr; 48315+ /* Word3 */ 48316+ u32 linear_len : 16; 48317+ u32 reserv3 : 16; 48318+ /* MAX_SKB_FRAGS is 30 */ 48319+ struct frags_info frags[30]; 48320+}; 48321+ 48322+#endif 48323diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.c b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.c 48324new file mode 100644 48325index 000000000..e7a3989b8 48326--- /dev/null 48327+++ b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.c 48328@@ -0,0 +1,109 @@ 48329+/* 48330+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 48331+ * Description: Hieth driver phy_fix process 48332+ * Author: KTP_BSP 48333+ * Create: 2018-10-08 48334+ */ 48335+ 48336+#include <linux/phy.h> 48337+#include "phy_fix.h" 48338+ 48339+static const u32 phy_v272_fix_param[] = { 48340+#include "festa_v272_2723.h" 48341+}; 48342+ 48343+static const u32 phy_v115_fix_param[] = { 48344+#include "festa_s28v115_2c02.h" 48345+}; 48346+ 48347+static const u32 phy_v202_fix_param[] = { 48348+#include "festa_s28v202_2e01.h" 48349+}; 48350+ 48351+static int phy_expanded_write_bulk(struct phy_device *phy_dev, 48352+ const u32 reg_and_val[], int count) 48353+{ 48354+ int i, v; 48355+ u32 reg_addr; 48356+ u16 val; 48357+ 48358+ v = phy_read(phy_dev, MII_BMCR); 48359+ v = (u32)v | BMCR_PDOWN; 48360+ phy_write(phy_dev, MII_BMCR, v); 48361+ 48362+ for (i = 0; i < count; i += 2) { /* Process 2 data at a time. */ 48363+ reg_addr = reg_and_val[i]; 48364+ val = (u16)reg_and_val[i + 1]; 48365+ phy_write(phy_dev, MII_EXPMA, reg_addr); 48366+ phy_write(phy_dev, MII_EXPMD, val); 48367+ } 48368+ 48369+ v = phy_read(phy_dev, MII_BMCR); 48370+ v = (u32)v & (~BMCR_PDOWN); 48371+ phy_write(phy_dev, MII_BMCR, v); 48372+ 48373+ return 0; 48374+} 48375+ 48376+static int hisilicon_fephy_v272_fix(struct phy_device *phy_dev) 48377+{ 48378+ int count; 48379+ 48380+ count = ARRAY_SIZE(phy_v272_fix_param); 48381+ if (count % 2) /* must be an even number, mod 2 */ 48382+ pr_warn("internal FEPHY fix register count is not right.\n"); 48383+ phy_expanded_write_bulk(phy_dev, phy_v272_fix_param, count); 48384+ 48385+ return 0; 48386+} 48387+ 48388+static int hisilicon_fephy_v115_fix(struct phy_device *phy_dev) 48389+{ 48390+ int count; 48391+ 48392+ count = ARRAY_SIZE(phy_v115_fix_param); 48393+ if (count % 2) /* must be an even number, mod 2 */ 48394+ pr_warn("internal FEPHY fix register count is not right.\n"); 48395+ phy_expanded_write_bulk(phy_dev, phy_v115_fix_param, count); 48396+ 48397+ return 0; 48398+} 48399+ 48400+static int hisilicon_fephy_v202_fix(struct phy_device *phy_dev) 48401+{ 48402+ int count; 48403+ 48404+ count = ARRAY_SIZE(phy_v202_fix_param); 48405+ if (count % 2) /* must be an even number, mod 2 */ 48406+ pr_warn("internal FEPHY fix register count is not right.\n"); 48407+ phy_expanded_write_bulk(phy_dev, phy_v202_fix_param, count); 48408+ 48409+ return 0; 48410+} 48411+ 48412+void phy_register_fixups(void) 48413+{ 48414+ phy_register_fixup_for_uid(HISILICON_PHY_ID_FESTAV272, 48415+ HISILICON_PHY_MASK, 48416+ hisilicon_fephy_v272_fix); 48417+ 48418+ phy_register_fixup_for_uid(HISILICON_PHY_ID_FESTAV115, 48419+ HISILICON_PHY_MASK, 48420+ hisilicon_fephy_v115_fix); 48421+ 48422+ phy_register_fixup_for_uid(HISILICON_PHY_ID_FESTAV202, 48423+ HISILICON_PHY_MASK, 48424+ hisilicon_fephy_v202_fix); 48425+} 48426+ 48427+void phy_unregister_fixups(void) 48428+{ 48429+ phy_unregister_fixup_for_uid(HISILICON_PHY_ID_FESTAV272, 48430+ HISILICON_PHY_MASK); 48431+ 48432+ phy_unregister_fixup_for_uid(HISILICON_PHY_ID_FESTAV115, 48433+ HISILICON_PHY_MASK); 48434+ 48435+ phy_unregister_fixup_for_uid(HISILICON_PHY_ID_FESTAV202, 48436+ HISILICON_PHY_MASK); 48437+} 48438diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.h b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.h 48439new file mode 100644 48440index 000000000..b7a725090 48441--- /dev/null 48442+++ b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.h 48443@@ -0,0 +1,22 @@ 48444+/* 48445+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved. 48446+ * Description: Hieth driver phy fixup head file 48447+ * Author: KTP_BSP 48448+ * Create: 2018-10-08 48449+ */ 48450+ 48451+#ifndef __HIETH_PHY_FIX_H__ 48452+#define __HIETH_PHY_FIX_H__ 48453+ 48454+#define HISILICON_PHY_ID_FESTAV272 0x20669901 48455+#define HISILICON_PHY_ID_FESTAV115 0x20669903 48456+#define HISILICON_PHY_ID_FESTAV202 0x20669906 48457+#define HISILICON_PHY_MASK 0xffffffff 48458+ 48459+#define MII_EXPMD 0x1d 48460+#define MII_EXPMA 0x1e 48461+ 48462+void phy_register_fixups(void); 48463+void phy_unregister_fixups(void); 48464+ 48465+#endif 48466diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/util.c b/drivers/net/ethernet/hisilicon/hisi-femac/util.c 48467new file mode 100644 48468index 000000000..4f803784e 48469--- /dev/null 48470+++ b/drivers/net/ethernet/hisilicon/hisi-femac/util.c 48471@@ -0,0 +1,318 @@ 48472+/* 48473+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 48474+ * Description: Hieth driver util file 48475+ * Author: KTP_BSP 48476+ * Create: 2020-05-19 48477+ */ 48478+ 48479+#include <linux/if_vlan.h> 48480+#include <linux/ip.h> 48481+#include <net/ipv6.h> 48482+#include <linux/phy.h> 48483+ 48484+#include "util.h" 48485+ 48486+static void hisi_femac_do_udp_checksum(struct sk_buff *skb) 48487+{ 48488+ int offset; 48489+ __wsum csum; 48490+ __sum16 udp_csum; 48491+ 48492+ offset = skb_checksum_start_offset(skb); 48493+ WARN_ON(offset >= skb_headlen(skb)); 48494+ csum = skb_checksum(skb, offset, skb->len - offset, 0); 48495+ 48496+ offset += skb->csum_offset; 48497+ WARN_ON(offset + sizeof(__sum16) > skb_headlen(skb)); 48498+ 48499+ udp_csum = csum_fold(csum); 48500+ if (udp_csum == 0) 48501+ udp_csum = CSUM_MANGLED_0; 48502+ 48503+ *(__sum16 *)(skb->data + offset) = udp_csum; 48504+ 48505+ skb->ip_summed = CHECKSUM_NONE; 48506+} 48507+ 48508+static __be16 hisi_femac_get_l3_proto(struct sk_buff *skb) 48509+{ 48510+ __be16 l3_proto; 48511+ 48512+ l3_proto = skb->protocol; 48513+ if (skb->protocol == htons(ETH_P_8021Q)) 48514+ l3_proto = vlan_get_protocol(skb); 48515+ 48516+ return l3_proto; 48517+} 48518+ 48519+static inline bool hisi_femac_skb_is_ipv6(struct sk_buff *skb) 48520+{ 48521+ return (hisi_femac_get_l3_proto(skb) == htons(ETH_P_IPV6)); 48522+} 48523+ 48524+static int hisi_femac_check_hw_capability_for_ipv6(struct sk_buff *skb) 48525+{ 48526+ unsigned int l4_proto; 48527+ 48528+ l4_proto = ipv6_hdr(skb)->nexthdr; 48529+ if ((l4_proto != IPPROTO_TCP) && (l4_proto != IPPROTO_UDP)) { 48530+ /* 48531+ * when IPv6 next header is not tcp or udp, 48532+ * it means that IPv6 next header is extension header. 48533+ * Hardware can't deal with this case, 48534+ * so do checksumming by software or do GSO by software. 48535+ */ 48536+ if (skb_is_gso(skb)) { 48537+ return -ENOTSUPP; 48538+ } 48539+ 48540+ if (skb->ip_summed == CHECKSUM_PARTIAL && 48541+ skb_checksum_help(skb)) { 48542+ return -EINVAL; 48543+ } 48544+ } 48545+ 48546+ return 0; 48547+} 48548+ 48549+int hisi_femac_check_hw_capability(struct sk_buff *skb) 48550+{ 48551+ /* 48552+ * if tcp_mtu_probe() use (2 * tp->mss_cache) as probe_size, 48553+ * the linear data length will be larger than 2048, 48554+ * the MAC can't handle it, so let the software do it. 48555+ */ 48556+ if (skb_is_gso(skb) && (skb_headlen(skb) > 2048)) { /* max is 2048 */ 48557+ return -ENOTSUPP; 48558+ } 48559+ 48560+ if (hisi_femac_skb_is_ipv6(skb)) { 48561+ return hisi_femac_check_hw_capability_for_ipv6(skb); 48562+ } 48563+ 48564+ return 0; 48565+} 48566+ 48567+static unsigned int hisi_femac_get_pkt_info_gso(struct sk_buff *skb, 48568+ bool txcsum, unsigned int max_mss, unsigned int l4_proto) 48569+{ 48570+ u32 pkt_info = 0; 48571+ bool do_txcsum = txcsum; 48572+ 48573+ /* 48574+ * Although netcard support UFO feature, it can't deal with 48575+ * UDP header checksum. 48576+ * So the driver will do UDP header checksum and netcard will just 48577+ * fragment the packet. 48578+ */ 48579+ if (do_txcsum && skb_is_gso(skb) && (l4_proto == IPPROTO_UDP)) { 48580+ hisi_femac_do_udp_checksum(skb); 48581+ do_txcsum = false; 48582+ } 48583+ 48584+ if (do_txcsum) 48585+ pkt_info |= BIT_FLAG_TXCSUM; 48586+ 48587+ if (skb_is_gso(skb)) { 48588+ pkt_info |= (BIT_FLAG_SG | BIT_FLAG_TSO); 48589+ } else if (skb_shinfo(skb)->nr_frags) { 48590+ pkt_info |= BIT_FLAG_SG; 48591+ } 48592+ 48593+ pkt_info |= (skb_shinfo(skb)->nr_frags << BIT_OFFSET_NFRAGS_NUM); 48594+ pkt_info |= (skb_is_gso(skb) ? ((skb_shinfo(skb)->gso_size > max_mss) ? 48595+ max_mss : skb_shinfo(skb)->gso_size) : 48596+ (skb->len + ETH_FCS_LEN)); 48597+ return pkt_info; 48598+} 48599+ 48600+u32 hisi_femac_get_pkt_info(struct sk_buff *skb) 48601+{ 48602+ __be16 l3_proto; 48603+ unsigned int l4_proto = IPPROTO_MAX; 48604+ bool do_txcsum = false; 48605+ int max_data_len; 48606+ unsigned int max_mss = ETH_DATA_LEN; 48607+ u32 pkt_info = 0; 48608+ 48609+ if (skb == NULL) 48610+ return 0; 48611+ 48612+ max_data_len = skb->len - ETH_HLEN; 48613+ 48614+ if (skb->ip_summed == CHECKSUM_PARTIAL) 48615+ do_txcsum = true; 48616+ 48617+ l3_proto = skb->protocol; 48618+ if (skb->protocol == htons(ETH_P_8021Q)) { 48619+ l3_proto = vlan_get_protocol(skb); 48620+ max_data_len -= VLAN_HLEN; 48621+ pkt_info |= BIT_FLAG_VLAN; 48622+ } 48623+ 48624+ if (l3_proto == htons(ETH_P_IP)) { 48625+ struct iphdr *iph = ip_hdr(skb); 48626+ 48627+ if ((max_data_len >= GSO_MAX_SIZE) && 48628+ (ntohs(iph->tot_len) <= (iph->ihl << 2))) /* trans 2 bytes */ 48629+ iph->tot_len = htons(GSO_MAX_SIZE - 1); 48630+ 48631+ max_mss -= iph->ihl * WORD_TO_BYTE; 48632+ pkt_info |= (iph->ihl << BIT_OFFSET_IP_HEADER_LEN); 48633+ l4_proto = iph->protocol; 48634+ } else if (l3_proto == htons(ETH_P_IPV6)) { 48635+ max_mss -= IPV6_HDR_LEN * WORD_TO_BYTE; 48636+ pkt_info |= BIT_FLAG_IPV6; 48637+ pkt_info |= (IPV6_HDR_LEN << BIT_OFFSET_IP_HEADER_LEN); 48638+ l4_proto = ipv6_hdr(skb)->nexthdr; 48639+ } else { 48640+ do_txcsum = false; 48641+ } 48642+ 48643+ if (l4_proto == IPPROTO_TCP) { 48644+ max_mss -= tcp_hdr(skb)->doff * WORD_TO_BYTE; 48645+ pkt_info |= (tcp_hdr(skb)->doff << BIT_OFFSET_PROT_HEADER_LEN); 48646+ } else if (l4_proto == IPPROTO_UDP) { 48647+ if (l3_proto == htons(ETH_P_IPV6)) 48648+ max_mss -= sizeof(struct frag_hdr); 48649+ pkt_info |= (BIT_FLAG_UDP | 48650+ (UDP_HDR_LEN << BIT_OFFSET_PROT_HEADER_LEN)); 48651+ } else { 48652+ do_txcsum = false; 48653+ } 48654+ 48655+ pkt_info |= hisi_femac_get_pkt_info_gso(skb, do_txcsum, max_mss, l4_proto); 48656+ 48657+ return pkt_info; 48658+} 48659+ 48660+void hisi_femac_sleep_us(u32 time_us) 48661+{ 48662+ u32 time_ms; 48663+ 48664+ if (!time_us) { 48665+ return; 48666+ } 48667+ 48668+ time_ms = DIV_ROUND_UP(time_us, 1000); /* add 1000us, round up */ 48669+ if (time_ms < 20) { /* less than 20 ms */ 48670+ usleep_range(time_us, time_us + 500); /* add maximum 500us */ 48671+ } else { 48672+ msleep(time_ms); 48673+ } 48674+} 48675+ 48676+void hisi_femac_set_flow_ctrl(const struct hisi_femac_priv *priv) 48677+{ 48678+ unsigned int pause_en; 48679+ unsigned int tx_flow_ctrl; 48680+ 48681+ if (priv == NULL) 48682+ return; 48683+ 48684+ tx_flow_ctrl = readl(priv->port_base + FC_LEVEL); 48685+ tx_flow_ctrl &= ~FC_DEACTIVE_THR_MASK; 48686+ tx_flow_ctrl |= priv->tx_pause_deactive_thresh; 48687+ tx_flow_ctrl &= ~FC_ACTIVE_THR_MASK; 48688+ tx_flow_ctrl |= priv->tx_pause_active_thresh << BITS_FC_ACTIVE_THR_OFFSET; 48689+ 48690+ pause_en = readl(priv->port_base + MAC_SET); 48691+ 48692+ if (priv->tx_pause_en) { 48693+ tx_flow_ctrl |= BIT_FC_EN; 48694+ pause_en |= BIT_PAUSE_EN; 48695+ } else { 48696+ tx_flow_ctrl &= ~BIT_FC_EN; 48697+ pause_en &= ~BIT_PAUSE_EN; 48698+ } 48699+ 48700+ writel(tx_flow_ctrl, priv->port_base + FC_LEVEL); 48701+ 48702+ writel(pause_en, priv->port_base + MAC_SET); 48703+} 48704+ 48705+void hisi_femac_get_pauseparam(struct net_device *dev, 48706+ struct ethtool_pauseparam *pause) 48707+{ 48708+ struct hisi_femac_priv *priv = netdev_priv(dev); 48709+ 48710+ if (dev == NULL || dev->phydev == NULL || pause == NULL) 48711+ return; 48712+ 48713+ pause->autoneg = dev->phydev->autoneg; 48714+ pause->rx_pause = 1; 48715+ if (priv->tx_pause_en) 48716+ pause->tx_pause = 1; 48717+} 48718+ 48719+int hisi_femac_set_pauseparam(struct net_device *dev, 48720+ struct ethtool_pauseparam *pause) 48721+{ 48722+ struct hisi_femac_priv *priv = netdev_priv(dev); 48723+ struct phy_device *phy = NULL; 48724+ int ret = 0; 48725+ 48726+ if (dev == NULL || pause == NULL || pause->rx_pause == 0) { 48727+ return -EINVAL; 48728+ } 48729+ 48730+ phy = dev->phydev; 48731+ 48732+ if (pause->tx_pause != priv->tx_pause_en) { 48733+ priv->tx_pause_en = pause->tx_pause; 48734+ hisi_femac_set_flow_ctrl(priv); 48735+ } 48736+ 48737+ if (phy != NULL && phy->autoneg) { 48738+ if (netif_running(dev)) { 48739+ struct ethtool_cmd cmd; 48740+ /* auto-negotiation automatically restarted */ 48741+ cmd.cmd = ETHTOOL_NWAY_RST; 48742+ cmd.supported = phy->supported; 48743+ cmd.advertising = phy->advertising; 48744+ cmd.autoneg = phy->autoneg; 48745+ cmd.speed = phy->speed; 48746+ cmd.duplex = phy->duplex; 48747+ cmd.phy_address = phy->mdio.addr; 48748+// ret = phy_ethtool_sset(phy, &cmd); 48749+ } 48750+ } 48751+ 48752+ return ret; 48753+} 48754+ 48755+void hisi_femac_enable_rxcsum_drop(const struct hisi_femac_priv *priv, 48756+ bool drop) 48757+{ 48758+ unsigned int val; 48759+ if (priv == NULL) 48760+ return; 48761+ 48762+ val = readl(priv->port_base + RX_COE_CTRL); 48763+ val &= ~COE_ERR_DROP; 48764+ if (drop) 48765+ val |= (BIT_COE_IPHDR_DROP | BIT_COE_IPV6_UDP_ZERO_DROP); 48766+ writel(val, priv->port_base + RX_COE_CTRL); 48767+} 48768+ 48769+int hisi_femac_set_features(struct net_device *dev, netdev_features_t features) 48770+{ 48771+ struct hisi_femac_priv *priv = NULL; 48772+ netdev_features_t changed; 48773+ 48774+ if (dev == NULL) 48775+ return -1; 48776+ 48777+ priv = netdev_priv(dev); 48778+ changed = dev->features ^ features; 48779+ 48780+ if (changed & NETIF_F_RXCSUM) { 48781+ if (features & NETIF_F_RXCSUM) { 48782+ hisi_femac_enable_rxcsum_drop(priv, true); 48783+ } else { 48784+ hisi_femac_enable_rxcsum_drop(priv, false); 48785+ } 48786+ } 48787+ 48788+ return 0; 48789+} 48790diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/util.h b/drivers/net/ethernet/hisilicon/hisi-femac/util.h 48791new file mode 100644 48792index 000000000..009424857 48793--- /dev/null 48794+++ b/drivers/net/ethernet/hisilicon/hisi-femac/util.h 48795@@ -0,0 +1,25 @@ 48796+/* 48797+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. 48798+ * Description: Hieth driver util head file 48799+ * Author: KTP_BSP 48800+ * Create: 2020-05-19 48801+ */ 48802+ 48803+#ifndef __HIETH_UTIL_H__ 48804+#define __HIETH_UTIL_H__ 48805+ 48806+#include "hisi_femac.h" 48807+ 48808+int hisi_femac_check_hw_capability(struct sk_buff *skb); 48809+u32 hisi_femac_get_pkt_info(struct sk_buff *skb); 48810+void hisi_femac_sleep_us(u32 time_us); 48811+void hisi_femac_set_flow_ctrl(const struct hisi_femac_priv *priv); 48812+void hisi_femac_get_pauseparam(struct net_device *dev, 48813+ struct ethtool_pauseparam *pause); 48814+int hisi_femac_set_pauseparam(struct net_device *dev, 48815+ struct ethtool_pauseparam *pause); 48816+void hisi_femac_enable_rxcsum_drop(const struct hisi_femac_priv *priv, 48817+ bool drop); 48818+int hisi_femac_set_features(struct net_device *dev, netdev_features_t features); 48819+ 48820+#endif 48821\ No newline at end of file 48822diff --git a/drivers/net/ethernet/hisilicon/hisi_femac.c b/drivers/net/ethernet/hisilicon/hisi_femac.c 48823index 57c3bc4f7..180805656 100644 48824--- a/drivers/net/ethernet/hisilicon/hisi_femac.c 48825+++ b/drivers/net/ethernet/hisilicon/hisi_femac.c 48826@@ -86,7 +86,7 @@ 48827 /* software tx and rx queue number, should be power of 2 */ 48828 #define TXQ_NUM 64 48829 #define RXQ_NUM 128 48830-#define FEMAC_POLL_WEIGHT 16 48831+#define FEMAC_POLL_WEIGHT 64 48832 48833 #define PHY_RESET_DELAYS_PROPERTY "hisilicon,phy-reset-delays-us" 48834 48835@@ -973,6 +973,6 @@ static struct platform_driver hisi_femac_driver = { 48836 module_platform_driver(hisi_femac_driver); 48837 48838 MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC driver"); 48839-MODULE_AUTHOR("Dongpo Li <lidongpo@hisilicon.com>"); 48840+MODULE_AUTHOR("Hisilicon"); 48841 MODULE_LICENSE("GPL v2"); 48842 MODULE_ALIAS("platform:hisi-femac"); 48843diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 48844index 7fb7a4196..1a357516b 100644 48845--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 48846+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 48847@@ -702,7 +702,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data) 48848 48849 static int hns_gmac_get_sset_count(int stringset) 48850 { 48851- if (stringset == ETH_SS_STATS) 48852+ if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) 48853 return ARRAY_SIZE(g_gmac_stats_string); 48854 48855 return 0; 48856diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 48857index d0f8b1fff..c5176565f 100644 48858--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 48859+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 48860@@ -444,7 +444,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb) 48861 48862 int hns_ppe_get_sset_count(int stringset) 48863 { 48864- if (stringset == ETH_SS_STATS) 48865+ if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) 48866 return ETH_PPE_STATIC_NUM; 48867 return 0; 48868 } 48869diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c 48870index b6c8910cf..4cda44494 100644 48871--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c 48872+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c 48873@@ -897,7 +897,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data) 48874 */ 48875 int hns_rcb_get_ring_sset_count(int stringset) 48876 { 48877- if (stringset == ETH_SS_STATS) 48878+ if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) 48879 return HNS_RING_STATIC_REG_NUM; 48880 48881 return 0; 48882diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c 48883index 3616b77ca..883c5f5db 100644 48884--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c 48885+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c 48886@@ -2092,8 +2092,11 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev, 48887 ret = mlx4_get_module_info(mdev->dev, priv->port, 48888 offset, ee->len - i, data + i); 48889 48890- if (!ret) /* Done reading */ 48891+ if (!ret) { 48892+ /* DOM was not readable after all */ 48893+ memset(data + i, 0, ee->len - i); 48894 return 0; 48895+ } 48896 48897 if (ret < 0) { 48898 en_err(priv, 48899diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig 48900index a10cc460d..42603264a 100644 48901--- a/drivers/net/mdio/Kconfig 48902+++ b/drivers/net/mdio/Kconfig 48903@@ -107,6 +107,13 @@ config MDIO_HISI_FEMAC 48904 This module provides a driver for the MDIO busses found in the 48905 Hisilicon SoC that have an Fast Ethernet MAC. 48906 48907+config MDIO_HISI_GEMAC 48908+ tristate "Hisilicon GEMAC MDIO bus controller" 48909+ depends on HAS_IOMEM && OF_MDIO 48910+ help 48911+ This module provides a driver for the MDIO busses found in the 48912+ Hisilicon SoC that have an Gigabit Ethernet MAC. 48913+ 48914 config MDIO_I2C 48915 tristate 48916 depends on I2C 48917diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile 48918index 5c498dde4..67b74ed9d 100644 48919--- a/drivers/net/mdio/Makefile 48920+++ b/drivers/net/mdio/Makefile 48921@@ -9,7 +9,10 @@ obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o 48922 obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o 48923 obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium.o 48924 obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o 48925+obj-$(CONFIG_ARCH_HI3531DV200) += mdio_hi3531dv200_gemac.o 48926+obj-$(CONFIG_ARCH_HI3535AV100) += mdio_hi3535av100_gemac.o 48927 obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o 48928+obj-$(CONFIG_MDIO_HISI_GEMAC) += mdio-hisi-gemac.o 48929 obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o 48930 obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o 48931 obj-$(CONFIG_MDIO_IPQ8064) += mdio-ipq8064.o 48932diff --git a/drivers/net/phy/mdio_hisi_femac.c b/drivers/net/phy/mdio_hisi_femac.c 48933new file mode 100644 48934index 000000000..25f187574 48935--- /dev/null 48936+++ b/drivers/net/phy/mdio_hisi_femac.c 48937@@ -0,0 +1,489 @@ 48938+/* 48939+ * Hisilicon Fast Ethernet MDIO Bus Driver 48940+ * 48941+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 48942+ * 48943+ * This program is free software; you can redistribute it and/or modify 48944+ * it under the terms of the GNU General Public License as published by 48945+ * the Free Software Foundation; either version 2 of the License, or 48946+ * (at your option) any later version. 48947+ * 48948+ * This program is distributed in the hope that it will be useful, 48949+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 48950+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 48951+ * GNU General Public License for more details. 48952+ * 48953+ * You should have received a copy of the GNU General Public License 48954+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 48955+ */ 48956+ 48957+#include <linux/clk.h> 48958+#include <linux/iopoll.h> 48959+#include <linux/kernel.h> 48960+#include <linux/module.h> 48961+#include <linux/of_address.h> 48962+#include <linux/of_mdio.h> 48963+#include <linux/platform_device.h> 48964+#include <linux/reset.h> 48965+ 48966+#define MDIO_RWCTRL 0x00 48967+#define MDIO_RO_DATA 0x04 48968+#define MDIO_WRITE BIT(13) 48969+#define MDIO_RW_FINISH BIT(15) 48970+#define BIT_PHY_ADDR_OFFSET 8 48971+#define BIT_WR_DATA_OFFSET 16 48972+ 48973+#define BIT_MASK_FEPHY_ADDR GENMASK(4, 0) 48974+#define BIT_FEPHY_SEL BIT(5) 48975+ 48976+#if defined(CONFIG_ARCH_HI3536DV100) 48977+#define BIT_OFFSET_LD_SET 0 48978+#define BIT_OFFSET_LDO_SET 5 48979+#define BIT_OFFSET_R_TUNING 8 48980+#elif defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500) 48981+#define BIT_OFFSET_LD_SET 6 48982+#define BIT_OFFSET_LDO_SET 12 48983+#define BIT_OFFSET_R_TUNING 0 48984+#define DEF_LD_AM 0x9 48985+#define DEF_LDO_AM 0x3 48986+#define DEF_R_TUNING 0x16 48987+#else 48988+#define BIT_OFFSET_LD_SET 25 48989+#define BIT_OFFSET_LDO_SET 22 48990+#define BIT_OFFSET_R_TUNING 16 48991+#endif 48992+#define MII_EXPMD 0x1d 48993+#define MII_EXPMA 0x1e 48994+ 48995+#define REG_LD_AM 0x3050 48996+#define BIT_MASK_LD_SET GENMASK(4, 0) 48997+#define REG_LDO_AM 0x3051 48998+#define BIT_MASK_LDO_SET GENMASK(2, 0) 48999+#define REG_R_TUNING 0x3052 49000+#define BIT_MASK_R_TUNING GENMASK(5, 0) 49001+#define REG_WR_DONE 0x3053 49002+#define BIT_CFG_DONE BIT(0) 49003+#define BIT_CFG_ACK BIT(1) 49004+#define REG_DEF_ATE 0x3057 49005+#define BIT_AUTOTRIM_DONE BIT(0) 49006+ 49007+#define PHY_RESET_DELAYS_PROPERTY "hisilicon,phy-reset-delays-us" 49008+ 49009+enum phy_reset_delays { 49010+ PRE_DELAY, 49011+ PULSE, 49012+ POST_DELAY, 49013+ DELAYS_NUM, 49014+}; 49015+ 49016+struct hisi_femac_mdio_data { 49017+ struct clk *clk; 49018+ struct clk *fephy_clk; 49019+ struct reset_control *phy_rst; 49020+ struct reset_control *fephy_rst; 49021+ u32 phy_reset_delays[DELAYS_NUM]; 49022+ void __iomem *membase; 49023+ void __iomem *fephy_iobase; 49024+ void __iomem *fephy_trim_iobase; 49025+ struct mii_bus *bus; 49026+ u32 phy_addr; 49027+}; 49028+ 49029+static int hisi_femac_mdio_wait_ready(struct hisi_femac_mdio_data *data) 49030+{ 49031+ u32 val; 49032+ 49033+ return readl_poll_timeout_atomic(data->membase + MDIO_RWCTRL, 49034+ val, val & MDIO_RW_FINISH, 20, 10000); 49035+} 49036+ 49037+static int hisi_femac_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 49038+{ 49039+ struct hisi_femac_mdio_data *data = bus->priv; 49040+ int ret; 49041+ 49042+ ret = hisi_femac_mdio_wait_ready(data); 49043+ if (ret) 49044+ return ret; 49045+ 49046+ writel(((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum), 49047+ data->membase + MDIO_RWCTRL); 49048+ 49049+ ret = hisi_femac_mdio_wait_ready(data); 49050+ if (ret) 49051+ return ret; 49052+ 49053+ return readl(data->membase + MDIO_RO_DATA) & 0xFFFF; 49054+} 49055+ 49056+static int hisi_femac_mdio_write(struct mii_bus *bus, int mii_id, int regnum, 49057+ u16 value) 49058+{ 49059+ struct hisi_femac_mdio_data *data = bus->priv; 49060+ int ret; 49061+ 49062+ ret = hisi_femac_mdio_wait_ready(data); 49063+ if (ret) 49064+ return ret; 49065+ 49066+ writel(MDIO_WRITE | (value << BIT_WR_DATA_OFFSET) | 49067+ ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum), 49068+ data->membase + MDIO_RWCTRL); 49069+ 49070+ return hisi_femac_mdio_wait_ready(data); 49071+} 49072+ 49073+static void hisi_femac_sleep_us(u32 time_us) 49074+{ 49075+ u32 time_ms; 49076+ 49077+ if (!time_us) 49078+ return; 49079+ 49080+ time_ms = DIV_ROUND_UP(time_us, 1000); 49081+ if (time_ms < 20) 49082+ usleep_range(time_us, time_us + 500); 49083+ else 49084+ msleep(time_ms); 49085+} 49086+ 49087+static void hisi_femac_phy_reset(const struct hisi_femac_mdio_data *data) 49088+{ 49089+ /* To make sure PHY hardware reset success, 49090+ * we must keep PHY in deassert state first and 49091+ * then complete the hardware reset operation 49092+ */ 49093+ reset_control_deassert(data->phy_rst); 49094+ hisi_femac_sleep_us(data->phy_reset_delays[PRE_DELAY]); 49095+ 49096+ reset_control_assert(data->phy_rst); 49097+ /* delay some time to ensure reset ok, 49098+ * this depends on PHY hardware feature 49099+ */ 49100+ hisi_femac_sleep_us(data->phy_reset_delays[PULSE]); 49101+ reset_control_deassert(data->phy_rst); 49102+ /* delay some time to ensure later MDIO access */ 49103+ hisi_femac_sleep_us(data->phy_reset_delays[POST_DELAY]); 49104+} 49105+ 49106+static void hisi_femac_get_phy_addr(struct hisi_femac_mdio_data *data, 49107+ struct device_node *np) 49108+{ 49109+ struct device_node *child = NULL; 49110+ int addr; 49111+ 49112+ child = of_get_next_available_child(np, NULL); 49113+ if (!child) { 49114+ pr_err("%s: No valid PHY device node!\n", __func__); 49115+ return; 49116+ } 49117+ 49118+ addr = of_mdio_parse_addr(&data->bus->dev, child); 49119+ if (addr < 0) { 49120+ pr_err("%s: get PHY address failed!\n", __func__); 49121+ return; 49122+ } 49123+ 49124+ data->phy_addr = addr; 49125+} 49126+ 49127+static inline bool hisi_femac_use_fephy(struct hisi_femac_mdio_data *data) 49128+{ 49129+ /*return false;*/ 49130+ return (data->fephy_iobase ? 49131+ !(readl(data->fephy_iobase) & BIT_FEPHY_SEL) : false); 49132+} 49133+ 49134+static void hisi_femac_fephy_reset(struct hisi_femac_mdio_data *data) 49135+{ 49136+ u32 val; 49137+ 49138+ /* disable MDCK clock to make sure FEPHY reset success */ 49139+ clk_disable_unprepare(data->clk); 49140+ 49141+ val = readl(data->fephy_iobase); 49142+ val &= ~BIT_MASK_FEPHY_ADDR; 49143+ val |= data->phy_addr; 49144+ writel(val, data->fephy_iobase); 49145+ 49146+ clk_prepare_enable(data->fephy_clk); 49147+ udelay(10); /* 10:delay */ 49148+ 49149+ reset_control_assert(data->fephy_rst); 49150+ udelay(10); 49151+ reset_control_deassert(data->fephy_rst); 49152+ /* delay at least 15ms for MDIO operation */ 49153+ msleep(20); 49154+ 49155+ clk_prepare_enable(data->clk); 49156+ /* delay 5ms after enable MDCK to make sure FEPHY trim safe */ 49157+ mdelay(5); 49158+} 49159+ 49160+static inline int fephy_expanded_read(struct mii_bus *bus, int phy_addr, 49161+ u32 reg_addr) 49162+{ 49163+ int ret; 49164+ 49165+ hisi_femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); 49166+ ret = hisi_femac_mdio_read(bus, phy_addr, MII_EXPMD); 49167+ 49168+ return ret; 49169+} 49170+ 49171+static inline int fephy_expanded_write(struct mii_bus *bus, int phy_addr, 49172+ u32 reg_addr, u16 val) 49173+{ 49174+ int ret; 49175+ 49176+ hisi_femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); 49177+ ret = hisi_femac_mdio_write(bus, phy_addr, MII_EXPMD, val); 49178+ 49179+ return ret; 49180+} 49181+ 49182+void hisi_femac_fephy_use_default_trim(struct hisi_femac_mdio_data *data) 49183+{ 49184+ unsigned short val; 49185+ int timeout = 3; 49186+ 49187+ pr_info("No OTP data, festa PHY use default ATE parameters!\n"); 49188+ 49189+ do { 49190+ msleep(250); 49191+ val = fephy_expanded_read(data->bus, data->phy_addr, 49192+ REG_DEF_ATE); 49193+ val &= BIT_AUTOTRIM_DONE; 49194+ } while (!val && --timeout); 49195+ 49196+ if (!timeout) 49197+ pr_err("festa PHY wait autotrim done timeout!\n"); 49198+ 49199+ mdelay(5); 49200+} 49201+ 49202+static void hisi_femac_fephy_trim(struct hisi_femac_mdio_data *data) 49203+{ 49204+ struct mii_bus *bus = data->bus; 49205+ u32 phy_addr = data->phy_addr; 49206+ int timeout = 3000; 49207+ u32 val; 49208+ u8 ld_set; 49209+ u8 ldo_set; 49210+ u8 r_tuning; 49211+ 49212+ /* FEPHY get OTP trim data from special reg not fephy control reg1 */ 49213+#if defined(CONFIG_ARCH_HI3536DV100) || \ 49214+ defined(CONFIG_ARCH_HI3521DV200) || \ 49215+ defined(CONFIG_ARCH_HI3520DV500) 49216+ val = readl(data->fephy_trim_iobase); 49217+#else 49218+ val = readl(data->fephy_iobase); 49219+#endif 49220+ ld_set = (val >> BIT_OFFSET_LD_SET) & BIT_MASK_LD_SET; 49221+ ldo_set = (val >> BIT_OFFSET_LDO_SET) & BIT_MASK_LDO_SET; 49222+ r_tuning = (val >> BIT_OFFSET_R_TUNING) & BIT_MASK_R_TUNING; 49223+ 49224+#if defined(CONFIG_ARCH_HI3521DV200) || \ 49225+ defined(CONFIG_ARCH_HI3520DV500) 49226+ if (!ld_set && !ldo_set && !r_tuning) { 49227+ ld_set = DEF_LD_AM; 49228+ ldo_set = DEF_LDO_AM; 49229+ r_tuning = DEF_R_TUNING; 49230+ } 49231+#endif 49232+ 49233+ if (!ld_set && !ldo_set && !r_tuning) { 49234+ hisi_femac_fephy_use_default_trim(data); 49235+ return; 49236+ } 49237+ 49238+ val = fephy_expanded_read(bus, phy_addr, REG_LD_AM); 49239+ val = (val & ~BIT_MASK_LD_SET) | (ld_set & BIT_MASK_LD_SET); 49240+ fephy_expanded_write(bus, phy_addr, REG_LD_AM, val); 49241+ 49242+ val = fephy_expanded_read(bus, phy_addr, REG_LDO_AM); 49243+ val = (val & ~BIT_MASK_LDO_SET) | (ldo_set & BIT_MASK_LDO_SET); 49244+ fephy_expanded_write(bus, phy_addr, REG_LDO_AM, val); 49245+ 49246+ val = fephy_expanded_read(bus, phy_addr, REG_R_TUNING); 49247+ val = (val & ~BIT_MASK_R_TUNING) | (r_tuning & BIT_MASK_R_TUNING); 49248+ fephy_expanded_write(bus, phy_addr, REG_R_TUNING, val); 49249+ 49250+ val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE); 49251+ if (val & BIT_CFG_ACK) 49252+ pr_err("festa PHY 0x3053 bit CFG_ACK value: 1\n"); 49253+ val = val | BIT_CFG_DONE; 49254+ fephy_expanded_write(bus, phy_addr, REG_WR_DONE, val); 49255+ 49256+ do { 49257+ usleep_range(100, 150); 49258+ val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE); 49259+ val &= BIT_CFG_ACK; 49260+ } while (!val && --timeout); 49261+ if (!timeout) 49262+ pr_err("festa PHY 0x3053 wait bit CFG_ACK timeout!\n"); 49263+ 49264+ mdelay(5); 49265+ 49266+ pr_info("FEPHY:addr=%d, la_am=0x%x, ldo_am=0x%x, r_tuning=0x%x\n", 49267+ phy_addr, 49268+ fephy_expanded_read(bus, phy_addr, REG_LD_AM), 49269+ fephy_expanded_read(bus, phy_addr, REG_LDO_AM), 49270+ fephy_expanded_read(bus, phy_addr, REG_R_TUNING)); 49271+} 49272+ 49273+static void hisi_femac_fephy_reset_and_trim(struct hisi_femac_mdio_data *data) 49274+{ 49275+ hisi_femac_fephy_reset(data); 49276+ hisi_femac_fephy_trim(data); 49277+} 49278+ 49279+static void hisi_femac_fephy_set_phy_addr(struct hisi_femac_mdio_data *data) 49280+{ 49281+ u32 val; 49282+ 49283+ if (!data->fephy_iobase) 49284+ return; 49285+ 49286+ val = readl(data->fephy_iobase); 49287+ val &= ~BIT_MASK_FEPHY_ADDR; 49288+ val |= (data->phy_addr + 1); 49289+ writel(val, data->fephy_iobase); 49290+} 49291+ 49292+static int hisi_femac_mdio_probe(struct platform_device *pdev) 49293+{ 49294+ struct device_node *np = pdev->dev.of_node; 49295+ struct mii_bus *bus = NULL; 49296+ struct hisi_femac_mdio_data *data = NULL; 49297+ struct resource *res = NULL; 49298+ int ret; 49299+ 49300+ bus = mdiobus_alloc_size(sizeof(*data)); 49301+ if (!bus) 49302+ return -ENOMEM; 49303+ 49304+ bus->name = "hisi_femac_mii_bus"; 49305+ bus->read = &hisi_femac_mdio_read; 49306+ bus->write = &hisi_femac_mdio_write; 49307+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); 49308+ bus->parent = &pdev->dev; 49309+ 49310+ data = bus->priv; 49311+ data->bus = bus; 49312+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 49313+ data->membase = devm_ioremap_resource(&pdev->dev, res); 49314+ if (IS_ERR(data->membase)) { 49315+ ret = PTR_ERR(data->membase); 49316+ goto err_out_free_mdiobus; 49317+ } 49318+ 49319+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 49320+ if (res) { 49321+ data->fephy_iobase = devm_ioremap_resource(&pdev->dev, res); 49322+ if (IS_ERR(data->fephy_iobase)) { 49323+ ret = PTR_ERR(data->fephy_iobase); 49324+ goto err_out_free_mdiobus; 49325+ } 49326+ } else { 49327+ data->fephy_iobase = NULL; 49328+ } 49329+ 49330+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); 49331+ if (res) { 49332+ data->fephy_trim_iobase = devm_ioremap_resource(&pdev->dev, 49333+ res); 49334+ if (IS_ERR(data->fephy_trim_iobase)) { 49335+ ret = PTR_ERR(data->fephy_trim_iobase); 49336+ goto err_out_free_mdiobus; 49337+ } 49338+ } else { 49339+ data->fephy_trim_iobase = NULL; 49340+ } 49341+ 49342+ data->clk = devm_clk_get(&pdev->dev, "mdio"); 49343+ if (IS_ERR(data->clk)) { 49344+ ret = PTR_ERR(data->clk); 49345+ goto err_out_free_mdiobus; 49346+ } 49347+ 49348+ data->fephy_clk = devm_clk_get(&pdev->dev, "phy"); 49349+ if (IS_ERR(data->fephy_clk)) 49350+ data->fephy_clk = NULL; 49351+ 49352+ ret = clk_prepare_enable(data->clk); 49353+ if (ret) 49354+ goto err_out_free_mdiobus; 49355+ 49356+ data->phy_rst = devm_reset_control_get(&pdev->dev, "external-phy"); 49357+ if (IS_ERR(data->phy_rst)) { 49358+ data->phy_rst = NULL; 49359+ } else { 49360+ ret = of_property_read_u32_array(np, 49361+ PHY_RESET_DELAYS_PROPERTY, 49362+ data->phy_reset_delays, 49363+ DELAYS_NUM); 49364+ if (ret) 49365+ goto err_out_disable_clk; 49366+ hisi_femac_phy_reset(data); 49367+ } 49368+ 49369+ data->fephy_rst = devm_reset_control_get(&pdev->dev, "internal-phy"); 49370+ if (IS_ERR(data->fephy_rst)) 49371+ data->fephy_rst = NULL; 49372+ 49373+ hisi_femac_get_phy_addr(data, np); 49374+ if (hisi_femac_use_fephy(data)) 49375+ hisi_femac_fephy_reset_and_trim(data); 49376+ else 49377+ hisi_femac_fephy_set_phy_addr(data); 49378+ 49379+ ret = of_mdiobus_register(bus, np); 49380+ if (ret) 49381+ goto err_out_disable_clk; 49382+ 49383+ platform_set_drvdata(pdev, bus); 49384+ 49385+ return 0; 49386+ 49387+err_out_disable_clk: 49388+ clk_disable_unprepare(data->fephy_clk); 49389+ clk_disable_unprepare(data->clk); 49390+err_out_free_mdiobus: 49391+ mdiobus_free(bus); 49392+ return ret; 49393+} 49394+ 49395+static int hisi_femac_mdio_remove(struct platform_device *pdev) 49396+{ 49397+ struct mii_bus *bus = platform_get_drvdata(pdev); 49398+ struct hisi_femac_mdio_data *data = bus->priv; 49399+ 49400+ mdiobus_unregister(bus); 49401+ clk_disable_unprepare(data->clk); 49402+ mdiobus_free(bus); 49403+ 49404+ return 0; 49405+} 49406+ 49407+static const struct of_device_id hisi_femac_mdio_dt_ids[] = { 49408+ { .compatible = "hisilicon,hisi-femac-mdio" }, 49409+ { } 49410+}; 49411+MODULE_DEVICE_TABLE(of, hisi_femac_mdio_dt_ids); 49412+ 49413+static struct platform_driver hisi_femac_mdio_driver = { 49414+ .probe = hisi_femac_mdio_probe, 49415+ .remove = hisi_femac_mdio_remove, 49416+ .driver = { 49417+ .name = "hisi-femac-mdio", 49418+ .of_match_table = hisi_femac_mdio_dt_ids, 49419+ }, 49420+}; 49421+ 49422+module_platform_driver(hisi_femac_mdio_driver); 49423+ 49424+MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC MDIO interface driver"); 49425+MODULE_AUTHOR("Hisilicon>"); 49426+MODULE_LICENSE("GPL v2"); 49427diff --git a/drivers/net/phy/mdio_hisi_gemac.c b/drivers/net/phy/mdio_hisi_gemac.c 49428new file mode 100644 49429index 000000000..79ebfa400 49430--- /dev/null 49431+++ b/drivers/net/phy/mdio_hisi_gemac.c 49432@@ -0,0 +1,256 @@ 49433+/* 49434+ * Hisilicon Gigabit Ethernet MDIO Bus Driver 49435+ * 49436+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 49437+ * 49438+ * This program is free software; you can redistribute it and/or modify 49439+ * it under the terms of the GNU General Public License as published by 49440+ * the Free Software Foundation; either version 2 of the License, or 49441+ * (at your option) any later version. 49442+ * 49443+ * This program is distributed in the hope that it will be useful, 49444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 49445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49446+ * GNU General Public License for more details. 49447+ * 49448+ * You should have received a copy of the GNU General Public License 49449+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 49450+ */ 49451+ 49452+#include <linux/clk.h> 49453+#include <linux/iopoll.h> 49454+#include <linux/kernel.h> 49455+#include <linux/module.h> 49456+#include <linux/of_address.h> 49457+#include <linux/of_mdio.h> 49458+#include <linux/platform_device.h> 49459+#include <linux/reset.h> 49460+#include "mdio_hisi_gemac.h" 49461+ 49462+#if defined(CONFIG_ARCH_HI3519) || defined(CONFIG_ARCH_HI3519V101) || \ 49463+ defined(CONFIG_ARCH_HI3516AV200) 49464+#ifdef readl 49465+#undef readl 49466+#undef writel 49467+#define readl hi_readl 49468+#define writel hi_writel 49469+#endif 49470+#endif 49471+ 49472+#define MDIO_SINGLE_CMD 0x00 49473+#define MDIO_SINGLE_DATA 0x04 49474+#define MDIO_RDATA_STATUS 0x10 49475+#define BIT_PHY_ADDR_OFFSET 8 49476+#define MDIO_WRITE BIT(16) 49477+#define MDIO_READ BIT(17) 49478+#define MDIO_START BIT(20) 49479+#define MDIO_START_READ (MDIO_START | MDIO_READ) 49480+#define MDIO_START_WRITE (MDIO_START | MDIO_WRITE) 49481+ 49482+struct hisi_gemac_mdio_data { 49483+ struct clk *clk; 49484+ struct reset_control *phy_rst; 49485+ void __iomem *membase; 49486+}; 49487+ 49488+static int hisi_gemac_mdio_wait_ready(struct hisi_gemac_mdio_data *data) 49489+{ 49490+ u32 val; 49491+ 49492+ return readl_poll_timeout(data->membase + MDIO_SINGLE_CMD, 49493+ val, !(val & MDIO_START), 20, 10000); 49494+} 49495+ 49496+static int hisi_gemac_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 49497+{ 49498+ struct hisi_gemac_mdio_data *data = bus->priv; 49499+ int ret; 49500+ 49501+ ret = hisi_gemac_mdio_wait_ready(data); 49502+ if (ret) 49503+ return ret; 49504+ 49505+ writel(MDIO_START_READ | ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | 49506+ ((u32)regnum), 49507+ data->membase + MDIO_SINGLE_CMD); 49508+ 49509+ ret = hisi_gemac_mdio_wait_ready(data); 49510+ if (ret) 49511+ return ret; 49512+ 49513+ /* if read data is invalid, we just return 0 instead of -EAGAIN. 49514+ * This can make MDIO more robust when reading PHY status. 49515+ */ 49516+ if (readl(data->membase + MDIO_RDATA_STATUS)) 49517+ return 0; 49518+ 49519+ return readl(data->membase + MDIO_SINGLE_DATA) >> 16; 49520+} 49521+ 49522+static int hisi_gemac_mdio_write(struct mii_bus *bus, int mii_id, int regnum, 49523+ u16 value) 49524+{ 49525+ struct hisi_gemac_mdio_data *data = bus->priv; 49526+ int ret; 49527+ 49528+ ret = hisi_gemac_mdio_wait_ready(data); 49529+ if (ret) 49530+ return ret; 49531+ 49532+ writel(value, data->membase + MDIO_SINGLE_DATA); 49533+ writel(MDIO_START_WRITE | ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | 49534+ ((u32)regnum), 49535+ data->membase + MDIO_SINGLE_CMD); 49536+ 49537+ return hisi_gemac_mdio_wait_ready(data); 49538+} 49539+ 49540+static void hisi_gemac_external_phy_reset(struct hisi_gemac_mdio_data const *data) 49541+{ 49542+ if (data->phy_rst) { 49543+ /* write 0 to cancel reset */ 49544+ reset_control_deassert(data->phy_rst); 49545+ msleep(50); 49546+ 49547+ /* HIFONE or 98cv200 use CRG register to reset phy */ 49548+ /* RST_BIT, write 0 to reset phy, write 1 to cancel reset */ 49549+ reset_control_assert(data->phy_rst); 49550+ 49551+ /* delay some time to ensure reset ok, 49552+ * this depends on PHY hardware feature 49553+ */ 49554+ msleep(50); 49555+ 49556+ /* write 0 to cancel reset */ 49557+ reset_control_deassert(data->phy_rst); 49558+ /* delay some time to ensure later MDIO access */ 49559+ msleep(50); 49560+ } else { 49561+#if defined(CONFIG_ARCH_HI3516A) 49562+#include <mach/hi3516a_io.h> 49563+#define GPIO_BASE_ETH_PHY_RESET 0x20140000 49564+#define GPIO_BIT_ETH_PHY_RESET 1 49565+ void __iomem *gpio_base; 49566+ u32 val; 49567+ 49568+ gpio_base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ETH_PHY_RESET); 49569+ /* use GPIO to do hardware PHY reset */ 49570+ /* set direction */ 49571+ val = readl(gpio_base + 0x400); 49572+ val |= (1 << GPIO_BIT_ETH_PHY_RESET); 49573+ writel(val, gpio_base + 0x400); 49574+ 49575+ /* Firstly, set to 1 regardless of the value of this pin */ 49576+ writel(0xFF, gpio_base + (4 << GPIO_BIT_ETH_PHY_RESET)); 49577+ msleep(20); 49578+ 49579+ /* Set to 0 to reset, then sleep 200ms */ 49580+ writel(0x0, gpio_base + (4 << GPIO_BIT_ETH_PHY_RESET)); 49581+ msleep(20); 49582+ 49583+ /* then, cancel reset, and should sleep 50ms */ 49584+ writel(0xFF, gpio_base + (4 << GPIO_BIT_ETH_PHY_RESET)); 49585+ msleep(200); 49586+#endif 49587+ } 49588+} 49589+ 49590+static int hisi_gemac_mdio_probe(struct platform_device *pdev) 49591+{ 49592+ struct device_node *np = pdev->dev.of_node; 49593+ struct mii_bus *bus = NULL; 49594+ struct hisi_gemac_mdio_data *data = NULL; 49595+ struct resource *res = NULL; 49596+ int ret; 49597+ 49598+ ret = hisi_gemac_pinctrl_config(pdev); 49599+ if (ret) { 49600+ pr_err("higmac pinctrl config error=%d.\n", ret); 49601+ return ret; 49602+ } 49603+ 49604+ bus = mdiobus_alloc_size(sizeof(*data)); 49605+ if (!bus) 49606+ return -ENOMEM; 49607+ 49608+ bus->name = "hisi_gemac_mii_bus"; 49609+ bus->read = &hisi_gemac_mdio_read; 49610+ bus->write = &hisi_gemac_mdio_write; 49611+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); 49612+ bus->parent = &pdev->dev; 49613+ 49614+ data = bus->priv; 49615+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 49616+ if (res == NULL || data == NULL) { 49617+ ret = -ENXIO; 49618+ goto err_out_free_mdiobus; 49619+ } 49620+ data->membase = devm_ioremap(&pdev->dev, res->start, 49621+ resource_size(res)); 49622+ if (!data->membase) { 49623+ ret = -ENOMEM; 49624+ goto err_out_free_mdiobus; 49625+ } 49626+ 49627+ data->clk = devm_clk_get(&pdev->dev, NULL); 49628+ if (IS_ERR(data->clk)) { 49629+ ret = PTR_ERR(data->clk); 49630+ goto err_out_free_mdiobus; 49631+ } 49632+ 49633+ ret = clk_prepare_enable(data->clk); 49634+ if (ret) 49635+ goto err_out_free_mdiobus; 49636+ 49637+ data->phy_rst = devm_reset_control_get(&pdev->dev, "phy_reset"); 49638+ if (IS_ERR(data->phy_rst)) 49639+ data->phy_rst = NULL; 49640+ hisi_gemac_external_phy_reset(data); 49641+ 49642+ ret = of_mdiobus_register(bus, np); 49643+ if (ret) 49644+ goto err_out_disable_clk; 49645+ 49646+ platform_set_drvdata(pdev, bus); 49647+ 49648+ return 0; 49649+ 49650+err_out_disable_clk: 49651+ clk_disable_unprepare(data->clk); 49652+err_out_free_mdiobus: 49653+ mdiobus_free(bus); 49654+ return ret; 49655+} 49656+ 49657+static int hisi_gemac_mdio_remove(struct platform_device *pdev) 49658+{ 49659+ struct mii_bus *bus = platform_get_drvdata(pdev); 49660+ struct hisi_gemac_mdio_data *data = bus->priv; 49661+ 49662+ mdiobus_unregister(bus); 49663+ clk_disable_unprepare(data->clk); 49664+ mdiobus_free(bus); 49665+ 49666+ return 0; 49667+} 49668+ 49669+static const struct of_device_id hisi_gemac_mdio_dt_ids[] = { 49670+ { .compatible = "hisilicon,hisi-gemac-mdio" }, 49671+ { } 49672+}; 49673+MODULE_DEVICE_TABLE(of, hisi_gemac_mdio_dt_ids); 49674+ 49675+static struct platform_driver hisi_gemac_mdio_driver = { 49676+ .probe = hisi_gemac_mdio_probe, 49677+ .remove = hisi_gemac_mdio_remove, 49678+ .driver = { 49679+ .name = "hisi-gemac-mdio", 49680+ .of_match_table = hisi_gemac_mdio_dt_ids, 49681+ }, 49682+}; 49683+ 49684+module_platform_driver(hisi_gemac_mdio_driver); 49685+ 49686+MODULE_DESCRIPTION("Hisilicon Gigabit Ethernet MAC MDIO interface driver"); 49687+MODULE_AUTHOR("Hisilicon>"); 49688+MODULE_LICENSE("GPL v2"); 49689diff --git a/drivers/net/phy/mdio_hisi_gemac.h b/drivers/net/phy/mdio_hisi_gemac.h 49690new file mode 100644 49691index 000000000..5eefc01e5 49692--- /dev/null 49693+++ b/drivers/net/phy/mdio_hisi_gemac.h 49694@@ -0,0 +1,32 @@ 49695+/* 49696+ * Hisilicon gemac pinout config headerfile. 49697+ * 49698+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved. 49699+ * 49700+ * This program is free software; you can redistribute it and/or modify 49701+ * it under the terms of the GNU General Public License as published by 49702+ * the Free Software Foundation; either version 2 of the License, or 49703+ * (at your option) any later version. 49704+ * 49705+ * This program is distributed in the hope that it will be useful, 49706+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 49707+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49708+ * GNU General Public License for more details. 49709+ * 49710+ * You should have received a copy of the GNU General Public License 49711+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 49712+ */ 49713+ 49714+#ifndef __MDIO_HISI_GEMAC_H__ 49715+#define __MDIO_HISI_GEMAC_H__ 49716+ 49717+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) 49718+int hisi_gemac_pinctrl_config(struct platform_device *pdev); 49719+#else 49720+static inline int hisi_gemac_pinctrl_config(struct platform_device *pdev) 49721+{ 49722+ return 0; 49723+} 49724+#endif 49725+ 49726+#endif /* __MDIO_HISI_GEMAC_H__ */ 49727diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c 49728index db7866b6f..413159372 100644 49729--- a/drivers/net/phy/phy.c 49730+++ b/drivers/net/phy/phy.c 49731@@ -260,6 +260,28 @@ static void phy_sanitize_settings(struct phy_device *phydev) 49732 } 49733 } 49734 49735+int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) 49736+{ 49737+ cmd->supported = phydev->supported; 49738+ 49739+ cmd->advertising = phydev->advertising; 49740+ cmd->lp_advertising = phydev->lp_advertising; 49741+ 49742+ ethtool_cmd_speed_set(cmd, phydev->speed); 49743+ cmd->duplex = phydev->duplex; 49744+ if (phydev->interface == PHY_INTERFACE_MODE_MOCA) 49745+ cmd->port = PORT_BNC; 49746+ else 49747+ cmd->port = PORT_MII; 49748+ cmd->phy_address = phydev->mdio.addr; 49749+ cmd->transceiver = phy_is_internal(phydev) ? 49750+ XCVR_INTERNAL : XCVR_EXTERNAL; 49751+ cmd->autoneg = phydev->autoneg; 49752+ cmd->eth_tp_mdix_ctrl = phydev->mdix; 49753+ 49754+ return 0; 49755+} 49756+EXPORT_SYMBOL(phy_ethtool_gset); 49757 void phy_ethtool_ksettings_get(struct phy_device *phydev, 49758 struct ethtool_link_ksettings *cmd) 49759 { 49760diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c 49761index b4879306b..cb7b1635c 100644 49762--- a/drivers/net/phy/realtek.c 49763+++ b/drivers/net/phy/realtek.c 49764@@ -29,6 +29,12 @@ 49765 #define RTL8211F_PHYCR1 0x18 49766 #define RTL8211F_INSR 0x1d 49767 49768+/* RTL8211F RGMII requires special TX delays depending 49769+ on the actual hardware circuit/wiring. 49770+ TXDLY register does not need to be set 49771+ when pin No.25 via 4.7k-ohm to DVDD-RG. 49772+*/ 49773+#define RTL8211F_RGMII_TX_DELAY_ENABLE 1 49774 #define RTL8211F_TX_DELAY BIT(8) 49775 #define RTL8211F_RX_DELAY BIT(3) 49776 49777@@ -185,6 +191,10 @@ static int rtl8211f_config_init(struct phy_device *phydev) 49778 u16 val; 49779 int ret; 49780 49781+#if RTL8211F_RGMII_TX_DELAY_ENABLE 49782+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII) 49783+ return ret; 49784+#endif 49785 val = RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_XTAL_OFF; 49786 phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1, val, val); 49787 49788diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c 49789index 0d374a294..9f2151377 100644 49790--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c 49791+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c 49792@@ -5806,6 +5806,7 @@ static int rtl8xxxu_submit_int_urb(struct ieee80211_hw *hw) 49793 ret = usb_submit_urb(urb, GFP_KERNEL); 49794 if (ret) { 49795 usb_unanchor_urb(urb); 49796+ usb_free_urb(urb); 49797 goto error; 49798 } 49799 49800diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig 49801index 0c473d75e..cb9f492fd 100644 49802--- a/drivers/pci/Kconfig 49803+++ b/drivers/pci/Kconfig 49804@@ -256,5 +256,6 @@ source "drivers/pci/hotplug/Kconfig" 49805 source "drivers/pci/controller/Kconfig" 49806 source "drivers/pci/endpoint/Kconfig" 49807 source "drivers/pci/switch/Kconfig" 49808+source "drivers/pci/hipcie/Kconfig" 49809 49810 endif 49811diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile 49812index 522d2b974..2b9167379 100644 49813--- a/drivers/pci/Makefile 49814+++ b/drivers/pci/Makefile 49815@@ -36,5 +36,6 @@ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ 49816 49817 obj-y += controller/ 49818 obj-y += switch/ 49819+obj-$(CONFIG_HIPCIE) += hipcie/ 49820 49821 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG 49822diff --git a/drivers/pci/hipcie/Kconfig b/drivers/pci/hipcie/Kconfig 49823new file mode 100644 49824index 000000000..c8d88ef66 49825--- /dev/null 49826+++ b/drivers/pci/hipcie/Kconfig 49827@@ -0,0 +1,27 @@ 49828+menuconfig HIPCIE 49829+ bool "Hisilicon PCI Express support" 49830+ depends on PCI && (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3559AV100 || ARCH_HI3531A || ARCH_HI3519AV100 || ARCH_HI3568V100 || ARCH_HI3569V100) 49831+ default y if PCI 49832+ default n if ! PCI 49833+ help 49834+ Hisilicon PCI Express support 49835+ Choose this selection to support PCI Express uses. 49836+ 49837+if HIPCIE 49838+ 49839+menu "PCI Express configs" 49840+ 49841+ 49842+config LIMIT_MAX_RD_REQ_SIZE 49843+ bool "limit pcie max read request size" 49844+ depends on PCI && (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3559AV100 || ARCH_HI3531A || ARCH_HI3519AV100 || ARCH_HI3568V100 || ARCH_HI3569V100) 49845+ help 49846+ The default max read request size of pcie device is 512 Byte. When pcie use 49847+ the card of pcie-to-sata to connect to the sata disk, with the default max read 49848+ request size value of 512 byte, would cause the low bandwidth of VDP. If you enable 49849+ the LIMIT_MAX_RD_REQ_SIZE config, the max read request size of pcie device would be 49850+ set to 128 byte, and the problem of VDP low band width also be avoided. 49851+ 49852+endmenu 49853+ 49854+endif 49855diff --git a/drivers/pci/hipcie/Makefile b/drivers/pci/hipcie/Makefile 49856new file mode 100644 49857index 000000000..04554201e 49858--- /dev/null 49859+++ b/drivers/pci/hipcie/Makefile 49860@@ -0,0 +1,8 @@ 49861+ 49862+obj-$(CONFIG_HIPCIE) += hipcie.o 49863+ 49864+hipcie-objs := pcie.o 49865+ 49866+ifeq ($(CONFIG_PCI_DEBUG),y) 49867+ EXTRA_CFLAGS += -DPCIE_DEBUG 49868+endif 49869diff --git a/drivers/pci/hipcie/pci.h b/drivers/pci/hipcie/pci.h 49870new file mode 100644 49871index 000000000..daefc0faf 49872--- /dev/null 49873+++ b/drivers/pci/hipcie/pci.h 49874@@ -0,0 +1,96 @@ 49875+/* 49876+ * arch/arm/include/asm/mach/pci.h 49877+ * 49878+ * Copyright (C) 2000 Russell King 49879+ * 49880+ * This program is free software; you can redistribute it and/or modify 49881+ * it under the terms of the GNU General Public License version 2 as 49882+ * published by the Free Software Foundation. 49883+ */ 49884+ 49885+#ifndef __ASM_MACH_PCI_H 49886+#define __ASM_MACH_PCI_H 49887+ 49888+#include <linux/ioport.h> 49889+ 49890+struct pci_sys_data; 49891+struct pci_ops; 49892+struct pci_bus; 49893+struct device; 49894+ 49895+#ifdef CONFIG_PCI_MSI 49896+#define HISI_PCI_MSI_NR (8 * 32) 49897+struct hisi_msi { 49898+ struct msi_controller chip; 49899+ DECLARE_BITMAP(used, HISI_PCI_MSI_NR); 49900+ struct irq_domain *domain; 49901+ unsigned long pages; 49902+ struct mutex lock; 49903+ int irq; 49904+}; 49905+#endif 49906+ 49907+struct hw_pci { 49908+#ifdef CONFIG_PCI_DOMAINS 49909+ int domain; 49910+#endif 49911+#ifdef CONFIG_PCI_MSI 49912+ struct hisi_msi msi; 49913+#endif 49914+ struct device *dev; 49915+ struct pci_ops *ops; 49916+ int nr_controllers; 49917+ void **private_data; 49918+ int (*setup)(int nr, struct pci_sys_data *); 49919+ struct pci_bus *(*scan)(int nr, struct pci_sys_data *); 49920+ void (*preinit)(void); 49921+ void (*postinit)(void); 49922+ u8 (*swizzle)(struct pci_dev *dev, u8 *pin); 49923+ int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); 49924+ resource_size_t (*align_resource)(struct pci_dev *dev, 49925+ const struct resource *res, 49926+ resource_size_t start, 49927+ resource_size_t size, 49928+ resource_size_t align); 49929+ void (*add_bus)(struct pci_bus *bus); 49930+ void (*remove_bus)(struct pci_bus *bus); 49931+}; 49932+ 49933+/* 49934+ * Per-controller structure 49935+ */ 49936+struct pci_sys_data { 49937+#ifdef CONFIG_PCI_DOMAINS 49938+ int domain; 49939+#endif 49940+ struct list_head node; 49941+ int busnr; /* primary bus number */ 49942+ u64 mem_offset; /* bus->cpu memory mapping offset */ 49943+ unsigned long io_offset; /* bus->cpu IO mapping offset */ 49944+ struct pci_bus *bus; /* PCI bus */ 49945+ struct list_head resources; /* root bus resources (apertures) */ 49946+ struct resource io_res; 49947+ char io_res_name[12]; 49948+ /* Bridge swizzling */ 49949+ u8 (*swizzle)(struct pci_dev *, u8 *); 49950+ /* IRQ mapping */ 49951+ int (*map_irq)(const struct pci_dev *, u8, u8); 49952+ /* Resource alignement requirements */ 49953+ resource_size_t (*align_resource)(struct pci_dev *dev, 49954+ const struct resource *res, 49955+ resource_size_t start, 49956+ resource_size_t size, 49957+ resource_size_t align); 49958+ void (*add_bus)(struct pci_bus *bus); 49959+ void (*remove_bus)(struct pci_bus *bus); 49960+ void *private_data; /* platform controller private data */ 49961+}; 49962+ 49963+void __weak pcibios_update_irq(struct pci_dev *dev, int irq) 49964+{ 49965+ dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq); 49966+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 49967+} 49968+ 49969+ 49970+#endif /* __ASM_MACH_PCI_H */ 49971diff --git a/drivers/pci/hipcie/pcie.c b/drivers/pci/hipcie/pcie.c 49972new file mode 100644 49973index 000000000..4c44b6b44 49974--- /dev/null 49975+++ b/drivers/pci/hipcie/pcie.c 49976@@ -0,0 +1,985 @@ 49977+/* 49978+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 49979+ * 49980+ * This program is free software; you can redistribute it and/or modify 49981+ * it under the terms of the GNU General Public License as published by 49982+ * the Free Software Foundation; either version 2 of the License, or 49983+ * (at your option) any later version. 49984+ * 49985+ * This program is distributed in the hope that it will be useful, 49986+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 49987+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49988+ * GNU General Public License for more details. 49989+ * 49990+ * You should have received a copy of the GNU General Public License 49991+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 49992+ */ 49993+ 49994+#include <linux/module.h> 49995+#include <linux/kernel.h> 49996+#include <linux/pci.h> 49997+#include <linux/mbus.h> 49998+#include <asm/irq.h> 49999+#include <linux/of.h> 50000+#include <linux/of_pci.h> 50001+#include <linux/platform_device.h> 50002+#include <linux/delay.h> 50003+#include <linux/spinlock.h> 50004+#include <linux/version.h> 50005+#include <asm/siginfo.h> 50006+#include <linux/interrupt.h> 50007+#include <linux/irq.h> 50008+#include <linux/irqdomain.h> 50009+#include <linux/msi.h> 50010+#include <linux/of_irq.h> 50011+#include "../pci.h" 50012+#ifdef CONFIG_ARM64 50013+#include "pci.h" 50014+#endif 50015+ 50016+#define PCIE_DBG_REG 1 50017+#define PCIE_DBG_FUNC 2 50018+#define PCIE_DBG_MODULE 3 50019+ 50020+#define PCIE_DEBUG_LEVEL PCIE_DBG_MODULE 50021+ 50022+/* #define PCIE_DEBUG */ 50023+#ifdef PCIE_DEBUG 50024+#define pcie_debug(level, str, arg...) \ 50025+ do { \ 50026+ if ((level) <= PCIE_DEBUG_LEVEL) { \ 50027+ pr_debug("%s->%d," str "\n", \ 50028+ __func__, __LINE__, ##arg); \ 50029+ } \ 50030+ } while (0) 50031+#else 50032+#define pcie_debug(level, str, arg...) 50033+#endif 50034+ 50035+#define pcie_assert(con) \ 50036+ do { \ 50037+ if (!(con)) { \ 50038+ pr_err("%s->%d,assert fail!\n", \ 50039+ __func__, __LINE__); \ 50040+ } \ 50041+ } while (0) 50042+ 50043+#define pcie_error(str, arg...) \ 50044+ pr_err("%s->%d" str "\n", __func__, __LINE__, ##arg) 50045+ 50046+#define __256MB__ 0x10000000 50047+#define __128MB__ 0x8000000 50048+#define __4KB__ 0x1000 50049+#define __8KB__ 0x2000 50050+#define __16KB__ 0x4000 50051+ 50052+enum pcie_sel { 50053+ /* 50054+ * No controller selected. 50055+ */ 50056+ pcie_sel_none, 50057+ /* 50058+ * PCIE0 selected. 50059+ */ 50060+ pcie0_x1_sel, 50061+ /* 50062+ * PCIE1 selected. 50063+ */ 50064+ pcie1_x1_sel 50065+}; 50066+ 50067+enum pcie_rc_sel { 50068+ pcie_controller_unselected, 50069+ pcie_controller_selected 50070+}; 50071+ 50072+enum pcie_controller { 50073+ pcie_controller_none = -1, 50074+ pcie_controller_0 = 0, 50075+ pcie_controller_1 = 1 50076+}; 50077+ 50078+struct pcie_iatu { 50079+ unsigned int viewport; /* iATU Viewport Register */ 50080+ unsigned int region_ctrl_1; /* Region Control 1 Register */ 50081+ unsigned int region_ctrl_2; /* Region Control 2 Register */ 50082+ unsigned int lbar; /* Lower Base Address Register */ 50083+ unsigned int ubar; /* Upper Base Address Register */ 50084+ unsigned int lar; /* Limit Address Register */ 50085+ unsigned int ltar; /* Lower Target Address Register */ 50086+ unsigned int utar; /* Upper Target Address Register */ 50087+}; 50088+ 50089+#define MAX_IATU_PER_CTRLLER (6) 50090+ 50091+struct pcie_info { 50092+ /* 50093+ * Root bus number 50094+ */ 50095+ int root_bus_nr; 50096+ enum pcie_controller controller; 50097+ 50098+ /* 50099+ * Devices configuration space base 50100+ */ 50101+ unsigned long base_addr; 50102+ 50103+ /* 50104+ * RC configuration space base 50105+ */ 50106+ unsigned long conf_base_addr; 50107+}; 50108+ 50109+#define MAX_PCIE_CONTROLLER_NUM 2 50110+static struct pcie_info pcie_info[MAX_PCIE_CONTROLLER_NUM] = { 50111+ { .root_bus_nr = -1, }, 50112+ { .root_bus_nr = -1, } 50113+}; 50114+ 50115+static int pcie_controllers_nr; 50116+ 50117+static unsigned int pcie_errorvalue; 50118+ 50119+struct device_node *g_of_node = NULL; 50120+ 50121+static DEFINE_SPINLOCK(cw_lock); 50122+ 50123+#define msi_contrl_interrupt 0x830 50124+#define MSI_CTRL_UPPER_ADDR_OFF 0x824 50125+#define MSI_CTRL_ADDR_OFF 0x820 50126+#define MSI_CTRL_INT_EN_OFF0 0x828 50127+#define MSI_CTRL_INT_EN_OFF1 0x834 50128+#define MSI_CTRL_INT_EN_OFF2 0x840 50129+#define MSI_CTRL_INT_EN_OFF3 0x84c 50130+#define MSI_CTRL_INT_EN_OFF4 0x858 50131+#define MSI_CTRL_INT_EN_OFF5 0x864 50132+#define MSI_CTRL_INT_EN_OFF6 0x870 50133+#define MSI_CTRL_INT_EN_OFF7 0x87c 50134+ 50135+#define PCIE0_MODE_SEL (1 << 0) 50136+#define PCIE1_MODE_SEL (1 << 1) 50137+ 50138+#if defined(CONFIG_ARCH_HI3531DV200) 50139+#include "pcie_hi3531dv200.c" 50140+#elif defined(CONFIG_ARCH_HI3535AV100) 50141+#include "pcie_hi3535av100.c" 50142+#elif defined(CONFIG_ARCH_HI3519AV100) 50143+#include "pcie_hi3519av100.c" 50144+#elif defined(CONFIG_ARCH_HI3559AV100) 50145+#include "pcie_hi3559av100.c" 50146+#else 50147+#error You must have defined CONFIG_ARCH_HI35xx... 50148+#endif 50149+ 50150+static struct pcie_info *bus_to_info(int busnr) 50151+{ 50152+ int i = pcie_controllers_nr; 50153+ for (; i >= 0; i--) { 50154+ if (pcie_info[i].controller != pcie_controller_none 50155+ && pcie_info[i].root_bus_nr <= busnr 50156+ && pcie_info[i].root_bus_nr != -1) 50157+ return &pcie_info[i]; 50158+ } 50159+ 50160+ return NULL; 50161+} 50162+ 50163+#define PCIE_CFG_BUS(busnr) ((busnr & 0xff) << 20) 50164+#define PCIE_CFG_DEV(devfn) ((devfn & 0xff) << 12) 50165+#define PCIE_CFG_REG(reg) (reg & 0xffc) /* set dword align */ 50166+ 50167+static inline unsigned long to_pcie_address(struct pci_bus *bus, 50168+ unsigned int devfn, int where) 50169+{ 50170+ struct pcie_info *info = bus_to_info(bus->number); 50171+ unsigned long address = 0; 50172+ 50173+ if (unlikely(!info)) { 50174+ pcie_error( 50175+ "%s:Cannot find corresponding controller for appointed device!", __func__); 50176+ BUG(); 50177+ } 50178+ 50179+ address = info->base_addr + (PCIE_CFG_BUS(bus->number) 50180+ | PCIE_CFG_DEV(devfn) | PCIE_CFG_REG((unsigned int)where)); 50181+ 50182+ return address; 50183+} 50184+ 50185+static inline int is_pcie_link_up(struct pcie_info *info) 50186+{ 50187+ int i; 50188+ 50189+ for (i = 0; i < 10000; i++) { 50190+ if (__arch_check_pcie_link(info)) 50191+ break; 50192+ udelay(100); 50193+ } 50194+ 50195+ return (i < 10000); 50196+} 50197+ 50198+static int pcie_read_from_device(struct pci_bus *bus, unsigned int devfn, 50199+ int where, int size, u32 *value) 50200+{ 50201+ struct pcie_info *info = bus_to_info(bus->number); 50202+ unsigned int val; 50203+ void __iomem *addr; 50204+ int i = 0; 50205+ 50206+ if (unlikely(!info)) { 50207+ pcie_error( 50208+ "%s:Cannot find corresponding controller for appointed device!", __func__); 50209+ BUG(); 50210+ } 50211+ if (!is_pcie_link_up(info)) { 50212+ pcie_debug(PCIE_DBG_MODULE, "pcie %d not link up!", 50213+ info->controller); 50214+ return -1; 50215+ } 50216+ 50217+ addr = (void __iomem *)(uintptr_t)to_pcie_address(bus, devfn, where); 50218+ 50219+ val = readl(addr); 50220+ 50221+ i = 0; 50222+ while (i < 2000) { 50223+ __asm__ __volatile__("nop\n"); 50224+ i++; 50225+ } 50226+ 50227+ if (pcie_errorvalue == 1) { 50228+ pcie_errorvalue = 0; 50229+ val = 0xffffffff; 50230+ } 50231+ 50232+ if (size == 1) 50233+ *value = ((val >> (((unsigned int)where & 0x3) << 3)) & 0xff); 50234+ else if (size == 2) 50235+ *value = ((val >> (((unsigned int)where & 0x3) << 3)) & 0xffff); 50236+ else if (size == 4) 50237+ *value = val; 50238+ else { 50239+ pcie_error("Unknown size(%d) for read ops", size); 50240+ BUG(); 50241+ } 50242+ 50243+ return PCIBIOS_SUCCESSFUL; 50244+} 50245+ 50246+static int pcie_read_from_dbi(struct pcie_info *info, unsigned int devfn, 50247+ int where, int size, u32 *value) 50248+{ 50249+ unsigned int val; 50250+ 50251+ /* 50252+ * For host-side config space read, ignore device func nr. 50253+ */ 50254+ if (devfn > 0) 50255+ return -EIO; 50256+ 50257+ val = (u32)readl((void *)(uintptr_t)(info->conf_base_addr + 50258+ ((unsigned int)where & (~0x3)))); 50259+ 50260+ if (1 == size) 50261+ *value = (val >> (((unsigned int)where & 0x3) << 3)) & 0xff; 50262+ else if (2 == size) 50263+ *value = (val >> (((unsigned int)where & 0x3) << 3)) & 0xffff; 50264+ else if (4 == size) 50265+ *value = val; 50266+ else { 50267+ pcie_error("Unknown size for config read operation!"); 50268+ BUG(); 50269+ } 50270+ 50271+ return PCIBIOS_SUCCESSFUL; 50272+} 50273+ 50274+static int pcie_read_conf(struct pci_bus *bus, unsigned int devfn, 50275+ int where, int size, u32 *value) 50276+{ 50277+ struct pcie_info *info = bus_to_info(bus->number); 50278+ int ret; 50279+ 50280+ if (unlikely(!info)) { 50281+ pcie_error( 50282+ "%s:Cannot find corresponding controller for appointed device!", __func__); 50283+ BUG(); 50284+ } 50285+ 50286+ if (bus->number == info->root_bus_nr) 50287+ ret = pcie_read_from_dbi(info, devfn, where, size, value); 50288+ else 50289+ ret = pcie_read_from_device(bus, devfn, where, size, value); 50290+ 50291+ pcie_debug(PCIE_DBG_REG, 50292+ "bus %d, devfn %d, where 0x%x, size 0x%x, value 0x%x", 50293+ bus->number & 0xff, devfn, where, size, *value); 50294+ 50295+ return ret; 50296+} 50297+ 50298+static int pcie_write_to_device(struct pci_bus *bus, unsigned int devfn, 50299+ int where, int size, u32 value) 50300+{ 50301+ struct pcie_info *info = bus_to_info(bus->number); 50302+ void __iomem *addr; 50303+ unsigned int org; 50304+ unsigned long flag; 50305+ 50306+ if (unlikely(!info)) { 50307+ pcie_error( 50308+ "%s:Cannot find corresponding controller for appointed device!", __func__); 50309+ BUG(); 50310+ } 50311+ 50312+ if (!is_pcie_link_up(info)) { 50313+ pcie_debug(PCIE_DBG_MODULE, "pcie %d not link up!", 50314+ info->controller); 50315+ return -1; 50316+ } 50317+ 50318+ spin_lock_irqsave(&cw_lock, flag); 50319+ 50320+ pcie_read_from_device(bus, devfn, where, 4, &org); 50321+ 50322+ addr = (void __iomem *)(uintptr_t)to_pcie_address(bus, devfn, where); 50323+ 50324+ if (size == 1) { 50325+ org &= (~(0xff << (((unsigned int)where & 0x3) << 3))); 50326+ org |= (value << (((unsigned int)where & 0x3) << 3)); 50327+ } else if (size == 2) { 50328+ org &= (~(0xffff << (((unsigned int)where & 0x3) << 3))); 50329+ org |= (value << (((unsigned int)where & 0x3) << 3)); 50330+ } else if (size == 4) { 50331+ org = value; 50332+ } else { 50333+ pcie_error("Unknown size(%d) for read ops", size); 50334+ BUG(); 50335+ } 50336+ 50337+ writel(org, addr); 50338+ 50339+ spin_unlock_irqrestore(&cw_lock, flag); 50340+ 50341+ return PCIBIOS_SUCCESSFUL; 50342+} 50343+ 50344+static int pcie_write_to_dbi(struct pcie_info *info, unsigned int devfn, 50345+ int where, int size, u32 value) 50346+{ 50347+ unsigned long flag; 50348+ unsigned int org; 50349+ 50350+ spin_lock_irqsave(&cw_lock, flag); 50351+ 50352+ if (pcie_read_from_dbi(info, devfn, (unsigned int)where, 4, &org)) { 50353+ pcie_error("Cannot read from dbi! 0x%x:0x%x:0x%x!", 50354+ 0, devfn, (unsigned int)where); 50355+ spin_unlock_irqrestore(&cw_lock, flag); 50356+ return -EIO; 50357+ } 50358+ if (size == 1) { 50359+ org &= (~(0xff << (((unsigned int)where & 0x3) << 3))); 50360+ org |= (value << (((unsigned int)where & 0x3) << 3)); 50361+ } else if (size == 2) { 50362+ org &= (~(0xffff << (((unsigned int)where & 0x3) << 3))); 50363+ org |= (value << (((unsigned int)where & 0x3) << 3)); 50364+ } else if (size == 4) { 50365+ org = value; 50366+ } else { 50367+ pcie_error("Unknown size(%d) for read ops", size); 50368+ BUG(); 50369+ } 50370+ writel(org, ((void __iomem *)(uintptr_t)info->conf_base_addr + 50371+ ((unsigned int)where & (~0x3)))); 50372+ 50373+ spin_unlock_irqrestore(&cw_lock, flag); 50374+ 50375+ return PCIBIOS_SUCCESSFUL; 50376+} 50377+ 50378+static int pcie_write_conf(struct pci_bus *bus, unsigned int devfn, 50379+ int where, int size, u32 value) 50380+{ 50381+ struct pcie_info *info = bus_to_info(bus->number); 50382+ 50383+ pcie_debug(PCIE_DBG_REG, 50384+ "bus %d, devfn %d, where 0x%x, size 0x%x, value 0x%x", 50385+ bus->number & 0xff, devfn, where, size, value); 50386+ 50387+ if (unlikely(!info)) { 50388+ pcie_error( 50389+ "%s:Cannot find corresponding controller for appointed device!", __func__); 50390+ BUG(); 50391+ } 50392+ 50393+ if (bus->number == info->root_bus_nr) 50394+ return pcie_write_to_dbi(info, devfn, where, size, value); 50395+ else 50396+ return pcie_write_to_device(bus, devfn, where, size, value); 50397+} 50398+ 50399+static struct pci_ops pcie_ops = { 50400+ .read = pcie_read_conf, 50401+ .write = pcie_write_conf, 50402+}; 50403+ 50404+void pci_set_max_rd_req_size(const struct pci_bus *bus) 50405+{ 50406+ struct pci_dev *dev = NULL; 50407+ struct pci_bus *child = NULL; 50408+ int pos; 50409+ unsigned short dev_contrl_reg_val = 0; 50410+ unsigned int max_rd_req_size = 0; 50411+ 50412+ list_for_each_entry(dev, &bus->devices, bus_list) { 50413+ /* set device max read requset size */ 50414+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP); 50415+ if (pos) { 50416+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, 50417+ &dev_contrl_reg_val); 50418+ max_rd_req_size = (dev_contrl_reg_val >> 12) & 0x7; 50419+ if (max_rd_req_size > 0x0) { 50420+ dev_contrl_reg_val &= ~(max_rd_req_size << 12); 50421+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, 50422+ dev_contrl_reg_val); 50423+ } 50424+ } 50425+ } 50426+ 50427+ list_for_each_entry(dev, &bus->devices, bus_list) { 50428+ BUG_ON(!dev->is_probed); 50429+ child = dev->subordinate; 50430+ if (child) 50431+ pci_set_max_rd_req_size(child); 50432+ } 50433+} 50434+ 50435+#ifdef CONFIG_PCI_MSI 50436+int pci_msi_is_enable(struct platform_device *pdev) 50437+{ 50438+ int msi_irq; 50439+ 50440+ msi_irq = platform_get_irq_byname(pdev, "msi"); 50441+ if (msi_irq < 0) { 50442+ return false; 50443+ } 50444+ 50445+ return true; 50446+} 50447+#endif 50448+ 50449+#ifdef CONFIG_ARM64 50450+ 50451+static int pci_common_init(struct platform_device *pdev, struct hw_pci *hipcie) 50452+{ 50453+ struct device_node *dn = pdev->dev.of_node; 50454+ struct pcie_info *info = NULL; 50455+ struct pci_bus *bus = NULL; 50456+ resource_size_t io_addr; 50457+ int ret; 50458+ int pcie_contrl = -1; 50459+ int bus_start; 50460+ 50461+ LIST_HEAD(res); 50462+ 50463+ ret = of_property_read_u32(dn, "pcie_controller", &pcie_contrl); 50464+ if (ret) { 50465+ pr_err("%s:No pcie_controller found!\n", __func__); 50466+ return -EINVAL; 50467+ } 50468+ 50469+ if (pcie_contrl == 0) 50470+ bus_start = 0; 50471+ else 50472+ bus_start = 0x2; 50473+ 50474+ ret = devm_of_pci_get_host_bridge_resources(&pdev->dev, bus_start, 0xff, &res, 50475+ &io_addr); 50476+ if (ret) 50477+ return ret; 50478+ bus = pci_create_root_bus(&pdev->dev, bus_start, &pcie_ops, hipcie, &res); 50479+ if (!bus) 50480+ return -ENOMEM; 50481+ 50482+#ifdef CONFIG_PCI_MSI 50483+ if (pci_msi_is_enable(pdev)) { 50484+ bus->msi = &hipcie->msi.chip; 50485+ } 50486+#endif 50487+ 50488+#ifdef CONFIG_LIMIT_MAX_RD_REQ_SIZE 50489+ pci_set_max_rd_req_size(bus); 50490+#endif 50491+ 50492+ pcie_info[pcie_contrl].root_bus_nr = bus->number; 50493+ info = bus_to_info(bus->number); 50494+ if (info != NULL) 50495+ __arch_config_iatu_tbl(info, NULL); 50496+ 50497+ pci_scan_child_bus(bus); 50498+ pci_assign_unassigned_bus_resources(bus); 50499+ pci_bus_add_devices(bus); 50500+ 50501+ platform_set_drvdata(pdev, hipcie); 50502+ 50503+ return 0; 50504+} 50505+#else 50506+static int pci_common_init_bvt(struct platform_device *pdev, 50507+ struct hw_pci *hipcie) 50508+{ 50509+ struct device_node *dn = pdev->dev.of_node; 50510+ struct pcie_info *info = NULL; 50511+ struct pci_bus *bus = NULL; 50512+ resource_size_t io_addr; 50513+ int ret; 50514+ int pcie_contrl; 50515+ int bus_start; 50516+ 50517+ LIST_HEAD(res); 50518+ 50519+ ret = of_property_read_u32(dn, "pcie_controller", &pcie_contrl); 50520+ if (ret) { 50521+ pr_err("%s:No pcie_controller found!\n", __func__); 50522+ return -EINVAL; 50523+ } 50524+ 50525+ if (pcie_contrl == 0) 50526+ bus_start = 0; 50527+ else 50528+ bus_start = 2; 50529+ 50530+ ret = devm_of_pci_get_host_bridge_resources(&pdev->dev, bus_start, 0xff, &res, &io_addr); 50531+ if (ret) 50532+ return ret; 50533+ 50534+ bus = pci_create_root_bus(&pdev->dev, bus_start, &pcie_ops, hipcie, &res); 50535+ if (!bus) 50536+ return -ENOMEM; 50537+ 50538+#ifdef CONFIG_PCI_MSI 50539+ if (pci_msi_is_enable(pdev)) { 50540+ bus->msi = &hipcie->msi.chip; 50541+ } 50542+#endif 50543+ 50544+#ifdef CONFIG_LIMIT_MAX_RD_REQ_SIZE 50545+ pci_set_max_rd_req_size(bus); 50546+#endif 50547+ 50548+ pcie_info[pcie_contrl].root_bus_nr = bus->number; 50549+ info = bus_to_info(bus->number); 50550+ if (info != NULL) { 50551+ __arch_config_iatu_tbl(info, NULL); 50552+ } 50553+ 50554+ pci_scan_child_bus(bus); 50555+ pci_assign_unassigned_bus_resources(bus); 50556+ pci_bus_add_devices(bus); 50557+ 50558+ platform_set_drvdata(pdev, hipcie); 50559+ 50560+ return 0; 50561+} 50562+#endif 50563+ 50564+#ifdef CONFIG_PCI_MSI 50565+static inline struct hisi_msi *to_hisi_msi(struct msi_controller *chip) 50566+{ 50567+ return container_of(chip, struct hisi_msi, chip); 50568+} 50569+ 50570+static int hisi_msi_alloc(struct hisi_msi *chip) 50571+{ 50572+ int msi; 50573+ 50574+ mutex_lock(&chip->lock); 50575+ 50576+ msi = find_first_zero_bit(chip->used, HISI_PCI_MSI_NR); 50577+ if (msi < HISI_PCI_MSI_NR) 50578+ set_bit(msi, chip->used); 50579+ else 50580+ msi = -ENOSPC; 50581+ 50582+ mutex_unlock(&chip->lock); 50583+ 50584+ return msi; 50585+} 50586+ 50587+static void hisi_msi_free(struct hisi_msi *chip, unsigned long irq) 50588+{ 50589+ struct device *dev = chip->chip.dev; 50590+ 50591+ mutex_lock(&chip->lock); 50592+ 50593+ if (!test_bit(irq, chip->used)) 50594+ dev_err(dev, "trying to free unused MSI#%lu\n", irq); 50595+ else 50596+ clear_bit(irq, chip->used); 50597+ 50598+ mutex_unlock(&chip->lock); 50599+} 50600+ 50601+static irqreturn_t hisi_pcie_msi_irq(int irq, void *data) 50602+{ 50603+ struct hw_pci *hi_pcie = data; 50604+ struct device *dev = hi_pcie->dev; 50605+ struct hisi_msi *msi = &hi_pcie->msi; 50606+ unsigned int i; 50607+ unsigned int processed = 0; 50608+ void *dbi_base = (void *)(uintptr_t) 50609+ pcie_info[hi_pcie->nr_controllers].conf_base_addr; 50610+ 50611+ for (i = 0; i < 8; i++) { 50612+ unsigned long reg = readl(dbi_base + 0x830 + i * 0xc); 50613+ 50614+ while (reg) { 50615+ unsigned int offset = find_first_bit(®, 32); 50616+ unsigned int index = i * 32 + offset; 50617+ unsigned int irq; 50618+ 50619+ /* clear the interrupt */ 50620+ writel(1 << offset, dbi_base + msi_contrl_interrupt + i * 0xc); 50621+ 50622+ irq = irq_find_mapping(msi->domain, index); 50623+ if (irq) { 50624+ if (test_bit(index, msi->used)) { 50625+ generic_handle_irq(irq); 50626+ } else 50627+ dev_info(dev, "unhandled MSI\n"); 50628+ } else { 50629+ /* 50630+ * * that's weird who triggered this? 50631+ * * just clear it 50632+ * */ 50633+ dev_info(dev, "unexpected MSI\n"); 50634+ } 50635+ 50636+ /* see if there's any more pending in this vector */ 50637+ reg = readl(dbi_base + msi_contrl_interrupt + i * 0xc); 50638+ processed++; 50639+ } 50640+ } 50641+ return processed > 0 ? IRQ_HANDLED : IRQ_NONE; 50642+} 50643+ 50644+static int hisi_msi_setup_irq(struct msi_controller *chip, 50645+ struct pci_dev *pdev, struct msi_desc *desc) 50646+{ 50647+ struct hisi_msi *msi = to_hisi_msi(chip); 50648+ struct msi_msg msg; 50649+ unsigned int irq; 50650+ int hwirq; 50651+ 50652+ if (pdev->bus->number == pcie_info[0].root_bus_nr || 50653+ pdev->bus->number == pcie_info[1].root_bus_nr) 50654+ return 0; 50655+ 50656+ hwirq = hisi_msi_alloc(msi); 50657+ if (hwirq < 0) 50658+ return hwirq; 50659+ 50660+ irq = irq_create_mapping(msi->domain, hwirq); 50661+ if (!irq) { 50662+ hisi_msi_free(msi, hwirq); 50663+ return -EINVAL; 50664+ } 50665+ 50666+ irq_set_msi_desc(irq, desc); 50667+ 50668+ desc->msi_attrib.multiple = 0x5; 50669+ 50670+ msg.address_lo = virt_to_phys((void *)(uintptr_t)msi->pages); 50671+ msg.address_hi = (virt_to_phys((void *)(uintptr_t)msi->pages) >> 32); 50672+ msg.data = hwirq; 50673+ 50674+ pci_write_msi_msg(irq, &msg); 50675+ 50676+ return 0; 50677+} 50678+ 50679+static void hisi_msi_teardown_irq(struct msi_controller *chip, 50680+ unsigned int irq) 50681+{ 50682+ struct hisi_msi *msi = to_hisi_msi(chip); 50683+ struct irq_data *d = irq_get_irq_data(irq); 50684+ irq_hw_number_t hwirq = 0; 50685+ 50686+ if (d != NULL) 50687+ hwirq = irqd_to_hwirq(d); 50688+ 50689+ irq_dispose_mapping(irq); 50690+ hisi_msi_free(msi, hwirq); 50691+} 50692+ 50693+static struct irq_chip hisi_msi_irq_chip = { 50694+ .name = "HISI PCIe MSI", 50695+ .irq_enable = pci_msi_unmask_irq, 50696+ .irq_disable = pci_msi_mask_irq, 50697+ .irq_mask = pci_msi_mask_irq, 50698+ .irq_unmask = pci_msi_unmask_irq, 50699+}; 50700+ 50701+static int hisi_msi_map(struct irq_domain *domain, unsigned int irq, 50702+ irq_hw_number_t hwirq) 50703+{ 50704+ irq_set_chip_and_handler(irq, &hisi_msi_irq_chip, handle_simple_irq); 50705+ irq_set_chip_data(irq, domain->host_data); 50706+ 50707+ return 0; 50708+} 50709+ 50710+static const struct irq_domain_ops msi_domain_ops = { 50711+ .map = hisi_msi_map, 50712+}; 50713+ 50714+static int hisi_pcie_enable_msi(struct hw_pci *pcie) 50715+{ 50716+ struct device *dev = pcie->dev; 50717+ struct platform_device *pdev = to_platform_device(dev); 50718+ struct hisi_msi *msi = &pcie->msi; 50719+ unsigned long base; 50720+ int err; 50721+ 50722+ void *dbi_base = (void *)(uintptr_t) 50723+ pcie_info[pcie->nr_controllers].conf_base_addr; 50724+ 50725+ if (!msi) { 50726+ dev_err(dev, "msi is null, error.\n"); 50727+ return -EINVAL; 50728+ } 50729+ 50730+ mutex_init(&msi->lock); 50731+ 50732+ msi->chip.dev = dev; 50733+ msi->chip.setup_irq = hisi_msi_setup_irq; 50734+ msi->chip.teardown_irq = hisi_msi_teardown_irq; 50735+ 50736+ msi->domain = irq_domain_add_linear(dev->of_node, HISI_PCI_MSI_NR, 50737+ &msi_domain_ops, &msi->chip); 50738+ if (!msi->domain) { 50739+ dev_err(dev, "failed to create IRQ domain\n"); 50740+ return -ENOMEM; 50741+ } 50742+ 50743+ err = platform_get_irq_byname(pdev, "msi"); 50744+ if (err < 0) { 50745+ dev_err(dev, "failed to get IRQ: %d\n", err); 50746+ goto err; 50747+ } 50748+ 50749+ msi->irq = err; 50750+ 50751+ err = request_irq(msi->irq, hisi_pcie_msi_irq, IRQF_NO_THREAD, 50752+ hisi_msi_irq_chip.name, pcie); 50753+ if (err < 0) { 50754+ dev_err(dev, "failed to request IRQ: %d\n", err); 50755+ goto err; 50756+ } 50757+ 50758+ /* setup AFI/FPCI range */ 50759+ msi->pages = __get_free_pages(GFP_KERNEL, 0); 50760+ base = virt_to_phys((void *)(uintptr_t)msi->pages); 50761+ 50762+ writel(base >> 32, dbi_base + MSI_CTRL_UPPER_ADDR_OFF); 50763+ writel(base, dbi_base + MSI_CTRL_ADDR_OFF); 50764+ 50765+ /* enable all MSI vectors */ 50766+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF0); 50767+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF1); 50768+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF2); 50769+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF3); 50770+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF4); 50771+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF5); 50772+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF6); 50773+ writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF7); 50774+ 50775+ return 0; 50776+ 50777+err: 50778+ irq_domain_remove(msi->domain); 50779+ return err; 50780+} 50781+ 50782+static int hisi_pcie_disable_msi(struct hw_pci *pcie) 50783+{ 50784+ struct hisi_msi *msi = &pcie->msi; 50785+ unsigned int i, irq; 50786+ void *dbi_base = (void *)(uintptr_t) 50787+ pcie_info[pcie->nr_controllers].conf_base_addr; 50788+ 50789+ /* disable all MSI vectors */ 50790+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF0); 50791+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF1); 50792+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF2); 50793+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF3); 50794+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF4); 50795+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF5); 50796+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF6); 50797+ writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF7); 50798+ 50799+ free_pages(msi->pages, 0); 50800+ 50801+ if (msi->irq > 0) 50802+ free_irq(msi->irq, pcie); 50803+ 50804+ for (i = 0; i < HISI_PCI_MSI_NR; i++) { 50805+ irq = irq_find_mapping(msi->domain, i); 50806+ if (irq > 0) 50807+ irq_dispose_mapping(irq); 50808+ } 50809+ 50810+ irq_domain_remove(msi->domain); 50811+ 50812+ return 0; 50813+} 50814+#endif 50815+ 50816+static int __init pcie_init(struct platform_device *pdev) 50817+{ 50818+ int err; 50819+ struct hw_pci *hipcie = NULL; 50820+ 50821+ if (!pdev) { 50822+ pr_err("pdev is null!\n"); 50823+ return -ENOMEM; 50824+ } 50825+ 50826+ hipcie = kzalloc(sizeof(struct hw_pci), GFP_KERNEL); 50827+ if (!hipcie) { 50828+ pr_err("kzalloc hw_pci space failed!\n"); 50829+ return -ENOMEM; 50830+ } 50831+ 50832+ hipcie->dev = &pdev->dev; 50833+ 50834+ g_of_node = pdev->dev.of_node; 50835+ if (!g_of_node) { 50836+ pr_err("get node from dts failed! controller:%d\n", pcie_controllers_nr); 50837+ kfree(hipcie); 50838+ return -EIO; 50839+ } 50840+ 50841+ err = of_property_read_u32(g_of_node, "pcie_controller", &pcie_controllers_nr); 50842+ if (err) { 50843+ pr_err("%s:No pcie_controller found!\n", __func__); 50844+ kfree(hipcie); 50845+ return -EINVAL; 50846+ } 50847+ 50848+ if (__arch_pcie_info_setup(pcie_info, &pcie_controllers_nr)) { 50849+ kfree(hipcie); 50850+ return -EIO; 50851+ } 50852+ 50853+ if (pcie_controllers_nr >= MAX_PCIE_CONTROLLER_NUM) { 50854+ pr_err("pcie_controllers_nr is Invalid, pcie_controllers_nr: %d\n", 50855+ pcie_controllers_nr); 50856+ kfree(hipcie); 50857+ return -EINVAL; 50858+ } 50859+ 50860+ if (__arch_pcie_sys_init(&pcie_info[pcie_controllers_nr])) 50861+ goto pcie_init_err; 50862+ 50863+ hipcie->nr_controllers = pcie_controllers_nr; 50864+ pr_err("Number of PCIe controllers: %d\n", 50865+ hipcie->nr_controllers); 50866+ 50867+#ifdef CONFIG_PCI_MSI 50868+ if (pci_msi_is_enable(pdev)) { 50869+ err = hisi_pcie_enable_msi(hipcie); 50870+ if (err < 0) { 50871+ pr_err("failed to enable MSI support: %d\n", err); 50872+ goto pcie_init_err; 50873+ } 50874+ } 50875+#endif 50876+ 50877+#ifdef CONFIG_ARM64 50878+ err = pci_common_init(pdev, hipcie); 50879+#else 50880+ err = pci_common_init_bvt(pdev, hipcie); 50881+#endif 50882+ 50883+ if (err) 50884+ goto disable_msi; 50885+ 50886+ return 0; 50887+ 50888+disable_msi: 50889+#ifdef CONFIG_PCI_MSI 50890+ if (pci_msi_is_enable(pdev)) 50891+ hisi_pcie_disable_msi(hipcie); 50892+#endif 50893+pcie_init_err: 50894+ __arch_pcie_info_release(&pcie_info[pcie_controllers_nr]); 50895+ 50896+ kfree(hipcie); 50897+ 50898+ return -EIO; 50899+} 50900+ 50901+static int __exit pcie_uinit(struct platform_device *pdev) 50902+{ 50903+ __arch_pcie_info_release(pcie_info); 50904+ return 0; 50905+} 50906+ 50907+#include <linux/platform_device.h> 50908+#include <linux/pm.h> 50909+ 50910+int hisi_pcie_plat_driver_probe(struct platform_device *pdev) 50911+{ 50912+ return 0; 50913+} 50914+int hisi_pcie_plat_driver_remove(struct platform_device *pdev) 50915+{ 50916+ return 0; 50917+} 50918+ 50919+#ifdef CONFIG_PM 50920+int hisi_pcie_plat_driver_suspend(struct device *dev) 50921+{ 50922+ __arch_pcie_sys_exit(); 50923+ return 0; 50924+} 50925+ 50926+int hisi_pcie_plat_driver_resume(struct device *dev) 50927+{ 50928+ return __arch_pcie_sys_init(pcie_info); 50929+} 50930+ 50931+const struct dev_pm_ops hisi_pcie_pm_ops = { 50932+ .suspend = NULL, 50933+ .suspend_noirq = hisi_pcie_plat_driver_suspend, 50934+ .resume = NULL, 50935+ .resume_noirq = hisi_pcie_plat_driver_resume 50936+}; 50937+ 50938+#define HISI_PCIE_PM_OPS (&hisi_pcie_pm_ops) 50939+#else 50940+#define HISI_PCIE_PM_OPS NULL 50941+#endif 50942+ 50943+#define PCIE_RC_DRV_NAME "hisi pcie root complex" 50944+ 50945+static const struct of_device_id hisi_pcie_match_table[] = { 50946+ { .compatible = "hisilicon,hisi-pcie", }, 50947+ {}, 50948+}; 50949+ 50950+static struct platform_driver hisi_pcie_driver = { 50951+ .driver = { 50952+ .name = "hisi-pcie", 50953+ .owner = THIS_MODULE, 50954+ .of_match_table = of_match_ptr(hisi_pcie_match_table), 50955+ }, 50956+ .probe = pcie_init, 50957+}; 50958+module_platform_driver(hisi_pcie_driver); 50959+ 50960+MODULE_DESCRIPTION("Hisilicon PCI-Express Root Complex driver"); 50961+MODULE_LICENSE("GPL"); 50962diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c 50963index 8b587fc97..07482a509 100644 50964--- a/drivers/pci/pci-driver.c 50965+++ b/drivers/pci/pci-driver.c 50966@@ -19,6 +19,7 @@ 50967 #include <linux/kexec.h> 50968 #include <linux/of_device.h> 50969 #include <linux/acpi.h> 50970+#include <linux/of_pci.h> 50971 #include <linux/dma-map-ops.h> 50972 #include "pci.h" 50973 #include "pcie/portdrv.h" 50974@@ -394,6 +395,9 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) 50975 50976 int __weak pcibios_alloc_irq(struct pci_dev *dev) 50977 { 50978+#ifdef CONFIG_SATA_AHCI 50979+ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); 50980+#endif 50981 return 0; 50982 } 50983 50984diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig 50985index 9ed5f167a..533d43e77 100644 50986--- a/drivers/phy/Kconfig 50987+++ b/drivers/phy/Kconfig 50988@@ -83,5 +83,6 @@ source "drivers/phy/tegra/Kconfig" 50989 source "drivers/phy/ti/Kconfig" 50990 source "drivers/phy/intel/Kconfig" 50991 source "drivers/phy/xilinx/Kconfig" 50992+source "drivers/phy/hibvt/Kconfig" 50993 50994 endmenu 50995diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile 50996index 6eb291677..38a096b29 100644 50997--- a/drivers/phy/Makefile 50998+++ b/drivers/phy/Makefile 50999@@ -9,6 +9,7 @@ obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o 51000 obj-$(CONFIG_PHY_XGENE) += phy-xgene.o 51001 obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o 51002 obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o 51003+obj-$(CONFIG_ARCH_HISI_BVT) += hibvt/ 51004 obj-y += allwinner/ \ 51005 amlogic/ \ 51006 broadcom/ \ 51007diff --git a/drivers/phy/hibvt/Kconfig b/drivers/phy/hibvt/Kconfig 51008new file mode 100644 51009index 000000000..9fcb56c1c 51010--- /dev/null 51011+++ b/drivers/phy/hibvt/Kconfig 51012@@ -0,0 +1,23 @@ 51013+config PHY_HISI_SATA 51014+ tristate "Hisilicon sata phy support" 51015+ depends on (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3521DV200 || ARCH_HI3520DV500) && OF && HAS_IOMEM 51016+ default n 51017+ select GENERIC_PHY 51018+ help 51019+ Enable this to support the sata phy that is part of 51020+ sata driver for hisilicon 51021+ 51022+config HISI_SATA_MODE 51023+ int "Hisi sata interworking speed mode(1.5G:0/3G:1/6G:2)" 51024+ depends on PHY_HISI_SATA 51025+ help 51026+ Hisilicon sata interworking speed mode 51027+ 51028+menuconfig HI_USB_PHY 51029+ tristate "HiSilicon USB support" 51030+ 51031+if HI_USB_PHY 51032+ 51033+source "drivers/phy/hibvt/usb/Kconfig" 51034+ 51035+endif # HI_USB_PHY 51036diff --git a/drivers/phy/hibvt/Makefile b/drivers/phy/hibvt/Makefile 51037new file mode 100644 51038index 000000000..7b038f48e 51039--- /dev/null 51040+++ b/drivers/phy/hibvt/Makefile 51041@@ -0,0 +1,5 @@ 51042+# 51043+# Makefile for the phy drivers. 51044+# 51045+obj-$(CONFIG_PHY_HISI_SATA) += phy-hisi-sata.o 51046+obj-y += usb/ 51047diff --git a/drivers/phy/hibvt/phy-hisi-sata.c b/drivers/phy/hibvt/phy-hisi-sata.c 51048new file mode 100644 51049index 000000000..d7384fec3 51050--- /dev/null 51051+++ b/drivers/phy/hibvt/phy-hisi-sata.c 51052@@ -0,0 +1,175 @@ 51053+/* 51054+ * Copyright (c) 2016-2019 HiSilicon Technologies Co., Ltd. 51055+ * 51056+ * This program is free software; you can redistribute it and/or modify it 51057+ * under the terms of the GNU General Public License as published by the 51058+ * Free Software Foundation; either version 2 of the License, or (at your 51059+ * option) any later version. 51060+ * 51061+ * This program is distributed in the hope that it will be useful, 51062+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 51063+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51064+ * GNU General Public License for more details. 51065+ * 51066+ * You should have received a copy of the GNU General Public License 51067+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 51068+ * 51069+ */ 51070+ 51071+#include <linux/delay.h> 51072+#include <linux/io.h> 51073+#include <linux/module.h> 51074+#include <linux/phy/phy.h> 51075+#include <linux/platform_device.h> 51076+#include <linux/io.h> 51077+ 51078+static unsigned int phy_mode = CONFIG_HISI_SATA_MODE; 51079+static unsigned int ports_num; 51080+unsigned int sata_port_map; 51081+ 51082+#ifdef MODULE 51083+module_param(mode_3g, uint, 0600); 51084+MODULE_PARM_DESC(phy_mode, "sata phy mode (0:1.5G;1:3G(default);2:6G)"); 51085+#endif 51086+ 51087+#ifdef CONFIG_ARCH_HI3531DV200 51088+#include "phy-hi3531dv200-sata.c" 51089+#endif 51090+ 51091+#ifdef CONFIG_ARCH_HI3535AV100 51092+#include "phy-hi3535av100-sata.c" 51093+#endif 51094+ 51095+#ifdef CONFIG_ARCH_HI3521DV200 51096+#include "phy-hi3521dv200-sata.c" 51097+#endif 51098+ 51099+#ifdef CONFIG_ARCH_HI3520DV500 51100+#include "phy-hi3521dv200-sata.c" 51101+#endif 51102+ 51103+static int hisi_sata_phy_init(struct phy *phy) 51104+{ 51105+ unsigned int sata_port_num = 0; 51106+ void __iomem *mmio = phy_get_drvdata(phy); 51107+ 51108+ sata_port_num = hisi_sata_get_port_info(); 51109+ if ((sata_port_num < 1)) { 51110+ pr_err("sata ports number:%d WRONG!!!\n", sata_port_num); 51111+ return -EINVAL; 51112+ } 51113+ ports_num = sata_port_num; 51114+ 51115+ hisi_sata_poweron(); 51116+ hisi_sata_reset(); 51117+ hisi_sata_phy_reset(); 51118+ hisi_sata_phy_clk_sel(); 51119+ hisi_sata_clk_enable(); 51120+ msleep(20); 51121+ hisi_sata_phy_unreset(); 51122+ msleep(20); 51123+ hisi_sata_unreset(); 51124+ msleep(20); 51125+ hisi_sata_phy_config(mmio, phy_mode); 51126+ 51127+ return 0; 51128+} 51129+ 51130+static int hisi_sata_phy_exit(struct phy *phy) 51131+{ 51132+ hisi_sata_phy_reset(); 51133+ msleep(20); 51134+ hisi_sata_reset(); 51135+ msleep(20); 51136+ hisi_sata_clk_reset(); 51137+ msleep(20); 51138+ hisi_sata_clk_disable(); 51139+ hisi_sata_poweroff(); 51140+ msleep(20); 51141+ 51142+ return 0; 51143+} 51144+ 51145+static struct phy_ops hisi_sata_phy_ops = { 51146+ .init = hisi_sata_phy_init, 51147+ .exit = hisi_sata_phy_exit, 51148+ .owner = THIS_MODULE, 51149+}; 51150+ 51151+static int hisi_sata_phy_probe(struct platform_device *pdev) 51152+{ 51153+ struct phy_provider *phy_provider = NULL; 51154+ struct device *dev = &pdev->dev; 51155+ struct resource *res = NULL; 51156+ struct phy *phy = NULL; 51157+ void __iomem *mmio = NULL; 51158+ 51159+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 51160+ if (!res) { 51161+ dev_err(dev, "failed to get reg base\n"); 51162+ return -ENOENT; 51163+ } 51164+ 51165+ mmio = devm_ioremap(dev, res->start, resource_size(res)); 51166+ if (!mmio) 51167+ return -ENOMEM; 51168+ 51169+ phy = devm_phy_create(dev, NULL, &hisi_sata_phy_ops); 51170+ if (IS_ERR(phy)) { 51171+ dev_err(dev, "failed to create PHY\n"); 51172+ return PTR_ERR(phy); 51173+ } 51174+ 51175+ of_property_read_u32(dev->of_node, "ports_num_max", &ports_num); 51176+ 51177+ phy_set_drvdata(phy, mmio); 51178+ 51179+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 51180+ if (IS_ERR(phy_provider)) 51181+ return PTR_ERR(phy_provider); 51182+ 51183+ return 0; 51184+} 51185+ 51186+static int hisi_sata_phy_suspend(struct platform_device *pdev, 51187+ pm_message_t state) 51188+{ 51189+ struct device *dev = &pdev->dev; 51190+ struct phy *phy = to_phy(dev); 51191+ 51192+ hisi_sata_phy_exit(phy); 51193+ 51194+ return 0; 51195+} 51196+ 51197+static int hisi_sata_phy_resume(struct platform_device *pdev) 51198+{ 51199+ struct device *dev = &pdev->dev; 51200+ struct phy *phy = to_phy(dev); 51201+ 51202+ hisi_sata_phy_init(phy); 51203+ 51204+ return 0; 51205+} 51206+ 51207+static const struct of_device_id hisi_sata_phy_of_match[] = { 51208+ { .compatible = "hisilicon,hisi-sata-phy", }, 51209+ { }, 51210+}; 51211+MODULE_DEVICE_TABLE(of, hisi_sata_phy_of_match); 51212+ 51213+static struct platform_driver hisi_sata_phy_driver = { 51214+ .probe = hisi_sata_phy_probe, 51215+ .suspend = hisi_sata_phy_suspend, 51216+ .resume = hisi_sata_phy_resume, 51217+ .driver = { 51218+ .name = "hisi-sata-phy", 51219+ .of_match_table = hisi_sata_phy_of_match, 51220+ } 51221+}; 51222+module_platform_driver(hisi_sata_phy_driver); 51223+ 51224+MODULE_AUTHOR("HiSilicon BVT"); 51225+MODULE_DESCRIPTION("HISILICON SATA PHY driver"); 51226+MODULE_ALIAS("platform:hisi-sata-phy"); 51227+MODULE_LICENSE("GPL v2"); 51228diff --git a/drivers/phy/hibvt/phy-hisi-sata.h b/drivers/phy/hibvt/phy-hisi-sata.h 51229new file mode 100644 51230index 000000000..44730c519 51231--- /dev/null 51232+++ b/drivers/phy/hibvt/phy-hisi-sata.h 51233@@ -0,0 +1,39 @@ 51234+/* 51235+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 51236+ * 51237+ * This program is free software; you can redistribute it and/or modify it 51238+ * under the terms of the GNU General Public License as published by the 51239+ * Free Software Foundation; either version 2 of the License, or (at your 51240+ * option) any later version. 51241+ * 51242+ * This program is distributed in the hope that it will be useful, 51243+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 51244+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51245+ * GNU General Public License for more details. 51246+ * 51247+ * You should have received a copy of the GNU General Public License 51248+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 51249+ * 51250+ */ 51251+ 51252+enum { 51253+ /* hisi extended global controller registers */ 51254+ PHY_CTL0 = 0xA0, 51255+ PHY_CTL1 = 0xA4, 51256+ PHY_RST_BACK_MASK = 0xAC, 51257+ PHY_CTL2 = 0xB0, 51258+ 51259+#define PHY_DATA_INVERT (0x1 << 3) 51260+#define PHY0_RST_MASK (0x1 << 4) 51261+#define PHY_RST_MASK_ALL (0xF << 4) 51262+ 51263+ /* hisi extended registers for each SATA port */ 51264+ PORT_FIFOTH = 0x44, 51265+ PORT_FIFOTH2 = 0x7C, 51266+ PORT_PHYCTL1 = 0x48, 51267+ PORT_PHYCTL = 0x74, 51268+ 51269+#define PHY_MODE_1_5G 0 51270+#define PHY_MODE_3G 1 51271+#define PHY_MODE_6G 2 51272+}; 51273diff --git a/drivers/phy/hibvt/usb/Kconfig b/drivers/phy/hibvt/usb/Kconfig 51274new file mode 100644 51275index 000000000..c7b5ab6e7 51276--- /dev/null 51277+++ b/drivers/phy/hibvt/usb/Kconfig 51278@@ -0,0 +1,85 @@ 51279+# 51280+# Phy drivers for Hisilicon platforms 51281+# 51282+config PHY_HISI_USB2 51283+ bool 51284+ depends on (!ARCH_HI3559AV100 && !ARCH_HI3569V100 && !ARCH_HI3516EV200 && \ 51285+ !ARCH_HI3516EV300 && !ARCH_HI3518EV300 && !ARCH_HI3516DV200) 51286+ default y 51287+ help 51288+ Support for PHY on Hisilicon Socs. This Phy supports 51289+ USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one 51290+ USB host port to accept one USB device. Support init the phy 51291+ and adjust phy Eye Diagram. 51292+ 51293+config PHY_HISI_USB3 51294+ bool 51295+ depends on (ARCH_HI3519AV100 || ARCH_HI3556AV100 || ARCH_HI3559AV100 || \ 51296+ ARCH_HI3569V100 || ARCH_HI3568V100 || ARCH_HI3531DV200 || \ 51297+ ARCH_HI3535AV100) 51298+ default y 51299+ help 51300+ Support for PHY on Hisilicon Socs. This Phy supports 51301+ USB3.0 and Compatible with USB2.0. It suppots one 51302+ USB host port to accept one USB device. Support init the phy 51303+ and adjust phy Eye Diagram. 51304+ 51305+config HIBVT_USB_PHY 51306+ bool "Hisilicon USB PHY driver" 51307+ depends on (!ARCH_HI3516EV200 && !ARCH_HI3516EV300 && !ARCH_HI3518EV300 && \ 51308+ !ARCH_HI3516DV200) 51309+ default y 51310+ help 51311+ Support for PHY on Hisilicon Socs. This Phy supports 51312+ USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one 51313+ USB host port to accept one USB device. Support init the phy 51314+ and adjust phy Eye Diagram. 51315+ 51316+config PHY_HISI_XVP_USB2 51317+ tristate "Hisilicon XVP USB2 PHY Driver" 51318+ depends on (ARCH_HI3516EV200 || ARCH_HI3516EV300 || ARCH_HI3518EV300 || \ 51319+ ARCH_HI3516DV200) 51320+ select GENERIC_PHY 51321+ default y 51322+ help 51323+ Support for PHY on Hisilicon Socs. This Phy supports 51324+ USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one 51325+ USB host port to accept one USB device. Support init the phy 51326+ and adjust phy Eye Diagram. 51327+ 51328+menuconfig USB_MODE_OPTION 51329+ bool "Hisilicon USB related configuration" 51330+ depends on (!ARCH_HI3516EV200 && !ARCH_HI3516EV300 && !ARCH_HI3518EV300 && \ 51331+ !ARCH_HI3516DV200 && !ARCH_HI3531DV200 && !ARCH_HI3535AV100 && \ 51332+ !ARCH_HI3521DV200 && !ARCH_HI3520DV500) 51333+ 51334+if USB_MODE_OPTION 51335+ 51336+config USB_DRD0_IN_HOST 51337+ bool "USB DRD0 Mode Select HOST" 51338+ help 51339+ Select whether the USB drd0 is working in host mode. 51340+ 51341+config USB_DRD0_IN_DEVICE 51342+ bool "USB DRD0 Mode Select DEVICE" 51343+ depends on (!ARCH_HI3531DV200 && !ARCH_HI3535AV100 && !ARCH_HI3521DV200 && \ 51344+ !ARCH_HI3520DV500) 51345+ help 51346+ Select whether the USB drd0 is working in device mode. 51347+ 51348+config USB_DRD1_IN_HOST 51349+ bool "USB DRD1 Mode Select HOST" 51350+ depends on (ARCH_HI3519AV100 || ARCH_HI3556AV100 || ARCH_HI3559AV100 || \ 51351+ ARCH_HI3569V100 || ARCH_HI3568V100) 51352+ help 51353+ Select whether the USB drd1 is working in host mode. 51354+ 51355+config USB_DRD1_IN_DEVICE 51356+ bool "USB DRD1 Mode Select DEVICE" 51357+ depends on (!USB_DRD1_IN_HOST && !USB_DRD0_IN_DEVICE) 51358+ depends on (ARCH_HI3519AV100 || ARCH_HI3556AV100 || ARCH_HI3559AV100 || \ 51359+ ARCH_HI3569V100 || ARCH_HI3568V100) 51360+ help 51361+ Select whether the USB drd1 is working in device mode. 51362+ 51363+endif # USB_MODE_OPTION 51364diff --git a/drivers/phy/hibvt/usb/Makefile b/drivers/phy/hibvt/usb/Makefile 51365new file mode 100644 51366index 000000000..dc9e8d71f 51367--- /dev/null 51368+++ b/drivers/phy/hibvt/usb/Makefile 51369@@ -0,0 +1,17 @@ 51370+obj-$(CONFIG_HIBVT_USB_PHY) += phy-hisi-usb.o 51371+obj-$(CONFIG_ARCH_HI3531DV200) += phy-hi3531dv200-usb.o 51372+obj-$(CONFIG_ARCH_HI3535AV100) += phy-hi3531dv200-usb.o 51373+obj-$(CONFIG_ARCH_HI3521DV200) += phy-hi3521dv200-usb.o 51374+obj-$(CONFIG_ARCH_HI3520DV500) += phy-hi3521dv200-usb.o 51375+obj-$(CONFIG_ARCH_HI3559AV100) += phy-hi3559av100-usb.o 51376+obj-$(CONFIG_ARCH_HI3569V100) += phy-hi3559av100-usb.o 51377+obj-$(CONFIG_ARCH_HI3556AV100) += phy-hi3556av100-usb.o 51378+obj-$(CONFIG_ARCH_HI3519AV100) += phy-hi3519av100-usb.o 51379+obj-$(CONFIG_ARCH_HI3568V100) += phy-hi3519av100-usb.o 51380+obj-$(CONFIG_ARCH_HI3516CV500) += phy-hi3516cv500-usb.o 51381+obj-$(CONFIG_ARCH_HI3516DV300) += phy-hi3516dv300-usb.o 51382+obj-$(CONFIG_ARCH_HI3559V200) += phy-hi3559v200-usb.o 51383+obj-$(CONFIG_ARCH_HI3562V100) += phy-hi3559v200-usb.o 51384+obj-$(CONFIG_ARCH_HI3566V100) += phy-hi3559v200-usb.o 51385+obj-$(CONFIG_ARCH_HI3556V200) += phy-hi3556v200-usb.o 51386+obj-$(CONFIG_PHY_HISI_XVP_USB2) += phy-hixvp-hisi-usb.o 51387diff --git a/drivers/phy/hibvt/usb/phy-hi3516dv300-usb.c b/drivers/phy/hibvt/usb/phy-hi3516dv300-usb.c 51388new file mode 100644 51389index 000000000..ba232b259 51390--- /dev/null 51391+++ b/drivers/phy/hibvt/usb/phy-hi3516dv300-usb.c 51392@@ -0,0 +1,310 @@ 51393+/* 51394+ * phy-hi3516dv300-usb.c 51395+ * 51396+ * USB phy driver. 51397+ * 51398+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved. 51399+ * 51400+ * This program is free software; you can redistribute it and/or modify 51401+ * it under the terms of the GNU General Public License as published by 51402+ * the Free Software Foundation; either version 2 of the License, or 51403+ * (at your option) any later version. 51404+ * 51405+ * This program is distributed in the hope that it will be useful, 51406+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 51407+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51408+ * GNU General Public License for more details. 51409+ * 51410+ * You should have received a copy of the GNU General Public License 51411+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 51412+ */ 51413+ 51414+#include <linux/delay.h> 51415+#include <linux/of_address.h> 51416+#include <linux/phy/phy.h> 51417+#include <linux/usb/ch9.h> 51418+ 51419+#include "phy-hisi-usb.h" 51420+ 51421+#define CRG_BASE_REG 0x140 51422+#define USB2_UTMI_PCTRL (0x1 << 15) 51423+#define USB2_PHY_TEST_SRST_REQ (0x1 << 14) 51424+#define USB2_UTMI_CKSEL (0x1 << 13) 51425+#define USB2_UTMI_CKEN (0x1 << 12) 51426+#define USB2_REF_CKEN (0x1 << 9) 51427+#define USB2_BUS_CKEN (0x1 << 8) 51428+#define USB2_VCC_SRST_REQ (0x1 << 3) 51429+#define USB2_PHY_CKEN (0x1 << 2) 51430+#define USB2_PHY_PORT_TREQ (0x1 << 1) 51431+#define USB2_PHY_REQ (0x1 << 0) 51432+ 51433+#define CTRL_BASE_REG 0x100e0000 51434+ 51435+#define REG_GUSB3PIPECTL0 0xc2c0 51436+#define PCS_SSP_SOFT_RESET (0x1 << 31) 51437+#define PORT_DISABLE_SUSPEND (0x1 << 17) 51438+ 51439+#define REG_GCTL 0xc110 51440+#define PORT_CAP_DIR (0x3 << 12) 51441+#define PORT_SET_HOST (0x1 << 12) 51442+ 51443+#define GTXTHRCFG 0xc108 51444+#define USB2_G_TXTHRCFG 0x23100000 51445+ 51446+#define GRXTHRCFG 0xc10c 51447+#define USB2_G_RXTHRCFG 0x23100000 51448+ 51449+#define REG_GUCTL1 0xc11c 51450+#define PARKMODE_DISABLE_FSLS (0x1 << 15) 51451+#define PARKMODE_DISABLE_HS (0x1 << 16) 51452+#define PARKMODE_DISABLE_SS (0x1 << 17) 51453+ 51454+#define USB2_INNO_PHY_BASE_REG 0x10110000 51455+#define USB2_PHY_CLK_OUTPUT_REG 0x18 51456+#define USB2_PHY_CLK_OUTPUT_VAL 0x0c 51457+#define USB2_INNO_TRIM_OFFSET 0x0c 51458+ 51459+#define USB2_VBUS_IO_BASE_REG 0x10ff0000 51460+#define USB2_VBUS_IO_OFFSET 0x40 51461+#define USB2_VBUS_IO_VAL 0x431 51462+ 51463+#define USB_TRIM_BASE_REG 0x100a0000 51464+#define USB_TRIM_OFFSET 0x38 51465+#define USB_INNO_TRIM_MASK 0x7c 51466+#define USB_INNO_TRIM_VAL(a) (((a) << 2) & USB_INNO_TRIM_MASK) 51467+#define USB_TRIM_VAL_MASK 0x1f 51468+#define USB_TRIM_VAL_MIN 0xf 51469+#define USB_TRIM_VAL_MAX 0x1c 51470+ 51471+#define HS_HIGH_HEIGHT_TUNING_OFFSET 0x8 51472+#define HS_HIGH_HEIGHT_TUNING_MASK (0x7 << 4) 51473+#define HS_HIGH_HEIGHT_TUNING_VAL 0x5 << 4 51474+ 51475+#define PRE_EMPHASIS_TUNING_OFFSET 0x0 51476+#define PRE_EMPHASIS_TUNING_MASK (0x7 << 0) 51477+#define PRE_EMPHASIS_TUNING_VAL 0x7 << 0 51478+ 51479+#define PRE_EMPHASIS_STRENGTH_OFFSET 0x14 51480+#define PRE_EMPHASIS_STRENGTH_MASK (0x7 << 2) 51481+#define PRE_EMPHASIS_STRENGTH_VAL 0x3 << 2 51482+ 51483+#define HS_SLEW_RATE_TUNING_OFFSET 0x74 51484+#define HS_SLEW_RATE_TUNING_MASK (0x7 << 1) 51485+#define HS_SLEW_RATE_TUNING_VAL 0x7 << 1 51486+ 51487+#define DISCONNECT_TRIGGER_OFFSET 0x10 51488+#define DISCONNECT_TRIGGER_MASK (0xf << 4) 51489+#define DISCONNECT_TRIGGER_VAL 0xd << 4 51490+ 51491+static void usb_vbus_multi_gpio(void) 51492+{ 51493+ void __iomem *vbus = ioremap(USB2_VBUS_IO_BASE_REG, __1K__); 51494+ if (vbus == NULL) 51495+ return; 51496+ 51497+ writel(USB2_VBUS_IO_VAL, vbus + USB2_VBUS_IO_OFFSET); 51498+ udelay(U_LEVEL2); 51499+ 51500+ iounmap(vbus); 51501+} 51502+ 51503+static void usb_trim_c(void) 51504+{ 51505+ unsigned int reg; 51506+ unsigned int trim_val; 51507+ void __iomem *inno_clk_output = NULL; 51508+ void __iomem *usb_trim = NULL; 51509+ 51510+ inno_clk_output = ioremap(USB2_INNO_PHY_BASE_REG, __1K__); 51511+ if (inno_clk_output == NULL) 51512+ return; 51513+ 51514+ usb_trim = ioremap(USB_TRIM_BASE_REG, __1K__); 51515+ if (usb_trim == NULL) 51516+ goto free; 51517+ 51518+ /* set inno phy output clock */ 51519+ writel(USB2_PHY_CLK_OUTPUT_VAL, inno_clk_output + USB2_PHY_CLK_OUTPUT_REG); 51520+ udelay(U_LEVEL2); 51521+ 51522+ /* 51523+ * USB Trim config:45ohm HS ODT value tuning & FS/LS 51524+ * driver strength tuning, adapt it to usb trim val. 51525+ */ 51526+ trim_val = readl(usb_trim + USB_TRIM_OFFSET); 51527+ trim_val &= USB_TRIM_VAL_MASK; 51528+ if ((trim_val >= USB_TRIM_VAL_MIN) && (trim_val <= USB_TRIM_VAL_MAX)) { 51529+ reg = readl(inno_clk_output + USB2_INNO_TRIM_OFFSET); 51530+ udelay(U_LEVEL2); 51531+ reg &= ~USB_INNO_TRIM_MASK; 51532+ reg |= USB_INNO_TRIM_VAL(trim_val); 51533+ writel(reg, inno_clk_output + USB2_INNO_TRIM_OFFSET); 51534+ udelay(U_LEVEL2); 51535+ } 51536+ 51537+ iounmap(usb_trim); 51538+free: 51539+ iounmap(inno_clk_output); 51540+ return; 51541+} 51542+ 51543+static void usb_crg_c(struct phy *phy) 51544+{ 51545+ unsigned int reg; 51546+ struct hisi_priv *priv = phy_get_drvdata(phy); 51547+ 51548+ /* usb phy reset */ 51549+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51550+ reg |= USB2_PHY_TEST_SRST_REQ; 51551+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51552+ udelay(U_LEVEL5); 51553+ 51554+ /* cancel usb phy srst */ 51555+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51556+ reg &= ~USB2_PHY_TEST_SRST_REQ; 51557+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51558+ udelay(U_LEVEL2); 51559+ 51560+ /* usb2 vcc reset */ 51561+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51562+ reg |= USB2_VCC_SRST_REQ; 51563+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51564+ udelay(U_LEVEL6); 51565+ 51566+ usb_trim_c(); 51567+ 51568+ /* open phy ref cken, utmi pctrl and utmi cksel */ 51569+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51570+ reg |= USB2_PHY_CKEN; 51571+ reg &= ~USB2_UTMI_PCTRL; 51572+ reg &= ~USB2_UTMI_CKSEL; 51573+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51574+ udelay(U_LEVEL1); 51575+ 51576+ /* open utmi cken and controller ref cken */ 51577+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51578+ reg |= USB2_UTMI_CKEN; 51579+ reg |= USB2_REF_CKEN; 51580+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51581+ udelay(U_LEVEL1); 51582+ 51583+ /* open bus cken */ 51584+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51585+ reg |= USB2_BUS_CKEN; 51586+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51587+ udelay(U_LEVEL6); 51588+ 51589+ /* cancel POR reset, TPOR reset and vcc reset */ 51590+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51591+ reg &= ~USB2_PHY_REQ; 51592+ reg &= ~USB2_PHY_PORT_TREQ; 51593+ reg &= ~USB2_VCC_SRST_REQ; 51594+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51595+ udelay(U_LEVEL6); 51596+} 51597+ 51598+static void usb_ctrl_c(struct phy *phy) 51599+{ 51600+ unsigned int reg; 51601+ struct hisi_priv *priv = phy_get_drvdata(phy); 51602+ 51603+ priv->ctrl_base = ioremap(CTRL_BASE_REG, __64K__); 51604+ if (priv->ctrl_base == NULL) 51605+ return; 51606+ 51607+ reg = readl(priv->ctrl_base + REG_GUCTL1); 51608+ reg |= PARKMODE_DISABLE_FSLS; 51609+ reg |= PARKMODE_DISABLE_HS; 51610+ reg |= PARKMODE_DISABLE_SS; 51611+ writel(reg, priv->ctrl_base + REG_GUCTL1); 51612+ udelay(U_LEVEL2); 51613+ 51614+ reg = readl(priv->ctrl_base + REG_GUSB3PIPECTL0); 51615+ reg |= PCS_SSP_SOFT_RESET; 51616+ writel(reg, priv->ctrl_base + REG_GUSB3PIPECTL0); 51617+ udelay(U_LEVEL2); 51618+ 51619+ reg = readl(priv->ctrl_base + REG_GCTL); 51620+ reg &= ~PORT_CAP_DIR; 51621+ reg |= PORT_SET_HOST; /* [13:12] 01: Host; 10: Device; 11: OTG */ 51622+ writel(reg, priv->ctrl_base + REG_GCTL); 51623+ udelay(U_LEVEL2); 51624+ 51625+ reg = readl(priv->ctrl_base + REG_GUSB3PIPECTL0); 51626+ reg &= ~PCS_SSP_SOFT_RESET; 51627+ reg &= ~PORT_DISABLE_SUSPEND; /* disable suspend */ 51628+ writel(reg, priv->ctrl_base + REG_GUSB3PIPECTL0); 51629+ udelay(U_LEVEL2); 51630+ 51631+ writel(USB2_G_TXTHRCFG, priv->ctrl_base + GTXTHRCFG); 51632+ writel(USB2_G_RXTHRCFG, priv->ctrl_base + GRXTHRCFG); 51633+ udelay(U_LEVEL2); 51634+ 51635+ iounmap(priv->ctrl_base); 51636+} 51637+ 51638+static void usb_eye_c(struct phy *phy) 51639+{ 51640+ unsigned int reg; 51641+ void __iomem *inno_base = NULL; 51642+ 51643+ inno_base = ioremap(USB2_INNO_PHY_BASE_REG, __1K__); 51644+ if (inno_base == NULL) 51645+ return; 51646+ 51647+ /* HS eye height tuning */ 51648+ reg = readl(inno_base + HS_HIGH_HEIGHT_TUNING_OFFSET); 51649+ reg &= ~HS_HIGH_HEIGHT_TUNING_MASK; 51650+ reg |= HS_HIGH_HEIGHT_TUNING_VAL; 51651+ writel(reg, inno_base + HS_HIGH_HEIGHT_TUNING_OFFSET); 51652+ 51653+ /* Pre-emphasis tuning */ 51654+ reg = readl(inno_base + PRE_EMPHASIS_TUNING_OFFSET); 51655+ reg &= ~PRE_EMPHASIS_TUNING_MASK; 51656+ reg |= PRE_EMPHASIS_TUNING_VAL; 51657+ writel(reg, inno_base + PRE_EMPHASIS_TUNING_OFFSET); 51658+ 51659+ /* Pre-emphasis strength */ 51660+ reg = readl(inno_base + PRE_EMPHASIS_STRENGTH_OFFSET); 51661+ reg &= ~PRE_EMPHASIS_STRENGTH_MASK; 51662+ reg |= PRE_EMPHASIS_STRENGTH_VAL; 51663+ writel(reg, inno_base + PRE_EMPHASIS_STRENGTH_OFFSET); 51664+ 51665+ /* HS driver slew rate tunning */ 51666+ reg = readl(inno_base + HS_SLEW_RATE_TUNING_OFFSET); 51667+ reg &= ~HS_SLEW_RATE_TUNING_MASK; 51668+ reg |= HS_SLEW_RATE_TUNING_VAL; 51669+ writel(reg, inno_base + HS_SLEW_RATE_TUNING_OFFSET); 51670+ 51671+ /* HOST disconnects detection trigger point */ 51672+ reg = readl(inno_base + DISCONNECT_TRIGGER_OFFSET); 51673+ reg &= ~DISCONNECT_TRIGGER_MASK; 51674+ reg |= DISCONNECT_TRIGGER_VAL; 51675+ writel(reg, inno_base + DISCONNECT_TRIGGER_OFFSET); 51676+ iounmap(inno_base); 51677+} 51678+ 51679+void hisi_usb_phy_on(struct phy *phy) 51680+{ 51681+ usb_crg_c(phy); 51682+ 51683+ usb_vbus_multi_gpio(); 51684+ 51685+ usb_eye_c(phy); 51686+ 51687+ usb_ctrl_c(phy); 51688+} 51689+EXPORT_SYMBOL(hisi_usb_phy_on); 51690+ 51691+void hisi_usb_phy_off(struct phy *phy) 51692+{ 51693+ unsigned int reg; 51694+ struct hisi_priv *priv = phy_get_drvdata(phy); 51695+ 51696+ /* usb2 vcc reset */ 51697+ reg = readl(priv->peri_crg + CRG_BASE_REG); 51698+ reg |= USB2_VCC_SRST_REQ; 51699+ writel(reg, priv->peri_crg + CRG_BASE_REG); 51700+ udelay(U_LEVEL6); 51701+} 51702+EXPORT_SYMBOL(hisi_usb_phy_off); 51703diff --git a/drivers/phy/hibvt/usb/phy-hisi-usb.c b/drivers/phy/hibvt/usb/phy-hisi-usb.c 51704new file mode 100644 51705index 000000000..da83abdf9 51706--- /dev/null 51707+++ b/drivers/phy/hibvt/usb/phy-hisi-usb.c 51708@@ -0,0 +1,149 @@ 51709+/* 51710+ * phy-hisi-usb.c 51711+ * 51712+ * USB phy driver. 51713+ * 51714+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved. 51715+ * 51716+ * This program is free software; you can redistribute it and/or modify 51717+ * it under the terms of the GNU General Public License as published by 51718+ * the Free Software Foundation; either version 2 of the License, or 51719+ * (at your option) any later version. 51720+ * 51721+ * This program is distributed in the hope that it will be useful, 51722+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 51723+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51724+ * GNU General Public License for more details. 51725+ * 51726+ * You should have received a copy of the GNU General Public License 51727+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 51728+ */ 51729+ 51730+#include <linux/module.h> 51731+#include <linux/phy/phy.h> 51732+#include <linux/platform_device.h> 51733+#include <linux/of_address.h> 51734+ 51735+#include "phy-hisi-usb.h" 51736+ 51737+static int hisi_usb_phy_probe(struct platform_device *pdev) 51738+{ 51739+ struct device *dev = &pdev->dev; 51740+ struct phy *phy = NULL; 51741+ struct hisi_priv *priv = NULL; 51742+ struct device_node *np = pdev->dev.of_node; 51743+ 51744+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 51745+ if (priv == NULL) 51746+ return -ENOMEM; 51747+ 51748+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); 51749+ if (phy == NULL) { 51750+ devm_kfree(dev, priv); 51751+ return -ENOMEM; 51752+ } 51753+ 51754+ priv->peri_crg = of_iomap(np, CRG_NODE_IDX); 51755+ if (IS_ERR(priv->peri_crg)) 51756+ priv->peri_crg = NULL; 51757+ 51758+ priv->misc_ctrl = of_iomap(np, MISC_NODE_IDX); 51759+ if (IS_ERR(priv->misc_ctrl)) 51760+ priv->misc_ctrl = NULL; 51761+ 51762+ priv->sys_ctrl = of_iomap(np, SYS_NODE_IDX); 51763+ if (IS_ERR(priv->sys_ctrl)) 51764+ priv->sys_ctrl = NULL; 51765+ 51766+ priv->ctrl_base = of_iomap(np, CTRL_NODE_IDX); 51767+ if (IS_ERR(priv->ctrl_base)) 51768+ priv->ctrl_base = NULL; 51769+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 51770+ if (of_property_read_u32(np, "phyid", &priv->phyid)) 51771+ return -EINVAL; 51772+#endif 51773+ platform_set_drvdata(pdev, phy); 51774+ phy_set_drvdata(phy, priv); 51775+ 51776+#ifdef CONFIG_PHY_HISI_USB2 51777+ hisi_usb_phy_on(phy); 51778+#endif 51779+#ifdef CONFIG_PHY_HISI_USB3 51780+ hisi_usb3_phy_on(phy); 51781+#endif 51782+ iounmap(priv->peri_crg); 51783+ iounmap(priv->misc_ctrl); 51784+ iounmap(priv->sys_ctrl); 51785+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 51786+ iounmap(priv->ctrl_base); 51787+#endif 51788+ 51789+ return 0; 51790+} 51791+ 51792+static int hisi_usb_phy_remove(struct platform_device *pdev) 51793+{ 51794+ struct device *dev = &pdev->dev; 51795+ struct phy *phy = dev_get_drvdata(&pdev->dev); 51796+ struct hisi_priv *priv = phy_get_drvdata(phy); 51797+ 51798+#ifdef CONFIG_PHY_HISI_USB2 51799+ hisi_usb_phy_off(phy); 51800+#endif 51801+#ifdef CONFIG_PHY_HISI_USB3 51802+ hisi_usb3_phy_off(phy); 51803+#endif 51804+ devm_kfree(dev, priv); 51805+ devm_kfree(dev, phy); 51806+ 51807+ return 0; 51808+} 51809+ 51810+static const struct of_device_id hisi_usb_phy_of_match[] = { 51811+ { .compatible = "hisilicon,hisi-usb-phy", }, 51812+ { .compatible = "hisilicon,hisi-usb3-phy_0", }, 51813+ { .compatible = "hisilicon,hisi-usb3-phy_1", }, 51814+ { }, 51815+}; 51816+MODULE_DEVICE_TABLE(of, hisi_usb_phy_of_match); 51817+ 51818+#ifdef CONFIG_PM_SLEEP 51819+static int hisi_usb_phy_suspend(struct device *dev) 51820+{ 51821+ struct phy *phy = dev_get_drvdata(dev); 51822+#ifdef CONFIG_PHY_HISI_USB2 51823+ hisi_usb_phy_off(phy); 51824+#endif 51825+#ifdef CONFIG_PHY_HISI_USB3 51826+ hisi_usb3_phy_off(phy); 51827+#endif 51828+ return 0; 51829+} 51830+ 51831+static int hisi_usb_phy_resume(struct device *dev) 51832+{ 51833+ struct phy *phy = dev_get_drvdata(dev); 51834+#ifdef CONFIG_PHY_HISI_USB2 51835+ hisi_usb_phy_on(phy); 51836+#endif 51837+#ifdef CONFIG_PHY_HISI_USB3 51838+ hisi_usb3_phy_on(phy); 51839+#endif 51840+ return 0; 51841+} 51842+#endif /* CONFIG_PM_SLEEP */ 51843+ 51844+static SIMPLE_DEV_PM_OPS(hisi_usb_pm_ops, hisi_usb_phy_suspend, 51845+ hisi_usb_phy_resume); 51846+ 51847+static struct platform_driver hisi_usb_phy_driver = { 51848+ .probe = hisi_usb_phy_probe, 51849+ .remove = hisi_usb_phy_remove, 51850+ .driver = { 51851+ .name = "hisi-usb-phy", 51852+ .pm = &hisi_usb_pm_ops, 51853+ .of_match_table = hisi_usb_phy_of_match, 51854+ } 51855+}; 51856+module_platform_driver(hisi_usb_phy_driver); 51857+MODULE_LICENSE("GPL v2"); 51858diff --git a/drivers/phy/hibvt/usb/phy-hisi-usb.h b/drivers/phy/hibvt/usb/phy-hisi-usb.h 51859new file mode 100644 51860index 000000000..5e20e6e4a 51861--- /dev/null 51862+++ b/drivers/phy/hibvt/usb/phy-hisi-usb.h 51863@@ -0,0 +1,72 @@ 51864+/* 51865+ * phy-hisi-usb.h 51866+ * 51867+ * USB phy driver headerfile. 51868+ * 51869+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved. 51870+ * 51871+ * This program is free software; you can redistribute it and/or modify 51872+ * it under the terms of the GNU General Public License as published by 51873+ * the Free Software Foundation; either version 2 of the License, or 51874+ * (at your option) any later version. 51875+ * 51876+ * This program is distributed in the hope that it will be useful, 51877+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 51878+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51879+ * GNU General Public License for more details. 51880+ * 51881+ * You should have received a copy of the GNU General Public License 51882+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 51883+ */ 51884+ 51885+#ifndef USB2_INCLUDE_PHY_H 51886+#define USB2_INCLUDE_PHY_H 51887+ 51888+extern void hisi_usb_phy_on(struct phy *phy); 51889+extern void hisi_usb_phy_off(struct phy *phy); 51890+extern void hisi_usb3_phy_on(struct phy *phy); 51891+extern void hisi_usb3_phy_off(struct phy *phy); 51892+ 51893+struct hisi_priv { 51894+ void __iomem *peri_crg; 51895+ void __iomem *misc_ctrl; 51896+ void __iomem *sys_ctrl; 51897+ void __iomem *ctrl_base; 51898+ unsigned int phyid; 51899+}; 51900+ 51901+typedef enum mode { 51902+ PCIE_X2 = 0, 51903+ PCIE_X1, 51904+ USB3 51905+} combphy_mode; 51906+ 51907+#define U_LEVEL1 10 51908+#define U_LEVEL2 20 51909+#define U_LEVEL3 30 51910+#define U_LEVEL4 50 51911+#define U_LEVEL5 100 51912+#define U_LEVEL6 200 51913+#define U_LEVEL7 300 51914+#define U_LEVEL8 500 51915+ 51916+#define M_LEVEL1 2 51917+#define M_LEVEL2 5 51918+#define M_LEVEL3 10 51919+#define M_LEVEL4 20 51920+#define M_LEVEL5 50 51921+#define M_LEVEL6 100 51922+#define M_LEVEL7 200 51923+ 51924+#define __1K__ 0x400 51925+#define __2K__ 0x800 51926+#define __4K__ 0x1000 51927+#define __8K__ 0x2000 51928+#define __64K__ 0x10000 51929+ 51930+#define CRG_NODE_IDX 0 51931+#define MISC_NODE_IDX 1 51932+#define SYS_NODE_IDX 2 51933+#define CTRL_NODE_IDX 3 51934+ 51935+#endif /* USB2_INCLUDE_PHY_H */ 51936diff --git a/drivers/phy/hibvt/usb/phy-hixvp-hisi-usb.c b/drivers/phy/hibvt/usb/phy-hixvp-hisi-usb.c 51937new file mode 100644 51938index 000000000..be6831947 51939--- /dev/null 51940+++ b/drivers/phy/hibvt/usb/phy-hixvp-hisi-usb.c 51941@@ -0,0 +1,803 @@ 51942+/* 51943+ * phy-hixvp-hisi-usb.c 51944+ * 51945+ * USB phy driver. 51946+ * 51947+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved. 51948+ * 51949+ * This program is free software; you can redistribute it and/or modify it 51950+ * under the terms of the GNU General Public License as published by the 51951+ * Free Software Foundation; either version 2 of the License, or (at your 51952+ * option) any later version. 51953+ * 51954+ * This program is distributed in the hope that it will be useful, 51955+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 51956+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51957+ * GNU General Public License for more details. 51958+ * 51959+ * You should have received a copy of the GNU General Public License 51960+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 51961+ * 51962+ */ 51963+#include <linux/clk-provider.h> 51964+#include <linux/clk.h> 51965+#include <linux/delay.h> 51966+#include <linux/module.h> 51967+#include <linux/of_address.h> 51968+#include <linux/phy/phy.h> 51969+#include <linux/platform_device.h> 51970+#include <linux/reset.h> 51971+#include <linux/usb/ch9.h> 51972+ 51973+#include "phy-hisi-usb.h" 51974+ 51975+#define HIXVP_PHY_TRIM_OFFSET 0x0008 51976+#define HIXVP_PHY_TRIM_MASK 0x1f00 51977+#define HIXVP_PHY_TRIM_VAL(a) (((a) << 8) & HIXVP_PHY_TRIM_MASK) 51978+ 51979+#define HIXVP_PHY_SVB_OFFSET 0x0000 51980+#define HIXVP_PHY_SVB_MASK 0x0f000000 51981+#define HIXVP_PHY_SVB_VAL(a) (((a) << 24) & HIXVP_PHY_SVB_MASK) 51982+ 51983+struct hisi_hixvp_priv { 51984+ void __iomem *crg_base; 51985+ void __iomem *phy_base; 51986+ void __iomem *pin_base; 51987+ struct phy *phy; 51988+ struct device *dev; 51989+ struct clk **clks; 51990+ int num_clocks; 51991+ u32 phy_pll_offset; 51992+ u32 phy_pll_mask; 51993+ u32 phy_pll_val; 51994+ u32 crg_offset; 51995+ u32 crg_defal_mask; 51996+ u32 crg_defal_val; 51997+ u32 vbus_offset; 51998+ u32 vbus_val; 51999+ int vbus_flag; 52000+ u32 pwren_offset; 52001+ u32 pwren_val; 52002+ int pwren_flag; 52003+ u32 ana_cfg_0_eye_val; 52004+ u32 ana_cfg_0_offset; 52005+ int ana_cfg_0_flag; 52006+ u32 ana_cfg_2_eye_val; 52007+ u32 ana_cfg_2_offset; 52008+ int ana_cfg_2_flag; 52009+ u32 ana_cfg_4_eye_val; 52010+ u32 ana_cfg_4_offset; 52011+ int ana_cfg_4_flag; 52012+ struct reset_control *usb_phy_tpor_rst; 52013+ struct reset_control *usb_phy_por_rst; 52014+ u32 trim_otp_addr; 52015+ u32 trim_otp_mask; 52016+ u32 trim_otp_bit_offset; 52017+ u32 trim_otp_min; 52018+ u32 trim_otp_max; 52019+ int trim_flag; 52020+ u32 svb_otp_addr; 52021+ u32 svb_otp_predev5_min; 52022+ u32 svb_otp_predev5_max; 52023+ u32 svb_phy_predev5_val; 52024+ int svb_predev5_flag; 52025+ u32 svb_otp_predev4_min; 52026+ u32 svb_otp_predev4_max; 52027+ u32 svb_phy_predev4_val; 52028+ int svb_predev4_flag; 52029+ u32 svb_otp_predev3_min; 52030+ u32 svb_otp_predev3_max; 52031+ u32 svb_phy_predev3_val; 52032+ int svb_predev3_flag; 52033+ u32 svb_otp_predev2_min; 52034+ u32 svb_otp_predev2_max; 52035+ u32 svb_phy_predev2_val; 52036+ int svb_predev2_flag; 52037+ int svb_flag; 52038+}; 52039+ 52040+void hisi_usb_hixvp_def_all_exist(struct hisi_hixvp_priv *priv) 52041+{ 52042+ if (priv == NULL) 52043+ return; 52044+ 52045+ /* All parameters exist by default */ 52046+ priv->vbus_flag = 1; 52047+ 52048+ priv->pwren_flag = 1; 52049+ 52050+ priv->ana_cfg_0_flag = 1; 52051+ 52052+ priv->ana_cfg_2_flag = 1; 52053+ 52054+ priv->ana_cfg_4_flag = 1; 52055+ 52056+ priv->trim_flag = 1; 52057+ 52058+ priv->svb_predev5_flag = 1; 52059+ 52060+ priv->svb_predev4_flag = 1; 52061+ 52062+ priv->svb_predev3_flag = 1; 52063+ 52064+ priv->svb_predev2_flag = 1; 52065+ 52066+ priv->svb_flag = 1; 52067+} 52068+ 52069+void hisi_usb_hixvp_get_eye_para(const struct device *dev, 52070+ struct hisi_hixvp_priv *priv) 52071+{ 52072+ int ret; 52073+ 52074+ if ((dev == NULL) || (priv == NULL)) 52075+ return; 52076+ 52077+ if (dev->of_node == NULL) 52078+ return; 52079+ 52080+ /* 52081+ * Get phy eye parameters,if you want to change them,please open 52082+ * dtsi file and modify parameters at phy node. 52083+ */ 52084+ ret = of_property_read_u32(dev->of_node, "ana_cfg_0_eye_val", 52085+ &(priv->ana_cfg_0_eye_val)); 52086+ if (ret) 52087+ priv->ana_cfg_0_flag = 0; 52088+ 52089+ ret = of_property_read_u32(dev->of_node, "ana_cfg_0_offset", 52090+ &(priv->ana_cfg_0_offset)); 52091+ if (ret) 52092+ priv->ana_cfg_0_flag = 0; 52093+ 52094+ ret = of_property_read_u32(dev->of_node, "ana_cfg_2_eye_val", 52095+ &(priv->ana_cfg_2_eye_val)); 52096+ if (ret) 52097+ priv->ana_cfg_2_flag = 0; 52098+ 52099+ ret = of_property_read_u32(dev->of_node, "ana_cfg_2_offset", 52100+ &(priv->ana_cfg_2_offset)); 52101+ if (ret) 52102+ priv->ana_cfg_2_flag = 0; 52103+ 52104+ ret = of_property_read_u32(dev->of_node, "ana_cfg_4_eye_val", 52105+ &(priv->ana_cfg_4_eye_val)); 52106+ if (ret) 52107+ priv->ana_cfg_4_flag = 0; 52108+ 52109+ ret = of_property_read_u32(dev->of_node, "ana_cfg_4_offset", 52110+ &(priv->ana_cfg_4_offset)); 52111+ if (ret) 52112+ priv->ana_cfg_4_flag = 0; 52113+} 52114+ 52115+void hisi_usb_hixvp_phy_eye_config(const struct hisi_hixvp_priv *priv) 52116+{ 52117+ if (priv == NULL) 52118+ return; 52119+ 52120+ if (priv->ana_cfg_0_flag) 52121+ writel(priv->ana_cfg_0_eye_val, priv->phy_base + priv->ana_cfg_0_offset); 52122+ 52123+ if (priv->ana_cfg_2_flag) 52124+ writel(priv->ana_cfg_2_eye_val, priv->phy_base + priv->ana_cfg_2_offset); 52125+ 52126+ if (priv->ana_cfg_4_flag) 52127+ writel(priv->ana_cfg_4_eye_val, priv->phy_base + priv->ana_cfg_4_offset); 52128+} 52129+ 52130+void hisi_usb_hixvp_get_trim_para(const struct device *dev, 52131+ struct hisi_hixvp_priv *priv) 52132+{ 52133+ int ret; 52134+ 52135+ if ((dev == NULL) || (priv == NULL)) 52136+ return; 52137+ 52138+ if (dev->of_node == NULL) 52139+ return; 52140+ 52141+ /* get phy trim parameters */ 52142+ ret = of_property_read_u32(dev->of_node, "trim_otp_addr", 52143+ &(priv->trim_otp_addr)); 52144+ if (ret) 52145+ priv->trim_flag = 0; 52146+ 52147+ ret = of_property_read_u32(dev->of_node, "trim_otp_mask", 52148+ &(priv->trim_otp_mask)); 52149+ if (ret) 52150+ priv->trim_flag = 0; 52151+ 52152+ ret = of_property_read_u32(dev->of_node, "trim_otp_bit_offset", 52153+ &(priv->trim_otp_bit_offset)); 52154+ if (ret) 52155+ priv->trim_flag = 0; 52156+ 52157+ ret = of_property_read_u32(dev->of_node, "trim_otp_min", &(priv->trim_otp_min)); 52158+ if (ret) 52159+ priv->trim_flag = 0; 52160+ 52161+ ret = of_property_read_u32(dev->of_node, "trim_otp_max", &(priv->trim_otp_max)); 52162+ if (ret) 52163+ priv->trim_flag = 0; 52164+} 52165+ 52166+void hisi_usb_hixvp_phy_trim_config(const struct hisi_hixvp_priv *priv) 52167+{ 52168+ unsigned int trim_otp_val; 52169+ unsigned int reg; 52170+ void __iomem *phy_trim = NULL; 52171+ 52172+ if (priv == NULL) 52173+ return; 52174+ 52175+ if (priv->trim_flag) { 52176+ phy_trim = ioremap_nocache(priv->trim_otp_addr, __1K__); 52177+ if (phy_trim == NULL) 52178+ return; 52179+ 52180+ reg = readl(phy_trim); 52181+ trim_otp_val = (reg & priv->trim_otp_mask); 52182+ if ((trim_otp_val >= priv->trim_otp_min) && 52183+ (trim_otp_val <= priv->trim_otp_max)) { 52184+ /* set trim value to HiXVPV100 phy */ 52185+ reg = readl(priv->phy_base + HIXVP_PHY_TRIM_OFFSET); 52186+ reg &= ~HIXVP_PHY_TRIM_MASK; 52187+ reg |= HIXVP_PHY_TRIM_VAL(trim_otp_val >> priv->trim_otp_bit_offset); 52188+ writel(reg, priv->phy_base + HIXVP_PHY_TRIM_OFFSET); 52189+ } 52190+ iounmap(phy_trim); 52191+ } 52192+} 52193+ 52194+void hisi_usb_hixvp_get_svb_para_1(const struct device *dev, 52195+ struct hisi_hixvp_priv *priv) 52196+{ 52197+ int ret; 52198+ 52199+ if ((dev == NULL) || (priv == NULL)) 52200+ return; 52201+ 52202+ if (dev->of_node == NULL) 52203+ return; 52204+ 52205+ /* get phy svb parmteters */ 52206+ ret = of_property_read_u32(dev->of_node, "svb_otp_addr", & 52207+ (priv->svb_otp_addr)); 52208+ if (ret) 52209+ priv->svb_flag = 0; 52210+ 52211+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_min", 52212+ &(priv->svb_otp_predev5_min)); 52213+ if (ret) 52214+ priv->svb_predev5_flag = 0; 52215+ 52216+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_max", 52217+ &(priv->svb_otp_predev5_max)); 52218+ if (ret) 52219+ priv->svb_predev5_flag = 0; 52220+ 52221+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev5_val", 52222+ &(priv->svb_phy_predev5_val)); 52223+ if (ret) 52224+ priv->svb_predev5_flag = 0; 52225+ 52226+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_min", 52227+ &(priv->svb_otp_predev4_min)); 52228+ if (ret) 52229+ priv->svb_predev4_flag = 0; 52230+ 52231+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_max", 52232+ &(priv->svb_otp_predev4_max)); 52233+ if (ret) 52234+ priv->svb_predev4_flag = 0; 52235+ 52236+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev4_val", 52237+ &(priv->svb_phy_predev4_val)); 52238+ if (ret) 52239+ priv->svb_predev4_flag = 0; 52240+} 52241+ 52242+void hisi_usb_hixvp_get_svb_para_2(const struct device *dev, 52243+ struct hisi_hixvp_priv *priv) 52244+{ 52245+ int ret; 52246+ 52247+ if ((dev == NULL) || (priv == NULL)) 52248+ return; 52249+ 52250+ if (dev->of_node == NULL) 52251+ return; 52252+ 52253+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_min", 52254+ &(priv->svb_otp_predev3_min)); 52255+ if (ret) 52256+ priv->svb_predev3_flag = 0; 52257+ 52258+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_max", 52259+ &(priv->svb_otp_predev3_max)); 52260+ if (ret) 52261+ priv->svb_predev3_flag = 0; 52262+ 52263+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev3_val", 52264+ &(priv->svb_phy_predev3_val)); 52265+ if (ret) 52266+ priv->svb_predev3_flag = 0; 52267+ 52268+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_min", 52269+ &(priv->svb_otp_predev2_min)); 52270+ if (ret) 52271+ priv->svb_predev2_flag = 0; 52272+ 52273+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_max", 52274+ &(priv->svb_otp_predev2_max)); 52275+ if (ret) 52276+ priv->svb_predev2_flag = 0; 52277+ 52278+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev2_val", 52279+ &(priv->svb_phy_predev2_val)); 52280+ if (ret) 52281+ priv->svb_predev2_flag = 0; 52282+} 52283+ 52284+void hisi_usb_hixvp_phy_svb_config(const struct hisi_hixvp_priv *priv) 52285+{ 52286+ unsigned int reg; 52287+ unsigned int ret; 52288+ void __iomem *phy_svb = NULL; 52289+ 52290+ if (priv == NULL) 52291+ return; 52292+ 52293+ if (priv->svb_flag) { 52294+ phy_svb = ioremap_nocache(priv->svb_otp_addr, __1K__); 52295+ if (phy_svb == NULL) 52296+ return; 52297+ 52298+ ret = readl(phy_svb); 52299+ reg = readl(priv->phy_base + HIXVP_PHY_SVB_OFFSET); 52300+ reg &= ~HIXVP_PHY_SVB_MASK; 52301+ if ((ret >= priv->svb_otp_predev5_min) && 52302+ (ret < priv->svb_otp_predev5_max) && (priv->svb_predev5_flag)) 52303+ reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev5_val); 52304+ else if ((ret >= priv->svb_otp_predev4_min) && 52305+ (ret < priv->svb_otp_predev4_max) && (priv->svb_predev4_flag)) 52306+ reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev4_val); 52307+ else if ((ret >= priv->svb_otp_predev3_min) && 52308+ (ret <= priv->svb_otp_predev3_max) && (priv->svb_predev3_flag)) 52309+ reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev3_val); 52310+ else if ((ret > priv->svb_otp_predev2_min) && 52311+ (ret <= priv->svb_otp_predev2_max) && (priv->svb_predev2_flag)) 52312+ reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev2_val); 52313+ else 52314+ reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev4_val); 52315+ 52316+ writel(reg, priv->phy_base + HIXVP_PHY_SVB_OFFSET); 52317+ iounmap(phy_svb); 52318+ } 52319+} 52320+ 52321+static void hisi_usb_vbus_and_pwren_config(const struct device *dev, 52322+ struct hisi_hixvp_priv *priv) 52323+{ 52324+ int ret; 52325+ 52326+ if ((dev == NULL) || (priv == NULL)) 52327+ return; 52328+ 52329+ if (dev->of_node == NULL) 52330+ return; 52331+ 52332+ /* Some chips do not have VBUS encapsulation and need to be configured */ 52333+ ret = of_property_read_u32(dev->of_node, "vbus_offset", &(priv->vbus_offset)); 52334+ if (ret) 52335+ priv->vbus_flag = 0; 52336+ 52337+ ret = of_property_read_u32(dev->of_node, "vbus_val", &(priv->vbus_val)); 52338+ if (ret) 52339+ priv->vbus_flag = 0; 52340+ 52341+ /* Some chips do not have PWREN encapsulation and need to be configured */ 52342+ ret = of_property_read_u32(dev->of_node, "pwren_offset", &(priv->pwren_offset)); 52343+ if (ret) 52344+ priv->pwren_flag = 0; 52345+ 52346+ ret = of_property_read_u32(dev->of_node, "pwren_val", &(priv->pwren_val)); 52347+ if (ret) 52348+ priv->pwren_flag = 0; 52349+ 52350+ if (priv->vbus_flag) 52351+ writel(priv->vbus_val, priv->pin_base + priv->vbus_offset); 52352+ 52353+ udelay(U_LEVEL2); 52354+ 52355+ if (priv->pwren_flag) 52356+ writel(priv->pwren_val, priv->pin_base + priv->pwren_offset); 52357+ 52358+ udelay(U_LEVEL2); 52359+} 52360+ 52361+static int hisi_usb_hixvp_get_pll_clk(const struct device *dev, 52362+ struct hisi_hixvp_priv *priv) 52363+{ 52364+ int ret; 52365+ 52366+ if ((dev == NULL) || (priv == NULL)) 52367+ return -EINVAL; 52368+ 52369+ if (dev->of_node == NULL) 52370+ return -EINVAL; 52371+ 52372+ /* Get phy pll clk config parameters from the phy node of the dtsi file */ 52373+ ret = of_property_read_u32(dev->of_node, "phy_pll_offset", 52374+ &(priv->phy_pll_offset)); 52375+ if (ret) { 52376+ dev_err(dev, "get phy_pll_offset failed: %d\n", ret); 52377+ return ret; 52378+ } 52379+ 52380+ ret = of_property_read_u32(dev->of_node, "phy_pll_mask", &(priv->phy_pll_mask)); 52381+ if (ret) { 52382+ dev_err(dev, "get phy_pll_mask failed: %d\n", ret); 52383+ return ret; 52384+ } 52385+ 52386+ ret = of_property_read_u32(dev->of_node, "phy_pll_val", &(priv->phy_pll_val)); 52387+ if (ret) { 52388+ dev_err(dev, "get phy_pll_val failed: %d\n", ret); 52389+ return ret; 52390+ } 52391+ 52392+ return 0; 52393+} 52394+ 52395+static int hisi_usb_hixvp_set_crg_val(const struct device *dev, 52396+ struct hisi_hixvp_priv *priv) 52397+{ 52398+ int ret; 52399+ unsigned int reg; 52400+ 52401+ if ((dev == NULL) || (priv == NULL)) 52402+ return -EINVAL; 52403+ 52404+ if (dev->of_node == NULL) 52405+ return -EINVAL; 52406+ 52407+ /* Get CRG default value from the phy node of the dtsi file */ 52408+ ret = of_property_read_u32(dev->of_node, "crg_offset", &(priv->crg_offset)); 52409+ if (ret) { 52410+ dev_err(dev, "get crg_offset failed: %d\n", ret); 52411+ return ret; 52412+ } 52413+ 52414+ ret = of_property_read_u32(dev->of_node, "crg_defal_mask", 52415+ &(priv->crg_defal_mask)); 52416+ if (ret) { 52417+ dev_err(dev, "get crg_defal_mask failed: %d\n", ret); 52418+ return ret; 52419+ } 52420+ 52421+ ret = of_property_read_u32(dev->of_node, "crg_defal_val", 52422+ &(priv->crg_defal_val)); 52423+ if (ret) { 52424+ dev_err(dev, "get crg_defal_val failed: %d\n", ret); 52425+ return ret; 52426+ } 52427+ 52428+ /* write phy crg default value */ 52429+ reg = readl(priv->crg_base + priv->crg_offset); 52430+ reg &= ~priv->crg_defal_mask; 52431+ reg |= priv->crg_defal_val; 52432+ writel(reg, priv->crg_base + priv->crg_offset); 52433+ 52434+ return 0; 52435+} 52436+ 52437+static int hisi_usb_hixvp_phy_get_para(struct device *dev, 52438+ struct hisi_hixvp_priv *priv) 52439+{ 52440+ int ret; 52441+ 52442+ if ((dev == NULL) || (priv == NULL)) 52443+ return -EINVAL; 52444+ 52445+ hisi_usb_hixvp_def_all_exist(priv); 52446+ 52447+ ret = hisi_usb_hixvp_get_pll_clk(dev, priv); 52448+ if (ret) { 52449+ dev_err(dev, "get pll clk failed: %d\n", ret); 52450+ return ret; 52451+ } 52452+ 52453+ hisi_usb_hixvp_get_trim_para(dev, priv); 52454+ hisi_usb_hixvp_get_eye_para(dev, priv); 52455+ hisi_usb_hixvp_get_svb_para_1(dev, priv); 52456+ hisi_usb_hixvp_get_svb_para_2(dev, priv); 52457+ 52458+ return 0; 52459+} 52460+ 52461+static int hisi_usb_hixvp_phy_get_clks(struct hisi_hixvp_priv *priv, int count) 52462+{ 52463+ struct device *dev = priv->dev; 52464+ struct device_node *np = dev->of_node; 52465+ int i; 52466+ 52467+ priv->num_clocks = count; 52468+ 52469+ if (!count) 52470+ return 0; 52471+ 52472+ priv->clks = 52473+ devm_kcalloc(dev, priv->num_clocks, sizeof(struct clk *), GFP_KERNEL); 52474+ if (priv->clks == NULL) 52475+ return -ENOMEM; 52476+ 52477+ for (i = 0; i < priv->num_clocks; i++) { 52478+ struct clk *clk; 52479+ 52480+ clk = of_clk_get(np, i); 52481+ if (IS_ERR(clk)) { 52482+ while (--i >= 0) 52483+ clk_put(priv->clks[i]); 52484+ 52485+ devm_kfree(dev, priv->clks); 52486+ priv->clks = NULL; 52487+ return PTR_ERR(clk); 52488+ } 52489+ 52490+ priv->clks[i] = clk; 52491+ } 52492+ return 0; 52493+} 52494+ 52495+static int hisi_usb_hixvp_clk_rst_config(struct platform_device *pdev, 52496+ struct hisi_hixvp_priv *priv) 52497+{ 52498+ struct device *dev = &pdev->dev; 52499+ struct device_node *np = pdev->dev.of_node; 52500+ int ret; 52501+ 52502+ ret = hisi_usb_hixvp_phy_get_clks(priv, of_clk_get_parent_count(np)); 52503+ if (ret) { 52504+ dev_err(dev, "get hixvp phy clk failed\n"); 52505+ return ret; 52506+ } 52507+ 52508+ priv->usb_phy_tpor_rst = devm_reset_control_get(dev, "phy_tpor_reset"); 52509+ if (IS_ERR_OR_NULL(priv->usb_phy_tpor_rst)) { 52510+ dev_err(dev, "get phy_tpor_reset failed: %d\n", ret); 52511+ return PTR_ERR(priv->usb_phy_tpor_rst); 52512+ } 52513+ 52514+ priv->usb_phy_por_rst = devm_reset_control_get(dev, "phy_por_reset"); 52515+ if (IS_ERR_OR_NULL(priv->usb_phy_por_rst)) { 52516+ dev_err(dev, "get phy_por_reset failed: %d\n", ret); 52517+ return PTR_ERR(priv->usb_phy_por_rst); 52518+ } 52519+ 52520+ return 0; 52521+} 52522+ 52523+static int hisi_usb_hixvp_iomap(struct device_node *np, 52524+ struct hisi_hixvp_priv *priv) 52525+{ 52526+ if ((np == NULL) || (priv == NULL)) 52527+ return -EINVAL; 52528+ 52529+ priv->phy_base = of_iomap(np, 0); 52530+ if (IS_ERR(priv->phy_base)) 52531+ return -ENOMEM; 52532+ 52533+ priv->crg_base = of_iomap(np, 1); 52534+ if (IS_ERR(priv->crg_base)) { 52535+ iounmap(priv->phy_base); 52536+ return -ENOMEM; 52537+ } 52538+ 52539+ priv->pin_base = of_iomap(np, 2); 52540+ if (IS_ERR(priv->pin_base)) { 52541+ iounmap(priv->phy_base); 52542+ iounmap(priv->crg_base); 52543+ return -ENOMEM; 52544+ } 52545+ 52546+ return 0; 52547+} 52548+ 52549+static int hisi_usb_hixvp_phy_init(struct phy *phy) 52550+{ 52551+ struct hisi_hixvp_priv *priv = phy_get_drvdata(phy); 52552+ int i, ret; 52553+ unsigned int reg; 52554+ 52555+ for (i = 0; i < priv->num_clocks; i++) { 52556+ ret = clk_prepare_enable(priv->clks[i]); 52557+ if (ret < 0) { 52558+ while (--i >= 0) { 52559+ clk_disable_unprepare(priv->clks[i]); 52560+ clk_put(priv->clks[i]); 52561+ } 52562+ } 52563+ } 52564+ 52565+ udelay(U_LEVEL5); 52566+ 52567+ /* undo por reset */ 52568+ ret = reset_control_deassert(priv->usb_phy_por_rst); 52569+ if (ret) 52570+ return ret; 52571+ 52572+ /* pll out clk */ 52573+ reg = readl(priv->phy_base + priv->phy_pll_offset); 52574+ reg &= ~priv->phy_pll_mask; 52575+ reg |= priv->phy_pll_val; 52576+ writel(reg, priv->phy_base + priv->phy_pll_offset); 52577+ 52578+ mdelay(M_LEVEL1); 52579+ 52580+ /* undo tpor reset */ 52581+ ret = reset_control_deassert(priv->usb_phy_tpor_rst); 52582+ if (ret) 52583+ return ret; 52584+ 52585+ udelay(U_LEVEL6); 52586+ 52587+ hisi_usb_hixvp_phy_eye_config(priv); 52588+ 52589+ hisi_usb_hixvp_phy_trim_config(priv); 52590+ 52591+ hisi_usb_hixvp_phy_svb_config(priv); 52592+ return 0; 52593+} 52594+ 52595+static int hisi_usb_hixvp_phy_exit(struct phy *phy) 52596+{ 52597+ struct hisi_hixvp_priv *priv = phy_get_drvdata(phy); 52598+ int i, ret; 52599+ 52600+ for (i = 0; i < priv->num_clocks; i++) 52601+ clk_disable_unprepare(priv->clks[i]); 52602+ 52603+ ret = reset_control_assert(priv->usb_phy_por_rst); 52604+ if (ret) 52605+ return ret; 52606+ 52607+ ret = reset_control_assert(priv->usb_phy_tpor_rst); 52608+ if (ret) 52609+ return ret; 52610+ 52611+ return 0; 52612+} 52613+ 52614+static const struct phy_ops hisi_usb_hixvp_phy_ops = { 52615+ .init = hisi_usb_hixvp_phy_init, 52616+ .exit = hisi_usb_hixvp_phy_exit, 52617+ .owner = THIS_MODULE, 52618+}; 52619+ 52620+static int hisi_usb_hixvp_phy_probe(struct platform_device *pdev) 52621+{ 52622+ struct device *dev = &pdev->dev; 52623+ struct phy *phy = NULL; 52624+ struct hisi_hixvp_priv *priv = NULL; 52625+ struct device_node *np = pdev->dev.of_node; 52626+ struct phy_provider *phy_provider = NULL; 52627+ int ret; 52628+ 52629+ phy = devm_phy_create(dev, dev->of_node, &hisi_usb_hixvp_phy_ops); 52630+ if (IS_ERR(phy)) 52631+ return PTR_ERR(phy); 52632+ 52633+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 52634+ if (priv == NULL) 52635+ return -ENOMEM; 52636+ 52637+ ret = hisi_usb_hixvp_iomap(np, priv); 52638+ if (ret) { 52639+ devm_kfree(dev, priv); 52640+ priv = NULL; 52641+ 52642+ return -ENOMEM; 52643+ } 52644+ 52645+ platform_set_drvdata(pdev, priv); 52646+ priv->dev = dev; 52647+ 52648+ ret = hisi_usb_hixvp_clk_rst_config(pdev, priv); 52649+ if (ret) 52650+ goto xvp_unmap; 52651+ 52652+ ret = hisi_usb_hixvp_phy_get_para(dev, priv); 52653+ if (ret) 52654+ goto xvp_unmap; 52655+ 52656+ hisi_usb_vbus_and_pwren_config(dev, priv); 52657+ 52658+ ret = hisi_usb_hixvp_set_crg_val(dev, priv); 52659+ if (ret) 52660+ goto xvp_unmap; 52661+ 52662+ platform_set_drvdata(pdev, priv); 52663+ phy_set_drvdata(phy, priv); 52664+ 52665+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 52666+ if (IS_ERR(phy_provider)) { 52667+ ret = PTR_ERR(phy_provider); 52668+ goto xvp_unmap; 52669+ } 52670+ 52671+ return 0; 52672+xvp_unmap: 52673+ iounmap(priv->phy_base); 52674+ iounmap(priv->crg_base); 52675+ iounmap(priv->pin_base); 52676+ 52677+ devm_kfree(dev, priv); 52678+ priv = NULL; 52679+ 52680+ return ret; 52681+} 52682+ 52683+static int hisi_usb_hixvp_phy_remove(struct platform_device *pdev) 52684+{ 52685+ struct device *dev = &pdev->dev; 52686+ struct hisi_hixvp_priv *priv = platform_get_drvdata(pdev); 52687+ int i; 52688+ 52689+ for (i = 0; i < priv->num_clocks; i++) 52690+ clk_put(priv->clks[i]); 52691+ 52692+ iounmap(priv->phy_base); 52693+ iounmap(priv->crg_base); 52694+ iounmap(priv->pin_base); 52695+ 52696+ devm_kfree(dev, priv); 52697+ priv = NULL; 52698+ 52699+ return 0; 52700+} 52701+ 52702+#ifdef CONFIG_PM_SLEEP 52703+static int hisi_usb_hixvp_phy_suspend(struct device *dev) 52704+{ 52705+ struct phy *phy = dev_get_drvdata(dev); 52706+ 52707+ if (hisi_usb_hixvp_phy_exit(phy)) 52708+ return -1; 52709+ 52710+ return 0; 52711+} 52712+ 52713+static int hisi_usb_hixvp_phy_resume(struct device *dev) 52714+{ 52715+ struct phy *phy = dev_get_drvdata(dev); 52716+ 52717+ if (hisi_usb_hixvp_phy_init(phy)) 52718+ return -1; 52719+ 52720+ return 0; 52721+} 52722+#endif /* CONFIG_PM_SLEEP */ 52723+ 52724+static SIMPLE_DEV_PM_OPS(hisi_usb_pm_ops, hisi_usb_hixvp_phy_suspend, 52725+ hisi_usb_hixvp_phy_resume); 52726+ 52727+static const struct of_device_id hisi_usb_hixvp_phy_of_match[] = { 52728+ { .compatible = "hisilicon,hixvp-usb2-phy" }, 52729+ {}, 52730+}; 52731+ 52732+static struct platform_driver hisi_usb_hixvp_phy_driver = { 52733+ .probe = hisi_usb_hixvp_phy_probe, 52734+ .remove = hisi_usb_hixvp_phy_remove, 52735+ .driver = { 52736+ .name = "hisi-usb-hixvp-phy", 52737+ .pm = &hisi_usb_pm_ops, 52738+ .of_match_table = hisi_usb_hixvp_phy_of_match, 52739+ } 52740+}; 52741+module_platform_driver(hisi_usb_hixvp_phy_driver); 52742+MODULE_DESCRIPTION("HISILICON USB HIXVP PHY driver"); 52743+MODULE_ALIAS("platform:hisi-usb-hixvp-phy"); 52744+MODULE_LICENSE("GPL v2"); 52745diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig 52746index d55b3727e..6d73fab25 100644 52747--- a/drivers/power/reset/Kconfig 52748+++ b/drivers/power/reset/Kconfig 52749@@ -95,7 +95,7 @@ config POWER_RESET_GPIO_RESTART 52750 52751 config POWER_RESET_HISI 52752 bool "Hisilicon power-off driver" 52753- depends on ARCH_HISI 52754+ depends on ARCH_HISI || ARCH_HISI_BVT 52755 help 52756 Reboot support for Hisilicon boards. 52757 52758diff --git a/drivers/ras/Kconfig b/drivers/ras/Kconfig 52759index c2a236f2e..fa3951a03 100644 52760--- a/drivers/ras/Kconfig 52761+++ b/drivers/ras/Kconfig 52762@@ -29,8 +29,8 @@ menuconfig RAS 52763 so have ideal availability, but may be unreliable, with frequent 52764 data corruption. 52765 52766-if RAS 52767+#if RAS 52768 52769-source "arch/x86/ras/Kconfig" 52770+#source "arch/x86/ras/Kconfig" 52771 52772-endif 52773+#endif 52774diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig 52775index 54cf5ec8f..a1de70bd3 100644 52776--- a/drivers/rtc/Kconfig 52777+++ b/drivers/rtc/Kconfig 52778@@ -944,6 +944,14 @@ comment "Platform RTC drivers" 52779 # <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a 52780 # global rtc_lock ... it's not yet just another platform_device. 52781 52782+config RTC_DRV_HIBVT 52783+ tristate "HiSilicon BVT RTC support" 52784+ help 52785+ Generic RTC framework driver for HiSilicon BVT SoCs. 52786+ 52787+ To compile this driver as a module, choose M here: the module 52788+ will be called rtc-hibvt. 52789+ 52790 config RTC_DRV_CMOS 52791 tristate "PC-style 'CMOS'" 52792 depends on X86 || ARM || PPC || MIPS || SPARC64 52793diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile 52794index bfb574641..41f5ad4f9 100644 52795--- a/drivers/rtc/Makefile 52796+++ b/drivers/rtc/Makefile 52797@@ -18,6 +18,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o 52798 52799 # Keep the list ordered. 52800 52801+obj-$(CONFIG_RTC_DRV_HIBVT) += rtc-hibvt.o 52802 obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o 52803 obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o 52804 obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o 52805diff --git a/drivers/rtc/rtc-hibvt.c b/drivers/rtc/rtc-hibvt.c 52806new file mode 100644 52807index 000000000..2ad9e970e 52808--- /dev/null 52809+++ b/drivers/rtc/rtc-hibvt.c 52810@@ -0,0 +1,663 @@ 52811+/* 52812+ * rtc-hibvt.c 52813+ * 52814+ * RTC driver for Hisilicon BVT 52815+ * 52816+ * Copyright (C) 2016 HiSilicon Technologies Co., Ltd. 52817+ * 52818+ * This program is free software; you can redistribute it and/or modify 52819+ * it under the terms of the GNU General Public License as published by 52820+ * the Free Software Foundation; either version 2 of the License, or 52821+ * (at your option) any later version. 52822+ * 52823+ * This program is distributed in the hope that it will be useful, 52824+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 52825+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 52826+ * GNU General Public License for more details. 52827+ */ 52828+ 52829+#include <linux/bcd.h> 52830+#include <linux/bitops.h> 52831+#include <linux/log2.h> 52832+#include <linux/interrupt.h> 52833+#include <linux/kernel.h> 52834+#include <linux/module.h> 52835+#include <linux/rtc.h> 52836+#include <linux/version.h> 52837+#include <linux/io.h> 52838+#include <linux/delay.h> 52839+ 52840+#include <linux/of.h> 52841+#include <linux/of_device.h> 52842+#include <linux/platform_device.h> 52843+ 52844+union u_spi_rw { 52845+ struct { 52846+ unsigned int spi_wdata : 8; /* [7:0] */ 52847+ unsigned int spi_rdata : 8; /* [15:8] */ 52848+ unsigned int spi_addr : 7; /* [22:16] */ 52849+ unsigned int spi_rw : 1; /* [23] */ 52850+ unsigned int spi_start : 1; /* [24] */ 52851+ unsigned int reserved : 6; /* [30:25] */ 52852+ unsigned int spi_busy : 1; /* [31] */ 52853+ } bits; 52854+ unsigned int u32; 52855+}; 52856+ 52857+struct hibvt_time_str { 52858+ unsigned char dayl; 52859+ unsigned char dayh; 52860+ unsigned char second; 52861+ unsigned char minute; 52862+ unsigned char hour; 52863+}; 52864+ 52865+#define SPI_CLK_DIV 0x000 52866+#define SPI_RW 0x004 52867+ 52868+#define SPI_WRITE 0 52869+#define SPI_READ 1 52870+ 52871+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) || \ 52872+ defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500) 52873+ 52874+/* RTC REG */ 52875+#define RTC_10MS_COUN 0x00 52876+#define RTC_S_COUNT 0x04 52877+#define RTC_M_COUNT 0x08 52878+#define RTC_H_COUNT 0x0C 52879+#define RTC_D_COUNT_L 0x10 52880+#define RTC_D_COUNT_H 0x14 52881+ 52882+#define RTC_MR_10MS 0x18 52883+#define RTC_MR_S 0x1C 52884+#define RTC_MR_M 0x20 52885+#define RTC_MR_H 0x24 52886+#define RTC_MR_D_L 0x28 52887+#define RTC_MR_D_H 0x2C 52888+ 52889+#define RTC_LR_10MS 0x30 52890+#define RTC_LR_S 0x34 52891+#define RTC_LR_M 0x38 52892+#define RTC_LR_H 0x3C 52893+#define RTC_LR_D_L 0x40 52894+#define RTC_LR_D_H 0x44 52895+ 52896+#define RTC_LORD 0x48 52897+ 52898+#define RTC_IMSC 0x4C 52899+#define RTC_INT_CLR 0x50 52900+#define RTC_INT 0x54 52901+#define RTC_INT_RAW 0x58 52902+ 52903+#define RTC_CLK 0x5C 52904+#define RTC_POR_N 0x60 52905+#define RTC_SAR_CTRL 0x68 52906+#define RTC_CLK_CFG 0x6C 52907+ 52908+#define RTC_FREQ_H 0x144 52909+#define RTC_FREQ_L 0x148 52910+ 52911+#define RTC_REG_LOCK1 0x190 52912+#define RTC_REG_LOCK2 0x194 52913+#define RTC_REG_LOCK3 0x198 52914+#define RTC_REG_LOCK4 0x19C 52915+#endif 52916+ 52917+#if defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100) || \ 52918+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \ 52919+ defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \ 52920+ defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) || \ 52921+ defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200) || \ 52922+ defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100) || \ 52923+ defined(CONFIG_ARCH_HI3568V100) || defined(CONFIG_ARCH_HI3559AV100) || \ 52924+ defined(CONFIG_ARCH_HI3559CV100) || defined(CONFIG_ARCH_HI3569V100) 52925+ 52926+#define SPI_RTC_TYPE 52927+ 52928+/* RTC REG */ 52929+#define RTC_10MS_COUN 0x00 52930+#define RTC_S_COUNT 0x01 52931+#define RTC_M_COUNT 0x02 52932+#define RTC_H_COUNT 0x03 52933+#define RTC_D_COUNT_L 0x04 52934+#define RTC_D_COUNT_H 0x05 52935+ 52936+#define RTC_MR_10MS 0x06 52937+#define RTC_MR_S 0x07 52938+#define RTC_MR_M 0x08 52939+#define RTC_MR_H 0x09 52940+#define RTC_MR_D_L 0x0A 52941+#define RTC_MR_D_H 0x0B 52942+ 52943+#define RTC_LR_10MS 0x0C 52944+#define RTC_LR_S 0x0D 52945+#define RTC_LR_M 0x0E 52946+#define RTC_LR_H 0x0F 52947+#define RTC_LR_D_L 0x10 52948+#define RTC_LR_D_H 0x11 52949+ 52950+#define RTC_LORD 0x12 52951+ 52952+#define RTC_IMSC 0x13 52953+#define RTC_INT_CLR 0x14 52954+#define RTC_INT 0x15 52955+#define RTC_INT_RAW 0x16 52956+ 52957+#define RTC_CLK 0x17 52958+#define RTC_POR_N 0x18 52959+#define RTC_SAR_CTRL 0x1A 52960+#define RTC_CLK_CFG 0x1B 52961+ 52962+#define RTC_FREQ_H 0x51 52963+#define RTC_FREQ_L 0x52 52964+ 52965+#define RTC_REG_LOCK1 0x64 52966+#define RTC_REG_LOCK2 0x65 52967+#define RTC_REG_LOCK3 0x66 52968+#define RTC_REG_LOCK4 0x67 52969+#endif 52970+ 52971+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) || \ 52972+ defined(CONFIG_ARCH_HI3569V100) 52973+#define PWR_REG_ADDR 0x180C0000 52974+#define PWR_REG_LENGTH 0x100 52975+#endif 52976+#define FREQ_H_DEFAULT 0x8 52977+#define FREQ_L_DEFAULT 0x1B 52978+ 52979+#define LV_CTL_DEFAULT 0x20 52980+#define CLK_DIV_DEFAULT 0x4 52981+#define INT_RST_DEFAULT 0x0 52982+#define INT_MSK_DEFAULT 0x4 52983+ 52984+#define AIE_INT_MASK BIT(0) 52985+#define LV_INT_MASK BIT(1) 52986+#define REG_LOAD_STAT BIT(0) 52987+#define REG_LOCK_STAT BIT(1) 52988+#define REG_LOCK_BYPASS BIT(2) 52989+ 52990+#define RTC_RW_RETRY_CNT 5 52991+#define SPI_RW_RETRY_CNT 500 52992+#define RTC_SLEEP_TIME_MS 20 52993+ 52994+#define date_to_sec(d, h, m, s) ((s) + (m) * 60 + (h) * 60 * 60 + (d) * 24 * 60 * 60) 52995+#define sec_to_day(s) ((s) / (60 * 60 * 24)) 52996+ 52997+struct hibvt_rtc { 52998+ struct rtc_device *rtc_dev; 52999+ void __iomem *regs; 53000+ int rtc_irq; 53001+}; 53002+#define hibvt_rtc_readl(x) (*((volatile unsigned char *)(x))) 53003+#define hibvt_rtc_writel(v, x) (*((volatile unsigned char *)(x)) = (v)) 53004+ 53005+#if defined(SPI_RTC_TYPE) 53006+static int hibvt_spi_write(void *spi_reg, unsigned char reg, 53007+ unsigned char val) 53008+{ 53009+ union u_spi_rw w_data, r_data; 53010+ int cnt = SPI_RW_RETRY_CNT; 53011+ 53012+ r_data.u32 = 0; 53013+ w_data.u32 = 0; 53014+ 53015+ w_data.bits.spi_wdata = val; 53016+ w_data.bits.spi_addr = reg; 53017+ w_data.bits.spi_rw = SPI_WRITE; 53018+ w_data.bits.spi_start = 0x1; 53019+ 53020+ writel(w_data.u32, (spi_reg+SPI_RW)); 53021+ 53022+ do 53023+ r_data.u32 = readl(spi_reg+SPI_RW); 53024+ while (r_data.bits.spi_busy && (--cnt)); 53025+ 53026+ if (r_data.bits.spi_busy) 53027+ return -EIO; 53028+ 53029+ return 0; 53030+} 53031+ 53032+static int hibvt_spi_read(void *spi_reg, unsigned char reg, 53033+ unsigned char *val) 53034+{ 53035+ union u_spi_rw w_data, r_data; 53036+ int cnt = SPI_RW_RETRY_CNT; 53037+ 53038+ r_data.u32 = 0; 53039+ w_data.u32 = 0; 53040+ w_data.bits.spi_addr = reg; 53041+ w_data.bits.spi_rw = SPI_READ; 53042+ w_data.bits.spi_start = 0x1; 53043+ 53044+ writel(w_data.u32, (spi_reg+SPI_RW)); 53045+ 53046+ do 53047+ r_data.u32 = readl(spi_reg+SPI_RW); 53048+ while (r_data.bits.spi_busy && (--cnt)); 53049+ 53050+ if (r_data.bits.spi_busy) 53051+ return -EIO; 53052+ 53053+ *val = r_data.bits.spi_rdata; 53054+ 53055+ return 0; 53056+} 53057+#else 53058+static unsigned int hibvt_write_reg(void *spi_reg, unsigned long offset, 53059+ unsigned char val) 53060+{ 53061+ hibvt_rtc_writel(val, (spi_reg + offset)); 53062+ return 0; 53063+} 53064+ 53065+static unsigned int hibvt_read_reg(void *spi_reg, unsigned long offset, 53066+ unsigned char *val) 53067+{ 53068+ *val = hibvt_rtc_readl(spi_reg + offset); 53069+ return 0; 53070+} 53071+#endif 53072+ 53073+ 53074+static unsigned int hibvt_rtc_write(void *spi_reg, unsigned long offset, 53075+ unsigned char val) 53076+{ 53077+#if defined(SPI_RTC_TYPE) 53078+ return hibvt_spi_write(spi_reg, offset, val); 53079+#else 53080+ return hibvt_write_reg(spi_reg, offset, val); 53081+#endif 53082+} 53083+ 53084+static unsigned int hibvt_rtc_read(void *spi_reg, unsigned long offset, 53085+ unsigned char *val) 53086+{ 53087+#if defined(SPI_RTC_TYPE) 53088+ return hibvt_spi_read(spi_reg, offset, val); 53089+#else 53090+ return hibvt_read_reg(spi_reg, offset, val); 53091+#endif 53092+} 53093+ 53094+static int hibvt_rtc_read_time(struct device *dev, struct rtc_time *time) 53095+{ 53096+ struct hibvt_rtc *rtc = dev_get_drvdata(dev); 53097+ struct hibvt_time_str time_str = {0}; 53098+ unsigned long seconds = 0; 53099+ unsigned int day; 53100+ unsigned char raw_value = 0; 53101+ int cnt = RTC_RW_RETRY_CNT; 53102+ 53103+ hibvt_rtc_read(rtc->regs, RTC_INT_RAW, &raw_value); 53104+ 53105+ if (raw_value & LV_INT_MASK) 53106+ /* low voltage detected, date/time is not reliable. */ 53107+ hibvt_rtc_write(rtc->regs, RTC_INT_CLR, 1); 53108+ 53109+ hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value); 53110+ if (raw_value & REG_LOCK_BYPASS) 53111+ hibvt_rtc_write(rtc->regs, RTC_LORD, 53112+ (~(REG_LOCK_BYPASS)) & raw_value); 53113+ 53114+ hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value); 53115+ /* lock the time */ 53116+ hibvt_rtc_write(rtc->regs, RTC_LORD, (REG_LOCK_STAT) | raw_value); 53117+ /* wait rtc load flag */ 53118+ do { 53119+ hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value); 53120+ msleep(RTC_SLEEP_TIME_MS); 53121+ } while ((raw_value & REG_LOCK_STAT) && (--cnt)); 53122+ 53123+ if (raw_value & REG_LOCK_STAT) 53124+ return -EBUSY; 53125+ 53126+ hibvt_rtc_read(rtc->regs, RTC_S_COUNT, &time_str.second); 53127+ hibvt_rtc_read(rtc->regs, RTC_M_COUNT, &time_str.minute); 53128+ hibvt_rtc_read(rtc->regs, RTC_H_COUNT, &time_str.hour); 53129+ hibvt_rtc_read(rtc->regs, RTC_D_COUNT_L, &time_str.dayl); 53130+ hibvt_rtc_read(rtc->regs, RTC_D_COUNT_H, &time_str.dayh); 53131+ 53132+ day = (time_str.dayl | (time_str.dayh << 8)); /* Move to a high 8 bit. */ 53133+ seconds = date_to_sec(day, time_str.hour, time_str.minute, time_str.second); 53134+ 53135+ rtc_time64_to_tm(seconds, time); 53136+ 53137+ return rtc_valid_tm(time); 53138+} 53139+ 53140+static int hibvt_rtc_set_time(struct device *dev, struct rtc_time *time) 53141+{ 53142+ struct hibvt_rtc *rtc = dev_get_drvdata(dev); 53143+ unsigned int days; 53144+ unsigned long seconds = 0; 53145+ unsigned int cnt = RTC_RW_RETRY_CNT; 53146+ unsigned char raw_value = 0; 53147+ 53148+ seconds = rtc_tm_to_time64(time); 53149+ 53150+ days = sec_to_day(seconds); 53151+ 53152+ hibvt_rtc_write(rtc->regs, RTC_LR_10MS, 0); 53153+ hibvt_rtc_write(rtc->regs, RTC_LR_S, time->tm_sec); 53154+ hibvt_rtc_write(rtc->regs, RTC_LR_M, time->tm_min); 53155+ hibvt_rtc_write(rtc->regs, RTC_LR_H, time->tm_hour); 53156+ hibvt_rtc_write(rtc->regs, RTC_LR_D_L, (days & 0xFF)); 53157+ hibvt_rtc_write(rtc->regs, RTC_LR_D_H, (days >> 8)); /* Move to a Low 8 bit. */ 53158+ 53159+ hibvt_rtc_write(rtc->regs, RTC_LORD, 53160+ (raw_value | REG_LOAD_STAT)); 53161+ /* wait rtc load flag */ 53162+ do { 53163+ hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value); 53164+ msleep(RTC_SLEEP_TIME_MS); 53165+ } while ((raw_value & REG_LOAD_STAT) && (--cnt)); 53166+ 53167+ if (raw_value & REG_LOAD_STAT) 53168+ return -EBUSY; 53169+ 53170+ return 0; 53171+} 53172+ 53173+static int hibvt_rtc_read_alarm(struct device *dev, 53174+ struct rtc_wkalrm *alrm) 53175+{ 53176+ struct hibvt_rtc *rtc = dev_get_drvdata(dev); 53177+ struct hibvt_time_str time_str = {0}; 53178+ unsigned long seconds = 0; 53179+ unsigned int day; 53180+ unsigned char int_state = 0; 53181+ 53182+ memset(alrm, 0, sizeof(struct rtc_wkalrm)); 53183+ 53184+ hibvt_rtc_read(rtc->regs, RTC_MR_S, &time_str.second); 53185+ hibvt_rtc_read(rtc->regs, RTC_MR_M, &time_str.minute); 53186+ hibvt_rtc_read(rtc->regs, RTC_MR_H, &time_str.hour); 53187+ hibvt_rtc_read(rtc->regs, RTC_MR_D_L, &time_str.dayl); 53188+ hibvt_rtc_read(rtc->regs, RTC_MR_D_H, &time_str.dayh); 53189+ 53190+ day = (unsigned int)(time_str.dayl | (time_str.dayh << 8)); /* Move to a high 8 bit. */ 53191+ seconds = date_to_sec(day, time_str.hour, time_str.minute, time_str.second); 53192+ 53193+ rtc_time64_to_tm(seconds, &alrm->time); 53194+ 53195+ hibvt_rtc_read(rtc->regs, RTC_IMSC, &int_state); 53196+ 53197+ alrm->enabled = !!(int_state & AIE_INT_MASK); 53198+ alrm->pending = alrm->enabled; 53199+ 53200+ return 0; 53201+} 53202+ 53203+static int hibvt_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 53204+{ 53205+ struct hibvt_rtc *rtc = dev_get_drvdata(dev); 53206+ unsigned int days; 53207+ unsigned long seconds = 0; 53208+ unsigned char val = 0; 53209+ 53210+ seconds = rtc_tm_to_time64(&alrm->time); 53211+ 53212+ days = sec_to_day(seconds); 53213+ 53214+ hibvt_rtc_write(rtc->regs, RTC_MR_10MS, 0); 53215+ hibvt_rtc_write(rtc->regs, RTC_MR_S, alrm->time.tm_sec); 53216+ hibvt_rtc_write(rtc->regs, RTC_MR_M, alrm->time.tm_min); 53217+ hibvt_rtc_write(rtc->regs, RTC_MR_H, alrm->time.tm_hour); 53218+ hibvt_rtc_write(rtc->regs, RTC_MR_D_L, (days & 0xFF)); 53219+ hibvt_rtc_write(rtc->regs, RTC_MR_D_H, (days >> 8)); /* Move to a Low 8 bit. */ 53220+ 53221+ hibvt_rtc_read(rtc->regs, RTC_IMSC, &val); 53222+ if (alrm->enabled) 53223+ hibvt_rtc_write(rtc->regs, RTC_IMSC, val | AIE_INT_MASK); 53224+ else 53225+ hibvt_rtc_write(rtc->regs, RTC_IMSC, val & ~AIE_INT_MASK); 53226+ 53227+ return 0; 53228+} 53229+ 53230+static int hibvt_rtc_alarm_irq_enable(struct device *dev, 53231+ unsigned int enabled) 53232+{ 53233+ struct hibvt_rtc *rtc = dev_get_drvdata(dev); 53234+ unsigned char val = 0; 53235+ 53236+ hibvt_rtc_read(rtc->regs, RTC_IMSC, &val); 53237+ if (enabled) 53238+ hibvt_rtc_write(rtc->regs, RTC_IMSC, val | AIE_INT_MASK); 53239+ else 53240+ hibvt_rtc_write(rtc->regs, RTC_IMSC, val & ~AIE_INT_MASK); 53241+ 53242+ return 0; 53243+} 53244+ 53245+/* 53246+ * interrupt function 53247+ * do nothing. left for future 53248+ */ 53249+static irqreturn_t hibvt_rtc_alm_interrupt(int irq, void *data) 53250+{ 53251+ struct hibvt_rtc *rtc = (struct hibvt_rtc *)data; 53252+ unsigned char val = 0; 53253+ 53254+ hibvt_rtc_read(rtc->regs, RTC_INT, &val); 53255+ hibvt_rtc_write(rtc->regs, RTC_INT_CLR, AIE_INT_MASK); 53256+ 53257+ if (val & AIE_INT_MASK) 53258+ rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); 53259+ 53260+ return IRQ_HANDLED; 53261+} 53262+ 53263+#define FREQ_MAX_VAL 3277000 53264+#define FREQ_MIN_VAL 3276000 53265+ 53266+static int hibvt_rtc_ioctl(struct device *dev, 53267+ unsigned int cmd, unsigned long arg) 53268+{ 53269+ struct hibvt_rtc *rtc = dev_get_drvdata(dev); 53270+ 53271+ switch (cmd) { 53272+ case RTC_PLL_SET: { 53273+ char freq_l, freq_h; 53274+ struct rtc_pll_info pll_info = {0}; 53275+ 53276+ if (copy_from_user(&pll_info, (struct rtc_pll_info *)(uintptr_t)arg, 53277+ sizeof(struct rtc_pll_info))) 53278+ return -EFAULT; 53279+ 53280+ /* freq = 32700 + (freq /3052)*100 */ 53281+ if (pll_info.pll_value > FREQ_MAX_VAL || 53282+ pll_info.pll_value < FREQ_MIN_VAL) 53283+ return -EINVAL; 53284+ 53285+ /* freq convert: (freq-3270000) * 3052 / 10000 */ 53286+ pll_info.pll_value = (pll_info.pll_value - 3270000) * 53287+ 3052 / 10000; 53288+ 53289+ /* & 0xff Obtains the lower eight bits of data. */ 53290+ freq_l = (char)(pll_info.pll_value & 0xff); 53291+ /* pll_info.pll_value >> 8 & 0xf Obtains the last four bits of the higher eight bits. */ 53292+ freq_h = (char)((pll_info.pll_value >> 8) & 0xf); 53293+ 53294+ hibvt_rtc_write(rtc->regs, RTC_FREQ_H, freq_h); 53295+ hibvt_rtc_write(rtc->regs, RTC_FREQ_L, freq_l); 53296+ 53297+ return 0; 53298+ } 53299+ case RTC_PLL_GET: { 53300+ char freq_l = 0; 53301+ char freq_h = 0; 53302+ struct rtc_pll_info pll_info = {0}; 53303+ 53304+ hibvt_rtc_read(rtc->regs, RTC_FREQ_H, &freq_h); 53305+ hibvt_rtc_read(rtc->regs, RTC_FREQ_L, &freq_l); 53306+ 53307+ if ((void __user *)(uintptr_t)arg == NULL) { 53308+ dev_err(dev, "IO err or user buf is NULL..\n"); 53309+ return -1; 53310+ } 53311+ 53312+ /* freq_h & 0xf << 8 :Shifts leftwards by 8 bits and obtains the lower 4 bits. */ 53313+ pll_info.pll_value = (((unsigned)freq_h & 0xf) << 8) + freq_l; 53314+ 53315+ /* freq convert: 3270000 + (freq * 10000) / 3052 */ 53316+ pll_info.pll_value = 3270000 + ((unsigned int)pll_info.pll_value * 10000) / 3052; 53317+ 53318+ pll_info.pll_max = FREQ_MAX_VAL; 53319+ pll_info.pll_min = FREQ_MIN_VAL; 53320+ if (copy_to_user((void __user *)(uintptr_t)arg, 53321+ &pll_info, sizeof(struct rtc_pll_info))) 53322+ return -EFAULT; 53323+ 53324+ return 0; 53325+ } 53326+ default: 53327+ return -ENOIOCTLCMD; 53328+ } 53329+} 53330+ 53331+static const struct rtc_class_ops hibvt_rtc_ops = { 53332+ .read_time = hibvt_rtc_read_time, 53333+ .set_time = hibvt_rtc_set_time, 53334+ .read_alarm = hibvt_rtc_read_alarm, 53335+ .set_alarm = hibvt_rtc_set_alarm, 53336+ .alarm_irq_enable = hibvt_rtc_alarm_irq_enable, 53337+ .ioctl = hibvt_rtc_ioctl, 53338+}; 53339+ 53340+static int hibvt_rtc_init(struct hibvt_rtc *rtc) 53341+{ 53342+ void *spi_reg = rtc->regs; 53343+ unsigned char val = 0; 53344+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) || \ 53345+ defined(CONFIG_ARCH_HI3569V100) 53346+ void *pwr_reg = NULL; 53347+#endif 53348+ /* 53349+ * clk div value = (apb_clk/spi_clk)/2-1, 53350+ * apb clk = 100MHz, spi_clk = 10MHz,so value= 0x4 53351+ */ 53352+ writel(CLK_DIV_DEFAULT, (spi_reg + SPI_CLK_DIV)); 53353+ 53354+ hibvt_rtc_write(spi_reg, RTC_IMSC, INT_MSK_DEFAULT); 53355+ hibvt_rtc_write(spi_reg, RTC_SAR_CTRL, LV_CTL_DEFAULT); 53356+ 53357+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) || \ 53358+ defined(CONFIG_ARCH_HI3569V100) 53359+ pwr_reg = ioremap(PWR_REG_ADDR, PWR_REG_LENGTH); 53360+ if(pwr_reg == NULL) { 53361+ return -1; 53362+ } 53363+ writel(0x5A5AABCD, pwr_reg+0x58); 53364+ iounmap(pwr_reg); 53365+#else 53366+ /* default driver capability */ 53367+ hibvt_rtc_write(spi_reg, RTC_REG_LOCK4, 0x5A); /* 0x5A:ctl order */ 53368+ hibvt_rtc_write(spi_reg, RTC_REG_LOCK3, 0x5A); /* 0x5A:ctl order */ 53369+ hibvt_rtc_write(spi_reg, RTC_REG_LOCK2, 0xAB); /* 0xAB:ctl order */ 53370+ hibvt_rtc_write(spi_reg, RTC_REG_LOCK1, 0xCD); /* 0xCD:ctl order */ 53371+#endif 53372+ 53373+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) ||\ 53374+ defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) ||\ 53375+ defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) ||\ 53376+ defined(CONFIG_ARCH_HI3519AV100) || defined(CONFIG_ARCH_HI3556AV100) ||\ 53377+ defined(CONFIG_ARCH_HI3536DV100) || defined(CONFIG_ARCH_HI3562V100) ||\ 53378+ defined(CONFIG_ARCH_HI3566V100) || defined(CONFIG_ARCH_HI3569V100) || \ 53379+ defined(CONFIG_ARCH_HI3568V100) 53380+ hibvt_rtc_write(spi_reg, RTC_CLK_CFG, 0x02); 53381+#elif defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) ||\ 53382+ defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200) ||\ 53383+ defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) || \ 53384+ defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500) 53385+ hibvt_rtc_write(spi_reg, RTC_CLK_CFG, 0x03); 53386+#else 53387+ /* HI3536CV100 */ 53388+ hibvt_rtc_write(spi_reg, RTC_CLK_CFG, 0x01); 53389+#endif 53390+ 53391+ /* default FREQ COEF */ 53392+ hibvt_rtc_write(spi_reg, RTC_FREQ_H, FREQ_H_DEFAULT); 53393+ hibvt_rtc_write(spi_reg, RTC_FREQ_L, FREQ_L_DEFAULT); 53394+ 53395+ hibvt_rtc_read(spi_reg, RTC_INT_RAW, &val); 53396+ 53397+ if (val & LV_INT_MASK) 53398+ /* low voltage detected, date/time is not reliable. */ 53399+ hibvt_rtc_write(rtc->regs, RTC_INT_CLR, 1); 53400+ 53401+ return 0; 53402+} 53403+ 53404+static int hibvt_rtc_probe(struct platform_device *pdev) 53405+{ 53406+ struct resource *mem = NULL; 53407+ struct hibvt_rtc *rtc = NULL; 53408+ int ret; 53409+ 53410+ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); 53411+ if (!rtc) 53412+ return -ENOMEM; 53413+ 53414+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 53415+ rtc->regs = devm_ioremap_resource(&pdev->dev, mem); 53416+ if (IS_ERR((const void *)rtc->regs)) { 53417+ dev_err(&pdev->dev, "could not map I/O memory\n"); 53418+ return PTR_ERR((const void *)rtc->regs); 53419+ } 53420+ 53421+ rtc->rtc_irq = platform_get_irq(pdev, 0); 53422+ ret = devm_request_irq(&pdev->dev, rtc->rtc_irq, 53423+ hibvt_rtc_alm_interrupt, 0, pdev->name, rtc); 53424+ if (ret) { 53425+ dev_err(&pdev->dev, "could not request irq %d\n", rtc->rtc_irq); 53426+ return ret; 53427+ } 53428+ 53429+ platform_set_drvdata(pdev, rtc); 53430+ rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, 53431+ &hibvt_rtc_ops, THIS_MODULE); 53432+ if (IS_ERR(rtc->rtc_dev)) { 53433+ dev_err(&pdev->dev, "could not register rtc device\n"); 53434+ return PTR_ERR(rtc->rtc_dev); 53435+ } 53436+ 53437+ if (hibvt_rtc_init(rtc)) { 53438+ dev_err(&pdev->dev, "hibvt_rtc_init failed.\n"); 53439+ return -EIO; 53440+ } 53441+ 53442+ dev_info(&pdev->dev, "RTC driver for hibvt enabled\n"); 53443+ 53444+ return 0; 53445+} 53446+ 53447+static int hibvt_rtc_remove(struct platform_device *pdev) 53448+{ 53449+ return 0; 53450+} 53451+ 53452+static const struct of_device_id hibvt_rtc_match[] = { 53453+ { .compatible = "hisilicon,hi35xx-rtc" }, 53454+ {}, 53455+}; 53456+ 53457+static struct platform_driver hibvt_rtc_driver = { 53458+ .probe = hibvt_rtc_probe, 53459+ .remove = hibvt_rtc_remove, 53460+ .driver = { 53461+ .name = "hibvt_rtc", 53462+ .of_match_table = hibvt_rtc_match, 53463+ }, 53464+}; 53465+ 53466+module_platform_driver(hibvt_rtc_driver); 53467+ 53468+#define OSDRV_MODULE_VERSION_STRING "HISI_rtc @HiMPP" 53469+ 53470+MODULE_AUTHOR("Hisilicon"); 53471+MODULE_DESCRIPTION("Hisilicon RTC driver"); 53472+MODULE_LICENSE("GPL v2"); 53473+MODULE_VERSION("HI_VERSION=" OSDRV_MODULE_VERSION_STRING); 53474diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig 53475index c339517b7..4ff8f3de5 100644 53476--- a/drivers/scsi/ufs/Kconfig 53477+++ b/drivers/scsi/ufs/Kconfig 53478@@ -182,3 +182,12 @@ config SCSI_UFS_CRYPTO 53479 Enabling this makes it possible for the kernel to use the crypto 53480 capabilities of the UFS device (if present) to perform crypto 53481 operations on data being transferred to/from the device. 53482+ 53483+config SCSI_UFS_HI3559AV100 53484+ tristate "Hi3559av100 specific hooks to UFS controller platform driver" 53485+ depends on SCSI_UFSHCD_PLATFORM 53486+ help 53487+ This selects the UFS support for Hi3559av100 SoC. 53488+ 53489+ Select this if you have UFS controller on Hi3751v810 chipset. 53490+ If unsure, say N. 53491diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile 53492index 4679af1b5..8042bf7c6 100644 53493--- a/drivers/scsi/ufs/Makefile 53494+++ b/drivers/scsi/ufs/Makefile 53495@@ -16,3 +16,4 @@ obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o 53496 obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o 53497 obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o 53498 obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o 53499+obj-$(CONFIG_SCSI_UFS_HI3559AV100) += hi3559av100.o 53500diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c 53501index 24927cf48..ccf04e4f1 100644 53502--- a/drivers/scsi/ufs/ufshcd-pltfrm.c 53503+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c 53504@@ -17,6 +17,9 @@ 53505 #include "unipro.h" 53506 53507 #define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2 53508+#define UFSHCD_DEFAULT_PWM FAST_MODE 53509+#define UFSHCD_DEFAULT_GEAR UFS_HS_G1 53510+#define UFSHCD_DEFAULT_RATE PA_HS_MODE_B 53511 53512 static int ufshcd_parse_clock_info(struct ufs_hba *hba) 53513 { 53514@@ -172,6 +175,9 @@ static int ufshcd_parse_regulator_info(struct ufs_hba *hba) 53515 struct device *dev = hba->dev; 53516 struct ufs_vreg_info *info = &hba->vreg_info; 53517 53518+ if (hba->info_skip) 53519+ return 0; 53520+ 53521 err = ufshcd_populate_vreg(dev, "vdd-hba", &info->vdd_hba); 53522 if (err) 53523 goto out; 53524@@ -189,6 +195,18 @@ static int ufshcd_parse_regulator_info(struct ufs_hba *hba) 53525 return err; 53526 } 53527 53528+static void ufshcd_parse_cd_pin(struct ufs_hba *hba) 53529+{ 53530+#ifdef CONFIG_SCSI_UFS_CARD 53531+ struct device *dev = hba->dev; 53532+ struct device_node *np = dev->of_node; 53533+ if (of_get_property(np, "cd-gpio", NULL)) 53534+ hba->cd_gpio = of_get_named_gpio(np, "cd-gpio", 0); 53535+ else 53536+ hba->cd_gpio = -1; 53537+#endif 53538+} 53539+ 53540 #ifdef CONFIG_PM 53541 /** 53542 * ufshcd_pltfrm_suspend - suspend power management function 53543@@ -242,6 +260,34 @@ void ufshcd_pltfrm_shutdown(struct platform_device *pdev) 53544 } 53545 EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown); 53546 53547+static void ufshcd_init_skip_info(struct ufs_hba *hba) 53548+{ 53549+ struct device *dev = hba->dev; 53550+ int ret; 53551+ 53552+ ret = of_property_read_u32(dev->of_node, "skip-info", &hba->info_skip); 53553+ if (ret) 53554+ hba->info_skip = 0; 53555+} 53556+ 53557+static void ufshcd_init_powermode(struct ufs_hba *hba) 53558+{ 53559+ struct device *dev = hba->dev; 53560+ int ret; 53561+ 53562+ ret = of_property_read_u32(dev->of_node, "power-mode", &hba->hc_pwm); 53563+ if (ret) 53564+ hba->hc_pwm = UFSHCD_DEFAULT_PWM; 53565+ 53566+ ret = of_property_read_u32(dev->of_node, "gear", &hba->hc_gear); 53567+ if (ret) 53568+ hba->hc_gear = UFSHCD_DEFAULT_GEAR; 53569+ 53570+ ret = of_property_read_u32(dev->of_node, "rate", &hba->hc_rate); 53571+ if (ret) 53572+ hba->hc_rate = UFSHCD_DEFAULT_RATE; 53573+} 53574+ 53575 static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba) 53576 { 53577 struct device *dev = hba->dev; 53578@@ -388,6 +434,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, 53579 } 53580 53581 hba->vops = vops; 53582+ ufshcd_init_skip_info(hba); 53583 53584 err = ufshcd_parse_clock_info(hba); 53585 if (err) { 53586@@ -402,6 +449,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, 53587 goto dealloc_host; 53588 } 53589 53590+ ufshcd_parse_cd_pin(hba); 53591+ ufshcd_init_powermode(hba); 53592 ufshcd_init_lanes_per_dir(hba); 53593 53594 err = ufshcd_init(hba, mmio_base, irq); 53595diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c 53596index 3139d9df6..fc0b43268 100644 53597--- a/drivers/scsi/ufs/ufshcd.c 53598+++ b/drivers/scsi/ufs/ufshcd.c 53599@@ -6231,6 +6231,40 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) 53600 return retval; 53601 } 53602 53603+#ifdef CONFIG_SCSI_UFS_CARD 53604+static int ufshcd_check_card_detect(struct ufs_hba *hba) 53605+{ 53606+ int ret = D_IGNORED; 53607+ 53608+ if (gpio_is_valid(hba->cd_gpio)) 53609+ ret = gpio_get_value(hba->cd_gpio) ? D_NO_DETECT : D_DETECT; 53610+ 53611+ return ret; 53612+} 53613+ 53614+static irqreturn_t ufshcd_intr_card_detect(int irq, void *__hba) 53615+{ 53616+ struct ufs_hba *hba = __hba; 53617+ unsigned long flags; 53618+ 53619+ spin_lock_irqsave(hba->host->host_lock, flags); 53620+ hba->card_status_changed = true; 53621+ hba->ufshcd_state = UFSHCD_STATE_OFFLINE; 53622+ spin_unlock_irqrestore(hba->host->host_lock, flags); 53623+ 53624+ /* 53625+ * This handler would not work during UFS driver's sleep mode. 53626+ * That makes pending tasks failed when UFS driver enters 53627+ * into suspend mode and interface re-establishment be permitted 53628+ * only after UFS driver exit from suspend mode. 53629+ */ 53630+ if (!(work_pending(&hba->cd_work))) { 53631+ queue_work(hba->cd_wq, &hba->cd_work); 53632+ } 53633+ return IRQ_HANDLED; 53634+} 53635+#endif 53636+ 53637 static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag) 53638 { 53639 int err = 0; 53640@@ -6829,6 +6863,10 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) 53641 int err; 53642 unsigned long flags; 53643 53644+#ifdef CONFIG_SCSI_UFS_CARD 53645+ if (ufshcd_check_card_detect(hba) == D_NO_DETECT) 53646+ return 0; 53647+#endif 53648 /* 53649 * Stop the host controller and complete the requests 53650 * cleared by h/w 53651@@ -6844,6 +6882,8 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) 53652 /* scale up clocks to max frequency before full reinitialization */ 53653 ufshcd_set_clk_freq(hba, true); 53654 53655+ ufshcd_vops_clk_hareware_init_notify(hba); 53656+ 53657 err = ufshcd_hba_enable(hba); 53658 if (err) 53659 goto out; 53660@@ -7268,6 +7308,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba) 53661 dev_info->wspecversion = desc_buf[DEVICE_DESC_PARAM_SPEC_VER] << 8 | 53662 desc_buf[DEVICE_DESC_PARAM_SPEC_VER + 1]; 53663 53664+ hba->manufacturer_id = dev_desc->wmanufacturerid; 53665 model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; 53666 53667 err = ufshcd_read_string_desc(hba, model_index, 53668@@ -7831,6 +7872,138 @@ static const struct attribute_group *ufshcd_driver_groups[] = { 53669 NULL, 53670 }; 53671 53672+#ifdef CONFIG_SCSI_UFS_CARD 53673+static int ufshcd_select_next_job(struct ufs_hba *hba, bool current_status) 53674+{ 53675+ bool is_card_detected; 53676+ 53677+ /* 53678+ * We assume scenarios for 4 cases and decribe them 53679+ * with following conventions 53680+ * 53681+ * Physical card Status (A) / Device file status (B) 53682+ * Insertion (I) / Removal (R) 53683+ * 53684+ * 1) A = I 53685+ * 1-1) B = I : (I) -> R 53686+ * This might means bad card insertion that can cause 53687+ * something wrong for opertions. 53688+ * 53689+ * 1-2) B = R : (R) -> I 53690+ * Normal insertion 53691+ * 53692+ * 2) A = R 53693+ * 2-1) B = I : (I) -> R 53694+ * Normal removal 53695+ * 53696+ * 2-2) B = R : (R) 53697+ * Return because old status is 'removal' 53698+ * and any care isn't required. 53699+ * 53700+ * 53701+ */ 53702+ is_card_detected = (D_DETECT == ufshcd_check_card_detect(hba)); 53703+ if (hba->latest_card_status == H_INSERT) { 53704+ return H_REMOVE; 53705+ } else { 53706+ if (is_card_detected) 53707+ return H_INSERT; 53708+ else 53709+ return H_BREAK; 53710+ } 53711+} 53712+ 53713+static void ufshcd_card_detect_handler(struct work_struct *work) 53714+{ 53715+ struct ufs_hba *hba; 53716+ unsigned long flags; 53717+ int tag; 53718+ unsigned long outstanding_reqs; 53719+ int current_status; 53720+ struct scsi_target *starget; 53721+ struct uic_command uic_cmd = {0}; 53722+ 53723+ hba = container_of(work, struct ufs_hba, cd_work); 53724+ msleep(50); 53725+ current_status = hba->latest_card_status; 53726+ while (1) { 53727+ pm_runtime_get_sync(hba->dev); 53728+ 53729+ /* 53730+ * There is a requirement of whether card detection interrupt 53731+ * happens before terminating here not to miss the interrupt. 53732+ * The hint should be wrapped by spin lock. 53733+ */ 53734+ spin_lock_irqsave(hba->host->host_lock, flags); 53735+ if (unlikely(!hba->card_status_changed)) { 53736+ spin_unlock_irqrestore(hba->host->host_lock, flags); 53737+ return; 53738+ } 53739+ hba->card_status_changed = false; 53740+ spin_unlock_irqrestore(hba->host->host_lock, flags); 53741+ 53742+ current_status = ufshcd_select_next_job(hba, current_status); 53743+ 53744+ if (current_status == H_INSERT) { 53745+ /* 53746+ * On insertion, a total sequence to initialize 53747+ * UFS interface is required. 53748+ */ 53749+ 53750+ ufshcd_hba_enable(hba); 53751+ ufshcd_probe_hba(hba); 53752+ 53753+ dev_err(hba->dev, "card inserted\n"); 53754+ hba->latest_card_status = current_status; 53755+ hba->error_count = 0; 53756+ break; 53757+ } else if (current_status == H_REMOVE) { 53758+ /* 53759+ * On removal, clearing slots and I/O completion 53760+ * of pending tasks, if any, are required. 53761+ */ 53762+ 53763+ spin_lock_irqsave(hba->host->host_lock, flags); 53764+ outstanding_reqs = hba->outstanding_reqs; 53765+ spin_unlock_irqrestore(hba->host->host_lock, flags); 53766+ if (outstanding_reqs) { 53767+ for_each_set_bit(tag, &outstanding_reqs, hba->nutrs) 53768+ ufshcd_clear_cmd(hba, tag); 53769+ __ufshcd_transfer_req_compl(hba, DID_NO_CONNECT); 53770+ } 53771+ 53772+ uic_cmd.command = UIC_CMD_DME_RESET; 53773+ ufshcd_send_uic_cmd(hba, &uic_cmd); 53774+ 53775+ spin_lock_irqsave(hba->host->host_lock, flags); 53776+ ufshcd_hba_stop(hba, true); 53777+ hba->ufshcd_state = UFSHCD_STATE_OFFLINE; 53778+ spin_unlock_irqrestore(hba->host->host_lock, flags); 53779+ 53780+ /* 53781+ * A device file removal is required on card removal 53782+ */ 53783+ if (!list_empty(&hba->host->__targets)) { 53784+ starget = list_first_entry(&hba->host->__targets, 53785+ struct scsi_target, siblings); 53786+ scsi_remove_device(hba->sdev_rpmb); 53787+ scsi_remove_device(hba->sdev_boot); 53788+ scsi_remove_device(hba->sdev_ufs_device); 53789+ scsi_remove_target(&starget->dev); 53790+ } 53791+ 53792+ dev_err(hba->dev, "card removed\n"); 53793+ hba->latest_card_status = current_status; 53794+ return; 53795+ } else { 53796+ dev_err(hba->dev, "returned\n"); 53797+ break; 53798+ } 53799+ } 53800+ pm_runtime_put_sync(hba->dev); 53801+} 53802+#endif 53803+ 53804 static struct ufs_hba_variant_params ufs_hba_vps = { 53805 .hba_enable_delay_us = 1000, 53806 .wb_flush_threshold = UFS_WB_BUF_REMAIN_PERCENT(40), 53807@@ -8540,6 +8713,10 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) 53808 enum ufs_dev_pwr_mode req_dev_pwr_mode; 53809 enum uic_link_state req_link_state; 53810 53811+#ifdef CONFIG_SCSI_UFS_CARD 53812+ if (hba->ufshcd_state == UFSHCD_STATE_OFFLINE) 53813+ return 0; 53814+#endif 53815 hba->pm_op_in_progress = 1; 53816 if (!ufshcd_is_shutdown_pm(pm_op)) { 53817 pm_lvl = ufshcd_is_runtime_pm(pm_op) ? 53818@@ -9017,6 +9194,9 @@ void ufshcd_remove(struct ufs_hba *hba) 53819 ufshcd_exit_clk_gating(hba); 53820 if (ufshcd_is_clkscaling_supported(hba)) 53821 device_remove_file(hba->dev, &hba->clk_scaling.enable_attr); 53822+#ifdef CONFIG_SCSI_UFS_CARD 53823+ destroy_workqueue(hba->cd_wq); 53824+#endif 53825 ufshcd_hba_exit(hba); 53826 } 53827 EXPORT_SYMBOL_GPL(ufshcd_remove); 53828@@ -9185,6 +9365,14 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) 53829 INIT_WORK(&hba->eh_work, ufshcd_err_handler); 53830 INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler); 53831 53832+#ifdef CONFIG_SCSI_UFS_CARD 53833+ INIT_WORK(&hba->cd_work, ufshcd_card_detect_handler); 53834+ hba->cd_wq = alloc_workqueue("ufshcd_cd_wq", WQ_FREEZABLE, 0); 53835+ if (!hba->cd_wq) { 53836+ err = -ENOMEM; 53837+ goto out_error; 53838+ } 53839+#endif 53840 /* Initialize UIC command mutex */ 53841 mutex_init(&hba->uic_cmd_mutex); 53842 53843@@ -9293,7 +9481,37 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) 53844 */ 53845 ufshcd_set_ufs_dev_active(hba); 53846 53847+#ifndef CONFIG_SCSI_UFS_CARD 53848 async_schedule(ufshcd_async_scan, hba); 53849+#else 53850+ unsigned int cd_irq; 53851+ if (gpio_is_valid(hba->cd_gpio) && 53852+ !gpio_request(hba->cd_gpio, "UFSCARD")) { 53853+ cd_irq = gpio_to_irq(hba->cd_gpio); 53854+ dev_err(hba->dev, "card detection interrupt number = %d\n", cd_irq); 53855+ if (cd_irq && 53856+ devm_request_irq(hba->dev, cd_irq, ufshcd_intr_card_detect, 53857+ IRQF_TRIGGER_RISING | 53858+ IRQF_TRIGGER_FALLING | 53859+ IRQF_ONESHOT, 53860+ UFSCARDHCD, hba) == 0) { 53861+ dev_warn(hba->dev, "success to request irq for card detect.\n"); 53862+ enable_irq_wake(cd_irq); 53863+ hba->is_cd_irq_enabled = true; 53864+ hba->cd_irq = cd_irq; 53865+ } else 53866+ dev_warn(hba->dev, "cannot request irq for card detect.\n"); 53867+ } 53868+ 53869+ if (D_DETECT == ufshcd_check_card_detect(hba)) { 53870+ hba->latest_card_status = true; 53871+ async_schedule(ufshcd_async_scan, hba); 53872+ } else { 53873+ hba->latest_card_status = false; 53874+ ufshcd_hba_stop(hba, true); 53875+ hba->ufshcd_state = UFSHCD_STATE_OFFLINE; 53876+ } 53877+#endif 53878 ufs_sysfs_add_nodes(hba->dev); 53879 53880 return 0; 53881diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h 53882index 812aa3487..c2fe83d27 100644 53883--- a/drivers/scsi/ufs/ufshcd.h 53884+++ b/drivers/scsi/ufs/ufshcd.h 53885@@ -50,6 +50,7 @@ 53886 53887 #define UFSHCD "ufshcd" 53888 #define UFSHCD_DRIVER_VERSION "0.2" 53889+#define UFSCARDHCD "ufscarddetect" 53890 53891 struct ufs_hba; 53892 53893@@ -324,6 +325,7 @@ struct ufs_hba_variant_ops { 53894 void *data); 53895 int (*program_key)(struct ufs_hba *hba, 53896 const union ufs_crypto_cfg_entry *cfg, int slot); 53897+ void (*clk_hareware_init_notify)(void); 53898 }; 53899 53900 /* clock gating state */ 53901@@ -463,6 +465,20 @@ struct ufs_stats { 53902 struct ufs_err_reg_hist task_abort; 53903 }; 53904 53905+/* card status */ 53906+enum ufs_card_status { 53907+ D_IGNORED = -1, 53908+ D_NO_DETECT = 0, 53909+ D_DETECT, 53910+}; 53911+ 53912+/* card detect handler action */ 53913+enum { 53914+ H_BREAK = -1, 53915+ H_REMOVE = 0, 53916+ H_INSERT, 53917+}; 53918+ 53919 enum ufshcd_quirks { 53920 /* Interrupt aggregation support is broken */ 53921 UFSHCD_QUIRK_BROKEN_INTR_AGGR = 1 << 0, 53922@@ -747,6 +763,18 @@ struct ufs_hba { 53923 struct work_struct eh_work; 53924 struct work_struct eeh_work; 53925 53926+#ifdef CONFIG_SCSI_UFS_CARD 53927+ /* card irq */ 53928+ unsigned int cd_irq; 53929+ bool is_cd_irq_enabled; 53930+ 53931+ /* card detect & work queue */ 53932+ int cd_gpio; 53933+ bool latest_card_status; 53934+ bool card_status_changed; 53935+ struct work_struct cd_work; 53936+ struct workqueue_struct *cd_wq; 53937+#endif 53938 /* HBA Errors */ 53939 u32 errors; 53940 u32 uic_error; 53941@@ -757,6 +785,7 @@ struct ufs_hba { 53942 bool force_pmc; 53943 bool silence_err_logs; 53944 53945+ uint16_t manufacturer_id; 53946 /* Device management request data */ 53947 struct ufs_dev_cmd dev_cmd; 53948 ktime_t last_dme_cmd_tstamp; 53949@@ -781,6 +810,11 @@ struct ufs_hba { 53950 /* Control to enable/disable host capabilities */ 53951 u32 caps; 53952 53953+ u32 hc_pwm; 53954+ u32 hc_gear; 53955+ u32 hc_rate; 53956+ u32 info_skip; 53957+ 53958 struct devfreq *devfreq; 53959 struct ufs_clk_scaling clk_scaling; 53960 bool is_sys_suspended; 53961@@ -1234,4 +1268,9 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) 53962 int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, 53963 const char *prefix); 53964 53965+static inline void ufshcd_vops_clk_hareware_init_notify(struct ufs_hba *hba) 53966+{ 53967+ if (hba->vops && hba->vops->clk_hareware_init_notify) 53968+ hba->vops->clk_hareware_init_notify(); 53969+} 53970 #endif /* End of Header */ 53971diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c 53972index 0584f4d2f..d035d4995 100644 53973--- a/drivers/spi/spi-gpio.c 53974+++ b/drivers/spi/spi-gpio.c 53975@@ -367,8 +367,10 @@ static int spi_gpio_probe(struct platform_device *pdev) 53976 else 53977 status = spi_gpio_probe_pdata(pdev, master); 53978 53979- if (status) 53980+ if (status) { 53981+ spi_master_put(master); 53982 return status; 53983+ } 53984 53985 spi_gpio = spi_master_get_devdata(master); 53986 53987diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c 53988index d1776fea2..3b280d713 100644 53989--- a/drivers/spi/spi-pl022.c 53990+++ b/drivers/spi/spi-pl022.c 53991@@ -34,6 +34,7 @@ 53992 #include <linux/gpio.h> 53993 #include <linux/of_gpio.h> 53994 #include <linux/pinctrl/consumer.h> 53995+#include <linux/of_address.h> 53996 53997 /* 53998 * This macro is used to define some register default values. 53999@@ -127,6 +128,18 @@ 54000 /* This one is only in the PL023 variant */ 54001 #define SSP_CR1_MASK_FBCLKDEL_ST (0x7UL << 13) 54002 54003+#ifdef CONFIG_ARCH_HISI_BVT 54004+/* 54005+ * The Hisilicon version of this block adds some bits 54006+ * in SSP_CR1 54007+ */ 54008+#define SSP_CR1_MASK_BIGEND_HISI (0x1UL << 4) 54009+#define SSP_CR1_MASK_ALTASENS_HISI (0x1UL << 6) 54010+ 54011+#define SSP_TX_FIFO_CR(r) (r + 0x28) 54012+#define SSP_RX_FIFO_CR(r) (r + 0x2C) 54013+#endif 54014+ 54015 /* 54016 * SSP Status Register - SSP_SR 54017 */ 54018@@ -288,6 +301,10 @@ 54019 54020 #define SPI_POLLING_TIMEOUT 1000 54021 54022+#ifdef CONFIG_ARCH_HISI_BVT 54023+#define PL022_IDS_INDEX_HISI 4 54024+#endif 54025+ 54026 /* 54027 * The type of reading going on on this chip 54028 */ 54029@@ -330,6 +347,15 @@ struct vendor_data { 54030 bool internal_cs_ctrl; 54031 }; 54032 54033+#ifdef CONFIG_ARCH_HISI_BVT 54034+struct cs_data { 54035+ struct resource res; 54036+ void __iomem *virt_addr; 54037+ unsigned int cs_sb; 54038+ unsigned int cs_mask_bit; 54039+}; 54040+#endif 54041+ 54042 /** 54043 * struct pl022 - This is the private SSP driver data structure 54044 * @adev: AMBA device model hookup 54045@@ -399,6 +425,9 @@ struct pl022 { 54046 #endif 54047 int cur_cs; 54048 int *chipselects; 54049+#ifdef CONFIG_ARCH_HISI_BVT 54050+ struct cs_data *cs_data; 54051+#endif 54052 }; 54053 54054 /** 54055@@ -455,13 +484,41 @@ static void null_cs_control(u32 command) 54056 static void internal_cs_control(struct pl022 *pl022, u32 command) 54057 { 54058 u32 tmp; 54059+#ifdef CONFIG_ARCH_HISI_BVT 54060+ struct amba_device *adev = pl022->adev; 54061+ struct amba_driver *adrv = container_of(adev->dev.driver, 54062+ struct amba_driver, drv); 54063+ 54064+ if (pl022->vendor->extended_cr && (adev->periphid == 54065+ adrv->id_table[PL022_IDS_INDEX_HISI].id)) { 54066+ if (pl022->cs_data) { 54067+ tmp = readl(pl022->cs_data->virt_addr); 54068+ tmp &= ~(pl022->cs_data->cs_mask_bit); 54069+ tmp |= ((u32)pl022->cur_cs) << pl022->cs_data->cs_sb; 54070+ writel(tmp, pl022->cs_data->virt_addr); 54071+ } 54072 54073- tmp = readw(SSP_CSR(pl022->virtbase)); 54074- if (command == SSP_CHIP_SELECT) 54075- tmp &= ~BIT(pl022->cur_cs); 54076- else 54077- tmp |= BIT(pl022->cur_cs); 54078- writew(tmp, SSP_CSR(pl022->virtbase)); 54079+ if (command == SSP_CHIP_SELECT) 54080+ /* Enable SSP */ 54081+ writew((readw(SSP_CR1(pl022->virtbase)) | 54082+ SSP_CR1_MASK_SSE), 54083+ SSP_CR1(pl022->virtbase)); 54084+ else 54085+ /* disable SSP */ 54086+ writew((readw(SSP_CR1(pl022->virtbase)) & 54087+ (~SSP_CR1_MASK_SSE)), 54088+ SSP_CR1(pl022->virtbase)); 54089+ } else { 54090+#endif 54091+ tmp = readw(SSP_CSR(pl022->virtbase)); 54092+ if (command == SSP_CHIP_SELECT) 54093+ tmp &= ~BIT(pl022->cur_cs); 54094+ else 54095+ tmp |= BIT(pl022->cur_cs); 54096+ writew(tmp, SSP_CSR(pl022->virtbase)); 54097+#ifdef CONFIG_ARCH_HISI_BVT 54098+ } 54099+#endif 54100 } 54101 54102 static void pl022_cs_control(struct pl022 *pl022, u32 command) 54103@@ -561,8 +618,16 @@ static int flush(struct pl022 *pl022) 54104 static void restore_state(struct pl022 *pl022) 54105 { 54106 struct chip_data *chip = pl022->cur_chip; 54107+#ifdef CONFIG_ARCH_HISI_BVT 54108+ struct amba_device *adev = pl022->adev; 54109+ struct amba_driver *adrv = container_of(adev->dev.driver, 54110+ struct amba_driver, drv); 54111 54112+ if (pl022->vendor->extended_cr && (adev->periphid != 54113+ adrv->id_table[PL022_IDS_INDEX_HISI].id)) 54114+#else 54115 if (pl022->vendor->extended_cr) 54116+#endif 54117 writel(chip->cr0, SSP_CR0(pl022->virtbase)); 54118 else 54119 writew(chip->cr0, SSP_CR0(pl022->virtbase)); 54120@@ -635,6 +700,15 @@ static void restore_state(struct pl022 *pl022) 54121 GEN_MASK_BITS(SSP_FEEDBACK_CLK_DELAY_NONE, SSP_CR1_MASK_FBCLKDEL_ST, 13) \ 54122 ) 54123 54124+#ifdef CONFIG_ARCH_HISI_BVT 54125+/* Hisilicon versions extend this register to use all 16 bits */ 54126+#define DEFAULT_SSP_REG_CR1_HISI ( \ 54127+ DEFAULT_SSP_REG_CR1 | \ 54128+ GEN_MASK_BITS(SSP_RX_MSB, SSP_CR1_MASK_BIGEND_HISI, 4) | \ 54129+ GEN_MASK_BITS(0x1, SSP_CR1_MASK_ALTASENS_HISI, 6) \ 54130+) 54131+#endif 54132+ 54133 #define DEFAULT_SSP_REG_CPSR ( \ 54134 GEN_MASK_BITS(SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \ 54135 ) 54136@@ -654,8 +728,22 @@ static void load_ssp_default_config(struct pl022 *pl022) 54137 writel(DEFAULT_SSP_REG_CR0_ST_PL023, SSP_CR0(pl022->virtbase)); 54138 writew(DEFAULT_SSP_REG_CR1_ST_PL023, SSP_CR1(pl022->virtbase)); 54139 } else if (pl022->vendor->extended_cr) { 54140+#ifdef CONFIG_ARCH_HISI_BVT 54141+ struct amba_device *adev = pl022->adev; 54142+ struct amba_driver *adrv = container_of(adev->dev.driver, 54143+ struct amba_driver, drv); 54144+ 54145+ if (adev->periphid == adrv->id_table[PL022_IDS_INDEX_HISI].id) { 54146+ writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); 54147+ writew(DEFAULT_SSP_REG_CR1_HISI, 54148+ SSP_CR1(pl022->virtbase)); 54149+ } else { 54150+#endif 54151 writel(DEFAULT_SSP_REG_CR0_ST, SSP_CR0(pl022->virtbase)); 54152 writew(DEFAULT_SSP_REG_CR1_ST, SSP_CR1(pl022->virtbase)); 54153+#ifdef CONFIG_ARCH_HISI_BVT 54154+ } 54155+#endif 54156 } else { 54157 writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); 54158 writew(DEFAULT_SSP_REG_CR1, SSP_CR1(pl022->virtbase)); 54159@@ -1138,7 +1226,7 @@ static int pl022_dma_probe(struct pl022 *pl022) 54160 if (!pl022->dummypage) 54161 goto err_no_dummypage; 54162 54163- dev_info(&pl022->adev->dev, "setup for DMA on RX %s, TX %s\n", 54164+ dev_dbg(&pl022->adev->dev, "setup for DMA on RX %s, TX %s\n", 54165 dma_chan_name(pl022->dma_rx_channel), 54166 dma_chan_name(pl022->dma_tx_channel)); 54167 54168@@ -1563,11 +1651,10 @@ static void do_polling_transfer(struct pl022 *pl022) 54169 54170 /* Update total byte transferred */ 54171 message->actual_length += pl022->cur_transfer->len; 54172+ if (pl022->cur_transfer->cs_change) 54173+ pl022_cs_control(pl022, SSP_CHIP_DESELECT); 54174 /* Move to next transfer */ 54175 message->state = next_transfer(pl022); 54176- if (message->state != STATE_DONE 54177- && pl022->cur_transfer->cs_change) 54178- pl022_cs_control(pl022, SSP_CHIP_DESELECT); 54179 } 54180 out: 54181 /* Handle end of message */ 54182@@ -1855,6 +1942,13 @@ static int pl022_setup(struct spi_device *spi) 54183 unsigned int bits = spi->bits_per_word; 54184 u32 tmp; 54185 struct device_node *np = spi->dev.of_node; 54186+#ifdef CONFIG_ARCH_HISI_BVT 54187+ struct amba_device *adev = pl022->adev; 54188+ struct amba_driver *adrv = container_of(adev->dev.driver, 54189+ struct amba_driver, drv); 54190+ writel(0, SSP_TX_FIFO_CR(pl022->virtbase)); 54191+ writel(0, SSP_RX_FIFO_CR(pl022->virtbase)); 54192+#endif 54193 54194 if (!spi->max_speed_hz) 54195 return -EINVAL; 54196@@ -1997,7 +2091,12 @@ static int pl022_setup(struct spi_device *spi) 54197 chip->cpsr = clk_freq.cpsdvsr; 54198 54199 /* Special setup for the ST micro extended control registers */ 54200+#ifdef CONFIG_ARCH_HISI_BVT 54201+ if (pl022->vendor->extended_cr && (adev->periphid != 54202+ adrv->id_table[PL022_IDS_INDEX_HISI].id)) { 54203+#else 54204 if (pl022->vendor->extended_cr) { 54205+#endif 54206 u32 etx; 54207 54208 if (pl022->vendor->pl023) { 54209@@ -2031,6 +2130,22 @@ static int pl022_setup(struct spi_device *spi) 54210 SSP_CR1_MASK_RXIFLSEL_ST, 7); 54211 SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, 54212 SSP_CR1_MASK_TXIFLSEL_ST, 10); 54213+#ifdef CONFIG_ARCH_HISI_BVT 54214+ } else if (pl022->vendor->extended_cr && (adev->periphid == 54215+ adrv->id_table[PL022_IDS_INDEX_HISI].id)) { 54216+ SSP_WRITE_BITS(chip->cr0, bits - 1, 54217+ SSP_CR0_MASK_DSS, 0); 54218+ SSP_WRITE_BITS(chip->cr0, chip_info->iface, 54219+ SSP_CR0_MASK_FRF, 4); 54220+ 54221+ if (spi->mode & SPI_LSB_FIRST) 54222+ tmp = !!SPI_LSB_FIRST; 54223+ else 54224+ tmp = !SPI_LSB_FIRST; 54225+ 54226+ SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_BIGEND_HISI, 4); 54227+ SSP_WRITE_BITS(chip->cr1, 0x1, SSP_CR1_MASK_ALTASENS_HISI, 6); 54228+#endif 54229 } else { 54230 SSP_WRITE_BITS(chip->cr0, bits - 1, 54231 SSP_CR0_MASK_DSS, 0); 54232@@ -2119,6 +2234,8 @@ pl022_platform_data_dt_get(struct device *dev) 54233 static int pl022_probe(struct amba_device *adev, const struct amba_id *id) 54234 { 54235 struct device *dev = &adev->dev; 54236+ struct amba_driver *adrv = container_of(adev->dev.driver, 54237+ struct amba_driver, drv); 54238 struct pl022_ssp_controller *platform_info = 54239 dev_get_platdata(&adev->dev); 54240 struct spi_master *master; 54241@@ -2126,7 +2243,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) 54242 struct device_node *np = adev->dev.of_node; 54243 int status = 0, i, num_cs; 54244 54245- dev_info(&adev->dev, 54246+ dev_dbg(&adev->dev, 54247 "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); 54248 if (!platform_info && IS_ENABLED(CONFIG_OF)) 54249 platform_info = pl022_platform_data_dt_get(dev); 54250@@ -2182,6 +2299,43 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) 54251 } else if (pl022->vendor->internal_cs_ctrl) { 54252 for (i = 0; i < num_cs; i++) 54253 pl022->chipselects[i] = i; 54254+ 54255+#ifdef CONFIG_ARCH_HISI_BVT 54256+ if ((adev->periphid == adrv->id_table[PL022_IDS_INDEX_HISI].id) 54257+ && pl022->vendor->extended_cr 54258+ && (num_cs > 1)) { 54259+ pl022->cs_data = devm_kzalloc(dev, 54260+ sizeof(struct cs_data), 54261+ GFP_KERNEL); 54262+ if (!pl022->cs_data) { 54263+ status = -ENOMEM; 54264+ goto err_no_mem; 54265+ } 54266+ 54267+ if (of_address_to_resource(np, 1, 54268+ &pl022->cs_data->res)) { 54269+ status = -EPROBE_DEFER; 54270+ goto err_no_gpio; 54271+ } 54272+ 54273+ if (of_property_read_u32(np, "hisi,spi_cs_sb", 54274+ &pl022->cs_data->cs_sb)) { 54275+ status = -EPROBE_DEFER; 54276+ goto err_no_gpio; 54277+ } 54278+ 54279+ if (of_property_read_u32(np, "hisi,spi_cs_mask_bit", 54280+ &pl022->cs_data->cs_mask_bit)) { 54281+ status = -EPROBE_DEFER; 54282+ goto err_no_gpio; 54283+ } 54284+ 54285+ pl022->cs_data->virt_addr = devm_ioremap(dev, 54286+ pl022->cs_data->res.start, 54287+ resource_size(&pl022->cs_data->res)); 54288+ } else 54289+ pl022->cs_data = NULL; 54290+#endif 54291 } else if (IS_ENABLED(CONFIG_OF)) { 54292 for (i = 0; i < num_cs; i++) { 54293 int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); 54294@@ -2227,7 +2381,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) 54295 status = -ENOMEM; 54296 goto err_no_ioremap; 54297 } 54298- dev_info(&adev->dev, "mapped registers from %pa to %p\n", 54299+ dev_dbg(&adev->dev, "mapped registers from %pa to %p\n", 54300 &adev->res.start, pl022->virtbase); 54301 54302 pl022->clk = devm_clk_get(&adev->dev, NULL); 54303@@ -2287,7 +2441,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) 54304 54305 /* let runtime pm put suspend */ 54306 if (platform_info->autosuspend_delay > 0) { 54307- dev_info(&adev->dev, 54308+ dev_dbg(&adev->dev, 54309 "will use autosuspend for runtime pm, delay %dms\n", 54310 platform_info->autosuspend_delay); 54311 pm_runtime_set_autosuspend_delay(dev, 54312@@ -2308,6 +2462,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) 54313 err_no_ioremap: 54314 amba_release_regions(adev); 54315 err_no_ioregion: 54316+#ifdef CONFIG_ARCH_HISI_BVT 54317+ if (pl022->cs_data) 54318+ devm_iounmap(&adev->dev, pl022->cs_data->virt_addr); 54319+#endif 54320 err_no_gpio: 54321 err_no_mem: 54322 spi_master_put(master); 54323@@ -2334,6 +2492,10 @@ pl022_remove(struct amba_device *adev) 54324 54325 clk_disable_unprepare(pl022->clk); 54326 amba_release_regions(adev); 54327+#ifdef CONFIG_ARCH_HISI_BVT 54328+ if (pl022->cs_data) 54329+ devm_iounmap(&adev->dev, pl022->cs_data->virt_addr); 54330+#endif 54331 tasklet_disable(&pl022->pump_transfers); 54332 return 0; 54333 } 54334@@ -2445,6 +2607,17 @@ static struct vendor_data vendor_lsi = { 54335 .internal_cs_ctrl = true, 54336 }; 54337 54338+#ifdef CONFIG_ARCH_HISI_BVT 54339+static struct vendor_data vendor_hisi = { 54340+ .fifodepth = 256, 54341+ .max_bpw = 16, 54342+ .unidir = false, 54343+ .extended_cr = true, 54344+ .pl023 = false, 54345+ .loopback = true, 54346+ .internal_cs_ctrl = true, 54347+}; 54348+#endif 54349 static const struct amba_id pl022_ids[] = { 54350 { 54351 /* 54352@@ -2485,6 +2658,17 @@ static const struct amba_id pl022_ids[] = { 54353 .mask = 0x000fffff, 54354 .data = &vendor_lsi, 54355 }, 54356+#ifdef CONFIG_ARCH_HISI_BVT 54357+ { 54358+ /* 54359+ * Hisilicon derivative, this has a 16bit wide 54360+ * and 256 locations deep TX/RX FIFO 54361+ */ 54362+ .id = 0x00800022, 54363+ .mask = 0xffffffff, 54364+ .data = &vendor_hisi, 54365+ }, 54366+#endif 54367 { 0, 0 }, 54368 }; 54369 54370diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c 54371index 1850bacdb..d3934eb8f 100644 54372--- a/drivers/tty/vt/vc_screen.c 54373+++ b/drivers/tty/vt/vc_screen.c 54374@@ -373,6 +373,9 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 54375 loff_t pos; 54376 bool viewed, attr, uni_mode; 54377 54378+ if (use_unicode(inode)) 54379+ return -EOPNOTSUPP; 54380+ 54381 con_buf = (char *) __get_free_page(GFP_KERNEL); 54382 if (!con_buf) 54383 return -ENOMEM; 54384diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c 54385index 95a9bae72..ad951a1a1 100644 54386--- a/drivers/usb/core/hub.c 54387+++ b/drivers/usb/core/hub.c 54388@@ -1419,6 +1419,10 @@ static int hub_configure(struct usb_hub *hub, 54389 ret = -ENODEV; 54390 goto fail; 54391 } else if (hub->descriptor->bNbrPorts == 0) { 54392+ if (!hdev->parent) { 54393+ dev_info(hub_dev, "hub can't support USB3.0\n"); 54394+ return -ENODEV; 54395+ } 54396 message = "hub doesn't have any ports!"; 54397 ret = -ENODEV; 54398 goto fail; 54399diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c 54400index e61436637..b507a25ce 100644 54401--- a/drivers/usb/core/notify.c 54402+++ b/drivers/usb/core/notify.c 54403@@ -66,3 +66,11 @@ void usb_notify_remove_bus(struct usb_bus *ubus) 54404 { 54405 blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); 54406 } 54407+void usb_notify_online_status(bool online) 54408+{ 54409+ if (online) { 54410+ blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_ADD, NULL); 54411+ } else { 54412+ blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_REMOVE, NULL); 54413+ } 54414+} 54415diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile 54416index ae86da0dc..9abca9a8a 100644 54417--- a/drivers/usb/dwc3/Makefile 54418+++ b/drivers/usb/dwc3/Makefile 54419@@ -2,10 +2,9 @@ 54420 # define_trace.h needs to know how to find our header 54421 CFLAGS_trace.o := -I$(src) 54422 54423-obj-$(CONFIG_USB_DWC3) += dwc3.o 54424- 54425-dwc3-y := core.o 54426+obj-$(CONFIG_USB_DWC3) += dwc3.o dwc3-hisi.o 54427 54428+dwc3-y := core.o proc.o 54429 ifneq ($(CONFIG_TRACING),) 54430 dwc3-y += trace.o 54431 endif 54432diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c 54433index 1580d51ae..1219a6487 100644 54434--- a/drivers/usb/dwc3/core.c 54435+++ b/drivers/usb/dwc3/core.c 54436@@ -37,9 +37,25 @@ 54437 #include "io.h" 54438 54439 #include "debug.h" 54440+#include "dwc3-hisi.h" 54441 54442 #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ 54443 54444+ 54445+/* 54446+ * Default to the number of outstanding pipelined transfer 54447+ * requests is 0x3[11:8], modify the field change to 0x7. 54448+ */ 54449+static void dwc3_outstanding_pipe_choose(struct dwc3 *dwc) 54450+{ 54451+ u32 reg; 54452+ 54453+ reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1); 54454+ reg &= ~DWC3_PIPE_TRANS_LIMIT_MASK; 54455+ reg |= DWC3_PIPE_TRANS_LIMIT; 54456+ dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg); 54457+} 54458+ 54459 /** 54460 * dwc3_get_dr_mode - Validates and sets dr_mode 54461 * @dwc: pointer to our context structure 54462@@ -1294,7 +1310,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) 54463 */ 54464 hird_threshold = 12; 54465 54466- dwc->maximum_speed = usb_get_maximum_speed(dev); 54467+ dwc->maximum_speed = usb_get_max_speed(dev); 54468+ 54469 dwc->dr_mode = usb_get_dr_mode(dev); 54470 dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); 54471 54472@@ -1330,6 +1347,9 @@ static void dwc3_get_properties(struct dwc3 *dwc) 54473 device_property_read_u8(dev, "snps,tx-max-burst-prd", 54474 &tx_max_burst_prd); 54475 54476+ dwc->usb2_lpm_disable = device_property_read_bool(dev, 54477+ "snps,usb2-lpm-disable"); 54478+ 54479 dwc->disable_scramble_quirk = device_property_read_bool(dev, 54480 "snps,disable_scramble_quirk"); 54481 dwc->u2exit_lfps_quirk = device_property_read_bool(dev, 54482@@ -1367,6 +1387,16 @@ static void dwc3_get_properties(struct dwc3 *dwc) 54483 dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev, 54484 "snps,parkmode-disable-ss-quirk"); 54485 54486+ dwc->dis_initiate_u1 = device_property_read_bool(dev, 54487+ "snps,dis_initiate_u1"); 54488+ dwc->dis_initiate_u2 = device_property_read_bool(dev, 54489+ "snps,dis_initiate_u2"); 54490+ 54491+ dwc->eps_new_init = device_property_read_bool(dev, 54492+ "snps,eps_new_init"); 54493+ device_property_read_u32(dev, "eps_directions", 54494+ &dwc->eps_directions); 54495+ 54496 dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, 54497 "snps,tx_de_emphasis_quirk"); 54498 device_property_read_u8(dev, "snps,tx_de_emphasis", 54499@@ -1550,6 +1580,10 @@ static int dwc3_probe(struct platform_device *pdev) 54500 platform_set_drvdata(pdev, dwc); 54501 dwc3_cache_hwparams(dwc); 54502 54503+ device_property_read_u32_array(dev, "eps_map", 54504+ dwc->dwceps_map_to_usbeps, 54505+ DWC3_NUM_EPS(&dwc->hwparams)); 54506+ 54507 spin_lock_init(&dwc->lock); 54508 mutex_init(&dwc->mutex); 54509 54510@@ -1585,6 +1619,8 @@ static int dwc3_probe(struct platform_device *pdev) 54511 goto err4; 54512 } 54513 54514+ dwc3_outstanding_pipe_choose(dwc); 54515+ 54516 dwc3_check_params(dwc); 54517 dwc3_debugfs_init(dwc); 54518 54519@@ -1652,6 +1688,10 @@ static int dwc3_remove(struct platform_device *pdev) 54520 dwc3_free_event_buffers(dwc); 54521 dwc3_free_scratch_buffers(dwc); 54522 54523+ hisi_dwc3_exited(); 54524+ 54525+ dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); 54526+ 54527 return 0; 54528 } 54529 54530diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h 54531index 79e1b82e5..ace408a7e 100644 54532--- a/drivers/usb/dwc3/core.h 54533+++ b/drivers/usb/dwc3/core.h 54534@@ -32,6 +32,8 @@ 54535 #include <linux/phy/phy.h> 54536 54537 #define DWC3_MSG_MAX 500 54538+#define DWC3_PIPE_TRANS_LIMIT_MASK (0xf << 8) 54539+#define DWC3_PIPE_TRANS_LIMIT (0x7 << 8) 54540 54541 /* Global constants */ 54542 #define DWC3_PULL_UP_TIMEOUT 500 /* ms */ 54543@@ -478,6 +480,9 @@ 54544 54545 #define DWC3_DSTS_RXFIFOEMPTY BIT(17) 54546 54547+#define DWC3_EVENT_PRAM_MAX_SOFFN 0x3fff 54548+#define DWC3_EVENT_PRAM_SOFFN_MASK 0x3fff 54549+ 54550 #define DWC3_DSTS_SOFFN_MASK (0x3fff << 3) 54551 #define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3) 54552 54553@@ -658,7 +663,7 @@ struct dwc3_event_buffer { 54554 #define DWC3_EP_DIRECTION_TX true 54555 #define DWC3_EP_DIRECTION_RX false 54556 54557-#define DWC3_TRB_NUM 256 54558+#define DWC3_TRB_NUM 4096 54559 54560 /** 54561 * struct dwc3_ep - device side endpoint representation 54562@@ -726,8 +731,8 @@ struct dwc3_ep { 54563 * By using u8 types we ensure that our % operator when incrementing 54564 * enqueue and dequeue get optimized away by the compiler. 54565 */ 54566- u8 trb_enqueue; 54567- u8 trb_dequeue; 54568+ u32 trb_enqueue; 54569+ u32 trb_dequeue; 54570 54571 u8 number; 54572 u8 type; 54573@@ -1092,6 +1097,8 @@ struct dwc3 { 54574 struct dwc3_event_buffer *ev_buf; 54575 struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM]; 54576 54577+ u32 dwceps_map_to_usbeps[DWC3_ENDPOINTS_NUM]; 54578+ 54579 struct usb_gadget *gadget; 54580 struct usb_gadget_driver *gadget_driver; 54581 54582@@ -1199,6 +1206,12 @@ struct dwc3 { 54583 u8 speed; 54584 54585 u8 num_eps; 54586+/* 54587+ * NOTICE: eps_directions bitmap[0~31] 0: out ep, 1: in ep 54588+ * and used with total ep numbers(num_out_eps + num_in_eps) 54589+ */ 54590+#define DWC3_EPS_DEFAULT_DIRECTIONS 0xaaaaaaaa 54591+ u32 eps_directions; 54592 54593 struct dwc3_hwparams hwparams; 54594 struct dentry *root; 54595@@ -1215,6 +1228,13 @@ struct dwc3 { 54596 u8 tx_thr_num_pkt_prd; 54597 u8 tx_max_burst_prd; 54598 54599+ struct proc_dir_entry* parent_entry; 54600+ struct proc_dir_entry* csts_entry; 54601+ u8 udc_connect_status; 54602+#define UDC_DISCONNECTED 0 54603+#define UDC_CONNECT_HOST 1 54604+#define UDC_CONNECT_CHARGER 2 54605+ 54606 const char *hsphy_interface; 54607 54608 unsigned connected:1; 54609@@ -1253,6 +1273,10 @@ struct dwc3 { 54610 unsigned dis_del_phy_power_chg_quirk:1; 54611 unsigned dis_tx_ipgap_linecheck_quirk:1; 54612 unsigned parkmode_disable_ss_quirk:1; 54613+ unsigned dis_initiate_u1:1; 54614+ unsigned dis_initiate_u2:1; 54615+ 54616+ unsigned eps_new_init:1; 54617 54618 unsigned tx_de_emphasis_quirk:1; 54619 unsigned tx_de_emphasis:2; 54620@@ -1519,6 +1543,9 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc) 54621 { } 54622 #endif 54623 54624+int dwc3_proc_init(struct dwc3 *dwc); 54625+int dwc3_proc_shutdown(struct dwc3 *dwc); 54626+ 54627 /* power management interface */ 54628 #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) 54629 int dwc3_gadget_suspend(struct dwc3 *dwc); 54630diff --git a/drivers/usb/dwc3/dwc3-hisi.c b/drivers/usb/dwc3/dwc3-hisi.c 54631new file mode 100644 54632index 000000000..d8d3e8377 54633--- /dev/null 54634+++ b/drivers/usb/dwc3/dwc3-hisi.c 54635@@ -0,0 +1,446 @@ 54636+/* 54637+ * dwc3-hisi.c 54638+ * 54639+ * Dwc3 private driver for Hisilicon. 54640+ * 54641+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved. 54642+ * 54643+ * This program is free software; you can redistribute it and/or modify it 54644+ * under the terms of the GNU General Public License as published by the 54645+ * Free Software Foundation; either version 2 of the License, or (at your 54646+ * option) any later version. 54647+ * 54648+ * This program is distributed in the hope that it will be useful, 54649+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 54650+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 54651+ * GNU General Public License for more details. 54652+ * 54653+ * You should have received a copy of the GNU General Public License 54654+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 54655+ * 54656+ */ 54657+ 54658+#include <linux/clk-provider.h> 54659+#include <linux/clk.h> 54660+#include <linux/delay.h> 54661+#include <linux/dma-mapping.h> 54662+#include <linux/kernel.h> 54663+#include <linux/module.h> 54664+#include <linux/of.h> 54665+#include <linux/of_address.h> 54666+#include <linux/of_irq.h> 54667+#include <linux/of_platform.h> 54668+#include <linux/phy/phy.h> 54669+#include <linux/platform_device.h> 54670+#include <linux/pm_runtime.h> 54671+#include <linux/reset.h> 54672+#include <linux/slab.h> 54673+#include <linux/usb/ch9.h> 54674+ 54675+#include "dwc3-hisi.h" 54676+ 54677+#define USB3_CTRL 0x190 54678+#define REG_SYS_STAT 0x8c 54679+#define PCIE_USB3_MODE_MASK (0x3 << 12) 54680+#define USB3_PCLK_OCC_SEL (0x1 << 30) 54681+ 54682+#define PERI_USB3_GTXTHRCFG 0x2310000 54683+ 54684+#define REG_GUSB3PIPECTL0 0xc2c0 54685+#define GTXTHRCFG 0xc108 54686+ 54687+#define PCS_SSP_SOFT_RESET (0x1 << 31) 54688+#define SUSPEND_USB3_SS_PHY (0x1 << 17) 54689+ 54690+#define GUSB2PHYCFG_OFFSET 0xc200 54691+#define GCTL_OFFSET 0xc110 54692+#define GUCTL_OFFSET 0xc12C 54693+#define GFLADJ_OFFSET 0xc630 54694+ 54695+#define U2_FREECLK_EXISTS (0x1 << 30) 54696+#define SOFITPSYNC (0x1 << 10) 54697+#define REFCLKPER_MASK 0xffc00000 54698+#define REFCLKPER_VAL 0x29 54699+#define set_refclkper(a) (((a) << 22) & REFCLKPER_MASK) 54700+ 54701+#define PLS1 (0x1 << 31) 54702+#define DECR_MASK 0x7f000000 54703+#define DECR_VAL 0xa 54704+#define set_decr(a) (((a) << 24) & DECR_MASK) 54705+ 54706+#define LPM_SEL (0x1 << 23) 54707+#define FLADJ_MASK 0x003fff00 54708+#define FLADJ_VAL 0x7f0 54709+#define set_fladj(a) (((a) << 8) & FLADJ_MASK) 54710+ 54711+/* hi3559a */ 54712+#define DOUBLE_PCIE_MODE 0x0 54713+#define P0_PCIE_ADD_P1_USB3 (0x1 << 12) 54714+#define DOUBLE_USB3 (0x2 << 12) 54715+ 54716+/* hi3556a,hi3519a */ 54717+#define PCIE_X1_MODE (0x0 << 12) 54718+#define USB3_MODE (0x1 << 12) 54719+ 54720+static struct hi_priv *usb_priv = NULL; 54721+ 54722+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 54723+static int speed_adapt_for_hi3559a(struct device_node *np) 54724+{ 54725+ unsigned int ret; 54726+ unsigned int reg; 54727+ 54728+ if (np == NULL) 54729+ return -EINVAL; 54730+ 54731+ usb_priv->speed_id = -1; 54732+ 54733+ reg = readl(usb_priv->sys_ctrl + REG_SYS_STAT); 54734+ reg &= PCIE_USB3_MODE_MASK; 54735+ 54736+ switch (reg) { 54737+ case DOUBLE_PCIE_MODE: 54738+ ret = USB_SPEED_HIGH; 54739+ break; 54740+ case P0_PCIE_ADD_P1_USB3: 54741+ if (of_property_read_u32(np, "port_speed", &usb_priv->speed_id)) 54742+ usb_priv->speed_id = -1; 54743+ 54744+ if (usb_priv->speed_id == 0) 54745+ ret = USB_SPEED_HIGH; 54746+ else if (usb_priv->speed_id == 1) 54747+ ret = USB_SPEED_SUPER; 54748+ else 54749+ ret = USB_SPEED_UNKNOWN; 54750+ 54751+ break; 54752+ case DOUBLE_USB3: 54753+ ret = USB_SPEED_SUPER; 54754+ break; 54755+ default: 54756+ ret = USB_SPEED_UNKNOWN; 54757+ } 54758+ 54759+ return ret; 54760+} 54761+#endif 54762+ 54763+#if defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100) 54764+static int speed_adapt_for_hi3556a(struct device *dev) 54765+{ 54766+ unsigned int ret; 54767+ unsigned int reg; 54768+ 54769+ if (dev == NULL) 54770+ return -EINVAL; 54771+ 54772+ reg = readl(usb_priv->sys_ctrl + REG_SYS_STAT); 54773+ reg &= PCIE_USB3_MODE_MASK; 54774+ 54775+ if (reg == PCIE_X1_MODE) 54776+ ret = USB_SPEED_HIGH; 54777+ else 54778+ ret = usb_get_maximum_speed(dev); 54779+ 54780+ return ret; 54781+} 54782+#endif 54783+ 54784+int usb_get_max_speed(struct device *dev) 54785+{ 54786+ unsigned int ret; 54787+ struct device_node *np = dev->of_node; 54788+ 54789+ if (np == NULL) 54790+ return -EINVAL; 54791+ 54792+ usb_priv = kzalloc(sizeof(*usb_priv), GFP_KERNEL); 54793+ if (usb_priv == NULL) 54794+ return -ENOMEM; 54795+ 54796+ usb_priv->peri_crg = of_iomap(np, DEV_NODE_FLAG1); 54797+ if (IS_ERR(usb_priv->peri_crg)) { 54798+ kfree(usb_priv); 54799+ usb_priv = NULL; 54800+ return -ENOMEM; 54801+ } 54802+ 54803+ usb_priv->sys_ctrl = of_iomap(np, DEV_NODE_FLAG2); 54804+ if (IS_ERR(usb_priv->sys_ctrl)) { 54805+ iounmap(usb_priv->peri_crg); 54806+ 54807+ kfree(usb_priv); 54808+ usb_priv = NULL; 54809+ return -ENOMEM; 54810+ } 54811+ 54812+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100) 54813+ ret = speed_adapt_for_hi3559a(np); 54814+#elif defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100) 54815+ ret = speed_adapt_for_hi3556a(dev); 54816+#else 54817+ ret = usb_get_maximum_speed(dev); 54818+#endif 54819+ 54820+ iounmap(usb_priv->sys_ctrl); 54821+ iounmap(usb_priv->peri_crg); 54822+ 54823+ return ret; 54824+} 54825+EXPORT_SYMBOL(usb_get_max_speed); 54826+ 54827+void hisi_dwc3_exited(void) 54828+{ 54829+ kfree(usb_priv); 54830+ usb_priv = NULL; 54831+} 54832+EXPORT_SYMBOL(hisi_dwc3_exited); 54833+ 54834+static int set_ctrl_crg_val(struct device_node *np, struct dwc3_hisi *hisi) 54835+{ 54836+ unsigned int ret; 54837+ unsigned int reg; 54838+ 54839+ if ((np == NULL) || (hisi == NULL)) 54840+ return -EINVAL; 54841+ 54842+ /* get usb ctrl crg para */ 54843+ ret = of_property_read_u32(np, "crg_offset", &hisi->crg_offset); 54844+ if (ret) 54845+ return ret; 54846+ 54847+ ret = of_property_read_u32(np, "crg_ctrl_def_mask", &hisi->crg_ctrl_def_mask); 54848+ if (ret) 54849+ return ret; 54850+ 54851+ ret = of_property_read_u32(np, "crg_ctrl_def_val", &hisi->crg_ctrl_def_val); 54852+ if (ret) 54853+ return ret; 54854+ 54855+ /* write usb ctrl crg default value */ 54856+ reg = readl(hisi->crg_base + hisi->crg_offset); 54857+ reg &= ~hisi->crg_ctrl_def_mask; 54858+ reg |= hisi->crg_ctrl_def_val; 54859+ writel(reg, hisi->crg_base + hisi->crg_offset); 54860+ 54861+ return 0; 54862+} 54863+ 54864+static int dwc3_hisi_clk_init(struct dwc3_hisi *hisi, int count) 54865+{ 54866+ struct device *dev = hisi->dev; 54867+ struct device_node *np = dev->of_node; 54868+ int i, ret; 54869+ 54870+ if (!count) 54871+ return -EINVAL; 54872+ 54873+ if (np == NULL) 54874+ return -EINVAL; 54875+ 54876+ hisi->num_clocks = count; 54877+ 54878+ hisi->clks = devm_kcalloc(dev, hisi->num_clocks, sizeof(struct clk *), 54879+ GFP_KERNEL); 54880+ if (hisi->clks == NULL) 54881+ return -ENOMEM; 54882+ 54883+ for (i = 0; i < hisi->num_clocks; i++) { 54884+ struct clk *clk; 54885+ 54886+ clk = of_clk_get(np, i); 54887+ if (IS_ERR(clk)) { 54888+ while (--i >= 0) 54889+ clk_put(hisi->clks[i]); 54890+ 54891+ ret = PTR_ERR(clk); 54892+ goto clk_free; 54893+ } 54894+ 54895+ ret = clk_prepare_enable(clk); 54896+ if (ret < 0) { 54897+ while (--i >= 0) { 54898+ clk_disable_unprepare(hisi->clks[i]); 54899+ clk_put(hisi->clks[i]); 54900+ } 54901+ clk_put(clk); 54902+ 54903+ goto clk_free; 54904+ } 54905+ 54906+ hisi->clks[i] = clk; 54907+ } 54908+ 54909+ return 0; 54910+clk_free: 54911+ devm_kfree(dev, hisi->clks); 54912+ hisi->clks = NULL; 54913+ 54914+ return ret; 54915+} 54916+ 54917+static void control_free_clk_config(struct dwc3_hisi *hisi) 54918+{ 54919+ unsigned int reg; 54920+ 54921+ if (hisi == NULL) 54922+ return; 54923+ 54924+ reg = readl(hisi->ctrl_base + GUSB2PHYCFG_OFFSET); 54925+ reg &= ~U2_FREECLK_EXISTS; 54926+ writel(reg, hisi->ctrl_base + GUSB2PHYCFG_OFFSET); 54927+ 54928+ reg = readl(hisi->ctrl_base + GCTL_OFFSET); 54929+ reg &= ~SOFITPSYNC; 54930+ writel(reg, hisi->ctrl_base + GCTL_OFFSET); 54931+ 54932+ reg = readl(hisi->ctrl_base + GUCTL_OFFSET); 54933+ reg &= ~REFCLKPER_MASK; 54934+ reg |= set_refclkper(REFCLKPER_VAL); 54935+ writel(reg, hisi->ctrl_base + GUCTL_OFFSET); 54936+ 54937+ reg = readl(hisi->ctrl_base + GFLADJ_OFFSET); 54938+ reg &= ~PLS1; 54939+ writel(reg, hisi->ctrl_base + GFLADJ_OFFSET); 54940+ 54941+ reg = readl(hisi->ctrl_base + GFLADJ_OFFSET); 54942+ reg &= ~DECR_MASK; 54943+ reg |= set_decr(DECR_VAL); 54944+ writel(reg, hisi->ctrl_base + GFLADJ_OFFSET); 54945+ 54946+ reg = readl(hisi->ctrl_base + GFLADJ_OFFSET); 54947+ reg |= LPM_SEL; 54948+ writel(reg, hisi->ctrl_base + GFLADJ_OFFSET); 54949+ 54950+ reg = readl(hisi->ctrl_base + GFLADJ_OFFSET); 54951+ reg &= ~FLADJ_MASK; 54952+ reg |= set_fladj(FLADJ_VAL); 54953+ writel(reg, hisi->ctrl_base + GFLADJ_OFFSET); 54954+} 54955+ 54956+static int dwc3_hisi_iomap(struct device_node *np, struct dwc3_hisi *hisi) 54957+{ 54958+ if ((np == NULL) || (hisi == NULL)) 54959+ return -EINVAL; 54960+ 54961+ hisi->ctrl_base = of_iomap(np, DEV_NODE_FLAG0); 54962+ if (IS_ERR(hisi->ctrl_base)) 54963+ return -ENOMEM; 54964+ 54965+ hisi->crg_base = of_iomap(np, DEV_NODE_FLAG1); 54966+ if (IS_ERR(hisi->crg_base)) { 54967+ iounmap(hisi->ctrl_base); 54968+ return -ENOMEM; 54969+ } 54970+ 54971+ return 0; 54972+} 54973+ 54974+static int dwc3_hisi_probe(struct platform_device *pdev) 54975+{ 54976+ struct dwc3_hisi *hisi = NULL; 54977+ struct device *dev = &pdev->dev; 54978+ struct device_node *np = dev->of_node; 54979+ int ret, i; 54980+ 54981+ hisi = devm_kzalloc(dev, sizeof(*hisi), GFP_KERNEL); 54982+ if (hisi == NULL) 54983+ return -ENOMEM; 54984+ 54985+ platform_set_drvdata(pdev, hisi); 54986+ hisi->dev = dev; 54987+ 54988+ ret = dwc3_hisi_iomap(np, hisi); 54989+ if (ret) { 54990+ devm_kfree(dev, hisi); 54991+ hisi = NULL; 54992+ 54993+ return -ENOMEM; 54994+ } 54995+ 54996+ hisi->port_rst = devm_reset_control_get(dev, "vcc_reset"); 54997+ if (IS_ERR_OR_NULL(hisi->port_rst)) { 54998+ ret = PTR_ERR(hisi->port_rst); 54999+ goto hidwc3_unmap; 55000+ } 55001+ 55002+ ret = set_ctrl_crg_val(np, hisi); 55003+ if (ret) 55004+ goto hidwc3_unmap; 55005+ 55006+ reset_control_assert(hisi->port_rst); 55007+ 55008+ ret = dwc3_hisi_clk_init(hisi, of_clk_get_parent_count(np)); 55009+ if (ret) 55010+ goto hidwc3_unmap; 55011+ 55012+ reset_control_deassert(hisi->port_rst); 55013+ 55014+ control_free_clk_config(hisi); 55015+ 55016+ udelay(U_LEVEL2); 55017+ 55018+ ret = of_platform_populate(np, NULL, NULL, dev); 55019+ if (ret) { 55020+ for (i = 0; i < hisi->num_clocks; i++) { 55021+ clk_disable_unprepare(hisi->clks[i]); 55022+ clk_put(hisi->clks[i]); 55023+ } 55024+ goto hidwc3_unmap; 55025+ } 55026+ 55027+ return 0; 55028+hidwc3_unmap: 55029+ iounmap(hisi->ctrl_base); 55030+ iounmap(hisi->crg_base); 55031+ 55032+ devm_kfree(dev, hisi); 55033+ hisi = NULL; 55034+ 55035+ return ret; 55036+} 55037+ 55038+static int dwc3_hisi_remove(struct platform_device *pdev) 55039+{ 55040+ struct dwc3_hisi *hisi = platform_get_drvdata(pdev); 55041+ struct device *dev = &pdev->dev; 55042+ int i; 55043+ 55044+ for (i = 0; i < hisi->num_clocks; i++) { 55045+ clk_disable_unprepare(hisi->clks[i]); 55046+ clk_put(hisi->clks[i]); 55047+ } 55048+ 55049+ reset_control_assert(hisi->port_rst); 55050+ 55051+ of_platform_depopulate(dev); 55052+ 55053+ iounmap(hisi->ctrl_base); 55054+ iounmap(hisi->crg_base); 55055+ 55056+ devm_kfree(dev, hisi); 55057+ hisi = NULL; 55058+ 55059+ return 0; 55060+} 55061+ 55062+static const struct of_device_id hisi_dwc3_match[] = { 55063+ { .compatible = "hisi,dwusb2" }, 55064+ { .compatible = "hisi,dwusb3" }, 55065+ {}, 55066+}; 55067+MODULE_DEVICE_TABLE(of, hisi_dwc3_match); 55068+ 55069+static struct platform_driver dwc3_hisi_driver = { 55070+ .probe = dwc3_hisi_probe, 55071+ .remove = dwc3_hisi_remove, 55072+ .driver = { 55073+ .name = "hisi-dwc3", 55074+ .of_match_table = hisi_dwc3_match, 55075+ }, 55076+}; 55077+module_platform_driver(dwc3_hisi_driver); 55078+ 55079+MODULE_LICENSE("GPL v2"); 55080+MODULE_DESCRIPTION("DesignWare USB3 of Hisilicon"); 55081+MODULE_AUTHOR("Hisilicon Technologies Co., Ltd..>"); 55082diff --git a/drivers/usb/dwc3/dwc3-hisi.h b/drivers/usb/dwc3/dwc3-hisi.h 55083new file mode 100644 55084index 000000000..606cf0507 55085--- /dev/null 55086+++ b/drivers/usb/dwc3/dwc3-hisi.h 55087@@ -0,0 +1,54 @@ 55088+/* 55089+ * dwc3-hisi.h 55090+ * 55091+ * Dwc3 private headerfile for Hisilicon. 55092+ * 55093+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved. 55094+ * 55095+ * This program is free software; you can redistribute it and/or modify it 55096+ * under the terms of the GNU General Public License as published by the 55097+ * Free Software Foundation; either version 2 of the License, or (at your 55098+ * option) any later version. 55099+ * 55100+ * This program is distributed in the hope that it will be useful, 55101+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 55102+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 55103+ * GNU General Public License for more details. 55104+ * 55105+ * You should have received a copy of the GNU General Public License 55106+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 55107+ * 55108+ */ 55109+ 55110+#ifndef USB_INCLUDE_DWC3_HISI_H 55111+#define USB_INCLUDE_DWC3_HISI_H 55112+ 55113+struct hi_priv { 55114+ void __iomem *peri_crg; 55115+ void __iomem *sys_ctrl; 55116+ void __iomem *misc_ctrl; 55117+ unsigned int speed_id; 55118+}; 55119+ 55120+struct dwc3_hisi { 55121+ struct device *dev; 55122+ struct clk **clks; 55123+ int num_clocks; 55124+ void __iomem *ctrl_base; 55125+ void __iomem *crg_base; 55126+ struct reset_control *port_rst; 55127+ u32 crg_offset; 55128+ u32 crg_ctrl_def_mask; 55129+ u32 crg_ctrl_def_val; 55130+}; 55131+ 55132+extern int usb_get_max_speed(struct device *dev); 55133+extern void hisi_dwc3_exited(void); 55134+ 55135+#define DEV_NODE_FLAG0 0 55136+#define DEV_NODE_FLAG1 1 55137+#define DEV_NODE_FLAG2 2 55138+ 55139+#define U_LEVEL2 200 55140+ 55141+#endif 55142diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c 55143index 3cd294264..edf3f9b59 100644 55144--- a/drivers/usb/dwc3/ep0.c 55145+++ b/drivers/usb/dwc3/ep0.c 55146@@ -281,6 +281,24 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) 55147 WARN_ON(ret < 0); 55148 } 55149 55150+static u32 dwc3_usbep_to_dwc3ep(struct dwc3 *dwc, u32 num) 55151+{ 55152+ u32 res = 0; 55153+ int i; 55154+ 55155+ if (!dwc) 55156+ return 0; 55157+ 55158+ for (i = 0; i < dwc->num_eps; i++) { 55159+ if (dwc->dwceps_map_to_usbeps[i] == num) { 55160+ res = i; 55161+ break; 55162+ } 55163+ } 55164+ 55165+ return res; 55166+} 55167+ 55168 static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) 55169 { 55170 struct dwc3_ep *dep; 55171@@ -291,6 +309,9 @@ static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) 55172 if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) 55173 epnum |= 1; 55174 55175+ if (dwc->eps_new_init) 55176+ epnum = dwc3_usbep_to_dwc3ep(dwc, epnum); 55177+ 55178 dep = dwc->eps[epnum]; 55179 if (dep == NULL) 55180 return NULL; 55181@@ -385,6 +406,9 @@ static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state, 55182 if (set && dwc->dis_u1_entry_quirk) 55183 return -EINVAL; 55184 55185+ if (dwc->dis_initiate_u1) 55186+ return -EINVAL; 55187+ 55188 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 55189 if (set) 55190 reg |= DWC3_DCTL_INITU1ENA; 55191@@ -409,6 +433,9 @@ static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state, 55192 if (set && dwc->dis_u2_entry_quirk) 55193 return -EINVAL; 55194 55195+ if (dwc->dis_initiate_u2) 55196+ return -EINVAL; 55197+ 55198 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 55199 if (set) 55200 reg |= DWC3_DCTL_INITU2ENA; 55201@@ -638,9 +665,14 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) 55202 * nothing is pending from application. 55203 */ 55204 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 55205- if (!dwc->dis_u1_entry_quirk) 55206+ if (dwc->dis_initiate_u1) 55207+ reg &= (~DWC3_DCTL_ACCEPTU1ENA); 55208+ else 55209 reg |= DWC3_DCTL_ACCEPTU1ENA; 55210- if (!dwc->dis_u2_entry_quirk) 55211+ 55212+ if (dwc->dis_initiate_u2) 55213+ reg &= (~DWC3_DCTL_ACCEPTU2ENA); 55214+ else 55215 reg |= DWC3_DCTL_ACCEPTU2ENA; 55216 dwc3_writel(dwc->regs, DWC3_DCTL, reg); 55217 } 55218diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c 55219old mode 100644 55220new mode 100755 55221index b75fe5680..bec11c742 55222--- a/drivers/usb/dwc3/gadget.c 55223+++ b/drivers/usb/dwc3/gadget.c 55224@@ -27,6 +27,8 @@ 55225 #include "gadget.h" 55226 #include "io.h" 55227 55228+static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep); 55229+ 55230 #define DWC3_ALIGN_FRAME(d, n) (((d)->frame_number + ((d)->interval * (n))) \ 55231 & ~((d)->interval - 1)) 55232 55233@@ -147,7 +149,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) 55234 * if it is point to the link TRB, wrap around to the beginning. The 55235 * link TRB is always at the last TRB entry. 55236 */ 55237-static void dwc3_ep_inc_trb(u8 *index) 55238+static void dwc3_ep_inc_trb(u32 *index) 55239 { 55240 (*index)++; 55241 if (*index == (DWC3_TRB_NUM - 1)) 55242@@ -594,7 +596,11 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action) 55243 * so on. We consider the direction bit as part of the physical 55244 * endpoint number. So USB endpoint 0x81 is 0x03. 55245 */ 55246- params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number); 55247+ if (dwc->eps_new_init) 55248+ params.param1 |= 55249+ DWC3_DEPCFG_EP_NUMBER(dwc->dwceps_map_to_usbeps[dep->number]); 55250+ else 55251+ params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number); 55252 55253 /* 55254 * We must use the lower 16 TX FIFOs even though 55255@@ -665,7 +671,12 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) 55256 dep->flags |= DWC3_EP_ENABLED; 55257 55258 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); 55259- reg |= DWC3_DALEPENA_EP(dep->number); 55260+ 55261+ if (dwc->eps_new_init) 55262+ reg |= DWC3_DALEPENA_EP(dwc->dwceps_map_to_usbeps[dep->number]); 55263+ else 55264+ reg |= DWC3_DALEPENA_EP(dep->number); 55265+ 55266 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); 55267 55268 if (usb_endpoint_xfer_control(desc)) 55269@@ -789,7 +800,12 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) 55270 __dwc3_gadget_ep_set_halt(dep, 0, false); 55271 55272 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); 55273- reg &= ~DWC3_DALEPENA_EP(dep->number); 55274+ 55275+ if (dwc->eps_new_init) 55276+ reg &= ~DWC3_DALEPENA_EP(dwc->dwceps_map_to_usbeps[dep->number]); 55277+ else 55278+ reg &= ~DWC3_DALEPENA_EP(dep->number); 55279+ 55280 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); 55281 55282 /* Clear out the ep descriptors for non-ep0 */ 55283@@ -920,9 +936,9 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, 55284 * index is 0, we will wrap backwards, skip the link TRB, and return 55285 * the one just before that. 55286 */ 55287-static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) 55288+static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u32 index) 55289 { 55290- u8 tmp = index; 55291+ u32 tmp = index; 55292 55293 if (!tmp) 55294 tmp = DWC3_TRB_NUM - 1; 55295@@ -932,7 +948,7 @@ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) 55296 55297 static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) 55298 { 55299- u8 trbs_left; 55300+ u32 trbs_left; 55301 55302 /* 55303 * If the enqueue & dequeue are equal then the TRB ring is either full 55304@@ -968,6 +984,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, 55305 struct dwc3 *dwc = dep->dwc; 55306 struct usb_gadget *gadget = dwc->gadget; 55307 enum usb_device_speed speed = gadget->speed; 55308+ unsigned int chain_skip = 0; 55309 55310 trb->size = DWC3_TRB_SIZE_LENGTH(length); 55311 trb->bpl = lower_32_bits(dma); 55312@@ -1016,8 +1033,19 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, 55313 mult--; 55314 55315 trb->size |= DWC3_TRB_SIZE_PCM1(mult); 55316+ 55317+ /* 55318+ * If there are three transactions per mframe, 55319+ * and each transcation length = 1024B, no any 55320+ * chain trb needed, so skip it. 55321+ */ 55322+ if (req->request.length == (3 * maxp)) 55323+ chain_skip = 1; 55324 } 55325+ if (speed == USB_SPEED_SUPER) 55326+ chain_skip = 1; 55327 } else { 55328+ chain_skip = 1; 55329 trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; 55330 } 55331 55332@@ -1053,7 +1081,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, 55333 if ((!no_interrupt && !chain) || must_interrupt) 55334 trb->ctrl |= DWC3_TRB_CTRL_IOC; 55335 55336- if (chain) 55337+ if ((!chain_skip) && chain) 55338 trb->ctrl |= DWC3_TRB_CTRL_CHN; 55339 else if (dep->stream_capable && is_last) 55340 trb->ctrl |= DWC3_TRB_CTRL_LST; 55341@@ -1167,6 +1195,9 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, 55342 static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, 55343 struct dwc3_request *req) 55344 { 55345+ struct dwc3 *dwc = dep->dwc; 55346+ struct usb_gadget *gadget = dwc->gadget; 55347+ enum usb_device_speed speed = gadget->speed; 55348 struct scatterlist *sg = req->start_sg; 55349 struct scatterlist *s; 55350 int i; 55351@@ -1220,9 +1251,13 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, 55352 num_trbs_left <= 2 && 55353 sg_dma_len(sg_next(s)) >= length)) 55354 must_interrupt = true; 55355- 55356- dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false, 55357- must_interrupt); 55358+ if ((speed == USB_SPEED_HIGH) && 55359+ usb_endpoint_xfer_isoc(dep->endpoint.desc)) 55360+ dwc3_prepare_one_trb(dep, req, trb_length, 1, 0, false, 55361+ must_interrupt); 55362+ else 55363+ dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false, 55364+ must_interrupt); 55365 } 55366 55367 /* 55368@@ -1382,6 +1417,13 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) 55369 if (starting) { 55370 params.param0 = upper_32_bits(req->trb_dma); 55371 params.param1 = lower_32_bits(req->trb_dma); 55372+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { 55373+ while (__dwc3_gadget_target_frame_elapsed(dep)) 55374+ dep->frame_number = DWC3_ALIGN_FRAME(dep, 1); 55375+ 55376+ dep->frame_number = DWC3_ALIGN_FRAME(dep, 1); 55377+ } 55378+ 55379 cmd = DWC3_DEPCMD_STARTTRANSFER; 55380 55381 if (dep->stream_capable) 55382@@ -1427,6 +1469,16 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc) 55383 return DWC3_DSTS_SOFFN(reg); 55384 } 55385 55386+static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep) { 55387+ u16 cframe = __dwc3_gadget_get_frame(dep->dwc); 55388+ u16 eframe = dep->frame_number & DWC3_EVENT_PRAM_SOFFN_MASK; 55389+ if (eframe == cframe) 55390+ return true; 55391+ 55392+ return (((eframe - cframe) & DWC3_EVENT_PRAM_SOFFN_MASK) 55393+ > DWC3_EVENT_PRAM_MAX_SOFFN / 2); 55394+} 55395+ 55396 /** 55397 * dwc3_gadget_start_isoc_quirk - workaround invalid frame number 55398 * @dep: isoc endpoint 55399@@ -1584,6 +1636,9 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) 55400 } 55401 55402 for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) { 55403+ while (__dwc3_gadget_target_frame_elapsed(dep)) 55404+ dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1); 55405+ 55406 dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1); 55407 55408 ret = __dwc3_gadget_kick_transfer(dep); 55409@@ -1668,8 +1723,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) 55410 */ 55411 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { 55412 if (!(dep->flags & DWC3_EP_PENDING_REQUEST) && 55413- !(dep->flags & DWC3_EP_TRANSFER_STARTED)) 55414+ list_empty(&dep->started_list)) { 55415+ dwc3_stop_active_transfer(dep, true, true); 55416 return 0; 55417+ } 55418 55419 if ((dep->flags & DWC3_EP_PENDING_REQUEST)) { 55420 if (!(dep->flags & DWC3_EP_TRANSFER_STARTED)) 55421@@ -1756,6 +1813,9 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, 55422 55423 spin_lock_irqsave(&dwc->lock, flags); 55424 55425+ if (list_empty(&dep->pending_list) && list_empty(&dep->started_list) ) 55426+ goto out; 55427+ 55428 list_for_each_entry(r, &dep->cancelled_list, list) { 55429 if (r == req) 55430 goto out; 55431@@ -2679,12 +2739,77 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum) 55432 return 0; 55433 } 55434 55435+static int dwc3_gadget_init_hw_all_endpoints(struct dwc3 *dwc) 55436+{ 55437+ struct dwc3_ep *dep = NULL; 55438+ struct dwc3_hwparams *parms = &dwc->hwparams; 55439+ u32 direction = dwc->eps_directions; 55440+ u8 num_eps = DWC3_NUM_EPS(parms); 55441+ u8 num_in_eps = 0; 55442+ u8 num_out_eps = 0; 55443+ u8 epnum = 0; 55444+ u8 i; 55445+ int ret; 55446+ 55447+ if (!direction) 55448+ direction = DWC3_EPS_DEFAULT_DIRECTIONS; 55449+ 55450+ for (i = 0; i < num_eps; i++) { 55451+ if (direction & 0x1) 55452+ epnum = (num_in_eps++ << 1) + 1; 55453+ else 55454+ epnum = (num_out_eps++ << 1); 55455+ 55456+ dep = kzalloc(sizeof(*dep), GFP_KERNEL); 55457+ if (!dep) 55458+ return -ENOMEM; 55459+ 55460+ dep->dwc = dwc; 55461+ dep->number = i; 55462+ dep->direction = !!(direction & 0x1); 55463+ dep->regs = dwc->regs + DWC3_DEP_BASE(i); 55464+ dwc->eps[i] = dep; 55465+ 55466+ snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, 55467+ (epnum & 1) ? "in" : "out"); 55468+ 55469+ dep->endpoint.name = dep->name; 55470+ 55471+ if (epnum == 0 || epnum == 1) { 55472+ dep->endpoint.desc = &dwc3_gadget_ep0_desc; 55473+ dep->endpoint.comp_desc = NULL; 55474+ ret = dwc3_gadget_init_control_endpoint(dep); 55475+ } else if (dep->direction) { 55476+ ret = dwc3_gadget_init_in_endpoint(dep); 55477+ } else { 55478+ ret = dwc3_gadget_init_out_endpoint(dep); 55479+ } 55480+ 55481+ if (ret) 55482+ return ret; 55483+ 55484+ dep->endpoint.caps.dir_in = !!(direction & 0x1); 55485+ dep->endpoint.caps.dir_out = !(direction & 0x1); 55486+ direction = (direction >> 1); 55487+ 55488+ INIT_LIST_HEAD(&dep->pending_list); 55489+ INIT_LIST_HEAD(&dep->started_list); 55490+ INIT_LIST_HEAD(&dep->cancelled_list); 55491+ } 55492+ 55493+ return 0; 55494+} 55495+ 55496 static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 total) 55497 { 55498 u8 epnum; 55499 55500 INIT_LIST_HEAD(&dwc->gadget->ep_list); 55501 55502+ if (dwc->eps_new_init) { 55503+ return dwc3_gadget_init_hw_all_endpoints(dwc); 55504+ } 55505+ 55506 for (epnum = 0; epnum < total; epnum++) { 55507 int ret; 55508 55509@@ -3640,6 +3765,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, 55510 break; 55511 case DWC3_DEVICE_EVENT_CONNECT_DONE: 55512 dwc3_gadget_conndone_interrupt(dwc); 55513+ usb_notify_online_status(true); 55514 break; 55515 case DWC3_DEVICE_EVENT_WAKEUP: 55516 dwc3_gadget_wakeup_interrupt(dwc); 55517@@ -3661,9 +3787,11 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, 55518 * Ignore suspend event until the gadget enters into 55519 * USB_STATE_CONFIGURED state. 55520 */ 55521- if (dwc->gadget->state >= USB_STATE_CONFIGURED) 55522+ if (dwc->gadget->state >= USB_STATE_CONFIGURED) { 55523 dwc3_gadget_suspend_interrupt(dwc, 55524 event->event_info); 55525+ usb_notify_online_status(false); 55526+ } 55527 } 55528 break; 55529 case DWC3_DEVICE_EVENT_SOF: 55530@@ -3892,6 +4020,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) 55531 goto err3; 55532 } 55533 55534+ dwc3_proc_init(dwc); 55535 55536 usb_initialize_gadget(dwc->dev, dwc->gadget, dwc_gadget_release); 55537 dev = &dwc->gadget->dev; 55538diff --git a/drivers/usb/dwc3/proc.c b/drivers/usb/dwc3/proc.c 55539new file mode 100755 55540index 000000000..7425e0eb9 55541--- /dev/null 55542+++ b/drivers/usb/dwc3/proc.c 55543@@ -0,0 +1,138 @@ 55544+/* 55545+ * proc.c 55546+ * 55547+ * Dwc3 private driver for Hisilicon. 55548+ * 55549+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved. 55550+ * 55551+ * This program is free software; you can redistribute it and/or modify it 55552+ * under the terms of the GNU General Public License as published by the 55553+ * Free Software Foundation; either version 2 of the License, or (at your 55554+ * option) any later version. 55555+ * 55556+ * This program is distributed in the hope that it will be useful, 55557+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 55558+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 55559+ * GNU General Public License for more details. 55560+ * 55561+ * You should have received a copy of the GNU General Public License 55562+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 55563+ * 55564+ */ 55565+ 55566+#include <linux/proc_fs.h> 55567+#include <linux/seq_file.h> 55568+#include <linux/device.h> 55569+#include <linux/io.h> 55570+#include <linux/platform_device.h> 55571+ 55572+#include "core.h" 55573+ 55574+#define DWC3_PROC_ROOT "dwc3" 55575+#define DWC3_PROC_CONNECTED_STATUS "csts" 55576+ 55577+static struct proc_dir_entry *proc_dwc3_dir = NULL; 55578+static int proc_dwc3_dir_cnt = 0; 55579+ 55580+static void dwc3_stats_seq_printout(struct seq_file *s) 55581+{ 55582+ struct dwc3 *dwc = s->private; 55583+ 55584+ switch (dwc->udc_connect_status) { 55585+ case UDC_CONNECT_HOST: 55586+ seq_puts(s, "cnt2host\n"); 55587+ break; 55588+ case UDC_CONNECT_CHARGER: 55589+ seq_puts(s, "cnt2charger\n"); 55590+ break; 55591+ default: 55592+ seq_puts(s, "disconnected\n"); 55593+ break; 55594+ } 55595+} 55596+ 55597+/* define parameters where showed in proc file */ 55598+static int dwc3_stats_seq_show(struct seq_file *s, void *v) 55599+{ 55600+ if (s == NULL) 55601+ return -EINVAL; 55602+ 55603+ dwc3_stats_seq_printout(s); 55604+ return 0; 55605+} 55606+ 55607+/* proc file open */ 55608+static int dwc3_stats_proc_open(struct inode *inode, struct file *file) 55609+{ 55610+ if ((inode == NULL) || (file == NULL)) 55611+ return -EINVAL; 55612+ 55613+ return single_open(file, dwc3_stats_seq_show, PDE_DATA(inode)); 55614+}; 55615+ 55616+/* proc file operation */ 55617+static const struct proc_ops dwc3_stats_proc_ops = { 55618+ .proc_open = dwc3_stats_proc_open, 55619+ .proc_read = seq_read, 55620+ .proc_release = single_release, 55621+}; 55622+ 55623+int dwc3_proc_init(struct dwc3 *dwc) 55624+{ 55625+ struct proc_dir_entry *proc_entry = NULL; 55626+ 55627+ if (dwc == NULL) 55628+ return -EINVAL; 55629+ 55630+ if (proc_dwc3_dir == NULL) { 55631+ proc_entry = proc_mkdir(DWC3_PROC_ROOT, NULL); 55632+ if (proc_entry == NULL) { 55633+ pr_err("%s: failed to create proc file %s\n", 55634+ __func__, DWC3_PROC_ROOT); 55635+ return 1; 55636+ } 55637+ proc_dwc3_dir = proc_entry; 55638+ } 55639+ proc_dwc3_dir_cnt++; 55640+ 55641+ proc_entry = proc_mkdir(to_platform_device(dwc->dev)->name, proc_dwc3_dir); 55642+ if (proc_entry == NULL) { 55643+ pr_err("%s: failed to create proc file %s\n", 55644+ __func__, to_platform_device(dwc->dev)->name); 55645+ return -1; 55646+ } 55647+ dwc->parent_entry = proc_entry; 55648+ 55649+ proc_entry = proc_create_data(DWC3_PROC_CONNECTED_STATUS, 55650+ 0, dwc->parent_entry, 55651+ &dwc3_stats_proc_ops, dwc); 55652+ if (proc_entry == NULL) { 55653+ pr_err("%s: failed to create proc file %s\n", 55654+ __func__, DWC3_PROC_CONNECTED_STATUS); 55655+ return -1; 55656+ } 55657+ dwc->csts_entry = proc_entry; 55658+ 55659+ /* 55660+ * add here if more proc information need. 55661+ */ 55662+ return 0; 55663+} 55664+ 55665+int dwc3_proc_shutdown(struct dwc3 *dwc) 55666+{ 55667+ if (proc_dwc3_dir != NULL) { 55668+ remove_proc_entry(DWC3_PROC_CONNECTED_STATUS, dwc->parent_entry); 55669+ remove_proc_entry(to_platform_device(dwc->dev)->name, proc_dwc3_dir); 55670+ } 55671+ 55672+ if (proc_dwc3_dir_cnt) 55673+ proc_dwc3_dir_cnt--; 55674+ 55675+ if (proc_dwc3_dir_cnt == 0) { 55676+ remove_proc_entry(DWC3_PROC_ROOT, NULL); 55677+ proc_dwc3_dir = NULL; 55678+ } 55679+ 55680+ return 0; 55681+} 55682diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c 55683index 8bec0cbf8..db79eab52 100644 55684--- a/drivers/usb/gadget/composite.c 55685+++ b/drivers/usb/gadget/composite.c 55686@@ -705,8 +705,7 @@ static int bos_desc(struct usb_composite_dev *cdev) 55687 usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE; 55688 usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY; 55689 usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT; 55690- usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | 55691- USB_BESL_SUPPORT | besl); 55692+ usb_ext->bmAttributes = cpu_to_le32(0x0); 55693 55694 /* 55695 * The Superspeed USB Capability descriptor shall be implemented by all 55696diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c 55697old mode 100644 55698new mode 100755 55699index 1eb4fa2e6..02be1969b 55700--- a/drivers/usb/gadget/epautoconf.c 55701+++ b/drivers/usb/gadget/epautoconf.c 55702@@ -67,6 +67,9 @@ struct usb_ep *usb_ep_autoconfig_ss( 55703 ) 55704 { 55705 struct usb_ep *ep; 55706+ u8 type; 55707+ 55708+ type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; 55709 55710 if (gadget->ops->match_ep) { 55711 ep = gadget->ops->match_ep(gadget, desc, ep_comp); 55712@@ -75,9 +78,16 @@ struct usb_ep *usb_ep_autoconfig_ss( 55713 } 55714 55715 /* Second, look at endpoints until an unclaimed one looks usable */ 55716- list_for_each_entry (ep, &gadget->ep_list, ep_list) { 55717- if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) 55718- goto found_ep; 55719+ if (type == USB_ENDPOINT_XFER_INT) { 55720+ list_for_each_entry_reverse(ep, &gadget->ep_list, ep_list) { 55721+ if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) 55722+ goto found_ep; 55723+ } 55724+ } else { 55725+ list_for_each_entry(ep, &gadget->ep_list, ep_list) { 55726+ if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) 55727+ goto found_ep; 55728+ } 55729 } 55730 55731 /* Fail */ 55732diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c 55733index 950c9435b..a92694ff6 100644 55734--- a/drivers/usb/gadget/function/f_mass_storage.c 55735+++ b/drivers/usb/gadget/function/f_mass_storage.c 55736@@ -307,6 +307,7 @@ struct fsg_common { 55737 unsigned int bad_lun_okay:1; 55738 unsigned int running:1; 55739 unsigned int sysfs:1; 55740+ unsigned int actived:1; 55741 55742 struct completion thread_notifier; 55743 struct task_struct *thread_task; 55744@@ -1338,7 +1339,7 @@ static int do_start_stop(struct fsg_common *common) 55745 55746 up_read(&common->filesem); 55747 down_write(&common->filesem); 55748- fsg_lun_close(curlun); 55749+ common->actived = 0; 55750 up_write(&common->filesem); 55751 down_read(&common->filesem); 55752 55753@@ -1775,7 +1776,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, 55754 55755 /* If the medium isn't mounted and the command needs to access 55756 * it, return an error. */ 55757- if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { 55758+ if (curlun && !common->actived && needs_medium) { 55759 curlun->sense_data = SS_MEDIUM_NOT_PRESENT; 55760 return -EINVAL; 55761 } 55762@@ -2234,6 +2235,7 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) 55763 } 55764 55765 common->running = 0; 55766+ common->actived = 0; 55767 if (!new_fsg || rc) 55768 return rc; 55769 55770@@ -2277,7 +2279,7 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) 55771 bh->inreq->complete = bulk_in_complete; 55772 bh->outreq->complete = bulk_out_complete; 55773 } 55774- 55775+ common->actived = 1; 55776 common->running = 1; 55777 for (i = 0; i < ARRAY_SIZE(common->luns); ++i) 55778 if (common->luns[i]) 55779diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c 55780index e65f474ad..5bb7ce3eb 100644 55781--- a/drivers/usb/gadget/function/f_uac1.c 55782+++ b/drivers/usb/gadget/function/f_uac1.c 55783@@ -56,6 +56,16 @@ static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio) 55784 /* Number of streaming interfaces */ 55785 #define F_AUDIO_NUM_INTERFACES 2 55786 55787+static struct usb_interface_assoc_descriptor uac_iad = { 55788+ .bLength = sizeof(uac_iad), 55789+ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, 55790+ .bFirstInterface = 0, 55791+ .bInterfaceCount = 3, 55792+ .bFunctionClass = USB_CLASS_AUDIO, 55793+ .bFunctionSubClass = 0, 55794+ .bFunctionProtocol = UAC_VERSION_1, 55795+}; 55796+ 55797 /* B.3.1 Standard AC Interface Descriptor */ 55798 static struct usb_interface_descriptor ac_interface_desc = { 55799 .bLength = USB_DT_INTERFACE_SIZE, 55800@@ -254,7 +264,46 @@ static struct uac_iso_endpoint_descriptor as_iso_in_desc = { 55801 .wLockDelay = 0, 55802 }; 55803 55804+static struct usb_ss_ep_comp_descriptor as_ss_ep_comp = { 55805+ .bLength = sizeof(as_ss_ep_comp), 55806+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 55807+ .bMaxBurst = 0, 55808+ .bmAttributes = 0, 55809+ .wBytesPerInterval = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), 55810+}; 55811+ 55812 static struct usb_descriptor_header *f_audio_desc[] = { 55813+ (struct usb_descriptor_header *)&uac_iad, 55814+ (struct usb_descriptor_header *)&ac_interface_desc, 55815+ (struct usb_descriptor_header *)&ac_header_desc, 55816+ 55817+ (struct usb_descriptor_header *)&usb_out_it_desc, 55818+ (struct usb_descriptor_header *)&io_out_ot_desc, 55819+ (struct usb_descriptor_header *)&io_in_it_desc, 55820+ (struct usb_descriptor_header *)&usb_in_ot_desc, 55821+ 55822+ (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, 55823+ (struct usb_descriptor_header *)&as_out_interface_alt_1_desc, 55824+ (struct usb_descriptor_header *)&as_out_header_desc, 55825+ 55826+ (struct usb_descriptor_header *)&as_out_type_i_desc, 55827+ 55828+ (struct usb_descriptor_header *)&as_out_ep_desc, 55829+ (struct usb_descriptor_header *)&as_iso_out_desc, 55830+ 55831+ (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, 55832+ (struct usb_descriptor_header *)&as_in_interface_alt_1_desc, 55833+ (struct usb_descriptor_header *)&as_in_header_desc, 55834+ 55835+ (struct usb_descriptor_header *)&as_in_type_i_desc, 55836+ 55837+ (struct usb_descriptor_header *)&as_in_ep_desc, 55838+ (struct usb_descriptor_header *)&as_iso_in_desc, 55839+ NULL, 55840+}; 55841+ 55842+static struct usb_descriptor_header *f_audio_ss_desc[] = { 55843+ (struct usb_descriptor_header *)&uac_iad, 55844 (struct usb_descriptor_header *)&ac_interface_desc, 55845 (struct usb_descriptor_header *)&ac_header_desc, 55846 55847@@ -270,6 +319,7 @@ static struct usb_descriptor_header *f_audio_desc[] = { 55848 (struct usb_descriptor_header *)&as_out_type_i_desc, 55849 55850 (struct usb_descriptor_header *)&as_out_ep_desc, 55851+ (struct usb_descriptor_header *)&as_ss_ep_comp, 55852 (struct usb_descriptor_header *)&as_iso_out_desc, 55853 55854 (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, 55855@@ -279,6 +329,7 @@ static struct usb_descriptor_header *f_audio_desc[] = { 55856 (struct usb_descriptor_header *)&as_in_type_i_desc, 55857 55858 (struct usb_descriptor_header *)&as_in_ep_desc, 55859+ (struct usb_descriptor_header *)&as_ss_ep_comp, 55860 (struct usb_descriptor_header *)&as_iso_in_desc, 55861 NULL, 55862 }; 55863@@ -567,6 +618,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) 55864 us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); 55865 if (IS_ERR(us)) 55866 return PTR_ERR(us); 55867+ uac_iad.iFunction = us[STR_AC_IF].id; 55868 ac_interface_desc.iInterface = us[STR_AC_IF].id; 55869 usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id; 55870 usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id; 55871@@ -603,6 +655,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) 55872 status = usb_interface_id(c, f); 55873 if (status < 0) 55874 goto fail; 55875+ uac_iad.bFirstInterface = status; 55876 ac_interface_desc.bInterfaceNumber = status; 55877 uac1->ac_intf = status; 55878 uac1->ac_alt = 0; 55879@@ -643,8 +696,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) 55880 audio->in_ep->desc = &as_in_ep_desc; 55881 55882 /* copy descriptors, and track endpoint copies */ 55883- status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, 55884- NULL); 55885+ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, 55886+ f_audio_ss_desc, NULL); 55887 if (status) 55888 goto fail; 55889 55890diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c 55891index f48a00e49..b6b9a69c2 100644 55892--- a/drivers/usb/gadget/function/f_uvc.c 55893+++ b/drivers/usb/gadget/function/f_uvc.c 55894@@ -642,7 +642,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) 55895 55896 uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size); 55897 uvc_ss_streaming_ep.bInterval = opts->streaming_interval; 55898- uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1; 55899+ uvc_ss_streaming_comp.bmAttributes = 1; 55900 uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; 55901 uvc_ss_streaming_comp.wBytesPerInterval = 55902 cpu_to_le16(max_packet_size * max_packet_mult * 55903@@ -789,6 +789,11 @@ static struct usb_function_instance *uvc_alloc_inst(void) 55904 struct uvc_descriptor_header **ctl_cls; 55905 int ret; 55906 55907+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; 55908+ /* GUID of the UVC H.264 extension unit */ 55909+ static char extension_guid[] = {0x41, 0x76, 0x9E, 0xA2, 0x04, 0xDE, 0xE3, 0x47, 55910+ 0x8B, 0x2B, 0xF4, 0x34, 0x1A, 0xFF, 0x00, 0x3B}; 55911+ 55912 opts = kzalloc(sizeof(*opts), GFP_KERNEL); 55913 if (!opts) 55914 return ERR_PTR(-ENOMEM); 55915@@ -824,6 +829,20 @@ static struct usb_function_instance *uvc_alloc_inst(void) 55916 pd->iProcessing = 0; 55917 pd->bmVideoStandards = 0; 55918 55919+ ed = &opts->uvc_extension; 55920+ ed->bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 2); 55921+ ed->bDescriptorType = USB_DT_CS_INTERFACE; 55922+ ed->bDescriptorSubType = UVC_VC_EXTENSION_UNIT; 55923+ ed->bUnitID = 10; 55924+ memcpy(ed->guidExtensionCode, extension_guid, sizeof(extension_guid)); 55925+ ed->bNrInPins = 1; 55926+ ed->baSourceID[0] = 2; 55927+ ed->bNumControls = 15; 55928+ ed->bControlSize = 2; 55929+ ed->bmControls[0] = 1; 55930+ ed->bmControls[1] = 0; 55931+ ed->iExtension = 0; 55932+ 55933 od = &opts->uvc_output_terminal; 55934 od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE; 55935 od->bDescriptorType = USB_DT_CS_INTERFACE; 55936@@ -847,8 +866,9 @@ static struct usb_function_instance *uvc_alloc_inst(void) 55937 ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ 55938 ctl_cls[1] = (struct uvc_descriptor_header *)cd; 55939 ctl_cls[2] = (struct uvc_descriptor_header *)pd; 55940- ctl_cls[3] = (struct uvc_descriptor_header *)od; 55941- ctl_cls[4] = NULL; /* NULL-terminate */ 55942+ ctl_cls[3] = (struct uvc_descriptor_header *)ed; 55943+ ctl_cls[4] = (struct uvc_descriptor_header *)od; 55944+ ctl_cls[5] = NULL; /* NULL-terminate */ 55945 opts->fs_control = 55946 (const struct uvc_descriptor_header * const *)ctl_cls; 55947 55948@@ -863,7 +883,8 @@ static struct usb_function_instance *uvc_alloc_inst(void) 55949 (const struct uvc_descriptor_header * const *)ctl_cls; 55950 55951 opts->streaming_interval = 1; 55952- opts->streaming_maxpacket = 1024; 55953+ opts->streaming_maxpacket = 3072; 55954+ opts->streaming_maxburst = 15; 55955 55956 ret = uvcg_attach_configfs(opts); 55957 if (ret < 0) { 55958diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h 55959index 9a01a7d4f..392ae14dc 100644 55960--- a/drivers/usb/gadget/function/u_uvc.h 55961+++ b/drivers/usb/gadget/function/u_uvc.h 55962@@ -52,6 +52,7 @@ struct f_uvc_opts { 55963 struct uvc_processing_unit_descriptor uvc_processing; 55964 struct uvc_output_terminal_descriptor uvc_output_terminal; 55965 struct uvc_color_matching_descriptor uvc_color_matching; 55966+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_extension; 55967 55968 /* 55969 * Control descriptors pointers arrays for full-/high-speed and 55970@@ -60,8 +61,8 @@ struct f_uvc_opts { 55971 * descriptors. Used by configfs only, must not be touched by legacy 55972 * gadgets. 55973 */ 55974- struct uvc_descriptor_header *uvc_fs_control_cls[5]; 55975- struct uvc_descriptor_header *uvc_ss_control_cls[5]; 55976+ struct uvc_descriptor_header *uvc_fs_control_cls[6]; 55977+ struct uvc_descriptor_header *uvc_ss_control_cls[6]; 55978 55979 /* 55980 * Streaming descriptors for full-speed, high-speed and super-speed. 55981diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h 55982index 23ee25383..f2936f637 100644 55983--- a/drivers/usb/gadget/function/uvc.h 55984+++ b/drivers/usb/gadget/function/uvc.h 55985@@ -64,8 +64,11 @@ extern unsigned int uvc_gadget_trace_param; 55986 /* ------------------------------------------------------------------------ 55987 * Driver specific constants 55988 */ 55989- 55990-#define UVC_NUM_REQUESTS 4 55991+#ifdef UVC_SG_REQ 55992+#define UVC_NUM_REQUESTS 1 55993+#else 55994+#define UVC_NUM_REQUESTS 32 55995+#endif 55996 #define UVC_MAX_REQUEST_SIZE 64 55997 #define UVC_MAX_EVENTS 4 55998 55999@@ -87,6 +90,9 @@ struct uvc_video { 56000 unsigned int imagesize; 56001 struct mutex mutex; /* protects frame parameters */ 56002 56003+ unsigned int num_sgs; /* record base */ 56004+ __u8 *sg_buf; 56005+ 56006 /* Requests */ 56007 unsigned int req_size; 56008 struct usb_request *req[UVC_NUM_REQUESTS]; 56009diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c 56010old mode 100644 56011new mode 100755 56012index 00fb58e50..604e87788 56013--- a/drivers/usb/gadget/function/uvc_configfs.c 56014+++ b/drivers/usb/gadget/function/uvc_configfs.c 56015@@ -319,7 +319,49 @@ static ssize_t uvcg_default_processing_bm_controls_show( 56016 return result; 56017 } 56018 56019-UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls); 56020+static ssize_t uvcg_default_processing_bm_controls_store( 56021+ struct config_item *item, const char *page, size_t len) 56022+{ 56023+ struct config_group *group = to_config_group(item); 56024+ struct f_uvc_opts *opts; 56025+ struct config_item *opts_item; 56026+ struct mutex *su_mutex = &group->cg_subsys->su_mutex; 56027+ struct uvc_processing_unit_descriptor *pd; 56028+ int ret, i; 56029+ const char *pg = page; 56030+ /* sign, base 2 representation, newline, terminator */ 56031+ char buf[1 + sizeof(u8) * 8 + 1 + 1]; 56032+ int idx; 56033+ 56034+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 56035+ 56036+ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 56037+ opts = to_f_uvc_opts(opts_item); 56038+ pd = &opts->uvc_processing; 56039+ 56040+ idx = 0; 56041+ while (pg - page < len) { 56042+ i = 0; 56043+ while (i < sizeof(buf) && (pg - page < len) && 56044+ *pg != '\0' && *pg != '\n') 56045+ buf[i++] = *pg++; 56046+ while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) 56047+ ++pg; 56048+ buf[i] = '\0'; 56049+ ret = kstrtou8(buf, 0, &pd->bmControls[idx++]); 56050+ if (ret < 0) 56051+ goto end; 56052+ if (idx >= pd->bControlSize) 56053+ break; 56054+ } 56055+ ret = len; 56056+end: 56057+ mutex_unlock(&opts->lock); 56058+ mutex_unlock(su_mutex); 56059+ return ret; 56060+} 56061+ 56062+UVC_ATTR(uvcg_default_processing_, bm_controls, bmControls); 56063 56064 static struct configfs_attribute *uvcg_default_processing_attrs[] = { 56065 &uvcg_default_processing_attr_b_unit_id, 56066@@ -342,11 +384,10 @@ static const struct uvcg_config_group_type uvcg_default_processing_type = { 56067 /* ----------------------------------------------------------------------------- 56068 * control/processing 56069 */ 56070- 56071 static const struct uvcg_config_group_type uvcg_processing_grp_type = { 56072 .type = { 56073- .ct_item_ops = &uvcg_config_item_ops, 56074- .ct_owner = THIS_MODULE, 56075+ .ct_item_ops = &uvcg_config_item_ops, 56076+ .ct_owner = THIS_MODULE, 56077 }, 56078 .name = "processing", 56079 .children = (const struct uvcg_config_group_type*[]) { 56080@@ -355,6 +396,115 @@ static const struct uvcg_config_group_type uvcg_processing_grp_type = { 56081 }, 56082 }; 56083 56084+/* control/extension/default */ 56085+static struct uvcg_default_extension { 56086+ struct config_group group; 56087+} uvcg_default_extension; 56088+ 56089+static inline struct uvcg_default_extension 56090+*to_uvcg_default_extension(struct config_item *item) 56091+{ 56092+ return container_of(to_config_group(item), 56093+ struct uvcg_default_extension, group); 56094+} 56095+ 56096+#define UVCG_DEFAULT_EXTENSION_ATTR(cname, aname, conv) \ 56097+static ssize_t uvcg_default_extension_##cname##_show( \ 56098+ struct config_item *item, char *page) \ 56099+{ \ 56100+ struct uvcg_default_extension *dp = to_uvcg_default_extension(item); \ 56101+ struct f_uvc_opts *opts; \ 56102+ struct config_item *opts_item; \ 56103+ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; \ 56104+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; \ 56105+ int result; \ 56106+ \ 56107+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 56108+ \ 56109+ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; \ 56110+ opts = to_f_uvc_opts(opts_item); \ 56111+ ed = &opts->uvc_extension; \ 56112+ \ 56113+ mutex_lock(&opts->lock); \ 56114+ result = sprintf(page, "%d\n", conv(ed->aname)); \ 56115+ mutex_unlock(&opts->lock); \ 56116+ \ 56117+ mutex_unlock(su_mutex); \ 56118+ return result; \ 56119+} \ 56120+ \ 56121+UVC_ATTR_RO(uvcg_default_extension_, cname, aname) 56122+ 56123+#define identity_conv(x) (x) 56124+ 56125+UVCG_DEFAULT_EXTENSION_ATTR(b_unit_id, bUnitID, identity_conv); 56126+UVCG_DEFAULT_EXTENSION_ATTR(b_num_input_pins, bNrInPins, identity_conv); 56127+UVCG_DEFAULT_EXTENSION_ATTR(i_extension, iExtension, identity_conv); 56128+ 56129+#undef identity_conv 56130+ 56131+#undef UVCG_DEFAULT_EXTENSION_ATTR 56132+ 56133+static ssize_t uvcg_default_extension_bm_controls_show( 56134+ struct config_item *item, char *page) 56135+{ 56136+ struct uvcg_default_extension *dp = to_uvcg_default_extension(item); 56137+ struct f_uvc_opts *opts; 56138+ struct config_item *opts_item; 56139+ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; 56140+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; 56141+ int result, i; 56142+ char *pg = page; 56143+ 56144+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 56145+ 56146+ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; 56147+ opts = to_f_uvc_opts(opts_item); 56148+ ed = &opts->uvc_extension; 56149+ 56150+ mutex_lock(&opts->lock); 56151+ for (result = 0, i = 0; i < ed->bControlSize; ++i) { 56152+ result += sprintf(pg, "%d\n", ed->bmControls[i]); 56153+ pg = page + result; 56154+ } 56155+ mutex_unlock(&opts->lock); 56156+ 56157+ mutex_unlock(su_mutex); 56158+ 56159+ return result; 56160+} 56161+ 56162+UVC_ATTR_RO(uvcg_default_extension_, bm_controls, bmControls); 56163+ 56164+static struct configfs_attribute *uvcg_default_extension_attrs[] = { 56165+ &uvcg_default_extension_attr_b_unit_id, 56166+ &uvcg_default_extension_attr_b_num_input_pins, 56167+ &uvcg_default_extension_attr_bm_controls, 56168+ &uvcg_default_extension_attr_i_extension, 56169+ NULL, 56170+}; 56171+ 56172+static struct config_item_type uvcg_default_extension_type = { 56173+ .ct_attrs = uvcg_default_extension_attrs, 56174+ .ct_owner = THIS_MODULE, 56175+}; 56176+ 56177+/* struct uvcg_extension {}; */ 56178+ 56179+/* control/extension */ 56180+static struct uvcg_extension_grp { 56181+ struct config_group group; 56182+} uvcg_extension_grp; 56183+ 56184+static struct config_item_type uvcg_extension_grp_type = { 56185+ .ct_owner = THIS_MODULE, 56186+ }; 56187+ 56188+/* streaming/frame_based */ 56189+static struct uvcg_frame_based_format_grp { 56190+ struct config_group group; 56191+} uvcg_frame_based_format_grp; 56192+ 56193 /* ----------------------------------------------------------------------------- 56194 * control/terminal/camera/default 56195 */ 56196@@ -430,7 +580,50 @@ static ssize_t uvcg_default_camera_bm_controls_show( 56197 return result; 56198 } 56199 56200-UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls); 56201+static ssize_t uvcg_default_camera_bm_controls_store( 56202+ struct config_item *item, const char *page, size_t len) 56203+{ 56204+ struct config_group *group = to_config_group(item); 56205+ struct f_uvc_opts *opts; 56206+ struct config_item *opts_item; 56207+ struct mutex *su_mutex = &group->cg_subsys->su_mutex; 56208+ struct uvc_camera_terminal_descriptor *cd; 56209+ int ret, i; 56210+ const char *pg = page; 56211+ /* sign, base 2 representation, newline, terminator */ 56212+ char buf[1 + sizeof(u8) * 8 + 1 + 1]; 56213+ int idx; 56214+ 56215+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 56216+ 56217+ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> 56218+ ci_parent; 56219+ opts = to_f_uvc_opts(opts_item); 56220+ cd = &opts->uvc_camera_terminal; 56221+ 56222+ idx = 0; 56223+ while (pg - page < len) { 56224+ i = 0; 56225+ while (i < sizeof(buf) && (pg - page < len) && 56226+ *pg != '\0' && *pg != '\n') 56227+ buf[i++] = *pg++; 56228+ while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) 56229+ ++pg; 56230+ buf[i] = '\0'; 56231+ ret = kstrtou8(buf, 0, &cd->bmControls[idx++]); 56232+ if (ret < 0) 56233+ goto end; 56234+ if (idx >= cd->bControlSize) 56235+ break; 56236+ } 56237+ ret = len; 56238+end: 56239+ mutex_unlock(&opts->lock); 56240+ mutex_unlock(su_mutex); 56241+ return ret; 56242+} 56243+ 56244+UVC_ATTR(uvcg_default_camera_, bm_controls, bmControls); 56245 56246 static struct configfs_attribute *uvcg_default_camera_attrs[] = { 56247 &uvcg_default_camera_attr_b_terminal_id, 56248@@ -772,6 +965,7 @@ static const char * const uvcg_format_names[] = { 56249 enum uvcg_format_type { 56250 UVCG_UNCOMPRESSED = 0, 56251 UVCG_MJPEG, 56252+ UVCG_FRAME_FRAME_BASED, 56253 }; 56254 56255 struct uvcg_format { 56256@@ -1381,6 +1575,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group, 56257 return ERR_PTR(-EINVAL); 56258 } 56259 ++fmt->num_frames; 56260+ h->frame.b_frame_index = fmt->num_frames; 56261 mutex_unlock(&opts->lock); 56262 56263 config_item_init_type_name(&h->item, name, &uvcg_frame_type); 56264@@ -1405,6 +1600,263 @@ static void uvcg_frame_drop(struct config_group *group, struct config_item *item 56265 config_item_put(item); 56266 } 56267 56268+struct uvcg_frame_based_frame { 56269+ struct { 56270+ u8 b_length; 56271+ u8 b_descriptor_type; 56272+ u8 b_descriptor_subtype; 56273+ u8 b_frame_index; 56274+ u8 bm_capabilities; 56275+ u16 w_width; 56276+ u16 w_height; 56277+ u32 dw_min_bit_rate; 56278+ u32 dw_max_bit_rate; 56279+ u32 dw_default_frame_interval; 56280+ u8 b_frame_interval_type; 56281+ u32 dw_bytes_per_line; 56282+ } __attribute__((packed)) frame; 56283+ u32 *dw_frame_interval; 56284+ enum uvcg_format_type fmt_type; 56285+ struct config_item item; 56286+}; 56287+ 56288+static struct uvcg_frame_based_frame *to_uvcg_frame_based_frame(struct config_item *item) 56289+{ 56290+ return container_of(item, struct uvcg_frame_based_frame, item); 56291+} 56292+ 56293+#define UVCG_FRAME_BASED_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \ 56294+static ssize_t uvcg_frame_based_frame_##cname##_show(struct config_item *item, char *page)\ 56295+{ \ 56296+ struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item); \ 56297+ struct f_uvc_opts *opts; \ 56298+ struct config_item *opts_item; \ 56299+ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 56300+ int result; \ 56301+ \ 56302+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 56303+ \ 56304+ opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 56305+ opts = to_f_uvc_opts(opts_item); \ 56306+ \ 56307+ mutex_lock(&opts->lock); \ 56308+ result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \ 56309+ mutex_unlock(&opts->lock); \ 56310+ \ 56311+ mutex_unlock(su_mutex); \ 56312+ return result; \ 56313+} \ 56314+ \ 56315+static ssize_t uvcg_frame_based_frame_##cname##_store(struct config_item *item, \ 56316+ const char *page, size_t len)\ 56317+{ \ 56318+ struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item); \ 56319+ struct f_uvc_opts *opts; \ 56320+ struct config_item *opts_item; \ 56321+ struct uvcg_format *fmt; \ 56322+ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 56323+ int ret; \ 56324+ u##bits num; \ 56325+ \ 56326+ ret = kstrtou##bits(page, 0, &num); \ 56327+ if (ret) \ 56328+ return ret; \ 56329+ \ 56330+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 56331+ \ 56332+ opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 56333+ opts = to_f_uvc_opts(opts_item); \ 56334+ fmt = to_uvcg_format(f->item.ci_parent); \ 56335+ \ 56336+ mutex_lock(&opts->lock); \ 56337+ if (fmt->linked || opts->refcnt) { \ 56338+ ret = -EBUSY; \ 56339+ goto end; \ 56340+ } \ 56341+ \ 56342+ f->frame.cname = to_little_endian(num); \ 56343+ ret = len; \ 56344+end: \ 56345+ mutex_unlock(&opts->lock); \ 56346+ mutex_unlock(su_mutex); \ 56347+ return ret; \ 56348+} \ 56349+ \ 56350+UVC_ATTR(uvcg_frame_based_frame_, cname, aname); 56351+ 56352+#define noop_conversion(x) (x) 56353+ 56354+UVCG_FRAME_BASED_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion, 56355+ noop_conversion, 8); 56356+UVCG_FRAME_BASED_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16); 56357+UVCG_FRAME_BASED_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16); 56358+UVCG_FRAME_BASED_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32); 56359+UVCG_FRAME_BASED_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32); 56360+UVCG_FRAME_BASED_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 56361+ le32_to_cpu, cpu_to_le32, 32); 56362+UVCG_FRAME_BASED_FRAME_ATTR(dw_bytes_per_line, dwBytesPerLine, 56363+ le32_to_cpu, cpu_to_le32, 32); 56364+ 56365+#undef noop_conversion 56366+ 56367+#undef UVCG_FRAME_BASED_FRAME_ATTR 56368+ 56369+static ssize_t uvcg_frame_based_frame_dw_frame_interval_show(struct config_item *item, 56370+ char *page) 56371+{ 56372+ struct uvcg_frame_based_frame *frm = to_uvcg_frame_based_frame(item); 56373+ struct f_uvc_opts *opts; 56374+ struct config_item *opts_item; 56375+ struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; 56376+ int result, i; 56377+ char *pg = page; 56378+ 56379+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 56380+ 56381+ opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; 56382+ opts = to_f_uvc_opts(opts_item); 56383+ 56384+ mutex_lock(&opts->lock); 56385+ for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { 56386+ result += sprintf(pg, "%d\n", 56387+ le32_to_cpu(frm->dw_frame_interval[i])); 56388+ pg = page + result; 56389+ } 56390+ mutex_unlock(&opts->lock); 56391+ 56392+ mutex_unlock(su_mutex); 56393+ return result; 56394+} 56395+ 56396+static ssize_t uvcg_frame_based_frame_dw_frame_interval_store(struct config_item *item, 56397+ const char *page, size_t len) 56398+{ 56399+ struct uvcg_frame_based_frame *ch = to_uvcg_frame_based_frame(item); 56400+ struct f_uvc_opts *opts; 56401+ struct config_item *opts_item; 56402+ struct uvcg_format *fmt; 56403+ struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; 56404+ int ret = 0, n = 0; 56405+ u32 *frm_intrv, *tmp; 56406+ 56407+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 56408+ 56409+ opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; 56410+ opts = to_f_uvc_opts(opts_item); 56411+ fmt = to_uvcg_format(ch->item.ci_parent); 56412+ 56413+ mutex_lock(&opts->lock); 56414+ if (fmt->linked || opts->refcnt) { 56415+ ret = -EBUSY; 56416+ goto end; 56417+ } 56418+ 56419+ ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); 56420+ if (ret) 56421+ goto end; 56422+ 56423+ tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); 56424+ if (!frm_intrv) { 56425+ ret = -ENOMEM; 56426+ goto end; 56427+ } 56428+ 56429+ ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); 56430+ if (ret) { 56431+ kfree(frm_intrv); 56432+ goto end; 56433+ } 56434+ 56435+ kfree(ch->dw_frame_interval); 56436+ ch->dw_frame_interval = frm_intrv; 56437+ ch->frame.b_frame_interval_type = n; 56438+ ret = len; 56439+ 56440+end: 56441+ mutex_unlock(&opts->lock); 56442+ mutex_unlock(su_mutex); 56443+ return ret; 56444+} 56445+ 56446+UVC_ATTR(uvcg_frame_based_frame_, dw_frame_interval, dwFrameInterval); 56447+ 56448+static struct configfs_attribute *uvcg_frame_based_frame_attrs[] = { 56449+ &uvcg_frame_based_frame_attr_bm_capabilities, 56450+ &uvcg_frame_based_frame_attr_w_width, 56451+ &uvcg_frame_based_frame_attr_w_height, 56452+ &uvcg_frame_based_frame_attr_dw_min_bit_rate, 56453+ &uvcg_frame_based_frame_attr_dw_max_bit_rate, 56454+ &uvcg_frame_based_frame_attr_dw_default_frame_interval, 56455+ &uvcg_frame_based_frame_attr_dw_frame_interval, 56456+ &uvcg_frame_based_frame_attr_dw_bytes_per_line, 56457+ NULL, 56458+}; 56459+ 56460+static struct config_item_type uvcg_frame_based_frame_type = { 56461+ .ct_attrs = uvcg_frame_based_frame_attrs, 56462+ .ct_owner = THIS_MODULE, 56463+}; 56464+ 56465+static struct config_item *uvcg_frame_based_frame_make(struct config_group *group, 56466+ const char *name) 56467+{ 56468+ struct uvcg_frame_based_frame *h; 56469+ struct uvcg_format *fmt; 56470+ struct f_uvc_opts *opts; 56471+ struct config_item *opts_item; 56472+ 56473+ h = kzalloc(sizeof(*h), GFP_KERNEL); 56474+ if (!h) 56475+ return ERR_PTR(-ENOMEM); 56476+ 56477+ h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; 56478+ h->frame.b_frame_index = 1; 56479+ h->frame.w_width = cpu_to_le16(640); 56480+ h->frame.w_height = cpu_to_le16(360); 56481+ h->frame.dw_min_bit_rate = cpu_to_le32(18432000); 56482+ h->frame.dw_max_bit_rate = cpu_to_le32(55296000); 56483+ h->frame.dw_default_frame_interval = cpu_to_le32(333333); 56484+ h->frame.dw_bytes_per_line = cpu_to_le32(0); 56485+ 56486+ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 56487+ opts = to_f_uvc_opts(opts_item); 56488+ 56489+ mutex_lock(&opts->lock); 56490+ fmt = to_uvcg_format(&group->cg_item); 56491+ if (fmt->type == UVCG_FRAME_FRAME_BASED) { 56492+ h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED; 56493+ h->fmt_type = UVCG_FRAME_FRAME_BASED; 56494+ } else { 56495+ mutex_unlock(&opts->lock); 56496+ kfree(h); 56497+ return ERR_PTR(-EINVAL); 56498+ } 56499+ ++fmt->num_frames; 56500+ h->frame.b_frame_index = fmt->num_frames; 56501+ mutex_unlock(&opts->lock); 56502+ 56503+ config_item_init_type_name(&h->item, name, &uvcg_frame_based_frame_type); 56504+ 56505+ return &h->item; 56506+} 56507+ 56508+static void uvcg_frame_based_frame_drop(struct config_group *group, struct config_item *item) 56509+{ 56510+ struct uvcg_frame_based_frame *h = to_uvcg_frame_based_frame(item); 56511+ struct uvcg_format *fmt; 56512+ struct f_uvc_opts *opts; 56513+ struct config_item *opts_item; 56514+ 56515+ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 56516+ opts = to_f_uvc_opts(opts_item); 56517+ 56518+ mutex_lock(&opts->lock); 56519+ fmt = to_uvcg_format(&group->cg_item); 56520+ --fmt->num_frames; 56521+ kfree(h); 56522+ mutex_unlock(&opts->lock); 56523+} 56524+ 56525 static void uvcg_format_set_indices(struct config_group *fmt) 56526 { 56527 struct config_item *ci; 56528@@ -1629,10 +2081,17 @@ static const struct config_item_type uvcg_uncompressed_type = { 56529 static struct config_group *uvcg_uncompressed_make(struct config_group *group, 56530 const char *name) 56531 { 56532+#ifndef CONFIG_HISI_MC 56533 static char guid[] = { 56534 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 56535 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 56536 }; 56537+#else 56538+ static char guid[] = { 56539+ 'N', 'V', '2', '1', 0x00, 0x00, 0x10, 0x00, 56540+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 56541+ }; 56542+#endif 56543 struct uvcg_uncompressed *h; 56544 56545 h = kzalloc(sizeof(*h), GFP_KERNEL); 56546@@ -1643,7 +2102,11 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group, 56547 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 56548 h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; 56549 memcpy(h->desc.guidFormat, guid, sizeof(guid)); 56550+#ifndef CONFIG_HISI_MC 56551 h->desc.bBitsPerPixel = 16; 56552+#else 56553+ h->desc.bBitsPerPixel = 12; 56554+#endif 56555 h->desc.bDefaultFrameIndex = 1; 56556 h->desc.bAspectRatioX = 0; 56557 h->desc.bAspectRatioY = 0; 56558@@ -1818,6 +2281,205 @@ static const struct config_item_type uvcg_mjpeg_type = { 56559 .ct_owner = THIS_MODULE, 56560 }; 56561 56562+/* streaming/frame_based<NAME> */ 56563+struct uvcg_frame_based_format { 56564+ struct uvcg_format fmt; 56565+ struct uvc_frame_based_format_desc desc; 56566+}; 56567+ 56568+static struct uvcg_frame_based_format *to_uvcg_frame_based_format(struct config_item *item) 56569+{ 56570+ return container_of( 56571+ container_of(to_config_group(item), struct uvcg_format, group), 56572+ struct uvcg_frame_based_format, fmt); 56573+} 56574+ 56575+static struct configfs_group_operations uvcg_frame_based_format_group_ops = { 56576+ .make_item = uvcg_frame_based_frame_make, 56577+ .drop_item = uvcg_frame_based_frame_drop, 56578+}; 56579+ 56580+#define UVCG_FRAME_BASED_FORMAT_ATTR_RO(cname, aname, conv) \ 56581+static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\ 56582+{ \ 56583+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ 56584+ struct f_uvc_opts *opts; \ 56585+ struct config_item *opts_item; \ 56586+ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 56587+ int result; \ 56588+ \ 56589+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 56590+ \ 56591+ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 56592+ opts = to_f_uvc_opts(opts_item); \ 56593+ \ 56594+ mutex_lock(&opts->lock); \ 56595+ result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 56596+ mutex_unlock(&opts->lock); \ 56597+ \ 56598+ mutex_unlock(su_mutex); \ 56599+ return result; \ 56600+} \ 56601+ \ 56602+UVC_ATTR_RO(uvcg_frame_based_format_, cname, aname) 56603+ 56604+#define UVCG_FRAME_BASED_FORMAT_ATTR(cname, aname, conv) \ 56605+static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\ 56606+{ \ 56607+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ 56608+ struct f_uvc_opts *opts; \ 56609+ struct config_item *opts_item; \ 56610+ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 56611+ int result; \ 56612+ \ 56613+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 56614+ \ 56615+ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 56616+ opts = to_f_uvc_opts(opts_item); \ 56617+ \ 56618+ mutex_lock(&opts->lock); \ 56619+ result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 56620+ mutex_unlock(&opts->lock); \ 56621+ \ 56622+ mutex_unlock(su_mutex); \ 56623+ return result; \ 56624+} \ 56625+ \ 56626+static ssize_t \ 56627+uvcg_frame_based_format_##cname##_store(struct config_item *item, \ 56628+ const char *page, size_t len) \ 56629+{ \ 56630+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ 56631+ struct f_uvc_opts *opts; \ 56632+ struct config_item *opts_item; \ 56633+ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 56634+ int ret; \ 56635+ u8 num; \ 56636+ \ 56637+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 56638+ \ 56639+ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 56640+ opts = to_f_uvc_opts(opts_item); \ 56641+ \ 56642+ mutex_lock(&opts->lock); \ 56643+ if (u->fmt.linked || opts->refcnt) { \ 56644+ ret = -EBUSY; \ 56645+ goto end; \ 56646+ } \ 56647+ \ 56648+ ret = kstrtou8(page, 0, &num); \ 56649+ if (ret) \ 56650+ goto end; \ 56651+ \ 56652+ if (num > 255) { \ 56653+ ret = -EINVAL; \ 56654+ goto end; \ 56655+ } \ 56656+ u->desc.aname = num; \ 56657+ ret = len; \ 56658+end: \ 56659+ mutex_unlock(&opts->lock); \ 56660+ mutex_unlock(su_mutex); \ 56661+ return ret; \ 56662+} \ 56663+ \ 56664+UVC_ATTR(uvcg_frame_based_format_, cname, aname) 56665+ 56666+#define identity_conv(x) (x) 56667+ 56668+UVCG_FRAME_BASED_FORMAT_ATTR(b_default_frame_index, bDefaultFrameIndex, 56669+ identity_conv); 56670+UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); 56671+UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); 56672+UVCG_FRAME_BASED_FORMAT_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); 56673+ 56674+#undef identity_conv 56675+ 56676+#undef UVCG_FRAME_BASED_FORMAT_ATTR 56677+#undef UVCG_FRAME_BASED_FORMAT_ATTR_RO 56678+ 56679+static inline ssize_t 56680+uvcg_frame_based_format_bma_controls_show(struct config_item *item, char *page) 56681+{ 56682+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); 56683+ return uvcg_format_bma_controls_show(&u->fmt, page); 56684+} 56685+ 56686+static inline ssize_t 56687+uvcg_frame_based_format_bma_controls_store(struct config_item *item, 56688+ const char *page, size_t len) 56689+{ 56690+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); 56691+ return uvcg_format_bma_controls_store(&u->fmt, page, len); 56692+} 56693+ 56694+UVC_ATTR(uvcg_frame_based_format_, bma_controls, bmaControls); 56695+ 56696+static struct configfs_attribute *uvcg_frame_based_format_attrs[] = { 56697+ &uvcg_frame_based_format_attr_b_default_frame_index, 56698+ &uvcg_frame_based_format_attr_b_aspect_ratio_x, 56699+ &uvcg_frame_based_format_attr_b_aspect_ratio_y, 56700+ &uvcg_frame_based_format_attr_bm_interface_flags, 56701+ &uvcg_frame_based_format_attr_bma_controls, 56702+ NULL, 56703+}; 56704+ 56705+static struct config_item_type uvcg_frame_based_format_type = { 56706+ .ct_group_ops = &uvcg_frame_based_format_group_ops, 56707+ .ct_attrs = uvcg_frame_based_format_attrs, 56708+ .ct_owner = THIS_MODULE, 56709+}; 56710+ 56711+static struct config_group *uvcg_frame_based_format_make(struct config_group *group, 56712+ const char *name) 56713+{ 56714+ static char guid[] = { /*Declear frame frame based as H264*/ 56715+ 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, 56716+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 56717+ }; 56718+ struct uvcg_frame_based_format *h; 56719+ 56720+ h = kzalloc(sizeof(*h), GFP_KERNEL); 56721+ if (!h) 56722+ return ERR_PTR(-ENOMEM); 56723+ 56724+ h->desc.bLength = UVC_DT_FRAME_BASED_FORMAT_SIZE; 56725+ h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 56726+ h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED; 56727+ memcpy(h->desc.guidFormat, guid, sizeof(guid)); 56728+ h->desc.bBitsPerPixel = 16; 56729+ h->desc.bDefaultFrameIndex = 1; 56730+ h->desc.bAspectRatioX = 0; 56731+ h->desc.bAspectRatioY = 0; 56732+ h->desc.bmInterfaceFlags = 0; 56733+ h->desc.bCopyProtect = 0; 56734+ h->desc.bVariableSize = 1; 56735+ 56736+ h->fmt.type = UVCG_FRAME_FRAME_BASED; 56737+ config_group_init_type_name(&h->fmt.group, name, 56738+ &uvcg_frame_based_format_type); 56739+ 56740+ return &h->fmt.group; 56741+} 56742+ 56743+static void uvcg_frame_based_format_drop(struct config_group *group, 56744+ struct config_item *item) 56745+{ 56746+ struct uvcg_frame_based_format *h = to_uvcg_frame_based_format(item); 56747+ 56748+ kfree(h); 56749+} 56750+ 56751+static struct configfs_group_operations uvcg_frame_based_format_grp_ops = { 56752+ .make_group = uvcg_frame_based_format_make, 56753+ .drop_item = uvcg_frame_based_format_drop, 56754+}; 56755+ 56756+static struct config_item_type uvcg_frame_based_format_grp_type = { 56757+ .ct_group_ops = &uvcg_frame_based_format_grp_ops, 56758+ .ct_owner = THIS_MODULE, 56759+}; 56760+ 56761 static struct config_group *uvcg_mjpeg_make(struct config_group *group, 56762 const char *name) 56763 { 56764@@ -2049,6 +2711,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, 56765 container_of(fmt, struct uvcg_mjpeg, fmt); 56766 56767 *size += sizeof(m->desc); 56768+ } else if (fmt->type == UVCG_FRAME_FRAME_BASED) { 56769+ struct uvcg_frame_based_format *h = 56770+ container_of(fmt, struct uvcg_frame_based_format, fmt); 56771+ 56772+ *size += sizeof(h->desc); 56773 } else { 56774 return -EINVAL; 56775 } 56776@@ -2057,7 +2724,14 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, 56777 case UVCG_FRAME: { 56778 struct uvcg_frame *frm = priv1; 56779 int sz = sizeof(frm->dw_frame_interval); 56780+ if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) { 56781+ struct uvcg_frame_based_frame *fb_frm = priv1; 56782+ *size += sizeof(fb_frm->frame); 56783+ *size += fb_frm->frame.b_frame_interval_type * sizeof(fb_frm->dw_frame_interval); 56784 56785+ ++*count; 56786+ return 0; 56787+ } 56788 *size += sizeof(frm->frame); 56789 *size += frm->frame.b_frame_interval_type * sz; 56790 } 56791@@ -2123,6 +2797,15 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, 56792 m->desc.bNumFrameDescriptors = fmt->num_frames; 56793 memcpy(*dest, &m->desc, sizeof(m->desc)); 56794 *dest += sizeof(m->desc); 56795+ } else if (fmt->type == UVCG_FRAME_FRAME_BASED) { 56796+ struct uvc_frame_based_format_desc *ffb = *dest; 56797+ struct uvcg_frame_based_format *h = 56798+ container_of(fmt, struct uvcg_frame_based_format, fmt); 56799+ 56800+ memcpy(*dest, &h->desc, sizeof(h->desc)); 56801+ *dest += sizeof(h->desc); 56802+ ffb->bNumFrameDescriptors = fmt->num_frames; 56803+ ffb->bFormatIndex = n + 1; 56804 } else { 56805 return -EINVAL; 56806 } 56807@@ -2132,6 +2815,19 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, 56808 struct uvcg_frame *frm = priv1; 56809 struct uvc_descriptor_header *h = *dest; 56810 56811+ if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) { 56812+ struct uvcg_frame_based_frame *fb_frm = priv1; 56813+ sz = sizeof(fb_frm->frame); 56814+ memcpy(*dest, &fb_frm->frame, sz); 56815+ *dest += sz; 56816+ sz = fb_frm->frame.b_frame_interval_type * 56817+ sizeof(*fb_frm->dw_frame_interval); 56818+ memcpy(*dest, fb_frm->dw_frame_interval, sz); 56819+ *dest += sz; 56820+ h->bLength = UVC_DT_FRAME_BASED_FRAME_SIZE( 56821+ fb_frm->frame.b_frame_interval_type); 56822+ return 0; 56823+ } 56824 sz = sizeof(frm->frame); 56825 memcpy(*dest, &frm->frame, sz); 56826 *dest += sz; 56827diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c 56828index 4ca89eab6..1272038be 100644 56829--- a/drivers/usb/gadget/function/uvc_v4l2.c 56830+++ b/drivers/usb/gadget/function/uvc_v4l2.c 56831@@ -56,8 +56,13 @@ struct uvc_format { 56832 }; 56833 56834 static struct uvc_format uvc_formats[] = { 56835+#ifndef CONFIG_HISI_MC 56836 { 16, V4L2_PIX_FMT_YUYV }, 56837+#else 56838+ { 12, V4L2_PIX_FMT_NV21 }, 56839+#endif 56840 { 0, V4L2_PIX_FMT_MJPEG }, 56841+ { 0, V4L2_PIX_FMT_H264 }, 56842 }; 56843 56844 static int 56845diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c 56846index 633e23d58..835f5f048 100644 56847--- a/drivers/usb/gadget/function/uvc_video.c 56848+++ b/drivers/usb/gadget/function/uvc_video.c 56849@@ -12,13 +12,15 @@ 56850 #include <linux/usb/ch9.h> 56851 #include <linux/usb/gadget.h> 56852 #include <linux/usb/video.h> 56853- 56854+#include <linux/usb/g_uvc.h> 56855 #include <media/v4l2-dev.h> 56856 56857 #include "uvc.h" 56858 #include "uvc_queue.h" 56859 #include "uvc_video.h" 56860 56861+#include <linux/scatterlist.h> 56862+#include <linux/io.h> 56863 /* -------------------------------------------------------------------------- 56864 * Video codecs 56865 */ 56866@@ -98,9 +100,45 @@ static void 56867 uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, 56868 struct uvc_buffer *buf) 56869 { 56870+ int ret; 56871+#ifdef UVC_SG_REQ 56872+ int len; 56873+ int ttllen = 0; 56874+ unsigned int sg_idx; 56875+ u8 *mem = NULL; 56876+ 56877+ for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++) { 56878+ mem = sg_virt(&req->sg[sg_idx]); 56879+ len = video->req_size; 56880+ 56881+ /* Add the header. */ 56882+ ret = uvc_video_encode_header(video, buf, mem, len); 56883+ mem += ret; 56884+ len -= ret; 56885+ 56886+ /* Process video data. */ 56887+ ret = uvc_video_encode_data(video, buf, mem, len); 56888+ len -= ret; 56889+ 56890+ /* Sync sg buffer len , default is 1024 or 3072 */ 56891+ sg_set_buf(&req->sg[sg_idx], sg_virt(&req->sg[sg_idx]), 56892+ video->req_size - len); 56893+ ttllen += video->req_size - len; 56894+ 56895+ if (buf->bytesused == video->queue.buf_used) { 56896+ video->queue.buf_used = 0; 56897+ buf->state = UVC_BUF_STATE_DONE; 56898+ uvcg_queue_next_buffer(&video->queue, buf); 56899+ video->fid ^= UVC_STREAM_FID; 56900+ break; 56901+ } 56902+ } 56903+ req->num_sgs = sg_idx + 1; 56904+ sg_mark_end(&req->sg[sg_idx]); 56905+ req->length = ttllen; 56906+#else 56907 void *mem = req->buf; 56908 int len = video->req_size; 56909- int ret; 56910 56911 /* Add the header. */ 56912 ret = uvc_video_encode_header(video, buf, mem, len); 56913@@ -119,6 +157,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, 56914 uvcg_queue_next_buffer(&video->queue, buf); 56915 video->fid ^= UVC_STREAM_FID; 56916 } 56917+#endif 56918 } 56919 56920 /* -------------------------------------------------------------------------- 56921@@ -129,6 +168,15 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req) 56922 { 56923 int ret; 56924 56925+ /* 56926+ * Fixme, this is just to workaround the warning by udc core when the ep 56927+ * is disabled, this may happens when the uvc application is still 56928+ * streaming new data while the uvc gadget driver has already recieved 56929+ * the streamoff but the streamoff event is not yet received by the app 56930+ */ 56931+ if (!video->ep->enabled) 56932+ return -EINVAL; 56933+ 56934 ret = usb_ep_queue(video->ep, req, GFP_ATOMIC); 56935 if (ret < 0) { 56936 uvcg_err(&video->uvc->func, "Failed to queue request (%d).\n", 56937@@ -176,9 +224,22 @@ static int 56938 uvc_video_free_requests(struct uvc_video *video) 56939 { 56940 unsigned int i; 56941+#ifdef UVC_SG_REQ 56942+ unsigned int sg_idx; 56943+#endif 56944 56945 for (i = 0; i < UVC_NUM_REQUESTS; ++i) { 56946 if (video->req[i]) { 56947+#ifdef UVC_SG_REQ 56948+ for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++) 56949+ if (sg_page(&video->req[i]->sg[sg_idx])) 56950+ kfree(sg_virt(&video->req[i]->sg[sg_idx])); 56951+ 56952+ if (video->req[i]->sg) { 56953+ kfree(video->req[i]->sg); 56954+ video->req[i]->sg = NULL; 56955+ } 56956+#endif 56957 usb_ep_free_request(video->ep, video->req[i]); 56958 video->req[i] = NULL; 56959 } 56960@@ -200,6 +261,11 @@ uvc_video_alloc_requests(struct uvc_video *video) 56961 unsigned int req_size; 56962 unsigned int i; 56963 int ret = -ENOMEM; 56964+#ifdef UVC_SG_REQ 56965+ struct scatterlist *sg; 56966+ unsigned int num_sgs; 56967+ unsigned int sg_idx; 56968+#endif 56969 56970 BUG_ON(video->req_size); 56971 56972@@ -207,6 +273,35 @@ uvc_video_alloc_requests(struct uvc_video *video) 56973 * max_t(unsigned int, video->ep->maxburst, 1) 56974 * (video->ep->mult); 56975 56976+#ifdef UVC_SG_REQ 56977+ num_sgs = ((video->imagesize / (req_size - 2)) + 1); 56978+ video->num_sgs = num_sgs; 56979+ 56980+ for (i = 0; i < UVC_NUM_REQUESTS; ++i) { 56981+ sg = kmalloc(num_sgs * sizeof(struct scatterlist), GFP_ATOMIC); 56982+ if (sg == NULL) 56983+ goto error; 56984+ sg_init_table(sg, num_sgs); 56985+ 56986+ video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL); 56987+ if (video->req[i] == NULL) 56988+ goto error; 56989+ 56990+ for (sg_idx = 0 ; sg_idx < num_sgs ; sg_idx++) { 56991+ video->sg_buf = kmalloc(req_size, GFP_KERNEL); 56992+ if (video->sg_buf == NULL) 56993+ goto error; 56994+ sg_set_buf(&sg[sg_idx], video->sg_buf, req_size); 56995+ } 56996+ video->req[i]->sg = sg; 56997+ video->req[i]->num_sgs = num_sgs; 56998+ video->req[i]->length = 0; 56999+ video->req[i]->complete = uvc_video_complete; 57000+ video->req[i]->context = video; 57001+ 57002+ list_add_tail(&video->req[i]->list, &video->req_free); 57003+ } 57004+#else 57005 for (i = 0; i < UVC_NUM_REQUESTS; ++i) { 57006 video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL); 57007 if (video->req_buffer[i] == NULL) 57008@@ -223,7 +318,7 @@ uvc_video_alloc_requests(struct uvc_video *video) 57009 57010 list_add_tail(&video->req[i]->list, &video->req_free); 57011 } 57012- 57013+#endif 57014 video->req_size = req_size; 57015 57016 return 0; 57017@@ -276,6 +371,9 @@ static void uvcg_video_pump(struct work_struct *work) 57018 break; 57019 } 57020 57021+#ifdef UVC_SG_REQ 57022+ sg_unmark_end(&req->sg[req->num_sgs - 1]); 57023+#endif 57024 video->encode(req, video, buf); 57025 57026 /* Queue the USB request */ 57027@@ -289,6 +387,9 @@ static void uvcg_video_pump(struct work_struct *work) 57028 } 57029 57030 spin_lock_irqsave(&video->req_lock, flags); 57031+#ifdef UVC_SG_REQ 57032+ sg_unmark_end(&req->sg[req->num_sgs - 1]); 57033+#endif 57034 list_add_tail(&req->list, &video->req_free); 57035 spin_unlock_irqrestore(&video->req_lock, flags); 57036 return; 57037@@ -348,11 +449,17 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) 57038 INIT_WORK(&video->pump, uvcg_video_pump); 57039 57040 video->uvc = uvc; 57041+#ifndef CONFIG_HISI_MC 57042 video->fcc = V4L2_PIX_FMT_YUYV; 57043+ video->imagesize = 320 * 240 * 2; 57044 video->bpp = 16; 57045+#else 57046+ video->fcc = V4L2_PIX_FMT_NV21; 57047+ video->imagesize = 320 * 240 * 3 / 2; /* YUV420: w*h*1.5 */ 57048+ video->bpp = 12; 57049+#endif 57050 video->width = 320; 57051 video->height = 240; 57052- video->imagesize = 320 * 240 * 2; 57053 57054 /* Initialize the video buffers queue. */ 57055 uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT, 57056diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c 57057index 869dce5f1..3807bb163 100644 57058--- a/drivers/vfio/pci/vfio_pci_intrs.c 57059+++ b/drivers/vfio/pci/vfio_pci_intrs.c 57060@@ -642,6 +642,8 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, 57061 int (*func)(struct vfio_pci_device *vdev, unsigned index, 57062 unsigned start, unsigned count, uint32_t flags, 57063 void *data) = NULL; 57064+ int ret; 57065+ u16 cmd; 57066 57067 switch (index) { 57068 case VFIO_PCI_INTX_IRQ_INDEX: 57069@@ -689,5 +691,19 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, 57070 if (!func) 57071 return -ENOTTY; 57072 57073- return func(vdev, index, start, count, flags, data); 57074+ if (index == VFIO_PCI_MSIX_IRQ_INDEX) { 57075+ down_write(&vdev->memory_lock); 57076+ pci_read_config_word(vdev->pdev, PCI_COMMAND, &cmd); 57077+ pci_write_config_word(vdev->pdev, PCI_COMMAND, 57078+ cmd | PCI_COMMAND_MEMORY); 57079+ } 57080+ 57081+ ret = func(vdev, index, start, count, flags, data); 57082+ 57083+ if (index == VFIO_PCI_MSIX_IRQ_INDEX) { 57084+ pci_write_config_word(vdev->pdev, PCI_COMMAND, cmd); 57085+ up_write(&vdev->memory_lock); 57086+ } 57087+ 57088+ return ret; 57089 } 57090diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c 57091index fe888b5dc..5a0791e56 100644 57092--- a/drivers/vfio/vfio_iommu_spapr_tce.c 57093+++ b/drivers/vfio/vfio_iommu_spapr_tce.c 57094@@ -21,9 +21,9 @@ 57095 #include <linux/sched/signal.h> 57096 #include <linux/mm.h> 57097 57098-#include <asm/iommu.h> 57099-#include <asm/tce.h> 57100-#include <asm/mmu_context.h> 57101+#include <linux/iommu.h> 57102+/* #include <linux/tce.h> */ 57103+#include <linux/mmu_context.h> 57104 57105 #define DRIVER_VERSION "0.1" 57106 #define DRIVER_AUTHOR "aik@ozlabs.ru" 57107diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c 57108index fbd438e9b..64431a1a9 100644 57109--- a/drivers/vfio/vfio_iommu_type1.c 57110+++ b/drivers/vfio/vfio_iommu_type1.c 57111@@ -28,6 +28,7 @@ 57112 #include <linux/iommu.h> 57113 #include <linux/module.h> 57114 #include <linux/mm.h> 57115+#include <linux/ptrace.h> 57116 #include <linux/kthread.h> 57117 #include <linux/rbtree.h> 57118 #include <linux/sched/signal.h> 57119@@ -64,6 +65,7 @@ MODULE_PARM_DESC(dma_entry_limit, 57120 57121 struct vfio_iommu { 57122 struct list_head domain_list; 57123+ struct list_head mm_list; 57124 struct list_head iova_list; 57125 struct vfio_domain *external_domain; /* domain for external user */ 57126 struct mutex lock; 57127@@ -103,6 +105,14 @@ struct vfio_group { 57128 struct list_head next; 57129 bool mdev_group; /* An mdev group */ 57130 bool pinned_page_dirty_scope; 57131+ bool sva_enabled; 57132+}; 57133+ 57134+struct vfio_mm { 57135+#define VFIO_PASID_INVALID (-1) 57136+ int pasid; 57137+ struct mm_struct *mm; 57138+ struct list_head next; 57139 }; 57140 57141 struct vfio_iova { 57142diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c 57143index 0791480bf..5a195dd31 100644 57144--- a/fs/9p/vfs_inode.c 57145+++ b/fs/9p/vfs_inode.c 57146@@ -999,6 +999,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat, 57147 u32 request_mask, unsigned int flags) 57148 { 57149 struct dentry *dentry = path->dentry; 57150+ struct inode *inode = d_inode(dentry); 57151 struct v9fs_session_info *v9ses; 57152 struct p9_fid *fid; 57153 struct p9_wstat *st; 57154@@ -1006,7 +1007,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat, 57155 p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); 57156 v9ses = v9fs_dentry2v9ses(dentry); 57157 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 57158- generic_fillattr(d_inode(dentry), stat); 57159+ generic_fillattr(inode, stat); 57160 return 0; 57161 } 57162 fid = v9fs_fid_lookup(dentry); 57163@@ -1017,8 +1018,10 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat, 57164 if (IS_ERR(st)) 57165 return PTR_ERR(st); 57166 57167- v9fs_stat2inode(st, d_inode(dentry), dentry->d_sb, 0); 57168- generic_fillattr(d_inode(dentry), stat); 57169+ spin_lock(&inode->i_lock); 57170+ v9fs_stat2inode(st, inode, dentry->d_sb); 57171+ spin_unlock(&inode->i_lock); 57172+ generic_fillattr(inode, stat); 57173 57174 p9stat_free(st); 57175 kfree(st); 57176diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c 57177index 72b67d810..74629e0a7 100644 57178--- a/fs/9p/vfs_inode_dotl.c 57179+++ b/fs/9p/vfs_inode_dotl.c 57180@@ -459,6 +459,7 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat, 57181 u32 request_mask, unsigned int flags) 57182 { 57183 struct dentry *dentry = path->dentry; 57184+ struct inode *inode = d_inode(dentry); 57185 struct v9fs_session_info *v9ses; 57186 struct p9_fid *fid; 57187 struct p9_stat_dotl *st; 57188@@ -466,7 +467,7 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat, 57189 p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); 57190 v9ses = v9fs_dentry2v9ses(dentry); 57191 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 57192- generic_fillattr(d_inode(dentry), stat); 57193+ generic_fillattr(inode, stat); 57194 return 0; 57195 } 57196 fid = v9fs_fid_lookup(dentry); 57197@@ -481,8 +482,10 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat, 57198 if (IS_ERR(st)) 57199 return PTR_ERR(st); 57200 57201- v9fs_stat2inode_dotl(st, d_inode(dentry), 0); 57202- generic_fillattr(d_inode(dentry), stat); 57203+ spin_lock(&inode->i_lock); 57204+ v9fs_stat2inode_dotl(st, inode); 57205+ spin_unlock(&inode->i_lock); 57206+ generic_fillattr(inode, stat); 57207 /* Change block size to what the server returned */ 57208 stat->blksize = st->st_blksize; 57209 57210diff --git a/fs/aio.c b/fs/aio.c 57211index bd182bcca..425db15b5 100644 57212--- a/fs/aio.c 57213+++ b/fs/aio.c 57214@@ -1764,6 +1764,12 @@ static int aio_poll(struct aio_kiocb *aiocb, const struct iocb *iocb) 57215 INIT_LIST_HEAD(&req->wait.entry); 57216 init_waitqueue_func_entry(&req->wait, aio_poll_wake); 57217 57218+ /* 57219+ * file may be released by aio_poll_wake() if an expected event 57220+ * is triggered immediately after the return of vfs_poll(), so 57221+ * an extra reference is needed here to prevent use-after-free. 57222+ */ 57223+ get_file(req->file); 57224 mask = vfs_poll(req->file, &apt.pt) & req->events; 57225 spin_lock_irq(&ctx->ctx_lock); 57226 if (likely(req->head)) { 57227@@ -1791,6 +1797,8 @@ static int aio_poll(struct aio_kiocb *aiocb, const struct iocb *iocb) 57228 spin_unlock_irq(&ctx->ctx_lock); 57229 if (mask) 57230 iocb_put(aiocb); 57231+ /* release the extra reference for vfs_poll() */ 57232+ fput(req->file); 57233 return apt.error; 57234 } 57235 57236diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c 57237index c99e293b5..9a2861604 100644 57238--- a/fs/btrfs/block-group.c 57239+++ b/fs/btrfs/block-group.c 57240@@ -1824,6 +1824,41 @@ static struct btrfs_block_group *btrfs_create_block_group_cache( 57241 return cache; 57242 } 57243 57244+static int check_exist_chunk(struct btrfs_fs_info *fs_info, u64 start, u64 len, 57245+ u64 flags) 57246+{ 57247+ struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; 57248+ struct extent_map *em; 57249+ int ret; 57250+ 57251+ read_lock(&map_tree->map_tree.lock); 57252+ em = lookup_extent_mapping(&map_tree->map_tree, start, len); 57253+ read_unlock(&map_tree->map_tree.lock); 57254+ 57255+ if (!em) { 57256+ btrfs_err_rl(fs_info, 57257+ "block group start=%llu len=%llu doesn't have corresponding chunk", 57258+ start, len); 57259+ ret = -ENOENT; 57260+ goto out; 57261+ } 57262+ if (em->start != start || em->len != len || 57263+ (em->map_lookup->type & BTRFS_BLOCK_GROUP_TYPE_MASK) != 57264+ (flags & BTRFS_BLOCK_GROUP_TYPE_MASK)) { 57265+ btrfs_err_rl(fs_info, 57266+"block group start=%llu len=%llu flags=0x%llx doesn't match with chunk start=%llu len=%llu flags=0x%llx", 57267+ start, len , flags & BTRFS_BLOCK_GROUP_TYPE_MASK, 57268+ em->start, em->len, em->map_lookup->type & 57269+ BTRFS_BLOCK_GROUP_TYPE_MASK); 57270+ ret = -EUCLEAN; 57271+ goto out; 57272+ } 57273+ ret = 0; 57274+out: 57275+ free_extent_map(em); 57276+ return ret; 57277+} 57278+ 57279 /* 57280 * Iterate all chunks and verify that each of them has the corresponding block 57281 * group 57282@@ -2021,6 +2056,9 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info) 57283 need_clear = 1; 57284 57285 while (1) { 57286+ struct btrfs_block_group_item bg; 57287+ int slot; 57288+ 57289 ret = find_first_block_group(info, path, &key); 57290 if (ret > 0) 57291 break; 57292diff --git a/fs/fat/dir.c b/fs/fat/dir.c 57293index c4a274285..5972b82de 100644 57294--- a/fs/fat/dir.c 57295+++ b/fs/fat/dir.c 57296@@ -565,7 +565,8 @@ static int __fat_readdir(struct inode *inode, struct file *file, 57297 const char *fill_name = NULL; 57298 int fake_offset = 0; 57299 loff_t cpos; 57300- int short_len = 0, fill_len = 0; 57301+ int short_len; 57302+ int fill_len; 57303 int ret = 0; 57304 57305 mutex_lock(&sbi->s_lock); 57306@@ -614,12 +615,13 @@ static int __fat_readdir(struct inode *inode, struct file *file, 57307 bh = NULL; 57308 ret = status; 57309 goto end_of_dir; 57310- } else if (status == PARSE_INVALID) 57311+ } else if (status == PARSE_INVALID) { 57312 goto record_end; 57313- else if (status == PARSE_NOT_LONGNAME) 57314+ } else if (status == PARSE_NOT_LONGNAME) { 57315 goto parse_record; 57316- else if (status == PARSE_EOF) 57317+ } else if (status == PARSE_EOF) { 57318 goto end_of_dir; 57319+ } 57320 57321 if (nr_slots) { 57322 void *longname = unicode + FAT_MAX_UNI_CHARS; 57323@@ -672,8 +674,9 @@ static int __fat_readdir(struct inode *inode, struct file *file, 57324 if (tmp) { 57325 inum = tmp->i_ino; 57326 iput(tmp); 57327- } else 57328+ } else { 57329 inum = iunique(sb, MSDOS_ROOT_INO); 57330+ } 57331 if (!dir_emit(ctx, fill_name, fill_len, inum, 57332 (de->attr & ATTR_DIR) ? DT_DIR : DT_REG)) 57333 goto fill_failed; 57334@@ -783,6 +786,388 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *file, 57335 ret = buf.result; 57336 return ret; 57337 } 57338+#ifdef CONFIG_HISI_MC 57339+/* 57340+ * This is the "fatfilldirall_t" function type, 57341+ * used by fat_ioctl_filldirall to let 57342+ * the kernel specify what kind of dirent layout it wants to have. 57343+ * This allows the kernel to read directories into kernel space or 57344+ * to have different dirent layouts depending on the binary type. 57345+ */ 57346+typedef int (*fatfilldirall_t)(void *__buf, const char *name, 57347+ int name_len, loff_t offset, u64 ino, 57348+ unsigned int d_type, struct msdos_dir_entry *de, 57349+ char *d_createtime); 57350+struct fatdirall_context { 57351+ const fatfilldirall_t actor; 57352+ loff_t pos; 57353+}; 57354+ 57355+struct fat_ioctl_filldirall_callback { 57356+ struct fatdirall_context ctx; 57357+ struct fat_direntall __user *current_dir; 57358+ struct fat_direntall __user *previous; 57359+ int count; 57360+ int usecount; 57361+ int error; 57362+ int result; 57363+ const char *longname; 57364+ int long_len; 57365+ const char *shortname; 57366+ int short_len; 57367+}; 57368+ 57369+static inline bool fat_dir_emit(struct fatdirall_context *ctx, 57370+ const char *name, int namelen, 57371+ u64 ino, unsigned type, 57372+ struct msdos_dir_entry *de, 57373+ char *d_createtime) 57374+{ 57375+ return ctx->actor(ctx, name, namelen, ctx->pos, ino, 57376+ type, de, d_createtime) == 0; 57377+} 57378+static inline bool fat_dir_emit_dot(struct file *file, 57379+ struct fatdirall_context *ctx, 57380+ struct msdos_dir_entry *de, 57381+ char *d_createtime) 57382+{ 57383+ return ctx->actor(ctx, ".", 1, ctx->pos, 57384+ file->f_path.dentry->d_inode->i_ino, 57385+ DT_DIR, de, d_createtime) == 0; 57386+} 57387+static inline bool fat_dir_emit_dotdot(struct file *file, 57388+ struct fatdirall_context *ctx, 57389+ struct msdos_dir_entry *de, 57390+ char *d_createtime) 57391+{ 57392+ return ctx->actor(ctx, "..", 2, ctx->pos, 57393+ parent_ino(file->f_path.dentry), 57394+ DT_DIR, de, d_createtime) == 0; 57395+} 57396+ 57397+static inline bool fat_dir_emit_dots(struct file *file, 57398+ struct fatdirall_context *ctx, 57399+ struct msdos_dir_entry *de, 57400+ char *d_createtime) 57401+{ 57402+ if (ctx->pos == 0) { 57403+ if (!fat_dir_emit_dot(file, ctx, de, d_createtime)) 57404+ return false; 57405+ ctx->pos = 1; 57406+ } 57407+ if (ctx->pos == 1) { 57408+ if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime)) 57409+ return false; 57410+ ctx->pos = 2; 57411+ } 57412+ return true; 57413+} 57414+ 57415+ 57416+static int __fat_readdirall(struct inode *inode, struct file *file, 57417+ struct fatdirall_context *ctx, int short_only, 57418+ struct fat_ioctl_filldirall_callback *both) 57419+{ 57420+ struct super_block *sb = inode->i_sb; 57421+ struct msdos_sb_info *sbi = MSDOS_SB(sb); 57422+ struct buffer_head *bh; 57423+ struct msdos_dir_entry *de; 57424+ unsigned char nr_slots; 57425+ wchar_t *unicode = NULL; 57426+ unsigned char bufname[FAT_MAX_SHORT_SIZE]; 57427+ int isvfat = sbi->options.isvfat; 57428+ const char *fill_name = NULL; 57429+ int fake_offset = 0; 57430+ loff_t cpos; 57431+ int short_len = 0, fill_len = 0; 57432+ int ret = 0; 57433+ char d_createtime[8]; 57434+ 57435+ mutex_lock(&sbi->s_lock); 57436+ 57437+ cpos = ctx->pos; 57438+ /* Fake . and .. for the root directory. */ 57439+ if (inode->i_ino == MSDOS_ROOT_INO) { 57440+ if (!fat_dir_emit_dots(file, ctx, NULL, NULL)) 57441+ goto out; 57442+ if (ctx->pos == 2) { 57443+ fake_offset = 1; 57444+ cpos = 0; 57445+ } 57446+ } 57447+ if (cpos & (sizeof(struct msdos_dir_entry) - 1)) { 57448+ ret = -ENOENT; 57449+ goto out; 57450+ } 57451+ 57452+ bh = NULL; 57453+get_new: 57454+ if (fat_get_entry(inode, &cpos, &bh, &de) == -1) 57455+ goto end_of_dir; 57456+parse_record: 57457+ nr_slots = 0; 57458+ /* 57459+ * Check for long filename entry, but if short_only, we don't 57460+ * need to parse long filename. 57461+ */ 57462+ if (isvfat && !short_only) { 57463+ if (de->name[0] == DELETED_FLAG) 57464+ goto record_end; 57465+ if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME)) 57466+ goto record_end; 57467+ if (de->attr != ATTR_EXT && IS_FREE(de->name)) 57468+ goto record_end; 57469+ } else { 57470+ if ((de->attr & ATTR_VOLUME) || IS_FREE(de->name)) 57471+ goto record_end; 57472+ } 57473+ 57474+ if (isvfat && de->attr == ATTR_EXT) { 57475+ int status = fat_parse_long(inode, &cpos, &bh, &de, 57476+ &unicode, &nr_slots); 57477+ if (status < 0) { 57478+ ctx->pos = cpos; 57479+ ret = status; 57480+ goto out; 57481+ } else if (status == PARSE_INVALID) 57482+ goto record_end; 57483+ else if (status == PARSE_NOT_LONGNAME) 57484+ goto parse_record; 57485+ else if (status == PARSE_EOF) 57486+ goto end_of_dir; 57487+ 57488+ if (nr_slots) { 57489+ void *longname = unicode + FAT_MAX_UNI_CHARS; 57490+ int size = PATH_MAX - FAT_MAX_UNI_SIZE; 57491+ int len = fat_uni_to_x8(sb, unicode, longname, size); 57492+ 57493+ fill_name = longname; 57494+ fill_len = len; 57495+ 57496+ short_len = fat_parse_short(sb, de, bufname, 57497+ sbi->options.dotsOK); 57498+ if (short_len == 0) 57499+ goto record_end; 57500+ 57501+ /* hack for fat_ioctl_filldir() */ 57502+ both->longname = fill_name; 57503+ both->long_len = fill_len; 57504+ both->shortname = bufname; 57505+ both->short_len = short_len; 57506+ fill_name = NULL; 57507+ fill_len = 0; 57508+ goto start_filldir; 57509+ } 57510+ } 57511+ 57512+ short_len = fat_parse_short(sb, de, bufname, sbi->options.dotsOK); 57513+ if (short_len == 0) 57514+ goto record_end; 57515+ 57516+ fill_name = bufname; 57517+ fill_len = short_len; 57518+ 57519+start_filldir: 57520+ if (!fake_offset) 57521+ ctx->pos = cpos - (nr_slots + 1) 57522+ * sizeof(struct msdos_dir_entry); 57523+ 57524+ memset(d_createtime, 0, 8); 57525+ fat_time_fat2str(sbi, d_createtime, de->ctime, 57526+ de->cdate, de->ctime_cs); 57527+ 57528+ if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME)) { 57529+ if (!fat_dir_emit_dot(file, ctx, de, d_createtime)) 57530+ goto fill_failed; 57531+ } else if (!memcmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) { 57532+ if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime)) 57533+ goto fill_failed; 57534+ } else { 57535+ unsigned long inum; 57536+ loff_t i_pos = fat_make_i_pos(sb, bh, de); 57537+ struct inode *tmp = fat_iget(sb, i_pos); 57538+ 57539+ if (tmp) { 57540+ inum = tmp->i_ino; 57541+ iput(tmp); 57542+ } else 57543+ inum = iunique(sb, MSDOS_ROOT_INO); 57544+ if (!fat_dir_emit(ctx, fill_name, fill_len, inum, 57545+ (de->attr & ATTR_DIR) ? DT_DIR : DT_REG, 57546+ de, d_createtime)) 57547+ goto fill_failed; 57548+ } 57549+ 57550+record_end: 57551+ fake_offset = 0; 57552+ ctx->pos = cpos; 57553+ goto get_new; 57554+end_of_dir: 57555+ ctx->pos = cpos; 57556+fill_failed: 57557+ brelse(bh); 57558+ if (unicode) 57559+ __putname(unicode); 57560+out: 57561+ mutex_unlock(&sbi->s_lock); 57562+ return ret; 57563+} 57564+ 57565+static int fat_ioctl_filldirall(void *__buf, const char *name, 57566+ int name_len, loff_t offset, 57567+ u64 ino, unsigned int d_type, 57568+ struct msdos_dir_entry *de, 57569+ char *d_createtime) 57570+{ 57571+ struct fat_direntall __user *dirent; 57572+ struct fat_ioctl_filldirall_callback *buf; 57573+ unsigned long d_ino; 57574+ int reclen = 0; 57575+ const char *longname = NULL; 57576+ int long_len = 0; 57577+ const char *shortname = NULL; 57578+ int short_len = 0; 57579+ 57580+ buf = (struct fat_ioctl_filldirall_callback *) __buf; 57581+ 57582+ if (name != NULL) { 57583+ reclen = ALIGN(offsetof(struct fat_direntall, d_name) 57584+ + name_len + 2, sizeof(long)); 57585+ } else { 57586+ longname = buf->longname; 57587+ long_len = buf->long_len; 57588+ shortname = buf->shortname; 57589+ short_len = buf->short_len; 57590+ reclen = ALIGN(offsetof(struct fat_direntall, d_name) 57591+ + long_len + 2, sizeof(long)); 57592+ } 57593+ 57594+ buf->error = -EINVAL; /* only used if we fail.. */ 57595+ 57596+ if (reclen >= buf->count) 57597+ return -EINVAL; 57598+ 57599+ d_ino = ino; 57600+ 57601+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 57602+ buf->error = -EOVERFLOW; 57603+ return -EOVERFLOW; 57604+ } 57605+ 57606+ dirent = buf->previous; 57607+ 57608+ if (dirent) { 57609+ if (__put_user(offset, &dirent->d_off)) 57610+ goto efault; 57611+ } 57612+ 57613+ dirent = buf->current_dir; 57614+ 57615+ if (__put_user(d_ino, &dirent->d_ino)) 57616+ goto efault; 57617+ 57618+ if (__put_user(reclen, &dirent->d_reclen)) 57619+ goto efault; 57620+ 57621+ if (name != NULL) { 57622+ if (copy_to_user(dirent->d_name, name, name_len)) 57623+ goto efault; 57624+ if (__put_user(0, dirent->d_name + name_len)) 57625+ goto efault; 57626+ } else { 57627+ if (copy_to_user(dirent->d_name, longname, long_len)) 57628+ goto efault; 57629+ if (__put_user(0, dirent->d_name + long_len)) 57630+ goto efault; 57631+ } 57632+ 57633+ if (__put_user(d_type, &dirent->d_type)) 57634+ goto efault; 57635+ 57636+ if (de != NULL) { 57637+ u64 u_size = 0; 57638+ if (copy_to_user(&dirent->d_size, &u_size, sizeof(u64))) 57639+ goto efault; 57640+ if (copy_to_user(&dirent->d_size, &de->size, sizeof(u32))) 57641+ goto efault; 57642+ } 57643+ 57644+ if (d_createtime != NULL) { 57645+ if (copy_to_user(dirent->d_createtime, d_createtime, 8)) 57646+ goto efault; 57647+ } 57648+ buf->previous = dirent; 57649+ dirent = (void __user *)dirent + reclen; 57650+ buf->current_dir = dirent; 57651+ buf->count -= reclen; 57652+ buf->usecount += reclen; 57653+ return 0; 57654+efault: 57655+ buf->error = -EFAULT; 57656+ return -EFAULT; 57657+} 57658+ 57659+ 57660+static int fat_ioctl_readdirall(struct inode *inode, struct file *file, 57661+ void __user *dirent, 57662+ int short_only, int both) 57663+{ 57664+ struct fat_ioctl_filldirall_callback buf = { 57665+ .ctx.actor = fat_ioctl_filldirall, 57666+ }; 57667+ 57668+ struct fat_direntall_buf __user *userbuf = dirent; 57669+ int ret; 57670+ 57671+ buf.current_dir = &(userbuf->direntall); 57672+ buf.previous = NULL; 57673+ buf.error = 0; 57674+ buf.result = 0; 57675+ buf.usecount = 0; 57676+ 57677+ if (get_user(buf.count, &(userbuf->d_count))) 57678+ return -EFAULT; 57679+ 57680+ up_read(&inode->i_rwsem); 57681+ buf.ctx.pos = file->f_pos; 57682+ ret = -ENOENT; 57683+ if (!IS_DEADDIR(inode)) { 57684+ ret = __fat_readdirall(inode, file, &buf.ctx, 57685+ short_only, both ? &buf : NULL); 57686+ file->f_pos = buf.ctx.pos; 57687+ } 57688+ down_read(&inode->i_rwsem); 57689+ 57690+ if (__put_user(buf.usecount, &(userbuf->d_usecount))) 57691+ return -EFAULT; 57692+ if (ret >= 0) 57693+ ret = buf.result; 57694+ return ret; 57695+} 57696+ 57697+static int fat_dir_ioctl_readdirall(struct file *filp, unsigned int cmd, 57698+ unsigned long arg) 57699+{ 57700+ struct inode *inode = filp->f_path.dentry->d_inode; 57701+ struct fat_direntall_buf __user *direntallbuf; 57702+ int short_only, both; 57703+ 57704+ direntallbuf = (struct fat_direntall_buf __user *)arg; 57705+ 57706+ if (!access_ok(VERIFY_WRITE, direntallbuf, 57707+ sizeof(struct fat_direntall_buf))) 57708+ return -EFAULT; 57709+ if (put_user(0, &(direntallbuf->direntall.d_reclen))) 57710+ return -EFAULT; 57711+ if (put_user(0, &(direntallbuf->d_usecount))) 57712+ return -EFAULT; 57713+ short_only = 0; 57714+ both = 1; 57715+ return fat_ioctl_readdirall(inode, filp, direntallbuf, 57716+ short_only, both); 57717+} 57718+#endif 57719+ 57720 57721 static long fat_dir_ioctl(struct file *filp, unsigned int cmd, 57722 unsigned long arg) 57723@@ -790,7 +1175,10 @@ static long fat_dir_ioctl(struct file *filp, unsigned int cmd, 57724 struct inode *inode = file_inode(filp); 57725 struct __fat_dirent __user *d1 = (struct __fat_dirent __user *)arg; 57726 int short_only, both; 57727- 57728+#ifdef CONFIG_HISI_MC 57729+ if (VFAT_IOCTL_READDIR_ALL == cmd) 57730+ return fat_dir_ioctl_readdirall(filp, cmd, arg); 57731+#endif 57732 switch (cmd) { 57733 case VFAT_IOCTL_READDIR_SHORT: 57734 short_only = 1; 57735@@ -1094,11 +1482,15 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, 57736 err = -ENOMEM; 57737 goto error; 57738 } 57739+#ifndef CONFIG_ARCH_HISI_BVT 57740 /* Avoid race with userspace read via bdev */ 57741 lock_buffer(bhs[n]); 57742+#endif 57743 memset(bhs[n]->b_data, 0, sb->s_blocksize); 57744 set_buffer_uptodate(bhs[n]); 57745+#ifndef CONFIG_ARCH_HISI_BVT 57746 unlock_buffer(bhs[n]); 57747+#endif 57748 mark_buffer_dirty_inode(bhs[n], dir); 57749 57750 n++; 57751@@ -1155,8 +1547,10 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts) 57752 fat_time_unix2fat(sbi, ts, &time, &date, &time_cs); 57753 57754 de = (struct msdos_dir_entry *)bhs[0]->b_data; 57755+#ifndef CONFIG_ARCH_HISI_BVT 57756 /* Avoid race with userspace read via bdev */ 57757 lock_buffer(bhs[0]); 57758+#endif 57759 /* filling the new directory slots ("." and ".." entries) */ 57760 memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME); 57761 memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME); 57762@@ -1179,7 +1573,9 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts) 57763 de[0].size = de[1].size = 0; 57764 memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); 57765 set_buffer_uptodate(bhs[0]); 57766+#ifndef CONFIG_ARCH_HISI_BVT 57767 unlock_buffer(bhs[0]); 57768+#endif 57769 mark_buffer_dirty_inode(bhs[0], dir); 57770 57771 err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE); 57772@@ -1237,11 +1633,15 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots, 57773 57774 /* fill the directory entry */ 57775 copy = min(size, sb->s_blocksize); 57776+#ifndef CONFIG_ARCH_HISI_BVT 57777 /* Avoid race with userspace read via bdev */ 57778 lock_buffer(bhs[n]); 57779+#endif 57780 memcpy(bhs[n]->b_data, slots, copy); 57781 set_buffer_uptodate(bhs[n]); 57782+#ifndef CONFIG_ARCH_HISI_BVT 57783 unlock_buffer(bhs[n]); 57784+#endif 57785 mark_buffer_dirty_inode(bhs[n], dir); 57786 slots += copy; 57787 size -= copy; 57788diff --git a/fs/fat/fat.h b/fs/fat/fat.h 57789index 922a0c6ba..a84663246 100644 57790--- a/fs/fat/fat.h 57791+++ b/fs/fat/fat.h 57792@@ -444,6 +444,10 @@ extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts, 57793 __le16 __time, __le16 __date, u8 time_cs); 57794 extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, 57795 __le16 *time, __le16 *date, u8 *time_cs); 57796+#ifdef CONFIG_HISI_MC 57797+extern void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime, 57798+ __le16 __time, __le16 __date, u8 time_cs); 57799+#endif 57800 extern int fat_truncate_time(struct inode *inode, struct timespec64 *now, 57801 int flags); 57802 extern int fat_update_time(struct inode *inode, struct timespec64 *now, 57803diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c 57804index f7e3304b7..4351eaa8b 100644 57805--- a/fs/fat/fatent.c 57806+++ b/fs/fat/fatent.c 57807@@ -379,6 +379,9 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs, 57808 int err, n, copy; 57809 57810 err = 0; 57811+#ifdef CONFIG_HISI_MC 57812+ return 0; 57813+#endif 57814 for (copy = 1; copy < sbi->fats; copy++) { 57815 sector_t backup_fat = sbi->fat_length * copy; 57816 57817@@ -388,11 +391,15 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs, 57818 err = -ENOMEM; 57819 goto error; 57820 } 57821+#ifndef CONFIG_ARCH_HISI_BVT 57822 /* Avoid race with userspace read via bdev */ 57823 lock_buffer(c_bh); 57824+#endif 57825 memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize); 57826 set_buffer_uptodate(c_bh); 57827+#ifndef CONFIG_ARCH_HISI_BVT 57828 unlock_buffer(c_bh); 57829+#endif 57830 mark_buffer_dirty_inode(c_bh, sbi->fat_inode); 57831 if (sb->s_flags & SB_SYNCHRONOUS) 57832 err = sync_dirty_buffer(c_bh); 57833diff --git a/fs/fat/file.c b/fs/fat/file.c 57834index f9ee27cf4..f424520d7 100644 57835--- a/fs/fat/file.c 57836+++ b/fs/fat/file.c 57837@@ -198,6 +198,17 @@ int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) 57838 return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL); 57839 } 57840 57841+#ifdef CONFIG_HISI_MC 57842+int fat_file_flush(struct file *file, fl_owner_t id) 57843+{ 57844+ struct address_space * mapping = file->f_mapping; 57845+ struct inode *inode = mapping->host; 57846+ 57847+ inode->i_sb->s_op->write_inode(inode, NULL); 57848+ 57849+ return 0; 57850+} 57851+#endif 57852 57853 const struct file_operations fat_file_operations = { 57854 .llseek = generic_file_llseek, 57855@@ -211,6 +222,9 @@ const struct file_operations fat_file_operations = { 57856 .splice_read = generic_file_splice_read, 57857 .splice_write = iter_file_splice_write, 57858 .fallocate = fat_fallocate, 57859+#ifdef CONFIG_HISI_MC 57860+ .flush = fat_file_flush, 57861+#endif 57862 }; 57863 57864 static int fat_cont_expand(struct inode *inode, loff_t size) 57865@@ -461,7 +475,13 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) 57866 /* use a default check */ 57867 return 0; 57868 } 57869- 57870+#ifdef CONFIG_HISI_MC 57871+void reset_mmu_private(struct inode *inode, loff_t offset) 57872+{ 57873+ MSDOS_I(inode)->mmu_private = offset; 57874+ inode->i_ctime = inode->i_mtime = ((struct timespec64) { get_seconds(), 0 }); 57875+} 57876+#endif 57877 #define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET) 57878 /* valid file mode bits */ 57879 #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO) 57880@@ -494,6 +514,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) 57881 * hole before it. XXX: this is no longer true with new truncate 57882 * sequence. 57883 */ 57884+#ifndef CONFIG_HISI_MC 57885 if (attr->ia_valid & ATTR_SIZE) { 57886 inode_dio_wait(inode); 57887 57888@@ -504,7 +525,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) 57889 attr->ia_valid &= ~ATTR_SIZE; 57890 } 57891 } 57892- 57893+#endif 57894 if (((attr->ia_valid & ATTR_UID) && 57895 (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) || 57896 ((attr->ia_valid & ATTR_GID) && 57897@@ -534,6 +555,9 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) 57898 goto out; 57899 down_write(&MSDOS_I(inode)->truncate_lock); 57900 truncate_setsize(inode, attr->ia_size); 57901+#ifdef CONFIG_HISI_MC 57902+ reset_mmu_private(inode, attr->ia_size); 57903+#endif 57904 fat_truncate_blocks(inode, attr->ia_size); 57905 up_write(&MSDOS_I(inode)->truncate_lock); 57906 } 57907diff --git a/fs/fat/inode.c b/fs/fat/inode.c 57908index bab9b202b..769444c64 100644 57909--- a/fs/fat/inode.c 57910+++ b/fs/fat/inode.c 57911@@ -628,8 +628,9 @@ static void fat_free_eofblocks(struct inode *inode) 57912 round_up(MSDOS_I(inode)->mmu_private, 57913 MSDOS_SB(inode->i_sb)->cluster_size)) { 57914 int err; 57915- 57916+#ifndef CONFIG_HISI_MC 57917 fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private); 57918+#endif 57919 /* Fallocate results in updating the i_start/iogstart 57920 * for the zero byte file. So, make it return to 57921 * original state during evict and commit it to avoid 57922@@ -899,7 +900,70 @@ static int __fat_write_inode(struct inode *inode, int wait) 57923 brelse(bh); 57924 return err; 57925 } 57926+#ifdef CONFIG_HISI_MC 57927+static int __fat_write_inode_(struct inode *inode, int wait) 57928+{ 57929+ struct super_block *sb = inode->i_sb; 57930+ struct msdos_sb_info *sbi = MSDOS_SB(sb); 57931+ struct buffer_head *bh; 57932+ struct msdos_dir_entry *raw_entry; 57933+ loff_t i_pos; 57934+ sector_t blocknr; 57935+ int err = 0; 57936+ int offset; 57937+ 57938+ if (inode->i_ino == MSDOS_ROOT_INO) 57939+ return 0; 57940+ 57941+retry: 57942+ i_pos = fat_i_pos_read(sbi, inode); 57943+ if (!i_pos) 57944+ return 0; 57945+ 57946+ fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset); 57947+ bh = sb_bread(sb, blocknr); 57948+ if (!bh) { 57949+ fat_msg(sb, KERN_ERR, "unable to read inode block " 57950+ "for updating (i_pos %lld)", i_pos); 57951+ return -EIO; 57952+ } 57953+ spin_lock(&sbi->inode_hash_lock); 57954+ if (i_pos != MSDOS_I(inode)->i_pos) { 57955+ spin_unlock(&sbi->inode_hash_lock); 57956+ brelse(bh); 57957+ goto retry; 57958+ } 57959 57960+ raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset]; 57961+ if (S_ISDIR(inode->i_mode)) { 57962+ raw_entry->size = 0; 57963+ } else { 57964+ if ((raw_entry->start != 0) || (raw_entry->starthi != 0)) { 57965+ spin_unlock(&sbi->inode_hash_lock); 57966+ goto file_out; 57967+ } 57968+ raw_entry->size = cpu_to_le32(inode->i_size); 57969+ } 57970+ raw_entry->attr = fat_make_attrs(inode); 57971+ fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart); 57972+ fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time, 57973+ &raw_entry->date, NULL); 57974+ if (sbi->options.isvfat) { 57975+ __le16 atime; 57976+ fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime, 57977+ &raw_entry->cdate, &raw_entry->ctime_cs); 57978+ fat_time_unix2fat(sbi, &inode->i_atime, &atime, 57979+ &raw_entry->adate, NULL); 57980+ } 57981+ spin_unlock(&sbi->inode_hash_lock); 57982+ mark_buffer_dirty(bh); 57983+ if (wait) 57984+ err = sync_dirty_buffer(bh); 57985+file_out: 57986+ brelse(bh); 57987+ return err; 57988+} 57989+#endif 57990 static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) 57991 { 57992 int err; 57993@@ -910,8 +974,17 @@ static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) 57994 mutex_lock(&MSDOS_SB(sb)->s_lock); 57995 err = fat_clusters_flush(sb); 57996 mutex_unlock(&MSDOS_SB(sb)->s_lock); 57997- } else 57998- err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 57999+ } else { 58000+#ifdef CONFIG_HISI_MC 58001+ if (NULL == wbc) { 58002+ err = __fat_write_inode(inode, 1); 58003+ } else { 58004+ err = __fat_write_inode_(inode, wbc->sync_mode == WB_SYNC_ALL); 58005+ } 58006+#else 58007+ err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 58008+#endif 58009+ } 58010 58011 return err; 58012 } 58013diff --git a/fs/fat/misc.c b/fs/fat/misc.c 58014index f1b2a1fc2..ddb5cf98a 100644 58015--- a/fs/fat/misc.c 58016+++ b/fs/fat/misc.c 58017@@ -198,7 +198,8 @@ static inline int fat_tz_offset(struct msdos_sb_info *sbi) 58018 void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts, 58019 __le16 __time, __le16 __date, u8 time_cs) 58020 { 58021- u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date); 58022+ u16 time = le16_to_cpu(__time); 58023+ u16 date = le16_to_cpu(__date); 58024 time64_t second; 58025 long day, leap_day, month, year; 58026 58027@@ -267,6 +268,35 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, 58028 } 58029 EXPORT_SYMBOL_GPL(fat_time_unix2fat); 58030 58031+#ifdef CONFIG_HISI_MC 58032+void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime, 58033+ __le16 __time, __le16 __date, u8 time_cs) 58034+{ 58035+ u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date); 58036+ time_t day, month, year; 58037+ 58038+ year = date >> 9; 58039+ month = max(1, (date >> 5) & 0xf); 58040+ day = max(1, date & 0x1f) - 1; 58041+ 58042+ d_createtime[0] = year; 58043+ d_createtime[1] = month; 58044+ d_createtime[2] = day; 58045+ d_createtime[3] = (time >> 11); /*hour*/ 58046+ d_createtime[4] = ((time >> 5) & 0x3f); /*min*/ 58047+ d_createtime[5] = (time & 0x1f); /*second 2s*/ 58048+ 58049+ if (!sbi->options.tz_set) 58050+ d_createtime[4] += sys_tz.tz_minuteswest; 58051+ else 58052+ d_createtime[4] -= sbi->options.time_offset; 58053+ 58054+ if (time_cs) 58055+ d_createtime[5] += (time_cs / 100); /*second 1s*/ 58056+} 58057+EXPORT_SYMBOL_GPL(fat_time_fat2str); 58058+#endif 58059+ 58060 static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts) 58061 { 58062 return (struct timespec64){ ts.tv_sec & ~1ULL, 0 }; 58063diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h 58064index 5e91d578f..01116b8ea 100644 58065--- a/fs/jffs2/compr.h 58066+++ b/fs/jffs2/compr.h 58067@@ -29,9 +29,15 @@ 58068 #define JFFS2_DYNRUBIN_PRIORITY 20 58069 #define JFFS2_LZARI_PRIORITY 30 58070 #define JFFS2_RTIME_PRIORITY 50 58071+ 58072+#ifdef CONFIG_HISI_MC 58073+#define JFFS2_LZMA_PRIORITY 70 58074+#define JFFS2_ZLIB_PRIORITY 80 58075+#define JFFS2_LZO_PRIORITY 90 58076+#else 58077 #define JFFS2_ZLIB_PRIORITY 60 58078 #define JFFS2_LZO_PRIORITY 80 58079- 58080+#endif 58081 58082 #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ 58083 #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ 58084diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c 58085index df46f2d3f..b38ea130b 100644 58086--- a/fs/ubifs/file.c 58087+++ b/fs/ubifs/file.c 58088@@ -1493,6 +1493,9 @@ static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags) 58089 */ 58090 if (PageWriteback(page)) 58091 return 0; 58092+#ifdef CONFIG_ARCH_HISI_BVT 58093+ return 0; 58094+#endif 58095 ubifs_assert(c, PagePrivate(page)); 58096 ubifs_assert(c, 0); 58097 detach_page_private(page); 58098diff --git a/include/dt-bindings/clock/hi3516dv300-clock.h b/include/dt-bindings/clock/hi3516dv300-clock.h 58099new file mode 100644 58100index 000000000..408c9b09d 58101--- /dev/null 58102+++ b/include/dt-bindings/clock/hi3516dv300-clock.h 58103@@ -0,0 +1,100 @@ 58104+/* 58105+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. 58106+ * 58107+ * This program is free software; you can redistribute it and/or modify it 58108+ * under the terms of the GNU General Public License as published by the 58109+ * Free Software Foundation; either version 2 of the License, or (at your 58110+ * option) any later version. 58111+ * 58112+ * This program is distributed in the hope that it will be useful, 58113+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 58114+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 58115+ * GNU General Public License for more details. 58116+ * 58117+ * You should have received a copy of the GNU General Public License 58118+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 58119+ * 58120+ */ 58121+ 58122+#ifndef __DTS_HI3516DV300_CLOCK_H 58123+#define __DTS_HI3516DV300_CLOCK_H 58124+ 58125+/* clk in Hi3516CV500 CRG */ 58126+/* fixed rate clocks */ 58127+#define HI3516DV300_FIXED_3M 1 58128+#define HI3516DV300_FIXED_6M 2 58129+#define HI3516DV300_FIXED_12M 3 58130+#define HI3516DV300_FIXED_24M 4 58131+#define HI3516DV300_FIXED_50M 5 58132+#define HI3516DV300_FIXED_83P3M 6 58133+#define HI3516DV300_FIXED_100M 7 58134+#define HI3516DV300_FIXED_125M 8 58135+#define HI3516DV300_FIXED_148P5M 9 58136+#define HI3516DV300_FIXED_150M 10 58137+#define HI3516DV300_FIXED_200M 11 58138+#define HI3516DV300_FIXED_250M 12 58139+#define HI3516DV300_FIXED_300M 13 58140+#define HI3516DV300_FIXED_324M 14 58141+#define HI3516DV300_FIXED_342M 15 58142+#define HI3516DV300_FIXED_375M 16 58143+#define HI3516DV300_FIXED_400M 17 58144+#define HI3516DV300_FIXED_448M 18 58145+#define HI3516DV300_FIXED_500M 19 58146+#define HI3516DV300_FIXED_540M 20 58147+#define HI3516DV300_FIXED_600M 21 58148+#define HI3516DV300_FIXED_750M 22 58149+#define HI3516DV300_FIXED_1000M 23 58150+#define HI3516DV300_FIXED_1500M 24 58151+#define HI3516DV300_FIXED_54M 25 58152+#define HI3516DV300_FIXED_25M 26 58153+#define HI3516DV300_FIXED_163M 27 58154+#define HI3516DV300_FIXED_257M 28 58155+#define HI3516DV300_FIXED_396M 29 58156+ 58157+/* mux clocks */ 58158+#define HI3516DV300_SYSAXI_CLK 30 58159+#define HI3516DV300_SYSAPB_CLK 31 58160+#define HI3516DV300_FMC_MUX 32 58161+#define HI3516DV300_UART_MUX 33 58162+#define HI3516DV300_MMC0_MUX 34 58163+#define HI3516DV300_MMC1_MUX 35 58164+#define HI3516DV300_MMC2_MUX 36 58165+#define HI3516DV300_UART1_MUX 33 58166+#define HI3516DV300_UART2_MUX 37 58167+#define HI3516DV300_UART4_MUX 38 58168+#define HI3516DV300_ETH_MUX 39 58169+ 58170+/* gate clocks */ 58171+#define HI3516DV300_UART0_CLK 40 58172+#define HI3516DV300_UART1_CLK 41 58173+#define HI3516DV300_UART2_CLK 42 58174+#define HI3516DV300_FMC_CLK 43 58175+#define HI3516DV300_ETH0_CLK 44 58176+#define HI3516DV300_USB2_BUS_CLK 45 58177+#define HI3516DV300_USB2_CLK 46 58178+#define HI3516DV300_DMAC_CLK 47 58179+#define HI3516DV300_SPI0_CLK 48 58180+#define HI3516DV300_SPI1_CLK 49 58181+#define HI3516DV300_MMC0_CLK 50 58182+#define HI3516DV300_MMC1_CLK 51 58183+#define HI3516DV300_MMC2_CLK 52 58184+#define HI3516DV300_UART4_CLK 53 58185+#define HI3516DV300_SPI2_CLK 54 58186+#define HI3516DV300_I2C0_CLK 55 58187+#define HI3516DV300_I2C1_CLK 56 58188+#define HI3516DV300_I2C2_CLK 57 58189+#define HI3516DV300_I2C3_CLK 58 58190+#define HI3516DV300_I2C4_CLK 59 58191+#define HI3516DV300_I2C5_CLK 60 58192+#define HI3516DV300_I2C6_CLK 61 58193+#define HI3516DV300_I2C7_CLK 62 58194+#define HI3516DV300_UART3_MUX 63 58195+#define HI3516DV300_UART3_CLK 64 58196+#define HI3516DV300_DMAC_AXICLK 70 58197+#define HI3516DV300_PWM_CLK 71 58198+#define HI3516DV300_PWM_MUX 72 58199+ 58200+#define HI3516DV300_NR_CLKS 256 58201+#define HI3516DV300_NR_RSTS 256 58202+ 58203+#endif /* __DTS_HI3516DV300_CLOCK_H */ 58204diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h 58205index 31febd3e1..0fa3ac740 100644 58206--- a/include/linux/blkdev.h 58207+++ b/include/linux/blkdev.h 58208@@ -1384,7 +1384,11 @@ static inline bool bdev_is_partition(struct block_device *bdev) 58209 enum blk_default_limits { 58210 BLK_MAX_SEGMENTS = 128, 58211 BLK_SAFE_MAX_SECTORS = 255, 58212+#ifndef CONFIG_HISI_MC 58213 BLK_DEF_MAX_SECTORS = 2560, 58214+#else 58215+ BLK_DEF_MAX_SECTORS = 8192, 58216+#endif 58217 BLK_MAX_SEGMENT_SIZE = 65536, 58218 BLK_SEG_BOUNDARY_MASK = 0xFFFFFFFFUL, 58219 }; 58220diff --git a/include/linux/cpu.h b/include/linux/cpu.h 58221index d6428aaf6..a8d659c9a 100644 58222--- a/include/linux/cpu.h 58223+++ b/include/linux/cpu.h 58224@@ -41,6 +41,7 @@ extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id); 58225 extern bool arch_find_n_match_cpu_physical_id(struct device_node *cpun, 58226 int cpu, unsigned int *thread); 58227 58228+extern int hi_register_cpu_notifier(struct notifier_block *nb); 58229 extern int cpu_add_dev_attr(struct device_attribute *attr); 58230 extern void cpu_remove_dev_attr(struct device_attribute *attr); 58231 58232diff --git a/include/linux/fb.h b/include/linux/fb.h 58233index ecfbcc055..b8567818b 100644 58234--- a/include/linux/fb.h 58235+++ b/include/linux/fb.h 58236@@ -293,6 +293,12 @@ struct fb_ops { 58237 /* called at KDB enter and leave time to prepare the console */ 58238 int (*fb_debug_enter)(struct fb_info *info); 58239 int (*fb_debug_leave)(struct fb_info *info); 58240+#ifdef CONFIG_ARCH_HISI_BVT 58241+#ifdef CONFIG_DMA_SHARED_BUFFER 58242+ /* Export the frame buffer as a dmabuf object */ 58243+ struct dma_buf *(*fb_dmabuf_export)(struct fb_info *info); 58244+#endif 58245+#endif 58246 }; 58247 58248 #ifdef CONFIG_FB_TILEBLITTING 58249diff --git a/include/linux/hi_cma.h b/include/linux/hi_cma.h 58250new file mode 100644 58251index 000000000..38444524f 58252--- /dev/null 58253+++ b/include/linux/hi_cma.h 58254@@ -0,0 +1,54 @@ 58255+/* 58256+ * hi_cma.h 58257+ * 58258+ * Copyright (c) 2019 HiSilicon Technologies Co., Ltd. 58259+ * 58260+ * This program is free software; you can redistribute it and/or modify 58261+ * it under the terms of the GNU General Public License as published by 58262+ * the Free Software Foundation; either version 2 of the License, or 58263+ * (at your option) any later version. 58264+ * 58265+ * This program is distributed in the hope that it will be useful, 58266+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 58267+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 58268+ * GNU General Public License for more details. 58269+ * 58270+ * You should have received a copy of the GNU General Public License 58271+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 58272+ */ 58273+#ifndef __HI_CMA_H__ 58274+#define __HI_CMA_H__ 58275+ 58276+#include <linux/device.h> 58277+#include <linux/dma-mapping.h> 58278+#include <linux/dma-map-ops.h> 58279+#include <linux/module.h> 58280+#include <linux/string.h> 58281+#include <linux/cma.h> 58282+#include <linux/memblock.h> 58283+#include <linux/of.h> 58284+#include <linux/of_fdt.h> 58285+#include <linux/of_reserved_mem.h> 58286+ 58287+#define NAME_LEN_MAX 64 58288+#define ZONE_MAX 64 58289+ 58290+struct cma_zone { 58291+ struct device pdev; 58292+ char name[NAME_LEN_MAX]; 58293+ gfp_t gfp; 58294+ phys_addr_t phys_start; 58295+ phys_addr_t nbytes; 58296+ u32 alloc_type; 58297+ u32 block_align; 58298+}; 58299+ 58300+#ifdef CONFIG_CMA 58301+int is_hicma_address(phys_addr_t phys, unsigned long size); 58302+phys_addr_t hisi_get_zones_start(void); 58303+struct cma_zone *hisi_get_cma_zone(const char *name); 58304+struct device *hisi_get_cma_device(const char *name); 58305+int __init hisi_declare_heap_memory(void); 58306+#endif /* CONFIG_CMA */ 58307+ 58308+#endif 58309diff --git a/include/linux/hiedmac.h b/include/linux/hiedmac.h 58310new file mode 100644 58311index 000000000..26157899a 58312--- /dev/null 58313+++ b/include/linux/hiedmac.h 58314@@ -0,0 +1,65 @@ 58315+#ifndef __DMAC_H__ 58316+#define __DMAC_H__ 58317+ 58318+#define DMAC_ERROR_BASE 0x64 58319+ 58320+#define DMAC_CHN_SUCCESS (DMAC_ERROR_BASE + 0x10) 58321+#define DMAC_CHN_ERROR (DMAC_ERROR_BASE + 0x11) 58322+#define DMAC_CHN_TIMEOUT (DMAC_ERROR_BASE + 0x12) 58323+#define DMAC_CHN_ALLOCAT (DMAC_ERROR_BASE + 0x13) 58324+#define DMAC_CHN_VACANCY (DMAC_ERROR_BASE + 0x14) 58325+#define DMAC_NOT_FINISHED (DMAC_ERROR_BASE + 0xe) 58326+ 58327+#ifdef CONFIG_HIEDMAC 58328+extern int dma_driver_init(void); 58329+extern int dmac_channelclose(unsigned int channel); 58330+extern int dmac_channelstart(unsigned int u32channel); 58331+extern int dmac_channel_allocate(void); 58332+ 58333+extern int dmac_start_m2p(unsigned int channel, unsigned int pmemaddr, 58334+ unsigned int uwperipheralid, 58335+ unsigned int uwnumtransfers, 58336+ unsigned int next_lli_addr); 58337+extern int dmac_m2p_transfer(unsigned long long memaddr, unsigned int uwperipheralid, 58338+ unsigned int length); 58339+extern int dmac_channel_free(unsigned int channel); 58340+ 58341+extern int do_dma_m2p(unsigned long long memaddr, unsigned int peripheral_addr, 58342+ unsigned int length); 58343+extern int do_dma_p2m(unsigned long mem_addr, unsigned int peripheral_addr, 58344+ unsigned int length); 58345+extern int dmac_wait(int channel); 58346+ 58347+extern int dmac_start_m2m(unsigned int channel, unsigned long psource, 58348+ unsigned long pdest, unsigned int uwnumtransfers); 58349+extern int dmac_m2m_transfer(unsigned long source, unsigned long dest, 58350+ unsigned int length); 58351+extern int dmac_register_isr(unsigned int channel, void *pisr); 58352+extern int free_dmalli_space(unsigned int *ppheadlli, unsigned int page_num); 58353+extern int dmac_start_llim2p(unsigned int channel, unsigned int *pfirst_lli, 58354+ unsigned int uwperipheralid); 58355+extern int dmac_buildllim2m(unsigned long *ppheadlli, 58356+ unsigned long psource, 58357+ unsigned long pdest, 58358+ unsigned int totaltransfersize, 58359+ unsigned int uwnumtransfers); 58360+ 58361+extern int dmac_start_llim2m(unsigned int channel, unsigned long *pfirst_lli); 58362+ 58363+extern int allocate_dmalli_space(struct device *dev, unsigned long *ppheadlli, 58364+ unsigned int page_num); 58365+#endif /* CONFIG_HIEDMAC*/ 58366+ 58367+ 58368+/*structure for LLI*/ 58369+typedef struct dmac_lli { 58370+ //must be 64Byte aligned 58371+ unsigned long next_lli; 58372+ unsigned int reserved[5]; 58373+ unsigned int count; 58374+ unsigned long src_addr; 58375+ unsigned long dest_addr; 58376+ unsigned int config; 58377+ unsigned int pad[51]; 58378+} dmac_lli; 58379+#endif 58380diff --git a/include/linux/i2c.h b/include/linux/i2c.h 58381index a670ae129..815f52046 100644 58382--- a/include/linux/i2c.h 58383+++ b/include/linux/i2c.h 58384@@ -124,6 +124,23 @@ static inline int i2c_master_send_dmasafe(const struct i2c_client *client, 58385 /* Transfer num messages. 58386 */ 58387 int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); 58388+ 58389+#ifdef CONFIG_ARCH_HISI_BVT 58390+ 58391+extern int hi_i2c_master_send(const struct i2c_client *client, const char *buf, 58392+ int count); 58393+ 58394+extern int hi_i2c_master_send_mul_reg(const struct i2c_client *client, const char *buf, 58395+ unsigned int count, unsigned int reg_data_width); 58396+ 58397+extern int hi_i2c_master_recv(const struct i2c_client *client, char *buf, 58398+ int count); 58399+ 58400+extern int hi_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, 58401+ int num); 58402+ 58403+#endif 58404+ 58405 /* Unlocked flavor */ 58406 int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); 58407 58408diff --git a/include/linux/mfd/hisi_fmc.h b/include/linux/mfd/hisi_fmc.h 58409new file mode 100644 58410index 000000000..28ce45908 58411--- /dev/null 58412+++ b/include/linux/mfd/hisi_fmc.h 58413@@ -0,0 +1,477 @@ 58414+/* 58415+ * Header file for HiSilicon Flash Memory Controller Driver 58416+ * 58417+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 58418+ * 58419+ * This program is free software; you can redistribute it and/or modify 58420+ * it under the terms of the GNU General Public License version 2 as 58421+ * published by the Free Software Foundation. 58422+ */ 58423+ 58424+#ifndef __HISI_FMC_H 58425+#define __HISI_FMC_H 58426+ 58427+#include <linux/compiler.h> 58428+#include <linux/clk.h> 58429+#include <linux/mutex.h> 58430+#include <linux/bitops.h> 58431+ 58432+#define _512B (512) 58433+#define _1K (1024) 58434+#define _2K (2048) 58435+#define _4K (4096) 58436+#define _8K (8192) 58437+#define _16K (16384) 58438+#define _32K (32768) 58439+#define _64K (0x10000UL) 58440+#define _128K (0x20000UL) 58441+#define _256K (0x40000UL) 58442+#define _512K (0x80000UL) 58443+#define _1M (0x100000UL) 58444+#define _2M (0x200000UL) 58445+#define _4M (0x400000UL) 58446+#define _8M (0x800000UL) 58447+#define _16M (0x1000000UL) 58448+#define _32M (0x2000000UL) 58449+#define _64M (0x4000000UL) 58450+#define _128M (0x8000000UL) 58451+#define _256M (0x10000000UL) 58452+#define _512M (0x20000000UL) 58453+#define _1G (0x40000000ULL) 58454+#define _2G (0x80000000ULL) 58455+#define _4G (0x100000000ULL) 58456+#define _8G (0x200000000ULL) 58457+#define _16G (0x400000000ULL) 58458+#define _64G (0x1000000000ULL) 58459+ 58460+/* HIFMC REG MAP */ 58461+#define FMC_CFG 0x00 58462+#define FMC_CFG_SPI_NAND_SEL(_type) (((_size) & 0x3) << 11) 58463+#define SPI_NOR_ADDR_MODE BIT(10) 58464+#define FMC_CFG_OP_MODE_MASK BIT_MASK(0) 58465+#define FMC_CFG_OP_MODE_BOOT 0 58466+#define FMC_CFG_OP_MODE_NORMAL 1 58467+#define SPI_NOR_ADDR_MODE_3BYTES (0x0 << 10) 58468+#define SPI_NOR_ADDR_MODE_4BYTES (0x1 << 10) 58469+ 58470+#define FMC_CFG_BLOCK_SIZE(_size) (((_size) & 0x3) << 8) 58471+#define FMC_CFG_ECC_TYPE(_type) (((_type) & 0x7) << 5) 58472+#define FMC_CFG_PAGE_SIZE(_size) (((_size) & 0x3) << 3) 58473+#define FMC_CFG_FLASH_SEL(_type) (((_type) & 0x3) << 1) 58474+#define FMC_CFG_OP_MODE(_mode) ((_mode) & 0x1) 58475+ 58476+#define SPI_NAND_MFR_OTHER 0x0 58477+#define SPI_NAND_MFR_WINBOND 0x1 58478+#define SPI_NAND_MFR_ESMT 0x2 58479+#define SPI_NAND_MFR_MICRON 0x3 58480+ 58481+#define SPI_NAND_SEL_SHIFT 11 58482+#define SPI_NAND_SEL_MASK (0x3 << SPI_NAND_SEL_SHIFT) 58483+ 58484+#define SPI_NOR_ADDR_MODE_3_BYTES 0x0 58485+#define SPI_NOR_ADDR_MODE_4_BYTES 0x1 58486+ 58487+#define SPI_NOR_ADDR_MODE_SHIFT 10 58488+#define SPI_NOR_ADDR_MODE_MASK (0x1 << SPI_NOR_ADDR_MODE_SHIFT) 58489+ 58490+#define BLOCK_SIZE_64_PAGE 0x0 58491+#define BLOCK_SIZE_128_PAGE 0x1 58492+#define BLOCK_SIZE_256_PAGE 0x2 58493+#define BLOCK_SIZE_512_PAGE 0x3 58494+ 58495+#define BLOCK_SIZE_MASK (0x3 << 8) 58496+ 58497+#define ECC_TYPE_0BIT 0x0 58498+#define ECC_TYPE_8BIT 0x1 58499+#define ECC_TYPE_16BIT 0x2 58500+#define ECC_TYPE_24BIT 0x3 58501+#define ECC_TYPE_28BIT 0x4 58502+#define ECC_TYPE_40BIT 0x5 58503+#define ECC_TYPE_64BIT 0x6 58504+ 58505+#define ECC_TYPE_SHIFT 5 58506+#define ECC_TYPE_MASK (0x7 << ECC_TYPE_SHIFT) 58507+ 58508+#define PAGE_SIZE_2KB 0x0 58509+#define PAGE_SIZE_4KB 0x1 58510+#define PAGE_SIZE_8KB 0x2 58511+#define PAGE_SIZE_16KB 0x3 58512+ 58513+#define PAGE_SIZE_SHIFT 3 58514+#define PAGE_SIZE_MASK (0x3 << PAGE_SIZE_SHIFT) 58515+ 58516+#define FLASH_TYPE_SPI_NOR 0x0 58517+#define FLASH_TYPE_SPI_NAND 0x1 58518+#define FLASH_TYPE_NAND 0x2 58519+#define FLASH_TYPE_UNKNOWN 0x3 58520+ 58521+#define FLASH_TYPE_SEL_MASK (0x3 << 1) 58522+#define GET_SPI_FLASH_TYPE(_reg) (((_reg) >> 1) & 0x3) 58523+ 58524+#define FMC_GLOBAL_CFG 0x04 58525+#define FMC_GLOBAL_CFG_WP_ENABLE BIT(6) 58526+#define FMC_GLOBAL_CFG_RANDOMIZER_EN (1 << 2) 58527+#define FLASH_TYPE_SEL_MASK (0x3 << 1) 58528+#define FMC_CFG_FLASH_SEL(_type) (((_type) & 0x3) << 1) 58529+ 58530+#define FMC_GLOBAL_CFG_DTR_MODE BIT(11) 58531+#define FMC_SPI_TIMING_CFG 0x08 58532+#define TIMING_CFG_TCSH(nr) (((nr) & 0xf) << 8) 58533+#define TIMING_CFG_TCSS(nr) (((nr) & 0xf) << 4) 58534+#define TIMING_CFG_TSHSL(nr) ((nr) & 0xf) 58535+ 58536+#define CS_HOLD_TIME 0x6 58537+#define CS_SETUP_TIME 0x6 58538+#define CS_DESELECT_TIME 0xf 58539+ 58540+#define FMC_PND_PWIDTH_CFG 0x0c 58541+#define PWIDTH_CFG_RW_HCNT(_n) (((_n) & 0xf) << 8) 58542+#define PWIDTH_CFG_R_LCNT(_n) (((_n) & 0xf) << 4) 58543+#define PWIDTH_CFG_W_LCNT(_n) ((_n) & 0xf) 58544+ 58545+#define RW_H_WIDTH (0xa) 58546+#define R_L_WIDTH (0xa) 58547+#define W_L_WIDTH (0xa) 58548+ 58549+#define FMC_INT 0x18 58550+#define FMC_INT_AHB_OP BIT(7) 58551+#define FMC_INT_WR_LOCK BIT(6) 58552+#define FMC_INT_DMA_ERR BIT(5) 58553+#define FMC_INT_ERR_ALARM BIT(4) 58554+#define FMC_INT_ERR_INVALID BIT(3) 58555+#define FMC_INT_ERR_INVALID_MASK (0x8) 58556+#define FMC_INT_ERR_VALID BIT(2) 58557+#define FMC_INT_ERR_VALID_MASK (0x4) 58558+#define FMC_INT_OP_FAIL BIT(1) 58559+#define FMC_INT_OP_DONE BIT(0) 58560+ 58561+#define FMC_INT_EN 0x1c 58562+#define FMC_INT_EN_AHB_OP BIT(7) 58563+#define FMC_INT_EN_WR_LOCK BIT(6) 58564+#define FMC_INT_EN_DMA_ERR BIT(5) 58565+#define FMC_INT_EN_ERR_ALARM BIT(4) 58566+#define FMC_INT_EN_ERR_INVALID BIT(3) 58567+#define FMC_INT_EN_ERR_VALID BIT(2) 58568+#define FMC_INT_EN_OP_FAIL BIT(1) 58569+#define FMC_INT_EN_OP_DONE BIT(0) 58570+ 58571+#define FMC_INT_CLR 0x20 58572+#define FMC_INT_CLR_AHB_OP BIT(7) 58573+#define FMC_INT_CLR_WR_LOCK BIT(6) 58574+#define FMC_INT_CLR_DMA_ERR BIT(5) 58575+#define FMC_INT_CLR_ERR_ALARM BIT(4) 58576+#define FMC_INT_CLR_ERR_INVALID BIT(3) 58577+#define FMC_INT_CLR_ERR_VALID BIT(2) 58578+#define FMC_INT_CLR_OP_FAIL BIT(1) 58579+#define FMC_INT_CLR_OP_DONE BIT(0) 58580+ 58581+#define FMC_INT_CLR_ALL 0xff 58582+ 58583+#define FMC_CMD 0x24 58584+#define FMC_CMD_CMD2(_cmd) (((_cmd) & 0xff) << 8) 58585+#define FMC_CMD_CMD1(_cmd) ((_cmd) & 0xff) 58586+ 58587+#define FMC_ADDRH 0x28 58588+#define FMC_ADDRH_SET(_addr) ((_addr) & 0xff) 58589+ 58590+#define FMC_ADDRL 0x2c 58591+#define FMC_ADDRL_BLOCK_MASK(_page) ((_page) & 0xffffffc0) 58592+#define FMC_ADDRL_BLOCK_H_MASK(_page) (((_page) & 0xffff) << 16) 58593+#define FMC_ADDRL_BLOCK_L_MASK(_page) ((_page) & 0xffc0) 58594+ 58595+#define READ_ID_ADDR 0x00 58596+#define PROTECT_ADDR 0xa0 58597+#define FEATURE_ADDR 0xb0 58598+#define STATUS_ADDR 0xc0 58599+#define FMC_OP_CFG 0x30 58600+#define OP_CFG_FM_CS(_cs) ((_cs) << 11) 58601+#define OP_CFG_FORCE_CS_EN(_en) ((_en) << 10) 58602+#define OP_CFG_MEM_IF_TYPE(_type) (((_type) & 0x7) << 7) 58603+#define OP_CFG_ADDR_NUM(_addr) (((_addr) & 0x7) << 4) 58604+#define OP_CFG_DUMMY_NUM(_dummy) ((_dummy) & 0xf) 58605+#define OP_CFG_OEN_EN (0x1 << 13) 58606+ 58607+#define IF_TYPE_SHIFT 7 58608+#define IF_TYPE_MASK (0x7 << IF_TYPE_SHIFT) 58609+ 58610+#define READ_ID_ADDR_NUM 1 58611+#define FEATURES_OP_ADDR_NUM 1 58612+#define STD_OP_ADDR_NUM 3 58613+ 58614+#define FMC_SPI_OP_ADDR 0x34 58615+ 58616+#define FMC_DATA_NUM 0x38 58617+#define FMC_DATA_NUM_CNT(_n) ((_n) & 0x3fff) 58618+ 58619+#define SPI_NOR_SR_LEN 1 /* Status Register length */ 58620+#define SPI_NOR_CR_LEN 1 /* Config Register length */ 58621+#define FEATURES_DATA_LEN 1 58622+#define READ_OOB_BB_LEN 1 58623+ 58624+#define PROTECT_BRWD_MASK BIT(7) 58625+#define PROTECT_BP3_MASK BIT(6) 58626+#define PROTECT_BP2_MASK BIT(5) 58627+#define PROTECT_BP1_MASK BIT(4) 58628+#define PROTECT_BP0_MASK BIT(3) 58629+ 58630+#define ANY_BP_ENABLE(_val) ((PROTECT_BP3_MASK & _val) \ 58631+ || (PROTECT_BP2_MASK & _val) \ 58632+ || (PROTECT_BP1_MASK & _val) \ 58633+ || (PROTECT_BP0_MASK & _val)) 58634+ 58635+#define ALL_BP_MASK (PROTECT_BP3_MASK \ 58636+ | PROTECT_BP2_MASK \ 58637+ | PROTECT_BP1_MASK \ 58638+ | PROTECT_BP0_MASK) 58639+ 58640+#define FEATURE_ECC_ENABLE (1 << 4) 58641+#define FEATURE_QE_ENABLE (1 << 0) 58642+ 58643+#define FMC_OP 0x3c 58644+#define FMC_OP_DUMMY_EN BIT(8) 58645+#define FMC_OP_CMD1_EN BIT(7) 58646+#define FMC_OP_ADDR_EN BIT(6) 58647+#define FMC_OP_WRITE_DATA_EN BIT(5) 58648+#define FMC_OP_CMD2_EN BIT(4) 58649+#define FMC_OP_WAIT_READY_EN BIT(3) 58650+#define FMC_OP_READ_DATA_EN BIT(2) 58651+#define FMC_OP_READ_STATUS_EN BIT(1) 58652+#define FMC_OP_REG_OP_START BIT(0) 58653+ 58654+#define FMC_OP_DMA 0x68 58655+#define FMC_DMA_LEN 0x40 58656+#define FMC_DMA_LEN_SET(_len) ((_len) & 0x0fffffff) 58657+ 58658+#define FMC_DMA_AHB_CTRL 0x48 58659+#define FMC_DMA_AHB_CTRL_DMA_PP_EN BIT(3) 58660+#define FMC_DMA_AHB_CTRL_BURST16_EN BIT(2) 58661+#define FMC_DMA_AHB_CTRL_BURST8_EN BIT(1) 58662+#define FMC_DMA_AHB_CTRL_BURST4_EN BIT(0) 58663+ 58664+#define ALL_BURST_ENABLE (FMC_DMA_AHB_CTRL_BURST16_EN \ 58665+ | FMC_DMA_AHB_CTRL_BURST8_EN \ 58666+ | FMC_DMA_AHB_CTRL_BURST4_EN) 58667+ 58668+#define FMC_DMA_ADDR_OFFSET 4096 58669+ 58670+#define FMC_DMA_SADDR_D0 0x4c 58671+ 58672+#define FMC_DMA_SADDR_D1 0x50 58673+ 58674+#define FMC_DMA_SADDR_D2 0x54 58675+ 58676+#define FMC_DMA_SADDR_D3 0x58 58677+ 58678+#define FMC_DMA_SADDR_OOB 0x5c 58679+ 58680+#ifdef CONFIG_64BIT 58681+#define FMC_DMA_SADDRH_D0 0x200 58682+#define FMC_DMA_SADDRH_SHIFT 0x3LL 58683+#define FMC_DMA_SADDRH_MASK (FMC_DMA_SADDRH_SHIFT << 32) 58684+ 58685+#define FMC_DMA_SADDRH_OOB 0x210 58686+#endif 58687+ 58688+#define FMC_DMA_BLK_SADDR 0x60 58689+#define FMC_DMA_BLK_SADDR_SET(_addr) ((_addr) & 0xffffff) 58690+ 58691+#define FMC_DMA_BLK_LEN 0x64 58692+#define FMC_DMA_BLK_LEN_SET(_len) ((_len) & 0xffff) 58693+ 58694+#define FMC_OP_CTRL 0x68 58695+#define OP_CTRL_RD_OPCODE(code) (((code) & 0xff) << 16) 58696+#define OP_CTRL_WR_OPCODE(code) (((code) & 0xff) << 8) 58697+#define OP_CTRL_RD_OP_SEL(_op) (((_op) & 0x3) << 4) 58698+#define OP_CTRL_DMA_OP(_type) ((_type) << 2) 58699+#define OP_CTRL_RW_OP(op) ((op) << 1) 58700+#define OP_CTRL_DMA_OP_READY BIT(0) 58701+ 58702+#define RD_OP_READ_ALL_PAGE 0x0 58703+#define RD_OP_READ_OOB 0x1 58704+#define RD_OP_BLOCK_READ 0x2 58705+ 58706+#define RD_OP_SHIFT 4 58707+#define RD_OP_MASK (0x3 << RD_OP_SHIFT) 58708+ 58709+#define OP_TYPE_DMA 0x0 58710+#define OP_TYPE_REG 0x1 58711+ 58712+#define FMC_OP_READ 0x0 58713+#define FMC_OP_WRITE 0x1 58714+#define RW_OP_READ 0x0 58715+#define RW_OP_WRITE 0x1 58716+ 58717+#define FMC_OP_PARA 0x70 58718+#define FMC_OP_PARA_RD_OOB_ONLY BIT(1) 58719+ 58720+#define FMC_BOOT_SET 0x74 58721+#define FMC_BOOT_SET_DEVICE_ECC_EN BIT(3) 58722+#define FMC_BOOT_SET_BOOT_QUAD_EN BIT(1) 58723+ 58724+#define FMC_STATUS 0xac 58725+ 58726+#ifndef FMC_VERSION 58727+#define FMC_VERSION 0xbc 58728+#endif 58729+ 58730+/* Hifmc IP version */ 58731+#ifndef HIFMC_VER_100 58732+#define HIFMC_VER_100 (0x100) 58733+#endif 58734+ 58735+/* DMA address align with 32 bytes. */ 58736+#define FMC_DMA_ALIGN 32 58737+ 58738+#define FMC_CHIP_DELAY 25 58739+#define HIFMC_ECC_ERR_NUM0_BUF0 0xc0 58740+#define GET_ECC_ERR_NUM(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) 58741+ 58742+#define DISABLE 0 58743+#define ENABLE 1 58744+ 58745+#define HIFMC_REG_ADDRESS_LEN 0x200 58746+ 58747+#define FMC_MAX_READY_WAIT_JIFFIES (HZ) 58748+ 58749+#define MAX_SPI_NOR_ID_LEN 8 58750+#define MAX_NAND_ID_LEN 8 58751+#define MAX_SPI_NAND_ID_LEN 3 58752+ 58753+#define GET_OP 0 58754+#define SET_OP 1 58755+ 58756+#define STATUS_ECC_MASK (0x3 << 4) 58757+#define STATUS_P_FAIL_MASK (1 << 3) 58758+#define STATUS_E_FAIL_MASK (1 << 2) 58759+#define STATUS_WEL_MASK (1 << 1) 58760+#define STATUS_OIP_MASK (1 << 0) 58761+ 58762+#define FMC_VERSION 0xbc 58763+ 58764+/* Hifmc IP version */ 58765+#define HIFMC_VER_100 (0x100) 58766+ 58767+#define CONFIG_SPI_NAND_MAX_CHIP_NUM (1) 58768+ 58769+#define CONFIG_HIFMC100_MAX_NAND_CHIP (1) 58770+ 58771+#define GET_PAGE_INDEX(host) \ 58772+ ((host->addr_value[0] >> 16) | (host->addr_value[1] << 16)) 58773+#define HIFMC_MAX_CHIP_NUM 2 58774+ 58775+extern unsigned char hifmc_cs_user[]; 58776+ 58777+#define hifmc_readl(_host, _reg) \ 58778+ (readl((char *)_host->regbase + (_reg))) 58779+ 58780+#define hifmc_readb( _addr) \ 58781+ (readb((void __iomem *)(_addr))) 58782+ 58783+#define hifmc_readw( _addr) \ 58784+ (readw((void __iomem *)(_addr))) 58785+ 58786+#define hifmc_writel(_host, _reg, _value) \ 58787+ (writel((u_int)(_value), ((char *)_host->regbase + (_reg)))) 58788+ 58789+#define hifmc_writeb(_val, _addr) \ 58790+ (writeb((u_int)(_val), ((char *)_addr))) 58791+ 58792+#define FMC_WAIT_TIMEOUT 0x2000000 58793+ 58794+#define FMC_CMD_WAIT_CPU_FINISH(_host) \ 58795+ do { \ 58796+ unsigned regval, timeout = FMC_WAIT_TIMEOUT * 2; \ 58797+ do { \ 58798+ regval = hifmc_readl((_host), FMC_OP); \ 58799+ --timeout; \ 58800+ } while ((regval & FMC_OP_REG_OP_START) && timeout); \ 58801+ if (!timeout) \ 58802+ pr_info("Error: Wait cmd cpu finish timeout!\n"); \ 58803+ } while (0) 58804+ 58805+#define FMC_DMA_WAIT_INT_FINISH(_host) \ 58806+ do { \ 58807+ unsigned regval, timeout = FMC_WAIT_TIMEOUT; \ 58808+ do { \ 58809+ regval = hifmc_readl((_host), FMC_INT); \ 58810+ --timeout; \ 58811+ } while ((!(regval & FMC_INT_OP_DONE) && timeout)); \ 58812+ if (!timeout) \ 58813+ pr_info("Error: Wait dma int finish timeout!\n"); \ 58814+ } while (0) 58815+ 58816+#define FMC_DMA_WAIT_CPU_FINISH(_host) \ 58817+ do { \ 58818+ unsigned regval, timeout = FMC_WAIT_TIMEOUT; \ 58819+ do { \ 58820+ regval = hifmc_readl((_host), FMC_OP_CTRL); \ 58821+ --timeout; \ 58822+ } while ((regval & OP_CTRL_DMA_OP_READY) && timeout); \ 58823+ if (!timeout) \ 58824+ pr_info("Error: Wait dma cpu finish timeout!\n"); \ 58825+ } while (0) 58826+ 58827+#define BT_DBG 0 /* Boot init debug print */ 58828+#define ER_DBG 0 /* Erase debug print */ 58829+#define WR_DBG 0 /* Write debug print */ 58830+#define RD_DBG 0 /* Read debug print */ 58831+#define QE_DBG 0 /* Quad Enable debug print */ 58832+#define OP_DBG 0 /* OP command debug print */ 58833+#define DMA_DB 0 /* DMA read or write debug print */ 58834+#define AC_DBG 0 /* 3-4byte Address Cycle */ 58835+#define SR_DBG 0 /* Status Register debug print */ 58836+#define CR_DBG 0 /* Config Register debug print */ 58837+#define FT_DBG 0 /* Features debug print */ 58838+#define WE_DBG 0 /* Write Enable debug print */ 58839+#define BP_DBG 0 /* Block Protection debug print */ 58840+#define EC_DBG 0 /* enable/disable ecc0 and randomizer */ 58841+#define PM_DBG 0 /* power management debug */ 58842+ 58843+#define FMC_PR(_type, _fmt, arg...) \ 58844+ do { \ 58845+ if (_type) \ 58846+ DB_MSG(_fmt, ##arg) \ 58847+ } while (0) 58848+ 58849+#define DB_MSG(_fmt, arg...) \ 58850+ pr_info("%s(%d): " _fmt, __func__, __LINE__, ##arg); 58851+ 58852+#define DB_BUG(fmt, args...) \ 58853+ do { \ 58854+ pr_info("%s(%d): BUG: " fmt, __FILE__, __LINE__, ##args); \ 58855+ while (1) \ 58856+ ; \ 58857+ } while (0) 58858+ 58859+enum hifmc_iftype { 58860+ IF_TYPE_STD, 58861+ IF_TYPE_DUAL, 58862+ IF_TYPE_DIO, 58863+ IF_TYPE_QUAD, 58864+ IF_TYPE_QIO, 58865+}; 58866+ 58867+struct hisi_fmc { 58868+ void __iomem *regbase; 58869+ void __iomem *iobase; 58870+ struct clk *clk; 58871+ struct mutex lock; 58872+ void *buffer; 58873+ dma_addr_t dma_buffer; 58874+ unsigned int dma_len; 58875+}; 58876+ 58877+struct hifmc_cmd_op { 58878+ unsigned char cs; 58879+ unsigned char cmd; 58880+ unsigned char l_cmd; 58881+ unsigned char addr_h; 58882+ unsigned int addr_l; 58883+ unsigned int data_no; 58884+ unsigned short option; 58885+ unsigned short op_cfg; 58886+}; 58887+ 58888+extern struct mutex fmc_switch_mutex; 58889+ 58890+#endif /* __HISI_FMC_H */ 58891diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h 58892index 40d7e98fc..5b77c8cda 100644 58893--- a/include/linux/mmc/host.h 58894+++ b/include/linux/mmc/host.h 58895@@ -173,6 +173,7 @@ struct mmc_host_ops { 58896 */ 58897 int (*multi_io_quirk)(struct mmc_card *card, 58898 unsigned int direction, int blk_size); 58899+ int (*card_info_save)(struct mmc_host *host); 58900 }; 58901 58902 struct mmc_cqe_ops { 58903@@ -281,6 +282,12 @@ struct mmc_host { 58904 unsigned int f_min; 58905 unsigned int f_max; 58906 unsigned int f_init; 58907+ unsigned int type; 58908+#define MMC_HOST_TYPE_MMC 0 /* MMC card */ 58909+#define MMC_HOST_TYPE_SD 1 /* SD card */ 58910+#define MMC_HOST_TYPE_SDIO 2 /* SDIO card */ 58911+#define MMC_HOST_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ 58912+ 58913 u32 ocr_avail; 58914 u32 ocr_avail_sdio; /* SDIO-specific OCR */ 58915 u32 ocr_avail_sd; /* SD-specific OCR */ 58916@@ -425,6 +432,11 @@ struct mmc_host { 58917 58918 struct delayed_work detect; 58919 int detect_change; /* card detect flag */ 58920+ u32 card_status; 58921+#define MMC_CARD_UNINIT 0 58922+#define MMC_CARD_INIT 1 58923+#define MMC_CARD_INIT_FAIL 2 58924+ 58925 struct mmc_slot slot; 58926 58927 const struct mmc_bus_ops *bus_ops; /* current bus driver */ 58928diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h 58929index 157357ec1..3588dc165 100644 58930--- a/include/linux/mtd/mtd.h 58931+++ b/include/linux/mtd/mtd.h 58932@@ -18,6 +18,12 @@ 58933 58934 #include <asm/div64.h> 58935 58936+#define MTD_ERASE_PENDING 0x01 58937+#define MTD_ERASING 0x02 58938+#define MTD_ERASE_SUSPEND 0x04 58939+#define MTD_ERASE_DONE 0x08 58940+#define MTD_ERASE_FAILED 0x10 58941+ 58942 #define MTD_FAIL_ADDR_UNKNOWN -1LL 58943 58944 struct mtd_info; 58945@@ -28,9 +34,18 @@ struct mtd_info; 58946 * or was not specific to any particular block. 58947 */ 58948 struct erase_info { 58949+ struct mtd_info *mtd; 58950 uint64_t addr; 58951 uint64_t len; 58952 uint64_t fail_addr; 58953+ u_long time; 58954+ u_long retries; 58955+ unsigned dev; 58956+ unsigned cell; 58957+ void (*callback) (struct erase_info *self); 58958+ u_long priv; 58959+ u_char state; 58960+ struct erase_info *next; 58961 }; 58962 58963 struct mtd_erase_region_info { 58964@@ -55,11 +70,9 @@ struct mtd_erase_region_info { 58965 * @datbuf: data buffer - if NULL only oob data are read/written 58966 * @oobbuf: oob data buffer 58967 * 58968- * Note, some MTD drivers do not allow you to write more than one OOB area at 58969- * one go. If you try to do that on such an MTD device, -EINVAL will be 58970- * returned. If you want to make your implementation portable on all kind of MTD 58971- * devices you should split the write request into several sub-requests when the 58972- * request crosses a page boundary. 58973+ * Note, it is allowed to read more than one OOB area at one go, but not write. 58974+ * The interface assumes that the OOB write requests program only one page's 58975+ * OOB area. 58976 */ 58977 struct mtd_oob_ops { 58978 unsigned int mode; 58979@@ -314,6 +327,10 @@ struct mtd_info { 58980 int (*_point) (struct mtd_info *mtd, loff_t from, size_t len, 58981 size_t *retlen, void **virt, resource_size_t *phys); 58982 int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len); 58983+ unsigned long (*_get_unmapped_area) (struct mtd_info *mtd, 58984+ unsigned long len, 58985+ unsigned long offset, 58986+ unsigned long flags); 58987 int (*_read) (struct mtd_info *mtd, loff_t from, size_t len, 58988 size_t *retlen, u_char *buf); 58989 int (*_write) (struct mtd_info *mtd, loff_t to, size_t len, 58990@@ -356,6 +373,11 @@ struct mtd_info { 58991 int (*_get_device) (struct mtd_info *mtd); 58992 void (*_put_device) (struct mtd_info *mtd); 58993 58994+ /* Backing device capabilities for this device 58995+ * - provides mmap capabilities 58996+ */ 58997+ struct backing_dev_info *backing_dev_info; 58998+ 58999 /* 59000 * flag indicates a panic write, low level drivers can take appropriate 59001 * action if required to ensure writes go through 59002@@ -456,13 +478,11 @@ static inline void mtd_set_of_node(struct mtd_info *mtd, 59003 struct device_node *np) 59004 { 59005 mtd->dev.of_node = np; 59006- if (!mtd->name) 59007- of_property_read_string(np, "label", &mtd->name); 59008 } 59009 59010 static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd) 59011 { 59012- return dev_of_node(&mtd->dev); 59013+ return mtd->dev.of_node; 59014 } 59015 59016 static inline u32 mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) 59017@@ -580,34 +600,6 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd) 59018 return do_div(sz, mtd->erasesize); 59019 } 59020 59021-/** 59022- * mtd_align_erase_req - Adjust an erase request to align things on eraseblock 59023- * boundaries. 59024- * @mtd: the MTD device this erase request applies on 59025- * @req: the erase request to adjust 59026- * 59027- * This function will adjust @req->addr and @req->len to align them on 59028- * @mtd->erasesize. Of course we expect @mtd->erasesize to be != 0. 59029- */ 59030-static inline void mtd_align_erase_req(struct mtd_info *mtd, 59031- struct erase_info *req) 59032-{ 59033- u32 mod; 59034- 59035- if (WARN_ON(!mtd->erasesize)) 59036- return; 59037- 59038- mod = mtd_mod_by_eb(req->addr, mtd); 59039- if (mod) { 59040- req->addr -= mod; 59041- req->len += mod; 59042- } 59043- 59044- mod = mtd_mod_by_eb(req->addr + req->len, mtd); 59045- if (mod) 59046- req->len += mtd->erasesize - mod; 59047-} 59048- 59049 static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) 59050 { 59051 if (mtd->writesize_shift) 59052@@ -692,6 +684,8 @@ extern void register_mtd_user (struct mtd_notifier *new); 59053 extern int unregister_mtd_user (struct mtd_notifier *old); 59054 void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); 59055 59056+void mtd_erase_callback(struct erase_info *instr); 59057+ 59058 static inline int mtd_is_bitflip(int err) { 59059 return err == -EUCLEAN; 59060 } 59061diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h 59062index 60bac2c0e..04e292e88 100644 59063--- a/include/linux/mtd/spi-nor.h 59064+++ b/include/linux/mtd/spi-nor.h 59065@@ -11,6 +11,44 @@ 59066 #include <linux/mtd/mtd.h> 59067 #include <linux/spi/spi-mem.h> 59068 59069+#ifdef CONFIG_ARCH_HISI_BVT 59070+#define SNOR_MFR_EON CFI_MFR_EON 59071+#define SNOR_MFR_WINBOND 0xef 59072+#define SNOR_MFR_ESMT 0x8c 59073+#define SNOR_MFR_GD 0xc8 59074+#define SNOR_MFR_XTX 0x0b 59075+#define SNOR_MFR_PUYA 0x85 59076+ 59077+/* Flash set the RESET# from */ 59078+#define SPI_NOR_SR_RST_MASK BIT(7) 59079+#define SPI_NOR_GET_RST(val) (((val) & SPI_NOR_SR_RST_MASK) >> 7) 59080+#define SPI_NOR_SET_RST(val) ((val) | SPI_NOR_SR_RST_MASK) 59081+ 59082+/* Flash block protect */ 59083+#ifdef CONFIG_HISI_SPI_BLOCK_PROTECT 59084+#define _2M (0x200000UL) 59085+#define _4M (0x400000UL) 59086+#define _8M (0x800000UL) 59087+#define _16M (0x1000000UL) 59088+#define _32M (0x2000000UL) 59089+ 59090+#define BP_NUM_3 3 59091+#define BP_NUM_4 4 59092+ 59093+#define DEBUG_SPI_NOR_BP 0 59094+ 59095+#define SPI_NOR_SR_BP0_SHIFT 2 59096+#define SPI_NOR_SR_BP_WIDTH_4 0xf 59097+#define SPI_NOR_SR_BP_MASK_4 (SPI_NOR_SR_BP_WIDTH_4 << SPI_NOR_SR_BP0_SHIFT) 59098+ 59099+#define SPI_NOR_SR_BP_WIDTH_3 0x7 59100+#define SPI_NOR_SR_BP_MASK_3 (SPI_NOR_SR_BP_WIDTH_3 << SPI_NOR_SR_BP0_SHIFT) 59101+ 59102+#define LOCK_LEVEL_MAX(bp_num) (((0x01) << bp_num) - 1) 59103+ 59104+#endif /* CONFIG_HISI_SPI_BLOCK_PROTECT */ 59105+#endif /* CONFIG_ARCH_HISI_BVT */ 59106+ 59107 /* 59108 * Note on opcode nomenclature: some opcodes have a format like 59109 * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number 59110@@ -98,6 +136,17 @@ 59111 59112 /* Used for Spansion flashes only. */ 59113 #define SPINOR_OP_BRWR 0x17 /* Bank register write */ 59114+ 59115+#ifdef CONFIG_ARCH_HISI_BVT 59116+#define SPINOR_OP_RDSR3 0x15 /* Read Status Register-3 */ 59117+#define SPINOR_OP_WRSR3 0x11 /* Write Status Register-3 1 byte*/ 59118+/* Used for GigaDevice flashes only. */ 59119+#define SPINOR_OP_WRCR 0x31 /* Config register write */ 59120+/* Software reset code */ 59121+#define CR_DUMMY_CYCLE (0x03 << 6) /* Macronix dummy cycle bits */ 59122+#define SR_QUAD_EN_XTX BIT(1) 59123+#endif 59124+ 59125 #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ 59126 59127 /* Used for Micron flashes only. */ 59128@@ -166,6 +215,23 @@ 59129 (SNOR_PROTO_IS_DTR | \ 59130 SNOR_PROTO_STR(_inst_nbits, _addr_nbits, _data_nbits)) 59131 59132+#ifdef CONFIG_ARCH_HISI_BVT 59133+#define SNOR_OP_READ(_num_mode_clocks, _num_wait_states, _opcode, _proto) \ 59134+ { \ 59135+ .num_mode_clocks = _num_mode_clocks, \ 59136+ .num_wait_states = _num_wait_states, \ 59137+ .opcode = _opcode, \ 59138+ .proto = _proto, \ 59139+ } 59140+ 59141+#define SNOR_OP_PROGRAMS(_opcode, _proto) \ 59142+ { \ 59143+ .opcode = _opcode, \ 59144+ .proto = _proto, \ 59145+ } 59146+ 59147+#endif /* CONFIG_ARCH_HISI_BVT */ 59148+ 59149 enum spi_nor_protocol { 59150 SNOR_PROTO_1_1_1 = SNOR_PROTO_STR(1, 1, 1), 59151 SNOR_PROTO_1_1_2 = SNOR_PROTO_STR(1, 1, 2), 59152@@ -386,6 +452,15 @@ struct spi_nor { 59153 struct spi_mem_dirmap_desc *wdesc; 59154 } dirmap; 59155 59156+#ifdef CONFIG_ARCH_HISI_BVT 59157+#ifdef CONFIG_HISI_SPI_BLOCK_PROTECT 59158+ unsigned int end_addr; 59159+ unsigned int lock_level_max; 59160+ unsigned char level; 59161+#endif 59162+ struct device_node *flash_node; 59163+ u32 clkrate; 59164+#endif 59165 void *priv; 59166 }; 59167 59168@@ -414,6 +489,13 @@ static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) 59169 * 59170 * Return: 0 for success, others for failure. 59171 */ 59172+#ifdef CONFIG_ARCH_HISI_BVT 59173+void spi_nor_driver_shutdown(struct spi_nor *nor); 59174+#ifdef CONFIG_PM 59175+int spi_nor_suspend(struct spi_nor *nor, pm_message_t state); 59176+int hisi_spi_nor_resume(struct spi_nor *nor); 59177+#endif 59178+#endif /* CONFIG_ARCH_HISI_BVT */ 59179 int spi_nor_scan(struct spi_nor *nor, const char *name, 59180 const struct spi_nor_hwcaps *hwcaps); 59181 59182diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h 59183index f96b7f8d8..11911795d 100644 59184--- a/include/linux/netdev_features.h 59185+++ b/include/linux/netdev_features.h 59186@@ -30,6 +30,7 @@ enum { 59187 NETIF_F_GRO_BIT, /* Generic receive offload */ 59188 NETIF_F_LRO_BIT, /* large receive offload */ 59189 59190+ NETIF_F_UFO_BIT, /* UDPv4 fragmentation */ 59191 /**/NETIF_F_GSO_SHIFT, /* keep the order of SKB_GSO_* bits */ 59192 NETIF_F_TSO_BIT /* ... TCPv4 segmentation */ 59193 = NETIF_F_GSO_SHIFT, 59194@@ -127,6 +128,7 @@ enum { 59195 #define NETIF_F_TSO6 __NETIF_F(TSO6) 59196 #define NETIF_F_TSO_ECN __NETIF_F(TSO_ECN) 59197 #define NETIF_F_TSO __NETIF_F(TSO) 59198+#define NETIF_F_UFO __NETIF_F(UFO) 59199 #define NETIF_F_VLAN_CHALLENGED __NETIF_F(VLAN_CHALLENGED) 59200 #define NETIF_F_RXFCS __NETIF_F(RXFCS) 59201 #define NETIF_F_RXALL __NETIF_F(RXALL) 59202@@ -207,7 +209,7 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start) 59203 NETIF_F_FSO) 59204 59205 /* List of features with software fallbacks. */ 59206-#define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | \ 59207+#define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | NETIF_F_UFO | \ 59208 NETIF_F_GSO_SCTP) 59209 59210 /* 59211diff --git a/include/linux/phy.h b/include/linux/phy.h 59212index 08725a262..45c717bc1 100644 59213--- a/include/linux/phy.h 59214+++ b/include/linux/phy.h 59215@@ -1547,6 +1547,7 @@ void phy_queue_state_machine(struct phy_device *phydev, unsigned long jiffies); 59216 void phy_mac_interrupt(struct phy_device *phydev); 59217 void phy_start_machine(struct phy_device *phydev); 59218 void phy_stop_machine(struct phy_device *phydev); 59219+int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); 59220 void phy_ethtool_ksettings_get(struct phy_device *phydev, 59221 struct ethtool_link_ksettings *cmd); 59222 int phy_ethtool_ksettings_set(struct phy_device *phydev, 59223diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h 59224index acbf1875a..f4573b855 100644 59225--- a/include/linux/skbuff.h 59226+++ b/include/linux/skbuff.h 59227@@ -521,6 +521,7 @@ struct skb_shared_info { 59228 struct skb_shared_hwtstamps hwtstamps; 59229 unsigned int gso_type; 59230 u32 tskey; 59231+ __be32 ip6_frag_id; 59232 59233 /* 59234 * Warning : all fields before dataref are cleared in __alloc_skb() 59235diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h 59236index e7b997d6f..8bec8c190 100644 59237--- a/include/linux/sunrpc/xprt.h 59238+++ b/include/linux/sunrpc/xprt.h 59239@@ -156,6 +156,7 @@ struct rpc_xprt_ops { 59240 void (*inject_disconnect)(struct rpc_xprt *xprt); 59241 int (*bc_setup)(struct rpc_xprt *xprt, 59242 unsigned int min_reqs); 59243+ struct svc_xprt*(*bc_get_xprt)(struct svc_serv *serv, struct net *net); 59244 size_t (*bc_maxpayload)(struct rpc_xprt *xprt); 59245 unsigned int (*bc_num_slots)(struct rpc_xprt *xprt); 59246 void (*bc_free_rqst)(struct rpc_rqst *rqst); 59247diff --git a/include/linux/types.h b/include/linux/types.h 59248index a14797760..2c35430e2 100644 59249--- a/include/linux/types.h 59250+++ b/include/linux/types.h 59251@@ -227,5 +227,8 @@ typedef void (*swap_func_t)(void *a, void *b, int size); 59252 typedef int (*cmp_r_func_t)(const void *a, const void *b, const void *priv); 59253 typedef int (*cmp_func_t)(const void *a, const void *b); 59254 59255+/* clocksource cycle base type */ 59256+typedef u64 cycle_t; 59257+ 59258 #endif /* __ASSEMBLY__ */ 59259 #endif /* _LINUX_TYPES_H */ 59260diff --git a/include/linux/usb.h b/include/linux/usb.h 59261index d6a41841b..de3232ee5 100644 59262--- a/include/linux/usb.h 59263+++ b/include/linux/usb.h 59264@@ -2019,8 +2019,11 @@ static inline int usb_translate_errors(int error_code) 59265 #define USB_DEVICE_REMOVE 0x0002 59266 #define USB_BUS_ADD 0x0003 59267 #define USB_BUS_REMOVE 0x0004 59268+#define USB_GADGET_ADD 0x0005 59269+#define USB_GADGET_REMOVE 0x0006 59270 extern void usb_register_notify(struct notifier_block *nb); 59271 extern void usb_unregister_notify(struct notifier_block *nb); 59272+extern void usb_notify_online_status(bool online); 59273 59274 /* debugfs stuff */ 59275 extern struct dentry *usb_debug_root; 59276diff --git a/include/uapi/linux/i2c-dev.h b/include/uapi/linux/i2c-dev.h 59277index 85f8047af..3f50287f3 100644 59278--- a/include/uapi/linux/i2c-dev.h 59279+++ b/include/uapi/linux/i2c-dev.h 59280@@ -52,6 +52,8 @@ 59281 #define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ 59282 #define I2C_SMBUS 0x0720 /* SMBus transfer */ 59283 59284+#define I2C_CONFIG_MUL_REG 0x070c 59285+#define I2C_CONFIG_FLAGS 0x070d 59286 59287 /* This is the structure as used in the I2C_SMBUS ioctl call */ 59288 struct i2c_smbus_ioctl_data { 59289diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h 59290index f71a1751c..f85deb485 100644 59291--- a/include/uapi/linux/i2c.h 59292+++ b/include/uapi/linux/i2c.h 59293@@ -22,7 +22,7 @@ 59294 MA 02110-1301 USA. */ 59295 /* ------------------------------------------------------------------------- */ 59296 59297-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 59298+/* With some changes from Kyosti Malkki <kmalkki@cc.hut.fi> and 59299 Frodo Looijaard <frodol@dds.nl> */ 59300 59301 #ifndef _UAPI_LINUX_I2C_H 59302@@ -81,8 +81,14 @@ struct i2c_msg { 59303 #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ 59304 #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */ 59305 #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */ 59306+#define I2C_M_16BIT_REG 0x0002 /* indicate reg bit-width is 16bit */ 59307+#define I2C_M_16BIT_DATA 0x0008 /* indicate data bit-width is 16bit */ 59308+#define I2C_M_DMA 0x0004 /* indicate use dma mode */ 59309 __u16 len; /* msg length */ 59310 __u8 *buf; /* pointer to msg data */ 59311+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC) 59312+ __u8 *highmem_buf; 59313+#endif 59314 }; 59315 59316 /* To determine what functionality is present */ 59317diff --git a/include/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h 59318index a5773899f..89a461a27 100644 59319--- a/include/uapi/linux/msdos_fs.h 59320+++ b/include/uapi/linux/msdos_fs.h 59321@@ -93,7 +93,23 @@ struct __fat_dirent { 59322 unsigned short d_reclen; 59323 char d_name[256]; /* We must not include limits.h! */ 59324 }; 59325+#ifdef CONFIG_HISI_MC 59326+struct fat_direntall { 59327+ unsigned long d_ino; 59328+ unsigned long d_off; 59329+ unsigned char d_type; 59330+ u64 d_size; 59331+ char d_createtime[8]; 59332+ unsigned short d_reclen; 59333+ char d_name[1]; 59334+}; 59335 59336+struct fat_direntall_buf { 59337+ int d_count; 59338+ int d_usecount; 59339+ struct fat_direntall direntall; 59340+}; 59341+#endif 59342 /* 59343 * ioctl commands 59344 */ 59345@@ -104,7 +120,9 @@ struct __fat_dirent { 59346 #define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32) 59347 /*Android kernel has used 0x12, so we use 0x13*/ 59348 #define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32) 59349- 59350+#ifdef CONFIG_HISI_MC 59351+#define VFAT_IOCTL_READDIR_ALL _IOR('r', 0x14, struct fat_direntall_buf) 59352+#endif 59353 struct fat_boot_sector { 59354 __u8 ignored[3]; /* Boot strap short or near jump */ 59355 __u8 system_id[8]; /* Name - can be used to special case 59356diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h 59357index 652f169a0..8addd4f94 100644 59358--- a/include/uapi/linux/usb/g_uvc.h 59359+++ b/include/uapi/linux/usb/g_uvc.h 59360@@ -12,6 +12,7 @@ 59361 #include <linux/types.h> 59362 #include <linux/usb/ch9.h> 59363 59364+#define UVC_SG_REQ 59365 #define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) 59366 #define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0) 59367 #define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1) 59368diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h 59369index bfdae12cd..2d33002e9 100644 59370--- a/include/uapi/linux/usb/video.h 59371+++ b/include/uapi/linux/usb/video.h 59372@@ -342,6 +342,8 @@ struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) { \ 59373 __u8 iExtension; \ 59374 } __attribute__ ((packed)) 59375 59376+DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(1,2); 59377+ 59378 /* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */ 59379 struct uvc_control_endpoint_descriptor { 59380 __u8 bLength; 59381@@ -567,5 +569,63 @@ struct UVC_FRAME_MJPEG(n) { \ 59382 __le32 dwFrameInterval[n]; \ 59383 } __attribute__ ((packed)) 59384 59385+/* 3.1.1 Frame Based Payload Video Format Descriptor */ 59386+struct uvc_frame_based_format_desc { 59387+ __u8 bLength; 59388+ __u8 bDescriptorType; 59389+ __u8 bDescriptorSubType; 59390+ __u8 bFormatIndex; 59391+ __u8 bNumFrameDescriptors; 59392+ __u8 guidFormat[16]; 59393+ __u8 bBitsPerPixel; 59394+ __u8 bDefaultFrameIndex; 59395+ __u8 bAspectRatioX; 59396+ __u8 bAspectRatioY; 59397+ __u8 bmInterfaceFlags; 59398+ __u8 bCopyProtect; 59399+ __u8 bVariableSize; 59400+} __attribute__((__packed__)); 59401+ 59402+#define UVC_DT_FRAME_BASED_FORMAT_SIZE 28 59403+ 59404+/* 3.1.2 Frame Based Payload Frame Descriptor */ 59405+struct uvc_frame_based_frame_desc { 59406+ __u8 bLength; 59407+ __u8 bDescriptorType; 59408+ __u8 bDescriptorSubType; 59409+ __u8 bFrameIndex; 59410+ __u8 bmCapabilities; 59411+ __u16 wWidth; 59412+ __u16 wHeight; 59413+ __u32 dwMinBitRate; 59414+ __u32 dwMaxBitRate; 59415+ __u32 dwDefaultFrameInterval; 59416+ __u8 bFrameIntervalType; 59417+ __u32 dwBytesPerLine; 59418+ __u32 dwFrameInterval[]; 59419+} __attribute__((__packed__)); 59420+ 59421+#define UVC_DT_FRAME_BASED_FRAME_SIZE(n) (26+4*(n)) 59422+ 59423+#define UVC_FRAME_BASED(n) \ 59424+ uvc_frame_based_desc##n 59425+ 59426+#define DECLARE_UVC_FRAME_BASED(n) \ 59427+struct UVC_FRAME_BASED(n) { \ 59428+ __u8 bLength; \ 59429+ __u8 bDescriptorType; \ 59430+ __u8 bDescriptorSubType; \ 59431+ __u8 bFrameIndex; \ 59432+ __u8 bmCapabilities; \ 59433+ __u16 wWidth; \ 59434+ __u16 wHeight; \ 59435+ __u32 dwMinBitRate; \ 59436+ __u32 dwMaxBitRate; \ 59437+ __u32 dwDefaultFrameInterval; \ 59438+ __u8 bFrameIntervalType; \ 59439+ __u32 dwBytesPerLine; \ 59440+ __u32 dwFrameInterval[n]; \ 59441+} __attribute__ ((packed)) 59442+ 59443 #endif /* __LINUX_USB_VIDEO_H */ 59444 59445diff --git a/init/main.c b/init/main.c 59446index 63cdf49f7..4263c0bb3 100644 59447--- a/init/main.c 59448+++ b/init/main.c 59449@@ -842,6 +842,34 @@ static void __init mm_init(void) 59450 pti_init(); 59451 } 59452 59453+#ifndef HISI_CHIP_OEM 59454+static char * __initdata hi3516_usb_mode; 59455+static int __init hi3516_usb_mode_setup(char *str) 59456+{ 59457+ hi3516_usb_mode = str; 59458+ return 1; 59459+} 59460+__setup("Hi3516usbmode=", hi3516_usb_mode_setup); 59461+ 59462+/* 59463+ * Set up device tree oem feature 59464+ */ 59465+static void __init _dtb_hisi_oem(void) 59466+{ 59467+ if (hi3516_usb_mode != NULL && strcmp(hi3516_usb_mode, "host") == 0) { 59468+ pr_notice("set usb mode to %s \n",hi3516_usb_mode); 59469+ 59470+ struct device_node *root_node, *child_node; 59471+ root_node = of_find_node_by_name(NULL, "soc"); 59472+ if (root_node) 59473+ child_node = of_find_node_by_name(root_node, "xhci_0"); 59474+ if (child_node) 59475+ child_node->sibling = child_node->sibling->sibling; 59476+ } 59477+ 59478+} 59479+#endif 59480+ 59481 void __init __weak arch_call_rest_init(void) 59482 { 59483 rest_init(); 59484@@ -895,6 +923,10 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) 59485 parse_args("Setting extra init args", extra_init_args, 59486 NULL, 0, -1, -1, NULL, set_init_arg); 59487 59488+#ifndef HISI_CHIP_OEM 59489+ _dtb_hisi_oem(); 59490+#endif 59491+ 59492 /* 59493 * These use large bootmem allocations and must precede 59494 * kmem_cache_init() 59495diff --git a/kernel/cpu.c b/kernel/cpu.c 59496index 67c22941b..dfbd3887e 100644 59497--- a/kernel/cpu.c 59498+++ b/kernel/cpu.c 59499@@ -331,6 +331,19 @@ void lockdep_assert_cpus_held(void) 59500 percpu_rwsem_assert_held(&cpu_hotplug_lock); 59501 } 59502 59503+static RAW_NOTIFIER_HEAD(cpu_chain); 59504+ 59505+/* Need to know about CPUs going up/down? */ 59506+int hi_register_cpu_notifier(struct notifier_block *nb) 59507+{ 59508+ int ret; 59509+ cpu_maps_update_begin(); 59510+ ret = raw_notifier_chain_register(&cpu_chain, nb); 59511+ cpu_maps_update_done(); 59512+ return ret; 59513+} 59514+EXPORT_SYMBOL(hi_register_cpu_notifier); 59515+ 59516 static void lockdep_acquire_cpus_lock(void) 59517 { 59518 rwsem_acquire(&cpu_hotplug_lock.dep_map, 0, 0, _THIS_IP_); 59519diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c 59520index 16b95ff12..90f379978 100644 59521--- a/kernel/dma/contiguous.c 59522+++ b/kernel/dma/contiguous.c 59523@@ -164,6 +164,11 @@ void __init dma_pernuma_cma_reserve(void) 59524 * has been activated and all other subsystems have already allocated/reserved 59525 * memory. 59526 */ 59527+#ifdef CONFIG_ARCH_HISI_BVT 59528+#ifdef CONFIG_64BIT 59529+extern __init int hisi_declare_heap_memory(void); 59530+#endif 59531+#endif 59532 void __init dma_contiguous_reserve(phys_addr_t limit) 59533 { 59534 phys_addr_t selected_size = 0; 59535@@ -173,6 +178,11 @@ void __init dma_contiguous_reserve(phys_addr_t limit) 59536 59537 pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit); 59538 59539+#ifdef CONFIG_ARCH_HISI_BVT 59540+#ifdef CONFIG_64BIT 59541+ hisi_declare_heap_memory(); 59542+#endif 59543+#endif 59544 if (size_cmdline != -1) { 59545 selected_size = size_cmdline; 59546 selected_base = base_cmdline; 59547@@ -262,6 +272,7 @@ struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, 59548 59549 return cma_alloc(dev_get_cma_area(dev), count, align, no_warn); 59550 } 59551+EXPORT_SYMBOL(dma_alloc_from_contiguous); 59552 59553 /** 59554 * dma_release_from_contiguous() - release allocated pages 59555@@ -278,6 +289,12 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, 59556 { 59557 return cma_release(dev_get_cma_area(dev), pages, count); 59558 } 59559+EXPORT_SYMBOL(dma_release_from_contiguous); 59560+ 59561+#ifdef CONFIG_ARM64 59562+#include <asm/cacheflush.h> 59563+EXPORT_SYMBOL(__flush_dcache_area); 59564+#endif 59565 59566 static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp) 59567 { 59568diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c 59569index 85351a12c..e9e070a36 100644 59570--- a/kernel/printk/printk.c 59571+++ b/kernel/printk/printk.c 59572@@ -1475,7 +1475,7 @@ static int syslog_print(char __user *buf, int size) 59573 char *text; 59574 int len = 0; 59575 59576- text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); 59577+ text = kzalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); 59578 if (!text) 59579 return -ENOMEM; 59580 59581diff --git a/kernel/relay.c b/kernel/relay.c 59582index b08d936d5..1a62975c6 100644 59583--- a/kernel/relay.c 59584+++ b/kernel/relay.c 59585@@ -581,7 +581,8 @@ struct rchan *relay_open(const char *base_filename, 59586 if (!chan) 59587 return NULL; 59588 59589- chan->buf = alloc_percpu(struct rchan_buf *); 59590+ chan->buf = alloc_percpu_gfp(struct rchan_buf *, 59591+ GFP_KERNEL | __GFP_NOWARN); 59592 if (!chan->buf) { 59593 kfree(chan); 59594 return NULL; 59595diff --git a/mm/init-mm.c b/mm/init-mm.c 59596index 153162669..6382b3b6b 100644 59597--- a/mm/init-mm.c 59598+++ b/mm/init-mm.c 59599@@ -40,3 +40,4 @@ struct mm_struct init_mm = { 59600 .cpu_bitmap = CPU_BITS_NONE, 59601 INIT_MM_CONTEXT(init_mm) 59602 }; 59603+EXPORT_SYMBOL(init_mm); 59604diff --git a/mm/madvise.c b/mm/madvise.c 59605index 23b48a004..2e09438d6 100644 59606--- a/mm/madvise.c 59607+++ b/mm/madvise.c 59608@@ -30,6 +30,7 @@ 59609 #include <linux/swapops.h> 59610 #include <linux/shmem_fs.h> 59611 #include <linux/mmu_notifier.h> 59612+#include <linux/sched/mm.h> 59613 59614 #include <asm/tlb.h> 59615 59616diff --git a/mm/mincore.c b/mm/mincore.c 59617index 02db1a834..9a2c1208d 100644 59618--- a/mm/mincore.c 59619+++ b/mm/mincore.c 59620@@ -42,57 +42,15 @@ static int mincore_hugetlb(pte_t *pte, unsigned long hmask, unsigned long addr, 59621 return 0; 59622 } 59623 59624-/* 59625- * Later we can get more picky about what "in core" means precisely. 59626- * For now, simply check to see if the page is in the page cache, 59627- * and is up to date; i.e. that no page-in operation would be required 59628- * at this time if an application were to map and access this page. 59629- */ 59630-static unsigned char mincore_page(struct address_space *mapping, pgoff_t index) 59631-{ 59632- unsigned char present = 0; 59633- struct page *page; 59634- 59635- /* 59636- * When tmpfs swaps out a page from a file, any process mapping that 59637- * file will not get a swp_entry_t in its pte, but rather it is like 59638- * any other file mapping (ie. marked !present and faulted in with 59639- * tmpfs's .fault). So swapped out tmpfs mappings are tested here. 59640- */ 59641- page = find_get_incore_page(mapping, index); 59642- if (page) { 59643- present = PageUptodate(page); 59644- put_page(page); 59645- } 59646- 59647- return present; 59648-} 59649- 59650-static int __mincore_unmapped_range(unsigned long addr, unsigned long end, 59651- struct vm_area_struct *vma, unsigned char *vec) 59652-{ 59653- unsigned long nr = (end - addr) >> PAGE_SHIFT; 59654- int i; 59655- 59656- if (vma->vm_file) { 59657- pgoff_t pgoff; 59658- 59659- pgoff = linear_page_index(vma, addr); 59660- for (i = 0; i < nr; i++, pgoff++) 59661- vec[i] = mincore_page(vma->vm_file->f_mapping, pgoff); 59662- } else { 59663- for (i = 0; i < nr; i++) 59664- vec[i] = 0; 59665- } 59666- return nr; 59667-} 59668- 59669 static int mincore_unmapped_range(unsigned long addr, unsigned long end, 59670 __always_unused int depth, 59671 struct mm_walk *walk) 59672 { 59673- walk->private += __mincore_unmapped_range(addr, end, 59674- walk->vma, walk->private); 59675+ unsigned char *vec = walk->private; 59676+ unsigned long nr = (end - addr) >> PAGE_SHIFT; 59677+ 59678+ memset(vec, 0, nr); 59679+ walk->private += nr; 59680 return 0; 59681 } 59682 59683@@ -112,8 +70,9 @@ static int mincore_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 59684 goto out; 59685 } 59686 59687+ /* We'll consider a THP page under construction to be there */ 59688 if (pmd_trans_unstable(pmd)) { 59689- __mincore_unmapped_range(addr, end, vma, vec); 59690+ memset(vec, 1, nr); 59691 goto out; 59692 } 59693 59694@@ -122,28 +81,17 @@ static int mincore_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 59695 pte_t pte = *ptep; 59696 59697 if (pte_none(pte)) 59698- __mincore_unmapped_range(addr, addr + PAGE_SIZE, 59699- vma, vec); 59700+ *vec = 0; 59701 else if (pte_present(pte)) 59702 *vec = 1; 59703 else { /* pte is a swap entry */ 59704 swp_entry_t entry = pte_to_swp_entry(pte); 59705 59706- if (non_swap_entry(entry)) { 59707- /* 59708- * migration or hwpoison entries are always 59709- * uptodate 59710- */ 59711- *vec = 1; 59712- } else { 59713-#ifdef CONFIG_SWAP 59714- *vec = mincore_page(swap_address_space(entry), 59715- swp_offset(entry)); 59716-#else 59717- WARN_ON(1); 59718- *vec = 1; 59719-#endif 59720- } 59721+ /* 59722+ * migration or hwpoison entries are always 59723+ * uptodate 59724+ */ 59725+ *vec = !!non_swap_entry(entry); 59726 } 59727 vec++; 59728 } 59729diff --git a/mm/vmalloc.c b/mm/vmalloc.c 59730index f98801428..1a565eaad 100644 59731--- a/mm/vmalloc.c 59732+++ b/mm/vmalloc.c 59733@@ -326,6 +326,7 @@ int map_kernel_range(unsigned long start, unsigned long size, pgprot_t prot, 59734 flush_cache_vmap(start, start + size); 59735 return ret; 59736 } 59737+EXPORT_SYMBOL(map_kernel_range); 59738 59739 int is_vmalloc_or_module_addr(const void *x) 59740 { 59741@@ -2097,6 +2098,7 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, 59742 return __get_vm_area_node(size, 1, flags, start, end, NUMA_NO_NODE, 59743 GFP_KERNEL, caller); 59744 } 59745+EXPORT_SYMBOL(__get_vm_area_caller); 59746 59747 /** 59748 * get_vm_area - reserve a contiguous kernel virtual area 59749diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c 59750index 9f52145bb..6baf1f429 100644 59751--- a/net/bluetooth/hci_event.c 59752+++ b/net/bluetooth/hci_event.c 59753@@ -5593,7 +5593,8 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 59754 /* If the report will trigger a SCAN_REQ store it for 59755 * later merging. 59756 */ 59757- if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 59758+ if (!ext_adv && (type == LE_ADV_IND || 59759+ type == LE_ADV_SCAN_IND)) { 59760 store_pending_adv_report(hdev, bdaddr, bdaddr_type, 59761 rssi, flags, data, len); 59762 return; 59763diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c 59764index 19ef4577b..bebc833f4 100644 59765--- a/net/ipv4/tcp_output.c 59766+++ b/net/ipv4/tcp_output.c 59767@@ -1561,6 +1561,11 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue, 59768 return -ENOMEM; 59769 } 59770 59771+ if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) { 59772+ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); 59773+ return -ENOMEM; 59774+ } 59775+ 59776 if (skb_unclone(skb, gfp)) 59777 return -ENOMEM; 59778 59779diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c 59780index fae632da1..d6b8d6f61 100644 59781--- a/net/sunrpc/auth_gss/gss_mech_switch.c 59782+++ b/net/sunrpc/auth_gss/gss_mech_switch.c 59783@@ -34,11 +34,14 @@ gss_mech_free(struct gss_api_mech *gm) 59784 { 59785 struct pf_desc *pf; 59786 int i; 59787+ struct auth_domain *test; 59788 59789 for (i = 0; i < gm->gm_pf_num; i++) { 59790 pf = &gm->gm_pfs[i]; 59791- if (pf->domain) 59792- auth_domain_put(pf->domain); 59793+ test = auth_domain_find(pf->auth_domain_name); 59794+ if (test != NULL) { 59795+ test->flavour->domain_release(test); 59796+ } 59797 kfree(pf->auth_domain_name); 59798 pf->auth_domain_name = NULL; 59799 } 59800diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c 59801index d38788cd9..f526b67d5 100644 59802--- a/net/sunrpc/svc.c 59803+++ b/net/sunrpc/svc.c 59804@@ -1539,15 +1539,22 @@ int 59805 bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, 59806 struct svc_rqst *rqstp) 59807 { 59808+ struct net *net = req->rq_xprt->xprt_net; 59809 struct kvec *argv = &rqstp->rq_arg.head[0]; 59810 struct kvec *resv = &rqstp->rq_res.head[0]; 59811 struct rpc_task *task; 59812+ struct svc_xprt *s_xprt; 59813 int proc_error; 59814 int error; 59815 59816 dprintk("svc: %s(%p)\n", __func__, req); 59817 59818+ s_xprt = req->rq_xprt->ops->bc_get_xprt(serv, net); 59819+ if (!s_xprt) 59820+ goto proc_error; 59821+ 59822 /* Build the svc_rqst used by the common processing routine */ 59823+ rqstp->rq_xprt = s_xprt; 59824 rqstp->rq_xid = req->rq_xid; 59825 rqstp->rq_prot = req->rq_xprt->prot; 59826 rqstp->rq_server = serv; 59827@@ -1606,6 +1613,12 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, 59828 out: 59829 dprintk("svc: %s(), error=%d\n", __func__, error); 59830 return error; 59831+ 59832+proc_error: 59833+ /* Processing error: drop the request */ 59834+ xprt_free_bc_request(req); 59835+ error = -EINVAL; 59836+ goto out; 59837 } 59838 EXPORT_SYMBOL_GPL(bc_svc_process); 59839 #endif /* CONFIG_SUNRPC_BACKCHANNEL */ 59840diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c 59841index c92c1aac2..9d1a966ba 100644 59842--- a/net/sunrpc/xprtrdma/backchannel.c 59843+++ b/net/sunrpc/xprtrdma/backchannel.c 59844@@ -35,6 +35,11 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs) 59845 return 0; 59846 } 59847 59848+struct svc_xprt *xprt_rdma_bc_get_xprt(struct svc_serv *serv, struct net *net) 59849+{ 59850+ return svc_find_xprt(serv, "rdma-bc", net, AF_UNSPEC, 0); 59851+} 59852+ 59853 /** 59854 * xprt_rdma_bc_maxpayload - Return maximum backchannel message size 59855 * @xprt: transport 59856diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c 59857index 8fb047888..5ea56bc2a 100644 59858--- a/net/wireless/nl80211.c 59859+++ b/net/wireless/nl80211.c 59860@@ -2121,7 +2121,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, 59861 59862 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); 59863 if (!hdr) 59864- return -ENOBUFS; 59865+ goto nla_put_failure; 59866 59867 if (WARN_ON(!state)) 59868 return -EINVAL; 59869diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c 59870index 73df23570..9f959d7b5 100644 59871--- a/net/wireless/wext-sme.c 59872+++ b/net/wireless/wext-sme.c 59873@@ -201,8 +201,8 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, 59874 struct iw_request_info *info, 59875 struct iw_point *data, char *ssid) 59876 { 59877- struct wireless_dev *wdev = dev->ieee80211_ptr; 59878 int ret = 0; 59879+ struct wireless_dev *wdev = dev->ieee80211_ptr; 59880 59881 /* call only for station! */ 59882 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) 59883diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib 59884index 941337088..bbdfd6a1b 100644 59885--- a/scripts/Makefile.lib 59886+++ b/scripts/Makefile.lib 59887@@ -210,7 +210,9 @@ cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 59888 59889 ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) 59890 59891-DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes 59892+DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes \ 59893+ $(objtree)/include/generated \ 59894+ $(srctree)/include/dt-bindings 59895 59896 dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ 59897 $(addprefix -I,$(DTC_INCLUDE)) \ 59898@@ -316,7 +318,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE 59899 $(call if_changed,dt_S_dtb) 59900 59901 quiet_cmd_dtc = DTC $@ 59902-cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ 59903+cmd_dtc = mkdir -p $(dir $(dtc-tmp)); $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ 59904 $(DTC) -O $(patsubst .%,%,$(suffix $@)) -o $@ -b 0 \ 59905 $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ 59906 -d $(depfile).dtc.tmp $(dtc-tmp) ; \ 59907diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c 59908index 17cb6890d..af3392da3 100644 59909--- a/scripts/dtc/checks.c 59910+++ b/scripts/dtc/checks.c 59911@@ -819,8 +819,8 @@ static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node * 59912 59913 node->bus = &pci_bus; 59914 59915- if (!strprefixeq(node->name, node->basenamelen, "pci") && 59916- !strprefixeq(node->name, node->basenamelen, "pcie")) 59917+ if (!strprefixeq(node->name, 3, "pci") && 59918+ !strprefixeq(node->name, 4, "pcie")) 59919 FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); 59920 59921 prop = get_property(node, "ranges"); 59922diff --git a/sound/core/control.c b/sound/core/control.c 59923index 3b44378b9..b94592b46 100644 59924--- a/sound/core/control.c 59925+++ b/sound/core/control.c 59926@@ -1443,7 +1443,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, 59927 return -ENOMEM; 59928 59929 /* Check the number of elements for this userspace control. */ 59930- count = info->owner; 59931+ count = info->count; 59932 if (count == 0) 59933 count = 1; 59934 59935diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh 59936index 6fad54c7e..9d1302bb8 100755 59937--- a/tools/testing/selftests/net/fib_tests.sh 59938+++ b/tools/testing/selftests/net/fib_tests.sh 59939@@ -636,6 +636,20 @@ fib_suppress_test() 59940 cleanup 59941 } 59942 59943+fib_suppress_test() 59944+{ 59945+ $IP link add dummy1 type dummy 59946+ $IP link set dummy1 up 59947+ $IP -6 route add default dev dummy1 59948+ $IP -6 rule add table main suppress_prefixlength 0 59949+ ping -f -c 1000 -W 1 1234::1 || true 59950+ $IP -6 rule del table main suppress_prefixlength 0 59951+ $IP link del dummy1 59952+ 59953+ # If we got here without crashing, we're good. 59954+ return 0 59955+} 59956+ 59957 ################################################################################ 59958 # Tests on route add and replace 59959 59960