bmips: add new target
This target has full device tree support, thus reducing the number of patches needed for bcm63xx, in which there's a patch for every board. The intention is to start with a minimal amount of downstream patches and start upstreaming all of them. Current status: - Enabling EHCI/OHCI on BCM6358 causes a kernel panic. - BCM63268 lacks Timer Clocks/Reset support. - No PCI/PCIe drivers. - No ethernet drivers. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> Acked-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
This commit is contained in:
		
							
								
								
									
										23
									
								
								target/linux/bmips/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								target/linux/bmips/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| ARCH:=mips | ||||
| CPU_TYPE:=mips32 | ||||
| BOARD:=bmips | ||||
| BOARDNAME:=Broadcom BMIPS | ||||
| SUBTARGETS:=generic nand | ||||
| FEATURES:=gpio source-only squashfs usb | ||||
|  | ||||
| KERNEL_PATCHVER:=5.10 | ||||
|  | ||||
| define Target/Description | ||||
| 	Build firmware images for BCM33xx cable modem chips, | ||||
| 	BCM63xx DSL chips and BCM7xxx set-top box chips. | ||||
| endef | ||||
|  | ||||
| include $(INCLUDE_DIR)/target.mk | ||||
|  | ||||
| DEFAULT_PACKAGES += kmod-gpio-button-hotplug | ||||
|  | ||||
| $(eval $(call BuildTarget)) | ||||
							
								
								
									
										17
									
								
								target/linux/bmips/base-files/etc/board.d/01_leds
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								target/linux/bmips/base-files/etc/board.d/01_leds
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #!/bin/sh | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| . /lib/functions/leds.sh | ||||
| . /lib/functions/uci-defaults.sh | ||||
|  | ||||
| board_config_update | ||||
|  | ||||
| led_usb="$(get_dt_led usb)" | ||||
| [ -n "$led_usb" ] && ucidef_set_led_usbdev "usb" "usb" "$led_usb" "1-1" | ||||
|  | ||||
| led_usb2="$(get_dt_led usb2)" | ||||
| [ -n "$led_usb2" ] && ucidef_set_led_usbdev "usb2" "usb2" "$led_usb2" "2-1" | ||||
|  | ||||
| board_config_flush | ||||
|  | ||||
| exit 0 | ||||
							
								
								
									
										13
									
								
								target/linux/bmips/base-files/etc/uci-defaults/09_fix_crc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								target/linux/bmips/base-files/etc/uci-defaults/09_fix_crc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| . /lib/functions.sh | ||||
|  | ||||
| case "$(board_name)" in | ||||
| 	comtrend,ar-5315u|\ | ||||
| 	comtrend,ar-5387un|\ | ||||
| 	comtrend,vr-3025u) | ||||
| 		mtd fixtrx firmware | ||||
| 		;; | ||||
| esac | ||||
|  | ||||
| exit 0 | ||||
							
								
								
									
										59
									
								
								target/linux/bmips/base-files/lib/upgrade/platform.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								target/linux/bmips/base-files/lib/upgrade/platform.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| PART_NAME=firmware | ||||
| REQUIRE_IMAGE_METADATA=1 | ||||
|  | ||||
| platform_check_image() { | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| cfe_jffs2_nand_upgrade() { | ||||
| 	local tar_file="$1" | ||||
| 	local kernel_mtd="$(find_mtd_index $CI_KERNPART)" | ||||
|  | ||||
| 	if [ -z "$kernel_mtd" ]; then | ||||
| 		echo "$CI_KERNPART partition not found" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') | ||||
| 	board_dir=${board_dir%/} | ||||
|  | ||||
| 	local kernel_length=$(tar xf $tar_file ${board_dir}/kernel -O | wc -c 2> /dev/null) | ||||
| 	local rootfs_length=$(tar xf $tar_file ${board_dir}/root -O | wc -c 2> /dev/null) | ||||
|  | ||||
| 	if [ "$kernel_length" = 0 ]; then | ||||
| 		echo "kernel cannot be empty" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	flash_erase -j /dev/mtd${kernel_mtd} 0 0 | ||||
| 	tar xf $tar_file ${board_dir}/kernel -O | nandwrite /dev/mtd${kernel_mtd} - | ||||
|  | ||||
| 	local rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)" | ||||
|  | ||||
| 	nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "0" "0" | ||||
|  | ||||
| 	local ubidev="$( nand_find_ubi "$CI_UBIPART" )" | ||||
|  | ||||
| 	local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)" | ||||
| 	tar xf $tar_file ${board_dir}/root -O | \ | ||||
| 		ubiupdatevol /dev/$root_ubivol -s $rootfs_length - | ||||
|  | ||||
| 	nand_do_upgrade_success | ||||
| } | ||||
|  | ||||
| platform_do_upgrade() { | ||||
| 	case "$(board_name)" in | ||||
| 		comtrend,ar-5315u|\ | ||||
| 		comtrend,ar-5387un|\ | ||||
| 		comtrend,vr-3025u|\ | ||||
| 		huawei,hg556a-b) | ||||
| 			default_do_upgrade "$1" | ||||
| 			;; | ||||
| 		comtrend,vr-3032u|\ | ||||
| 		netgear,dgnd3700-v2) | ||||
| 			cfe_jffs2_nand_upgrade "$1" | ||||
| 			;; | ||||
| 	esac | ||||
| } | ||||
							
								
								
									
										264
									
								
								target/linux/bmips/config-5.10
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								target/linux/bmips/config-5.10
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,264 @@ | ||||
| CONFIG_ARCH_32BIT_OFF_T=y | ||||
| CONFIG_ARCH_HIBERNATION_POSSIBLE=y | ||||
| CONFIG_ARCH_MMAP_RND_BITS_MAX=15 | ||||
| CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 | ||||
| CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||||
| CONFIG_BCM6345_EXT_IRQ=y | ||||
| CONFIG_BCM6345_L1_IRQ=y | ||||
| CONFIG_BCM63XX_POWER=y | ||||
| CONFIG_BCM7038_L1_IRQ=y | ||||
| CONFIG_BCM7038_WDT=y | ||||
| CONFIG_BCM7120_L2_IRQ=y | ||||
| CONFIG_BLK_PM=y | ||||
| CONFIG_BMIPS_GENERIC=y | ||||
| CONFIG_BOARD_SCACHE=y | ||||
| CONFIG_BRCMSTB_L2_IRQ=y | ||||
| CONFIG_CEVT_R4K=y | ||||
| CONFIG_CLKDEV_LOOKUP=y | ||||
| CONFIG_CLK_BCM_63XX_GATE=y | ||||
| CONFIG_CLONE_BACKWARDS=y | ||||
| CONFIG_COMMON_CLK=y | ||||
| # CONFIG_COMMON_CLK_BOSTON is not set | ||||
| CONFIG_COMPAT_32BIT_TIME=y | ||||
| CONFIG_CPU_BIG_ENDIAN=y | ||||
| CONFIG_CPU_BMIPS=y | ||||
| CONFIG_CPU_BMIPS32_3300=y | ||||
| CONFIG_CPU_BMIPS4350=y | ||||
| CONFIG_CPU_BMIPS4380=y | ||||
| CONFIG_CPU_BMIPS5000=y | ||||
| CONFIG_CPU_GENERIC_DUMP_TLB=y | ||||
| CONFIG_CPU_HAS_PREFETCH=y | ||||
| CONFIG_CPU_HAS_RIXI=y | ||||
| CONFIG_CPU_HAS_SYNC=y | ||||
| # CONFIG_CPU_LITTLE_ENDIAN is not set | ||||
| CONFIG_CPU_MIPS32=y | ||||
| CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y | ||||
| CONFIG_CPU_NO_EFFICIENT_FFS=y | ||||
| CONFIG_CPU_R4K_CACHE_TLB=y | ||||
| CONFIG_CPU_RMAP=y | ||||
| CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y | ||||
| CONFIG_CPU_SUPPORTS_CPUFREQ=y | ||||
| CONFIG_CPU_SUPPORTS_HIGHMEM=y | ||||
| CONFIG_CRASH_DUMP=y | ||||
| CONFIG_CRC16=y | ||||
| CONFIG_CRYPTO_ACOMP2=y | ||||
| CONFIG_CRYPTO_AEAD=y | ||||
| CONFIG_CRYPTO_AEAD2=y | ||||
| CONFIG_CRYPTO_DEFLATE=y | ||||
| CONFIG_CRYPTO_HASH2=y | ||||
| CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 | ||||
| CONFIG_CRYPTO_LZO=y | ||||
| CONFIG_CRYPTO_MANAGER=y | ||||
| CONFIG_CRYPTO_MANAGER2=y | ||||
| CONFIG_CRYPTO_NULL2=y | ||||
| CONFIG_CRYPTO_RNG2=y | ||||
| CONFIG_CRYPTO_ZSTD=y | ||||
| CONFIG_CSRC_R4K=y | ||||
| CONFIG_DEBUG_INFO=y | ||||
| CONFIG_DMA_NONCOHERENT=y | ||||
| CONFIG_DTC=y | ||||
| # CONFIG_DT_BCM93384WVG is not set | ||||
| # CONFIG_DT_BCM93384WVG_VIPER is not set | ||||
| # CONFIG_DT_BCM96368MVWG is not set | ||||
| # CONFIG_DT_BCM97125CBMB is not set | ||||
| # CONFIG_DT_BCM97346DBSMB is not set | ||||
| # CONFIG_DT_BCM97358SVMB is not set | ||||
| # CONFIG_DT_BCM97360SVMB is not set | ||||
| # CONFIG_DT_BCM97362SVMB is not set | ||||
| # CONFIG_DT_BCM97420C is not set | ||||
| # CONFIG_DT_BCM97425SVMB is not set | ||||
| # CONFIG_DT_BCM97435SVMB is not set | ||||
| # CONFIG_DT_BCM9EJTAGPRB is not set | ||||
| # CONFIG_DT_COMTREND_VR3032U is not set | ||||
| # CONFIG_DT_NETGEAR_CVG834G is not set | ||||
| CONFIG_DT_NONE=y | ||||
| # CONFIG_DT_SFR_NEUFBOX4_SERCOMM is not set | ||||
| # CONFIG_DT_SFR_NEUFBOX6_SERCOMM is not set | ||||
| CONFIG_FIXED_PHY=y | ||||
| CONFIG_FW_LOADER_PAGED_BUF=y | ||||
| CONFIG_GENERIC_ATOMIC64=y | ||||
| CONFIG_GENERIC_CLOCKEVENTS=y | ||||
| CONFIG_GENERIC_CMOS_UPDATE=y | ||||
| CONFIG_GENERIC_CPU_AUTOPROBE=y | ||||
| CONFIG_GENERIC_GETTIMEOFDAY=y | ||||
| CONFIG_GENERIC_IOMAP=y | ||||
| CONFIG_GENERIC_IRQ_CHIP=y | ||||
| CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y | ||||
| CONFIG_GENERIC_IRQ_SHOW=y | ||||
| CONFIG_GENERIC_LIB_ASHLDI3=y | ||||
| CONFIG_GENERIC_LIB_ASHRDI3=y | ||||
| CONFIG_GENERIC_LIB_CMPDI2=y | ||||
| CONFIG_GENERIC_LIB_LSHRDI3=y | ||||
| CONFIG_GENERIC_LIB_UCMPDI2=y | ||||
| CONFIG_GENERIC_PCI_IOMAP=y | ||||
| CONFIG_GENERIC_PHY=y | ||||
| CONFIG_GENERIC_PINCONF=y | ||||
| CONFIG_GENERIC_PINCTRL_GROUPS=y | ||||
| CONFIG_GENERIC_PINMUX_FUNCTIONS=y | ||||
| CONFIG_GENERIC_SCHED_CLOCK=y | ||||
| CONFIG_GENERIC_SMP_IDLE_THREAD=y | ||||
| CONFIG_GENERIC_TIME_VSYSCALL=y | ||||
| CONFIG_GPIOLIB=y | ||||
| # CONFIG_GPIO_BRCMSTB is not set | ||||
| CONFIG_GPIO_GENERIC=y | ||||
| CONFIG_GPIO_GENERIC_PLATFORM=y | ||||
| CONFIG_HANDLE_DOMAIN_IRQ=y | ||||
| CONFIG_HARDIRQS_SW_RESEND=y | ||||
| CONFIG_HAS_DMA=y | ||||
| CONFIG_HAS_IOMEM=y | ||||
| CONFIG_HAS_IOPORT_MAP=y | ||||
| CONFIG_HW_RANDOM=y | ||||
| CONFIG_HW_RANDOM_BCM2835=y | ||||
| CONFIG_HZ=250 | ||||
| CONFIG_HZ_250=y | ||||
| CONFIG_HZ_PERIODIC=y | ||||
| CONFIG_INITRAMFS_SOURCE="" | ||||
| CONFIG_IRQCHIP=y | ||||
| CONFIG_IRQ_DOMAIN=y | ||||
| CONFIG_IRQ_FORCED_THREADING=y | ||||
| CONFIG_IRQ_MIPS_CPU=y | ||||
| CONFIG_IRQ_WORK=y | ||||
| CONFIG_LEDS_BCM6328=y | ||||
| CONFIG_LEDS_BCM6358=y | ||||
| CONFIG_LEDS_GPIO=y | ||||
| CONFIG_LIBFDT=y | ||||
| CONFIG_LLD_VERSION=0 | ||||
| CONFIG_LOCK_DEBUGGING_SUPPORT=y | ||||
| CONFIG_LZO_COMPRESS=y | ||||
| CONFIG_LZO_DECOMPRESS=y | ||||
| CONFIG_MDIO_BUS=y | ||||
| CONFIG_MDIO_DEVICE=y | ||||
| CONFIG_MEMFD_CREATE=y | ||||
| CONFIG_MFD_SYSCON=y | ||||
| CONFIG_MIGRATION=y | ||||
| CONFIG_MIPS=y | ||||
| CONFIG_MIPS_ASID_BITS=8 | ||||
| CONFIG_MIPS_ASID_SHIFT=0 | ||||
| CONFIG_MIPS_CBPF_JIT=y | ||||
| CONFIG_MIPS_CLOCK_VSYSCALL=y | ||||
| # CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set | ||||
| # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set | ||||
| CONFIG_MIPS_CMDLINE_FROM_DTB=y | ||||
| CONFIG_MIPS_CPU_SCACHE=y | ||||
| # CONFIG_MIPS_ELF_APPENDED_DTB is not set | ||||
| CONFIG_MIPS_EXTERNAL_TIMER=y | ||||
| CONFIG_MIPS_L1_CACHE_SHIFT=7 | ||||
| CONFIG_MIPS_L1_CACHE_SHIFT_6=y | ||||
| CONFIG_MIPS_L1_CACHE_SHIFT_7=y | ||||
| CONFIG_MIPS_LD_CAN_LINK_VDSO=y | ||||
| # CONFIG_MIPS_NO_APPENDED_DTB is not set | ||||
| CONFIG_MIPS_NR_CPU_NR_MAP=2 | ||||
| CONFIG_MIPS_O32_FP64_SUPPORT=y | ||||
| CONFIG_MIPS_RAW_APPENDED_DTB=y | ||||
| CONFIG_MODULES_USE_ELF_REL=y | ||||
| CONFIG_MODULE_FORCE_LOAD=y | ||||
| CONFIG_MODULE_FORCE_UNLOAD=y | ||||
| # CONFIG_MTD_BCM63XX_PARTS is not set | ||||
| CONFIG_MTD_CFI_ADV_OPTIONS=y | ||||
| CONFIG_MTD_CFI_BE_BYTE_SWAP=y | ||||
| # CONFIG_MTD_CFI_GEOMETRY is not set | ||||
| # CONFIG_MTD_CFI_NOSWAP is not set | ||||
| CONFIG_MTD_CFI_STAA=y | ||||
| CONFIG_MTD_JEDECPROBE=y | ||||
| # CONFIG_MTD_PARSER_IMAGETAG is not set | ||||
| CONFIG_NEED_DMA_MAP_STATE=y | ||||
| CONFIG_NET_FLOW_LIMIT=y | ||||
| CONFIG_NO_EXCEPT_FILL=y | ||||
| CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y | ||||
| CONFIG_NR_CPUS=2 | ||||
| CONFIG_OF=y | ||||
| CONFIG_OF_ADDRESS=y | ||||
| CONFIG_OF_EARLY_FLATTREE=y | ||||
| CONFIG_OF_FLATTREE=y | ||||
| CONFIG_OF_GPIO=y | ||||
| CONFIG_OF_IRQ=y | ||||
| CONFIG_OF_KOBJ=y | ||||
| CONFIG_OF_MDIO=y | ||||
| CONFIG_OF_NET=y | ||||
| CONFIG_PADATA=y | ||||
| CONFIG_PCI_DRIVERS_LEGACY=y | ||||
| CONFIG_PERF_USE_VMALLOC=y | ||||
| CONFIG_PGTABLE_LEVELS=2 | ||||
| CONFIG_PHYLIB=y | ||||
| CONFIG_PHYSICAL_START=0x80010000 | ||||
| CONFIG_PHY_BCM63XX_USBH=y | ||||
| # CONFIG_PHY_BRCM_SATA is not set | ||||
| CONFIG_PINCTRL=y | ||||
| CONFIG_PINCTRL_BCM6318=y | ||||
| CONFIG_PINCTRL_BCM63268=y | ||||
| CONFIG_PINCTRL_BCM6328=y | ||||
| CONFIG_PINCTRL_BCM6358=y | ||||
| CONFIG_PINCTRL_BCM6362=y | ||||
| CONFIG_PINCTRL_BCM6368=y | ||||
| CONFIG_PINCTRL_BCM63XX=y | ||||
| CONFIG_PM=y | ||||
| CONFIG_PM_CLK=y | ||||
| CONFIG_PM_GENERIC_DOMAINS=y | ||||
| CONFIG_PM_GENERIC_DOMAINS_OF=y | ||||
| CONFIG_POSIX_MQUEUE=y | ||||
| CONFIG_POSIX_MQUEUE_SYSCTL=y | ||||
| CONFIG_POWER_RESET=y | ||||
| CONFIG_POWER_RESET_SYSCON=y | ||||
| CONFIG_POWER_SUPPLY=y | ||||
| CONFIG_PROC_VMCORE=y | ||||
| CONFIG_QUEUED_RWLOCKS=y | ||||
| CONFIG_QUEUED_SPINLOCKS=y | ||||
| CONFIG_RATIONAL=y | ||||
| CONFIG_RCU_NEED_SEGCBLIST=y | ||||
| CONFIG_RCU_STALL_COMMON=y | ||||
| CONFIG_REGMAP=y | ||||
| CONFIG_REGMAP_MMIO=y | ||||
| CONFIG_RELAY=y | ||||
| CONFIG_RESET_BCM6345=y | ||||
| CONFIG_RESET_CONTROLLER=y | ||||
| CONFIG_RFS_ACCEL=y | ||||
| CONFIG_RPS=y | ||||
| CONFIG_SERIAL_BCM63XX=y | ||||
| CONFIG_SERIAL_BCM63XX_CONSOLE=y | ||||
| CONFIG_SERIAL_MCTRL_GPIO=y | ||||
| CONFIG_SGL_ALLOC=y | ||||
| CONFIG_SMP=y | ||||
| CONFIG_SMP_UP=y | ||||
| CONFIG_SOC_BCM63XX=y | ||||
| CONFIG_SPI=y | ||||
| CONFIG_SPI_BCM63XX=y | ||||
| CONFIG_SPI_BCM63XX_HSSPI=y | ||||
| CONFIG_SPI_MASTER=y | ||||
| CONFIG_SPI_MEM=y | ||||
| CONFIG_SRCU=y | ||||
| CONFIG_SWAP_IO_SPACE=y | ||||
| CONFIG_SWPHY=y | ||||
| CONFIG_SYNC_R4K=y | ||||
| CONFIG_SYSCTL_EXCEPTION_TRACE=y | ||||
| CONFIG_SYS_HAS_CPU_BMIPS=y | ||||
| CONFIG_SYS_HAS_CPU_BMIPS32_3300=y | ||||
| CONFIG_SYS_HAS_CPU_BMIPS4350=y | ||||
| CONFIG_SYS_HAS_CPU_BMIPS4380=y | ||||
| CONFIG_SYS_HAS_CPU_BMIPS5000=y | ||||
| CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y | ||||
| CONFIG_SYS_SUPPORTS_ARBIT_HZ=y | ||||
| CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y | ||||
| CONFIG_SYS_SUPPORTS_HIGHMEM=y | ||||
| CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y | ||||
| CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y | ||||
| CONFIG_SYS_SUPPORTS_SMP=y | ||||
| CONFIG_TARGET_ISA_REV=0 | ||||
| CONFIG_TICK_CPU_ACCOUNTING=y | ||||
| CONFIG_TREE_RCU=y | ||||
| CONFIG_TREE_SRCU=y | ||||
| CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y | ||||
| CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y | ||||
| CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y | ||||
| CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y | ||||
| CONFIG_USB_SUPPORT=y | ||||
| CONFIG_USE_OF=y | ||||
| CONFIG_VM_EVENT_COUNTERS=y | ||||
| CONFIG_WATCHDOG_CORE=y | ||||
| CONFIG_WATCHDOG_NOWAYOUT=y | ||||
| CONFIG_WEAK_ORDERING=y | ||||
| CONFIG_XPS=y | ||||
| CONFIG_XXHASH=y | ||||
| CONFIG_ZLIB_DEFLATE=y | ||||
| CONFIG_ZLIB_INFLATE=y | ||||
| CONFIG_ZSTD_COMPRESS=y | ||||
| CONFIG_ZSTD_DECOMPRESS=y | ||||
							
								
								
									
										193
									
								
								target/linux/bmips/dts/bcm63168-comtrend-vr-3032u.dts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								target/linux/bmips/dts/bcm63168-comtrend-vr-3032u.dts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "bcm63268.dtsi" | ||||
|  | ||||
| / { | ||||
| 	model = "Comtrend VR-3032u"; | ||||
| 	compatible = "comtrend,vr-3032u", "brcm,bcm63168", "brcm,bcm63268"; | ||||
|  | ||||
| 	aliases { | ||||
| 		led-boot = &led_power_green; | ||||
| 		led-failsafe = &led_power_green; | ||||
| 		led-running = &led_power_green; | ||||
| 		led-upgrade = &led_power_green; | ||||
|  | ||||
| 		led-usb = &led_usb_green; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0x00000000 0x04000000>; | ||||
| 	}; | ||||
|  | ||||
| 	keys { | ||||
| 		compatible = "gpio-keys-polled"; | ||||
| 		poll-interval = <20>; | ||||
|  | ||||
| 		reset { | ||||
| 			label = "reset"; | ||||
| 			gpios = <&pinctrl 33 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_RESTART>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
|  | ||||
| 		wps { | ||||
| 			label = "wps"; | ||||
| 			gpios = <&pinctrl 34 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_WPS_BUTTON>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ehci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &leds { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	brcm,serial-leds; | ||||
| 	brcm,serial-dat-low; | ||||
| 	brcm,serial-shift-inv; | ||||
|  | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pinctrl_serial_led>; | ||||
|  | ||||
| 	led@0 { | ||||
| 		/* GPHY0 Spd 0 */ | ||||
| 		reg = <0>; | ||||
| 		brcm,hardware-controlled; | ||||
| 		brcm,link-signal-sources = <0>; | ||||
| 	}; | ||||
|  | ||||
| 	led@1 { | ||||
| 		/* GPHY0 Spd 1 */ | ||||
| 		reg = <1>; | ||||
| 		brcm,hardware-controlled; | ||||
| 		brcm,link-signal-sources = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	led@2 { | ||||
| 		reg = <2>; | ||||
| 		active-low; | ||||
| 		label = "red:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led@3 { | ||||
| 		reg = <3>; | ||||
| 		active-low; | ||||
| 		label = "green:dsl"; | ||||
| 	}; | ||||
|  | ||||
| 	led_usb_green: led@4 { | ||||
| 		reg = <4>; | ||||
| 		active-low; | ||||
| 		label = "green:usb"; | ||||
| 	}; | ||||
|  | ||||
| 	led@7 { | ||||
| 		reg = <7>; | ||||
| 		active-low; | ||||
| 		label = "green:wps"; | ||||
| 	}; | ||||
|  | ||||
| 	led@8 { | ||||
| 		reg = <8>; | ||||
| 		active-low; | ||||
| 		label = "green:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led@9 { | ||||
| 		/* EPHY0 Act */ | ||||
| 		reg = <9>; | ||||
| 		brcm,hardware-controlled; | ||||
| 	}; | ||||
|  | ||||
| 	led@10 { | ||||
| 		/* EPHY1 Act */ | ||||
| 		reg = <10>; | ||||
| 		brcm,hardware-controlled; | ||||
| 	}; | ||||
|  | ||||
| 	led@11 { | ||||
| 		/* EPHY2 Act */ | ||||
| 		reg = <11>; | ||||
| 		brcm,hardware-controlled; | ||||
| 	}; | ||||
|  | ||||
| 	led@12 { | ||||
| 		/* GPHY0 Act */ | ||||
| 		reg = <12>; | ||||
| 		brcm,hardware-controlled; | ||||
| 	}; | ||||
|  | ||||
| 	led@13 { | ||||
| 		/* EPHY0 Spd */ | ||||
| 		reg = <13>; | ||||
| 		brcm,hardware-controlled; | ||||
| 	}; | ||||
|  | ||||
| 	led@14 { | ||||
| 		/* EPHY1 Spd */ | ||||
| 		reg = <14>; | ||||
| 		brcm,hardware-controlled; | ||||
| 	}; | ||||
|  | ||||
| 	led@15 { | ||||
| 		/* EPHY2 Spd */ | ||||
| 		reg = <15>; | ||||
| 		brcm,hardware-controlled; | ||||
| 	}; | ||||
|  | ||||
| 	led_power_green: led@20 { | ||||
| 		reg = <20>; | ||||
| 		active-low; | ||||
| 		label = "green:power"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &nflash { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	nandcs@0 { | ||||
| 		compatible = "brcm,nandcs"; | ||||
| 		#size-cells = <1>; | ||||
| 		#address-cells = <1>; | ||||
| 		reg = <0>; | ||||
| 		nand-ecc-step-size = <512>; | ||||
| 		nand-ecc-strength = <15>; | ||||
| 		nand-on-flash-bbt; | ||||
| 		brcm,nand-oob-sector-size = <64>; | ||||
|  | ||||
| 		partitions { | ||||
| 			compatible = "fixed-partitions"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
|  | ||||
| 			cferom: partition@0 { | ||||
| 				label = "cferom"; | ||||
| 				reg = <0x0000000 0x0020000>; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@20000 { | ||||
| 				compatible = "brcm,wfi-split"; | ||||
| 				label = "wfi"; | ||||
| 				reg = <0x0020000 0x7ac0000>; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ohci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usbh { | ||||
| 	status = "okay"; | ||||
| }; | ||||
							
								
								
									
										182
									
								
								target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,182 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "bcm6318.dtsi" | ||||
|  | ||||
| / { | ||||
| 	model = "Comtrend AR-5315u"; | ||||
| 	compatible = "comtrend,ar-5315u", "brcm,bcm6318"; | ||||
|  | ||||
| 	aliases { | ||||
| 		led-boot = &led_power_green; | ||||
| 		led-failsafe = &led_power_green; | ||||
| 		led-running = &led_power_green; | ||||
| 		led-upgrade = &led_power_green; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0x00000000 0x04000000>; | ||||
| 	}; | ||||
|  | ||||
| 	keys { | ||||
| 		compatible = "gpio-keys-polled"; | ||||
| 		poll-interval = <20>; | ||||
|  | ||||
| 		wps { | ||||
| 			label = "wps"; | ||||
| 			gpios = <&pinctrl 3 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_WPS_BUTTON>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
|  | ||||
| 		reset { | ||||
| 			label = "reset"; | ||||
| 			gpios = <&pinctrl 33 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_RESTART>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ehci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &hsspi { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	flash@0 { | ||||
| 		compatible = "jedec,spi-nor"; | ||||
| 		spi-max-frequency = <62500000>; | ||||
| 		spi-tx-bus-width = <2>; | ||||
| 		spi-rx-bus-width = <2>; | ||||
| 		reg = <0>; | ||||
|  | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		partitions { | ||||
| 			compatible = "fixed-partitions"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
|  | ||||
| 			cfe: partition@0 { | ||||
| 				reg = <0x000000 0x010000>; | ||||
| 				label = "cfe"; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@10000 { | ||||
| 				compatible = "brcm,bcm963xx-imagetag"; | ||||
| 				reg = <0x010000 0xfe0000>; | ||||
| 				label = "firmware"; | ||||
| 			}; | ||||
|  | ||||
| 			partition@ff0000 { | ||||
| 				reg = <0xff0000 0x010000>; | ||||
| 				label = "nvram"; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &leds { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pinctrl_leds | ||||
| 		     &pinctrl_ephy0_act_led &pinctrl_ephy1_act_led | ||||
| 		     &pinctrl_ephy2_act_led &pinctrl_ephy3_act_led>; | ||||
|  | ||||
| 	led@0 { | ||||
| 		reg = <0>; | ||||
| 		active-low; | ||||
| 		label = "green:wps"; | ||||
| 	}; | ||||
|  | ||||
| 	led_power_green: led@1 { | ||||
| 		reg = <1>; | ||||
| 		active-low; | ||||
| 		label = "green:power"; | ||||
| 	}; | ||||
|  | ||||
| 	led@2 { | ||||
| 		reg = <2>; | ||||
| 		active-low; | ||||
| 		label = "green:usb"; | ||||
| 	}; | ||||
|  | ||||
| 	led@4 { | ||||
| 		reg = <4>; | ||||
| 		brcm,hardware-controlled; | ||||
| 		brcm,link-signal-sources = <4>; | ||||
| 		/* EPHY0 Act */ | ||||
| 	}; | ||||
|  | ||||
| 	led@5 { | ||||
| 		reg = <5>; | ||||
| 		brcm,hardware-controlled; | ||||
| 		brcm,link-signal-sources = <5>; | ||||
| 		/* EPHY1 Act */ | ||||
| 	}; | ||||
|  | ||||
| 	led@6 { | ||||
| 		reg = <6>; | ||||
| 		brcm,hardware-controlled; | ||||
| 		brcm,link-signal-sources = <6>; | ||||
| 		/* EPHY2 Act */ | ||||
| 	}; | ||||
|  | ||||
| 	led@7 { | ||||
| 		reg = <7>; | ||||
| 		brcm,hardware-controlled; | ||||
| 		brcm,link-signal-sources = <7>; | ||||
| 		/* EPHY3 Act */ | ||||
| 	}; | ||||
|  | ||||
| 	led@8 { | ||||
| 		reg = <8>; | ||||
| 		active-low; | ||||
| 		label = "green:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led@9 { | ||||
| 		reg = <9>; | ||||
| 		active-low; | ||||
| 		label = "red:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led@10 { | ||||
| 		reg = <10>; | ||||
| 		active-low; | ||||
| 		label = "green:dsl"; | ||||
| 	}; | ||||
|  | ||||
| 	led@11 { | ||||
| 		reg = <11>; | ||||
| 		active-low; | ||||
| 		label = "red:power"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ohci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pinctrl { | ||||
| 	pinctrl_leds: leds { | ||||
| 		function = "led"; | ||||
| 		pins = "gpio0", "gpio1", | ||||
| 		       "gpio2", "gpio8", | ||||
| 		       "gpio9", "gpio10", | ||||
| 		       "gpio11"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usbh { | ||||
| 	status = "okay"; | ||||
| }; | ||||
							
								
								
									
										350
									
								
								target/linux/bmips/dts/bcm6318.dtsi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								target/linux/bmips/dts/bcm6318.dtsi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,350 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include <dt-bindings/clock/bcm6318-clock.h> | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
| #include <dt-bindings/input/input.h> | ||||
| #include <dt-bindings/interrupt-controller/bcm6318-interrupt-controller.h> | ||||
| #include <dt-bindings/reset/bcm6318-reset.h> | ||||
| #include <dt-bindings/soc/bcm6318-pm.h> | ||||
|  | ||||
| / { | ||||
| 	#address-cells = <1>; | ||||
| 	#size-cells = <1>; | ||||
| 	compatible = "brcm,bcm6318"; | ||||
|  | ||||
| 	aliases { | ||||
| 		pinctrl = &pinctrl; | ||||
| 		serial0 = &uart0; | ||||
| 		spi1 = &hsspi; | ||||
| 	}; | ||||
|  | ||||
| 	chosen { | ||||
| 		bootargs = "console=ttyS0,115200n8 earlycon"; | ||||
| 		stdout-path = "serial0:115200n8"; | ||||
| 	}; | ||||
|  | ||||
| 	clocks { | ||||
| 		periph_osc: periph-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <50000000>; | ||||
| 			clock-output-names = "periph"; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi_osc: hsspi-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <250000000>; | ||||
| 			clock-output-names = "hsspi_osc"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		mips-hpt-frequency = <166500000>; | ||||
|  | ||||
| 		cpu@0 { | ||||
| 			compatible = "brcm,bmips3300", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <0>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpu_intc: interrupt-controller { | ||||
| 		#address-cells = <0>; | ||||
| 		compatible = "mti,cpu-interrupt-controller"; | ||||
|  | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0 0>; | ||||
| 	}; | ||||
|  | ||||
| 	ubus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		compatible = "simple-bus"; | ||||
| 		ranges; | ||||
|  | ||||
| 		periph_clk: clock-controller@10000004 { | ||||
| 			compatible = "brcm,bcm6318-clocks"; | ||||
| 			reg = <0x10000004 0x4>; | ||||
| 			#clock-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		ubus_clk: clock-controller@10000008 { | ||||
| 			compatible = "brcm,bcm6318-ubus-clocks"; | ||||
| 			reg = <0x10000008 0x4>; | ||||
| 			#clock-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_rst: reset-controller@10000010 { | ||||
| 			compatible = "brcm,bcm6345-reset"; | ||||
| 			reg = <0x10000010 0x4>; | ||||
| 			#reset-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc: interrupt-controller@10000018 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6318-ext-intc"; | ||||
| 			reg = <0x10000018 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM6318_IRQ_EXT0>, | ||||
| 				     <BCM6318_IRQ_EXT1>, | ||||
| 				     <BCM6318_IRQ_EXT2>, | ||||
| 				     <BCM6318_IRQ_EXT3>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_intc: interrupt-controller@10000020 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-l1-intc"; | ||||
| 			reg = <0x10000020 0x20>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <1>; | ||||
|  | ||||
| 			interrupt-parent = <&cpu_intc>; | ||||
| 			interrupts = <2>, <3>; | ||||
| 		}; | ||||
|  | ||||
| 		wdt: watchdog@10000068 { | ||||
| 			compatible = "brcm,bcm7038-wdt"; | ||||
| 			reg = <0x10000068 0xc>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
|  | ||||
| 			timeout-sec = <30>; | ||||
| 		}; | ||||
|  | ||||
| 		pll_cntl: syscon@10000074 { | ||||
| 			compatible = "syscon"; | ||||
| 			reg = <0x10000074 0x4>; | ||||
| 			native-endian; | ||||
| 		}; | ||||
|  | ||||
| 		syscon-reboot { | ||||
| 			compatible = "syscon-reboot"; | ||||
| 			regmap = <&pll_cntl>; | ||||
| 			offset = <0>; | ||||
| 			mask = <0x1>; | ||||
| 		}; | ||||
|  | ||||
| 		pinctrl: pin-controller@10000080 { | ||||
| 			compatible = "brcm,bcm6318-pinctrl"; | ||||
| 			reg = <0x10000080 0x08>, | ||||
| 			      <0x10000088 0x08>, | ||||
| 			      <0x10000098 0x04>, | ||||
| 			      <0x1000009c 0x0c>, | ||||
| 			      <0x100000d4 0x18>; | ||||
| 			reg-names = "dirout", "dat", "mode", "mux", "pad"; | ||||
|  | ||||
| 			gpio-controller; | ||||
| 			#gpio-cells = <2>; | ||||
|  | ||||
| 			interrupt-parent = <&ext_intc>; | ||||
| 			interrupts = <0 0>, <1 0>; | ||||
| 			interrupt-names = "gpio33", "gpio34"; | ||||
|  | ||||
| 			pinctrl_ephy0_spd_led: ephy0_spd_led { | ||||
| 				function = "ephy0_spd_led"; | ||||
| 				pins = "gpio0"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy1_spd_led: ephy1_spd_led { | ||||
| 				function = "ephy1_spd_led"; | ||||
| 				pins = "gpio1"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy2_spd_led: ephy2_spd_led { | ||||
| 				function = "ephy2_spd_led"; | ||||
| 				pins = "gpio2"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy3_spd_led: ephy3_spd_led { | ||||
| 				function = "ephy3_spd_led"; | ||||
| 				pins = "gpio3"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy0_act_led: ephy0_act_led { | ||||
| 				function = "ephy0_act_led"; | ||||
| 				pins = "gpio4"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy1_act_led: ephy1_act_led { | ||||
| 				function = "ephy1_act_led"; | ||||
| 				pins = "gpio5"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy2_act_led: ephy2_act_led { | ||||
| 				function = "ephy2_act_led"; | ||||
| 				pins = "gpio6"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy3_act_led: ephy3_act_led { | ||||
| 				function = "ephy3_act_led"; | ||||
| 				pins = "gpio7"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_serial_led: serial_led { | ||||
| 				pinctrl_serial_led_data: serial_led_data { | ||||
| 					function = "serial_led_data"; | ||||
| 					pins = "gpio6"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_serial_led_clk: serial_led_clk { | ||||
| 					function = "serial_led_clk"; | ||||
| 					pins = "gpio7"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_inet_act_led: inet_act_led { | ||||
| 				function = "inet_act_led"; | ||||
| 				pins = "gpio8"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_inet_fail_led: inet_fail_led { | ||||
| 				function = "inet_fail_led"; | ||||
| 				pins = "gpio9"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_dsl_led: dsl_led { | ||||
| 				function = "dsl_led"; | ||||
| 				pins = "gpio10"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_post_fail_led: post_fail_led { | ||||
| 				function = "post_fail_led"; | ||||
| 				pins = "gpio11"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_wlan_wps_led: wlan_wps_led { | ||||
| 				function = "wlan_wps_led"; | ||||
| 				pins = "gpio12"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_usb_pwron: usb_pwron { | ||||
| 				function = "usb_pwron"; | ||||
| 				pins = "gpio13"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_usb_device_led: usb_device_led { | ||||
| 				function = "usb_device_led"; | ||||
| 				pins = "gpio13"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_usb_active: usb_active { | ||||
| 				function = "usb_active"; | ||||
| 				pins = "gpio40"; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		uart0: serial@10000100 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000100 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6318_IRQ_UART0>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		leds: led-controller@10000200 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,bcm6328-leds"; | ||||
| 			reg = <0x10000200 0x24>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		periph_pwr: power-controller@100008e8 { | ||||
| 			compatible = "brcm,bcm6318-power-controller"; | ||||
| 			reg = <0x100008e8 0x4>; | ||||
|  | ||||
| 			#power-domain-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi: spi@10003000 { | ||||
| 			compatible = "brcm,bcm6328-hsspi"; | ||||
| 			reg = <0x10003000 0x600>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6318_IRQ_HSSPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6318_CLK_HSSPI>, | ||||
| 				 <&hsspi_osc>; | ||||
| 			clock-names = "hsspi", | ||||
| 				      "pll"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6318_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ehci: usb@10005000 { | ||||
| 			compatible = "brcm,bcm6318-ehci", "generic-ehci"; | ||||
| 			reg = <0x10005000 0x100>; | ||||
| 			big-endian; | ||||
| 			ignore-oc; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6318_IRQ_EHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ohci: usb@10005100 { | ||||
| 			compatible = "brcm,bcm6318-ohci", "generic-ohci"; | ||||
| 			reg = <0x10005100 0x100>; | ||||
| 			big-endian; | ||||
| 			no-big-frame-no; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6318_IRQ_OHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usbh: usb-phy@10005200 { | ||||
| 			compatible = "brcm,bcm6318-usbh-phy"; | ||||
| 			reg = <0x10005200 0x38>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6318_CLK_USBD>, | ||||
| 				 <&ubus_clk BCM6318_UCLK_USB>; | ||||
| 			clock-names = "usbh", | ||||
| 				      "usb_ref"; | ||||
|  | ||||
| 			power-domains = <&periph_pwr BCM6318_POWER_DOMAIN_USB>; | ||||
| 			resets = <&periph_rst BCM6318_RST_USBH>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										427
									
								
								target/linux/bmips/dts/bcm63268.dtsi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								target/linux/bmips/dts/bcm63268.dtsi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,427 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include <dt-bindings/clock/bcm63268-clock.h> | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
| #include <dt-bindings/input/input.h> | ||||
| #include <dt-bindings/interrupt-controller/bcm63268-interrupt-controller.h> | ||||
| #include <dt-bindings/reset/bcm63268-reset.h> | ||||
| #include <dt-bindings/soc/bcm63268-pm.h> | ||||
|  | ||||
| / { | ||||
| 	#address-cells = <1>; | ||||
| 	#size-cells = <1>; | ||||
| 	compatible = "brcm,bcm63268"; | ||||
|  | ||||
| 	aliases { | ||||
| 		nflash = &nflash; | ||||
| 		pinctrl = &pinctrl; | ||||
| 		serial0 = &uart0; | ||||
| 		serial1 = &uart1; | ||||
| 		spi0 = &lsspi; | ||||
| 		spi1 = &hsspi; | ||||
| 	}; | ||||
|  | ||||
| 	chosen { | ||||
| 		bootargs = "console=ttyS0,115200n8 earlycon"; | ||||
| 		stdout-path = "serial0:115200n8"; | ||||
| 	}; | ||||
|  | ||||
| 	clocks { | ||||
| 		periph_osc: periph-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <50000000>; | ||||
| 			clock-output-names = "periph"; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi_osc: hsspi-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <400000000>; | ||||
| 			clock-output-names = "hsspi_osc"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		mips-hpt-frequency = <200000000>; | ||||
|  | ||||
| 		cpu@0 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <0>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@1 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <1>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpu_intc: interrupt-controller { | ||||
| 		#address-cells = <0>; | ||||
| 		compatible = "mti,cpu-interrupt-controller"; | ||||
|  | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0 0>; | ||||
| 	}; | ||||
|  | ||||
| 	ubus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		compatible = "simple-bus"; | ||||
| 		ranges; | ||||
|  | ||||
| 		periph_clk: clock-controller@10000004 { | ||||
| 			compatible = "brcm,bcm63268-clocks"; | ||||
| 			reg = <0x10000004 0x4>; | ||||
| 			#clock-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		pll_cntl: syscon@10000008 { | ||||
| 			compatible = "syscon"; | ||||
| 			reg = <0x10000008 0x4>; | ||||
| 			native-endian; | ||||
| 		}; | ||||
|  | ||||
| 		syscon-reboot { | ||||
| 			compatible = "syscon-reboot"; | ||||
| 			regmap = <&pll_cntl>; | ||||
| 			offset = <0x0>; | ||||
| 			mask = <0x1>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_rst: reset-controller@10000010 { | ||||
| 			compatible = "brcm,bcm6345-reset"; | ||||
| 			reg = <0x10000010 0x4>; | ||||
| 			#reset-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc: interrupt-controller@10000018 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-ext-intc"; | ||||
| 			reg = <0x10000018 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM63268_IRQ_EXT0>, | ||||
| 				     <BCM63268_IRQ_EXT1>, | ||||
| 				     <BCM63268_IRQ_EXT2>, | ||||
| 				     <BCM63268_IRQ_EXT3>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_intc: interrupt-controller@10000020 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-l1-intc"; | ||||
| 			reg = <0x10000020 0x20>, | ||||
| 			      <0x10000040 0x20>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <1>; | ||||
|  | ||||
| 			interrupt-parent = <&cpu_intc>; | ||||
| 			interrupts = <2>, <3>; | ||||
| 		}; | ||||
|  | ||||
| 		wdt: watchdog@1000009c { | ||||
| 			compatible = "brcm,bcm7038-wdt"; | ||||
| 			reg = <0x1000009c 0xc>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
|  | ||||
| 			timeout-sec = <30>; | ||||
| 		}; | ||||
|  | ||||
| 		pinctrl: pin-controller@100000c0 { | ||||
| 			compatible = "brcm,bcm63268-pinctrl"; | ||||
| 			reg = <0x100000c0 0x8>, | ||||
| 			      <0x100000c8 0x8>, | ||||
| 			      <0x100000d0 0x4>, | ||||
| 			      <0x100000d8 0x4>, | ||||
| 			      <0x100000dc 0x4>, | ||||
| 			      <0x100000f8 0x4>; | ||||
| 			reg-names = "dirout", "dat", "led", "mode", | ||||
| 				    "ctrl", "basemode"; | ||||
|  | ||||
| 			gpio-controller; | ||||
| 			#gpio-cells = <2>; | ||||
|  | ||||
| 			interrupt-parent = <&ext_intc>; | ||||
| 			interrupts = <0 0>, <1 0>, <2 0>, <3 0>; | ||||
| 			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35"; | ||||
|  | ||||
| 			pinctrl_serial_led: serial_led { | ||||
| 				pinctrl_serial_led_clk: serial_led_clk { | ||||
| 					function = "serial_led_clk"; | ||||
| 					pins = "gpio0"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_serial_led_data: serial_led_data { | ||||
| 					function = "serial_led_data"; | ||||
| 					pins = "gpio1"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_hsspi_cs4: hsspi_cs4 { | ||||
| 				function = "hsspi_cs4"; | ||||
| 				pins = "gpio16"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_hsspi_cs5: hsspi_cs5 { | ||||
| 				function = "hsspi_cs5"; | ||||
| 				pins = "gpio17"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_hsspi_cs6: hsspi_cs6 { | ||||
| 				function = "hsspi_cs6"; | ||||
| 				pins = "gpio8"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_hsspi_cs7: hsspi_cs7 { | ||||
| 				function = "hsspi_cs7"; | ||||
| 				pins = "gpio9"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_adsl_spi: adsl_spi { | ||||
| 				pinctrl_adsl_spi_miso: adsl_spi_miso { | ||||
| 					function = "adsl_spi_miso"; | ||||
| 					pins = "gpio18"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_adsl_spi_mosi: adsl_spi_mosi { | ||||
| 					function = "adsl_spi_mosi"; | ||||
| 					pins = "gpio19"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_vreq_clk: vreq_clk { | ||||
| 				function = "vreq_clk"; | ||||
| 				pins = "gpio22"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_pcie_clkreq_b: pcie_clkreq_b { | ||||
| 				function = "pcie_clkreq_b"; | ||||
| 				pins = "gpio23"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led_clk: robosw_led_clk { | ||||
| 				function = "robosw_led_clk"; | ||||
| 				pins = "gpio30"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led_data: robosw_led_data { | ||||
| 				function = "robosw_led_data"; | ||||
| 				pins = "gpio31"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_nand: nand { | ||||
| 				function = "nand"; | ||||
| 				group = "nand_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_gpio35_alt: gpio35_alt { | ||||
| 				function = "gpio35_alt"; | ||||
| 				pin = "gpio35"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_dectpd: dectpd { | ||||
| 				function = "dectpd"; | ||||
| 				group = "dectpd_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_vdsl_phy_override_0: vdsl_phy_override_0 { | ||||
| 				function = "vdsl_phy_override_0"; | ||||
| 				group = "vdsl_phy_override_0_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_vdsl_phy_override_1: vdsl_phy_override_1 { | ||||
| 				function = "vdsl_phy_override_1"; | ||||
| 				group = "vdsl_phy_override_1_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_vdsl_phy_override_2: vdsl_phy_override_2 { | ||||
| 				function = "vdsl_phy_override_2"; | ||||
| 				group = "vdsl_phy_override_2_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_vdsl_phy_override_3: vdsl_phy_override_3 { | ||||
| 				function = "vdsl_phy_override_3"; | ||||
| 				group = "vdsl_phy_override_3_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_dsl_gpio8: dsl_gpio8 { | ||||
| 				function = "dsl_gpio8"; | ||||
| 				group = "dsl_gpio8"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_dsl_gpio9: dsl_gpio9 { | ||||
| 				function = "dsl_gpio9"; | ||||
| 				group = "dsl_gpio9"; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		uart0: serial@10000180 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000180 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM63268_IRQ_UART0>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		uart1: serial@100001a0 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x100001a0 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM63268_IRQ_UART1>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		nflash: nand@10000200 { | ||||
| 			compatible = "brcm,nand-bcm6368", | ||||
| 				     "brcm,brcmnand-v4.0", | ||||
| 				     "brcm,brcmnand"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			reg = <0x10000200 0x180>, | ||||
| 			      <0x10000600 0x200>, | ||||
| 			      <0x100000b0 0x10>; | ||||
| 			reg-names = "nand", | ||||
| 				    "nand-cache", | ||||
| 				    "nand-int-base"; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM63268_IRQ_NAND>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM63268_CLK_NAND>; | ||||
| 			clock-names = "nand"; | ||||
|  | ||||
| 			pinctrl-names = "default"; | ||||
| 			pinctrl-0 = <&pinctrl_nand>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		lsspi: spi@10000800 { | ||||
| 			compatible = "brcm,bcm6358-spi"; | ||||
| 			reg = <0x10000800 0x70c>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM63268_IRQ_LSSPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM63268_CLK_SPI>; | ||||
| 			clock-names = "spi"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM63268_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi: spi@10001000 { | ||||
| 			compatible = "brcm,bcm6328-hsspi"; | ||||
| 			reg = <0x10001000 0x600>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM63268_IRQ_HSSPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM63268_CLK_HSSPI>, | ||||
| 				 <&hsspi_osc>; | ||||
| 			clock-names = "hsspi", | ||||
| 				      "pll"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM63268_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		periph_pwr: power-controller@1000184c { | ||||
| 			compatible = "brcm,bcm63268-power-controller"; | ||||
| 			reg = <0x1000184c 0x4>; | ||||
| 			#power-domain-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		leds: led-controller@10001900 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,bcm6328-leds"; | ||||
| 			reg = <0x10001900 0x24>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ehci: usb@10002500 { | ||||
| 			compatible = "brcm,bcm63268-ehci", "generic-ehci"; | ||||
| 			reg = <0x10002500 0x100>; | ||||
| 			big-endian; | ||||
| 			ignore-oc; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM63268_IRQ_EHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ohci: usb@10002600 { | ||||
| 			compatible = "brcm,bcm63268-ohci", "generic-ohci"; | ||||
| 			reg = <0x10002600 0x100>; | ||||
| 			big-endian; | ||||
| 			no-big-frame-no; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM63268_IRQ_OHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usbh: usb-phy@10002700 { | ||||
| 			compatible = "brcm,bcm63268-usbh-phy"; | ||||
| 			reg = <0x10002700 0x38>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM63268_CLK_USBH>; | ||||
| 			/* FIXME! <&timer_clk BCM63268_TCLK_USB_REF> */ | ||||
| 			clock-names = "usbh"; | ||||
| 			/* FIXME! usb_ref */ | ||||
|  | ||||
| 			power-domains = <&periph_pwr BCM63268_POWER_DOMAIN_USBH>; | ||||
| 			resets = <&periph_rst BCM63268_RST_USBH>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										127
									
								
								target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "bcm6328.dtsi" | ||||
|  | ||||
| / { | ||||
| 	model = "Comtrend AR-5387un"; | ||||
| 	compatible = "comtrend,ar-5387un", "brcm,bcm6328"; | ||||
|  | ||||
| 	aliases { | ||||
| 		led-boot = &led_power_green; | ||||
| 		led-failsafe = &led_power_green; | ||||
| 		led-running = &led_power_green; | ||||
| 		led-upgrade = &led_power_green; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0x00000000 0x04000000>; | ||||
| 	}; | ||||
|  | ||||
| 	keys { | ||||
| 		compatible = "gpio-keys-polled"; | ||||
| 		poll-interval = <20>; | ||||
|  | ||||
| 		reset { | ||||
| 			label = "reset"; | ||||
| 			gpios = <&pinctrl 23 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_RESTART>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ehci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &hsspi { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	flash@0 { | ||||
| 		compatible = "jedec,spi-nor"; | ||||
| 		spi-max-frequency = <16666667>; | ||||
| 		spi-tx-bus-width = <2>; | ||||
| 		spi-rx-bus-width = <2>; | ||||
| 		reg = <0>; | ||||
|  | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		partitions { | ||||
| 			compatible = "fixed-partitions"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
|  | ||||
| 			cfe: partition@0 { | ||||
| 				reg = <0x000000 0x010000>; | ||||
| 				label = "cfe"; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@10000 { | ||||
| 				compatible = "brcm,bcm963xx-imagetag"; | ||||
| 				reg = <0x010000 0xfe0000>; | ||||
| 				label = "firmware"; | ||||
| 			}; | ||||
|  | ||||
| 			partition@ff0000 { | ||||
| 				reg = <0xff0000 0x010000>; | ||||
| 				label = "nvram"; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &leds { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pinctrl_leds>; | ||||
|  | ||||
| 	led@1 { | ||||
| 		reg = <1>; | ||||
| 		label = "red:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led@4 { | ||||
| 		reg = <4>; | ||||
| 		label = "red:power"; | ||||
| 	}; | ||||
|  | ||||
| 	led@7 { | ||||
| 		reg = <7>; | ||||
| 		label = "green:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led_power_green: led@8 { | ||||
| 		reg = <8>; | ||||
| 		label = "green:power"; | ||||
| 	}; | ||||
|  | ||||
| 	led@11 { | ||||
| 		reg = <11>; | ||||
| 		active-low; | ||||
| 		label = "green:dsl"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ohci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pinctrl { | ||||
| 	pinctrl_leds: leds { | ||||
| 		function = "led"; | ||||
| 		pins = "gpio1", "gpio4", "gpio7", | ||||
| 		       "gpio8", "gpio11"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usbh { | ||||
| 	status = "okay"; | ||||
| }; | ||||
							
								
								
									
										368
									
								
								target/linux/bmips/dts/bcm6328.dtsi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								target/linux/bmips/dts/bcm6328.dtsi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,368 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include <dt-bindings/clock/bcm6328-clock.h> | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
| #include <dt-bindings/input/input.h> | ||||
| #include <dt-bindings/interrupt-controller/bcm6328-interrupt-controller.h> | ||||
| #include <dt-bindings/reset/bcm6328-reset.h> | ||||
| #include <dt-bindings/soc/bcm6328-pm.h> | ||||
|  | ||||
| / { | ||||
| 	#address-cells = <1>; | ||||
| 	#size-cells = <1>; | ||||
| 	compatible = "brcm,bcm6328"; | ||||
|  | ||||
| 	aliases { | ||||
| 		nflash = &nflash; | ||||
| 		pinctrl = &pinctrl; | ||||
| 		serial0 = &uart0; | ||||
| 		serial1 = &uart1; | ||||
| 		spi1 = &hsspi; | ||||
| 	}; | ||||
|  | ||||
| 	chosen { | ||||
| 		bootargs = "console=ttyS0,115200n8 earlycon"; | ||||
| 		stdout-path = "serial0:115200n8"; | ||||
| 	}; | ||||
|  | ||||
| 	clocks { | ||||
| 		periph_osc: periph-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <50000000>; | ||||
| 			clock-output-names = "periph"; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi_osc: hsspi-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <133333333>; | ||||
| 			clock-output-names = "hsspi_osc"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		mips-hpt-frequency = <160000000>; | ||||
|  | ||||
| 		cpu@0 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <0>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@1 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <1>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpu_intc: interrupt-controller { | ||||
| 		#address-cells = <0>; | ||||
| 		compatible = "mti,cpu-interrupt-controller"; | ||||
|  | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0 0>; | ||||
| 	}; | ||||
|  | ||||
| 	ubus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		compatible = "simple-bus"; | ||||
| 		ranges; | ||||
|  | ||||
| 		periph_clk: clock-controller@10000004 { | ||||
| 			compatible = "brcm,bcm6328-clocks"; | ||||
| 			reg = <0x10000004 0x4>; | ||||
| 			#clock-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_rst: reset-controller@10000010 { | ||||
| 			compatible = "brcm,bcm6345-reset"; | ||||
| 			reg = <0x10000010 0x4>; | ||||
| 			#reset-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc: interrupt-controller@10000018 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-ext-intc"; | ||||
| 			reg = <0x10000018 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM6328_IRQ_EXTO>, | ||||
| 				     <BCM6328_IRQ_EXT1>, | ||||
| 				     <BCM6328_IRQ_EXT2>, | ||||
| 				     <BCM6328_IRQ_EXT3>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_intc: interrupt-controller@10000020 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-l1-intc"; | ||||
| 			reg = <0x10000020 0x10>, | ||||
| 			      <0x10000030 0x10>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <1>; | ||||
|  | ||||
| 			interrupt-parent = <&cpu_intc>; | ||||
| 			interrupts = <2>, <3>; | ||||
| 		}; | ||||
|  | ||||
| 		wdt: watchdog@1000005c { | ||||
| 			compatible = "brcm,bcm7038-wdt"; | ||||
| 			reg = <0x1000005c 0xc>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
|  | ||||
| 			timeout-sec = <30>; | ||||
| 		}; | ||||
|  | ||||
| 		pll_cntl: syscon@10000068 { | ||||
| 			compatible = "syscon"; | ||||
| 			reg = <0x10000068 0x4>; | ||||
| 			native-endian; | ||||
| 		}; | ||||
|  | ||||
| 		syscon-reboot { | ||||
| 			compatible = "syscon-reboot"; | ||||
| 			regmap = <&pll_cntl>; | ||||
| 			offset = <0>; | ||||
| 			mask = <0x1>; | ||||
| 		}; | ||||
|  | ||||
| 		pinctrl: pin-controller@10000080 { | ||||
| 			compatible = "brcm,bcm6328-pinctrl"; | ||||
| 			reg = <0x10000080 0x8>, | ||||
| 			      <0x10000088 0x8>, | ||||
| 			      <0x10000098 0x4>, | ||||
| 			      <0x1000009c 0xc>; | ||||
| 			reg-names = "dirout", "dat", "mode", "mux"; | ||||
|  | ||||
| 			gpio-controller; | ||||
| 			#gpio-cells = <2>; | ||||
|  | ||||
| 			interrupt-parent = <&ext_intc>; | ||||
| 			interrupts = <3 0>, <2 0>, <0 0>, <1 0>; | ||||
| 			interrupt-names = "gpio12", "gpio15", | ||||
| 					  "gpio23", "gpio24"; | ||||
|  | ||||
| 			pinctrl_serial_led: serial_led { | ||||
| 				pinctrl_serial_led_data: serial_led_data { | ||||
| 					function = "serial_led_data"; | ||||
| 					pins = "gpio6"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_serial_led_clk: serial_led_clk { | ||||
| 					function = "serial_led_clk"; | ||||
| 					pins = "gpio7"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_inet_act_led: inet_act_led { | ||||
| 				function = "inet_act_led"; | ||||
| 				pins = "gpio11"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_pcie_clkreq: pcie_clkreq { | ||||
| 				function = "pcie_clkreq"; | ||||
| 				pins = "gpio16"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy0_spd_led: ephy0_spd_led { | ||||
| 				function = "led"; | ||||
| 				pins = "gpio17"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy1_spd_led: ephy1_spd_led { | ||||
| 				function = "led"; | ||||
| 				pins = "gpio18"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy2_spd_led: ephy2_spd_led { | ||||
| 				function = "led"; | ||||
| 				pins = "gpio19"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy3_spd_led: ephy3_spd_led { | ||||
| 				function = "led"; | ||||
| 				pins = "gpio20"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy0_act_led: ephy0_act_led { | ||||
| 				function = "ephy0_act_led"; | ||||
| 				pins = "gpio25"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy1_act_led: ephy1_act_led { | ||||
| 				function = "ephy1_act_led"; | ||||
| 				pins = "gpio26"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy2_act_led: ephy2_act_led { | ||||
| 				function = "ephy2_act_led"; | ||||
| 				pins = "gpio27"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy3_act_led: ephy3_act_led { | ||||
| 				function = "ephy3_act_led"; | ||||
| 				pins = "gpio28"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_hsspi_cs1: hsspi_cs1 { | ||||
| 				function = "hsspi_cs1"; | ||||
| 				pins = "hsspi_cs1"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_usb_port1_device: usb_port1_device { | ||||
| 				function = "usb_device_port"; | ||||
| 				pins = "usb_port1"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_usb_port1_host: usb_port1_host { | ||||
| 				function = "usb_host_port"; | ||||
| 				pins = "usb_port1"; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		uart0: serial@10000100 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000100 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6328_IRQ_UART0>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		uart1: serial@10000120 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000120 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6328_IRQ_UART1>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		nflash: nand@10000200 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,nand-bcm6368", | ||||
| 				     "brcm,brcmnand-v2.2", | ||||
| 				     "brcm,brcmnand"; | ||||
| 			reg = <0x10000200 0x180>, | ||||
| 			      <0x10000400 0x200>, | ||||
| 			      <0x10000070 0x10>; | ||||
| 			reg-names = "nand", | ||||
| 				    "nand-cache", | ||||
| 				    "nand-int-base"; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6328_IRQ_NAND>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		leds: led-controller@10000800 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,bcm6328-leds"; | ||||
| 			reg = <0x10000800 0x24>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi: spi@10001000 { | ||||
| 			compatible = "brcm,bcm6328-hsspi"; | ||||
| 			reg = <0x10001000 0x600>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6328_IRQ_HSSPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6328_CLK_HSSPI>, | ||||
| 				 <&hsspi_osc>; | ||||
| 			clock-names = "hsspi", | ||||
| 				      "pll"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6328_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		periph_pwr: power-controller@10001848 { | ||||
| 			compatible = "brcm,bcm6328-power-controller"; | ||||
| 			reg = <0x10001848 0x4>; | ||||
|  | ||||
| 			#power-domain-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		ehci: usb@10002500 { | ||||
| 			compatible = "brcm,bcm6328-ehci", "generic-ehci"; | ||||
| 			reg = <0x10002500 0x100>; | ||||
| 			big-endian; | ||||
| 			ignore-oc; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6328_IRQ_EHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ohci: usb@10002600 { | ||||
| 			compatible = "brcm,bcm6328-ohci", "generic-ohci"; | ||||
| 			reg = <0x10002600 0x100>; | ||||
| 			big-endian; | ||||
| 			no-big-frame-no; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6328_IRQ_OHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usbh: usb-phy@10002700 { | ||||
| 			compatible = "brcm,bcm6328-usbh-phy"; | ||||
| 			reg = <0x10002700 0x38>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6328_CLK_USBH>; | ||||
| 			clock-names = "usbh"; | ||||
|  | ||||
| 			power-domains = <&periph_pwr BCM6328_POWER_DOMAIN_USBH>; | ||||
| 			resets = <&periph_rst BCM6328_RST_USBH>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										168
									
								
								target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,168 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "bcm6358.dtsi" | ||||
|  | ||||
| / { | ||||
| 	compatible = "huawei,hg556a-b", "brcm,bcm6358"; | ||||
| 	model = "Huawei EchoLife HG556a (version B)"; | ||||
|  | ||||
| 	aliases { | ||||
| 		led-boot = &power_red; | ||||
| 		led-failsafe = &power_red; | ||||
| 		led-running = &power_red; | ||||
| 		led-upgrade = &power_red; | ||||
|  | ||||
| 		led-dsl = &dsl_red; | ||||
| 		led-internet = &dsl_red; | ||||
| 		led-usb = &hspa_red; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0x00000000 0x04000000>; | ||||
| 	}; | ||||
|  | ||||
| 	keys { | ||||
| 		compatible = "gpio-keys-polled"; | ||||
| 		poll-interval = <20>; | ||||
|  | ||||
| 		help { | ||||
| 			label = "help"; | ||||
| 			gpios = <&pinctrl 8 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_HELP>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
|  | ||||
| 		wlan { | ||||
| 			label = "wlan"; | ||||
| 			gpios = <&pinctrl 9 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_WLAN>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
|  | ||||
| 		restart { | ||||
| 			label = "restart"; | ||||
| 			gpios = <&pinctrl 10 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_RESTART>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
|  | ||||
| 		reset { | ||||
| 			label = "reset"; | ||||
| 			gpios = <&pinctrl 11 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_CONFIG>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	leds { | ||||
| 		compatible = "gpio-leds"; | ||||
|  | ||||
| 		led@0 { | ||||
| 			label = "red:message"; | ||||
| 			gpios = <&pinctrl 0 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		hspa_red: led@1 { | ||||
| 			label = "red:hspa"; | ||||
| 			gpios = <&pinctrl 1 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		dsl_red: led@2 { | ||||
| 			label = "red:dsl"; | ||||
| 			gpios = <&pinctrl 2 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		power_red: led@3 { | ||||
| 			label = "red:power"; | ||||
| 			gpios = <&pinctrl 3 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@6 { | ||||
| 			label = "all"; | ||||
| 			gpios = <&pinctrl 6 GPIO_ACTIVE_LOW>; | ||||
| 			default-state = "on"; | ||||
| 		}; | ||||
|  | ||||
| 		led@12 { | ||||
| 			label = "green:lan1"; | ||||
| 			gpios = <&pinctrl 12 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@13 { | ||||
| 			label = "red:lan1"; | ||||
| 			gpios = <&pinctrl 13 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@15 { | ||||
| 			label = "green:lan2"; | ||||
| 			gpios = <&pinctrl 15 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@22 { | ||||
| 			label = "red:lan2"; | ||||
| 			gpios = <&pinctrl 22 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@23 { | ||||
| 			label = "green:lan3"; | ||||
| 			gpios = <&pinctrl 23 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@26 { | ||||
| 			label = "red:lan3"; | ||||
| 			gpios = <&pinctrl 26 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@27 { | ||||
| 			label = "green:lan4"; | ||||
| 			gpios = <&pinctrl 27 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@28 { | ||||
| 			label = "red:lan4"; | ||||
| 			gpios = <&pinctrl 28 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &pflash { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	partitions { | ||||
| 		compatible = "fixed-partitions"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		cfe: partition@0 { | ||||
| 			label = "cfe"; | ||||
| 			reg = <0x000000 0x020000>; | ||||
| 			read-only; | ||||
| 		}; | ||||
|  | ||||
| 		partition@20000 { | ||||
| 			label = "firmware"; | ||||
| 			reg = <0x020000 0xec0000>; | ||||
| 			compatible = "brcm,bcm963xx-imagetag"; | ||||
| 		}; | ||||
|  | ||||
| 		cal_data: partition@ee0000 { | ||||
| 			label = "cal_data"; | ||||
| 			reg = <0xee0000 0x100000>; | ||||
| 			read-only; | ||||
| 		}; | ||||
|  | ||||
| 		partition@fe0000 { | ||||
| 			label = "nvram"; | ||||
| 			reg = <0xfe0000 0x020000>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usbh { | ||||
| 	status = "okay"; | ||||
| }; | ||||
							
								
								
									
										315
									
								
								target/linux/bmips/dts/bcm6358.dtsi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								target/linux/bmips/dts/bcm6358.dtsi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,315 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include <dt-bindings/clock/bcm6358-clock.h> | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
| #include <dt-bindings/input/input.h> | ||||
| #include <dt-bindings/interrupt-controller/bcm6358-interrupt-controller.h> | ||||
| #include <dt-bindings/reset/bcm6358-reset.h> | ||||
|  | ||||
| / { | ||||
| 	#address-cells = <1>; | ||||
| 	#size-cells = <1>; | ||||
| 	compatible = "brcm,bcm6358"; | ||||
|  | ||||
| 	aliases { | ||||
| 		pflash = &pflash; | ||||
| 		pinctrl = &pinctrl; | ||||
| 		serial0 = &uart0; | ||||
| 		serial1 = &uart1; | ||||
| 		spi0 = &lsspi; | ||||
| 	}; | ||||
|  | ||||
| 	chosen { | ||||
| 		bootargs = "console=ttyS0,115200n8 earlycon"; | ||||
| 		stdout-path = "serial0:115200n8"; | ||||
| 	}; | ||||
|  | ||||
| 	clocks { | ||||
| 		periph_osc: periph-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <50000000>; | ||||
| 			clock-output-names = "periph"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		mips-hpt-frequency = <150000000>; | ||||
|  | ||||
| 		cpu@0 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <0>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@1 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <1>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpu_intc: interrupt-controller { | ||||
| 		#address-cells = <0>; | ||||
| 		compatible = "mti,cpu-interrupt-controller"; | ||||
|  | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0 0>; | ||||
| 	}; | ||||
|  | ||||
| 	pflash: nor@1e000000 { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
| 		compatible = "cfi-flash"; | ||||
| 		reg = <0x1e000000 0x2000000>; | ||||
| 		bank-width = <2>; | ||||
|  | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	ubus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		compatible = "simple-bus"; | ||||
| 		ranges; | ||||
|  | ||||
| 		periph_clk: clock-controller@fffe0004 { | ||||
| 			compatible = "brcm,bcm6358-clocks"; | ||||
| 			reg = <0xfffe0004 0x4>; | ||||
| 			#clock-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		pll_cntl: syscon@fffe0008 { | ||||
| 			compatible = "syscon"; | ||||
| 			reg = <0xfffe0008 0x4>; | ||||
| 			native-endian; | ||||
| 		}; | ||||
|  | ||||
| 		syscon-reboot { | ||||
| 			compatible = "syscon-reboot"; | ||||
| 			regmap = <&pll_cntl>; | ||||
| 			offset = <0x0>; | ||||
| 			mask = <0x1>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_intc: interrupt-controller@fffe000c { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-l1-intc"; | ||||
| 			reg = <0xfffe000c 0x8>, | ||||
| 			      <0xfffe0038 0x8>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <1>; | ||||
|  | ||||
| 			interrupt-parent = <&cpu_intc>; | ||||
| 			interrupts = <2>, <3>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc0: interrupt-controller@fffe0014 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-ext-intc"; | ||||
| 			reg = <0xfffe0014 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM6358_IRQ_EXT0>, | ||||
| 				     <BCM6358_IRQ_EXT1>, | ||||
| 				     <BCM6358_IRQ_EXT2>, | ||||
| 				     <BCM6358_IRQ_EXT3>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc1: interrupt-controller@fffe001c { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-ext-intc"; | ||||
| 			reg = <0xfffe001c 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM6358_IRQ_EXT4>, | ||||
| 				     <BCM6358_IRQ_EXT5>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_rst: reset-controller@fffe0034 { | ||||
| 			compatible = "brcm,bcm6345-reset"; | ||||
| 			reg = <0xfffe0034 0x4>; | ||||
| 			#reset-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		pinctrl: pin-controller@fffe0080 { | ||||
| 			compatible = "brcm,bcm6358-pinctrl"; | ||||
| 			reg = <0xfffe0080 0x8>, | ||||
| 			      <0xfffe0088 0x8>; | ||||
| 			reg-names = "dirout", "dat", "mode"; | ||||
| 			brcm,gpiomode = <&gpiomode>; | ||||
|  | ||||
| 			gpio-controller; | ||||
| 			#gpio-cells = <2>; | ||||
|  | ||||
| 			interrupts-extended = <&ext_intc1 0 0>, | ||||
| 					      <&ext_intc1 1 0>, | ||||
| 					      <&ext_intc0 0 0>, | ||||
| 					      <&ext_intc0 1 0>, | ||||
| 					      <&ext_intc0 2 0>, | ||||
| 					      <&ext_intc0 3 0>; | ||||
| 			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35", | ||||
| 					  "gpio36", "gpio37"; | ||||
|  | ||||
| 			pinctrl_ebi_cs: ebi_cs { | ||||
| 				function = "ebi_cs"; | ||||
| 				groups = "ebi_cs_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_uart1: uart1 { | ||||
| 				function = "uart1"; | ||||
| 				groups = "uart1_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_serial_led: serial_led { | ||||
| 				function = "serial_led"; | ||||
| 				groups = "serial_led_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_legacy_led: legacy_led { | ||||
| 				function = "legacy_led"; | ||||
| 				groups = "legacy_led_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_led: led { | ||||
| 				function = "led"; | ||||
| 				groups = "led_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_spi_cs_23: spi_cs { | ||||
| 				function = "spi_cs"; | ||||
| 				groups = "spi_cs_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_utopia: utopia { | ||||
| 				function = "utopia"; | ||||
| 				groups = "utopia_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_pwm_syn_clk: pwm_syn_clk { | ||||
| 				function = "pwm_syn_clk"; | ||||
| 				groups = "pwm_syn_clk_grp"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_sys_irq: sys_irq { | ||||
| 				function = "sys_irq"; | ||||
| 				groups = "sys_irq_grp"; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		gpiomode: gpiomode@fffe0098 { | ||||
| 			compatible = "brcm,bcm6358-gpiomode", "syscon"; | ||||
| 			reg = <0xfffe0098 0x4>; | ||||
| 		}; | ||||
|  | ||||
| 		leds: led-controller@fffe00d0 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,bcm6358-leds"; | ||||
| 			reg = <0xfffe00d0 0x8>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		uart0: serial@fffe0100 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0xfffe0100 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6358_IRQ_UART0>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		uart1: serial@fffe0120 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0xfffe0120 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6358_IRQ_UART1>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		lsspi: spi@fffe0800 { | ||||
| 			compatible = "brcm,bcm6358-spi"; | ||||
| 			reg = <0xfffe0800 0x70c>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6358_IRQ_SPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6358_CLK_SPI>; | ||||
| 			clock-names = "spi"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6358_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ehci: usb@fffe1300 { | ||||
| 			compatible = "brcm,bcm6358-ehci", "generic-ehci"; | ||||
| 			reg = <0xfffe1300 0x100>; | ||||
| 			big-endian; | ||||
| 			ignore-oc; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6358_IRQ_EHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ohci: usb@fffe1400 { | ||||
| 			compatible = "brcm,bcm6358-ohci", "generic-ohci"; | ||||
| 			reg = <0xfffe1400 0x100>; | ||||
| 			big-endian; | ||||
| 			no-big-frame-no; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6358_IRQ_OHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usbh: usb-phy@fffe1500 { | ||||
| 			compatible = "brcm,bcm6358-usbh-phy"; | ||||
| 			reg = <0xfffe1500 0x38>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6358_RST_USBH>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										226
									
								
								target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,226 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "bcm6362.dtsi" | ||||
|  | ||||
| / { | ||||
| 	model = "Netgear DGND3700 v2"; | ||||
| 	compatible = "netgear,dgnd3700-v2", "brcm,bcm6362"; | ||||
|  | ||||
| 	aliases { | ||||
| 		led-boot = &led_power_green; | ||||
| 		led-failsafe = &led_power_green; | ||||
| 		led-running = &led_power_green; | ||||
| 		led-upgrade = &led_power_green; | ||||
|  | ||||
| 		led-ethernet = &led_ethernet_green; | ||||
| 		led-usb = &led_usb1_green; | ||||
| 		led-usb2 = &led_usb2_green; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0x00000000 0x04000000>; | ||||
| 	}; | ||||
|  | ||||
| 	keys { | ||||
| 		compatible = "gpio-keys-polled"; | ||||
| 		poll-interval = <20>; | ||||
|  | ||||
| 		reset { | ||||
| 			label = "reset"; | ||||
| 			gpios = <&pinctrl 24 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_RESTART>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
|  | ||||
| 		wlan { | ||||
| 			label = "wlan"; | ||||
| 			gpios = <&pinctrl 25 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_WLAN>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
|  | ||||
| 		wps { | ||||
| 			label = "wps"; | ||||
| 			gpios = <&pinctrl 26 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_WPS_BUTTON>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	leds { | ||||
| 		compatible = "gpio-leds"; | ||||
|  | ||||
| 		led@28 { | ||||
| 			label = "green:dsl"; | ||||
| 			gpios = <&pinctrl 28 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@34 { | ||||
| 			label = "red:power"; | ||||
| 			gpios = <&pinctrl 34 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ehci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &leds { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	brcm,serial-leds; | ||||
| 	brcm,serial-dat-low; | ||||
| 	brcm,serial-shift-inv; | ||||
| 	brcm,serial-mux; | ||||
|  | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pinctrl_leds &pinctrl_serial_led>; | ||||
|  | ||||
| 	led@1 { | ||||
| 		reg = <1>; | ||||
| 		active-low; | ||||
| 		label = "green:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led_power_green: led@8 { | ||||
| 		reg = <8>; | ||||
| 		label = "green:power"; | ||||
| 	}; | ||||
|  | ||||
| 	led@9 { | ||||
| 		reg = <9>; | ||||
| 		active-low; | ||||
| 		label = "green:wps"; | ||||
| 	}; | ||||
|  | ||||
| 	led@10 { | ||||
| 		reg = <10>; | ||||
| 		active-low; | ||||
| 		label = "green:usb1"; | ||||
| 	}; | ||||
|  | ||||
| 	led@11 { | ||||
| 		reg = <11>; | ||||
| 		active-low; | ||||
| 		label = "green:usb2"; | ||||
| 	}; | ||||
|  | ||||
| 	led@12 { | ||||
| 		reg = <12>; | ||||
| 		active-low; | ||||
| 		label = "amber:internet"; | ||||
| 	}; | ||||
|  | ||||
| 	led_ethernet_green: led@13 { | ||||
| 		reg = <13>; | ||||
| 		active-low; | ||||
| 		label = "green:ethernet"; | ||||
| 	}; | ||||
|  | ||||
| 	led@14 { | ||||
| 		reg = <14>; | ||||
| 		active-low; | ||||
| 		label = "amber:dsl"; | ||||
| 	}; | ||||
|  | ||||
| 	led_usb1_green: led@16 { | ||||
| 		reg = <16>; | ||||
| 		active-low; | ||||
| 		label = "amber:usb1"; | ||||
| 	}; | ||||
|  | ||||
| 	led_usb2_green: led@17 { | ||||
| 		reg = <17>; | ||||
| 		active-low; | ||||
| 		label = "amber:usb2"; | ||||
| 	}; | ||||
|  | ||||
| 	led@18 { | ||||
| 		reg = <18>; | ||||
| 		active-low; | ||||
| 		label = "amber:ethernet"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &nflash { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	nandcs@0 { | ||||
| 		compatible = "brcm,nandcs"; | ||||
| 		#size-cells = <1>; | ||||
| 		#address-cells = <1>; | ||||
| 		reg = <0>; | ||||
| 		nand-ecc-step-size = <512>; | ||||
| 		nand-ecc-strength = <15>; | ||||
| 		nand-on-flash-bbt; | ||||
|  | ||||
| 		partitions { | ||||
| 			compatible = "fixed-partitions"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
|  | ||||
| 			cferom: partition@0 { | ||||
| 				label = "cferom"; | ||||
| 				reg = <0x0000000 0x0004000>; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@4000 { | ||||
| 				compatible = "brcm,wfi"; | ||||
| 				label = "wfi"; | ||||
| 				reg = <0x0004000 0x1c7c000>; | ||||
| 			}; | ||||
|  | ||||
| 			partition@1c80000 { | ||||
| 				label = "flag"; | ||||
| 				reg = <0x1c80000 0x0040000>; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@1cc0000 { | ||||
| 				label = "pcbasn"; | ||||
| 				reg = <0x1cc0000 0x0040000>; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@1d00000 { | ||||
| 				label = "xxx"; | ||||
| 				reg = <0x1d00000 0x0080000>; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@1d80000 { | ||||
| 				label = "language_dev"; | ||||
| 				reg = <0x1d80000 0x0040000>; | ||||
| 				read-only; | ||||
| 			}; | ||||
|  | ||||
| 			partition@1dc0000 { | ||||
| 				label = "scnvram"; | ||||
| 				reg = <0x1dc0000 0x0100000>; | ||||
| 				read-only; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ohci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pinctrl { | ||||
| 	pinctrl_leds: leds { | ||||
| 		function = "led"; | ||||
| 		pins = "gpio1"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usbh { | ||||
| 	status = "okay"; | ||||
| }; | ||||
							
								
								
									
										468
									
								
								target/linux/bmips/dts/bcm6362.dtsi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										468
									
								
								target/linux/bmips/dts/bcm6362.dtsi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,468 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include <dt-bindings/clock/bcm6362-clock.h> | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
| #include <dt-bindings/input/input.h> | ||||
| #include <dt-bindings/interrupt-controller/bcm6362-interrupt-controller.h> | ||||
| #include <dt-bindings/reset/bcm6362-reset.h> | ||||
| #include <dt-bindings/soc/bcm6362-pm.h> | ||||
|  | ||||
| / { | ||||
| 	#address-cells = <1>; | ||||
| 	#size-cells = <1>; | ||||
| 	compatible = "brcm,bcm6362"; | ||||
|  | ||||
| 	aliases { | ||||
| 		nflash = &nflash; | ||||
| 		pinctrl = &pinctrl; | ||||
| 		serial0 = &uart0; | ||||
| 		serial1 = &uart1; | ||||
| 		spi0 = &lsspi; | ||||
| 		spi1 = &hsspi; | ||||
| 	}; | ||||
|  | ||||
| 	chosen { | ||||
| 		bootargs = "console=ttyS0,115200n8 earlycon"; | ||||
| 		stdout-path = "serial0:115200n8"; | ||||
| 	}; | ||||
|  | ||||
| 	clocks { | ||||
| 		periph_osc: periph-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <50000000>; | ||||
| 			clock-output-names = "periph"; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi_osc: hsspi-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <400000000>; | ||||
| 			clock-output-names = "hsspi_osc"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		mips-hpt-frequency = <200000000>; | ||||
|  | ||||
| 		cpu@0 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <0>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@1 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <1>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpu_intc: interrupt-controller { | ||||
| 		#address-cells = <0>; | ||||
| 		compatible = "mti,cpu-interrupt-controller"; | ||||
|  | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0 0>; | ||||
| 	}; | ||||
|  | ||||
| 	ubus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		compatible = "simple-bus"; | ||||
| 		ranges; | ||||
|  | ||||
| 		periph_clk: clock-controller@10000004 { | ||||
| 			compatible = "brcm,bcm6362-clocks"; | ||||
| 			reg = <0x10000004 0x4>; | ||||
| 			#clock-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		pll_cntl: syscon@10000008 { | ||||
| 			compatible = "syscon"; | ||||
| 			reg = <0x10000008 0x4>; | ||||
| 			native-endian; | ||||
| 		}; | ||||
|  | ||||
| 		syscon-reboot { | ||||
| 			compatible = "syscon-reboot"; | ||||
| 			regmap = <&pll_cntl>; | ||||
| 			offset = <0x0>; | ||||
| 			mask = <0x1>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_rst: reset-controller@10000010 { | ||||
| 			compatible = "brcm,bcm6345-reset"; | ||||
| 			reg = <0x10000010 0x4>; | ||||
| 			#reset-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc: interrupt-controller@10000018 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-ext-intc"; | ||||
| 			reg = <0x10000018 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM6362_IRQ_EXT0>, | ||||
| 				     <BCM6362_IRQ_EXT1>, | ||||
| 				     <BCM6362_IRQ_EXT2>, | ||||
| 				     <BCM6362_IRQ_EXT3>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_intc: interrupt-controller@10000020 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-l1-intc"; | ||||
| 			reg = <0x10000020 0x10>, | ||||
| 			      <0x10000030 0x10>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <1>; | ||||
|  | ||||
| 			interrupt-parent = <&cpu_intc>; | ||||
| 			interrupts = <2>, <3>; | ||||
| 		}; | ||||
|  | ||||
| 		wdt: watchdog@1000005c { | ||||
| 			compatible = "brcm,bcm7038-wdt"; | ||||
| 			reg = <0x1000005c 0xc>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
|  | ||||
| 			timeout-sec = <30>; | ||||
| 		}; | ||||
|  | ||||
| 		pinctrl: pin-controller@10000080 { | ||||
| 			compatible = "brcm,bcm6362-pinctrl"; | ||||
| 			reg = <0x10000080 0x8>, | ||||
| 			      <0x10000088 0x8>, | ||||
| 			      <0x10000090 0x4>, | ||||
| 			      <0x10000098 0x4>, | ||||
| 			      <0x1000009c 0x4>, | ||||
| 			      <0x100000b8 0x4>; | ||||
| 			reg-names = "dirout", "dat", "led", | ||||
| 				    "mode", "ctrl", "basemode"; | ||||
|  | ||||
| 			gpio-controller; | ||||
| 			#gpio-cells = <2>; | ||||
|  | ||||
| 			interrupt-parent = <&ext_intc>; | ||||
| 			interrupts = <0 0>, <1 0>, <2 0>, <3 0>; | ||||
| 			interrupt-names = "gpio24", "gpio25", | ||||
| 					  "gpio26", "gpio27"; | ||||
|  | ||||
| 			pinctrl_usb_device_led: usb_device_led { | ||||
| 				function = "usb_device_led"; | ||||
| 				pins = "gpio0"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_sys_irq: sys_irq { | ||||
| 				function = "sys_irq"; | ||||
| 				pins = "gpio1"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_serial_led: serial_led { | ||||
| 				pinctrl_serial_led_clk: serial_led_clk { | ||||
| 					function = "serial_led_clk"; | ||||
| 					pins = "gpio2"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_serial_led_data: serial_led_data { | ||||
| 					function = "serial_led_data"; | ||||
| 					pins = "gpio3"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led_data: robosw_led_data { | ||||
| 				function = "robosw_led_data"; | ||||
| 				pins = "gpio4"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led_clk: robosw_led_clk { | ||||
| 				function = "robosw_led_clk"; | ||||
| 				pins = "gpio5"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led0: robosw_led0 { | ||||
| 				function = "robosw_led0"; | ||||
| 				pins = "gpio6"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led1: robosw_led1 { | ||||
| 				function = "robosw_led1"; | ||||
| 				pins = "gpio7"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_inet_led: inet_led { | ||||
| 				function = "inet_led"; | ||||
| 				pins = "gpio8"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_spi_cs2: spi_cs2 { | ||||
| 				function = "spi_cs2"; | ||||
| 				pins = "gpio9"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_spi_cs3: spi_cs3 { | ||||
| 				function = "spi_cs3"; | ||||
| 				pins = "gpio10"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ntr_pulse: ntr_pulse { | ||||
| 				function = "ntr_pulse"; | ||||
| 				pins = "gpio11"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_uart1_scts: uart1_scts { | ||||
| 				function = "uart1_scts"; | ||||
| 				pins = "gpio12"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_uart1_srts: uart1_srts { | ||||
| 				function = "uart1_srts"; | ||||
| 				pins = "gpio13"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_uart1: uart1 { | ||||
| 				pinctrl_uart1_sdin: uart1_sdin { | ||||
| 					function = "uart1_sdin"; | ||||
| 					pins = "gpio14"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_uart1_sdout: uart1_sdout { | ||||
| 					function = "uart1_sdout"; | ||||
| 					pins = "gpio15"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_adsl_spi: adsl_spi { | ||||
| 				pinctrl_adsl_spi_miso: adsl_spi_miso { | ||||
| 					function = "adsl_spi_miso"; | ||||
| 					pins = "gpio16"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_adsl_spi_mosi: adsl_spi_mosi { | ||||
| 					function = "adsl_spi_mosi"; | ||||
| 					pins = "gpio17"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_adsl_spi_clk: adsl_spi_clk { | ||||
| 					function = "adsl_spi_clk"; | ||||
| 					pins = "gpio18"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_adsl_spi_cs: adsl_spi_cs { | ||||
| 					function = "adsl_spi_cs"; | ||||
| 					pins = "gpio19"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy0_led: ephy0_led { | ||||
| 				function = "ephy0_led"; | ||||
| 				pins = "gpio20"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy1_led: ephy1_led { | ||||
| 				function = "ephy1_led"; | ||||
| 				pins = "gpio21"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy2_led: ephy2_led { | ||||
| 				function = "ephy2_led"; | ||||
| 				pins = "gpio22"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy3_led: ephy3_led { | ||||
| 				function = "ephy3_led"; | ||||
| 				pins = "gpio23"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ext_irq0: ext_irq0 { | ||||
| 				function = "ext_irq0"; | ||||
| 				pins = "gpio24"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ext_irq1: ext_irq1 { | ||||
| 				function = "ext_irq1"; | ||||
| 				pins = "gpio25"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ext_irq2: ext_irq2 { | ||||
| 				function = "ext_irq2"; | ||||
| 				pins = "gpio26"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ext_irq3: ext_irq3 { | ||||
| 				function = "ext_irq3"; | ||||
| 				pins = "gpio27"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_nand: nand { | ||||
| 				function = "nand"; | ||||
| 				group = "nand_grp"; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		uart0: serial@10000100 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000100 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6362_IRQ_UART0>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		uart1: serial@10000120 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000120 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6362_IRQ_UART1>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		nflash: nand@10000200 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,nand-bcm6368", | ||||
| 				     "brcm,brcmnand-v2.2", | ||||
| 				     "brcm,brcmnand"; | ||||
| 			reg = <0x10000200 0x180>, | ||||
| 			      <0x10000600 0x200>, | ||||
| 			      <0x10000070 0x10>; | ||||
| 			reg-names = "nand", | ||||
| 				    "nand-cache", | ||||
| 				    "nand-int-base"; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6362_IRQ_NAND>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6362_CLK_NAND>; | ||||
| 			clock-names = "nand"; | ||||
|  | ||||
| 			pinctrl-names = "default"; | ||||
| 			pinctrl-0 = <&pinctrl_nand>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		lsspi: spi@10000800 { | ||||
| 			compatible = "brcm,bcm6358-spi"; | ||||
| 			reg = <0x10000800 0x70c>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6362_IRQ_LSSPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6362_CLK_SPI>; | ||||
| 			clock-names = "spi"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6362_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		hsspi: spi@10001000 { | ||||
| 			compatible = "brcm,bcm6328-hsspi"; | ||||
| 			reg = <0x10001000 0x600>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6362_IRQ_HSSPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6362_CLK_HSSPI>, | ||||
| 				 <&hsspi_osc>; | ||||
| 			clock-names = "hsspi", | ||||
| 				      "pll"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6362_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		periph_pwr: power-controller@10001848 { | ||||
| 			compatible = "brcm,bcm6362-power-controller"; | ||||
| 			reg = <0x10001848 0x4>; | ||||
| 			#power-domain-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		leds: led-controller@10001900 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,bcm6328-leds"; | ||||
| 			reg = <0x10001900 0x24>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ehci: usb@10002500 { | ||||
| 			compatible = "brcm,bcm6362-ehci", "generic-ehci"; | ||||
| 			reg = <0x10002500 0x100>; | ||||
| 			big-endian; | ||||
| 			ignore-oc; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6362_IRQ_EHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ohci: usb@10002600 { | ||||
| 			compatible = "brcm,bcm6362-ohci", "generic-ohci"; | ||||
| 			reg = <0x10002600 0x100>; | ||||
| 			big-endian; | ||||
| 			no-big-frame-no; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6362_IRQ_OHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usbh: usb-phy@10002700 { | ||||
| 			compatible = "brcm,bcm6362-usbh-phy"; | ||||
| 			reg = <0x10002700 0x38>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6362_CLK_USBH>; | ||||
| 			clock-names = "usbh"; | ||||
|  | ||||
| 			power-domains = <&periph_pwr BCM6362_POWER_DOMAIN_USBH>; | ||||
| 			resets = <&periph_rst BCM6362_RST_USBH>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										110
									
								
								target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "bcm6368.dtsi" | ||||
|  | ||||
| / { | ||||
| 	model = "Comtrend VR-3025u"; | ||||
| 	compatible = "comtrend,vr-3025u", "brcm,bcm6368"; | ||||
|  | ||||
| 	aliases { | ||||
| 		led-boot = &led_power_green; | ||||
| 		led-failsafe = &led_power_red; | ||||
| 		led-running = &led_power_green; | ||||
| 		led-upgrade = &led_power_green; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0x00000000 0x04000000>; | ||||
| 	}; | ||||
|  | ||||
| 	keys { | ||||
| 		compatible = "gpio-keys-polled"; | ||||
| 		poll-interval = <20>; | ||||
|  | ||||
| 		reset { | ||||
| 			label = "reset"; | ||||
| 			gpios = <&pinctrl 34 GPIO_ACTIVE_LOW>; | ||||
| 			linux,code = <KEY_RESTART>; | ||||
| 			debounce-interval = <60>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	leds { | ||||
| 		compatible = "gpio-leds"; | ||||
|  | ||||
| 		led@2 { | ||||
| 			label = "green:dsl"; | ||||
| 			gpios = <&pinctrl 2 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		led@5 { | ||||
| 			label = "green:internet"; | ||||
| 			gpios = <&pinctrl 5 GPIO_ACTIVE_HIGH>; | ||||
| 		}; | ||||
|  | ||||
| 		led_power_green: led@22 { | ||||
| 			label = "green:power"; | ||||
| 			gpios = <&pinctrl 22 GPIO_ACTIVE_HIGH>; | ||||
| 		}; | ||||
|  | ||||
| 		led_power_red: led@24 { | ||||
| 			label = "red:power"; | ||||
| 			gpios = <&pinctrl 24 GPIO_ACTIVE_HIGH>; | ||||
| 		}; | ||||
|  | ||||
| 		led@31 { | ||||
| 			label = "red:internet"; | ||||
| 			gpios = <&pinctrl 31 GPIO_ACTIVE_HIGH>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &ehci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &ohci { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pflash { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	partitions { | ||||
| 		compatible = "fixed-partitions"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		cfe: partition@0 { | ||||
| 			label = "CFE"; | ||||
| 			reg = <0x0000000 0x0020000>; | ||||
| 			read-only; | ||||
| 		}; | ||||
|  | ||||
| 		partition@20000 { | ||||
| 			compatible = "brcm,bcm963xx-imagetag"; | ||||
| 			label = "firmware"; | ||||
| 			reg = <0x0020000 0x1fc0000>; | ||||
| 		}; | ||||
|  | ||||
| 		partition@1fe0000 { | ||||
| 			label = "nvram"; | ||||
| 			reg = <0x1fe0000 0x020000>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &pinctrl { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pinctrl_pci &pinctrl_ephy0_led &pinctrl_ephy1_led | ||||
| 		     &pinctrl_ephy2_led &pinctrl_ephy3_led>; | ||||
| }; | ||||
|  | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usbh { | ||||
| 	status = "okay"; | ||||
| }; | ||||
							
								
								
									
										475
									
								
								target/linux/bmips/dts/bcm6368.dtsi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										475
									
								
								target/linux/bmips/dts/bcm6368.dtsi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,475 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include <dt-bindings/clock/bcm6368-clock.h> | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
| #include <dt-bindings/input/input.h> | ||||
| #include <dt-bindings/interrupt-controller/bcm6368-interrupt-controller.h> | ||||
| #include <dt-bindings/reset/bcm6368-reset.h> | ||||
|  | ||||
| / { | ||||
| 	#address-cells = <1>; | ||||
| 	#size-cells = <1>; | ||||
| 	compatible = "brcm,bcm6368"; | ||||
|  | ||||
| 	aliases { | ||||
| 		nflash = &nflash; | ||||
| 		pflash = &pflash; | ||||
| 		pinctrl = &pinctrl; | ||||
| 		serial0 = &uart0; | ||||
| 		serial1 = &uart1; | ||||
| 		spi0 = &lsspi; | ||||
| 	}; | ||||
|  | ||||
| 	chosen { | ||||
| 		bootargs = "console=ttyS0,115200n8 earlycon"; | ||||
| 		stdout-path = "serial0:115200n8"; | ||||
| 	}; | ||||
|  | ||||
| 	clocks { | ||||
| 		periph_osc: periph-osc { | ||||
| 			compatible = "fixed-clock"; | ||||
|  | ||||
| 			#clock-cells = <0>; | ||||
|  | ||||
| 			clock-frequency = <50000000>; | ||||
| 			clock-output-names = "periph"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		mips-hpt-frequency = <200000000>; | ||||
|  | ||||
| 		cpu@0 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <0>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@1 { | ||||
| 			compatible = "brcm,bmips4350", "mips,mips4Kc"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <1>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	cpu_intc: interrupt-controller { | ||||
| 		#address-cells = <0>; | ||||
| 		compatible = "mti,cpu-interrupt-controller"; | ||||
|  | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0 0>; | ||||
| 	}; | ||||
|  | ||||
| 	ubus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		compatible = "simple-bus"; | ||||
| 		ranges; | ||||
|  | ||||
| 		periph_clk: clock-controller@10000004 { | ||||
| 			compatible = "brcm,bcm6368-clocks"; | ||||
| 			reg = <0x10000004 0x4>; | ||||
| 			#clock-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		pll_cntl: syscon@10000008 { | ||||
| 			compatible = "syscon"; | ||||
| 			reg = <0x10000008 0x4>; | ||||
| 			native-endian; | ||||
| 		}; | ||||
|  | ||||
| 		syscon-reboot { | ||||
| 			compatible = "syscon-reboot"; | ||||
| 			regmap = <&pll_cntl>; | ||||
| 			offset = <0x0>; | ||||
| 			mask = <0x1>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_rst: reset-controller@10000010 { | ||||
| 			compatible = "brcm,bcm6345-reset"; | ||||
| 			reg = <0x10000010 0x4>; | ||||
| 			#reset-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc0: interrupt-controller@10000018 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-ext-intc"; | ||||
| 			reg = <0x10000018 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM6368_IRQ_EXT0>, | ||||
| 				     <BCM6368_IRQ_EXT1>, | ||||
| 				     <BCM6368_IRQ_EXT2>, | ||||
| 				     <BCM6368_IRQ_EXT3>; | ||||
| 		}; | ||||
|  | ||||
| 		ext_intc1: interrupt-controller@1000001c { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-ext-intc"; | ||||
| 			reg = <0x1000001c 0x4>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <2>; | ||||
|  | ||||
| 			interrupts = <BCM6368_IRQ_EXT4>, | ||||
| 				     <BCM6368_IRQ_EXT5>; | ||||
| 		}; | ||||
|  | ||||
| 		periph_intc: interrupt-controller@10000020 { | ||||
| 			#address-cells = <1>; | ||||
| 			compatible = "brcm,bcm6345-l1-intc"; | ||||
| 			reg = <0x10000020 0x10>, | ||||
| 			      <0x10000030 0x10>; | ||||
|  | ||||
| 			interrupt-controller; | ||||
| 			#interrupt-cells = <1>; | ||||
|  | ||||
| 			interrupt-parent = <&cpu_intc>; | ||||
| 			interrupts = <2>, <3>; | ||||
| 		}; | ||||
|  | ||||
| 		wdt: watchdog@1000005c { | ||||
| 			compatible = "brcm,bcm7038-wdt"; | ||||
| 			reg = <0x1000005c 0xc>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
|  | ||||
| 			timeout-sec = <30>; | ||||
| 		}; | ||||
|  | ||||
| 		pinctrl: pin-controller@10000080 { | ||||
| 			compatible = "brcm,bcm6368-pinctrl"; | ||||
| 			reg = <0x10000080 0x8>, | ||||
| 			      <0x10000088 0x8>, | ||||
| 			      <0x10000098 0x4>; | ||||
| 			reg-names = "dirout", "dat", "mode"; | ||||
| 			brcm,gpiobasemode = <&gpiobasemode>; | ||||
|  | ||||
| 			gpio-controller; | ||||
| 			#gpio-cells = <2>; | ||||
|  | ||||
| 			interrupts-extended = <&ext_intc1 0 0>, | ||||
| 					      <&ext_intc1 1 0>, | ||||
| 					      <&ext_intc0 0 0>, | ||||
| 					      <&ext_intc0 1 0>, | ||||
| 					      <&ext_intc0 2 0>, | ||||
| 					      <&ext_intc0 3 0>; | ||||
| 			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35", | ||||
| 					  "gpio36", "gpio37"; | ||||
|  | ||||
| 			pinctrl_analog_afe_0: analog_afe_0 { | ||||
| 				function = "analog_afe_0"; | ||||
| 				pins = "gpio0"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_analog_afe_1: analog_afe_1 { | ||||
| 				function = "analog_afe_1"; | ||||
| 				pins = "gpio1"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_sys_irq: sys_irq { | ||||
| 				function = "sys_irq"; | ||||
| 				pins = "gpio2"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_serial_led: serial_led { | ||||
| 				pinctrl_serial_led_data: serial_led_data { | ||||
| 					function = "serial_led_data"; | ||||
| 					pins = "gpio3"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_serial_led_clk: serial_led_clk { | ||||
| 					function = "serial_led_clk"; | ||||
| 					pins = "gpio4"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_inet_led: inet_led { | ||||
| 				function = "inet_led"; | ||||
| 				pins = "gpio5"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy0_led: ephy0_led { | ||||
| 				function = "ephy0_led"; | ||||
| 				pins = "gpio6"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy1_led: ephy1_led { | ||||
| 				function = "ephy1_led"; | ||||
| 				pins = "gpio7"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy2_led: ephy2_led { | ||||
| 				function = "ephy2_led"; | ||||
| 				pins = "gpio8"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ephy3_led: ephy3_led { | ||||
| 				function = "ephy3_led"; | ||||
| 				pins = "gpio9"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led_data: robosw_led_data { | ||||
| 				function = "robosw_led_data"; | ||||
| 				pins = "gpio10"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led_clk: robosw_led_clk { | ||||
| 				function = "robosw_led_clk"; | ||||
| 				pins = "gpio11"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led0: robosw_led0 { | ||||
| 				function = "robosw_led0"; | ||||
| 				pins = "gpio12"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_robosw_led1: robosw_led1 { | ||||
| 				function = "robosw_led1"; | ||||
| 				pins = "gpio13"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_usb_device_led: usb_device_led { | ||||
| 				function = "usb_device_led"; | ||||
| 				pins = "gpio14"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_pci: pci { | ||||
| 				pinctrl_pci_req1: pci_req1 { | ||||
| 					function = "pci_req1"; | ||||
| 					pins = "gpio16"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_pci_gnt1: pci_gnt1 { | ||||
| 					function = "pci_gnt1"; | ||||
| 					pins = "gpio17"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_pci_intb: pci_intb { | ||||
| 					function = "pci_intb"; | ||||
| 					pins = "gpio18"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_pci_req0: pci_req0 { | ||||
| 					function = "pci_req0"; | ||||
| 					pins = "gpio19"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_pci_gnt0: pci_gnt0 { | ||||
| 					function = "pci_gnt0"; | ||||
| 					pins = "gpio20"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_pcmcia: pcmcia { | ||||
| 				pinctrl_pcmcia_cd1: pcmcia_cd1 { | ||||
| 					function = "pcmcia_cd1"; | ||||
| 					pins = "gpio22"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_pcmcia_cd2: pcmcia_cd2 { | ||||
| 					function = "pcmcia_cd2"; | ||||
| 					pins = "gpio23"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_pcmcia_vs1: pcmcia_vs1 { | ||||
| 					function = "pcmcia_vs1"; | ||||
| 					pins = "gpio24"; | ||||
| 				}; | ||||
|  | ||||
| 				pinctrl_pcmcia_vs2: pcmcia_vs2 { | ||||
| 					function = "pcmcia_vs2"; | ||||
| 					pins = "gpio25"; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ebi_cs2: ebi_cs2 { | ||||
| 				function = "ebi_cs2"; | ||||
| 				pins = "gpio26"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_ebi_cs3: ebi_cs3 { | ||||
| 				function = "ebi_cs2"; | ||||
| 				pins = "gpio27"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_spi_cs2: spi_cs2 { | ||||
| 				function = "spi_cs2"; | ||||
| 				pins = "gpio28"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_spi_cs3: spi_cs3 { | ||||
| 				function = "spi_cs3"; | ||||
| 				pins = "gpio29"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_spi_cs4: spi_cs4 { | ||||
| 				function = "spi_cs4"; | ||||
| 				pins = "gpio30"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_spi_cs5: spi_cs5 { | ||||
| 				function = "spi_cs5"; | ||||
| 				pins = "gpio31"; | ||||
| 			}; | ||||
|  | ||||
| 			pinctrl_uart1: uart1 { | ||||
| 				function = "uart1"; | ||||
| 				group = "uart1_grp"; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		gpiobasemode: gpiobasemode@100000b8 { | ||||
| 			compatible = "brcm,bcm6368-gpiobasemode", "syscon"; | ||||
| 			reg = <0x100000b8 0x4>; | ||||
| 		}; | ||||
|  | ||||
| 		leds: led-controller@100000d0 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,bcm6358-leds"; | ||||
| 			reg = <0x100000d0 0x8>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		uart0: serial@10000100 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000100 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6368_IRQ_UART0>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		uart1: serial@10000120 { | ||||
| 			compatible = "brcm,bcm6345-uart"; | ||||
| 			reg = <0x10000120 0x18>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6368_IRQ_UART1>; | ||||
|  | ||||
| 			clocks = <&periph_osc>; | ||||
| 			clock-names = "periph"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		nflash: nand@10000200 { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			compatible = "brcm,nand-bcm6368", | ||||
| 				     "brcm,brcmnand-v2.1", | ||||
| 				     "brcm,brcmnand"; | ||||
| 			reg = <0x10000200 0x180>, | ||||
| 			      <0x10000600 0x200>, | ||||
| 			      <0x10000070 0x10>; | ||||
| 			reg-names = "nand", | ||||
| 				    "nand-cache", | ||||
| 				    "nand-int-base"; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6368_IRQ_NAND>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6368_CLK_NAND>; | ||||
| 			clock-names = "nand"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		lsspi: spi@10000800 { | ||||
| 			compatible = "brcm,bcm6358-spi"; | ||||
| 			reg = <0x10000800 0x70c>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6368_IRQ_SPI>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6368_CLK_SPI>; | ||||
| 			clock-names = "spi"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6368_RST_SPI>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ehci: usb@10001500 { | ||||
| 			compatible = "brcm,bcm6368-ehci", "generic-ehci"; | ||||
| 			reg = <0x10001500 0x100>; | ||||
| 			big-endian; | ||||
| 			ignore-oc; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6368_IRQ_EHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		ohci: usb@10001600 { | ||||
| 			compatible = "brcm,bcm6368-ohci", "generic-ohci"; | ||||
| 			reg = <0x10001600 0x100>; | ||||
| 			big-endian; | ||||
| 			no-big-frame-no; | ||||
|  | ||||
| 			interrupt-parent = <&periph_intc>; | ||||
| 			interrupts = <BCM6368_IRQ_OHCI>; | ||||
|  | ||||
| 			phys = <&usbh 0>; | ||||
| 			phy-names = "usb"; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usbh: usb-phy@10001700 { | ||||
| 			compatible = "brcm,bcm6368-usbh-phy"; | ||||
| 			reg = <0x10001700 0x38>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6368_CLK_USBH>; | ||||
| 			clock-names = "usbh"; | ||||
|  | ||||
| 			resets = <&periph_rst BCM6368_RST_USBH>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		random: rng@10004180 { | ||||
| 			compatible = "brcm,bcm6368-rng"; | ||||
| 			reg = <0x10004180 0x14>; | ||||
|  | ||||
| 			clocks = <&periph_clk BCM6368_CLK_IPSEC>; | ||||
| 			clock-names = "ipsec"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	pflash: nor@18000000 { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
| 		compatible = "cfi-flash"; | ||||
| 		reg = <0x18000000 0x2000000>; | ||||
| 		bank-width = <2>; | ||||
|  | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
| }; | ||||
| @@ -0,0 +1,84 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #ifndef __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6318_H | ||||
| #define __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6318_H | ||||
|  | ||||
| #define BCM6318_IRQ_TIMER0		0 | ||||
| #define BCM6318_IRQ_TIMER1		1 | ||||
| #define BCM6318_IRQ_TIMER2		2 | ||||
| #define BCM6318_IRQ_TIMER3		3 | ||||
| #define BCM6318_IRQ_USBS		4 | ||||
| #define BCM6318_IRQ_USB_CTL_RX_DMA	5 | ||||
| #define BCM6318_IRQ_USB_CTL_TX_DMA	6 | ||||
| #define BCM6318_IRQ_USB_BULK_RX_DMA	7 | ||||
| #define BCM6318_IRQ_USB_BULK_TX_DMA	8 | ||||
| #define BCM6318_IRQ_USB_ISO_RX_DMA	9 | ||||
| #define BCM6318_IRQ_USB_ISO_TX_DMA	10 | ||||
| #define BCM6318_IRQ_DG			11 | ||||
| #define BCM6318_IRQ_EPHY		12 | ||||
| #define BCM6318_IRQ_EPHY_EN0N		13 | ||||
| #define BCM6318_IRQ_EPHY_EN1N		14 | ||||
| #define BCM6318_IRQ_EPHY_EN2N		15 | ||||
| #define BCM6318_IRQ_EPHY_EN3N		16 | ||||
| #define BCM6318_IRQ_EPHY_EN0		17 | ||||
| #define BCM6318_IRQ_EPHY_EN1		18 | ||||
| #define BCM6318_IRQ_EPHY_EN2		19 | ||||
| #define BCM6318_IRQ_EPHY_EN3		20 | ||||
| #define BCM6318_IRQ_XDSL		21 | ||||
| #define BCM6318_IRQ_SDR			22 | ||||
| #define BCM6318_IRQ_PCIE_RC		23 | ||||
| #define BCM6318_IRQ_EXT0		24 | ||||
| #define BCM6318_IRQ_EXT1		25 | ||||
| #define BCM6318_IRQ_EXT2		26 | ||||
| #define BCM6318_IRQ_EXT3		27 | ||||
| #define BCM6318_IRQ_UART0		28 | ||||
| #define BCM6318_IRQ_HSSPI		29 | ||||
| #define BCM6318_IRQ_WAKE_ON_IRQ		30 | ||||
| #define BCM6318_IRQ_TIMER		31 | ||||
| #define BCM6318_IRQ_ENETSW_RX_DMA0	32 | ||||
| #define BCM6318_IRQ_ENETSW_RX_DMA1	33 | ||||
| #define BCM6318_IRQ_ENETSW_RX_DMA2	34 | ||||
| #define BCM6318_IRQ_ENETSW_RX_DMA3	35 | ||||
| #define BCM6318_IRQ_WDTIMER		37 | ||||
| #define BCM6318_IRQ_ENETSW		40 | ||||
| #define BCM6318_IRQ_OHCI		41 | ||||
| #define BCM6318_IRQ_EHCI		42 | ||||
| #define BCM6318_IRQ_ATM_DMA0		43 | ||||
| #define BCM6318_IRQ_ATM_DMA1		44 | ||||
| #define BCM6318_IRQ_ATM_DMA2		45 | ||||
| #define BCM6318_IRQ_ATM_DMA3		46 | ||||
| #define BCM6318_IRQ_ATM_DMA4		47 | ||||
| #define BCM6318_IRQ_ATM_DMA5		48 | ||||
| #define BCM6318_IRQ_ATM_DMA6		49 | ||||
| #define BCM6318_IRQ_ATM_DMA7		50 | ||||
| #define BCM6318_IRQ_ATM_DMA8		51 | ||||
| #define BCM6318_IRQ_ATM_DMA9		52 | ||||
| #define BCM6318_IRQ_ATM_DMA10		53 | ||||
| #define BCM6318_IRQ_ATM_DMA11		54 | ||||
| #define BCM6318_IRQ_ATM_DMA12		55 | ||||
| #define BCM6318_IRQ_ATM_DMA13		56 | ||||
| #define BCM6318_IRQ_ATM_DMA14		57 | ||||
| #define BCM6318_IRQ_ATM_DMA15		58 | ||||
| #define BCM6318_IRQ_ATM_DMA16		59 | ||||
| #define BCM6318_IRQ_ATM_DMA17		60 | ||||
| #define BCM6318_IRQ_ATM_DMA18		61 | ||||
| #define BCM6318_IRQ_ATM_DMA19		62 | ||||
| #define BCM6318_IRQ_SAR			63 | ||||
| #define BCM6318_IRQ_ADSL_ENERGY		64 | ||||
| #define BCM6318_IRQ_ADSL_ENERGY_N	65 | ||||
| #define BCM6318_IRQ_USB_ENERGY_ON	66 | ||||
| #define BCM6318_IRQ_USB_ENERGY_OFF	67 | ||||
| #define BCM6318_IRQ_PVTMON_TEMP		68 | ||||
| #define BCM6318_IRQ_SYSPLL_LOCK		69 | ||||
| #define BCM6318_IRQ_LCPLL_LOCK		70 | ||||
| #define BCM6318_IRQ_PMU_STABLE		71 | ||||
| #define BCM6318_IRQ_ENETSW_TX_DMA0	72 | ||||
| #define BCM6318_IRQ_ENETSW_TX_DMA1	73 | ||||
| #define BCM6318_IRQ_ENETSW_TX_DMA2	74 | ||||
| #define BCM6318_IRQ_ENETSW_TX_DMA3	75 | ||||
| #define BCM6318_IRQ_EPHY0_IDDQ_ENERGY	76 | ||||
| #define BCM6318_IRQ_EPHY1_IDDQ_ENERGY	77 | ||||
| #define BCM6318_IRQ_EPHY2_IDDQ_ENERGY	78 | ||||
| #define BCM6318_IRQ_EPHY3_IDDQ_ENERGY	79 | ||||
|  | ||||
| #endif /* __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6318_H */ | ||||
| @@ -0,0 +1,86 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #ifndef __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM63268_H | ||||
| #define __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM63268_H | ||||
|  | ||||
| #define BCM63268_IRQ_TIMER		0 | ||||
| #define BCM63268_IRQ_ENETSW_RX_DMA0	1 | ||||
| #define BCM63268_IRQ_ENETSW_RX_DMA1	2 | ||||
| #define BCM63268_IRQ_ENETSW_RX_DMA2	3 | ||||
| #define BCM63268_IRQ_ENETSW_RX_DMA3	4 | ||||
| #define BCM63268_IRQ_UART0		5 | ||||
| #define BCM63268_IRQ_HSSPI		6 | ||||
| #define BCM63268_IRQ_WLAN		7 | ||||
| #define BCM63268_IRQ_IPSEC		8 | ||||
| #define BCM63268_IRQ_OHCI		9 | ||||
| #define BCM63268_IRQ_EHCI		10 | ||||
| #define BCM63268_IRQ_USBS		11 | ||||
| #define BCM63268_IRQ_PCM		12 | ||||
| #define BCM63268_IRQ_EPHY		13 | ||||
| #define BCM63268_IRQ_DG			14 | ||||
| #define BCM63268_IRQ_EPHY0_EN		15 | ||||
| #define BCM63268_IRQ_EPHY1_EN		16 | ||||
| #define BCM63268_IRQ_EPHY2_EN		17 | ||||
| #define BCM63268_IRQ_GPHY_EN		18 | ||||
| #define BCM63268_IRQ_USB_CTL_RX_DMA	19 | ||||
| #define BCM63268_IRQ_USB_BULK_RX_DMA	20 | ||||
| #define BCM63268_IRQ_ISO_RX_DMA		21 | ||||
| #define BCM63268_IRQ_IPSEC_DMA0		22 | ||||
| #define BCM63268_IRQ_XDSL		23 | ||||
| #define BCM63268_IRQ_FAP0		24 | ||||
| #define BCM63268_IRQ_FAP1		25 | ||||
| #define BCM63268_IRQ_ATM_DMA0		26 | ||||
| #define BCM63268_IRQ_ATM_DMA1		27 | ||||
| #define BCM63268_IRQ_ATM_DMA2		28 | ||||
| #define BCM63268_IRQ_ATM_DMA3		29 | ||||
| #define BCM63268_IRQ_WAKE_ON_IRQ	30 | ||||
| #define BCM63268_IRQ_GPHY		31 | ||||
| #define BCM63268_IRQ_DECT0              32		 | ||||
| #define BCM63268_IRQ_DECT1		33 | ||||
| #define BCM63268_IRQ_UART1              34		 | ||||
| #define BCM63268_IRQ_WLAN_GPIO		35 | ||||
| #define BCM63268_IRQ_USB_CTL_TX_DMA	36 | ||||
| #define BCM63268_IRQ_USB_BULK_TX_DMA	37 | ||||
| #define BCM63268_IRQ_ISO_TX_DMA		38 | ||||
| #define BCM63268_IRQ_IPSEC_DMA1		39 | ||||
| #define BCM63268_IRQ_PCIE_RC		40 | ||||
| #define BCM63268_IRQ_PCIE_EP		41 | ||||
| #define BCM63268_IRQ_PCM_DMA0		42 | ||||
| #define BCM63268_IRQ_PCM_DMA1		43 | ||||
| #define BCM63268_IRQ_EXT0		44 | ||||
| #define BCM63268_IRQ_EXT1		45 | ||||
| #define BCM63268_IRQ_EXT2		46 | ||||
| #define BCM63268_IRQ_EXT3		47 | ||||
| #define BCM63268_IRQ_ENETSW		48 | ||||
| #define BCM63268_IRQ_SAR		49 | ||||
| #define BCM63268_IRQ_NAND		50 | ||||
| #define BCM63268_IRQ_RING_OSC		52 | ||||
| #define BCM63268_IRQ_USB_CONNECT	53 | ||||
| #define BCM63268_IRQ_USB_DISCONNECT	54 | ||||
| #define BCM63268_IRQ_PER_MBOX0		55 | ||||
| #define BCM63268_IRQ_PER_MBOX1		56 | ||||
| #define BCM63268_IRQ_PER_MBOX2		57 | ||||
| #define BCM63268_IRQ_PER_MBOX3		58 | ||||
| #define BCM63268_IRQ_ATM_DMA4		59 | ||||
| #define BCM63268_IRQ_ATM_DMA5		60 | ||||
| #define BCM63268_IRQ_ATM_DMA6		61 | ||||
| #define BCM63268_IRQ_ATM_DMA7		62 | ||||
| #define BCM63268_IRQ_ENETSW_TX_DMA0	64 | ||||
| #define BCM63268_IRQ_ENETSW_TX_DMA1	65 | ||||
| #define BCM63268_IRQ_ENETSW_TX_DMA2	66 | ||||
| #define BCM63268_IRQ_ENETSW_TX_DMA3	67 | ||||
| #define BCM63268_IRQ_ATM_DMA8		68 | ||||
| #define BCM63268_IRQ_ATM_DMA9		69 | ||||
| #define BCM63268_IRQ_ATM_DMA10		70 | ||||
| #define BCM63268_IRQ_ATM_DMA11		71 | ||||
| #define BCM63268_IRQ_ATM_DMA12		72 | ||||
| #define BCM63268_IRQ_ATM_DMA13		73 | ||||
| #define BCM63268_IRQ_ATM_DMA14		74 | ||||
| #define BCM63268_IRQ_ATM_DMA15		75 | ||||
| #define BCM63268_IRQ_ATM_DMA16		76 | ||||
| #define BCM63268_IRQ_ATM_DMA17		77 | ||||
| #define BCM63268_IRQ_ATM_DMA18		78 | ||||
| #define BCM63268_IRQ_ATM_DMA19		79 | ||||
| #define BCM63268_IRQ_LSSPI		80 | ||||
|  | ||||
| #endif /* __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM63268_H */ | ||||
| @@ -0,0 +1,68 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #ifndef __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6328_H | ||||
| #define __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6328_H | ||||
|  | ||||
| #define BCM6328_IRQ_NAND		0 | ||||
| #define BCM6328_IRQ_PCM			1 | ||||
| #define BCM6328_IRQ_PCM_DMA0		2 | ||||
| #define BCM6328_IRQ_PCM_DMA1		3 | ||||
| #define BCM6328_IRQ_USBS		4 | ||||
| #define BCM6328_IRQ_USB_CTL_RX_DMA	5 | ||||
| #define BCM6328_IRQ_USB_CTL_TX_DMA	6 | ||||
| #define BCM6328_IRQ_USB_BULK_RX_DMA	7 | ||||
| #define BCM6328_IRQ_USB_BULK_TX_DMA	8 | ||||
| #define BCM6328_IRQ_USB_ISO_RX_DMA	9 | ||||
| #define BCM6328_IRQ_USB_ISO_TX_DMA	10 | ||||
| #define BCM6328_IRQ_DG			11 | ||||
| #define BCM6328_IRQ_EPHY		12 | ||||
| #define BCM6328_IRQ_EPHY_EN0N		13 | ||||
| #define BCM6328_IRQ_EPHY_EN1N		14 | ||||
| #define BCM6328_IRQ_EPHY_EN2N		15 | ||||
| #define BCM6328_IRQ_EPHY_EN3N		16 | ||||
| #define BCM6328_IRQ_EPHY_EN0		17 | ||||
| #define BCM6328_IRQ_EPHY_EN1		18 | ||||
| #define BCM6328_IRQ_EPHY_EN2		19 | ||||
| #define BCM6328_IRQ_EPHY_EN3		20 | ||||
| #define BCM6328_IRQ_XDSL		21 | ||||
| #define BCM6328_IRQ_PCIE_EP		22 | ||||
| #define BCM6328_IRQ_PCIE_RC		23 | ||||
| #define BCM6328_IRQ_EXTO		24 | ||||
| #define BCM6328_IRQ_EXT1		25 | ||||
| #define BCM6328_IRQ_EXT2		26 | ||||
| #define BCM6328_IRQ_EXT3		27 | ||||
| #define BCM6328_IRQ_UART0		28 | ||||
| #define BCM6328_IRQ_HSSPI		29 | ||||
| #define BCM6328_IRQ_WAKE_ON_IRQ		30 | ||||
| #define BCM6328_IRQ_TIMER		31 | ||||
| #define BCM6328_IRQ_ENETSW_RX_DMA0	32 | ||||
| #define BCM6328_IRQ_ENETSW_RX_DMA1	33 | ||||
| #define BCM6328_IRQ_ENETSW_TX_DMA0	34 | ||||
| #define BCM6328_IRQ_ENETSW_TX_DMA1	35 | ||||
| #define BCM6328_IRQ_UART1		39 | ||||
| #define BCM6328_IRQ_ENETSW		40 | ||||
| #define BCM6328_IRQ_OHCI		41 | ||||
| #define BCM6328_IRQ_EHCI		42 | ||||
| #define BCM6328_IRQ_ATM_DMA0		43 | ||||
| #define BCM6328_IRQ_ATM_DMA1		44 | ||||
| #define BCM6328_IRQ_ATM_DMA2		45 | ||||
| #define BCM6328_IRQ_ATM_DMA3		46 | ||||
| #define BCM6328_IRQ_ATM_DMA4		47 | ||||
| #define BCM6328_IRQ_ATM_DMA5		48 | ||||
| #define BCM6328_IRQ_ATM_DMA6		49 | ||||
| #define BCM6328_IRQ_ATM_DMA7		50 | ||||
| #define BCM6328_IRQ_ATM_DMA8		51 | ||||
| #define BCM6328_IRQ_ATM_DMA9		52 | ||||
| #define BCM6328_IRQ_ATM_DMA10		53 | ||||
| #define BCM6328_IRQ_ATM_DMA11		54 | ||||
| #define BCM6328_IRQ_ATM_DMA12		55 | ||||
| #define BCM6328_IRQ_ATM_DMA13		56 | ||||
| #define BCM6328_IRQ_ATM_DMA14		57 | ||||
| #define BCM6328_IRQ_ATM_DMA15		58 | ||||
| #define BCM6328_IRQ_ATM_DMA16		59 | ||||
| #define BCM6328_IRQ_ATM_DMA17		60 | ||||
| #define BCM6328_IRQ_ATM_DMA18		61 | ||||
| #define BCM6328_IRQ_ATM_DMA19		62 | ||||
| #define BCM6328_IRQ_SAR			63 | ||||
|  | ||||
| #endif /* __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6328_H */ | ||||
| @@ -0,0 +1,38 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #ifndef __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6358_H | ||||
| #define __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6358_H | ||||
|  | ||||
| #define BCM6358_IRQ_TIMER		0 | ||||
| #define BCM6358_IRQ_SPI			1 | ||||
| #define BCM6358_IRQ_UART0		2 | ||||
| #define BCM6358_IRQ_UART1		3 | ||||
| #define BCM6358_IRQ_OHCI		5 | ||||
| #define BCM6358_IRQ_EMAC1		6 | ||||
| #define BCM6358_IRQ_USBS		7 | ||||
| #define BCM6358_IRQ_EMAC0		8 | ||||
| #define BCM6358_IRQ_EPHY		9 | ||||
| #define BCM6358_IRQ_EHCI		10 | ||||
| #define BCM6358_IRQ_USB_CTL_RX_DMA	11 | ||||
| #define BCM6358_IRQ_USB_CTL_TX_DMA	12 | ||||
| #define BCM6358_IRQ_USB_BULK_RX_DMA	13 | ||||
| #define BCM6358_IRQ_USB_BULK_TX_DMA	14 | ||||
| #define BCM6358_IRQ_EMAC0_RX_DMA	15 | ||||
| #define BCM6358_IRQ_EMAC0_TX_DMA	16 | ||||
| #define BCM6358_IRQ_EMAC1_RX_DMA	17 | ||||
| #define BCM6358_IRQ_EMAC1_TX_DMA	18 | ||||
| #define BCM6358_IRQ_ATM		        19 | ||||
| #define BCM6358_IRQ_EXT4		20 | ||||
| #define BCM6358_IRQ_EXT5		21 | ||||
| #define BCM6358_IRQ_PCM			22 | ||||
| #define BCM6358_IRQ_PCM_RX_DMA		23 | ||||
| #define BCM6358_IRQ_PCM_TX_DMA		24 | ||||
| #define BCM6358_IRQ_EXT0		25 | ||||
| #define BCM6358_IRQ_EXT1		26 | ||||
| #define BCM6358_IRQ_EXT2		27 | ||||
| #define BCM6358_IRQ_EXT3		28 | ||||
| #define BCM6358_IRQ_ADSL		29 | ||||
| #define BCM6358_IRQ_DG			30 | ||||
| #define BCM6358_IRQ_MPI			31 | ||||
|  | ||||
| #endif /* __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6358_H */ | ||||
| @@ -0,0 +1,71 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #ifndef __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6362_H | ||||
| #define __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6362_H | ||||
|  | ||||
| #define BCM6362_IRQ_TIMER		0 | ||||
| #define BCM6362_IRQ_RING_OSC		1 | ||||
| #define BCM6362_IRQ_LSSPI		2 | ||||
| #define BCM6362_IRQ_UART0		3 | ||||
| #define BCM6362_IRQ_UART1		4 | ||||
| #define BCM6362_IRQ_HSSPI		5 | ||||
| #define BCM6362_IRQ_WLAN_GPIO		6 | ||||
| #define BCM6362_IRQ_WLAN		7 | ||||
| #define BCM6362_IRQ_IPSEC		8 | ||||
| #define BCM6362_IRQ_OHCI		9 | ||||
| #define BCM6362_IRQ_EHCI		10 | ||||
| #define BCM6362_IRQ_USBS		11 | ||||
| #define BCM6362_IRQ_NAND		12 | ||||
| #define BCM6362_IRQ_PCM			13 | ||||
| #define BCM6362_IRQ_EPHY		14 | ||||
| #define BCM6362_IRQ_DF			15 | ||||
| #define BCM6362_IRQ_EPHY_EN0		16 | ||||
| #define BCM6362_IRQ_EPHY_EN1		17 | ||||
| #define BCM6362_IRQ_EPHY_EN2		18 | ||||
| #define BCM6362_IRQ_EPHY_EN3		19 | ||||
| #define BCM6362_IRQ_USB_CTL_RX_DMA	20 | ||||
| #define BCM6362_IRQ_USB_CTL_TX_DMA	21 | ||||
| #define BCM6362_IRQ_USB_BULK_RX_DMA	22 | ||||
| #define BCM6362_IRQ_USB_BULK_TX_DMA	23 | ||||
| #define BCM6362_IRQ_USB_ISO_RX_DMA	24 | ||||
| #define BCM6362_IRQ_USB_ISO_TX_DMA	25 | ||||
| #define BCM6362_IRQ_IPSEC_DMA0		26 | ||||
| #define BCM6362_IRQ_IPSEC_DMA1		27 | ||||
| #define BCM6362_IRQ_XDSL		28 | ||||
| #define BCM6362_IRQ_FAP			29 | ||||
| #define BCM6362_IRQ_PCIE_RC		30 | ||||
| #define BCM6362_IRQ_PCIE_EP		31 | ||||
| #define BCM6362_IRQ_ENETSW_RX_DMA0	32 | ||||
| #define BCM6362_IRQ_ENETSW_RX_DMA1	33 | ||||
| #define BCM6362_IRQ_ENETSW_RX_DMA2	34 | ||||
| #define BCM6362_IRQ_ENETSW_RX_DMA3	35 | ||||
| #define BCM6362_IRQ_PCM_DMA0		36 | ||||
| #define BCM6362_IRQ_PCM_DMA1		37 | ||||
| #define BCM6362_IRQ_DECT0		38 | ||||
| #define BCM6362_IRQ_DECT1		39 | ||||
| #define BCM6362_IRQ_EXT0		40 | ||||
| #define BCM6362_IRQ_EXT1		41 | ||||
| #define BCM6362_IRQ_EXT2		42 | ||||
| #define BCM6362_IRQ_EXT3		43 | ||||
| #define BCM6362_IRQ_ATM_DMA0		44 | ||||
| #define BCM6362_IRQ_ATM_DMA1		45 | ||||
| #define BCM6362_IRQ_ATM_DMA2		46 | ||||
| #define BCM6362_IRQ_ATM_DMA3		47 | ||||
| #define BCM6362_IRQ_ATM_DMA4		48 | ||||
| #define BCM6362_IRQ_ATM_DMA5		49 | ||||
| #define BCM6362_IRQ_ATM_DMA6		50 | ||||
| #define BCM6362_IRQ_ATM_DMA7		51 | ||||
| #define BCM6362_IRQ_ATM_DMA8		52 | ||||
| #define BCM6362_IRQ_ATM_DMA9		53 | ||||
| #define BCM6362_IRQ_ATM_DMA10		54 | ||||
| #define BCM6362_IRQ_ATM_DMA11		55 | ||||
| #define BCM6362_IRQ_ATM_DMA12		56 | ||||
| #define BCM6362_IRQ_ATM_DMA13		57 | ||||
| #define BCM6362_IRQ_ATM_DMA14		58 | ||||
| #define BCM6362_IRQ_ATM_DMA15		59 | ||||
| #define BCM6362_IRQ_ATM_DMA16		60 | ||||
| #define BCM6362_IRQ_ATM_DMA17		61 | ||||
| #define BCM6362_IRQ_ATM_DMA18		62		 | ||||
| #define BCM6362_IRQ_ATM_DMA19		63 | ||||
|  | ||||
| #endif /* __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6362_H */ | ||||
| @@ -0,0 +1,71 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #ifndef __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6368_H | ||||
| #define __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6368_H | ||||
|  | ||||
| #define BCM6368_IRQ_TIMER		0 | ||||
| #define BCM6368_IRQ_SPI			1 | ||||
| #define BCM6368_IRQ_UART0		2 | ||||
| #define BCM6368_IRQ_UART1		3 | ||||
| #define BCM6368_IRQ_XDSL		4 | ||||
| #define BCM6368_IRQ_OHCI		5 | ||||
| #define BCM6368_IRQ_IPSEC		6 | ||||
| #define BCM6368_IRQ_EHCI		7 | ||||
| #define BCM6368_IRQ_USBS		8 | ||||
| #define BCM6368_IRQ_RING_OSC		9 | ||||
| #define BCM6368_IRQ_NAND		10 | ||||
| #define BCM6368_IRQ_ATM			11 | ||||
| #define BCM6368_IRQ_PCM			12 | ||||
| #define BCM6368_IRQ_MPI			13 | ||||
| #define BCM6368_IRQ_DG			14 | ||||
| #define BCM6368_IRQ_EPHY		15 | ||||
| #define BCM6368_IRQ_EPHY_EN0		16 | ||||
| #define BCM6368_IRQ_EPHY_EN1		17 | ||||
| #define BCM6368_IRQ_EPHY_EN2		18 | ||||
| #define BCM6368_IRQ_EPHY_EN3		19 | ||||
| #define BCM6368_IRQ_EXT0		20 | ||||
| #define BCM6368_IRQ_EXT1		21 | ||||
| #define BCM6368_IRQ_EXT2		22 | ||||
| #define BCM6368_IRQ_EXT3		23 | ||||
| #define BCM6368_IRQ_EXT4		24 | ||||
| #define BCM6368_IRQ_EXT5		25 | ||||
| #define BCM6368_IRQ_USB_CTL_RX_DMA	26 | ||||
| #define BCM6368_IRQ_USB_CTL_TX_DMA	27 | ||||
| #define BCM6368_IRQ_USB_BULK_RX_DMA	28 | ||||
| #define BCM6368_IRQ_USB_BULK_TX_DMA	29 | ||||
| #define BCM6368_IRQ_USB_ISO_RX_DMA	30 | ||||
| #define BCM6368_IRQ_USB_ISO_TX_DMA	31 | ||||
| #define BCM6368_IRQ_ENETSW_RX_DMA0	32	 | ||||
| #define BCM6368_IRQ_ENETSW_RX_DMA1	33	 | ||||
| #define BCM6368_IRQ_ENETSW_RX_DMA2	34	 | ||||
| #define BCM6368_IRQ_ENETSW_RX_DMA3	35	 | ||||
| #define BCM6368_IRQ_ENETSW_TX_DMA0	36	 | ||||
| #define BCM6368_IRQ_ENETSW_TX_DMA1	37	 | ||||
| #define BCM6368_IRQ_ENETSW_TX_DMA2	38	 | ||||
| #define BCM6368_IRQ_ENETSW_TX_DMA3	39	 | ||||
| #define BCM6368_IRQ_ATM_DMA0		40 | ||||
| #define BCM6368_IRQ_ATM_DMA1		41 | ||||
| #define BCM6368_IRQ_ATM_DMA2		42 | ||||
| #define BCM6368_IRQ_ATM_DMA3		43 | ||||
| #define BCM6368_IRQ_ATM_DMA4		44 | ||||
| #define BCM6368_IRQ_ATM_DMA5		45 | ||||
| #define BCM6368_IRQ_ATM_DMA6		46 | ||||
| #define BCM6368_IRQ_ATM_DMA7		47 | ||||
| #define BCM6368_IRQ_ATM_DMA8		48 | ||||
| #define BCM6368_IRQ_ATM_DMA9		49 | ||||
| #define BCM6368_IRQ_ATM_DMA10		50 | ||||
| #define BCM6368_IRQ_ATM_DMA11		51 | ||||
| #define BCM6368_IRQ_ATM_DMA12		52 | ||||
| #define BCM6368_IRQ_ATM_DMA13		53 | ||||
| #define BCM6368_IRQ_ATM_DMA14		54 | ||||
| #define BCM6368_IRQ_ATM_DMA15		55 | ||||
| #define BCM6368_IRQ_ATM_DMA16		56 | ||||
| #define BCM6368_IRQ_ATM_DMA17		57 | ||||
| #define BCM6368_IRQ_ATM_DMA18		58 | ||||
| #define BCM6368_IRQ_ATM_DMA19		59 | ||||
| #define BCM6368_IRQ_IPSEC_DMA0		60 | ||||
| #define BCM6368_IRQ_IPSEC_DMA1		61 | ||||
| #define BCM6368_IRQ_PCM_DMA0		62 | ||||
| #define BCM6368_IRQ_PCM_DMA1		63 | ||||
|  | ||||
| #endif /* __DT_BINDINGS_INTERRUPT_CONTROLLER_BCM6368_H */ | ||||
							
								
								
									
										3
									
								
								target/linux/bmips/generic/config-default
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								target/linux/bmips/generic/config-default
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
| CONFIG_MTD_SPLIT_BCM63XX_FW=y | ||||
							
								
								
									
										5
									
								
								target/linux/bmips/generic/target.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								target/linux/bmips/generic/target.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| BOARDNAME:=generic | ||||
|  | ||||
| define Target/Description | ||||
|   BMIPS boards without NAND support  | ||||
| endef | ||||
							
								
								
									
										257
									
								
								target/linux/bmips/image/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								target/linux/bmips/image/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,257 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| include $(TOPDIR)/rules.mk | ||||
| include $(INCLUDE_DIR)/image.mk | ||||
|  | ||||
| KERNEL_LOADADDR := 0x80010000		# RAM start + 64K | ||||
| LOADER_ENTRY := 0x80a00000		# RAM start + 10M, for relocate | ||||
| RAMSIZE := 0x02000000			# 32MB | ||||
| LZMA_TEXT_START := 0x81800000		# 32MB - 8MB | ||||
|  | ||||
| DEVICE_VARS += CHIP_ID DEVICE_LOADADDR | ||||
|  | ||||
| define Build/Compile | ||||
| 	rm -rf $(KDIR)/relocate | ||||
| 	$(CP) ../../generic/image/relocate $(KDIR) | ||||
| 	$(MAKE) -C $(KDIR)/relocate \ | ||||
| 		CACHELINE_SIZE=16 \ | ||||
| 		CROSS_COMPILE=$(TARGET_CROSS) \ | ||||
| 		KERNEL_ADDR=$(KERNEL_LOADADDR) \ | ||||
| 		LZMA_TEXT_START=$(LOADER_ENTRY) | ||||
| endef | ||||
|  | ||||
| ### Kernel scripts ### | ||||
| define Build/loader-lzma | ||||
| 	@rm -rf $@.src | ||||
| 	$(MAKE) -C lzma-loader \ | ||||
| 		CHIP_ID=$(CHIP_ID) \ | ||||
| 		KERNEL_ADDR=$(KERNEL_LOADADDR) \ | ||||
| 		KDIR=$(KDIR) \ | ||||
| 		LOADER_ADDR=$(if $(DEVICE_LOADADDR),$(DEVICE_LOADADDR),$(LOADER_ENTRY)) \ | ||||
| 		LOADER_DATA="$@" \ | ||||
| 		LOADER_NAME="$(notdir $@)" \ | ||||
| 		LZMA_TEXT_START=$(LZMA_TEXT_START) \ | ||||
| 		PKG_BUILD_DIR="$@.src" \ | ||||
| 		RAMSIZE=$(RAMSIZE) \ | ||||
| 		TARGET_DIR="$(dir $@)" \ | ||||
| 		compile loader.$(1) | ||||
| 	@mv "$@.$(1)" "$@" | ||||
| 	@rm -rf $@.src | ||||
| endef | ||||
|  | ||||
| define Build/lzma-cfe | ||||
| 	# CFE is a LZMA nazi! It took me hours to find out the parameters! | ||||
| 	# Also I think lzma has a bug cause it generates different output depending on | ||||
| 	# if you use stdin / stdout or not. Use files instead of stdio here, cause | ||||
| 	# otherwise CFE will complain and not boot the image. | ||||
| 	$(call Build/lzma-no-dict,-d22 -fb64 -a1) | ||||
| 	# Strip out the length, CFE doesn't like this | ||||
| 	dd if=$@ of=$@.new bs=5 count=1 | ||||
| 	dd if=$@ of=$@.new ibs=13 obs=5 skip=1 seek=1 conv=notrunc | ||||
| 	@mv $@.new $@ | ||||
| endef | ||||
|  | ||||
| define Build/relocate-kernel | ||||
| 	# CFE only allows ~4 MiB for the uncompressed kernels, but uncompressed | ||||
| 	# kernel might get larger than that, so let CFE unpack and load at a | ||||
| 	# higher address and make the kernel relocate itself to the expected | ||||
| 	# location. | ||||
| 	( \ | ||||
| 		dd if=$(KDIR)/relocate/loader.bin bs=32 conv=sync && \ | ||||
| 		perl -e '@s = stat("$@"); print pack("N", @s[7])' && \ | ||||
| 		cat $@ \ | ||||
| 	) > $@.relocate | ||||
| 	@mv $@.relocate $@ | ||||
| endef | ||||
|  | ||||
| ### Image scripts ### | ||||
| define rootfspad/jffs2-128k | ||||
| --align-rootfs | ||||
| endef | ||||
| define rootfspad/jffs2-64k | ||||
| --align-rootfs | ||||
| endef | ||||
| define rootfspad/squashfs | ||||
| endef | ||||
|  | ||||
| define Image/FileSystemStrip | ||||
| $(firstword $(subst +,$(space),$(subst root.,,$(notdir $(1))))) | ||||
| endef | ||||
|  | ||||
| define Build/cfe-bin | ||||
| 	$(STAGING_DIR_HOST)/bin/imagetag -i $(IMAGE_KERNEL) -f $(IMAGE_ROOTFS) \ | ||||
| 		--output $@ --boardid $(CFE_BOARD_ID) --chipid $(CHIP_ID) \ | ||||
| 		--entry $(LOADER_ENTRY) --load-addr $(LOADER_ENTRY) \ | ||||
| 		--info1 "$(call ModelNameLimit16,$(DEVICE_NAME))" \ | ||||
| 		--info2 "$(call Image/FileSystemStrip,$(IMAGE_ROOTFS))" \ | ||||
| 		$(call rootfspad/$(call Image/FileSystemStrip,$(IMAGE_ROOTFS))) \ | ||||
| 		$(CFE_EXTRAS) $(1) | ||||
| endef | ||||
|  | ||||
| define Build/cfe-jffs2 | ||||
| 	$(STAGING_DIR_HOST)/bin/mkfs.jffs2 \ | ||||
| 		--big-endian \ | ||||
| 		--pad \ | ||||
| 		--no-cleanmarkers \ | ||||
| 		--eraseblock=$(patsubst %k,%KiB,$(BLOCKSIZE)) \ | ||||
| 		--root=$(1) \ | ||||
| 		--output=$@ \ | ||||
| 		--compression-mode=none | ||||
|  | ||||
| 	$(call Build/pad-to,$(BLOCKSIZE)) | ||||
| endef | ||||
|  | ||||
| define Build/cfe-jffs2-cferam | ||||
| 	mv $@ $@.kernel | ||||
|  | ||||
| 	rm -rf $@-cferam | ||||
| 	mkdir -p $@-cferam | ||||
|  | ||||
| 	# CFE ROM checks JFFS2 dirent version of cferam. | ||||
| 	# If version is not > 0 it will ignore the fs entry. | ||||
| 	# JFFS2 sets version 0 to the first fs entry and increments | ||||
| 	# it on the following ones, so let's create a dummy file that | ||||
| 	# will have version 0 and let cferam be the second (version 1). | ||||
| 	touch $@-cferam/1-openwrt | ||||
| 	# Add cferam as the last file in the JFFS2 partition | ||||
| 	cp $(KDIR)/bcm63xx-cfe/$(CFE_RAM_FILE) $@-cferam/$(CFE_RAM_JFFS2_NAME) | ||||
|  | ||||
| 	# The JFFS2 partition creation should result in the following | ||||
| 	# layout: | ||||
| 	# 1) 1-openwrt (version 0, ino 2) | ||||
| 	# 2) cferam.000 (version 1, ino 3) | ||||
| 	$(call Build/cfe-jffs2,$@-cferam) | ||||
|  | ||||
| 	# Some devices need padding between CFE RAM and kernel | ||||
| 	$(if $(CFE_RAM_JFFS2_PAD),$(call Build/pad-to,$(CFE_RAM_JFFS2_PAD))) | ||||
|  | ||||
| 	# Add CFE partition tag | ||||
| 	$(if $(CFE_PART_ID),$(call Build/cfe-part-tag)) | ||||
|  | ||||
| 	# Append kernel | ||||
| 	dd if=$@.kernel >> $@ | ||||
| 	rm -f $@.kernel | ||||
| endef | ||||
|  | ||||
| define Build/cfe-jffs2-kernel | ||||
| 	rm -rf $@-kernel | ||||
| 	mkdir -p $@-kernel | ||||
|  | ||||
| 	# CFE RAM checks JFFS2 dirent version of vmlinux. | ||||
| 	# If version is not > 0 it will ignore the fs entry. | ||||
| 	# JFFS2 sets version 0 to the first fs entry and increments | ||||
| 	# it on the following ones, so let's create a dummy file that | ||||
| 	# will have version 0 and let cferam be the second (version 1). | ||||
| 	touch $@-kernel/1-openwrt | ||||
| 	# vmlinux is located on a different JFFS2 partition, but CFE RAM | ||||
| 	# ignores it, so let's create another dummy file that will match | ||||
| 	# the JFFS2 ino of cferam entry on the first JFFS2 partition. | ||||
| 	# CFE RAM won't be able to find vmlinux if cferam has the same | ||||
| 	# ino as vmlinux. | ||||
| 	touch $@-kernel/2-openwrt | ||||
| 	# Add vmlinux as the last file in the JFFS2 partition | ||||
| 	$(TOPDIR)/scripts/cfe-bin-header.py \ | ||||
| 		--input-file $@ \ | ||||
| 		--output-file $@-kernel/vmlinux.lz \ | ||||
| 		--load-addr $(if $(DEVICE_LOADADDR),$(DEVICE_LOADADDR),$(LOADER_ENTRY)) \ | ||||
| 		--entry-addr $(if $(DEVICE_LOADADDR),$(DEVICE_LOADADDR),$(LOADER_ENTRY)) | ||||
|  | ||||
| 	# The JFFS2 partition creation should result in the following | ||||
| 	# layout: | ||||
| 	# 1) 1-openwrt (version 0, ino 2) | ||||
| 	# 2) 2-openwrt (version 1, ino 3) | ||||
| 	# 3) vmlinux.lz (version 2, ino 4) | ||||
| 	$(call Build/cfe-jffs2,$@-kernel) | ||||
| endef | ||||
|  | ||||
| define Build/cfe-part-tag | ||||
| 	mv $@ $@.part | ||||
|  | ||||
| 	$(TOPDIR)/scripts/cfe-partition-tag.py \ | ||||
| 		--input-file $@.part \ | ||||
| 		--output-file $@ \ | ||||
| 		--flags $(CFE_PART_FLAGS) \ | ||||
| 		--id $(CFE_PART_ID) \ | ||||
| 		--name $(VERSION_CODE) \ | ||||
| 		--version $(DEVICE_NAME) | ||||
|  | ||||
| 	$(call Build/pad-to,$(BLOCKSIZE)) | ||||
|  | ||||
| 	dd if=$@.part >> $@ | ||||
| endef | ||||
|  | ||||
| define Build/cfe-sercomm-crypto | ||||
| 	$(TOPDIR)/scripts/sercomm-crypto.py \ | ||||
| 		--input-file $@ \ | ||||
| 		--key-file $@.key \ | ||||
| 		--output-file $@.ser \ | ||||
| 		--version OpenWrt | ||||
| 	$(STAGING_DIR_HOST)/bin/openssl enc -md md5 -aes-256-cbc \ | ||||
| 		-in $@ -out $@.enc \ | ||||
| 		-K `cat $@.key` \ | ||||
| 		-iv 00000000000000000000000000000000 | ||||
| 	dd if=$@.enc >> $@.ser | ||||
| 	mv $@.ser $@ | ||||
| 	rm -f $@.enc $@.key | ||||
| endef | ||||
|  | ||||
| define Build/cfe-sercomm-load | ||||
| 	$(TOPDIR)/scripts/sercomm-payload.py \ | ||||
| 		--input-file $@ \ | ||||
| 		--output-file $@.new \ | ||||
| 		--pid "$(SERCOMM_PID)" | ||||
|  | ||||
| 	mv $@.new $@ | ||||
| endef | ||||
|  | ||||
| define Build/cfe-sercomm-part | ||||
| 	$(TOPDIR)/scripts/sercomm-partition-tag.py \ | ||||
| 		--input-file $@ \ | ||||
| 		--output-file $@.kernel_rootfs \ | ||||
| 		--part-name kernel_rootfs \ | ||||
| 		--part-version OpenWrt \ | ||||
| 		--rootfs-version $(SERCOMM_VERSION) | ||||
|  | ||||
| 	rm -rf $@-rootfs_lib | ||||
| 	mkdir -p $@-rootfs_lib | ||||
| 	echo $(SERCOMM_VERSION) > $@-rootfs_lib/lib_ver | ||||
| 	$(call Build/cfe-jffs2,$@-rootfs_lib) | ||||
| 	$(call Build/pad-to,$(BLOCKSIZE)) | ||||
| 	$(TOPDIR)/scripts/sercomm-partition-tag.py \ | ||||
| 		--input-file $@ \ | ||||
| 		--output-file $@.rootfs_lib \ | ||||
| 		--part-name rootfs_lib \ | ||||
| 		--part-version $(SERCOMM_VERSION) | ||||
|  | ||||
| 	mv $@.kernel_rootfs $@ | ||||
| 	dd if=$@.rootfs_lib >> $@ | ||||
| endef | ||||
|  | ||||
| define Build/cfe-wfi-tag | ||||
| 	$(TOPDIR)/scripts/cfe-wfi-tag.py \ | ||||
| 		--input-file $@ \ | ||||
| 		--output-file $@.new \ | ||||
| 		--version $(if $(1),$(1),$(CFE_WFI_VERSION)) \ | ||||
| 		--chip-id $(CFE_WFI_CHIP_ID) \ | ||||
| 		--flash-type $(CFE_WFI_FLASH_TYPE) \ | ||||
| 		$(if $(CFE_WFI_FLAGS),--flags $(CFE_WFI_FLAGS)) | ||||
| 	mv $@.new $@ | ||||
| endef | ||||
|  | ||||
| ### Device scripts ### | ||||
| define Device/Default | ||||
|   PROFILES = Default $$(DEVICE_NAME) | ||||
|   KERNEL_DEPENDS = $$(wildcard ../dts/$$(DEVICE_DTS).dts) | ||||
|   DEVICE_DTS_DIR := ../dts | ||||
|   CHIP_ID := | ||||
|   SOC = bcm$$(CHIP_ID) | ||||
|   DEVICE_DTS = $$(SOC)-$(subst _,-,$(1)) | ||||
|   DEVICE_LOADADDR := | ||||
| endef | ||||
|  | ||||
| USB1_PACKAGES := kmod-usb-ohci kmod-ledtrig-usbdev | ||||
| USB2_PACKAGES := $(USB1_PACKAGES) kmod-usb2 | ||||
|  | ||||
| include bcm63xx_$(SUBTARGET).mk | ||||
|  | ||||
| $(eval $(call BuildImage)) | ||||
							
								
								
									
										74
									
								
								target/linux/bmips/image/bcm63xx_generic.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								target/linux/bmips/image/bcm63xx_generic.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| DEVICE_VARS += CFE_BOARD_ID CFE_EXTRAS | ||||
| DEVICE_VARS += FLASH_MB IMAGE_OFFSET | ||||
|  | ||||
| define Device/bcm63xx-cfe | ||||
|   FILESYSTEMS := squashfs jffs2-64k jffs2-128k | ||||
|   KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma | ||||
|   KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-lzma elf | ||||
|   KERNEL_INITRAMFS_SUFFIX := .elf | ||||
|   IMAGES := cfe.bin sysupgrade.bin | ||||
|   IMAGE/cfe.bin := \ | ||||
|     cfe-bin $$$$(if $$$$(FLASH_MB),--pad $$$$(shell expr $$$$(FLASH_MB) / 2)) | ||||
|   IMAGE/sysupgrade.bin := cfe-bin | append-metadata | ||||
|   BLOCKSIZE := 0x10000 | ||||
|   IMAGE_OFFSET := | ||||
|   FLASH_MB := | ||||
|   CFE_BOARD_ID := | ||||
|   CFE_EXTRAS = --block-size $$(BLOCKSIZE) \ | ||||
|     --image-offset $$(if $$(IMAGE_OFFSET),$$(IMAGE_OFFSET),$$(BLOCKSIZE)) | ||||
| endef | ||||
|  | ||||
| # Legacy CFEs with specific LZMA parameters and no length | ||||
| define Device/bcm63xx-cfe-legacy | ||||
|   $(Device/bcm63xx-cfe) | ||||
|   KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma-cfe | ||||
| endef | ||||
|  | ||||
| define Device/comtrend_ar-5315u | ||||
|   $(Device/bcm63xx-cfe) | ||||
|   DEVICE_VENDOR := Comtrend | ||||
|   DEVICE_MODEL := AR-5315u | ||||
|   CHIP_ID := 6318 | ||||
|   CFE_BOARD_ID := 96318A-1441N1 | ||||
|   FLASH_MB := 16 | ||||
|   DEVICE_PACKAGES += $(USB2_PACKAGES) | ||||
| endef | ||||
| TARGET_DEVICES += comtrend_ar-5315u | ||||
|  | ||||
| define Device/comtrend_ar-5387un | ||||
|   $(Device/bcm63xx-cfe) | ||||
|   DEVICE_VENDOR := Comtrend | ||||
|   DEVICE_MODEL := AR-5387un | ||||
|   CHIP_ID := 6328 | ||||
|   CFE_BOARD_ID := 96328A-1441N1 | ||||
|   FLASH_MB := 16 | ||||
|   DEVICE_PACKAGES += $(USB2_PACKAGES) | ||||
| endef | ||||
| TARGET_DEVICES += comtrend_ar-5387un | ||||
|  | ||||
| define Device/comtrend_vr-3025u | ||||
|   $(Device/bcm63xx-cfe) | ||||
|   DEVICE_VENDOR := Comtrend | ||||
|   DEVICE_MODEL := VR-3025u | ||||
|   CHIP_ID := 6368 | ||||
|   CFE_BOARD_ID := 96368M-1541N | ||||
|   BLOCKSIZE := 0x20000 | ||||
|   FLASH_MB := 32 | ||||
|   DEVICE_PACKAGES += $(USB2_PACKAGES) | ||||
| endef | ||||
| TARGET_DEVICES += comtrend_vr-3025u | ||||
|  | ||||
| define Device/huawei_hg556a-b | ||||
|   $(Device/bcm63xx-cfe-legacy) | ||||
|   DEVICE_VENDOR := Huawei | ||||
|   DEVICE_MODEL := EchoLife HG556a | ||||
|   DEVICE_VARIANT := B | ||||
|   CHIP_ID := 6358 | ||||
|   CFE_BOARD_ID := HW556 | ||||
|   CFE_EXTRAS += --rsa-signature "EchoLife_HG556a" --tag-version 8 | ||||
|   BLOCKSIZE := 0x20000 | ||||
|   DEVICE_PACKAGES += $(USB2_PACKAGES) | ||||
| endef | ||||
| TARGET_DEVICES += huawei_hg556a-b | ||||
							
								
								
									
										81
									
								
								target/linux/bmips/image/bcm63xx_nand.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								target/linux/bmips/image/bcm63xx_nand.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| DEVICE_VARS += CFE_PART_FLAGS CFE_PART_ID | ||||
| DEVICE_VARS += CFE_RAM_FILE | ||||
| DEVICE_VARS += CFE_RAM_JFFS2_NAME CFE_RAM_JFFS2_PAD | ||||
| DEVICE_VARS += CFE_WFI_CHIP_ID CFE_WFI_FLASH_TYPE | ||||
| DEVICE_VARS += CFE_WFI_FLAGS CFE_WFI_VERSION | ||||
| DEVICE_VARS += SERCOMM_PID SERCOMM_VERSION | ||||
|  | ||||
| # CFE expects a single JFFS2 partition with cferam and kernel. However, | ||||
| # it's possible to fool CFE into properly loading both cferam and kernel | ||||
| # from two different JFFS2 partitions by adding dummy files (see | ||||
| # cfe-jffs2-cferam and cfe-jffs2-kernel). | ||||
| # Separate JFFS2 partitions allow upgrading openwrt without reflashing cferam | ||||
| # JFFS2 partition, which is much safer in case anything goes wrong. | ||||
| define Device/bcm63xx-nand | ||||
|   FILESYSTEMS := squashfs ubifs | ||||
|   KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma | cfe-jffs2-kernel | ||||
|   KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-lzma elf | ||||
|   KERNEL_INITRAMFS_SUFFIX := .elf | ||||
|   IMAGES := cfe.bin sysupgrade.bin | ||||
|   IMAGE/cfe.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) |\ | ||||
|     cfe-jffs2-cferam | append-ubi | cfe-wfi-tag | ||||
|   IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata | ||||
|   KERNEL_SIZE := 5120k | ||||
|   CFE_PART_FLAGS := | ||||
|   CFE_PART_ID := | ||||
|   CFE_RAM_FILE := | ||||
|   CFE_RAM_JFFS2_NAME := | ||||
|   CFE_RAM_JFFS2_PAD := | ||||
|   CFE_WFI_VERSION := | ||||
|   CFE_WFI_CHIP_ID = 0x$$(CHIP_ID) | ||||
|   CFE_WFI_FLASH_TYPE := | ||||
|   CFE_WFI_FLAGS := | ||||
|   UBINIZE_OPTS := -E 5 | ||||
|   DEVICE_PACKAGES += nand-utils | ||||
| endef | ||||
|  | ||||
| define Device/sercomm-nand | ||||
|   $(Device/bcm63xx-nand) | ||||
|   IMAGES := factory.img sysupgrade.bin | ||||
|   IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi |\ | ||||
|     cfe-sercomm-part | gzip | cfe-sercomm-load | cfe-sercomm-crypto | ||||
|   SERCOM_PID := | ||||
|   SERCOMM_VERSION := | ||||
| endef | ||||
|  | ||||
| define Device/comtrend_vr-3032u | ||||
|   $(Device/bcm63xx-nand) | ||||
|   DEVICE_VENDOR := Comtrend | ||||
|   DEVICE_MODEL := VR-3032u | ||||
|   CHIP_ID := 63268 | ||||
|   SOC := bcm63168 | ||||
|   CFE_RAM_FILE := comtrend,vr-3032u/cferam.000 | ||||
|   CFE_RAM_JFFS2_NAME := cferam.000 | ||||
|   BLOCKSIZE := 128k | ||||
|   PAGESIZE := 2048 | ||||
|   SUBPAGESIZE := 512 | ||||
|   VID_HDR_OFFSET := 2048 | ||||
|   DEVICE_PACKAGES += $(USB2_PACKAGES) | ||||
|   CFE_WFI_FLASH_TYPE := 3 | ||||
|   CFE_WFI_VERSION := 0x5732 | ||||
| endef | ||||
| TARGET_DEVICES += comtrend_vr-3032u | ||||
|  | ||||
| define Device/netgear_dgnd3700-v2 | ||||
|   $(Device/bcm63xx-nand) | ||||
|   DEVICE_VENDOR := NETGEAR | ||||
|   DEVICE_MODEL := DGND3700 | ||||
|   DEVICE_VARIANT := v2 | ||||
|   CHIP_ID := 6362 | ||||
|   CFE_RAM_FILE := netgear,dgnd3700-v2/cferam | ||||
|   CFE_RAM_JFFS2_NAME := cferam | ||||
|   CFE_RAM_JFFS2_PAD := 496k | ||||
|   BLOCKSIZE := 16k | ||||
|   PAGESIZE := 512 | ||||
|   DEVICE_PACKAGES += $(USB2_PACKAGES) | ||||
|   CFE_WFI_FLASH_TYPE := 2 | ||||
|   CFE_WFI_VERSION := 0x5731 | ||||
| endef | ||||
| TARGET_DEVICES += netgear_dgnd3700-v2 | ||||
							
								
								
									
										74
									
								
								target/linux/bmips/image/lzma-loader/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								target/linux/bmips/image/lzma-loader/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| # | ||||
| # Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| # Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
| # Copyright (C) 2011 OpenWrt.org | ||||
| # Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
| # | ||||
|  | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| LZMA_TEXT_START	:= 0x80a00000 | ||||
| LOADER		:= loader.bin | ||||
| LOADER_NAME	:= $(basename $(notdir $(LOADER))) | ||||
| LOADER_DATA 	:= | ||||
| TARGET_DIR	:= | ||||
|  | ||||
| UART_BASE_3329 := 0xb0000100 | ||||
| UART_BASE_3368 := 0xfff8c100 | ||||
| UART_BASE_3380 := 0xb4e00200 | ||||
| UART_BASE_3383 := 0xb4e00500 | ||||
| UART_BASE_3384 := 0xb4e00500 | ||||
| UART_BASE_6318 := 0xb0000100 | ||||
| UART_BASE_6328 := 0xb0000100 | ||||
| UART_BASE_6338 := 0xfffe0300 | ||||
| UART_BASE_6345 := 0xfffe0300 | ||||
| UART_BASE_6348 := 0xfffe0300 | ||||
| UART_BASE_6358 := 0xfffe0100 | ||||
| UART_BASE_6362 := 0xb0000100 | ||||
| UART_BASE_6368 := 0xb0000100 | ||||
| UART_BASE_63268 := 0xb0000180 | ||||
| UART_BASE_6816 := 0xb0000100 | ||||
| UART_BASE_6818 := 0xb0000100 | ||||
| UART_BASE_6828 := 0xb0000180 | ||||
| UART_BASE := $(if $(UART_BASE_$(CHIP_ID)),$(UART_BASE_$(CHIP_ID)),0) | ||||
|  | ||||
| ifeq ($(TARGET_DIR),) | ||||
| TARGET_DIR	:= $(KDIR) | ||||
| endif | ||||
|  | ||||
| LOADER_BIN	:= $(TARGET_DIR)/$(LOADER_NAME).bin | ||||
| LOADER_ELF	:= $(TARGET_DIR)/$(LOADER_NAME).elf | ||||
|  | ||||
| PKG_NAME := lzma-loader | ||||
| PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) | ||||
|  | ||||
| .PHONY : loader-compile loader.bin loader.elf | ||||
|  | ||||
| $(PKG_BUILD_DIR)/.prepared: | ||||
| 	mkdir $(PKG_BUILD_DIR) | ||||
| 	$(CP) ./src/* $(PKG_BUILD_DIR)/ | ||||
| 	touch $@ | ||||
|  | ||||
| loader-compile: $(PKG_BUILD_DIR)/.prepared | ||||
| 	$(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ | ||||
| 		LZMA_TEXT_START=$(LZMA_TEXT_START) \ | ||||
| 		LOADER_DATA=$(LOADER_DATA) \ | ||||
| 		UART_BASE=$(UART_BASE) \ | ||||
| 		clean all | ||||
|  | ||||
| loader.elf: $(PKG_BUILD_DIR)/loader.elf | ||||
| 	$(CP) $< $(LOADER_ELF) | ||||
|  | ||||
| loader.bin: $(PKG_BUILD_DIR)/loader.bin | ||||
| 	$(CP) $< $(LOADER_BIN) | ||||
|  | ||||
| download: | ||||
| prepare: $(PKG_BUILD_DIR)/.prepared | ||||
| compile: loader-compile | ||||
|  | ||||
| install: | ||||
|  | ||||
| clean: | ||||
| 	rm -rf $(PKG_BUILD_DIR) | ||||
							
								
								
									
										584
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										584
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,584 @@ | ||||
| /* | ||||
|   LzmaDecode.c | ||||
|   LZMA Decoder (optimized for Speed version) | ||||
|    | ||||
|   LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) | ||||
|   http://www.7-zip.org/ | ||||
|  | ||||
|   LZMA SDK is licensed under two licenses: | ||||
|   1) GNU Lesser General Public License (GNU LGPL) | ||||
|   2) Common Public License (CPL) | ||||
|   It means that you can select one of these two licenses and  | ||||
|   follow rules of that license. | ||||
|  | ||||
|   SPECIAL EXCEPTION: | ||||
|   Igor Pavlov, as the author of this Code, expressly permits you to  | ||||
|   statically or dynamically link your Code (or bind by name) to the  | ||||
|   interfaces of this file without subjecting your linked Code to the  | ||||
|   terms of the CPL or GNU LGPL. Any modifications or additions  | ||||
|   to this file, however, are subject to the LGPL or CPL terms. | ||||
| */ | ||||
|  | ||||
| #include "LzmaDecode.h" | ||||
|  | ||||
| #define kNumTopBits 24 | ||||
| #define kTopValue ((UInt32)1 << kNumTopBits) | ||||
|  | ||||
| #define kNumBitModelTotalBits 11 | ||||
| #define kBitModelTotal (1 << kNumBitModelTotalBits) | ||||
| #define kNumMoveBits 5 | ||||
|  | ||||
| #define RC_READ_BYTE (*Buffer++) | ||||
|  | ||||
| #define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ | ||||
|   { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} | ||||
|  | ||||
| #ifdef _LZMA_IN_CB | ||||
|  | ||||
| #define RC_TEST { if (Buffer == BufferLim) \ | ||||
|   { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ | ||||
|   BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} | ||||
|  | ||||
| #define RC_INIT Buffer = BufferLim = 0; RC_INIT2 | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } | ||||
|  | ||||
| #define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 | ||||
|   | ||||
| #endif | ||||
|  | ||||
| #define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } | ||||
|  | ||||
| #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) | ||||
| #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; | ||||
| #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; | ||||
|  | ||||
| #define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ | ||||
|   { UpdateBit0(p); mi <<= 1; A0; } else \ | ||||
|   { UpdateBit1(p); mi = (mi + mi) + 1; A1; }  | ||||
|    | ||||
| #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)                | ||||
|  | ||||
| #define RangeDecoderBitTreeDecode(probs, numLevels, res) \ | ||||
|   { int i = numLevels; res = 1; \ | ||||
|   do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ | ||||
|   res -= (1 << numLevels); } | ||||
|  | ||||
|  | ||||
| #define kNumPosBitsMax 4 | ||||
| #define kNumPosStatesMax (1 << kNumPosBitsMax) | ||||
|  | ||||
| #define kLenNumLowBits 3 | ||||
| #define kLenNumLowSymbols (1 << kLenNumLowBits) | ||||
| #define kLenNumMidBits 3 | ||||
| #define kLenNumMidSymbols (1 << kLenNumMidBits) | ||||
| #define kLenNumHighBits 8 | ||||
| #define kLenNumHighSymbols (1 << kLenNumHighBits) | ||||
|  | ||||
| #define LenChoice 0 | ||||
| #define LenChoice2 (LenChoice + 1) | ||||
| #define LenLow (LenChoice2 + 1) | ||||
| #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) | ||||
| #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) | ||||
| #define kNumLenProbs (LenHigh + kLenNumHighSymbols)  | ||||
|  | ||||
|  | ||||
| #define kNumStates 12 | ||||
| #define kNumLitStates 7 | ||||
|  | ||||
| #define kStartPosModelIndex 4 | ||||
| #define kEndPosModelIndex 14 | ||||
| #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) | ||||
|  | ||||
| #define kNumPosSlotBits 6 | ||||
| #define kNumLenToPosStates 4 | ||||
|  | ||||
| #define kNumAlignBits 4 | ||||
| #define kAlignTableSize (1 << kNumAlignBits) | ||||
|  | ||||
| #define kMatchMinLen 2 | ||||
|  | ||||
| #define IsMatch 0 | ||||
| #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) | ||||
| #define IsRepG0 (IsRep + kNumStates) | ||||
| #define IsRepG1 (IsRepG0 + kNumStates) | ||||
| #define IsRepG2 (IsRepG1 + kNumStates) | ||||
| #define IsRep0Long (IsRepG2 + kNumStates) | ||||
| #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) | ||||
| #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) | ||||
| #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) | ||||
| #define LenCoder (Align + kAlignTableSize) | ||||
| #define RepLenCoder (LenCoder + kNumLenProbs) | ||||
| #define Literal (RepLenCoder + kNumLenProbs) | ||||
|  | ||||
| #if Literal != LZMA_BASE_SIZE | ||||
| StopCompilingDueBUG | ||||
| #endif | ||||
|  | ||||
| int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) | ||||
| { | ||||
|   unsigned char prop0; | ||||
|   if (size < LZMA_PROPERTIES_SIZE) | ||||
|     return LZMA_RESULT_DATA_ERROR; | ||||
|   prop0 = propsData[0]; | ||||
|   if (prop0 >= (9 * 5 * 5)) | ||||
|     return LZMA_RESULT_DATA_ERROR; | ||||
|   { | ||||
|     for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); | ||||
|     for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); | ||||
|     propsRes->lc = prop0; | ||||
|     /* | ||||
|     unsigned char remainder = (unsigned char)(prop0 / 9); | ||||
|     propsRes->lc = prop0 % 9; | ||||
|     propsRes->pb = remainder / 5; | ||||
|     propsRes->lp = remainder % 5; | ||||
|     */ | ||||
|   } | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   { | ||||
|     int i; | ||||
|     propsRes->DictionarySize = 0; | ||||
|     for (i = 0; i < 4; i++) | ||||
|       propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); | ||||
|     if (propsRes->DictionarySize == 0) | ||||
|       propsRes->DictionarySize = 1; | ||||
|   } | ||||
|   #endif | ||||
|   return LZMA_RESULT_OK; | ||||
| } | ||||
|  | ||||
| #define kLzmaStreamWasFinishedId (-1) | ||||
|  | ||||
| int LzmaDecode(CLzmaDecoderState *vs, | ||||
|     #ifdef _LZMA_IN_CB | ||||
|     ILzmaInCallback *InCallback, | ||||
|     #else | ||||
|     const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, | ||||
|     #endif | ||||
|     unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) | ||||
| { | ||||
|   CProb *p = vs->Probs; | ||||
|   SizeT nowPos = 0; | ||||
|   Byte previousByte = 0; | ||||
|   UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; | ||||
|   UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; | ||||
|   int lc = vs->Properties.lc; | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|    | ||||
|   UInt32 Range = vs->Range; | ||||
|   UInt32 Code = vs->Code; | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   const Byte *Buffer = vs->Buffer; | ||||
|   const Byte *BufferLim = vs->BufferLim; | ||||
|   #else | ||||
|   const Byte *Buffer = inStream; | ||||
|   const Byte *BufferLim = inStream + inSize; | ||||
|   #endif | ||||
|   int state = vs->State; | ||||
|   UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; | ||||
|   int len = vs->RemainLen; | ||||
|   UInt32 globalPos = vs->GlobalPos; | ||||
|   UInt32 distanceLimit = vs->DistanceLimit; | ||||
|  | ||||
|   Byte *dictionary = vs->Dictionary; | ||||
|   UInt32 dictionarySize = vs->Properties.DictionarySize; | ||||
|   UInt32 dictionaryPos = vs->DictionaryPos; | ||||
|  | ||||
|   Byte tempDictionary[4]; | ||||
|  | ||||
|   #ifndef _LZMA_IN_CB | ||||
|   *inSizeProcessed = 0; | ||||
|   #endif | ||||
|   *outSizeProcessed = 0; | ||||
|   if (len == kLzmaStreamWasFinishedId) | ||||
|     return LZMA_RESULT_OK; | ||||
|  | ||||
|   if (dictionarySize == 0) | ||||
|   { | ||||
|     dictionary = tempDictionary; | ||||
|     dictionarySize = 1; | ||||
|     tempDictionary[0] = vs->TempDictionary[0]; | ||||
|   } | ||||
|  | ||||
|   if (len == kLzmaNeedInitId) | ||||
|   { | ||||
|     { | ||||
|       UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); | ||||
|       UInt32 i; | ||||
|       for (i = 0; i < numProbs; i++) | ||||
|         p[i] = kBitModelTotal >> 1;  | ||||
|       rep0 = rep1 = rep2 = rep3 = 1; | ||||
|       state = 0; | ||||
|       globalPos = 0; | ||||
|       distanceLimit = 0; | ||||
|       dictionaryPos = 0; | ||||
|       dictionary[dictionarySize - 1] = 0; | ||||
|       #ifdef _LZMA_IN_CB | ||||
|       RC_INIT; | ||||
|       #else | ||||
|       RC_INIT(inStream, inSize); | ||||
|       #endif | ||||
|     } | ||||
|     len = 0; | ||||
|   } | ||||
|   while(len != 0 && nowPos < outSize) | ||||
|   { | ||||
|     UInt32 pos = dictionaryPos - rep0; | ||||
|     if (pos >= dictionarySize) | ||||
|       pos += dictionarySize; | ||||
|     outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; | ||||
|     if (++dictionaryPos == dictionarySize) | ||||
|       dictionaryPos = 0; | ||||
|     len--; | ||||
|   } | ||||
|   if (dictionaryPos == 0) | ||||
|     previousByte = dictionary[dictionarySize - 1]; | ||||
|   else | ||||
|     previousByte = dictionary[dictionaryPos - 1]; | ||||
|  | ||||
|   #else /* if !_LZMA_OUT_READ */ | ||||
|  | ||||
|   int state = 0; | ||||
|   UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; | ||||
|   int len = 0; | ||||
|   const Byte *Buffer; | ||||
|   const Byte *BufferLim; | ||||
|   UInt32 Range; | ||||
|   UInt32 Code; | ||||
|  | ||||
|   #ifndef _LZMA_IN_CB | ||||
|   *inSizeProcessed = 0; | ||||
|   #endif | ||||
|   *outSizeProcessed = 0; | ||||
|  | ||||
|   { | ||||
|     UInt32 i; | ||||
|     UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); | ||||
|     for (i = 0; i < numProbs; i++) | ||||
|       p[i] = kBitModelTotal >> 1; | ||||
|   } | ||||
|    | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   RC_INIT; | ||||
|   #else | ||||
|   RC_INIT(inStream, inSize); | ||||
|   #endif | ||||
|  | ||||
|   #endif /* _LZMA_OUT_READ */ | ||||
|  | ||||
|   while(nowPos < outSize) | ||||
|   { | ||||
|     CProb *prob; | ||||
|     UInt32 bound; | ||||
|     int posState = (int)( | ||||
|         (nowPos  | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         + globalPos | ||||
|         #endif | ||||
|         ) | ||||
|         & posStateMask); | ||||
|  | ||||
|     prob = p + IsMatch + (state << kNumPosBitsMax) + posState; | ||||
|     IfBit0(prob) | ||||
|     { | ||||
|       int symbol = 1; | ||||
|       UpdateBit0(prob) | ||||
|       prob = p + Literal + (LZMA_LIT_SIZE *  | ||||
|         ((( | ||||
|         (nowPos  | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         + globalPos | ||||
|         #endif | ||||
|         ) | ||||
|         & literalPosMask) << lc) + (previousByte >> (8 - lc)))); | ||||
|  | ||||
|       if (state >= kNumLitStates) | ||||
|       { | ||||
|         int matchByte; | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         UInt32 pos = dictionaryPos - rep0; | ||||
|         if (pos >= dictionarySize) | ||||
|           pos += dictionarySize; | ||||
|         matchByte = dictionary[pos]; | ||||
|         #else | ||||
|         matchByte = outStream[nowPos - rep0]; | ||||
|         #endif | ||||
|         do | ||||
|         { | ||||
|           int bit; | ||||
|           CProb *probLit; | ||||
|           matchByte <<= 1; | ||||
|           bit = (matchByte & 0x100); | ||||
|           probLit = prob + 0x100 + bit + symbol; | ||||
|           RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) | ||||
|         } | ||||
|         while (symbol < 0x100); | ||||
|       } | ||||
|       while (symbol < 0x100) | ||||
|       { | ||||
|         CProb *probLit = prob + symbol; | ||||
|         RC_GET_BIT(probLit, symbol) | ||||
|       } | ||||
|       previousByte = (Byte)symbol; | ||||
|  | ||||
|       outStream[nowPos++] = previousByte; | ||||
|       #ifdef _LZMA_OUT_READ | ||||
|       if (distanceLimit < dictionarySize) | ||||
|         distanceLimit++; | ||||
|  | ||||
|       dictionary[dictionaryPos] = previousByte; | ||||
|       if (++dictionaryPos == dictionarySize) | ||||
|         dictionaryPos = 0; | ||||
|       #endif | ||||
|       if (state < 4) state = 0; | ||||
|       else if (state < 10) state -= 3; | ||||
|       else state -= 6; | ||||
|     } | ||||
|     else              | ||||
|     { | ||||
|       UpdateBit1(prob); | ||||
|       prob = p + IsRep + state; | ||||
|       IfBit0(prob) | ||||
|       { | ||||
|         UpdateBit0(prob); | ||||
|         rep3 = rep2; | ||||
|         rep2 = rep1; | ||||
|         rep1 = rep0; | ||||
|         state = state < kNumLitStates ? 0 : 3; | ||||
|         prob = p + LenCoder; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         UpdateBit1(prob); | ||||
|         prob = p + IsRepG0 + state; | ||||
|         IfBit0(prob) | ||||
|         { | ||||
|           UpdateBit0(prob); | ||||
|           prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; | ||||
|           IfBit0(prob) | ||||
|           { | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             UInt32 pos; | ||||
|             #endif | ||||
|             UpdateBit0(prob); | ||||
|              | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             if (distanceLimit == 0) | ||||
|             #else | ||||
|             if (nowPos == 0) | ||||
|             #endif | ||||
|               return LZMA_RESULT_DATA_ERROR; | ||||
|              | ||||
|             state = state < kNumLitStates ? 9 : 11; | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             pos = dictionaryPos - rep0; | ||||
|             if (pos >= dictionarySize) | ||||
|               pos += dictionarySize; | ||||
|             previousByte = dictionary[pos]; | ||||
|             dictionary[dictionaryPos] = previousByte; | ||||
|             if (++dictionaryPos == dictionarySize) | ||||
|               dictionaryPos = 0; | ||||
|             #else | ||||
|             previousByte = outStream[nowPos - rep0]; | ||||
|             #endif | ||||
|             outStream[nowPos++] = previousByte; | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             if (distanceLimit < dictionarySize) | ||||
|               distanceLimit++; | ||||
|             #endif | ||||
|  | ||||
|             continue; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             UpdateBit1(prob); | ||||
|           } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|           UInt32 distance; | ||||
|           UpdateBit1(prob); | ||||
|           prob = p + IsRepG1 + state; | ||||
|           IfBit0(prob) | ||||
|           { | ||||
|             UpdateBit0(prob); | ||||
|             distance = rep1; | ||||
|           } | ||||
|           else  | ||||
|           { | ||||
|             UpdateBit1(prob); | ||||
|             prob = p + IsRepG2 + state; | ||||
|             IfBit0(prob) | ||||
|             { | ||||
|               UpdateBit0(prob); | ||||
|               distance = rep2; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|               UpdateBit1(prob); | ||||
|               distance = rep3; | ||||
|               rep3 = rep2; | ||||
|             } | ||||
|             rep2 = rep1; | ||||
|           } | ||||
|           rep1 = rep0; | ||||
|           rep0 = distance; | ||||
|         } | ||||
|         state = state < kNumLitStates ? 8 : 11; | ||||
|         prob = p + RepLenCoder; | ||||
|       } | ||||
|       { | ||||
|         int numBits, offset; | ||||
|         CProb *probLen = prob + LenChoice; | ||||
|         IfBit0(probLen) | ||||
|         { | ||||
|           UpdateBit0(probLen); | ||||
|           probLen = prob + LenLow + (posState << kLenNumLowBits); | ||||
|           offset = 0; | ||||
|           numBits = kLenNumLowBits; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|           UpdateBit1(probLen); | ||||
|           probLen = prob + LenChoice2; | ||||
|           IfBit0(probLen) | ||||
|           { | ||||
|             UpdateBit0(probLen); | ||||
|             probLen = prob + LenMid + (posState << kLenNumMidBits); | ||||
|             offset = kLenNumLowSymbols; | ||||
|             numBits = kLenNumMidBits; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             UpdateBit1(probLen); | ||||
|             probLen = prob + LenHigh; | ||||
|             offset = kLenNumLowSymbols + kLenNumMidSymbols; | ||||
|             numBits = kLenNumHighBits; | ||||
|           } | ||||
|         } | ||||
|         RangeDecoderBitTreeDecode(probLen, numBits, len); | ||||
|         len += offset; | ||||
|       } | ||||
|  | ||||
|       if (state < 4) | ||||
|       { | ||||
|         int posSlot; | ||||
|         state += kNumLitStates; | ||||
|         prob = p + PosSlot + | ||||
|             ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<  | ||||
|             kNumPosSlotBits); | ||||
|         RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); | ||||
|         if (posSlot >= kStartPosModelIndex) | ||||
|         { | ||||
|           int numDirectBits = ((posSlot >> 1) - 1); | ||||
|           rep0 = (2 | ((UInt32)posSlot & 1)); | ||||
|           if (posSlot < kEndPosModelIndex) | ||||
|           { | ||||
|             rep0 <<= numDirectBits; | ||||
|             prob = p + SpecPos + rep0 - posSlot - 1; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             numDirectBits -= kNumAlignBits; | ||||
|             do | ||||
|             { | ||||
|               RC_NORMALIZE | ||||
|               Range >>= 1; | ||||
|               rep0 <<= 1; | ||||
|               if (Code >= Range) | ||||
|               { | ||||
|                 Code -= Range; | ||||
|                 rep0 |= 1; | ||||
|               } | ||||
|             } | ||||
|             while (--numDirectBits != 0); | ||||
|             prob = p + Align; | ||||
|             rep0 <<= kNumAlignBits; | ||||
|             numDirectBits = kNumAlignBits; | ||||
|           } | ||||
|           { | ||||
|             int i = 1; | ||||
|             int mi = 1; | ||||
|             do | ||||
|             { | ||||
|               CProb *prob3 = prob + mi; | ||||
|               RC_GET_BIT2(prob3, mi, ; , rep0 |= i); | ||||
|               i <<= 1; | ||||
|             } | ||||
|             while(--numDirectBits != 0); | ||||
|           } | ||||
|         } | ||||
|         else | ||||
|           rep0 = posSlot; | ||||
|         if (++rep0 == (UInt32)(0)) | ||||
|         { | ||||
|           /* it's for stream version */ | ||||
|           len = kLzmaStreamWasFinishedId; | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       len += kMatchMinLen; | ||||
|       #ifdef _LZMA_OUT_READ | ||||
|       if (rep0 > distanceLimit)  | ||||
|       #else | ||||
|       if (rep0 > nowPos) | ||||
|       #endif | ||||
|         return LZMA_RESULT_DATA_ERROR; | ||||
|  | ||||
|       #ifdef _LZMA_OUT_READ | ||||
|       if (dictionarySize - distanceLimit > (UInt32)len) | ||||
|         distanceLimit += len; | ||||
|       else | ||||
|         distanceLimit = dictionarySize; | ||||
|       #endif | ||||
|  | ||||
|       do | ||||
|       { | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         UInt32 pos = dictionaryPos - rep0; | ||||
|         if (pos >= dictionarySize) | ||||
|           pos += dictionarySize; | ||||
|         previousByte = dictionary[pos]; | ||||
|         dictionary[dictionaryPos] = previousByte; | ||||
|         if (++dictionaryPos == dictionarySize) | ||||
|           dictionaryPos = 0; | ||||
|         #else | ||||
|         previousByte = outStream[nowPos - rep0]; | ||||
|         #endif | ||||
|         len--; | ||||
|         outStream[nowPos++] = previousByte; | ||||
|       } | ||||
|       while(len != 0 && nowPos < outSize); | ||||
|     } | ||||
|   } | ||||
|   RC_NORMALIZE; | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   vs->Range = Range; | ||||
|   vs->Code = Code; | ||||
|   vs->DictionaryPos = dictionaryPos; | ||||
|   vs->GlobalPos = globalPos + (UInt32)nowPos; | ||||
|   vs->DistanceLimit = distanceLimit; | ||||
|   vs->Reps[0] = rep0; | ||||
|   vs->Reps[1] = rep1; | ||||
|   vs->Reps[2] = rep2; | ||||
|   vs->Reps[3] = rep3; | ||||
|   vs->State = state; | ||||
|   vs->RemainLen = len; | ||||
|   vs->TempDictionary[0] = tempDictionary[0]; | ||||
|   #endif | ||||
|  | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   vs->Buffer = Buffer; | ||||
|   vs->BufferLim = BufferLim; | ||||
|   #else | ||||
|   *inSizeProcessed = (SizeT)(Buffer - inStream); | ||||
|   #endif | ||||
|   *outSizeProcessed = nowPos; | ||||
|   return LZMA_RESULT_OK; | ||||
| } | ||||
							
								
								
									
										113
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| /*  | ||||
|   LzmaDecode.h | ||||
|   LZMA Decoder interface | ||||
|  | ||||
|   LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) | ||||
|   http://www.7-zip.org/ | ||||
|  | ||||
|   LZMA SDK is licensed under two licenses: | ||||
|   1) GNU Lesser General Public License (GNU LGPL) | ||||
|   2) Common Public License (CPL) | ||||
|   It means that you can select one of these two licenses and  | ||||
|   follow rules of that license. | ||||
|  | ||||
|   SPECIAL EXCEPTION: | ||||
|   Igor Pavlov, as the author of this code, expressly permits you to  | ||||
|   statically or dynamically link your code (or bind by name) to the  | ||||
|   interfaces of this file without subjecting your linked code to the  | ||||
|   terms of the CPL or GNU LGPL. Any modifications or additions  | ||||
|   to this file, however, are subject to the LGPL or CPL terms. | ||||
| */ | ||||
|  | ||||
| #ifndef __LZMADECODE_H | ||||
| #define __LZMADECODE_H | ||||
|  | ||||
| #include "LzmaTypes.h" | ||||
|  | ||||
| /* #define _LZMA_IN_CB */ | ||||
| /* Use callback for input data */ | ||||
|  | ||||
| /* #define _LZMA_OUT_READ */ | ||||
| /* Use read function for output data */ | ||||
|  | ||||
| /* #define _LZMA_PROB32 */ | ||||
| /* It can increase speed on some 32-bit CPUs,  | ||||
|    but memory usage will be doubled in that case */ | ||||
|  | ||||
| /* #define _LZMA_LOC_OPT */ | ||||
| /* Enable local speed optimizations inside code */ | ||||
|  | ||||
| #ifdef _LZMA_PROB32 | ||||
| #define CProb UInt32 | ||||
| #else | ||||
| #define CProb UInt16 | ||||
| #endif | ||||
|  | ||||
| #define LZMA_RESULT_OK 0 | ||||
| #define LZMA_RESULT_DATA_ERROR 1 | ||||
|  | ||||
| #ifdef _LZMA_IN_CB | ||||
| typedef struct _ILzmaInCallback | ||||
| { | ||||
|   int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); | ||||
| } ILzmaInCallback; | ||||
| #endif | ||||
|  | ||||
| #define LZMA_BASE_SIZE 1846 | ||||
| #define LZMA_LIT_SIZE 768 | ||||
|  | ||||
| #define LZMA_PROPERTIES_SIZE 5 | ||||
|  | ||||
| typedef struct _CLzmaProperties | ||||
| { | ||||
|   int lc; | ||||
|   int lp; | ||||
|   int pb; | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   UInt32 DictionarySize; | ||||
|   #endif | ||||
| }CLzmaProperties; | ||||
|  | ||||
| int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); | ||||
|  | ||||
| #define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) | ||||
|  | ||||
| #define kLzmaNeedInitId (-2) | ||||
|  | ||||
| typedef struct _CLzmaDecoderState | ||||
| { | ||||
|   CLzmaProperties Properties; | ||||
|   CProb *Probs; | ||||
|  | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   const unsigned char *Buffer; | ||||
|   const unsigned char *BufferLim; | ||||
|   #endif | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   unsigned char *Dictionary; | ||||
|   UInt32 Range; | ||||
|   UInt32 Code; | ||||
|   UInt32 DictionaryPos; | ||||
|   UInt32 GlobalPos; | ||||
|   UInt32 DistanceLimit; | ||||
|   UInt32 Reps[4]; | ||||
|   int State; | ||||
|   int RemainLen; | ||||
|   unsigned char TempDictionary[4]; | ||||
|   #endif | ||||
| } CLzmaDecoderState; | ||||
|  | ||||
| #ifdef _LZMA_OUT_READ | ||||
| #define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } | ||||
| #endif | ||||
|  | ||||
| int LzmaDecode(CLzmaDecoderState *vs, | ||||
|     #ifdef _LZMA_IN_CB | ||||
|     ILzmaInCallback *inCallback, | ||||
|     #else | ||||
|     const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, | ||||
|     #endif | ||||
|     unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										45
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaTypes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaTypes.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /*  | ||||
| LzmaTypes.h  | ||||
|  | ||||
| Types for LZMA Decoder | ||||
|  | ||||
| This file written and distributed to public domain by Igor Pavlov. | ||||
| This file is part of LZMA SDK 4.40 (2006-05-01) | ||||
| */ | ||||
|  | ||||
| #ifndef __LZMATYPES_H | ||||
| #define __LZMATYPES_H | ||||
|  | ||||
| #ifndef _7ZIP_BYTE_DEFINED | ||||
| #define _7ZIP_BYTE_DEFINED | ||||
| typedef unsigned char Byte; | ||||
| #endif  | ||||
|  | ||||
| #ifndef _7ZIP_UINT16_DEFINED | ||||
| #define _7ZIP_UINT16_DEFINED | ||||
| typedef unsigned short UInt16; | ||||
| #endif  | ||||
|  | ||||
| #ifndef _7ZIP_UINT32_DEFINED | ||||
| #define _7ZIP_UINT32_DEFINED | ||||
| #ifdef _LZMA_UINT32_IS_ULONG | ||||
| typedef unsigned long UInt32; | ||||
| #else | ||||
| typedef unsigned int UInt32; | ||||
| #endif | ||||
| #endif  | ||||
|  | ||||
| /* #define _LZMA_NO_SYSTEM_SIZE_T */ | ||||
| /* You can use it, if you don't want <stddef.h> */ | ||||
|  | ||||
| #ifndef _7ZIP_SIZET_DEFINED | ||||
| #define _7ZIP_SIZET_DEFINED | ||||
| #ifdef _LZMA_NO_SYSTEM_SIZE_T | ||||
| typedef UInt32 SizeT; | ||||
| #else | ||||
| #include <stddef.h> | ||||
| typedef size_t SizeT; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										85
									
								
								target/linux/bmips/image/lzma-loader/src/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								target/linux/bmips/image/lzma-loader/src/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| # | ||||
| # Makefile for the LZMA compressed kernel loader for BMIPS based boards | ||||
| # | ||||
| # Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| # Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
| # Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
| # | ||||
| # Some parts of this file was based on the OpenWrt specific lzma-loader | ||||
| # for the BCM47xx and ADM5120 based boards: | ||||
| #	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) | ||||
| #	Copyright (C) 2005 Mineharu Takahara <mtakahar@yahoo.com> | ||||
| #	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> | ||||
| # | ||||
|  | ||||
| LOADER_ADDR	:= | ||||
| KERNEL_ADDR	:= | ||||
| LZMA_TEXT_START	:= 0x80a00000 | ||||
| LOADER_DATA	:= | ||||
|  | ||||
| CC		:= $(CROSS_COMPILE)gcc | ||||
| LD		:= $(CROSS_COMPILE)ld | ||||
| OBJCOPY		:= $(CROSS_COMPILE)objcopy | ||||
| OBJDUMP		:= $(CROSS_COMPILE)objdump | ||||
|  | ||||
| BIN_FLAGS	:= -O binary -R .reginfo -R .note -R .comment -R .mdebug \ | ||||
| 		   -R .MIPS.abiflags -S | ||||
|  | ||||
| CFLAGS		= -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ | ||||
| 		  -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \ | ||||
| 		  -mno-abicalls -fno-pic -ffunction-sections -pipe \ | ||||
| 		  -ffreestanding -fhonour-copts \ | ||||
| 		  -mabi=32 -march=mips32 \ | ||||
| 		  -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap | ||||
| CFLAGS		+= -D_LZMA_PROB32 | ||||
| CFLAGS		+= -DUART_BASE=$(UART_BASE) | ||||
|  | ||||
| ASFLAGS		= $(CFLAGS) -D__ASSEMBLY__ | ||||
|  | ||||
| LDFLAGS		= -static --gc-sections -no-warn-mismatch | ||||
| LDFLAGS		+= -e startup -T loader.lds -Ttext $(LZMA_TEXT_START) | ||||
|  | ||||
| O_FORMAT 	= $(shell $(OBJDUMP) -i | head -2 | grep elf32) | ||||
|  | ||||
| OBJECTS		:= head.o loader.o cache.o board.o printf.o LzmaDecode.o | ||||
|  | ||||
| ifneq ($(strip $(LOADER_DATA)),) | ||||
| OBJECTS		+= data.o | ||||
| CFLAGS		+= -DLZMA_WRAPPER=1 -DLOADADDR=$(KERNEL_ADDR) | ||||
| endif | ||||
|  | ||||
|  | ||||
| all: loader.elf | ||||
|  | ||||
| # Don't build dependencies, this may die if $(CC) isn't gcc | ||||
| dep: | ||||
|  | ||||
| install: | ||||
|  | ||||
| %.o : %.c | ||||
| 	$(CC) $(CFLAGS) -c -o $@ $< | ||||
|  | ||||
| %.o : %.S | ||||
| 	$(CC) $(ASFLAGS) -c -o $@ $< | ||||
|  | ||||
| data.o: $(LOADER_DATA) | ||||
| 	$(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< | ||||
|  | ||||
| loader: $(OBJECTS) | ||||
| 	$(LD) $(LDFLAGS) -o $@ $(OBJECTS) | ||||
|  | ||||
| loader.bin: loader | ||||
| 	$(OBJCOPY) $(BIN_FLAGS) $< $@ | ||||
|  | ||||
| loader2.o: loader.bin | ||||
| 	$(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $< | ||||
|  | ||||
| loader.elf: loader2.o | ||||
| 	$(LD) -e startup -T loader2.lds -Ttext $(LOADER_ADDR) -o $@ $< | ||||
|  | ||||
| mrproper: clean | ||||
|  | ||||
| clean: | ||||
| 	rm -f loader *.elf *.bin *.o | ||||
							
								
								
									
										37
									
								
								target/linux/bmips/image/lzma-loader/src/board.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								target/linux/bmips/image/lzma-loader/src/board.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * BCM63XX specific implementation parts | ||||
|  * | ||||
|  * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com> | ||||
|  * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
|  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include "config.h" | ||||
|  | ||||
| #define READREG(r)	*(volatile unsigned int *)(r) | ||||
| #define WRITEREG(r,v)	*(volatile unsigned int *)(r) = v | ||||
|  | ||||
| #define UART_IR_REG	0x10 | ||||
| #define UART_FIFO_REG	0x14 | ||||
|  | ||||
| static void wait_xfered(void) | ||||
| { | ||||
|         unsigned int val; | ||||
|  | ||||
|         do { | ||||
|                 val = READREG(UART_BASE + UART_IR_REG); | ||||
|                 if (val & (1 << 5)) | ||||
|                         break; | ||||
|         } while (1); | ||||
| } | ||||
|  | ||||
| void board_putc(int ch) | ||||
| { | ||||
| 	if (!UART_BASE) | ||||
| 		return; | ||||
|  | ||||
| 	wait_xfered(); | ||||
| 	WRITEREG(UART_BASE + UART_FIFO_REG, ch); | ||||
| 	wait_xfered(); | ||||
| } | ||||
							
								
								
									
										42
									
								
								target/linux/bmips/image/lzma-loader/src/cache.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								target/linux/bmips/image/lzma-loader/src/cache.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * | ||||
|  * The cache manipulation routine has been taken from the U-Boot project. | ||||
|  *	(C) Copyright 2003 | ||||
|  *	Wolfgang Denk, DENX Software Engineering, <wd@denx.de> | ||||
|  */ | ||||
|  | ||||
| #include "cache.h" | ||||
| #include "cacheops.h" | ||||
| #include "config.h" | ||||
| #include "printf.h" | ||||
|  | ||||
| #define cache_op(op,addr)						\ | ||||
| 	__asm__ __volatile__(						\ | ||||
| 	"	.set	push					\n"	\ | ||||
| 	"	.set	noreorder				\n"	\ | ||||
| 	"	.set	mips3\n\t				\n"	\ | ||||
| 	"	cache	%0, %1					\n"	\ | ||||
| 	"	.set	pop					\n"	\ | ||||
| 	:								\ | ||||
| 	: "i" (op), "R" (*(unsigned char *)(addr))) | ||||
|  | ||||
| void flush_cache(unsigned long start_addr, unsigned long size) | ||||
| { | ||||
| 	unsigned long lsize = CONFIG_CACHELINE_SIZE; | ||||
| 	unsigned long addr = start_addr & ~(lsize - 1); | ||||
| 	unsigned long aend = (start_addr + size + (lsize - 1)) & ~(lsize - 1); | ||||
|  | ||||
| 	printf("blasting from 0x%08x to 0x%08x (0x%08x - 0x%08x)\n", start_addr, size, addr, aend); | ||||
|  | ||||
| 	while (1) { | ||||
| 		cache_op(Hit_Writeback_Inv_D, addr); | ||||
| 		cache_op(Hit_Invalidate_I, addr); | ||||
| 		if (addr == aend) | ||||
| 			break; | ||||
| 		addr += lsize; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/cache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/cache.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  */ | ||||
|  | ||||
| #ifndef __CACHE_H | ||||
| #define __CACHE_H | ||||
|  | ||||
| void flush_cache(unsigned long start_addr, unsigned long size); | ||||
|  | ||||
| #endif /* __CACHE_H */ | ||||
							
								
								
									
										82
									
								
								target/linux/bmips/image/lzma-loader/src/cacheops.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								target/linux/bmips/image/lzma-loader/src/cacheops.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Cache operations for the cache instruction. | ||||
|  * | ||||
|  * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle | ||||
|  * (C) Copyright 1999 Silicon Graphics, Inc. | ||||
|  */ | ||||
| #ifndef	__ASM_CACHEOPS_H | ||||
| #define	__ASM_CACHEOPS_H | ||||
|  | ||||
| /* | ||||
|  * Cache Operations available on all MIPS processors with R4000-style caches | ||||
|  */ | ||||
| #define Index_Invalidate_I      0x00 | ||||
| #define Index_Writeback_Inv_D   0x01 | ||||
| #define Index_Load_Tag_I	0x04 | ||||
| #define Index_Load_Tag_D	0x05 | ||||
| #define Index_Store_Tag_I	0x08 | ||||
| #define Index_Store_Tag_D	0x09 | ||||
| #if defined(CONFIG_CPU_LOONGSON2) | ||||
| #define Hit_Invalidate_I	0x00 | ||||
| #else | ||||
| #define Hit_Invalidate_I	0x10 | ||||
| #endif | ||||
| #define Hit_Invalidate_D	0x11 | ||||
| #define Hit_Writeback_Inv_D	0x15 | ||||
|  | ||||
| /* | ||||
|  * R4000-specific cacheops | ||||
|  */ | ||||
| #define Create_Dirty_Excl_D	0x0d | ||||
| #define Fill			0x14 | ||||
| #define Hit_Writeback_I		0x18 | ||||
| #define Hit_Writeback_D		0x19 | ||||
|  | ||||
| /* | ||||
|  * R4000SC and R4400SC-specific cacheops | ||||
|  */ | ||||
| #define Index_Invalidate_SI     0x02 | ||||
| #define Index_Writeback_Inv_SD  0x03 | ||||
| #define Index_Load_Tag_SI	0x06 | ||||
| #define Index_Load_Tag_SD	0x07 | ||||
| #define Index_Store_Tag_SI	0x0A | ||||
| #define Index_Store_Tag_SD	0x0B | ||||
| #define Create_Dirty_Excl_SD	0x0f | ||||
| #define Hit_Invalidate_SI	0x12 | ||||
| #define Hit_Invalidate_SD	0x13 | ||||
| #define Hit_Writeback_Inv_SD	0x17 | ||||
| #define Hit_Writeback_SD	0x1b | ||||
| #define Hit_Set_Virtual_SI	0x1e | ||||
| #define Hit_Set_Virtual_SD	0x1f | ||||
|  | ||||
| /* | ||||
|  * R5000-specific cacheops | ||||
|  */ | ||||
| #define R5K_Page_Invalidate_S	0x17 | ||||
|  | ||||
| /* | ||||
|  * RM7000-specific cacheops | ||||
|  */ | ||||
| #define Page_Invalidate_T	0x16 | ||||
|  | ||||
| /* | ||||
|  * R10000-specific cacheops | ||||
|  * | ||||
|  * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. | ||||
|  * Most of the _S cacheops are identical to the R4000SC _SD cacheops. | ||||
|  */ | ||||
| #define Index_Writeback_Inv_S	0x03 | ||||
| #define Index_Load_Tag_S	0x07 | ||||
| #define Index_Store_Tag_S	0x0B | ||||
| #define Hit_Invalidate_S	0x13 | ||||
| #define Cache_Barrier		0x14 | ||||
| #define Hit_Writeback_Inv_S	0x17 | ||||
| #define Index_Load_Data_I	0x18 | ||||
| #define Index_Load_Data_D	0x19 | ||||
| #define Index_Load_Data_S	0x1b | ||||
| #define Index_Store_Data_I	0x1c | ||||
| #define Index_Store_Data_D	0x1d | ||||
| #define Index_Store_Data_S	0x1f | ||||
|  | ||||
| #endif	/* __ASM_CACHEOPS_H */ | ||||
							
								
								
									
										15
									
								
								target/linux/bmips/image/lzma-loader/src/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								target/linux/bmips/image/lzma-loader/src/config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  */ | ||||
|  | ||||
| #ifndef _CONFIG_H_ | ||||
| #define _CONFIG_H_ | ||||
|  | ||||
| #define CONFIG_ICACHE_SIZE	(32 * 1024) | ||||
| #define CONFIG_DCACHE_SIZE	(32 * 1024) | ||||
| #define CONFIG_CACHELINE_SIZE	16 | ||||
|  | ||||
| #endif /* _CONFIG_H_ */ | ||||
							
								
								
									
										55
									
								
								target/linux/bmips/image/lzma-loader/src/cp0regdef.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								target/linux/bmips/image/lzma-loader/src/cp0regdef.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle | ||||
|  * | ||||
|  * Copyright (C) 2001, Monta Vista Software | ||||
|  * Author: jsun@mvista.com or jsun@junsun.net | ||||
|  */ | ||||
| #ifndef _cp0regdef_h_ | ||||
| #define _cp0regdef_h_ | ||||
|  | ||||
| #define CP0_INDEX $0 | ||||
| #define CP0_RANDOM $1 | ||||
| #define CP0_ENTRYLO0 $2 | ||||
| #define CP0_ENTRYLO1 $3 | ||||
| #define CP0_CONTEXT $4 | ||||
| #define CP0_PAGEMASK $5 | ||||
| #define CP0_WIRED $6 | ||||
| #define CP0_BADVADDR $8 | ||||
| #define CP0_COUNT $9 | ||||
| #define CP0_ENTRYHI $10 | ||||
| #define CP0_COMPARE $11 | ||||
| #define CP0_STATUS $12 | ||||
| #define CP0_CAUSE $13 | ||||
| #define CP0_EPC $14 | ||||
| #define CP0_PRID $15 | ||||
| #define CP0_CONFIG $16 | ||||
| #define CP0_LLADDR $17 | ||||
| #define CP0_WATCHLO $18 | ||||
| #define CP0_WATCHHI $19 | ||||
| #define CP0_XCONTEXT $20 | ||||
| #define CP0_FRAMEMASK $21 | ||||
| #define CP0_DIAGNOSTIC $22 | ||||
| #define CP0_PERFORMANCE $25 | ||||
| #define CP0_ECC $26 | ||||
| #define CP0_CACHEERR $27 | ||||
| #define CP0_TAGLO $28 | ||||
| #define CP0_TAGHI $29 | ||||
| #define CP0_ERROREPC $30 | ||||
|  | ||||
| #define read_32bit_c0_register(reg,sel)					\ | ||||
| ({	int __res;							\ | ||||
| 	if (sel == 0)							\ | ||||
| 		__asm__ __volatile__(					\ | ||||
| 			"mfc0\t%0, " #reg "\n\t"			\ | ||||
| 			: "=r" (__res));				\ | ||||
| 	else								\ | ||||
| 		__asm__ __volatile__(					\ | ||||
| 			".set\tmips32\n\t"				\ | ||||
| 			"mfc0\t%0, " #reg ", " #sel "\n\t"		\ | ||||
| 			".set mips0\n\t"				\ | ||||
| 			: "=r" (__res));				\ | ||||
| 	__res;								\ | ||||
| }) | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										118
									
								
								target/linux/bmips/image/lzma-loader/src/head.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								target/linux/bmips/image/lzma-loader/src/head.S
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * | ||||
|  * Some parts of this code was based on the OpenWrt specific lzma-loader | ||||
|  * for the BCM47xx and ADM5120 based boards: | ||||
|  *	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) | ||||
|  *	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> | ||||
|  */ | ||||
|  | ||||
| #include <asm/asm.h> | ||||
| #include <asm/regdef.h> | ||||
| #include "cp0regdef.h" | ||||
| #include "cacheops.h" | ||||
| #include "config.h" | ||||
|  | ||||
| #define KSEG0		0x80000000 | ||||
|  | ||||
| 	.macro	ehb | ||||
| 	sll     zero, 3 | ||||
| 	.endm | ||||
|  | ||||
| 	.text | ||||
|  | ||||
| LEAF(startup) | ||||
| 	.set noreorder | ||||
| 	.set mips32 | ||||
|  | ||||
| 	mtc0	zero, CP0_WATCHLO	# clear watch registers | ||||
| 	mtc0	zero, CP0_WATCHHI | ||||
| 	mtc0	zero, CP0_CAUSE		# clear before writing status register | ||||
|  | ||||
| 	mfc0	t0, CP0_STATUS | ||||
| 	li	t1, 0x1000001f | ||||
| 	or	t0, t1 | ||||
| 	xori	t0, 0x1f | ||||
| 	mtc0	t0, CP0_STATUS | ||||
| 	ehb | ||||
|  | ||||
| 	mtc0	zero, CP0_COUNT | ||||
| 	mtc0	zero, CP0_COMPARE | ||||
| 	ehb | ||||
|  | ||||
| 	la	t0, __reloc_label	# get linked address of label | ||||
| 	bal	__reloc_label		# branch and link to label to | ||||
| 	nop				# get actual address | ||||
| __reloc_label: | ||||
| 	subu	t0, ra, t0		# get reloc_delta | ||||
|  | ||||
| 	beqz	t0, __reloc_done         # if delta is 0 we are in the right place | ||||
| 	nop | ||||
|  | ||||
| 	/* Copy our code to the right place */ | ||||
| 	la	t1, _code_start		# get linked address of _code_start | ||||
| 	la	t2, _code_end		# get linked address of _code_end | ||||
| 	addu	t0, t0, t1		# calculate actual address of _code_start | ||||
|  | ||||
| __reloc_copy: | ||||
| 	lw	t3, 0(t0) | ||||
| 	sw	t3, 0(t1) | ||||
| 	add	t1, 4 | ||||
| 	blt	t1, t2, __reloc_copy | ||||
| 	add	t0, 4 | ||||
|  | ||||
| 	/* flush cache */ | ||||
| 	la	t0, _code_start | ||||
| 	la	t1, _code_end | ||||
|  | ||||
| 	li	t2, ~(CONFIG_CACHELINE_SIZE - 1) | ||||
| 	and	t0, t2 | ||||
| 	and	t1, t2 | ||||
| 	li	t2, CONFIG_CACHELINE_SIZE | ||||
|  | ||||
| 	b	__flush_check | ||||
| 	nop | ||||
|  | ||||
| __flush_line: | ||||
| 	cache	Hit_Writeback_Inv_D, 0(t0) | ||||
| 	cache	Hit_Invalidate_I, 0(t0) | ||||
| 	add	t0, t2 | ||||
|  | ||||
| __flush_check: | ||||
| 	bne	t0, t1, __flush_line | ||||
| 	nop | ||||
|  | ||||
| 	sync | ||||
|  | ||||
| __reloc_done: | ||||
|  | ||||
| 	/* clear bss */ | ||||
| 	la	t0, _bss_start | ||||
| 	la	t1, _bss_end | ||||
| 	b	__bss_check | ||||
| 	nop | ||||
|  | ||||
| __bss_fill: | ||||
| 	sw	zero, 0(t0) | ||||
| 	addi	t0, 4 | ||||
|  | ||||
| __bss_check: | ||||
| 	bne	t0, t1, __bss_fill | ||||
| 	nop | ||||
|  | ||||
| 	/* Setup new "C" stack */ | ||||
| 	la	sp, _stack | ||||
|  | ||||
| 	/* reserve stack space for a0-a3 registers */ | ||||
| 	subu	sp, 16 | ||||
|  | ||||
| 	/* jump to the decompressor routine */ | ||||
| 	la	t0, loader_main | ||||
| 	jr	t0 | ||||
| 	nop | ||||
|  | ||||
| 	.set reorder | ||||
| END(startup) | ||||
							
								
								
									
										169
									
								
								target/linux/bmips/image/lzma-loader/src/loader.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								target/linux/bmips/image/lzma-loader/src/loader.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * | ||||
|  * Some parts of this code was based on the OpenWrt specific lzma-loader | ||||
|  * for the BCM47xx and ADM5120 based boards: | ||||
|  *	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) | ||||
|  *	Copyright (C) 2005 Mineharu Takahara <mtakahar@yahoo.com> | ||||
|  *	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> | ||||
|  * | ||||
|  * The image_header structure has been taken from the U-Boot project. | ||||
|  *	(C) Copyright 2008 Semihalf | ||||
|  *	(C) Copyright 2000-2005 | ||||
|  *	Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||||
|  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "config.h" | ||||
| #include "cache.h" | ||||
| #include "printf.h" | ||||
| #include "LzmaDecode.h" | ||||
|  | ||||
| #define KSEG0			0x80000000 | ||||
| #define KSEG1			0xa0000000 | ||||
|  | ||||
| #define KSEG1ADDR(a)		((((unsigned)(a)) & 0x1fffffffU) | KSEG1) | ||||
|  | ||||
| #undef LZMA_DEBUG | ||||
|  | ||||
| #ifdef LZMA_DEBUG | ||||
| #  define DBG(f, a...)	printf(f, ## a) | ||||
| #else | ||||
| #  define DBG(f, a...)	do {} while (0) | ||||
| #endif | ||||
|  | ||||
| /* beyond the image end, size not known in advance */ | ||||
| extern unsigned char workspace[]; | ||||
|  | ||||
|  | ||||
| static CLzmaDecoderState lzma_state; | ||||
| static unsigned char *lzma_data; | ||||
| static unsigned long lzma_datasize; | ||||
| static unsigned long lzma_outsize; | ||||
| static unsigned long kernel_la; | ||||
|  | ||||
| static void halt(void) | ||||
| { | ||||
| 	printf("\nSystem halted!\n"); | ||||
| 	for(;;); | ||||
| } | ||||
|  | ||||
| static __inline__ unsigned char lzma_get_byte(void) | ||||
| { | ||||
| 	unsigned char c; | ||||
|  | ||||
| 	lzma_datasize--; | ||||
| 	c = *lzma_data++; | ||||
|  | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| static int lzma_init_props(void) | ||||
| { | ||||
| 	unsigned char props[LZMA_PROPERTIES_SIZE]; | ||||
| 	int res; | ||||
| 	int i; | ||||
|  | ||||
| 	/* read lzma properties */ | ||||
| 	for (i = 0; i < LZMA_PROPERTIES_SIZE; i++) | ||||
| 		props[i] = lzma_get_byte(); | ||||
|  | ||||
| 	/* read the lower half of uncompressed size in the header */ | ||||
| 	lzma_outsize = ((SizeT) lzma_get_byte()) + | ||||
| 		       ((SizeT) lzma_get_byte() << 8) + | ||||
| 		       ((SizeT) lzma_get_byte() << 16) + | ||||
| 		       ((SizeT) lzma_get_byte() << 24); | ||||
|  | ||||
| 	/* skip rest of the header (upper half of uncompressed size) */ | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 		lzma_get_byte(); | ||||
|  | ||||
| 	res = LzmaDecodeProperties(&lzma_state.Properties, props, | ||||
| 					LZMA_PROPERTIES_SIZE); | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| static int lzma_decompress(unsigned char *outStream) | ||||
| { | ||||
| 	SizeT ip, op; | ||||
| 	int ret; | ||||
|  | ||||
| 	lzma_state.Probs = (CProb *) workspace; | ||||
|  | ||||
| 	ret = LzmaDecode(&lzma_state, lzma_data, lzma_datasize, &ip, outStream, | ||||
| 			 lzma_outsize, &op); | ||||
|  | ||||
| 	if (ret != LZMA_RESULT_OK) { | ||||
| 		int i; | ||||
|  | ||||
| 		DBG("LzmaDecode error %d at %08x, osize:%d ip:%d op:%d\n", | ||||
| 		    ret, lzma_data + ip, lzma_outsize, ip, op); | ||||
|  | ||||
| 		for (i = 0; i < 16; i++) | ||||
| 			DBG("%02x ", lzma_data[ip + i]); | ||||
|  | ||||
| 		DBG("\n"); | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static void lzma_init_data(void) | ||||
| { | ||||
| 	extern unsigned char _lzma_data_start[]; | ||||
| 	extern unsigned char _lzma_data_end[]; | ||||
|  | ||||
| 	kernel_la = LOADADDR; | ||||
| 	lzma_data = _lzma_data_start; | ||||
| 	lzma_datasize = _lzma_data_end - _lzma_data_start; | ||||
| } | ||||
|  | ||||
| void loader_main(unsigned long reg_a0, unsigned long reg_a1, | ||||
| 		 unsigned long reg_a2, unsigned long reg_a3) | ||||
| { | ||||
| 	void (*kernel_entry) (unsigned long, unsigned long, unsigned long, | ||||
| 			      unsigned long); | ||||
| 	int res; | ||||
|  | ||||
| 	printf("\n\nOpenWrt kernel loader for BMIPS\n"); | ||||
| 	printf("Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>\n"); | ||||
| 	printf("Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>\n"); | ||||
| 	printf("Copyright (C) 2020 Alvaro Fernandez Rojas <noltari@gmail.com>\n"); | ||||
|  | ||||
| 	lzma_init_data(); | ||||
|  | ||||
| 	res = lzma_init_props(); | ||||
| 	if (res != LZMA_RESULT_OK) { | ||||
| 		printf("Incorrect LZMA stream properties!\n"); | ||||
| 		halt(); | ||||
| 	} | ||||
|  | ||||
| 	printf("Decompressing kernel... "); | ||||
|  | ||||
| 	res = lzma_decompress((unsigned char *) kernel_la); | ||||
| 	if (res != LZMA_RESULT_OK) { | ||||
| 		printf("failed, "); | ||||
| 		switch (res) { | ||||
| 		case LZMA_RESULT_DATA_ERROR: | ||||
| 			printf("data error!\n"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			printf("unknown error %d!\n", res); | ||||
| 		} | ||||
| 		halt(); | ||||
| 	} else { | ||||
| 		printf("done!\n"); | ||||
| 	} | ||||
|  | ||||
| 	flush_cache(kernel_la, lzma_outsize); | ||||
|  | ||||
| 	printf("Starting kernel at %08x...\n\n", kernel_la); | ||||
|  | ||||
| 	kernel_entry = (void *) kernel_la; | ||||
| 	kernel_entry(reg_a0, reg_a1, reg_a2, reg_a3); | ||||
| } | ||||
							
								
								
									
										36
									
								
								target/linux/bmips/image/lzma-loader/src/loader.lds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								target/linux/bmips/image/lzma-loader/src/loader.lds
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
|  | ||||
| OUTPUT_ARCH(mips) | ||||
| SECTIONS { | ||||
| 	.text : { | ||||
| 		_code_start = .; | ||||
| 		*(.text) | ||||
| 		*(.text.*) | ||||
| 		*(.rodata) | ||||
| 		*(.rodata.*) | ||||
| 		*(.data.lzma) | ||||
| 	} | ||||
|  | ||||
| 	. = ALIGN(32); | ||||
| 	.data : { | ||||
| 		*(.data) | ||||
| 		*(.data.*) | ||||
| 	} | ||||
|  | ||||
| 	. = ALIGN(32); | ||||
| 	_code_end = .; | ||||
|  | ||||
| 	_bss_start = .; | ||||
| 	.bss : { | ||||
| 		*(.bss) | ||||
| 		*(.bss.*) | ||||
| 	} | ||||
|  | ||||
| 	. = ALIGN(32); | ||||
| 	_bss_end = .; | ||||
|  | ||||
| 	. = . + 8192; | ||||
| 	_stack = .; | ||||
|  | ||||
| 	workspace = .; | ||||
| } | ||||
							
								
								
									
										12
									
								
								target/linux/bmips/image/lzma-loader/src/loader2.lds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								target/linux/bmips/image/lzma-loader/src/loader2.lds
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
|  | ||||
| OUTPUT_ARCH(mips) | ||||
| SECTIONS { | ||||
| 	.text : { | ||||
| 		startup = .; | ||||
| 		*(.text) | ||||
| 		*(.text.*) | ||||
| 		*(.data) | ||||
| 		*(.data.*) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										10
									
								
								target/linux/bmips/image/lzma-loader/src/lzma-data.lds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								target/linux/bmips/image/lzma-loader/src/lzma-data.lds
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
|  | ||||
| OUTPUT_ARCH(mips) | ||||
| SECTIONS { | ||||
| 	.data.lzma : { | ||||
| 		_lzma_data_start = .; | ||||
| 		*(.data) | ||||
| 		_lzma_data_end = .; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										345
									
								
								target/linux/bmips/image/lzma-loader/src/printf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								target/linux/bmips/image/lzma-loader/src/printf.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,345 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Copyright (C) 2001 MontaVista Software Inc. | ||||
|  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | ||||
|  */ | ||||
|  | ||||
| #include	"printf.h" | ||||
|  | ||||
| extern void board_putc(int ch); | ||||
|  | ||||
| /* this is the maximum width for a variable */ | ||||
| #define		LP_MAX_BUF	256 | ||||
|  | ||||
| /* macros */ | ||||
| #define		IsDigit(x)	( ((x) >= '0') && ((x) <= '9') ) | ||||
| #define		Ctod(x)		( (x) - '0') | ||||
|  | ||||
| /* forward declaration */ | ||||
| static int PrintChar(char *, char, int, int); | ||||
| static int PrintString(char *, char *, int, int); | ||||
| static int PrintNum(char *, unsigned long, int, int, int, int, char, int); | ||||
|  | ||||
| /* private variable */ | ||||
| static const char theFatalMsg[] = "fatal error in lp_Print!"; | ||||
|  | ||||
| /* -*- | ||||
|  * A low level printf() function. | ||||
|  */ | ||||
| static void | ||||
| lp_Print(void (*output)(void *, char *, int), | ||||
| 	 void * arg, | ||||
| 	 char *fmt, | ||||
| 	 va_list ap) | ||||
| { | ||||
|  | ||||
| #define 	OUTPUT(arg, s, l)  \ | ||||
|   { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \ | ||||
|        (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \ | ||||
|     } else { \ | ||||
|       (*output)(arg, s, l); \ | ||||
|     } \ | ||||
|   } | ||||
|  | ||||
|     char buf[LP_MAX_BUF]; | ||||
|  | ||||
|     char c; | ||||
|     char *s; | ||||
|     long int num; | ||||
|  | ||||
|     int longFlag; | ||||
|     int negFlag; | ||||
|     int width; | ||||
|     int prec; | ||||
|     int ladjust; | ||||
|     char padc; | ||||
|  | ||||
|     int length; | ||||
|  | ||||
|     for(;;) { | ||||
| 	{ | ||||
| 	    /* scan for the next '%' */ | ||||
| 	    char *fmtStart = fmt; | ||||
| 	    while ( (*fmt != '\0') && (*fmt != '%')) { | ||||
| 		fmt ++; | ||||
| 	    } | ||||
|  | ||||
| 	    /* flush the string found so far */ | ||||
| 	    OUTPUT(arg, fmtStart, fmt-fmtStart); | ||||
|  | ||||
| 	    /* are we hitting the end? */ | ||||
| 	    if (*fmt == '\0') break; | ||||
| 	} | ||||
|  | ||||
| 	/* we found a '%' */ | ||||
| 	fmt ++; | ||||
|  | ||||
| 	/* check for long */ | ||||
| 	if (*fmt == 'l') { | ||||
| 	    longFlag = 1; | ||||
| 	    fmt ++; | ||||
| 	} else { | ||||
| 	    longFlag = 0; | ||||
| 	} | ||||
|  | ||||
| 	/* check for other prefixes */ | ||||
| 	width = 0; | ||||
| 	prec = -1; | ||||
| 	ladjust = 0; | ||||
| 	padc = ' '; | ||||
|  | ||||
| 	if (*fmt == '-') { | ||||
| 	    ladjust = 1; | ||||
| 	    fmt ++; | ||||
| 	} | ||||
|  | ||||
| 	if (*fmt == '0') { | ||||
| 	    padc = '0'; | ||||
| 	    fmt++; | ||||
| 	} | ||||
|  | ||||
| 	if (IsDigit(*fmt)) { | ||||
| 	    while (IsDigit(*fmt)) { | ||||
| 		width = 10 * width + Ctod(*fmt++); | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
| 	if (*fmt == '.') { | ||||
| 	    fmt ++; | ||||
| 	    if (IsDigit(*fmt)) { | ||||
| 		prec = 0; | ||||
| 		while (IsDigit(*fmt)) { | ||||
| 		    prec = prec*10 + Ctod(*fmt++); | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/* check format flag */ | ||||
| 	negFlag = 0; | ||||
| 	switch (*fmt) { | ||||
| 	 case 'b': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'd': | ||||
| 	 case 'D': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    if (num < 0) { | ||||
| 		num = - num; | ||||
| 		negFlag = 1; | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'o': | ||||
| 	 case 'O': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'u': | ||||
| 	 case 'U': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'x': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'X': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'c': | ||||
| 	    c = (char)va_arg(ap, int); | ||||
| 	    length = PrintChar(buf, c, width, ladjust); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 's': | ||||
| 	    s = (char*)va_arg(ap, char *); | ||||
| 	    length = PrintString(buf, s, width, ladjust); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case '\0': | ||||
| 	    fmt --; | ||||
| 	    break; | ||||
|  | ||||
| 	 default: | ||||
| 	    /* output this char as it is */ | ||||
| 	    OUTPUT(arg, fmt, 1); | ||||
| 	}	/* switch (*fmt) */ | ||||
|  | ||||
| 	fmt ++; | ||||
|     }		/* for(;;) */ | ||||
|  | ||||
|     /* special termination call */ | ||||
|     OUTPUT(arg, "\0", 1); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* --------------- local help functions --------------------- */ | ||||
| static int | ||||
| PrintChar(char * buf, char c, int length, int ladjust) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     if (length < 1) length = 1; | ||||
|     if (ladjust) { | ||||
| 	*buf = c; | ||||
| 	for (i=1; i< length; i++) buf[i] = ' '; | ||||
|     } else { | ||||
| 	for (i=0; i< length-1; i++) buf[i] = ' '; | ||||
| 	buf[length - 1] = c; | ||||
|     } | ||||
|     return length; | ||||
| } | ||||
|  | ||||
| static int | ||||
| PrintString(char * buf, char* s, int length, int ladjust) | ||||
| { | ||||
|     int i; | ||||
|     int len=0; | ||||
|     char* s1 = s; | ||||
|     while (*s1++) len++; | ||||
|     if (length < len) length = len; | ||||
|  | ||||
|     if (ladjust) { | ||||
| 	for (i=0; i< len; i++) buf[i] = s[i]; | ||||
| 	for (i=len; i< length; i++) buf[i] = ' '; | ||||
|     } else { | ||||
| 	for (i=0; i< length-len; i++) buf[i] = ' '; | ||||
| 	for (i=length-len; i < length; i++) buf[i] = s[i-length+len]; | ||||
|     } | ||||
|     return length; | ||||
| } | ||||
|  | ||||
| static int | ||||
| PrintNum(char * buf, unsigned long u, int base, int negFlag, | ||||
| 	 int length, int ladjust, char padc, int upcase) | ||||
| { | ||||
|     /* algorithm : | ||||
|      *  1. prints the number from left to right in reverse form. | ||||
|      *  2. fill the remaining spaces with padc if length is longer than | ||||
|      *     the actual length | ||||
|      *     TRICKY : if left adjusted, no "0" padding. | ||||
|      *		    if negtive, insert  "0" padding between "0" and number. | ||||
|      *  3. if (!ladjust) we reverse the whole string including paddings | ||||
|      *  4. otherwise we only reverse the actual string representing the num. | ||||
|      */ | ||||
|  | ||||
|     int actualLength =0; | ||||
|     char *p = buf; | ||||
|     int i; | ||||
|  | ||||
|     do { | ||||
| 	int tmp = u %base; | ||||
| 	if (tmp <= 9) { | ||||
| 	    *p++ = '0' + tmp; | ||||
| 	} else if (upcase) { | ||||
| 	    *p++ = 'A' + tmp - 10; | ||||
| 	} else { | ||||
| 	    *p++ = 'a' + tmp - 10; | ||||
| 	} | ||||
| 	u /= base; | ||||
|     } while (u != 0); | ||||
|  | ||||
|     if (negFlag) { | ||||
| 	*p++ = '-'; | ||||
|     } | ||||
|  | ||||
|     /* figure out actual length and adjust the maximum length */ | ||||
|     actualLength = p - buf; | ||||
|     if (length < actualLength) length = actualLength; | ||||
|  | ||||
|     /* add padding */ | ||||
|     if (ladjust) { | ||||
| 	padc = ' '; | ||||
|     } | ||||
|     if (negFlag && !ladjust && (padc == '0')) { | ||||
| 	for (i = actualLength-1; i< length-1; i++) buf[i] = padc; | ||||
| 	buf[length -1] = '-'; | ||||
|     } else { | ||||
| 	for (i = actualLength; i< length; i++) buf[i] = padc; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /* prepare to reverse the string */ | ||||
|     { | ||||
| 	int begin = 0; | ||||
| 	int end; | ||||
| 	if (ladjust) { | ||||
| 	    end = actualLength - 1; | ||||
| 	} else { | ||||
| 	    end = length -1; | ||||
| 	} | ||||
|  | ||||
| 	while (end > begin) { | ||||
| 	    char tmp = buf[begin]; | ||||
| 	    buf[begin] = buf[end]; | ||||
| 	    buf[end] = tmp; | ||||
| 	    begin ++; | ||||
| 	    end --; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     /* adjust the string pointer */ | ||||
|     return length; | ||||
| } | ||||
|  | ||||
| static void printf_output(void *arg, char *s, int l) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     // special termination call | ||||
|     if ((l==1) && (s[0] == '\0')) return; | ||||
|  | ||||
|     for (i=0; i< l; i++) { | ||||
| 	board_putc(s[i]); | ||||
| 	if (s[i] == '\n') board_putc('\r'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void printf(char *fmt, ...) | ||||
| { | ||||
|     va_list ap; | ||||
|     va_start(ap, fmt); | ||||
|     lp_Print(printf_output, 0, fmt, ap); | ||||
|     va_end(ap); | ||||
| } | ||||
							
								
								
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/printf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/printf.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Copyright (C) 2001 MontaVista Software Inc. | ||||
|  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | ||||
|  */ | ||||
|  | ||||
| #ifndef _printf_h_ | ||||
| #define _printf_h_ | ||||
|  | ||||
| #include <stdarg.h> | ||||
| void printf(char *fmt, ...); | ||||
|  | ||||
| #endif /* _printf_h_ */ | ||||
							
								
								
									
										31
									
								
								target/linux/bmips/nand/config-default
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								target/linux/bmips/nand/config-default
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| CONFIG_CRC16=y | ||||
| CONFIG_CRYPTO_ACOMP2=y | ||||
| CONFIG_CRYPTO_DEFLATE=y | ||||
| CONFIG_CRYPTO_HASH_INFO=y | ||||
| CONFIG_CRYPTO_LZO=y | ||||
| CONFIG_CRYPTO_ZSTD=y | ||||
| CONFIG_JFFS2_FS_NAND=y | ||||
| CONFIG_LZO_COMPRESS=y | ||||
| CONFIG_LZO_DECOMPRESS=y | ||||
| CONFIG_MTD_NAND_BRCMNAND=y | ||||
| CONFIG_MTD_NAND_CORE=y | ||||
| CONFIG_MTD_NAND_ECC_SW_HAMMING=y | ||||
| CONFIG_MTD_RAW_NAND=y | ||||
| CONFIG_MTD_SPLIT_BCM_WFI_FW=y | ||||
| CONFIG_MTD_UBI=y | ||||
| CONFIG_MTD_UBI_BEB_LIMIT=20 | ||||
| CONFIG_MTD_UBI_BLOCK=y | ||||
| # CONFIG_MTD_UBI_FASTMAP is not set | ||||
| # CONFIG_MTD_UBI_GLUEBI is not set | ||||
| CONFIG_MTD_UBI_WL_THRESHOLD=4096 | ||||
| CONFIG_SGL_ALLOC=y | ||||
| CONFIG_UBIFS_FS=y | ||||
| CONFIG_UBIFS_FS_ADVANCED_COMPR=y | ||||
| CONFIG_UBIFS_FS_LZO=y | ||||
| CONFIG_UBIFS_FS_ZLIB=y | ||||
| CONFIG_UBIFS_FS_ZSTD=y | ||||
| CONFIG_XXHASH=y | ||||
| CONFIG_ZLIB_DEFLATE=y | ||||
| CONFIG_ZLIB_INFLATE=y | ||||
| CONFIG_ZSTD_COMPRESS=y | ||||
| CONFIG_ZSTD_DECOMPRESS=y | ||||
							
								
								
									
										6
									
								
								target/linux/bmips/nand/target.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								target/linux/bmips/nand/target.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| BOARDNAME:=nand | ||||
| FEATURES+=nand | ||||
|  | ||||
| define Target/Description | ||||
|   BMIPS boards with NAND support  | ||||
| endef | ||||
| @@ -0,0 +1,27 @@ | ||||
| From 29906e1aac11bf9907e26608216dc7970e73a70e Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:33 +0200 | ||||
| Subject: [PATCH 1/9] mips: bmips: select ARCH_HAS_RESET_CONTROLLER | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This allows to add reset controllers support. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Acked-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  arch/mips/Kconfig | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
|  | ||||
| --- a/arch/mips/Kconfig | ||||
| +++ b/arch/mips/Kconfig | ||||
| @@ -249,6 +249,7 @@ config ATH79 | ||||
|   | ||||
|  config BMIPS_GENERIC | ||||
|  	bool "Broadcom Generic BMIPS kernel" | ||||
| +	select ARCH_HAS_RESET_CONTROLLER | ||||
|  	select ARCH_HAS_SYNC_DMA_FOR_CPU_ALL | ||||
|  	select ARCH_HAS_PHYS_TO_DMA | ||||
|  	select BOOT_RAW | ||||
| @@ -0,0 +1,59 @@ | ||||
| From 10c1e714a68b45b124157aa02d80abe244a2a61a Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:34 +0200 | ||||
| Subject: [PATCH 2/9] dt-bindings: reset: add BCM6345 reset controller bindings | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Add device tree binding documentation for BCM6345 reset controller. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| Reviewed-by: Rob Herring <robh@kernel.org> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  .../bindings/reset/brcm,bcm6345-reset.yaml    | 37 +++++++++++++++++++ | ||||
|  1 file changed, 37 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.yaml | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.yaml | ||||
| @@ -0,0 +1,37 @@ | ||||
| +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||||
| +%YAML 1.2 | ||||
| +--- | ||||
| +$id: "http://devicetree.org/schemas/reset/brcm,bcm6345-reset.yaml#" | ||||
| +$schema: "http://devicetree.org/meta-schemas/core.yaml#" | ||||
| + | ||||
| +title: BCM6345 reset controller | ||||
| + | ||||
| +description: This document describes the BCM6345 reset controller. | ||||
| + | ||||
| +maintainers: | ||||
| +  - Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| + | ||||
| +properties: | ||||
| +  compatible: | ||||
| +    const: brcm,bcm6345-reset | ||||
| + | ||||
| +  reg: | ||||
| +    maxItems: 1 | ||||
| + | ||||
| +  "#reset-cells": | ||||
| +    const: 1 | ||||
| + | ||||
| +required: | ||||
| +  - compatible | ||||
| +  - reg | ||||
| +  - "#reset-cells" | ||||
| + | ||||
| +additionalProperties: false | ||||
| + | ||||
| +examples: | ||||
| +  - | | ||||
| +    reset-controller@10000010 { | ||||
| +      compatible = "brcm,bcm6345-reset"; | ||||
| +      reg = <0x10000010 0x4>; | ||||
| +      #reset-cells = <1>; | ||||
| +    }; | ||||
| @@ -0,0 +1,186 @@ | ||||
| From aac025437f14c1647dc6054b95daeebed34f6971 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:35 +0200 | ||||
| Subject: [PATCH 3/9] reset: add BCM6345 reset controller driver | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Add support for resetting blocks through the Linux reset controller | ||||
| subsystem for BCM63xx SoCs. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Reviewed-by: Florian Fainelli <F.fainelli@gmail.com> | ||||
| Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  drivers/reset/Kconfig         |   7 ++ | ||||
|  drivers/reset/Makefile        |   1 + | ||||
|  drivers/reset/reset-bcm6345.c | 135 ++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 143 insertions(+) | ||||
|  create mode 100644 drivers/reset/reset-bcm6345.c | ||||
|  | ||||
| --- a/drivers/reset/Kconfig | ||||
| +++ b/drivers/reset/Kconfig | ||||
| @@ -35,6 +35,13 @@ config RESET_AXS10X | ||||
|  	help | ||||
|  	  This enables the reset controller driver for AXS10x. | ||||
|   | ||||
| +config RESET_BCM6345 | ||||
| +	bool "BCM6345 Reset Controller" | ||||
| +	depends on BMIPS_GENERIC || COMPILE_TEST | ||||
| +	default BMIPS_GENERIC | ||||
| +	help | ||||
| +	  This enables the reset controller driver for BCM6345 SoCs. | ||||
| + | ||||
|  config RESET_BERLIN | ||||
|  	bool "Berlin Reset Driver" if COMPILE_TEST | ||||
|  	default ARCH_BERLIN | ||||
| --- a/drivers/reset/Makefile | ||||
| +++ b/drivers/reset/Makefile | ||||
| @@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ | ||||
|  obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o | ||||
|  obj-$(CONFIG_RESET_ATH79) += reset-ath79.o | ||||
|  obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o | ||||
| +obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o | ||||
|  obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o | ||||
|  obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o | ||||
|  obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/reset/reset-bcm6345.c | ||||
| @@ -0,0 +1,135 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0-or-later | ||||
| +/* | ||||
| + * BCM6345 Reset Controller Driver | ||||
| + * | ||||
| + * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/delay.h> | ||||
| +#include <linux/init.h> | ||||
| +#include <linux/io.h> | ||||
| +#include <linux/mod_devicetable.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/reset-controller.h> | ||||
| + | ||||
| +#define BCM6345_RESET_NUM		32 | ||||
| +#define BCM6345_RESET_SLEEP_MIN_US	10000 | ||||
| +#define BCM6345_RESET_SLEEP_MAX_US	20000 | ||||
| + | ||||
| +struct bcm6345_reset { | ||||
| +	struct reset_controller_dev rcdev; | ||||
| +	void __iomem *base; | ||||
| +	spinlock_t lock; | ||||
| +}; | ||||
| + | ||||
| +static inline struct bcm6345_reset * | ||||
| +to_bcm6345_reset(struct reset_controller_dev *rcdev) | ||||
| +{ | ||||
| +	return container_of(rcdev, struct bcm6345_reset, rcdev); | ||||
| +} | ||||
| + | ||||
| +static int bcm6345_reset_update(struct reset_controller_dev *rcdev, | ||||
| +				unsigned long id, bool assert) | ||||
| +{ | ||||
| +	struct bcm6345_reset *bcm6345_reset = to_bcm6345_reset(rcdev); | ||||
| +	unsigned long flags; | ||||
| +	uint32_t val; | ||||
| + | ||||
| +	spin_lock_irqsave(&bcm6345_reset->lock, flags); | ||||
| +	val = __raw_readl(bcm6345_reset->base); | ||||
| +	if (assert) | ||||
| +		val &= ~BIT(id); | ||||
| +	else | ||||
| +		val |= BIT(id); | ||||
| +	__raw_writel(val, bcm6345_reset->base); | ||||
| +	spin_unlock_irqrestore(&bcm6345_reset->lock, flags); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6345_reset_assert(struct reset_controller_dev *rcdev, | ||||
| +				unsigned long id) | ||||
| +{ | ||||
| +	return bcm6345_reset_update(rcdev, id, true); | ||||
| +} | ||||
| + | ||||
| +static int bcm6345_reset_deassert(struct reset_controller_dev *rcdev, | ||||
| +				  unsigned long id) | ||||
| +{ | ||||
| +	return bcm6345_reset_update(rcdev, id, false); | ||||
| +} | ||||
| + | ||||
| +static int bcm6345_reset_reset(struct reset_controller_dev *rcdev, | ||||
| +			       unsigned long id) | ||||
| +{ | ||||
| +	bcm6345_reset_update(rcdev, id, true); | ||||
| +	usleep_range(BCM6345_RESET_SLEEP_MIN_US, | ||||
| +		     BCM6345_RESET_SLEEP_MAX_US); | ||||
| + | ||||
| +	bcm6345_reset_update(rcdev, id, false); | ||||
| +	/* | ||||
| +	 * Ensure component is taken out reset state by sleeping also after | ||||
| +	 * deasserting the reset. Otherwise, the component may not be ready | ||||
| +	 * for operation. | ||||
| +	 */ | ||||
| +	usleep_range(BCM6345_RESET_SLEEP_MIN_US, | ||||
| +		     BCM6345_RESET_SLEEP_MAX_US); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6345_reset_status(struct reset_controller_dev *rcdev, | ||||
| +				unsigned long id) | ||||
| +{ | ||||
| +	struct bcm6345_reset *bcm6345_reset = to_bcm6345_reset(rcdev); | ||||
| + | ||||
| +	return !(__raw_readl(bcm6345_reset->base) & BIT(id)); | ||||
| +} | ||||
| + | ||||
| +static struct reset_control_ops bcm6345_reset_ops = { | ||||
| +	.assert = bcm6345_reset_assert, | ||||
| +	.deassert = bcm6345_reset_deassert, | ||||
| +	.reset = bcm6345_reset_reset, | ||||
| +	.status = bcm6345_reset_status, | ||||
| +}; | ||||
| + | ||||
| +static int bcm6345_reset_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct bcm6345_reset *bcm6345_reset; | ||||
| + | ||||
| +	bcm6345_reset = devm_kzalloc(&pdev->dev, | ||||
| +				     sizeof(*bcm6345_reset), GFP_KERNEL); | ||||
| +	if (!bcm6345_reset) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, bcm6345_reset); | ||||
| + | ||||
| +	bcm6345_reset->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(bcm6345_reset->base)) | ||||
| +		return PTR_ERR(bcm6345_reset->base); | ||||
| + | ||||
| +	spin_lock_init(&bcm6345_reset->lock); | ||||
| +	bcm6345_reset->rcdev.ops = &bcm6345_reset_ops; | ||||
| +	bcm6345_reset->rcdev.owner = THIS_MODULE; | ||||
| +	bcm6345_reset->rcdev.of_node = pdev->dev.of_node; | ||||
| +	bcm6345_reset->rcdev.of_reset_n_cells = 1; | ||||
| +	bcm6345_reset->rcdev.nr_resets = BCM6345_RESET_NUM; | ||||
| + | ||||
| +	return devm_reset_controller_register(&pdev->dev, | ||||
| +					      &bcm6345_reset->rcdev); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id bcm6345_reset_of_match[] = { | ||||
| +	{ .compatible = "brcm,bcm6345-reset" }, | ||||
| +	{ /* sentinel */ }, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_driver bcm6345_reset_driver = { | ||||
| +	.probe = bcm6345_reset_probe, | ||||
| +	.driver	= { | ||||
| +		.name = "bcm6345-reset", | ||||
| +		.of_match_table = bcm6345_reset_of_match, | ||||
| +		.suppress_bind_attrs = true, | ||||
| +	}, | ||||
| +}; | ||||
| +builtin_platform_driver(bcm6345_reset_driver); | ||||
| @@ -0,0 +1,56 @@ | ||||
| From 83f865d7e32e40b4903b1f83537c63fc5cdf1eb8 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:36 +0200 | ||||
| Subject: [PATCH 4/9] mips: bmips: dts: add BCM6328 reset controller support | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| BCM6328 SoCs have a reset controller for certain components. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Acked-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| Reviewed-by: Rob Herring <robh@kernel.org> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  arch/mips/boot/dts/brcm/bcm6328.dtsi      |  6 ++++++ | ||||
|  include/dt-bindings/reset/bcm6328-reset.h | 18 ++++++++++++++++++ | ||||
|  2 files changed, 24 insertions(+) | ||||
|  create mode 100644 include/dt-bindings/reset/bcm6328-reset.h | ||||
|  | ||||
| --- a/arch/mips/boot/dts/brcm/bcm6328.dtsi | ||||
| +++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi | ||||
| @@ -57,6 +57,12 @@ | ||||
|  			#clock-cells = <1>; | ||||
|  		}; | ||||
|   | ||||
| +		periph_rst: reset-controller@10000010 { | ||||
| +			compatible = "brcm,bcm6345-reset"; | ||||
| +			reg = <0x10000010 0x4>; | ||||
| +			#reset-cells = <1>; | ||||
| +		}; | ||||
| + | ||||
|  		periph_intc: interrupt-controller@10000020 { | ||||
|  			compatible = "brcm,bcm6345-l1-intc"; | ||||
|  			reg = <0x10000020 0x10>, | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/reset/bcm6328-reset.h | ||||
| @@ -0,0 +1,18 @@ | ||||
| +/* SPDX-License-Identifier: GPL-2.0+ */ | ||||
| + | ||||
| +#ifndef __DT_BINDINGS_RESET_BCM6328_H | ||||
| +#define __DT_BINDINGS_RESET_BCM6328_H | ||||
| + | ||||
| +#define BCM6328_RST_SPI		0 | ||||
| +#define BCM6328_RST_EPHY	1 | ||||
| +#define BCM6328_RST_SAR		2 | ||||
| +#define BCM6328_RST_ENETSW	3 | ||||
| +#define BCM6328_RST_USBS	4 | ||||
| +#define BCM6328_RST_USBH	5 | ||||
| +#define BCM6328_RST_PCM		6 | ||||
| +#define BCM6328_RST_PCIE_CORE	7 | ||||
| +#define BCM6328_RST_PCIE	8 | ||||
| +#define BCM6328_RST_PCIE_EXT	9 | ||||
| +#define BCM6328_RST_PCIE_HARD	10 | ||||
| + | ||||
| +#endif /* __DT_BINDINGS_RESET_BCM6328_H */ | ||||
| @@ -0,0 +1,53 @@ | ||||
| From 8079cfba4c7b8cae900c27104b4512fa5ed1f021 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:37 +0200 | ||||
| Subject: [PATCH 5/9] mips: bmips: dts: add BCM6358 reset controller support | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| BCM6358 SoCs have a reset controller for certain components. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Acked-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| Reviewed-by: Rob Herring <robh@kernel.org> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  arch/mips/boot/dts/brcm/bcm6358.dtsi      |  6 ++++++ | ||||
|  include/dt-bindings/reset/bcm6358-reset.h | 15 +++++++++++++++ | ||||
|  2 files changed, 21 insertions(+) | ||||
|  create mode 100644 include/dt-bindings/reset/bcm6358-reset.h | ||||
|  | ||||
| --- a/arch/mips/boot/dts/brcm/bcm6358.dtsi | ||||
| +++ b/arch/mips/boot/dts/brcm/bcm6358.dtsi | ||||
| @@ -82,6 +82,12 @@ | ||||
|  			interrupts = <2>, <3>; | ||||
|  		}; | ||||
|   | ||||
| +		periph_rst: reset-controller@fffe0034 { | ||||
| +			compatible = "brcm,bcm6345-reset"; | ||||
| +			reg = <0xfffe0034 0x4>; | ||||
| +			#reset-cells = <1>; | ||||
| +		}; | ||||
| + | ||||
|  		leds0: led-controller@fffe00d0 { | ||||
|  			#address-cells = <1>; | ||||
|  			#size-cells = <0>; | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/reset/bcm6358-reset.h | ||||
| @@ -0,0 +1,15 @@ | ||||
| +/* SPDX-License-Identifier: GPL-2.0+ */ | ||||
| + | ||||
| +#ifndef __DT_BINDINGS_RESET_BCM6358_H | ||||
| +#define __DT_BINDINGS_RESET_BCM6358_H | ||||
| + | ||||
| +#define BCM6358_RST_SPI		0 | ||||
| +#define BCM6358_RST_ENET	2 | ||||
| +#define BCM6358_RST_MPI		3 | ||||
| +#define BCM6358_RST_EPHY	6 | ||||
| +#define BCM6358_RST_SAR		7 | ||||
| +#define BCM6358_RST_USBH	12 | ||||
| +#define BCM6358_RST_PCM		13 | ||||
| +#define BCM6358_RST_ADSL	14 | ||||
| + | ||||
| +#endif /* __DT_BINDINGS_RESET_BCM6358_H */ | ||||
| @@ -0,0 +1,60 @@ | ||||
| From 226383600be58dcf2e070e4ac8a371640024fe54 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:38 +0200 | ||||
| Subject: [PATCH 6/9] mips: bmips: dts: add BCM6362 reset controller support | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| BCM6362 SoCs have a reset controller for certain components. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Acked-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| Reviewed-by: Rob Herring <robh@kernel.org> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  arch/mips/boot/dts/brcm/bcm6362.dtsi      |  6 ++++++ | ||||
|  include/dt-bindings/reset/bcm6362-reset.h | 22 ++++++++++++++++++++++ | ||||
|  2 files changed, 28 insertions(+) | ||||
|  create mode 100644 include/dt-bindings/reset/bcm6362-reset.h | ||||
|  | ||||
| --- a/arch/mips/boot/dts/brcm/bcm6362.dtsi | ||||
| +++ b/arch/mips/boot/dts/brcm/bcm6362.dtsi | ||||
| @@ -70,6 +70,12 @@ | ||||
|  			mask = <0x1>; | ||||
|  		}; | ||||
|   | ||||
| +		periph_rst: reset-controller@10000010 { | ||||
| +			compatible = "brcm,bcm6345-reset"; | ||||
| +			reg = <0x10000010 0x4>; | ||||
| +			#reset-cells = <1>; | ||||
| +		}; | ||||
| + | ||||
|  		periph_intc: interrupt-controller@10000020 { | ||||
|  			compatible = "brcm,bcm6345-l1-intc"; | ||||
|  			reg = <0x10000020 0x10>, | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/reset/bcm6362-reset.h | ||||
| @@ -0,0 +1,22 @@ | ||||
| +/* SPDX-License-Identifier: GPL-2.0+ */ | ||||
| + | ||||
| +#ifndef __DT_BINDINGS_RESET_BCM6362_H | ||||
| +#define __DT_BINDINGS_RESET_BCM6362_H | ||||
| + | ||||
| +#define BCM6362_RST_SPI		0 | ||||
| +#define BCM6362_RST_IPSEC	1 | ||||
| +#define BCM6362_RST_EPHY	2 | ||||
| +#define BCM6362_RST_SAR		3 | ||||
| +#define BCM6362_RST_ENETSW	4 | ||||
| +#define BCM6362_RST_USBD	5 | ||||
| +#define BCM6362_RST_USBH	6 | ||||
| +#define BCM6362_RST_PCM		7 | ||||
| +#define BCM6362_RST_PCIE_CORE	8 | ||||
| +#define BCM6362_RST_PCIE	9 | ||||
| +#define BCM6362_RST_PCIE_EXT	10 | ||||
| +#define BCM6362_RST_WLAN_SHIM	11 | ||||
| +#define BCM6362_RST_DDR_PHY	12 | ||||
| +#define BCM6362_RST_FAP		13 | ||||
| +#define BCM6362_RST_WLAN_UBUS	14 | ||||
| + | ||||
| +#endif /* __DT_BINDINGS_RESET_BCM6362_H */ | ||||
| @@ -0,0 +1,54 @@ | ||||
| From 7acf84e87857721d66a1ba800c2c50669089f43d Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:39 +0200 | ||||
| Subject: [PATCH 7/9] mips: bmips: dts: add BCM6368 reset controller support | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| BCM6368 SoCs have a reset controller for certain components. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Acked-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| Reviewed-by: Rob Herring <robh@kernel.org> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  arch/mips/boot/dts/brcm/bcm6368.dtsi      |  6 ++++++ | ||||
|  include/dt-bindings/reset/bcm6368-reset.h | 16 ++++++++++++++++ | ||||
|  2 files changed, 22 insertions(+) | ||||
|  create mode 100644 include/dt-bindings/reset/bcm6368-reset.h | ||||
|  | ||||
| --- a/arch/mips/boot/dts/brcm/bcm6368.dtsi | ||||
| +++ b/arch/mips/boot/dts/brcm/bcm6368.dtsi | ||||
| @@ -70,6 +70,12 @@ | ||||
|  			mask = <0x1>; | ||||
|  		}; | ||||
|   | ||||
| +		periph_rst: reset-controller@10000010 { | ||||
| +			compatible = "brcm,bcm6345-reset"; | ||||
| +			reg = <0x10000010 0x4>; | ||||
| +			#reset-cells = <1>; | ||||
| +		}; | ||||
| + | ||||
|  		periph_intc: interrupt-controller@10000020 { | ||||
|  			compatible = "brcm,bcm6345-l1-intc"; | ||||
|  			reg = <0x10000020 0x10>, | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/reset/bcm6368-reset.h | ||||
| @@ -0,0 +1,16 @@ | ||||
| +/* SPDX-License-Identifier: GPL-2.0+ */ | ||||
| + | ||||
| +#ifndef __DT_BINDINGS_RESET_BCM6368_H | ||||
| +#define __DT_BINDINGS_RESET_BCM6368_H | ||||
| + | ||||
| +#define BCM6368_RST_SPI		0 | ||||
| +#define BCM6368_RST_MPI		3 | ||||
| +#define BCM6368_RST_IPSEC	4 | ||||
| +#define BCM6368_RST_EPHY	6 | ||||
| +#define BCM6368_RST_SAR		7 | ||||
| +#define BCM6368_RST_SWITCH	10 | ||||
| +#define BCM6368_RST_USBD	11 | ||||
| +#define BCM6368_RST_USBH	12 | ||||
| +#define BCM6368_RST_PCM		13 | ||||
| + | ||||
| +#endif /* __DT_BINDINGS_RESET_BCM6368_H */ | ||||
| @@ -0,0 +1,64 @@ | ||||
| From b7aa228813bdf014d6ad173ca3abfced30f1ed37 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:40 +0200 | ||||
| Subject: [PATCH 8/9] mips: bmips: dts: add BCM63268 reset controller support | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| BCM63268 SoCs have a reset controller for certain components. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Acked-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| Reviewed-by: Rob Herring <robh@kernel.org> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  arch/mips/boot/dts/brcm/bcm63268.dtsi      |  6 +++++ | ||||
|  include/dt-bindings/reset/bcm63268-reset.h | 26 ++++++++++++++++++++++ | ||||
|  2 files changed, 32 insertions(+) | ||||
|  create mode 100644 include/dt-bindings/reset/bcm63268-reset.h | ||||
|  | ||||
| --- a/arch/mips/boot/dts/brcm/bcm63268.dtsi | ||||
| +++ b/arch/mips/boot/dts/brcm/bcm63268.dtsi | ||||
| @@ -70,6 +70,12 @@ | ||||
|  			mask = <0x1>; | ||||
|  		}; | ||||
|   | ||||
| +		periph_rst: reset-controller@10000010 { | ||||
| +			compatible = "brcm,bcm6345-reset"; | ||||
| +			reg = <0x10000010 0x4>; | ||||
| +			#reset-cells = <1>; | ||||
| +		}; | ||||
| + | ||||
|  		periph_intc: interrupt-controller@10000020 { | ||||
|  			compatible = "brcm,bcm6345-l1-intc"; | ||||
|  			reg = <0x10000020 0x20>, | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/reset/bcm63268-reset.h | ||||
| @@ -0,0 +1,26 @@ | ||||
| +/* SPDX-License-Identifier: GPL-2.0+ */ | ||||
| + | ||||
| +#ifndef __DT_BINDINGS_RESET_BCM63268_H | ||||
| +#define __DT_BINDINGS_RESET_BCM63268_H | ||||
| + | ||||
| +#define BCM63268_RST_SPI	0 | ||||
| +#define BCM63268_RST_IPSEC	1 | ||||
| +#define BCM63268_RST_EPHY	2 | ||||
| +#define BCM63268_RST_SAR	3 | ||||
| +#define BCM63268_RST_ENETSW	4 | ||||
| +#define BCM63268_RST_USBS	5 | ||||
| +#define BCM63268_RST_USBH	6 | ||||
| +#define BCM63268_RST_PCM	7 | ||||
| +#define BCM63268_RST_PCIE_CORE	8 | ||||
| +#define BCM63268_RST_PCIE	9 | ||||
| +#define BCM63268_RST_PCIE_EXT	10 | ||||
| +#define BCM63268_RST_WLAN_SHIM	11 | ||||
| +#define BCM63268_RST_DDR_PHY	12 | ||||
| +#define BCM63268_RST_FAP0	13 | ||||
| +#define BCM63268_RST_WLAN_UBUS	14 | ||||
| +#define BCM63268_RST_DECT	15 | ||||
| +#define BCM63268_RST_FAP1	16 | ||||
| +#define BCM63268_RST_PCIE_HARD	17 | ||||
| +#define BCM63268_RST_GPHY	18 | ||||
| + | ||||
| +#endif /* __DT_BINDINGS_RESET_BCM63268_H */ | ||||
| @@ -0,0 +1,42 @@ | ||||
| From 8c9e8b0a28225c46f2cca0a09a3a111bb043e874 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Wed, 17 Jun 2020 12:50:41 +0200 | ||||
| Subject: [PATCH 9/9] mips: bmips: add BCM6318 reset controller definitions | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| BCM6318 SoCs have a reset controller for certain components. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| Acked-by: Florian Fainelli <F.fainelli@gmail.com> | ||||
| Reviewed-by: Rob Herring <robh@kernel.org> | ||||
| Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||||
| --- | ||||
|  include/dt-bindings/reset/bcm6318-reset.h | 20 ++++++++++++++++++++ | ||||
|  1 file changed, 20 insertions(+) | ||||
|  create mode 100644 include/dt-bindings/reset/bcm6318-reset.h | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/reset/bcm6318-reset.h | ||||
| @@ -0,0 +1,20 @@ | ||||
| +/* SPDX-License-Identifier: GPL-2.0+ */ | ||||
| + | ||||
| +#ifndef __DT_BINDINGS_RESET_BCM6318_H | ||||
| +#define __DT_BINDINGS_RESET_BCM6318_H | ||||
| + | ||||
| +#define BCM6318_RST_SPI		0 | ||||
| +#define BCM6318_RST_EPHY	1 | ||||
| +#define BCM6318_RST_SAR		2 | ||||
| +#define BCM6318_RST_ENETSW	3 | ||||
| +#define BCM6318_RST_USBD	4 | ||||
| +#define BCM6318_RST_USBH	5 | ||||
| +#define BCM6318_RST_PCIE_CORE	6 | ||||
| +#define BCM6318_RST_PCIE	7 | ||||
| +#define BCM6318_RST_PCIE_EXT	8 | ||||
| +#define BCM6318_RST_PCIE_HARD	9 | ||||
| +#define BCM6318_RST_ADSL	10 | ||||
| +#define BCM6318_RST_PHYMIPS	11 | ||||
| +#define BCM6318_RST_HOSTMIPS	12 | ||||
| + | ||||
| +#endif /* __DT_BINDINGS_RESET_BCM6318_H */ | ||||
| @@ -0,0 +1,392 @@ | ||||
| From cf908990d4a8ccdb73ee4484aa8cadad379ca314 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jogo@openwrt.org> | ||||
| Date: Sun, 30 Nov 2014 14:54:27 +0100 | ||||
| Subject: [PATCH 2/5] irqchip: add support for bcm6345-style external | ||||
|  interrupt controller | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jogo@openwrt.org> | ||||
| --- | ||||
|  .../interrupt-controller/brcm,bcm6345-ext-intc.txt |   29 ++ | ||||
|  drivers/irqchip/Kconfig                            |    4 + | ||||
|  drivers/irqchip/Makefile                           |    1 + | ||||
|  drivers/irqchip/irq-bcm6345-ext.c                  |  287 ++++++++++++++++++++ | ||||
|  include/linux/irqchip/irq-bcm6345-ext.h            |   14 + | ||||
|  5 files changed, 335 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt | ||||
|  create mode 100644 drivers/irqchip/irq-bcm6345-ext.c | ||||
|  create mode 100644 include/linux/irqchip/irq-bcm6345-ext.h | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt | ||||
| @@ -0,0 +1,29 @@ | ||||
| +Broadcom BCM6345-style external interrupt controller | ||||
| + | ||||
| +Required properties: | ||||
| + | ||||
| +- compatible: Should be "brcm,bcm6345-ext-intc" or "brcm,bcm6318-ext-intc". | ||||
| +- reg: Specifies the base physical addresses and size of the registers. | ||||
| +- interrupt-controller: identifies the node as an interrupt controller. | ||||
| +- #interrupt-cells: Specifies the number of cells needed to encode an interrupt | ||||
| +  source, Should be 2. | ||||
| +- interrupt-parent: Specifies the phandle to the parent interrupt controller | ||||
| +  this one is cascaded from. | ||||
| +- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller | ||||
| +  node, valid values depend on the type of parent interrupt controller. | ||||
| + | ||||
| +Optional properties: | ||||
| + | ||||
| +- brcm,field-width: Size of each field (mask, clear, sense, ...) in bits in the | ||||
| +  register. Defaults to 4. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +ext_intc: interrupt-controller@10000018 { | ||||
| +	compatible = "brcm,bcm6345-ext-intc"; | ||||
| +	interrupt-parent = <&periph_intc>; | ||||
| +	#interrupt-cells = <2>; | ||||
| +	reg = <0x10000018 0x4>; | ||||
| +	interrupt-controller; | ||||
| +	interrupts = <24>, <25>, <26>, <27>; | ||||
| +}; | ||||
| --- a/drivers/irqchip/Kconfig | ||||
| +++ b/drivers/irqchip/Kconfig | ||||
| @@ -113,6 +113,10 @@ config I8259 | ||||
|  	bool | ||||
|  	select IRQ_DOMAIN | ||||
|   | ||||
| +config BCM6345_EXT_IRQ | ||||
| +	bool "BCM6345 External IRQ Controller" | ||||
| +	select IRQ_DOMAIN | ||||
| + | ||||
|  config BCM6345_L1_IRQ | ||||
|  	bool | ||||
|  	select GENERIC_IRQ_CHIP | ||||
| --- a/drivers/irqchip/Makefile | ||||
| +++ b/drivers/irqchip/Makefile | ||||
| @@ -63,6 +63,7 @@ obj-$(CONFIG_XTENSA_MX)			+= irq-xtensa- | ||||
|  obj-$(CONFIG_XILINX_INTC)		+= irq-xilinx-intc.o | ||||
|  obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o | ||||
|  obj-$(CONFIG_SOC_VF610)			+= irq-vf610-mscm-ir.o | ||||
| +obj-$(CONFIG_BCM6345_EXT_IRQ)		+= irq-bcm6345-ext.o | ||||
|  obj-$(CONFIG_BCM6345_L1_IRQ)		+= irq-bcm6345-l1.o | ||||
|  obj-$(CONFIG_BCM7038_L1_IRQ)		+= irq-bcm7038-l1.o | ||||
|  obj-$(CONFIG_BCM7120_L2_IRQ)		+= irq-bcm7120-l2.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/irqchip/irq-bcm6345-ext.c | ||||
| @@ -0,0 +1,299 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/ioport.h> | ||||
| +#include <linux/irq.h> | ||||
| +#include <linux/irqchip.h> | ||||
| +#include <linux/irqchip/chained_irq.h> | ||||
| +#include <linux/irqchip/irq-bcm6345-ext.h> | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_irq.h> | ||||
| +#include <linux/of_address.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/spinlock.h> | ||||
| + | ||||
| +#ifdef CONFIG_BCM63XX | ||||
| +#include <asm/mach-bcm63xx/bcm63xx_irq.h> | ||||
| + | ||||
| +#define VIRQ_BASE		IRQ_EXTERNAL_BASE | ||||
| +#else | ||||
| +#define VIRQ_BASE		0 | ||||
| +#endif | ||||
| + | ||||
| +#define MAX_IRQS		4 | ||||
| + | ||||
| +#define EXTIRQ_CFG_SENSE	0 | ||||
| +#define EXTIRQ_CFG_STAT		1 | ||||
| +#define EXTIRQ_CFG_CLEAR	2 | ||||
| +#define EXTIRQ_CFG_MASK		3 | ||||
| +#define EXTIRQ_CFG_BOTHEDGE	4 | ||||
| +#define EXTIRQ_CFG_LEVELSENSE	5 | ||||
| + | ||||
| +struct intc_data { | ||||
| +	struct irq_chip chip; | ||||
| +	struct irq_domain *domain; | ||||
| +	raw_spinlock_t lock; | ||||
| + | ||||
| +	int parent_irq[MAX_IRQS]; | ||||
| +	void __iomem *reg; | ||||
| +	int shift; | ||||
| +	unsigned int toggle_clear_on_ack:1; | ||||
| +}; | ||||
| + | ||||
| +static void bcm6345_ext_intc_irq_handle(struct irq_desc *desc) | ||||
| +{ | ||||
| +	struct intc_data *data = irq_desc_get_handler_data(desc); | ||||
| +	struct irq_chip *chip = irq_desc_get_chip(desc); | ||||
| +	unsigned int irq = irq_desc_get_irq(desc); | ||||
| +	unsigned int idx; | ||||
| + | ||||
| +	chained_irq_enter(chip, desc); | ||||
| + | ||||
| +	for (idx = 0; idx < MAX_IRQS; idx++) { | ||||
| +		if (data->parent_irq[idx] != irq) | ||||
| +			continue; | ||||
| + | ||||
| +		generic_handle_irq(irq_find_mapping(data->domain, idx)); | ||||
| +	} | ||||
| + | ||||
| +	chained_irq_exit(chip, desc); | ||||
| +} | ||||
| + | ||||
| +static void bcm6345_ext_intc_irq_ack(struct irq_data *data) | ||||
| +{ | ||||
| +	struct intc_data *priv = data->domain->host_data; | ||||
| +	irq_hw_number_t hwirq = irqd_to_hwirq(data); | ||||
| +	u32 reg; | ||||
| + | ||||
| +	raw_spin_lock(&priv->lock); | ||||
| +	reg = __raw_readl(priv->reg); | ||||
| +	__raw_writel(reg | (1 << (hwirq + EXTIRQ_CFG_CLEAR * priv->shift)), | ||||
| +		     priv->reg); | ||||
| +	if (priv->toggle_clear_on_ack) | ||||
| +		__raw_writel(reg, priv->reg); | ||||
| +	raw_spin_unlock(&priv->lock); | ||||
| +} | ||||
| + | ||||
| +static void bcm6345_ext_intc_irq_mask(struct irq_data *data) | ||||
| +{ | ||||
| +	struct intc_data *priv = data->domain->host_data; | ||||
| +	irq_hw_number_t hwirq = irqd_to_hwirq(data); | ||||
| +	u32 reg; | ||||
| + | ||||
| +	raw_spin_lock(&priv->lock); | ||||
| +	reg = __raw_readl(priv->reg); | ||||
| +	reg &= ~(1 << (hwirq + EXTIRQ_CFG_MASK * priv->shift)); | ||||
| +	__raw_writel(reg, priv->reg); | ||||
| +	raw_spin_unlock(&priv->lock); | ||||
| +} | ||||
| + | ||||
| +static void bcm6345_ext_intc_irq_unmask(struct irq_data *data) | ||||
| +{ | ||||
| +	struct intc_data *priv = data->domain->host_data; | ||||
| +	irq_hw_number_t hwirq = irqd_to_hwirq(data); | ||||
| +	u32 reg; | ||||
| + | ||||
| +	raw_spin_lock(&priv->lock); | ||||
| +	reg = __raw_readl(priv->reg); | ||||
| +	reg |= 1 << (hwirq + EXTIRQ_CFG_MASK * priv->shift); | ||||
| +	__raw_writel(reg, priv->reg); | ||||
| +	raw_spin_unlock(&priv->lock); | ||||
| +} | ||||
| + | ||||
| +static int bcm6345_ext_intc_set_type(struct irq_data *data, | ||||
| +				     unsigned int flow_type) | ||||
| +{ | ||||
| +	struct intc_data *priv = data->domain->host_data; | ||||
| +	irq_hw_number_t hwirq = irqd_to_hwirq(data); | ||||
| +	bool levelsense = 0, sense = 0, bothedge = 0; | ||||
| +	u32 reg; | ||||
| + | ||||
| +	flow_type &= IRQ_TYPE_SENSE_MASK; | ||||
| + | ||||
| +	if (flow_type == IRQ_TYPE_NONE) | ||||
| +		flow_type = IRQ_TYPE_LEVEL_LOW; | ||||
| + | ||||
| +	switch (flow_type) { | ||||
| +	case IRQ_TYPE_EDGE_BOTH: | ||||
| +		bothedge = 1; | ||||
| +		break; | ||||
| + | ||||
| +	case IRQ_TYPE_EDGE_RISING: | ||||
| +		sense = 1; | ||||
| +		break; | ||||
| + | ||||
| +	case IRQ_TYPE_EDGE_FALLING: | ||||
| +		break; | ||||
| + | ||||
| +	case IRQ_TYPE_LEVEL_HIGH: | ||||
| +		levelsense = 1; | ||||
| +		sense = 1; | ||||
| +		break; | ||||
| + | ||||
| +	case IRQ_TYPE_LEVEL_LOW: | ||||
| +		levelsense = 1; | ||||
| +		break; | ||||
| + | ||||
| +	default: | ||||
| +		pr_err("bogus flow type combination given!\n"); | ||||
| +		return -EINVAL; | ||||
| +	} | ||||
| + | ||||
| +	raw_spin_lock(&priv->lock); | ||||
| +	reg = __raw_readl(priv->reg); | ||||
| + | ||||
| +	if (levelsense) | ||||
| +		reg |= 1 << (hwirq + EXTIRQ_CFG_LEVELSENSE * priv->shift); | ||||
| +	else | ||||
| +		reg &= ~(1 << (hwirq + EXTIRQ_CFG_LEVELSENSE * priv->shift)); | ||||
| +	if (sense) | ||||
| +		reg |= 1 << (hwirq + EXTIRQ_CFG_SENSE * priv->shift); | ||||
| +	else | ||||
| +		reg &= ~(1 << (hwirq + EXTIRQ_CFG_SENSE * priv->shift)); | ||||
| +	if (bothedge) | ||||
| +		reg |= 1 << (hwirq + EXTIRQ_CFG_BOTHEDGE * priv->shift); | ||||
| +	else | ||||
| +		reg &= ~(1 << (hwirq + EXTIRQ_CFG_BOTHEDGE * priv->shift)); | ||||
| + | ||||
| +	__raw_writel(reg, priv->reg); | ||||
| +	raw_spin_unlock(&priv->lock); | ||||
| + | ||||
| +	irqd_set_trigger_type(data, flow_type); | ||||
| +	if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||||
| +		irq_set_handler_locked(data, handle_level_irq); | ||||
| +	else | ||||
| +		irq_set_handler_locked(data, handle_edge_irq); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6345_ext_intc_map(struct irq_domain *d, unsigned int irq, | ||||
| +				irq_hw_number_t hw) | ||||
| +{ | ||||
| +	struct intc_data *priv = d->host_data; | ||||
| + | ||||
| +	irq_set_chip_and_handler(irq, &priv->chip, handle_level_irq); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct irq_domain_ops bcm6345_ext_domain_ops = { | ||||
| +	.xlate = irq_domain_xlate_twocell, | ||||
| +	.map = bcm6345_ext_intc_map, | ||||
| +}; | ||||
| + | ||||
| +static int __init __bcm6345_ext_intc_init(struct device_node *node, | ||||
| +					  int num_irqs, int *irqs, | ||||
| +					  void __iomem *reg, int shift, | ||||
| +					  bool toggle_clear_on_ack) | ||||
| +{ | ||||
| +	struct intc_data *data; | ||||
| +	unsigned int i; | ||||
| +	int start = VIRQ_BASE; | ||||
| + | ||||
| +	data = kzalloc(sizeof(*data), GFP_KERNEL); | ||||
| +	if (!data) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	raw_spin_lock_init(&data->lock); | ||||
| + | ||||
| +	for (i = 0; i < num_irqs; i++) { | ||||
| +		data->parent_irq[i] = irqs[i]; | ||||
| + | ||||
| +		irq_set_handler_data(irqs[i], data); | ||||
| +		irq_set_chained_handler(irqs[i], bcm6345_ext_intc_irq_handle); | ||||
| +	} | ||||
| + | ||||
| +	data->reg = reg; | ||||
| +	data->shift = shift; | ||||
| +	data->toggle_clear_on_ack = toggle_clear_on_ack; | ||||
| + | ||||
| +	data->chip.name = "bcm6345-ext-intc"; | ||||
| +	data->chip.irq_ack = bcm6345_ext_intc_irq_ack; | ||||
| +	data->chip.irq_mask = bcm6345_ext_intc_irq_mask; | ||||
| +	data->chip.irq_unmask = bcm6345_ext_intc_irq_unmask; | ||||
| +	data->chip.irq_set_type = bcm6345_ext_intc_set_type; | ||||
| + | ||||
| +	/* | ||||
| +	 * If we have less than 4 irqs, this is the second controller on | ||||
| +	 * bcm63xx. So increase the VIRQ start to not overlap with the first | ||||
| +	 * one, but only do so if we actually use a non-zero start. | ||||
| +	 * | ||||
| +	 * This can be removed when bcm63xx has no legacy users anymore. | ||||
| +	 */ | ||||
| +	if (start && num_irqs < 4) | ||||
| +		start += 4; | ||||
| + | ||||
| +	data->domain = irq_domain_add_simple(node, num_irqs, start, | ||||
| +					     &bcm6345_ext_domain_ops, data); | ||||
| +	if (!data->domain) { | ||||
| +		kfree(data); | ||||
| +		return -ENOMEM; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +void __init bcm6345_ext_intc_init(int num_irqs, int *irqs, void __iomem *reg, | ||||
| +				  int shift) | ||||
| +{ | ||||
| +	__bcm6345_ext_intc_init(NULL, num_irqs, irqs, reg, shift, false); | ||||
| +} | ||||
| + | ||||
| +#ifdef CONFIG_OF | ||||
| +static int __init bcm6345_ext_intc_of_init(struct device_node *node, | ||||
| +					   struct device_node *parent) | ||||
| +{ | ||||
| +	int num_irqs, ret = -EINVAL; | ||||
| +	unsigned i; | ||||
| +	void __iomem *base; | ||||
| +	int irqs[MAX_IRQS] = { 0 }; | ||||
| +	u32 shift; | ||||
| +	bool toggle_clear_on_ack = false; | ||||
| + | ||||
| +	num_irqs = of_irq_count(node); | ||||
| + | ||||
| +	if (!num_irqs || num_irqs > MAX_IRQS) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	if (of_property_read_u32(node, "brcm,field-width", &shift)) | ||||
| +		shift = 4; | ||||
| + | ||||
| +	/* on BCM6318 setting CLEAR seems to continuously mask interrupts */ | ||||
| +	if (of_device_is_compatible(node, "brcm,bcm6318-ext-intc")) | ||||
| +		toggle_clear_on_ack = true; | ||||
| + | ||||
| +	for (i = 0; i < num_irqs; i++) { | ||||
| +		irqs[i] = irq_of_parse_and_map(node, i); | ||||
| +		if (!irqs[i]) | ||||
| +			return -ENOMEM; | ||||
| +	} | ||||
| + | ||||
| +	base = of_iomap(node, 0); | ||||
| +	if (!base) | ||||
| +		return -ENXIO; | ||||
| + | ||||
| +	ret = __bcm6345_ext_intc_init(node, num_irqs, irqs, base, shift, | ||||
| +				      toggle_clear_on_ack); | ||||
| +	if (!ret) | ||||
| +		return 0; | ||||
| + | ||||
| +	iounmap(base); | ||||
| + | ||||
| +	for (i = 0; i < num_irqs; i++) | ||||
| +		irq_dispose_mapping(irqs[i]); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +IRQCHIP_DECLARE(bcm6318_ext_intc, "brcm,bcm6318-ext-intc", | ||||
| +		bcm6345_ext_intc_of_init); | ||||
| +IRQCHIP_DECLARE(bcm6345_ext_intc, "brcm,bcm6345-ext-intc", | ||||
| +		bcm6345_ext_intc_of_init); | ||||
| +#endif | ||||
| --- /dev/null | ||||
| +++ b/include/linux/irqchip/irq-bcm6345-ext.h | ||||
| @@ -0,0 +1,14 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
| + */ | ||||
| + | ||||
| +#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H | ||||
| +#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H | ||||
| + | ||||
| +void bcm6345_ext_intc_init(int n_irqs, int *irqs, void __iomem *reg, int shift); | ||||
| + | ||||
| +#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H */ | ||||
| @@ -0,0 +1,8 @@ | ||||
| --- a/arch/mips/bmips/setup.c | ||||
| +++ b/arch/mips/bmips/setup.c | ||||
| @@ -201,4 +201,4 @@ static int __init plat_dev_init(void) | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| -device_initcall(plat_dev_init); | ||||
| +arch_initcall(plat_dev_init); | ||||
| @@ -0,0 +1,11 @@ | ||||
| --- a/drivers/tty/serial/bcm63xx_uart.c | ||||
| +++ b/drivers/tty/serial/bcm63xx_uart.c | ||||
| @@ -916,7 +916,7 @@ static void __exit bcm_uart_exit(void) | ||||
|  	uart_unregister_driver(&bcm_uart_driver); | ||||
|  } | ||||
|   | ||||
| -module_init(bcm_uart_init); | ||||
| +subsys_initcall(bcm_uart_init); | ||||
|  module_exit(bcm_uart_exit); | ||||
|   | ||||
|  MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>"); | ||||
| @@ -0,0 +1,11 @@ | ||||
| --- a/drivers/irqchip/irq-bcm6345-l1.c | ||||
| +++ b/drivers/irqchip/irq-bcm6345-l1.c | ||||
| @@ -121,7 +121,7 @@ static void bcm6345_l1_irq_handle(struct | ||||
|  	unsigned int idx; | ||||
|   | ||||
|  #ifdef CONFIG_SMP | ||||
| -	cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; | ||||
| +	cpu = intc->cpus[smp_processor_id()]; | ||||
|  #else | ||||
|  	cpu = intc->cpus[0]; | ||||
|  #endif | ||||
| @@ -0,0 +1,34 @@ | ||||
| From cf0d2fbaae9e962d91a321de75e0d4f9f9ccbdfe Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> | ||||
| Date: Thu, 21 Jan 2021 18:17:37 +0100 | ||||
| Subject: [PATCH] nand: brcmnand: fix OOB R/W with Hamming ECC | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Hamming ECC doesn't cover the OOB data, so reading or writing OOB shall | ||||
| always be done without ECC enabled. | ||||
| This is a problem when adding JFFS2 cleanmarkers to erased blocks. When JFFS2 | ||||
| clenmarkers are added to the OOB with ECC enabled, OOB bytes will be changed | ||||
| from ff ff ff to 00 00 00, reporting incorrect ECC errors. | ||||
|  | ||||
| Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| --- | ||||
|  drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c | ||||
| +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c | ||||
| @@ -2688,6 +2688,12 @@ static int brcmnand_attach_chip(struct n | ||||
|   | ||||
|  	ret = brcmstb_choose_ecc_layout(host); | ||||
|   | ||||
| +	/* If OOB is written with ECC enabled it will cause ECC errors */ | ||||
| +	if (is_hamming_ecc(host->ctrl, &host->hwcfg)) { | ||||
| +		chip->ecc.write_oob = brcmnand_write_oob_raw; | ||||
| +		chip->ecc.read_oob = brcmnand_read_oob_raw; | ||||
| +	} | ||||
| + | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
| @@ -0,0 +1,66 @@ | ||||
| --- a/drivers/watchdog/bcm7038_wdt.c | ||||
| +++ b/drivers/watchdog/bcm7038_wdt.c | ||||
| @@ -34,6 +34,24 @@ struct bcm7038_watchdog { | ||||
|   | ||||
|  static bool nowayout = WATCHDOG_NOWAYOUT; | ||||
|   | ||||
| +static inline void bcm7038_wdt_write(unsigned long data, void __iomem *reg) | ||||
| +{ | ||||
| +#ifdef CONFIG_CPU_BIG_ENDIAN | ||||
| +	iowrite32be(data, reg); | ||||
| +#else | ||||
| +	writel(data, reg); | ||||
| +#endif | ||||
| +} | ||||
| + | ||||
| +static inline unsigned long bcm7038_wdt_read(void __iomem *reg) | ||||
| +{ | ||||
| +#ifdef CONFIG_CPU_BIG_ENDIAN | ||||
| +	return ioread32be(reg); | ||||
| +#else | ||||
| +	return readl(reg); | ||||
| +#endif | ||||
| +} | ||||
| + | ||||
|  static void bcm7038_wdt_set_timeout_reg(struct watchdog_device *wdog) | ||||
|  { | ||||
|  	struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog); | ||||
| @@ -41,15 +59,15 @@ static void bcm7038_wdt_set_timeout_reg( | ||||
|   | ||||
|  	timeout = wdt->rate * wdog->timeout; | ||||
|   | ||||
| -	writel(timeout, wdt->base + WDT_TIMEOUT_REG); | ||||
| +	bcm7038_wdt_write(timeout, wdt->base + WDT_TIMEOUT_REG); | ||||
|  } | ||||
|   | ||||
|  static int bcm7038_wdt_ping(struct watchdog_device *wdog) | ||||
|  { | ||||
|  	struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog); | ||||
|   | ||||
| -	writel(WDT_START_1, wdt->base + WDT_CMD_REG); | ||||
| -	writel(WDT_START_2, wdt->base + WDT_CMD_REG); | ||||
| +	bcm7038_wdt_write(WDT_START_1, wdt->base + WDT_CMD_REG); | ||||
| +	bcm7038_wdt_write(WDT_START_2, wdt->base + WDT_CMD_REG); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
| @@ -66,8 +84,8 @@ static int bcm7038_wdt_stop(struct watch | ||||
|  { | ||||
|  	struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog); | ||||
|   | ||||
| -	writel(WDT_STOP_1, wdt->base + WDT_CMD_REG); | ||||
| -	writel(WDT_STOP_2, wdt->base + WDT_CMD_REG); | ||||
| +	bcm7038_wdt_write(WDT_STOP_1, wdt->base + WDT_CMD_REG); | ||||
| +	bcm7038_wdt_write(WDT_STOP_2, wdt->base + WDT_CMD_REG); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
| @@ -88,7 +106,7 @@ static unsigned int bcm7038_wdt_get_time | ||||
|  	struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog); | ||||
|  	u32 time_left; | ||||
|   | ||||
| -	time_left = readl(wdt->base + WDT_CMD_REG); | ||||
| +	time_left = bcm7038_wdt_read(wdt->base + WDT_CMD_REG); | ||||
|   | ||||
|  	return time_left / wdt->rate; | ||||
|  } | ||||
| @@ -0,0 +1,10 @@ | ||||
| --- a/drivers/spi/spi-bcm63xx.c | ||||
| +++ b/drivers/spi/spi-bcm63xx.c | ||||
| @@ -574,7 +574,6 @@ static int bcm63xx_spi_probe(struct plat | ||||
|  	master->bits_per_word_mask = SPI_BPW_MASK(8); | ||||
|  	master->max_transfer_size = bcm63xx_spi_max_length; | ||||
|  	master->max_message_size = bcm63xx_spi_max_length; | ||||
| -	master->auto_runtime_pm = true; | ||||
|  	bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT]; | ||||
|  	bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH]; | ||||
|  	bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]); | ||||
| @@ -0,0 +1,10 @@ | ||||
| --- a/drivers/spi/spi-bcm63xx-hsspi.c | ||||
| +++ b/drivers/spi/spi-bcm63xx-hsspi.c | ||||
| @@ -417,7 +417,6 @@ static int bcm63xx_hsspi_probe(struct pl | ||||
|  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | | ||||
|  			    SPI_RX_DUAL | SPI_TX_DUAL; | ||||
|  	master->bits_per_word_mask = SPI_BPW_MASK(8); | ||||
| -	master->auto_runtime_pm = true; | ||||
|   | ||||
|  	platform_set_drvdata(pdev, master); | ||||
|   | ||||
| @@ -0,0 +1,12 @@ | ||||
| --- a/drivers/usb/host/ehci-platform.c | ||||
| +++ b/drivers/usb/host/ehci-platform.c | ||||
| @@ -286,6 +286,9 @@ static int ehci_platform_probe(struct pl | ||||
|  		if (of_property_read_bool(dev->dev.of_node, "big-endian")) | ||||
|  			ehci->big_endian_mmio = ehci->big_endian_desc = 1; | ||||
|   | ||||
| +		if (of_property_read_bool(dev->dev.of_node, "ignore-oc")) | ||||
| +			ehci->ignore_oc = 1; | ||||
| + | ||||
|  		if (of_property_read_bool(dev->dev.of_node, | ||||
|  					  "needs-reset-on-resume")) | ||||
|  			priv->reset_on_resume = true; | ||||
| @@ -0,0 +1,226 @@ | ||||
| From ab2f33e35e35905a76204138143875251f3e1088 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Fri, 24 Jun 2016 22:07:42 +0200 | ||||
| Subject: [PATCH 01/13] pinctrl: add bcm63xx base code | ||||
|  | ||||
| Setup directory and add a helper for bcm63xx pinctrl support. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  drivers/pinctrl/Kconfig                   |   1 + | ||||
|  drivers/pinctrl/Makefile                  |   1 + | ||||
|  drivers/pinctrl/bcm63xx/Kconfig           |   3 + | ||||
|  drivers/pinctrl/bcm63xx/Makefile          |   1 + | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c | 142 ++++++++++++++++++++++++++++++ | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h |  14 +++ | ||||
|  7 files changed, 163 insertions(+) | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/Kconfig | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/Makefile | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h | ||||
|  | ||||
| --- a/drivers/pinctrl/Kconfig | ||||
| +++ b/drivers/pinctrl/Kconfig | ||||
| @@ -377,6 +377,7 @@ config PINCTRL_OCELOT | ||||
|  source "drivers/pinctrl/actions/Kconfig" | ||||
|  source "drivers/pinctrl/aspeed/Kconfig" | ||||
|  source "drivers/pinctrl/bcm/Kconfig" | ||||
| +source "drivers/pinctrl/bcm63xx/Kconfig" | ||||
|  source "drivers/pinctrl/berlin/Kconfig" | ||||
|  source "drivers/pinctrl/freescale/Kconfig" | ||||
|  source "drivers/pinctrl/intel/Kconfig" | ||||
| --- a/drivers/pinctrl/Makefile | ||||
| +++ b/drivers/pinctrl/Makefile | ||||
| @@ -51,6 +51,7 @@ obj-$(CONFIG_PINCTRL_EQUILIBRIUM)   += p | ||||
|  obj-y				+= actions/ | ||||
|  obj-$(CONFIG_ARCH_ASPEED)	+= aspeed/ | ||||
|  obj-y				+= bcm/ | ||||
| +obj-y				+= bcm63xx/ | ||||
|  obj-$(CONFIG_PINCTRL_BERLIN)	+= berlin/ | ||||
|  obj-y				+= freescale/ | ||||
|  obj-$(CONFIG_X86)		+= intel/ | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/Kconfig | ||||
| @@ -0,0 +1,3 @@ | ||||
| +config PINCTRL_BCM63XX | ||||
| +	bool | ||||
| +	select GPIO_GENERIC | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/Makefile | ||||
| @@ -0,0 +1 @@ | ||||
| +obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c | ||||
| @@ -0,0 +1,155 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/bitops.h> | ||||
| +#include <linux/device.h> | ||||
| +#include <linux/gpio/driver.h> | ||||
| +#include <linux/of_irq.h> | ||||
| + | ||||
| +#include "pinctrl-bcm63xx.h" | ||||
| +#include "../core.h" | ||||
| + | ||||
| +#define BANK_SIZE	sizeof(u32) | ||||
| +#define PINS_PER_BANK	(BANK_SIZE * BITS_PER_BYTE) | ||||
| + | ||||
| +#ifdef CONFIG_OF | ||||
| +static int bcm63xx_gpio_of_xlate(struct gpio_chip *gc, | ||||
| +				 const struct of_phandle_args *gpiospec, | ||||
| +				 u32 *flags) | ||||
| +{ | ||||
| +	struct gpio_chip *base = gpiochip_get_data(gc); | ||||
| +	int pin = gpiospec->args[0]; | ||||
| + | ||||
| +	if (gc != &base[pin / PINS_PER_BANK]) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	pin = pin % PINS_PER_BANK; | ||||
| + | ||||
| +	if (pin >= gc->ngpio) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	if (flags) | ||||
| +		*flags = gpiospec->args[1]; | ||||
| + | ||||
| +	return pin; | ||||
| +} | ||||
| +#endif | ||||
| + | ||||
| +static int bcm63xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) | ||||
| +{ | ||||
| +	struct gpio_chip *base = gpiochip_get_data(chip); | ||||
| +	char irq_name[7]; /* "gpioXX" */ | ||||
| + | ||||
| +	/* FIXME: this is ugly */ | ||||
| +	sprintf(irq_name, "gpio%d", gpio + PINS_PER_BANK * (chip - base)); | ||||
| +	return of_irq_get_byname(chip->of_node, irq_name); | ||||
| +} | ||||
| + | ||||
| +static int bcm63xx_setup_gpio(struct device *dev, struct gpio_chip *gc, | ||||
| +			      void __iomem *dirout, void __iomem *data, | ||||
| +			      size_t sz, int ngpio) | ||||
| + | ||||
| +{ | ||||
| +	int banks, chips, i, ret = -EINVAL; | ||||
| + | ||||
| +	chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK); | ||||
| +	banks = sz / BANK_SIZE; | ||||
| + | ||||
| +	for (i = 0; i < chips; i++) { | ||||
| +		int offset, pins; | ||||
| +		int reg_offset; | ||||
| +		char *label; | ||||
| + | ||||
| +		label = devm_kasprintf(dev, GFP_KERNEL, "bcm63xx-gpio.%i", i); | ||||
| +		if (!label) | ||||
| +			return -ENOMEM; | ||||
| + | ||||
| +		offset = i * PINS_PER_BANK; | ||||
| +		pins = min_t(int, ngpio - offset, PINS_PER_BANK); | ||||
| + | ||||
| +		/* the registers are treated like a huge big endian register */ | ||||
| +		reg_offset = (banks - i - 1) * BANK_SIZE; | ||||
| + | ||||
| +		ret = bgpio_init(&gc[i], dev, BANK_SIZE, data + reg_offset, | ||||
| +				 NULL, NULL, dirout + reg_offset, NULL, | ||||
| +				 BGPIOF_BIG_ENDIAN_BYTE_ORDER); | ||||
| +		if (ret) | ||||
| +			return ret; | ||||
| + | ||||
| +		gc[i].request = gpiochip_generic_request; | ||||
| +		gc[i].free = gpiochip_generic_free; | ||||
| + | ||||
| +		if (of_get_property(dev->of_node, "interrupt-names", NULL)) | ||||
| +			gc[i].to_irq = bcm63xx_gpio_to_irq; | ||||
| + | ||||
| +#ifdef CONFIG_OF | ||||
| +		gc[i].of_gpio_n_cells = 2; | ||||
| +		gc[i].of_xlate = bcm63xx_gpio_of_xlate; | ||||
| +#endif | ||||
| + | ||||
| +		gc[i].label = label; | ||||
| +		gc[i].ngpio = pins; | ||||
| + | ||||
| +		devm_gpiochip_add_data(dev, &gc[i], gc); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void bcm63xx_setup_pinranges(struct gpio_chip *gc, const char *name, | ||||
| +				    int ngpio) | ||||
| +{ | ||||
| +	int i, chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK); | ||||
| + | ||||
| +	for (i = 0; i < chips; i++) { | ||||
| +		int offset, pins; | ||||
| + | ||||
| +		offset = i * PINS_PER_BANK; | ||||
| +		pins = min_t(int, ngpio - offset, PINS_PER_BANK); | ||||
| + | ||||
| +		gpiochip_add_pin_range(&gc[i], name, 0, offset, pins); | ||||
| +	} | ||||
| +} | ||||
| + | ||||
| +struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev, | ||||
| +					     struct pinctrl_desc *desc, | ||||
| +					     void *priv, struct gpio_chip *gc, | ||||
| +					     int ngpio) | ||||
| +{ | ||||
| +	struct pinctrl_dev *pctldev; | ||||
| +	struct resource *res; | ||||
| +	void __iomem *dirout, *data; | ||||
| +	size_t sz; | ||||
| +	int ret; | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirout"); | ||||
| +	dirout = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(dirout)) | ||||
| +		return ERR_CAST(dirout); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); | ||||
| +	data = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(data)) | ||||
| +		return ERR_CAST(data); | ||||
| + | ||||
| +	sz = resource_size(res); | ||||
| + | ||||
| +	ret = bcm63xx_setup_gpio(&pdev->dev, gc, dirout, data, sz, ngpio); | ||||
| +	if (ret) | ||||
| +		return ERR_PTR(ret); | ||||
| + | ||||
| +	pctldev = devm_pinctrl_register(&pdev->dev, desc, priv); | ||||
| +	if (IS_ERR(pctldev)) | ||||
| +		return pctldev; | ||||
| + | ||||
| +	bcm63xx_setup_pinranges(gc, pinctrl_dev_get_devname(pctldev), ngpio); | ||||
| + | ||||
| +	dev_info(&pdev->dev, "registered at mmio %p\n", dirout); | ||||
| + | ||||
| +	return pctldev; | ||||
| +} | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h | ||||
| @@ -0,0 +1,14 @@ | ||||
| +#ifndef __PINCTRL_BCM63XX | ||||
| +#define __PINCTRL_BCM63XX | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/gpio.h> | ||||
| +#include <linux/pinctrl/pinctrl.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev, | ||||
| +					     struct pinctrl_desc *desc, | ||||
| +					     void *priv, struct gpio_chip *gc, | ||||
| +					     int ngpio); | ||||
| + | ||||
| +#endif | ||||
| @@ -0,0 +1,78 @@ | ||||
| From 4bdd40849632608d5cb7d3a64380cd76e7eea07b Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Wed, 27 Jul 2016 11:33:56 +0200 | ||||
| Subject: [PATCH 02/16] Documentation: add BCM6328 pincontroller binding | ||||
|  documentation | ||||
|  | ||||
| Add binding documentation for the pincontrol core found in BCM6328 SoCs. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  .../bindings/pinctrl/brcm,bcm6328-pinctrl.txt      | 61 ++++++++++++++++++++++ | ||||
|  1 file changed, 61 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt | ||||
| @@ -0,0 +1,61 @@ | ||||
| +* Broadcom BCM6328 pin controller | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible: Must be "brcm,bcm6328-pinctrl". | ||||
| +- reg: Register specifies of dirout, dat, mode, mux registers. | ||||
| +- reg-names: Must be "dirout", "dat", "mode", "mux". | ||||
| +- gpio-controller: Identifies this node as a GPIO controller. | ||||
| +- #gpio-cells: Must be <2> | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +pinctrl: pin-controller@10000080 { | ||||
| +	compatible = "brcm,bcm6328-pinctrl"; | ||||
| +	reg = <0x10000080 0x8>, | ||||
| +	      <0x10000088 0x8>, | ||||
| +	      <0x10000098 0x4>, | ||||
| +	      <0x1000009c 0xc>; | ||||
| +	reg-names = "dirout", "dat", "mode", "mux"; | ||||
| + | ||||
| +	gpio-controller; | ||||
| +	#gpio-cells = <2>; | ||||
| +}; | ||||
| + | ||||
| +Available pins/groups and functions: | ||||
| + | ||||
| +name		pins	functions | ||||
| +----------------------------------------------------------- | ||||
| +gpio0		0	led | ||||
| +gpio1		1	led | ||||
| +gpio2		2	led | ||||
| +gpio3		3	led | ||||
| +gpio4		4	led | ||||
| +gpio5		5	led | ||||
| +gpio6		6	led, serial_led_data | ||||
| +gpio7		7	led, serial_led_clk | ||||
| +gpio8		8	led | ||||
| +gpio9		9	led | ||||
| +gpio10		10	led | ||||
| +gpio11		11	led | ||||
| +gpio12		12	led | ||||
| +gpio13		13	led | ||||
| +gpio14		14	led | ||||
| +gpio15		15	led | ||||
| +gpio16		16	led, pcie_clkreq | ||||
| +gpio17		17	led | ||||
| +gpio18		18	led | ||||
| +gpio19		19	led | ||||
| +gpio20		20	led | ||||
| +gpio21		21	led | ||||
| +gpio22		22	led | ||||
| +gpio23		23	led | ||||
| +gpio24		24	- | ||||
| +gpio25		25	ephy0_act_led | ||||
| +gpio26		26	ephy1_act_led | ||||
| +gpio27		27	ephy2_act_led | ||||
| +gpio28		28	ephy3_act_led | ||||
| +gpio29		29	- | ||||
| +gpio30		30	- | ||||
| +gpio31		31	- | ||||
| +hsspi_cs1	-	hsspi_cs1 | ||||
| +usb_port1	-	usb_host_port, usb_device_port | ||||
| @@ -0,0 +1,495 @@ | ||||
| From 393e9753f6492c1fdf55891ddee60d955ae8b119 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Fri, 24 Jun 2016 22:12:50 +0200 | ||||
| Subject: [PATCH 03/16] pinctrl: add a pincontrol driver for BCM6328 | ||||
|  | ||||
| Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as | ||||
| GPIOs, as LEDs for the integrated LED controller, or various other | ||||
| functions. Its pincontrol mux registers also control other aspects, like | ||||
| switching the second USB port between host and device mode. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  drivers/pinctrl/bcm63xx/Kconfig           |   7 + | ||||
|  drivers/pinctrl/bcm63xx/Makefile          |   1 + | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c | 456 ++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 464 insertions(+) | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c | ||||
|  | ||||
| --- a/drivers/pinctrl/bcm63xx/Kconfig | ||||
| +++ b/drivers/pinctrl/bcm63xx/Kconfig | ||||
| @@ -1,3 +1,10 @@ | ||||
|  config PINCTRL_BCM63XX | ||||
|  	bool | ||||
|  	select GPIO_GENERIC | ||||
| + | ||||
| +config PINCTRL_BCM6328 | ||||
| +	bool "BCM6328 pincontrol driver" | ||||
| +	select PINMUX | ||||
| +	select PINCONF | ||||
| +	select PINCTRL_BCM63XX | ||||
| +	select GENERIC_PINCONF | ||||
| --- a/drivers/pinctrl/bcm63xx/Makefile | ||||
| +++ b/drivers/pinctrl/bcm63xx/Makefile | ||||
| @@ -1 +1,2 @@ | ||||
|  obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o | ||||
| +obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c | ||||
| @@ -0,0 +1,456 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/bitops.h> | ||||
| +#include <linux/gpio.h> | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/spinlock.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_gpio.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#include <linux/pinctrl/machine.h> | ||||
| +#include <linux/pinctrl/pinconf.h> | ||||
| +#include <linux/pinctrl/pinconf-generic.h> | ||||
| +#include <linux/pinctrl/pinmux.h> | ||||
| + | ||||
| +#include "../core.h" | ||||
| +#include "../pinctrl-utils.h" | ||||
| + | ||||
| +#include "pinctrl-bcm63xx.h" | ||||
| + | ||||
| +#define BCM6328_MUX_LO_REG	0x4 | ||||
| +#define BCM6328_MUX_HI_REG	0x0 | ||||
| +#define BCM6328_MUX_OTHER_REG	0x8 | ||||
| + | ||||
| +#define BCM6328_NGPIO		32 | ||||
| + | ||||
| +struct bcm6328_pingroup { | ||||
| +	const char *name; | ||||
| +	const unsigned * const pins; | ||||
| +	const unsigned num_pins; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6328_function { | ||||
| +	const char *name; | ||||
| +	const char * const *groups; | ||||
| +	const unsigned num_groups; | ||||
| + | ||||
| +	unsigned mode_val:1; | ||||
| +	unsigned mux_val:2; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6328_pinctrl { | ||||
| +	struct pinctrl_dev *pctldev; | ||||
| +	struct pinctrl_desc desc; | ||||
| + | ||||
| +	void __iomem *mode; | ||||
| +	void __iomem *mux[3]; | ||||
| + | ||||
| +	/* register access lock */ | ||||
| +	spinlock_t lock; | ||||
| + | ||||
| +	struct gpio_chip gpio; | ||||
| +}; | ||||
| + | ||||
| +static const struct pinctrl_pin_desc bcm6328_pins[] = { | ||||
| +	PINCTRL_PIN(0, "gpio0"), | ||||
| +	PINCTRL_PIN(1, "gpio1"), | ||||
| +	PINCTRL_PIN(2, "gpio2"), | ||||
| +	PINCTRL_PIN(3, "gpio3"), | ||||
| +	PINCTRL_PIN(4, "gpio4"), | ||||
| +	PINCTRL_PIN(5, "gpio5"), | ||||
| +	PINCTRL_PIN(6, "gpio6"), | ||||
| +	PINCTRL_PIN(7, "gpio7"), | ||||
| +	PINCTRL_PIN(8, "gpio8"), | ||||
| +	PINCTRL_PIN(9, "gpio9"), | ||||
| +	PINCTRL_PIN(10, "gpio10"), | ||||
| +	PINCTRL_PIN(11, "gpio11"), | ||||
| +	PINCTRL_PIN(12, "gpio12"), | ||||
| +	PINCTRL_PIN(13, "gpio13"), | ||||
| +	PINCTRL_PIN(14, "gpio14"), | ||||
| +	PINCTRL_PIN(15, "gpio15"), | ||||
| +	PINCTRL_PIN(16, "gpio16"), | ||||
| +	PINCTRL_PIN(17, "gpio17"), | ||||
| +	PINCTRL_PIN(18, "gpio18"), | ||||
| +	PINCTRL_PIN(19, "gpio19"), | ||||
| +	PINCTRL_PIN(20, "gpio20"), | ||||
| +	PINCTRL_PIN(21, "gpio21"), | ||||
| +	PINCTRL_PIN(22, "gpio22"), | ||||
| +	PINCTRL_PIN(23, "gpio23"), | ||||
| +	PINCTRL_PIN(24, "gpio24"), | ||||
| +	PINCTRL_PIN(25, "gpio25"), | ||||
| +	PINCTRL_PIN(26, "gpio26"), | ||||
| +	PINCTRL_PIN(27, "gpio27"), | ||||
| +	PINCTRL_PIN(28, "gpio28"), | ||||
| +	PINCTRL_PIN(29, "gpio29"), | ||||
| +	PINCTRL_PIN(30, "gpio30"), | ||||
| +	PINCTRL_PIN(31, "gpio31"), | ||||
| + | ||||
| +	/* | ||||
| +	 * No idea where they really are; so let's put them according | ||||
| +	 * to their mux offsets. | ||||
| +	 */ | ||||
| +	PINCTRL_PIN(36, "hsspi_cs1"), | ||||
| +	PINCTRL_PIN(38, "usb_p2"), | ||||
| +}; | ||||
| + | ||||
| +static unsigned gpio0_pins[] = { 0 }; | ||||
| +static unsigned gpio1_pins[] = { 1 }; | ||||
| +static unsigned gpio2_pins[] = { 2 }; | ||||
| +static unsigned gpio3_pins[] = { 3 }; | ||||
| +static unsigned gpio4_pins[] = { 4 }; | ||||
| +static unsigned gpio5_pins[] = { 5 }; | ||||
| +static unsigned gpio6_pins[] = { 6 }; | ||||
| +static unsigned gpio7_pins[] = { 7 }; | ||||
| +static unsigned gpio8_pins[] = { 8 }; | ||||
| +static unsigned gpio9_pins[] = { 9 }; | ||||
| +static unsigned gpio10_pins[] = { 10 }; | ||||
| +static unsigned gpio11_pins[] = { 11 }; | ||||
| +static unsigned gpio12_pins[] = { 12 }; | ||||
| +static unsigned gpio13_pins[] = { 13 }; | ||||
| +static unsigned gpio14_pins[] = { 14 }; | ||||
| +static unsigned gpio15_pins[] = { 15 }; | ||||
| +static unsigned gpio16_pins[] = { 16 }; | ||||
| +static unsigned gpio17_pins[] = { 17 }; | ||||
| +static unsigned gpio18_pins[] = { 18 }; | ||||
| +static unsigned gpio19_pins[] = { 19 }; | ||||
| +static unsigned gpio20_pins[] = { 20 }; | ||||
| +static unsigned gpio21_pins[] = { 21 }; | ||||
| +static unsigned gpio22_pins[] = { 22 }; | ||||
| +static unsigned gpio23_pins[] = { 23 }; | ||||
| +static unsigned gpio24_pins[] = { 24 }; | ||||
| +static unsigned gpio25_pins[] = { 25 }; | ||||
| +static unsigned gpio26_pins[] = { 26 }; | ||||
| +static unsigned gpio27_pins[] = { 27 }; | ||||
| +static unsigned gpio28_pins[] = { 28 }; | ||||
| +static unsigned gpio29_pins[] = { 29 }; | ||||
| +static unsigned gpio30_pins[] = { 30 }; | ||||
| +static unsigned gpio31_pins[] = { 31 }; | ||||
| + | ||||
| +static unsigned hsspi_cs1_pins[] = { 36 }; | ||||
| +static unsigned usb_port1_pins[] = { 38 }; | ||||
| + | ||||
| +#define BCM6328_GROUP(n)					\ | ||||
| +	{							\ | ||||
| +		.name = #n,					\ | ||||
| +		.pins = n##_pins,				\ | ||||
| +		.num_pins = ARRAY_SIZE(n##_pins),		\ | ||||
| +	} | ||||
| + | ||||
| +static struct bcm6328_pingroup bcm6328_groups[] = { | ||||
| +	BCM6328_GROUP(gpio0), | ||||
| +	BCM6328_GROUP(gpio1), | ||||
| +	BCM6328_GROUP(gpio2), | ||||
| +	BCM6328_GROUP(gpio3), | ||||
| +	BCM6328_GROUP(gpio4), | ||||
| +	BCM6328_GROUP(gpio5), | ||||
| +	BCM6328_GROUP(gpio6), | ||||
| +	BCM6328_GROUP(gpio7), | ||||
| +	BCM6328_GROUP(gpio8), | ||||
| +	BCM6328_GROUP(gpio9), | ||||
| +	BCM6328_GROUP(gpio10), | ||||
| +	BCM6328_GROUP(gpio11), | ||||
| +	BCM6328_GROUP(gpio12), | ||||
| +	BCM6328_GROUP(gpio13), | ||||
| +	BCM6328_GROUP(gpio14), | ||||
| +	BCM6328_GROUP(gpio15), | ||||
| +	BCM6328_GROUP(gpio16), | ||||
| +	BCM6328_GROUP(gpio17), | ||||
| +	BCM6328_GROUP(gpio18), | ||||
| +	BCM6328_GROUP(gpio19), | ||||
| +	BCM6328_GROUP(gpio20), | ||||
| +	BCM6328_GROUP(gpio21), | ||||
| +	BCM6328_GROUP(gpio22), | ||||
| +	BCM6328_GROUP(gpio23), | ||||
| +	BCM6328_GROUP(gpio24), | ||||
| +	BCM6328_GROUP(gpio25), | ||||
| +	BCM6328_GROUP(gpio26), | ||||
| +	BCM6328_GROUP(gpio27), | ||||
| +	BCM6328_GROUP(gpio28), | ||||
| +	BCM6328_GROUP(gpio29), | ||||
| +	BCM6328_GROUP(gpio30), | ||||
| +	BCM6328_GROUP(gpio31), | ||||
| + | ||||
| +	BCM6328_GROUP(hsspi_cs1), | ||||
| +	BCM6328_GROUP(usb_port1), | ||||
| +}; | ||||
| + | ||||
| +/* GPIO_MODE */ | ||||
| +static const char * const led_groups[] = { | ||||
| +	"gpio0", | ||||
| +	"gpio1", | ||||
| +	"gpio2", | ||||
| +	"gpio3", | ||||
| +	"gpio4", | ||||
| +	"gpio5", | ||||
| +	"gpio6", | ||||
| +	"gpio7", | ||||
| +	"gpio8", | ||||
| +	"gpio9", | ||||
| +	"gpio10", | ||||
| +	"gpio11", | ||||
| +	"gpio12", | ||||
| +	"gpio13", | ||||
| +	"gpio14", | ||||
| +	"gpio15", | ||||
| +	"gpio16", | ||||
| +	"gpio17", | ||||
| +	"gpio18", | ||||
| +	"gpio19", | ||||
| +	"gpio20", | ||||
| +	"gpio21", | ||||
| +	"gpio22", | ||||
| +	"gpio23", | ||||
| +}; | ||||
| + | ||||
| +/* PINMUX_SEL */ | ||||
| +static const char * const serial_led_data_groups[] = { | ||||
| +	"gpio6", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_clk_groups[] = { | ||||
| +	"gpio7", | ||||
| +}; | ||||
| + | ||||
| +static const char * const inet_act_led_groups[] = { | ||||
| +	"gpio11", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pcie_clkreq_groups[] = { | ||||
| +	"gpio16", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy0_act_led_groups[] = { | ||||
| +	"gpio25", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy1_act_led_groups[] = { | ||||
| +	"gpio26", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy2_act_led_groups[] = { | ||||
| +	"gpio27", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy3_act_led_groups[] = { | ||||
| +	"gpio28", | ||||
| +}; | ||||
| + | ||||
| +static const char * const hsspi_cs1_groups[] = { | ||||
| +	"hsspi_cs1" | ||||
| +}; | ||||
| + | ||||
| +static const char * const usb_host_port_groups[] = { | ||||
| +	"usb_port1", | ||||
| +}; | ||||
| + | ||||
| +static const char * const usb_device_port_groups[] = { | ||||
| +	"usb_port1", | ||||
| +}; | ||||
| + | ||||
| +#define BCM6328_MODE_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.mode_val = 1,				\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM6328_MUX_FUN(n, mux)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.mux_val = mux,				\ | ||||
| +	} | ||||
| + | ||||
| +static const struct bcm6328_function bcm6328_funcs[] = { | ||||
| +	BCM6328_MODE_FUN(led), | ||||
| +	BCM6328_MUX_FUN(serial_led_data, 2), | ||||
| +	BCM6328_MUX_FUN(serial_led_clk, 2), | ||||
| +	BCM6328_MUX_FUN(inet_act_led, 1), | ||||
| +	BCM6328_MUX_FUN(pcie_clkreq, 2), | ||||
| +	BCM6328_MUX_FUN(ephy0_act_led, 1), | ||||
| +	BCM6328_MUX_FUN(ephy1_act_led, 1), | ||||
| +	BCM6328_MUX_FUN(ephy2_act_led, 1), | ||||
| +	BCM6328_MUX_FUN(ephy3_act_led, 1), | ||||
| +	BCM6328_MUX_FUN(hsspi_cs1, 2), | ||||
| +	BCM6328_MUX_FUN(usb_host_port, 1), | ||||
| +	BCM6328_MUX_FUN(usb_device_port, 2), | ||||
| +}; | ||||
| + | ||||
| +static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6328_groups); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||||
| +						  unsigned group) | ||||
| +{ | ||||
| +	return bcm6328_groups[group].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||||
| +					  unsigned group, const unsigned **pins, | ||||
| +					  unsigned *num_pins) | ||||
| +{ | ||||
| +	*pins = bcm6328_groups[group].pins; | ||||
| +	*num_pins = bcm6328_groups[group].num_pins; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6328_funcs); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev, | ||||
| +						 unsigned selector) | ||||
| +{ | ||||
| +	return bcm6328_funcs[selector].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev, | ||||
| +				      unsigned selector, | ||||
| +				      const char * const **groups, | ||||
| +				      unsigned * const num_groups) | ||||
| +{ | ||||
| +	*groups = bcm6328_funcs[selector].groups; | ||||
| +	*num_groups = bcm6328_funcs[selector].num_groups; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void bcm6328_rmw_mux(struct bcm6328_pinctrl *pctl, unsigned pin, | ||||
| +			    u32 mode, u32 mux) | ||||
| +{ | ||||
| +	unsigned long flags; | ||||
| +	u32 reg; | ||||
| + | ||||
| +	spin_lock_irqsave(&pctl->lock, flags); | ||||
| +	if (pin < 32) { | ||||
| +		reg = __raw_readl(pctl->mode); | ||||
| +		reg &= ~BIT(pin); | ||||
| +		if (mode) | ||||
| +			reg |= BIT(pin); | ||||
| +		__raw_writel(reg, pctl->mode); | ||||
| +	} | ||||
| + | ||||
| +	reg = __raw_readl(pctl->mux[pin / 16]); | ||||
| +	reg &= ~(3UL << ((pin % 16) * 2)); | ||||
| +	reg |= mux << ((pin % 16) * 2); | ||||
| +	__raw_writel(reg, pctl->mux[pin / 16]); | ||||
| + | ||||
| +	spin_unlock_irqrestore(&pctl->lock, flags); | ||||
| +} | ||||
| + | ||||
| +static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, | ||||
| +				   unsigned selector, unsigned group) | ||||
| +{ | ||||
| +	struct bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	const struct bcm6328_pingroup *grp = &bcm6328_groups[group]; | ||||
| +	const struct bcm6328_function *f = &bcm6328_funcs[selector]; | ||||
| + | ||||
| +	bcm6328_rmw_mux(pctl, grp->pins[0], f->mode_val, f->mux_val); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev, | ||||
| +				       struct pinctrl_gpio_range *range, | ||||
| +				       unsigned offset) | ||||
| +{ | ||||
| +	struct bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| + | ||||
| +	/* disable all functions using this pin */ | ||||
| +	bcm6328_rmw_mux(pctl, offset, 0, 0); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct pinctrl_ops bcm6328_pctl_ops = { | ||||
| +	.get_groups_count	= bcm6328_pinctrl_get_group_count, | ||||
| +	.get_group_name		= bcm6328_pinctrl_get_group_name, | ||||
| +	.get_group_pins		= bcm6328_pinctrl_get_group_pins, | ||||
| +#ifdef CONFIG_OF | ||||
| +	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin, | ||||
| +	.dt_free_map		= pinctrl_utils_free_map, | ||||
| +#endif | ||||
| +}; | ||||
| + | ||||
| +static struct pinmux_ops bcm6328_pmx_ops = { | ||||
| +	.get_functions_count	= bcm6328_pinctrl_get_func_count, | ||||
| +	.get_function_name	= bcm6328_pinctrl_get_func_name, | ||||
| +	.get_function_groups	= bcm6328_pinctrl_get_groups, | ||||
| +	.set_mux		= bcm6328_pinctrl_set_mux, | ||||
| +	.gpio_request_enable	= bcm6328_gpio_request_enable, | ||||
| +	.strict			= true, | ||||
| +}; | ||||
| + | ||||
| +static int bcm6328_pinctrl_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct bcm6328_pinctrl *pctl; | ||||
| +	struct resource *res; | ||||
| +	void __iomem *mode, *mux; | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); | ||||
| +	mode = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(mode)) | ||||
| +		return PTR_ERR(mode); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux"); | ||||
| +	mux = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(mux)) | ||||
| +		return PTR_ERR(mux); | ||||
| + | ||||
| +	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); | ||||
| +	if (!pctl) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	spin_lock_init(&pctl->lock); | ||||
| + | ||||
| +	pctl->mode = mode; | ||||
| +	pctl->mux[0] = mux + BCM6328_MUX_LO_REG; | ||||
| +	pctl->mux[1] = mux + BCM6328_MUX_HI_REG; | ||||
| +	pctl->mux[2] = mux + BCM6328_MUX_OTHER_REG; | ||||
| + | ||||
| +	pctl->desc.name = dev_name(&pdev->dev); | ||||
| +	pctl->desc.owner = THIS_MODULE; | ||||
| +	pctl->desc.pctlops = &bcm6328_pctl_ops; | ||||
| +	pctl->desc.pmxops = &bcm6328_pmx_ops; | ||||
| + | ||||
| +	pctl->desc.npins = ARRAY_SIZE(bcm6328_pins); | ||||
| +	pctl->desc.pins = bcm6328_pins; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, pctl); | ||||
| + | ||||
| +	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, | ||||
| +						 &pctl->gpio, BCM6328_NGPIO); | ||||
| +	if (IS_ERR(pctl->pctldev)) | ||||
| +		return PTR_ERR(pctl->pctldev); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id bcm6328_pinctrl_match[] = { | ||||
| +	{ .compatible = "brcm,bcm6328-pinctrl", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_driver bcm6328_pinctrl_driver = { | ||||
| +	.probe = bcm6328_pinctrl_probe, | ||||
| +	.driver = { | ||||
| +		.name = "bcm6328-pinctrl", | ||||
| +		.of_match_table = bcm6328_pinctrl_match, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +builtin_platform_driver(bcm6328_pinctrl_driver); | ||||
| @@ -0,0 +1,61 @@ | ||||
| From c7c8fa7f5b5ee9bea751fa7bdae8ff4acde8f26e Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Wed, 27 Jul 2016 11:36:00 +0200 | ||||
| Subject: [PATCH 06/16] Documentation: add BCM6358 pincontroller binding | ||||
|  documentation | ||||
|  | ||||
| Add binding documentation for the pincontrol core found in BCM6358 SoCs. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  .../bindings/pinctrl/brcm,bcm6358-pinctrl.txt      | 44 ++++++++++++++++++++++ | ||||
|  1 file changed, 44 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt | ||||
| @@ -0,0 +1,44 @@ | ||||
| +* Broadcom BCM6358 pin controller | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible: Must be "brcm,bcm6358-pinctrl". | ||||
| +- reg: Register specifiers of dirout, dat registers. | ||||
| +- reg-names: Must be "dirout", "dat". | ||||
| +- brcm,gpiomode: Phandle to the shared gpiomode register. | ||||
| +- gpio-controller: Identifies this node as a gpio-controller. | ||||
| +- #gpio-cells: Must be <2>. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +pinctrl: pin-controller@fffe0080 { | ||||
| +	compatible = "brcm,bcm6358-pinctrl"; | ||||
| +	reg = <0xfffe0080 0x8>, | ||||
| +	      <0xfffe0088 0x8>, | ||||
| +	      <0xfffe0098 0x4>; | ||||
| +	reg-names = "dirout", "dat"; | ||||
| +	brcm,gpiomode = <&gpiomode>; | ||||
| + | ||||
| +	gpio-controller; | ||||
| +	#gpio-cells = <2>; | ||||
| +}; | ||||
| + | ||||
| +gpiomode: syscon@fffe0098 { | ||||
| +	compatible = "brcm,bcm6358-gpiomode", "syscon"; | ||||
| +	reg = <0xfffe0098 0x4>; | ||||
| +	native-endian; | ||||
| +}; | ||||
| + | ||||
| +Available pins/groups and functions: | ||||
| + | ||||
| +name		pins		functions | ||||
| +----------------------------------------------------------- | ||||
| +ebi_cs_grp	30-31		ebi_cs | ||||
| +uart1_grp	28-31		uart1 | ||||
| +spi_cs_grp	32-33		spi_cs | ||||
| +async_modem_grp	12-15		async_modem | ||||
| +legacy_led_grp	9-15		legacy_led | ||||
| +serial_led_grp	6-7		serial_led | ||||
| +led_grp		0-3		led | ||||
| +utopia_grp	12-15, 22-31	utopia | ||||
| +pwm_syn_clk_grp	8		pwm_syn_clk | ||||
| +sys_irq_grp	5		sys_irq | ||||
| @@ -0,0 +1,432 @@ | ||||
| From fb00ef462f3f8b70ea8902151cc72810fe90b999 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Fri, 24 Jun 2016 22:16:01 +0200 | ||||
| Subject: [PATCH 07/16] pinctrl: add a pincontrol driver for BCM6358 | ||||
|  | ||||
| Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different | ||||
| functions onto the GPIO pins. It does not support configuring individual | ||||
| pins but only whole groups. These groups may overlap, and still require | ||||
| the directions to be set correctly in the GPIO register. In addition the | ||||
| functions register controls other, not directly mux related functions. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  drivers/pinctrl/bcm63xx/Kconfig           |   8 + | ||||
|  drivers/pinctrl/bcm63xx/Makefile          |   1 + | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c | 393 ++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 402 insertions(+) | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c | ||||
|  | ||||
| --- a/drivers/pinctrl/bcm63xx/Kconfig | ||||
| +++ b/drivers/pinctrl/bcm63xx/Kconfig | ||||
| @@ -8,3 +8,11 @@ config PINCTRL_BCM6328 | ||||
|  	select PINCONF | ||||
|  	select PINCTRL_BCM63XX | ||||
|  	select GENERIC_PINCONF | ||||
| + | ||||
| +config PINCTRL_BCM6358 | ||||
| +	bool "BCM6358 pincontrol driver" | ||||
| +	select PINMUX | ||||
| +	select PINCONF | ||||
| +	select PINCTRL_BCM63XX | ||||
| +	select GENERIC_PINCONF | ||||
| +	select MFD_SYSCON | ||||
| --- a/drivers/pinctrl/bcm63xx/Makefile | ||||
| +++ b/drivers/pinctrl/bcm63xx/Makefile | ||||
| @@ -1,2 +1,3 @@ | ||||
|  obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o | ||||
| +obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c | ||||
| @@ -0,0 +1,390 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/bitops.h> | ||||
| +#include <linux/gpio.h> | ||||
| +#include <linux/gpio/driver.h> | ||||
| +#include <linux/mfd/syscon.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_gpio.h> | ||||
| +#include <linux/of_address.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/regmap.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#include <linux/pinctrl/pinconf.h> | ||||
| +#include <linux/pinctrl/pinconf-generic.h> | ||||
| +#include <linux/pinctrl/pinmux.h> | ||||
| +#include <linux/pinctrl/machine.h> | ||||
| + | ||||
| +#include "../core.h" | ||||
| +#include "../pinctrl-utils.h" | ||||
| + | ||||
| +#include "pinctrl-bcm63xx.h" | ||||
| + | ||||
| +/* GPIO_MODE register */ | ||||
| +#define BCM6358_MODE_MUX_NONE		0 | ||||
| + | ||||
| +/* overlays on gpio pins */ | ||||
| +#define BCM6358_MODE_MUX_EBI_CS		BIT(5) | ||||
| +#define BCM6358_MODE_MUX_UART1		BIT(6) | ||||
| +#define BCM6358_MODE_MUX_SPI_CS		BIT(7) | ||||
| +#define BCM6358_MODE_MUX_ASYNC_MODEM	BIT(8) | ||||
| +#define BCM6358_MODE_MUX_LEGACY_LED	BIT(9) | ||||
| +#define BCM6358_MODE_MUX_SERIAL_LED	BIT(10) | ||||
| +#define BCM6358_MODE_MUX_LED		BIT(11) | ||||
| +#define BCM6358_MODE_MUX_UTOPIA		BIT(12) | ||||
| +#define BCM6358_MODE_MUX_CLKRST		BIT(13) | ||||
| +#define BCM6358_MODE_MUX_PWM_SYN_CLK	BIT(14) | ||||
| +#define BCM6358_MODE_MUX_SYS_IRQ	BIT(15) | ||||
| + | ||||
| +#define BCM6358_NGPIO			40 | ||||
| + | ||||
| +struct bcm6358_pingroup { | ||||
| +	const char *name; | ||||
| +	const unsigned * const pins; | ||||
| +	const unsigned num_pins; | ||||
| + | ||||
| +	const u16 mode_val; | ||||
| + | ||||
| +	/* non-GPIO function muxes require the gpio direction to be set */ | ||||
| +	const u16 direction; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6358_function { | ||||
| +	const char *name; | ||||
| +	const char * const *groups; | ||||
| +	const unsigned num_groups; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6358_pinctrl { | ||||
| +	struct device *dev; | ||||
| +	struct pinctrl_dev *pctldev; | ||||
| +	struct pinctrl_desc desc; | ||||
| + | ||||
| +	struct regmap_field *overlays; | ||||
| + | ||||
| +	struct gpio_chip gpio[2]; | ||||
| +}; | ||||
| + | ||||
| +#define BCM6358_GPIO_PIN(a, b, bit1, bit2, bit3)		\ | ||||
| +	{							\ | ||||
| +		.number = a,					\ | ||||
| +		.name = b,					\ | ||||
| +		.drv_data = (void *)(BCM6358_MODE_MUX_##bit1 |	\ | ||||
| +				     BCM6358_MODE_MUX_##bit2 |	\ | ||||
| +				     BCM6358_MODE_MUX_##bit3),	\ | ||||
| +	} | ||||
| + | ||||
| +static const struct pinctrl_pin_desc bcm6358_pins[] = { | ||||
| +	BCM6358_GPIO_PIN(0, "gpio0", LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(1, "gpio1", LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(2, "gpio2", LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(3, "gpio3", LED, NONE, NONE), | ||||
| +	PINCTRL_PIN(4, "gpio4"), | ||||
| +	BCM6358_GPIO_PIN(5, "gpio5", SYS_IRQ, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(6, "gpio6", SERIAL_LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(7, "gpio7", SERIAL_LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(8, "gpio8", PWM_SYN_CLK, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(9, "gpio09", LEGACY_LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(10, "gpio10", LEGACY_LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(11, "gpio11", LEGACY_LED, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(12, "gpio12", LEGACY_LED, ASYNC_MODEM, UTOPIA), | ||||
| +	BCM6358_GPIO_PIN(13, "gpio13", LEGACY_LED, ASYNC_MODEM, UTOPIA), | ||||
| +	BCM6358_GPIO_PIN(14, "gpio14", LEGACY_LED, ASYNC_MODEM, UTOPIA), | ||||
| +	BCM6358_GPIO_PIN(15, "gpio15", LEGACY_LED, ASYNC_MODEM, UTOPIA), | ||||
| +	PINCTRL_PIN(16, "gpio16"), | ||||
| +	PINCTRL_PIN(17, "gpio17"), | ||||
| +	PINCTRL_PIN(18, "gpio18"), | ||||
| +	PINCTRL_PIN(19, "gpio19"), | ||||
| +	PINCTRL_PIN(20, "gpio20"), | ||||
| +	PINCTRL_PIN(21, "gpio21"), | ||||
| +	BCM6358_GPIO_PIN(22, "gpio22", UTOPIA, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(23, "gpio23", UTOPIA, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(24, "gpio24", UTOPIA, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(25, "gpio25", UTOPIA, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(26, "gpio26", UTOPIA, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(27, "gpio27", UTOPIA, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(28, "gpio28", UTOPIA, UART1, NONE), | ||||
| +	BCM6358_GPIO_PIN(29, "gpio29", UTOPIA, UART1, NONE), | ||||
| +	BCM6358_GPIO_PIN(30, "gpio30", UTOPIA, UART1, EBI_CS), | ||||
| +	BCM6358_GPIO_PIN(31, "gpio31", UTOPIA, UART1, EBI_CS), | ||||
| +	BCM6358_GPIO_PIN(32, "gpio32", SPI_CS, NONE, NONE), | ||||
| +	BCM6358_GPIO_PIN(33, "gpio33", SPI_CS, NONE, NONE), | ||||
| +	PINCTRL_PIN(34, "gpio34"), | ||||
| +	PINCTRL_PIN(35, "gpio35"), | ||||
| +	PINCTRL_PIN(36, "gpio36"), | ||||
| +	PINCTRL_PIN(37, "gpio37"), | ||||
| +	PINCTRL_PIN(38, "gpio38"), | ||||
| +	PINCTRL_PIN(39, "gpio39"), | ||||
| +}; | ||||
| + | ||||
| +static unsigned ebi_cs_grp_pins[] = { 30, 31 }; | ||||
| + | ||||
| +static unsigned uart1_grp_pins[] = { 28, 29, 30, 31 }; | ||||
| + | ||||
| +static unsigned spi_cs_grp_pins[] = { 32, 33 }; | ||||
| + | ||||
| +static unsigned async_modem_grp_pins[] = { 12, 13, 14, 15 }; | ||||
| + | ||||
| +static unsigned serial_led_grp_pins[] = { 6, 7 }; | ||||
| + | ||||
| +static unsigned legacy_led_grp_pins[] = { 9, 10, 11, 12, 13, 14, 15 }; | ||||
| + | ||||
| +static unsigned led_grp_pins[] = { 0, 1, 2, 3 }; | ||||
| + | ||||
| +static unsigned utopia_grp_pins[] = { | ||||
| +	12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, | ||||
| +}; | ||||
| + | ||||
| +static unsigned pwm_syn_clk_grp_pins[] = { 8 }; | ||||
| + | ||||
| +static unsigned sys_irq_grp_pins[] = { 5 }; | ||||
| + | ||||
| +#define BCM6358_GPIO_MUX_GROUP(n, bit, dir)			\ | ||||
| +	{							\ | ||||
| +		.name = #n,					\ | ||||
| +		.pins = n##_pins,				\ | ||||
| +		.num_pins = ARRAY_SIZE(n##_pins),		\ | ||||
| +		.mode_val = BCM6358_MODE_MUX_##bit,		\ | ||||
| +		.direction = dir,				\ | ||||
| +	} | ||||
| + | ||||
| +static const struct bcm6358_pingroup bcm6358_groups[] = { | ||||
| +	BCM6358_GPIO_MUX_GROUP(ebi_cs_grp, EBI_CS, 0x3), | ||||
| +	BCM6358_GPIO_MUX_GROUP(uart1_grp, UART1, 0x2), | ||||
| +	BCM6358_GPIO_MUX_GROUP(spi_cs_grp, SPI_CS, 0x6), | ||||
| +	BCM6358_GPIO_MUX_GROUP(async_modem_grp, ASYNC_MODEM, 0x6), | ||||
| +	BCM6358_GPIO_MUX_GROUP(legacy_led_grp, LEGACY_LED, 0x7f), | ||||
| +	BCM6358_GPIO_MUX_GROUP(serial_led_grp, SERIAL_LED, 0x3), | ||||
| +	BCM6358_GPIO_MUX_GROUP(led_grp, LED, 0xf), | ||||
| +	BCM6358_GPIO_MUX_GROUP(utopia_grp, UTOPIA, 0x000f), | ||||
| +	BCM6358_GPIO_MUX_GROUP(pwm_syn_clk_grp, PWM_SYN_CLK, 0x1), | ||||
| +	BCM6358_GPIO_MUX_GROUP(sys_irq_grp, SYS_IRQ, 0x1), | ||||
| +}; | ||||
| + | ||||
| +static const char * const ebi_cs_groups[] = { | ||||
| +	"ebi_cs_grp" | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_groups[] = { | ||||
| +	"uart1_grp" | ||||
| +}; | ||||
| + | ||||
| +static const char * const spi_cs_2_3_groups[] = { | ||||
| +	"spi_cs_2_3_grp" | ||||
| +}; | ||||
| + | ||||
| +static const char * const async_modem_groups[] = { | ||||
| +	"async_modem_grp" | ||||
| +}; | ||||
| + | ||||
| +static const char * const legacy_led_groups[] = { | ||||
| +	"legacy_led_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_groups[] = { | ||||
| +	"serial_led_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const led_groups[] = { | ||||
| +	"led_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const clkrst_groups[] = { | ||||
| +	"clkrst_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pwm_syn_clk_groups[] = { | ||||
| +	"pwm_syn_clk_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const sys_irq_groups[] = { | ||||
| +	"sys_irq_grp", | ||||
| +}; | ||||
| + | ||||
| +#define BCM6358_FUN(n)					\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +	} | ||||
| + | ||||
| +static const struct bcm6358_function bcm6358_funcs[] = { | ||||
| +	BCM6358_FUN(ebi_cs), | ||||
| +	BCM6358_FUN(uart1), | ||||
| +	BCM6358_FUN(spi_cs_2_3), | ||||
| +	BCM6358_FUN(async_modem), | ||||
| +	BCM6358_FUN(legacy_led), | ||||
| +	BCM6358_FUN(serial_led), | ||||
| +	BCM6358_FUN(led), | ||||
| +	BCM6358_FUN(clkrst), | ||||
| +	BCM6358_FUN(pwm_syn_clk), | ||||
| +	BCM6358_FUN(sys_irq), | ||||
| +}; | ||||
| + | ||||
| +static int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6358_groups); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||||
| +						  unsigned group) | ||||
| +{ | ||||
| +	return bcm6358_groups[group].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||||
| +					  unsigned group, const unsigned **pins, | ||||
| +					  unsigned *num_pins) | ||||
| +{ | ||||
| +	*pins = bcm6358_groups[group].pins; | ||||
| +	*num_pins = bcm6358_groups[group].num_pins; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6358_pinctrl_get_func_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6358_funcs); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6358_pinctrl_get_func_name(struct pinctrl_dev *pctldev, | ||||
| +						 unsigned selector) | ||||
| +{ | ||||
| +	return bcm6358_funcs[selector].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6358_pinctrl_get_groups(struct pinctrl_dev *pctldev, | ||||
| +				      unsigned selector, | ||||
| +				      const char * const **groups, | ||||
| +				      unsigned * const num_groups) | ||||
| +{ | ||||
| +	*groups = bcm6358_funcs[selector].groups; | ||||
| +	*num_groups = bcm6358_funcs[selector].num_groups; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev, | ||||
| +				   unsigned selector, unsigned group) | ||||
| +{ | ||||
| +	struct bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	const struct bcm6358_pingroup *grp = &bcm6358_groups[group]; | ||||
| +	u32 val = grp->mode_val; | ||||
| +	u32 mask = val; | ||||
| +	unsigned pin; | ||||
| + | ||||
| +	for (pin = 0; pin < grp->num_pins; pin++) | ||||
| +		mask |= (unsigned long)bcm6358_pins[pin].drv_data; | ||||
| + | ||||
| +	regmap_field_update_bits(pctl->overlays, mask, val); | ||||
| + | ||||
| +	for (pin = 0; pin < grp->num_pins; pin++) { | ||||
| +		int hw_gpio = bcm6358_pins[pin].number; | ||||
| +		struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32]; | ||||
| + | ||||
| +		if (grp->direction & BIT(pin)) | ||||
| +			gc->direction_output(gc, hw_gpio % 32, 0); | ||||
| +		else | ||||
| +			gc->direction_input(gc, hw_gpio % 32); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev, | ||||
| +				       struct pinctrl_gpio_range *range, | ||||
| +				       unsigned offset) | ||||
| +{ | ||||
| +	struct bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	u32 mask; | ||||
| + | ||||
| +	mask = (unsigned long)bcm6358_pins[offset].drv_data; | ||||
| +	if (!mask) | ||||
| +		return 0; | ||||
| + | ||||
| +	/* disable all functions using this pin */ | ||||
| +	return regmap_field_update_bits(pctl->overlays, mask, 0); | ||||
| +} | ||||
| + | ||||
| +static struct pinctrl_ops bcm6358_pctl_ops = { | ||||
| +	.get_groups_count	= bcm6358_pinctrl_get_group_count, | ||||
| +	.get_group_name		= bcm6358_pinctrl_get_group_name, | ||||
| +	.get_group_pins		= bcm6358_pinctrl_get_group_pins, | ||||
| +#ifdef CONFIG_OF | ||||
| +	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin, | ||||
| +	.dt_free_map		= pinctrl_utils_free_map, | ||||
| +#endif | ||||
| +}; | ||||
| + | ||||
| +static struct pinmux_ops bcm6358_pmx_ops = { | ||||
| +	.get_functions_count	= bcm6358_pinctrl_get_func_count, | ||||
| +	.get_function_name	= bcm6358_pinctrl_get_func_name, | ||||
| +	.get_function_groups	= bcm6358_pinctrl_get_groups, | ||||
| +	.set_mux		= bcm6358_pinctrl_set_mux, | ||||
| +	.gpio_request_enable	= bcm6358_gpio_request_enable, | ||||
| +	.strict			= true, | ||||
| +}; | ||||
| + | ||||
| +static int bcm6358_pinctrl_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct bcm6358_pinctrl *pctl; | ||||
| +	struct regmap *mode; | ||||
| +	struct reg_field overlays = REG_FIELD(0, 0, 15); | ||||
| + | ||||
| +	mode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | ||||
| +					       "brcm,gpiomode"); | ||||
| + | ||||
| +	if (IS_ERR(mode)) | ||||
| +		return PTR_ERR(mode); | ||||
| + | ||||
| +	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); | ||||
| +	if (!pctl) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	pctl->overlays = devm_regmap_field_alloc(&pdev->dev, mode, overlays); | ||||
| +	if (IS_ERR(pctl->overlays)) | ||||
| +		return PTR_ERR(pctl->overlays); | ||||
| + | ||||
| +	/* disable all muxes by default */ | ||||
| +	regmap_field_write(pctl->overlays, 0); | ||||
| + | ||||
| +	pctl->desc.name = dev_name(&pdev->dev); | ||||
| +	pctl->desc.owner = THIS_MODULE; | ||||
| +	pctl->desc.pctlops = &bcm6358_pctl_ops; | ||||
| +	pctl->desc.pmxops = &bcm6358_pmx_ops; | ||||
| + | ||||
| +	pctl->desc.npins = ARRAY_SIZE(bcm6358_pins); | ||||
| +	pctl->desc.pins = bcm6358_pins; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, pctl); | ||||
| + | ||||
| +	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, | ||||
| +						 pctl->gpio, BCM6358_NGPIO); | ||||
| +	if (IS_ERR(pctl->pctldev)) | ||||
| +		return PTR_ERR(pctl->pctldev); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id bcm6358_pinctrl_match[] = { | ||||
| +	{ .compatible = "brcm,bcm6358-pinctrl", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_driver bcm6358_pinctrl_driver = { | ||||
| +	.probe = bcm6358_pinctrl_probe, | ||||
| +	.driver = { | ||||
| +		.name = "bcm6358-pinctrl", | ||||
| +		.of_match_table = bcm6358_pinctrl_match, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +builtin_platform_driver(bcm6358_pinctrl_driver); | ||||
| @@ -0,0 +1,96 @@ | ||||
| From ba03ea8ada2ca71c9095d96a1e4085c2c5cf0e69 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Wed, 27 Jul 2016 11:36:18 +0200 | ||||
| Subject: [PATCH 08/16] Documentation: add BCM6362 pincontroller binding | ||||
|  documentation | ||||
|  | ||||
| Add binding documentation for the pincontrol core found in BCM6362 SoCs. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  .../bindings/pinctrl/brcm,bcm6362-pinctrl.txt      | 79 ++++++++++++++++++++++ | ||||
|  1 file changed, 79 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt | ||||
| @@ -0,0 +1,79 @@ | ||||
| +* Broadcom BCM6362 pin controller | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible: Must be "brcm,bcm6362-pinctrl" | ||||
| +- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers. | ||||
| +- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode". | ||||
| +- gpio-controller: Identifies this node as a GPIO controller. | ||||
| +- #gpio-cells: Must be <2>. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +pinctrl: pin-controller@10000080 { | ||||
| +	compatible = "brcm,bcm6362-pinctrl"; | ||||
| +	reg = <0x10000080 0x8>, | ||||
| +	      <0x10000088 0x8>, | ||||
| +	      <0x10000090 0x4>, | ||||
| +	      <0x10000098 0x4>, | ||||
| +	      <0x1000009c 0x4>, | ||||
| +	      <0x100000b8 0x4>; | ||||
| +	reg-names = "dirout", "dat", "led", | ||||
| +		    "mode", "ctrl", "basemode"; | ||||
| + | ||||
| +	gpio-controller; | ||||
| +	#gpio-cells = <2>; | ||||
| +}; | ||||
| + | ||||
| +Available pins/groups and functions: | ||||
| + | ||||
| +name		pins		functions | ||||
| +----------------------------------------------------------- | ||||
| +gpio0		0		led, usb_device_led | ||||
| +gpio1		1		led, sys_irq | ||||
| +gpio2		2		led, serial_led_clk | ||||
| +gpio3		3		led, serial_led_data | ||||
| +gpio4		4		led, robosw_led_data | ||||
| +gpio5		5		led, robosw_led_clk | ||||
| +gpio6		6		led, robosw_led0 | ||||
| +gpio7		7		led, robosw_led1 | ||||
| +gpio8		8		led, inet_led | ||||
| +gpio9		9		led, spi_cs2 | ||||
| +gpio10		10		led, spi_cs3 | ||||
| +gpio11		11		led, ntr_pulse | ||||
| +gpio12		12		led, uart1_scts | ||||
| +gpio13		13		led, uart1_srts | ||||
| +gpio14		14		led, uart1_sdin | ||||
| +gpio15		15		led, uart1_sdout | ||||
| +gpio16		16		led, adsl_spi_miso | ||||
| +gpio17		17		led, adsl_spi_mosi | ||||
| +gpio18		18		led, adsl_spi_clk | ||||
| +gpio19		19		led, adsl_spi_cs | ||||
| +gpio20		20		led, ephy0_led | ||||
| +gpio21		21		led, ephy1_led | ||||
| +gpio22		22		led, ephy2_led | ||||
| +gpio23		23		led, ephy3_led | ||||
| +gpio24		24		ext_irq0 | ||||
| +gpio25		25		ext_irq1 | ||||
| +gpio26		26		ext_irq2 | ||||
| +gpio27		27		ext_irq3 | ||||
| +gpio28		28		- | ||||
| +gpio29		29		- | ||||
| +gpio30		30		- | ||||
| +gpio31		31		- | ||||
| +gpio32		32		wifi | ||||
| +gpio33		33		wifi | ||||
| +gpio34		34		wifi | ||||
| +gpio35		35		wifi | ||||
| +gpio36		36		wifi | ||||
| +gpio37		37		wifi | ||||
| +gpio38		38		wifi | ||||
| +gpio39		39		wifi | ||||
| +gpio40		40		wifi | ||||
| +gpio41		41		wifi | ||||
| +gpio42		42		wifi | ||||
| +gpio43		43		wifi | ||||
| +gpio44		44		wifi | ||||
| +gpio45		45		wifi | ||||
| +gpio46		46		wifi | ||||
| +gpio47		47		wifi | ||||
| +nand_grp	8, 12-23, 27	nand | ||||
| @@ -0,0 +1,733 @@ | ||||
| From eea6b96701d734095e2f823f3a82d9b063f553ae Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Fri, 24 Jun 2016 22:17:20 +0200 | ||||
| Subject: [PATCH 09/16] pinctrl: add a pincontrol driver for BCM6362 | ||||
|  | ||||
| Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual | ||||
| GPIO pins to the LED controller, to be available by the integrated | ||||
| wifi, or other functions. It also supports overlay groups, of which | ||||
| only NAND is documented. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  drivers/pinctrl/bcm63xx/Kconfig           |   7 + | ||||
|  drivers/pinctrl/bcm63xx/Makefile          |   1 + | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c | 692 ++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 700 insertions(+) | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c | ||||
|  | ||||
| --- a/drivers/pinctrl/bcm63xx/Kconfig | ||||
| +++ b/drivers/pinctrl/bcm63xx/Kconfig | ||||
| @@ -16,3 +16,10 @@ config PINCTRL_BCM6358 | ||||
|  	select PINCTRL_BCM63XX | ||||
|  	select GENERIC_PINCONF | ||||
|  	select MFD_SYSCON | ||||
| + | ||||
| +config PINCTRL_BCM6362 | ||||
| +	bool "BCM6362 pincontrol driver" | ||||
| +	select PINMUX | ||||
| +	select PINCONF | ||||
| +	select PINCTRL_BCM63XX | ||||
| +	select GENERIC_PINCONF | ||||
| --- a/drivers/pinctrl/bcm63xx/Makefile | ||||
| +++ b/drivers/pinctrl/bcm63xx/Makefile | ||||
| @@ -1,3 +1,4 @@ | ||||
|  obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o | ||||
| +obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c | ||||
| @@ -0,0 +1,692 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/spinlock.h> | ||||
| +#include <linux/bitops.h> | ||||
| +#include <linux/gpio.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_gpio.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#include <linux/pinctrl/pinconf.h> | ||||
| +#include <linux/pinctrl/pinconf-generic.h> | ||||
| +#include <linux/pinctrl/pinmux.h> | ||||
| +#include <linux/pinctrl/machine.h> | ||||
| + | ||||
| +#include "../core.h" | ||||
| +#include "../pinctrl-utils.h" | ||||
| + | ||||
| +#include "pinctrl-bcm63xx.h" | ||||
| + | ||||
| +#define BCM6362_NGPIO	48 | ||||
| + | ||||
| +/* GPIO_BASEMODE register */ | ||||
| +#define BASEMODE_NAND	BIT(2) | ||||
| + | ||||
| +enum bcm6362_pinctrl_reg { | ||||
| +	BCM6362_LEDCTRL, | ||||
| +	BCM6362_MODE, | ||||
| +	BCM6362_CTRL, | ||||
| +	BCM6362_BASEMODE, | ||||
| +}; | ||||
| + | ||||
| +struct bcm6362_pingroup { | ||||
| +	const char *name; | ||||
| +	const unsigned * const pins; | ||||
| +	const unsigned num_pins; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6362_function { | ||||
| +	const char *name; | ||||
| +	const char * const *groups; | ||||
| +	const unsigned num_groups; | ||||
| + | ||||
| +	enum bcm6362_pinctrl_reg reg; | ||||
| +	u32 basemode_mask; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6362_pinctrl { | ||||
| +	struct pinctrl_dev *pctldev; | ||||
| +	struct pinctrl_desc desc; | ||||
| + | ||||
| +	void __iomem *led; | ||||
| +	void __iomem *mode; | ||||
| +	void __iomem *ctrl; | ||||
| +	void __iomem *basemode; | ||||
| + | ||||
| +	/* register access lock */ | ||||
| +	spinlock_t lock; | ||||
| + | ||||
| +	struct gpio_chip gpio[2]; | ||||
| +}; | ||||
| + | ||||
| +#define BCM6362_PIN(a, b, mask)			\ | ||||
| +	{					\ | ||||
| +		.number = a,			\ | ||||
| +		.name = b,			\ | ||||
| +		.drv_data = (void *)(mask),	\ | ||||
| +	} | ||||
| + | ||||
| +static const struct pinctrl_pin_desc bcm6362_pins[] = { | ||||
| +	PINCTRL_PIN(0, "gpio0"), | ||||
| +	PINCTRL_PIN(1, "gpio1"), | ||||
| +	PINCTRL_PIN(2, "gpio2"), | ||||
| +	PINCTRL_PIN(3, "gpio3"), | ||||
| +	PINCTRL_PIN(4, "gpio4"), | ||||
| +	PINCTRL_PIN(5, "gpio5"), | ||||
| +	PINCTRL_PIN(6, "gpio6"), | ||||
| +	PINCTRL_PIN(7, "gpio7"), | ||||
| +	BCM6362_PIN(8, "gpio8", BASEMODE_NAND), | ||||
| +	PINCTRL_PIN(9, "gpio9"), | ||||
| +	PINCTRL_PIN(10, "gpio10"), | ||||
| +	PINCTRL_PIN(11, "gpio11"), | ||||
| +	BCM6362_PIN(12, "gpio12", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(13, "gpio13", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(14, "gpio14", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(15, "gpio15", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(16, "gpio16", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(17, "gpio17", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(18, "gpio18", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(19, "gpio19", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(20, "gpio20", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(21, "gpio21", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(22, "gpio22", BASEMODE_NAND), | ||||
| +	BCM6362_PIN(23, "gpio23", BASEMODE_NAND), | ||||
| +	PINCTRL_PIN(24, "gpio24"), | ||||
| +	PINCTRL_PIN(25, "gpio25"), | ||||
| +	PINCTRL_PIN(26, "gpio26"), | ||||
| +	BCM6362_PIN(27, "gpio27", BASEMODE_NAND), | ||||
| +	PINCTRL_PIN(28, "gpio28"), | ||||
| +	PINCTRL_PIN(29, "gpio29"), | ||||
| +	PINCTRL_PIN(30, "gpio30"), | ||||
| +	PINCTRL_PIN(31, "gpio31"), | ||||
| +	PINCTRL_PIN(32, "gpio32"), | ||||
| +	PINCTRL_PIN(33, "gpio33"), | ||||
| +	PINCTRL_PIN(34, "gpio34"), | ||||
| +	PINCTRL_PIN(35, "gpio35"), | ||||
| +	PINCTRL_PIN(36, "gpio36"), | ||||
| +	PINCTRL_PIN(37, "gpio37"), | ||||
| +	PINCTRL_PIN(38, "gpio38"), | ||||
| +	PINCTRL_PIN(39, "gpio39"), | ||||
| +	PINCTRL_PIN(40, "gpio40"), | ||||
| +	PINCTRL_PIN(41, "gpio41"), | ||||
| +	PINCTRL_PIN(42, "gpio42"), | ||||
| +	PINCTRL_PIN(43, "gpio43"), | ||||
| +	PINCTRL_PIN(44, "gpio44"), | ||||
| +	PINCTRL_PIN(45, "gpio45"), | ||||
| +	PINCTRL_PIN(46, "gpio46"), | ||||
| +	PINCTRL_PIN(47, "gpio47"), | ||||
| +}; | ||||
| + | ||||
| +static unsigned gpio0_pins[] = { 0 }; | ||||
| +static unsigned gpio1_pins[] = { 1 }; | ||||
| +static unsigned gpio2_pins[] = { 2 }; | ||||
| +static unsigned gpio3_pins[] = { 3 }; | ||||
| +static unsigned gpio4_pins[] = { 4 }; | ||||
| +static unsigned gpio5_pins[] = { 5 }; | ||||
| +static unsigned gpio6_pins[] = { 6 }; | ||||
| +static unsigned gpio7_pins[] = { 7 }; | ||||
| +static unsigned gpio8_pins[] = { 8 }; | ||||
| +static unsigned gpio9_pins[] = { 9 }; | ||||
| +static unsigned gpio10_pins[] = { 10 }; | ||||
| +static unsigned gpio11_pins[] = { 11 }; | ||||
| +static unsigned gpio12_pins[] = { 12 }; | ||||
| +static unsigned gpio13_pins[] = { 13 }; | ||||
| +static unsigned gpio14_pins[] = { 14 }; | ||||
| +static unsigned gpio15_pins[] = { 15 }; | ||||
| +static unsigned gpio16_pins[] = { 16 }; | ||||
| +static unsigned gpio17_pins[] = { 17 }; | ||||
| +static unsigned gpio18_pins[] = { 18 }; | ||||
| +static unsigned gpio19_pins[] = { 19 }; | ||||
| +static unsigned gpio20_pins[] = { 20 }; | ||||
| +static unsigned gpio21_pins[] = { 21 }; | ||||
| +static unsigned gpio22_pins[] = { 22 }; | ||||
| +static unsigned gpio23_pins[] = { 23 }; | ||||
| +static unsigned gpio24_pins[] = { 24 }; | ||||
| +static unsigned gpio25_pins[] = { 25 }; | ||||
| +static unsigned gpio26_pins[] = { 26 }; | ||||
| +static unsigned gpio27_pins[] = { 27 }; | ||||
| +static unsigned gpio28_pins[] = { 28 }; | ||||
| +static unsigned gpio29_pins[] = { 29 }; | ||||
| +static unsigned gpio30_pins[] = { 30 }; | ||||
| +static unsigned gpio31_pins[] = { 31 }; | ||||
| +static unsigned gpio32_pins[] = { 32 }; | ||||
| +static unsigned gpio33_pins[] = { 33 }; | ||||
| +static unsigned gpio34_pins[] = { 34 }; | ||||
| +static unsigned gpio35_pins[] = { 35 }; | ||||
| +static unsigned gpio36_pins[] = { 36 }; | ||||
| +static unsigned gpio37_pins[] = { 37 }; | ||||
| +static unsigned gpio38_pins[] = { 38 }; | ||||
| +static unsigned gpio39_pins[] = { 39 }; | ||||
| +static unsigned gpio40_pins[] = { 40 }; | ||||
| +static unsigned gpio41_pins[] = { 41 }; | ||||
| +static unsigned gpio42_pins[] = { 42 }; | ||||
| +static unsigned gpio43_pins[] = { 43 }; | ||||
| +static unsigned gpio44_pins[] = { 44 }; | ||||
| +static unsigned gpio45_pins[] = { 45 }; | ||||
| +static unsigned gpio46_pins[] = { 46 }; | ||||
| +static unsigned gpio47_pins[] = { 47 }; | ||||
| + | ||||
| +static unsigned nand_grp_pins[] = { | ||||
| +	8, 12, 13, 14, 15, 16, 17, | ||||
| +	18, 19, 20, 21, 22, 23, 27, | ||||
| +}; | ||||
| + | ||||
| +#define BCM6362_GROUP(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.pins = n##_pins,			\ | ||||
| +		.num_pins = ARRAY_SIZE(n##_pins),	\ | ||||
| +	} | ||||
| + | ||||
| +static struct bcm6362_pingroup bcm6362_groups[] = { | ||||
| +	BCM6362_GROUP(gpio0), | ||||
| +	BCM6362_GROUP(gpio1), | ||||
| +	BCM6362_GROUP(gpio2), | ||||
| +	BCM6362_GROUP(gpio3), | ||||
| +	BCM6362_GROUP(gpio4), | ||||
| +	BCM6362_GROUP(gpio5), | ||||
| +	BCM6362_GROUP(gpio6), | ||||
| +	BCM6362_GROUP(gpio7), | ||||
| +	BCM6362_GROUP(gpio8), | ||||
| +	BCM6362_GROUP(gpio9), | ||||
| +	BCM6362_GROUP(gpio10), | ||||
| +	BCM6362_GROUP(gpio11), | ||||
| +	BCM6362_GROUP(gpio12), | ||||
| +	BCM6362_GROUP(gpio13), | ||||
| +	BCM6362_GROUP(gpio14), | ||||
| +	BCM6362_GROUP(gpio15), | ||||
| +	BCM6362_GROUP(gpio16), | ||||
| +	BCM6362_GROUP(gpio17), | ||||
| +	BCM6362_GROUP(gpio18), | ||||
| +	BCM6362_GROUP(gpio19), | ||||
| +	BCM6362_GROUP(gpio20), | ||||
| +	BCM6362_GROUP(gpio21), | ||||
| +	BCM6362_GROUP(gpio22), | ||||
| +	BCM6362_GROUP(gpio23), | ||||
| +	BCM6362_GROUP(gpio24), | ||||
| +	BCM6362_GROUP(gpio25), | ||||
| +	BCM6362_GROUP(gpio26), | ||||
| +	BCM6362_GROUP(gpio27), | ||||
| +	BCM6362_GROUP(gpio28), | ||||
| +	BCM6362_GROUP(gpio29), | ||||
| +	BCM6362_GROUP(gpio30), | ||||
| +	BCM6362_GROUP(gpio31), | ||||
| +	BCM6362_GROUP(gpio32), | ||||
| +	BCM6362_GROUP(gpio33), | ||||
| +	BCM6362_GROUP(gpio34), | ||||
| +	BCM6362_GROUP(gpio35), | ||||
| +	BCM6362_GROUP(gpio36), | ||||
| +	BCM6362_GROUP(gpio37), | ||||
| +	BCM6362_GROUP(gpio38), | ||||
| +	BCM6362_GROUP(gpio39), | ||||
| +	BCM6362_GROUP(gpio40), | ||||
| +	BCM6362_GROUP(gpio41), | ||||
| +	BCM6362_GROUP(gpio42), | ||||
| +	BCM6362_GROUP(gpio43), | ||||
| +	BCM6362_GROUP(gpio44), | ||||
| +	BCM6362_GROUP(gpio45), | ||||
| +	BCM6362_GROUP(gpio46), | ||||
| +	BCM6362_GROUP(gpio47), | ||||
| +	BCM6362_GROUP(nand_grp), | ||||
| +}; | ||||
| + | ||||
| +static const char * const led_groups[] = { | ||||
| +	"gpio0", | ||||
| +	"gpio1", | ||||
| +	"gpio2", | ||||
| +	"gpio3", | ||||
| +	"gpio4", | ||||
| +	"gpio5", | ||||
| +	"gpio6", | ||||
| +	"gpio7", | ||||
| +	"gpio8", | ||||
| +	"gpio9", | ||||
| +	"gpio10", | ||||
| +	"gpio11", | ||||
| +	"gpio12", | ||||
| +	"gpio13", | ||||
| +	"gpio14", | ||||
| +	"gpio15", | ||||
| +	"gpio16", | ||||
| +	"gpio17", | ||||
| +	"gpio18", | ||||
| +	"gpio19", | ||||
| +	"gpio20", | ||||
| +	"gpio21", | ||||
| +	"gpio22", | ||||
| +	"gpio23", | ||||
| +}; | ||||
| + | ||||
| +static const char * const usb_device_led_groups[] = { | ||||
| +	"gpio0", | ||||
| +}; | ||||
| + | ||||
| +static const char * const sys_irq_groups[] = { | ||||
| +	"gpio1", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_clk_groups[] = { | ||||
| +	"gpio2", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_data_groups[] = { | ||||
| +	"gpio3", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led_data_groups[] = { | ||||
| +	"gpio4", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led_clk_groups[] = { | ||||
| +	"gpio5", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led0_groups[] = { | ||||
| +	"gpio6", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led1_groups[] = { | ||||
| +	"gpio7", | ||||
| +}; | ||||
| + | ||||
| +static const char * const inet_led_groups[] = { | ||||
| +	"gpio8", | ||||
| +}; | ||||
| + | ||||
| +static const char * const spi_cs2_groups[] = { | ||||
| +	"gpio9", | ||||
| +}; | ||||
| + | ||||
| +static const char * const spi_cs3_groups[] = { | ||||
| +	"gpio10", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ntr_pulse_groups[] = { | ||||
| +	"gpio11", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_scts_groups[] = { | ||||
| +	"gpio12", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_srts_groups[] = { | ||||
| +	"gpio13", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_sdin_groups[] = { | ||||
| +	"gpio14", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_sdout_groups[] = { | ||||
| +	"gpio15", | ||||
| +}; | ||||
| + | ||||
| +static const char * const adsl_spi_miso_groups[] = { | ||||
| +	"gpio16", | ||||
| +}; | ||||
| + | ||||
| +static const char * const adsl_spi_mosi_groups[] = { | ||||
| +	"gpio17", | ||||
| +}; | ||||
| + | ||||
| +static const char * const adsl_spi_clk_groups[] = { | ||||
| +	"gpio18", | ||||
| +}; | ||||
| + | ||||
| +static const char * const adsl_spi_cs_groups[] = { | ||||
| +	"gpio19", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy0_led_groups[] = { | ||||
| +	"gpio20", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy1_led_groups[] = { | ||||
| +	"gpio21", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy2_led_groups[] = { | ||||
| +	"gpio22", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy3_led_groups[] = { | ||||
| +	"gpio23", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ext_irq0_groups[] = { | ||||
| +	"gpio24", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ext_irq1_groups[] = { | ||||
| +	"gpio25", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ext_irq2_groups[] = { | ||||
| +	"gpio26", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ext_irq3_groups[] = { | ||||
| +	"gpio27", | ||||
| +}; | ||||
| + | ||||
| +static const char * const wifi_groups[] = { | ||||
| +	"gpio32", | ||||
| +	"gpio33", | ||||
| +	"gpio34", | ||||
| +	"gpio35", | ||||
| +	"gpio36", | ||||
| +	"gpio37", | ||||
| +	"gpio38", | ||||
| +	"gpio39", | ||||
| +	"gpio40", | ||||
| +	"gpio41", | ||||
| +	"gpio42", | ||||
| +	"gpio43", | ||||
| +	"gpio44", | ||||
| +	"gpio45", | ||||
| +	"gpio46", | ||||
| +	"gpio47", | ||||
| +}; | ||||
| + | ||||
| +static const char * const nand_groups[] = { | ||||
| +	"nand_grp", | ||||
| +}; | ||||
| + | ||||
| +#define BCM6362_LED_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM6362_LEDCTRL,			\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM6362_MODE_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM6362_MODE,			\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM6362_CTRL_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM6362_CTRL,			\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM6362_BASEMODE_FUN(n, mask)			\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM6362_BASEMODE,		\ | ||||
| +		.basemode_mask = (mask),		\ | ||||
| +	} | ||||
| + | ||||
| +static const struct bcm6362_function bcm6362_funcs[] = { | ||||
| +	BCM6362_LED_FUN(led), | ||||
| +	BCM6362_MODE_FUN(usb_device_led), | ||||
| +	BCM6362_MODE_FUN(sys_irq), | ||||
| +	BCM6362_MODE_FUN(serial_led_clk), | ||||
| +	BCM6362_MODE_FUN(serial_led_data), | ||||
| +	BCM6362_MODE_FUN(robosw_led_data), | ||||
| +	BCM6362_MODE_FUN(robosw_led_clk), | ||||
| +	BCM6362_MODE_FUN(robosw_led0), | ||||
| +	BCM6362_MODE_FUN(robosw_led1), | ||||
| +	BCM6362_MODE_FUN(inet_led), | ||||
| +	BCM6362_MODE_FUN(spi_cs2), | ||||
| +	BCM6362_MODE_FUN(spi_cs3), | ||||
| +	BCM6362_MODE_FUN(ntr_pulse), | ||||
| +	BCM6362_MODE_FUN(uart1_scts), | ||||
| +	BCM6362_MODE_FUN(uart1_srts), | ||||
| +	BCM6362_MODE_FUN(uart1_sdin), | ||||
| +	BCM6362_MODE_FUN(uart1_sdout), | ||||
| +	BCM6362_MODE_FUN(adsl_spi_miso), | ||||
| +	BCM6362_MODE_FUN(adsl_spi_mosi), | ||||
| +	BCM6362_MODE_FUN(adsl_spi_clk), | ||||
| +	BCM6362_MODE_FUN(adsl_spi_cs), | ||||
| +	BCM6362_MODE_FUN(ephy0_led), | ||||
| +	BCM6362_MODE_FUN(ephy1_led), | ||||
| +	BCM6362_MODE_FUN(ephy2_led), | ||||
| +	BCM6362_MODE_FUN(ephy3_led), | ||||
| +	BCM6362_MODE_FUN(ext_irq0), | ||||
| +	BCM6362_MODE_FUN(ext_irq1), | ||||
| +	BCM6362_MODE_FUN(ext_irq2), | ||||
| +	BCM6362_MODE_FUN(ext_irq3), | ||||
| +	BCM6362_CTRL_FUN(wifi), | ||||
| +	BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND), | ||||
| +}; | ||||
| + | ||||
| +static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6362_groups); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||||
| +						  unsigned group) | ||||
| +{ | ||||
| +	return bcm6362_groups[group].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||||
| +					  unsigned group, const unsigned **pins, | ||||
| +					  unsigned *num_pins) | ||||
| +{ | ||||
| +	*pins = bcm6362_groups[group].pins; | ||||
| +	*num_pins = bcm6362_groups[group].num_pins; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6362_funcs); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev, | ||||
| +						 unsigned selector) | ||||
| +{ | ||||
| +	return bcm6362_funcs[selector].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev, | ||||
| +				      unsigned selector, | ||||
| +				      const char * const **groups, | ||||
| +				      unsigned * const num_groups) | ||||
| +{ | ||||
| +	*groups = bcm6362_funcs[selector].groups; | ||||
| +	*num_groups = bcm6362_funcs[selector].num_groups; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void bcm6362_rmw_mux(struct bcm6362_pinctrl *pctl, void __iomem *reg, | ||||
| +			    u32 mask, u32 val) | ||||
| +{ | ||||
| +	unsigned long flags; | ||||
| +	u32 tmp; | ||||
| + | ||||
| +	spin_lock_irqsave(&pctl->lock, flags); | ||||
| +	tmp = __raw_readl(reg); | ||||
| +	tmp &= ~mask; | ||||
| +	tmp |= val & mask; | ||||
| +	__raw_writel(tmp, reg); | ||||
| + | ||||
| +	spin_unlock_irqrestore(&pctl->lock, flags); | ||||
| +} | ||||
| + | ||||
| +static void bcm6362_set_gpio(struct bcm6362_pinctrl *pctl, unsigned pin) | ||||
| +{ | ||||
| +	const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin]; | ||||
| +	u32 mask = BIT(pin % 32); | ||||
| + | ||||
| +	if (desc->drv_data) | ||||
| +		bcm6362_rmw_mux(pctl, pctl->basemode, (u32)desc->drv_data, 0); | ||||
| + | ||||
| +	if (pin < 32) { | ||||
| +		/* base mode 0 => gpio 1 => mux function */ | ||||
| +		bcm6362_rmw_mux(pctl, pctl->mode, mask, 0); | ||||
| + | ||||
| +		/* pins 0-23 might be muxed to led */ | ||||
| +		if (pin < 24) | ||||
| +			bcm6362_rmw_mux(pctl, pctl->led, mask, 0); | ||||
| +	} else { | ||||
| +		/* ctrl reg 0 => wifi function 1 => gpio */ | ||||
| +		bcm6362_rmw_mux(pctl, pctl->ctrl, mask, mask); | ||||
| +	} | ||||
| +} | ||||
| + | ||||
| +static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev, | ||||
| +				   unsigned selector, unsigned group) | ||||
| +{ | ||||
| +	struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	const struct bcm6362_pingroup *grp = &bcm6362_groups[group]; | ||||
| +	const struct bcm6362_function *f = &bcm6362_funcs[selector]; | ||||
| +	unsigned i; | ||||
| +	void __iomem *reg; | ||||
| +	u32 val, mask; | ||||
| + | ||||
| +	for (i = 0; i < grp->num_pins; i++) | ||||
| +		bcm6362_set_gpio(pctl, grp->pins[i]); | ||||
| + | ||||
| +	switch (f->reg) { | ||||
| +	case BCM6362_LEDCTRL: | ||||
| +		reg = pctl->led; | ||||
| +		mask = BIT(grp->pins[0]); | ||||
| +		val = BIT(grp->pins[0]); | ||||
| +		break; | ||||
| +	case BCM6362_MODE: | ||||
| +		reg = pctl->mode; | ||||
| +		mask = BIT(grp->pins[0]); | ||||
| +		val = BIT(grp->pins[0]); | ||||
| +		break; | ||||
| +	case BCM6362_CTRL: | ||||
| +		reg = pctl->ctrl; | ||||
| +		mask = BIT(grp->pins[0]); | ||||
| +		val = 0; | ||||
| +		break; | ||||
| +	case BCM6362_BASEMODE: | ||||
| +		reg = pctl->basemode; | ||||
| +		mask = f->basemode_mask; | ||||
| +		val = f->basemode_mask; | ||||
| +		break; | ||||
| +	default: | ||||
| +		WARN_ON(1); | ||||
| +		return -EINVAL; | ||||
| +	} | ||||
| + | ||||
| +	bcm6362_rmw_mux(pctl, reg, mask, val); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev, | ||||
| +				       struct pinctrl_gpio_range *range, | ||||
| +				       unsigned offset) | ||||
| +{ | ||||
| +	struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| + | ||||
| +	/* disable all functions using this pin */ | ||||
| +	bcm6362_set_gpio(pctl, offset); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct pinctrl_ops bcm6362_pctl_ops = { | ||||
| +	.get_groups_count	= bcm6362_pinctrl_get_group_count, | ||||
| +	.get_group_name		= bcm6362_pinctrl_get_group_name, | ||||
| +	.get_group_pins		= bcm6362_pinctrl_get_group_pins, | ||||
| +#ifdef CONFIG_OF | ||||
| +	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin, | ||||
| +	.dt_free_map		= pinctrl_utils_free_map, | ||||
| +#endif | ||||
| +}; | ||||
| + | ||||
| +static struct pinmux_ops bcm6362_pmx_ops = { | ||||
| +	.get_functions_count	= bcm6362_pinctrl_get_func_count, | ||||
| +	.get_function_name	= bcm6362_pinctrl_get_func_name, | ||||
| +	.get_function_groups	= bcm6362_pinctrl_get_groups, | ||||
| +	.set_mux		= bcm6362_pinctrl_set_mux, | ||||
| +	.gpio_request_enable	= bcm6362_gpio_request_enable, | ||||
| +	.strict			= true, | ||||
| +}; | ||||
| + | ||||
| +static int bcm6362_pinctrl_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct bcm6362_pinctrl *pctl; | ||||
| +	struct resource *res; | ||||
| +	void __iomem *led, *mode, *ctrl, *basemode; | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led"); | ||||
| +	led = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(led)) | ||||
| +		return PTR_ERR(led); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); | ||||
| +	mode = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(mode)) | ||||
| +		return PTR_ERR(mode); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); | ||||
| +	ctrl = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(ctrl)) | ||||
| +		return PTR_ERR(ctrl); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode"); | ||||
| +	basemode = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(basemode)) | ||||
| +		return PTR_ERR(basemode); | ||||
| + | ||||
| +	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); | ||||
| +	if (!pctl) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	spin_lock_init(&pctl->lock); | ||||
| + | ||||
| +	pctl->led = led; | ||||
| +	pctl->mode = mode; | ||||
| +	pctl->ctrl = ctrl; | ||||
| +	pctl->basemode = basemode; | ||||
| + | ||||
| +	pctl->desc.name = dev_name(&pdev->dev); | ||||
| +	pctl->desc.owner = THIS_MODULE; | ||||
| +	pctl->desc.pctlops = &bcm6362_pctl_ops; | ||||
| +	pctl->desc.pmxops = &bcm6362_pmx_ops; | ||||
| + | ||||
| +	pctl->desc.npins = ARRAY_SIZE(bcm6362_pins); | ||||
| +	pctl->desc.pins = bcm6362_pins; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, pctl); | ||||
| + | ||||
| +	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, | ||||
| +						 pctl->gpio, BCM6362_NGPIO); | ||||
| +	if (IS_ERR(pctl->pctldev)) | ||||
| +		return PTR_ERR(pctl->pctldev); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id bcm6362_pinctrl_match[] = { | ||||
| +	{ .compatible = "brcm,bcm6362-pinctrl", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_driver bcm6362_pinctrl_driver = { | ||||
| +	.probe = bcm6362_pinctrl_probe, | ||||
| +	.driver = { | ||||
| +		.name = "bcm6362-pinctrl", | ||||
| +		.of_match_table = bcm6362_pinctrl_match, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +builtin_platform_driver(bcm6362_pinctrl_driver); | ||||
| @@ -0,0 +1,84 @@ | ||||
| From 30594cf9bfff176a9e4b14c50dcd8b9d0cc3edec Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Wed, 27 Jul 2016 11:36:51 +0200 | ||||
| Subject: [PATCH 10/16] Documentation: add BCM6368 pincontroller binding | ||||
|  documentation | ||||
|  | ||||
| Add binding documentation for the pincontrol core found in BCM6368 SoCs. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  .../bindings/pinctrl/brcm,bcm6368-pinctrl.txt      | 67 ++++++++++++++++++++++ | ||||
|  1 file changed, 67 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt | ||||
| @@ -0,0 +1,67 @@ | ||||
| +* Broadcom BCM6368 pin controller | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible: Must be "brcm,bcm6368-pinctrl". | ||||
| +- reg: Register specifiers of dirout, dat, mode registers. | ||||
| +- reg-names: Must be "dirout", "dat", "mode". | ||||
| +- brcm,gpiobasemode: Phandle to the gpio basemode register. | ||||
| +- gpio-controller: Identifies this node as a GPIO controller. | ||||
| +- #gpio-cells: Must be <2>. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +pinctrl: pin-controller@10000080 { | ||||
| +	compatible = "brcm,bcm6368-pinctrl"; | ||||
| +	reg = <0x10000080 0x08>, | ||||
| +	      <0x10000088 0x08>, | ||||
| +	      <0x10000098 0x04>; | ||||
| +	reg-names = "dirout", "dat", "mode"; | ||||
| +	brcm,gpiobasemode = <&gpiobasemode>; | ||||
| + | ||||
| +	gpio-controller; | ||||
| +	#gpio-cells = <2>; | ||||
| +}; | ||||
| + | ||||
| +gpiobasemode: syscon@100000b8 { | ||||
| +	compatible = "brcm,bcm6368-gpiobasemode", "syscon"; | ||||
| +	reg = <0x100000b8 4>; | ||||
| +	native-endian; | ||||
| +}; | ||||
| + | ||||
| +Available pins/groups and functions: | ||||
| + | ||||
| +name		pins	functions | ||||
| +----------------------------------------------------------- | ||||
| +gpio0		0	analog_afe0 | ||||
| +gpio1		1	analog_afe1 | ||||
| +gpio2		2	sys_irq | ||||
| +gpio3		3	serial_led_data | ||||
| +gpio4		4	serial_led_clk | ||||
| +gpio5		5	inet_led | ||||
| +gpio6		6	ephy0_led | ||||
| +gpio7		7	ephy1_led | ||||
| +gpio8		8	ephy2_led | ||||
| +gpio9		9	ephy3_led | ||||
| +gpio10		10	robosw_led_data | ||||
| +gpio11		11	robosw_led_clk | ||||
| +gpio12		12	robosw_led0 | ||||
| +gpio13		13	robosw_led1 | ||||
| +gpio14		14	usb_device_led | ||||
| +gpio15		15	- | ||||
| +gpio16		16	pci_req1 | ||||
| +gpio17		17	pci_gnt1 | ||||
| +gpio18		18	pci_intb | ||||
| +gpio19		19	pci_req0 | ||||
| +gpio20		20	pci_gnt0 | ||||
| +gpio21		21	- | ||||
| +gpio22		22	pcmcia_cd1 | ||||
| +gpio23		23	pcmcia_cd2 | ||||
| +gpio24		24	pcmcia_vs1 | ||||
| +gpio25		25	pcmcia_vs2 | ||||
| +gpio26		26	ebi_cs2 | ||||
| +gpio27		27	ebi_cs3 | ||||
| +gpio28		28	spi_cs2 | ||||
| +gpio29		29	spi_cs3 | ||||
| +gpio30		30	spi_cs4 | ||||
| +gpio31		31	spi_cs5 | ||||
| +uart1_grp	30-33	uart1 | ||||
| @@ -0,0 +1,610 @@ | ||||
| From 90be3cb4f1a45b8be4a4ec264cd66c2f8e893fcb Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Fri, 24 Jun 2016 22:18:25 +0200 | ||||
| Subject: [PATCH 11/16] pinctrl: add a pincontrol driver for BCM6368 | ||||
|  | ||||
| Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32 | ||||
| GPIOs onto alternative functions. Not all are documented. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  drivers/pinctrl/bcm63xx/Kconfig           |  15 + | ||||
|  drivers/pinctrl/bcm63xx/Makefile          |   1 + | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c | 573 ++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 589 insertions(+) | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c | ||||
|  | ||||
| --- a/drivers/pinctrl/bcm63xx/Kconfig | ||||
| +++ b/drivers/pinctrl/bcm63xx/Kconfig | ||||
| @@ -23,3 +23,11 @@ config PINCTRL_BCM6362 | ||||
|  	select PINCONF | ||||
|  	select PINCTRL_BCM63XX | ||||
|  	select GENERIC_PINCONF | ||||
| + | ||||
| +config PINCTRL_BCM6368 | ||||
| +	bool "BCM6368 pincontrol driver" | ||||
| +	select PINMUX | ||||
| +	select PINCONF | ||||
| +	select PINCTRL_BCM63XX | ||||
| +	select GENERIC_PINCONF | ||||
| +	select MFD_SYSCON | ||||
| --- a/drivers/pinctrl/bcm63xx/Makefile | ||||
| +++ b/drivers/pinctrl/bcm63xx/Makefile | ||||
| @@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl | ||||
|  obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o | ||||
| +obj-$(CONFIG_PINCTRL_BCM6368)	+= pinctrl-bcm6368.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c | ||||
| @@ -0,0 +1,570 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/bitops.h> | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/gpio.h> | ||||
| +#include <linux/mfd/syscon.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_address.h> | ||||
| +#include <linux/of_gpio.h> | ||||
| +#include <linux/pinctrl/pinconf.h> | ||||
| +#include <linux/pinctrl/pinconf-generic.h> | ||||
| +#include <linux/pinctrl/pinmux.h> | ||||
| +#include <linux/pinctrl/machine.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/regmap.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/spinlock.h> | ||||
| + | ||||
| +#include "../core.h" | ||||
| +#include "../pinctrl-utils.h" | ||||
| + | ||||
| +#include "pinctrl-bcm63xx.h" | ||||
| + | ||||
| +#define BCM6368_NGPIO	38 | ||||
| + | ||||
| +#define BCM6368_BASEMODE_MASK	0x7 | ||||
| +#define BCM6368_BASEMODE_GPIO	0x0 | ||||
| +#define BCM6368_BASEMODE_UART1	0x1 | ||||
| + | ||||
| +struct bcm6368_pingroup { | ||||
| +	const char *name; | ||||
| +	const unsigned * const pins; | ||||
| +	const unsigned num_pins; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6368_function { | ||||
| +	const char *name; | ||||
| +	const char * const *groups; | ||||
| +	const unsigned num_groups; | ||||
| + | ||||
| +	unsigned dir_out:16; | ||||
| +	unsigned basemode:3; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6368_pinctrl { | ||||
| +	struct pinctrl_dev *pctldev; | ||||
| +	struct pinctrl_desc desc; | ||||
| + | ||||
| +	void __iomem *mode; | ||||
| +	struct regmap_field *overlay; | ||||
| + | ||||
| +	/* register access lock */ | ||||
| +	spinlock_t lock; | ||||
| + | ||||
| +	struct gpio_chip gpio[2]; | ||||
| +}; | ||||
| + | ||||
| +#define BCM6368_BASEMODE_PIN(a, b)		\ | ||||
| +	{					\ | ||||
| +		.number = a,			\ | ||||
| +		.name = b,			\ | ||||
| +		.drv_data = (void *)true	\ | ||||
| +	} | ||||
| + | ||||
| +static const struct pinctrl_pin_desc bcm6368_pins[] = { | ||||
| +	PINCTRL_PIN(0, "gpio0"), | ||||
| +	PINCTRL_PIN(1, "gpio1"), | ||||
| +	PINCTRL_PIN(2, "gpio2"), | ||||
| +	PINCTRL_PIN(3, "gpio3"), | ||||
| +	PINCTRL_PIN(4, "gpio4"), | ||||
| +	PINCTRL_PIN(5, "gpio5"), | ||||
| +	PINCTRL_PIN(6, "gpio6"), | ||||
| +	PINCTRL_PIN(7, "gpio7"), | ||||
| +	PINCTRL_PIN(8, "gpio8"), | ||||
| +	PINCTRL_PIN(9, "gpio9"), | ||||
| +	PINCTRL_PIN(10, "gpio10"), | ||||
| +	PINCTRL_PIN(11, "gpio11"), | ||||
| +	PINCTRL_PIN(12, "gpio12"), | ||||
| +	PINCTRL_PIN(13, "gpio13"), | ||||
| +	PINCTRL_PIN(14, "gpio14"), | ||||
| +	PINCTRL_PIN(15, "gpio15"), | ||||
| +	PINCTRL_PIN(16, "gpio16"), | ||||
| +	PINCTRL_PIN(17, "gpio17"), | ||||
| +	PINCTRL_PIN(18, "gpio18"), | ||||
| +	PINCTRL_PIN(19, "gpio19"), | ||||
| +	PINCTRL_PIN(20, "gpio20"), | ||||
| +	PINCTRL_PIN(21, "gpio21"), | ||||
| +	PINCTRL_PIN(22, "gpio22"), | ||||
| +	PINCTRL_PIN(23, "gpio23"), | ||||
| +	PINCTRL_PIN(24, "gpio24"), | ||||
| +	PINCTRL_PIN(25, "gpio25"), | ||||
| +	PINCTRL_PIN(26, "gpio26"), | ||||
| +	PINCTRL_PIN(27, "gpio27"), | ||||
| +	PINCTRL_PIN(28, "gpio28"), | ||||
| +	PINCTRL_PIN(29, "gpio29"), | ||||
| +	BCM6368_BASEMODE_PIN(30, "gpio30"), | ||||
| +	BCM6368_BASEMODE_PIN(31, "gpio31"), | ||||
| +	BCM6368_BASEMODE_PIN(32, "gpio32"), | ||||
| +	BCM6368_BASEMODE_PIN(33, "gpio33"), | ||||
| +	PINCTRL_PIN(34, "gpio34"), | ||||
| +	PINCTRL_PIN(35, "gpio35"), | ||||
| +	PINCTRL_PIN(36, "gpio36"), | ||||
| +	PINCTRL_PIN(37, "gpio37"), | ||||
| +}; | ||||
| + | ||||
| +static unsigned gpio0_pins[] = { 0 }; | ||||
| +static unsigned gpio1_pins[] = { 1 }; | ||||
| +static unsigned gpio2_pins[] = { 2 }; | ||||
| +static unsigned gpio3_pins[] = { 3 }; | ||||
| +static unsigned gpio4_pins[] = { 4 }; | ||||
| +static unsigned gpio5_pins[] = { 5 }; | ||||
| +static unsigned gpio6_pins[] = { 6 }; | ||||
| +static unsigned gpio7_pins[] = { 7 }; | ||||
| +static unsigned gpio8_pins[] = { 8 }; | ||||
| +static unsigned gpio9_pins[] = { 9 }; | ||||
| +static unsigned gpio10_pins[] = { 10 }; | ||||
| +static unsigned gpio11_pins[] = { 11 }; | ||||
| +static unsigned gpio12_pins[] = { 12 }; | ||||
| +static unsigned gpio13_pins[] = { 13 }; | ||||
| +static unsigned gpio14_pins[] = { 14 }; | ||||
| +static unsigned gpio15_pins[] = { 15 }; | ||||
| +static unsigned gpio16_pins[] = { 16 }; | ||||
| +static unsigned gpio17_pins[] = { 17 }; | ||||
| +static unsigned gpio18_pins[] = { 18 }; | ||||
| +static unsigned gpio19_pins[] = { 19 }; | ||||
| +static unsigned gpio20_pins[] = { 20 }; | ||||
| +static unsigned gpio21_pins[] = { 21 }; | ||||
| +static unsigned gpio22_pins[] = { 22 }; | ||||
| +static unsigned gpio23_pins[] = { 23 }; | ||||
| +static unsigned gpio24_pins[] = { 24 }; | ||||
| +static unsigned gpio25_pins[] = { 25 }; | ||||
| +static unsigned gpio26_pins[] = { 26 }; | ||||
| +static unsigned gpio27_pins[] = { 27 }; | ||||
| +static unsigned gpio28_pins[] = { 28 }; | ||||
| +static unsigned gpio29_pins[] = { 29 }; | ||||
| +static unsigned gpio30_pins[] = { 30 }; | ||||
| +static unsigned gpio31_pins[] = { 31 }; | ||||
| +static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 }; | ||||
| + | ||||
| +#define BCM6368_GROUP(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.pins = n##_pins,			\ | ||||
| +		.num_pins = ARRAY_SIZE(n##_pins),	\ | ||||
| +	} | ||||
| + | ||||
| +static struct bcm6368_pingroup bcm6368_groups[] = { | ||||
| +	BCM6368_GROUP(gpio0), | ||||
| +	BCM6368_GROUP(gpio1), | ||||
| +	BCM6368_GROUP(gpio2), | ||||
| +	BCM6368_GROUP(gpio3), | ||||
| +	BCM6368_GROUP(gpio4), | ||||
| +	BCM6368_GROUP(gpio5), | ||||
| +	BCM6368_GROUP(gpio6), | ||||
| +	BCM6368_GROUP(gpio7), | ||||
| +	BCM6368_GROUP(gpio8), | ||||
| +	BCM6368_GROUP(gpio9), | ||||
| +	BCM6368_GROUP(gpio10), | ||||
| +	BCM6368_GROUP(gpio11), | ||||
| +	BCM6368_GROUP(gpio12), | ||||
| +	BCM6368_GROUP(gpio13), | ||||
| +	BCM6368_GROUP(gpio14), | ||||
| +	BCM6368_GROUP(gpio15), | ||||
| +	BCM6368_GROUP(gpio16), | ||||
| +	BCM6368_GROUP(gpio17), | ||||
| +	BCM6368_GROUP(gpio18), | ||||
| +	BCM6368_GROUP(gpio19), | ||||
| +	BCM6368_GROUP(gpio20), | ||||
| +	BCM6368_GROUP(gpio21), | ||||
| +	BCM6368_GROUP(gpio22), | ||||
| +	BCM6368_GROUP(gpio23), | ||||
| +	BCM6368_GROUP(gpio24), | ||||
| +	BCM6368_GROUP(gpio25), | ||||
| +	BCM6368_GROUP(gpio26), | ||||
| +	BCM6368_GROUP(gpio27), | ||||
| +	BCM6368_GROUP(gpio28), | ||||
| +	BCM6368_GROUP(gpio29), | ||||
| +	BCM6368_GROUP(gpio30), | ||||
| +	BCM6368_GROUP(gpio31), | ||||
| +	BCM6368_GROUP(uart1_grp), | ||||
| +}; | ||||
| + | ||||
| +static const char * const analog_afe_0_groups[] = { | ||||
| +	"gpio0", | ||||
| +}; | ||||
| + | ||||
| +static const char * const analog_afe_1_groups[] = { | ||||
| +	"gpio1", | ||||
| +}; | ||||
| + | ||||
| +static const char * const sys_irq_groups[] = { | ||||
| +	"gpio2", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_data_groups[] = { | ||||
| +	"gpio3", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_clk_groups[] = { | ||||
| +	"gpio4", | ||||
| +}; | ||||
| + | ||||
| +static const char * const inet_led_groups[] = { | ||||
| +	"gpio5", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy0_led_groups[] = { | ||||
| +	"gpio6", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy1_led_groups[] = { | ||||
| +	"gpio7", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy2_led_groups[] = { | ||||
| +	"gpio8", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy3_led_groups[] = { | ||||
| +	"gpio9", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led_data_groups[] = { | ||||
| +	"gpio10", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led_clk_groups[] = { | ||||
| +	"gpio11", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led0_groups[] = { | ||||
| +	"gpio12", | ||||
| +}; | ||||
| + | ||||
| +static const char * const robosw_led1_groups[] = { | ||||
| +	"gpio13", | ||||
| +}; | ||||
| + | ||||
| +static const char * const usb_device_led_groups[] = { | ||||
| +	"gpio14", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pci_req1_groups[] = { | ||||
| +	"gpio16", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pci_gnt1_groups[] = { | ||||
| +	"gpio17", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pci_intb_groups[] = { | ||||
| +	"gpio18", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pci_req0_groups[] = { | ||||
| +	"gpio19", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pci_gnt0_groups[] = { | ||||
| +	"gpio20", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pcmcia_cd1_groups[] = { | ||||
| +	"gpio22", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pcmcia_cd2_groups[] = { | ||||
| +	"gpio23", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pcmcia_vs1_groups[] = { | ||||
| +	"gpio24", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pcmcia_vs2_groups[] = { | ||||
| +	"gpio25", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ebi_cs2_groups[] = { | ||||
| +	"gpio26", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ebi_cs3_groups[] = { | ||||
| +	"gpio27", | ||||
| +}; | ||||
| + | ||||
| +static const char * const spi_cs2_groups[] = { | ||||
| +	"gpio28", | ||||
| +}; | ||||
| + | ||||
| +static const char * const spi_cs3_groups[] = { | ||||
| +	"gpio29", | ||||
| +}; | ||||
| + | ||||
| +static const char * const spi_cs4_groups[] = { | ||||
| +	"gpio30", | ||||
| +}; | ||||
| + | ||||
| +static const char * const spi_cs5_groups[] = { | ||||
| +	"gpio31", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_groups[] = { | ||||
| +	"uart1_grp", | ||||
| +}; | ||||
| + | ||||
| +#define BCM6368_FUN(n, out)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.dir_out = out,				\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM6368_BASEMODE_FUN(n, val, out)		\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.basemode = BCM6368_BASEMODE_##val,	\ | ||||
| +		.dir_out = out,				\ | ||||
| +	} | ||||
| + | ||||
| +static const struct bcm6368_function bcm6368_funcs[] = { | ||||
| +	BCM6368_FUN(analog_afe_0, 1), | ||||
| +	BCM6368_FUN(analog_afe_1, 1), | ||||
| +	BCM6368_FUN(sys_irq, 1), | ||||
| +	BCM6368_FUN(serial_led_data, 1), | ||||
| +	BCM6368_FUN(serial_led_clk, 1), | ||||
| +	BCM6368_FUN(inet_led, 1), | ||||
| +	BCM6368_FUN(ephy0_led, 1), | ||||
| +	BCM6368_FUN(ephy1_led, 1), | ||||
| +	BCM6368_FUN(ephy2_led, 1), | ||||
| +	BCM6368_FUN(ephy3_led, 1), | ||||
| +	BCM6368_FUN(robosw_led_data, 1), | ||||
| +	BCM6368_FUN(robosw_led_clk, 1), | ||||
| +	BCM6368_FUN(robosw_led0, 1), | ||||
| +	BCM6368_FUN(robosw_led1, 1), | ||||
| +	BCM6368_FUN(usb_device_led, 1), | ||||
| +	BCM6368_FUN(pci_req1, 0), | ||||
| +	BCM6368_FUN(pci_gnt1, 0), | ||||
| +	BCM6368_FUN(pci_intb, 0), | ||||
| +	BCM6368_FUN(pci_req0, 0), | ||||
| +	BCM6368_FUN(pci_gnt0, 0), | ||||
| +	BCM6368_FUN(pcmcia_cd1, 0), | ||||
| +	BCM6368_FUN(pcmcia_cd2, 0), | ||||
| +	BCM6368_FUN(pcmcia_vs1, 0), | ||||
| +	BCM6368_FUN(pcmcia_vs2, 0), | ||||
| +	BCM6368_FUN(ebi_cs2, 1), | ||||
| +	BCM6368_FUN(ebi_cs3, 1), | ||||
| +	BCM6368_FUN(spi_cs2, 1), | ||||
| +	BCM6368_FUN(spi_cs3, 1), | ||||
| +	BCM6368_FUN(spi_cs4, 1), | ||||
| +	BCM6368_FUN(spi_cs5, 1), | ||||
| +	BCM6368_BASEMODE_FUN(uart1, UART1, 0x6), | ||||
| +}; | ||||
| + | ||||
| +static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6368_groups); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||||
| +						  unsigned group) | ||||
| +{ | ||||
| +	return bcm6368_groups[group].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||||
| +					  unsigned group, const unsigned **pins, | ||||
| +					  unsigned *num_pins) | ||||
| +{ | ||||
| +	*pins = bcm6368_groups[group].pins; | ||||
| +	*num_pins = bcm6368_groups[group].num_pins; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6368_funcs); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev *pctldev, | ||||
| +						 unsigned selector) | ||||
| +{ | ||||
| +	return bcm6368_funcs[selector].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6368_pinctrl_get_groups(struct pinctrl_dev *pctldev, | ||||
| +				      unsigned selector, | ||||
| +				      const char * const **groups, | ||||
| +				      unsigned * const num_groups) | ||||
| +{ | ||||
| +	*groups = bcm6368_funcs[selector].groups; | ||||
| +	*num_groups = bcm6368_funcs[selector].num_groups; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void bcm6368_rmw_mux(struct bcm6368_pinctrl *pctl, void __iomem *reg, | ||||
| +			    u32 mask, u32 val) | ||||
| +{ | ||||
| +	u32 tmp; | ||||
| + | ||||
| +	tmp = __raw_readl(reg); | ||||
| +	tmp &= ~mask; | ||||
| +	tmp |= (val & mask); | ||||
| +	__raw_writel(tmp, reg); | ||||
| +} | ||||
| + | ||||
| +static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, | ||||
| +				   unsigned selector, unsigned group) | ||||
| +{ | ||||
| +	struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	const struct bcm6368_pingroup *grp = &bcm6368_groups[group]; | ||||
| +	const struct bcm6368_function *fun = &bcm6368_funcs[selector]; | ||||
| +	unsigned long flags; | ||||
| +	int i, pin; | ||||
| + | ||||
| +	spin_lock_irqsave(&pctl->lock, flags); | ||||
| +	if (fun->basemode) { | ||||
| +		u32 mask = 0; | ||||
| + | ||||
| +		for (i = 0; i < grp->num_pins; i++) { | ||||
| +			pin = grp->pins[i]; | ||||
| +			if (pin < 32) | ||||
| +				mask |= BIT(pin); | ||||
| +		} | ||||
| + | ||||
| +		bcm6368_rmw_mux(pctl, pctl->mode, mask, 0); | ||||
| +		regmap_field_write(pctl->overlay, fun->basemode); | ||||
| +	} else { | ||||
| +		pin = grp->pins[0]; | ||||
| + | ||||
| +		if (bcm6368_pins[pin].drv_data) | ||||
| +			regmap_field_write(pctl->overlay, | ||||
| +					   BCM6368_BASEMODE_GPIO); | ||||
| + | ||||
| +		bcm6368_rmw_mux(pctl, pctl->mode, BIT(pin), BIT(pin)); | ||||
| +	} | ||||
| +	spin_unlock_irqrestore(&pctl->lock, flags); | ||||
| + | ||||
| +	for (pin = 0; pin < grp->num_pins; pin++) { | ||||
| +		int hw_gpio = bcm6368_pins[pin].number; | ||||
| +		struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32]; | ||||
| + | ||||
| +		if (fun->dir_out & BIT(pin)) | ||||
| +			gc->direction_output(gc, hw_gpio % 32, 0); | ||||
| +		else | ||||
| +			gc->direction_input(gc, hw_gpio % 32); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev, | ||||
| +				       struct pinctrl_gpio_range *range, | ||||
| +				       unsigned offset) | ||||
| +{ | ||||
| +	struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	unsigned long flags; | ||||
| + | ||||
| +	if (offset >= 32 && !bcm6368_pins[offset].drv_data) | ||||
| +		return 0; | ||||
| + | ||||
| +	spin_lock_irqsave(&pctl->lock, flags); | ||||
| +	/* disable all functions using this pin */ | ||||
| +	if (offset < 32) | ||||
| +		bcm6368_rmw_mux(pctl, pctl->mode, BIT(offset), 0); | ||||
| + | ||||
| +	if (bcm6368_pins[offset].drv_data) | ||||
| +		regmap_field_write(pctl->overlay, BCM6368_BASEMODE_GPIO); | ||||
| + | ||||
| +	spin_unlock_irqrestore(&pctl->lock, flags); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct pinctrl_ops bcm6368_pctl_ops = { | ||||
| +	.get_groups_count	= bcm6368_pinctrl_get_group_count, | ||||
| +	.get_group_name		= bcm6368_pinctrl_get_group_name, | ||||
| +	.get_group_pins		= bcm6368_pinctrl_get_group_pins, | ||||
| +#ifdef CONFIG_OF | ||||
| +	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin, | ||||
| +	.dt_free_map		= pinctrl_utils_free_map, | ||||
| +#endif | ||||
| +}; | ||||
| + | ||||
| +static struct pinmux_ops bcm6368_pmx_ops = { | ||||
| +	.get_functions_count	= bcm6368_pinctrl_get_func_count, | ||||
| +	.get_function_name	= bcm6368_pinctrl_get_func_name, | ||||
| +	.get_function_groups	= bcm6368_pinctrl_get_groups, | ||||
| +	.set_mux		= bcm6368_pinctrl_set_mux, | ||||
| +	.gpio_request_enable	= bcm6368_gpio_request_enable, | ||||
| +	.strict			= true, | ||||
| +}; | ||||
| + | ||||
| +static int bcm6368_pinctrl_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct bcm6368_pinctrl *pctl; | ||||
| +	struct resource *res; | ||||
| +	void __iomem *mode; | ||||
| +	struct regmap *basemode; | ||||
| +	struct reg_field overlay = REG_FIELD(0, 0, 3); | ||||
| + | ||||
| +	basemode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | ||||
| +						   "brcm,gpiobasemode"); | ||||
| + | ||||
| +	if (IS_ERR(basemode)) | ||||
| +		return PTR_ERR(basemode); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); | ||||
| +	mode = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(mode)) | ||||
| +		return PTR_ERR(mode); | ||||
| + | ||||
| +	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); | ||||
| +	if (!pctl) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	pctl->overlay = devm_regmap_field_alloc(&pdev->dev, basemode, overlay); | ||||
| +	if (IS_ERR(pctl->overlay)) | ||||
| +		return PTR_ERR(pctl->overlay); | ||||
| + | ||||
| +	spin_lock_init(&pctl->lock); | ||||
| + | ||||
| +	pctl->mode = mode; | ||||
| + | ||||
| +	/* disable all muxes by default */ | ||||
| +	__raw_writel(0, pctl->mode); | ||||
| + | ||||
| +	pctl->desc.name = dev_name(&pdev->dev); | ||||
| +	pctl->desc.owner = THIS_MODULE; | ||||
| +	pctl->desc.pctlops = &bcm6368_pctl_ops; | ||||
| +	pctl->desc.pmxops = &bcm6368_pmx_ops; | ||||
| + | ||||
| +	pctl->desc.npins = ARRAY_SIZE(bcm6368_pins); | ||||
| +	pctl->desc.pins = bcm6368_pins; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, pctl); | ||||
| + | ||||
| +	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, | ||||
| +						 pctl->gpio, BCM6368_NGPIO); | ||||
| +	if (IS_ERR(pctl->pctldev)) | ||||
| +		return PTR_ERR(pctl->pctldev); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id bcm6368_pinctrl_match[] = { | ||||
| +	{ .compatible = "brcm,bcm6368-pinctrl", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_driver bcm6368_pinctrl_driver = { | ||||
| +	.probe = bcm6368_pinctrl_probe, | ||||
| +	.driver = { | ||||
| +		.name = "bcm6368-pinctrl", | ||||
| +		.of_match_table = bcm6368_pinctrl_match, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +builtin_platform_driver(bcm6368_pinctrl_driver); | ||||
| @@ -0,0 +1,106 @@ | ||||
| From 28cc80e4ada5d73d5305fd268297825cd8d01936 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Wed, 27 Jul 2016 11:37:08 +0200 | ||||
| Subject: [PATCH 12/16] Documentation: add BCM63268 pincontroller binding | ||||
|  documentation | ||||
|  | ||||
| Add binding documentation for the pincontrol core found in the BCM63268 | ||||
| family SoCs. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  .../bindings/pinctrl/brcm,bcm63268-pinctrl.txt     | 88 ++++++++++++++++++++++ | ||||
|  1 file changed, 88 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt | ||||
| @@ -0,0 +1,88 @@ | ||||
| +* Broadcom BCM63268 pin controller | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible: Must be "brcm,bcm6362-pinctrl". | ||||
| +- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers. | ||||
| +- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode". | ||||
| +- gpio-controller: Identifies this node as a GPIO controller. | ||||
| +- #gpio-cells: Must be <2>. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +pinctrl: pin-controller@100000c0 { | ||||
| +	compatible = "brcm,bcm63268-pinctrl"; | ||||
| +	reg = <0x100000c0 0x8>, | ||||
| +	      <0x100000c8 0x8>, | ||||
| +	      <0x100000d0 0x4>, | ||||
| +	      <0x100000d8 0x4>, | ||||
| +	      <0x100000dc 0x4>, | ||||
| +	      <0x100000f8 0x4>; | ||||
| +	reg-names = "dirout", "dat", "led", "mode", | ||||
| +		    "ctrl", "basemode"; | ||||
| + | ||||
| +	gpio-controller; | ||||
| +	#gpio-cells = <2>; | ||||
| +}; | ||||
| + | ||||
| +Available pins/groups and functions: | ||||
| + | ||||
| +name		pins		functions | ||||
| +----------------------------------------------------------- | ||||
| +gpio0		0		led, serial_led_clk | ||||
| +gpio1		1		led, serial_led_data | ||||
| +gpio2		2		led, | ||||
| +gpio3		3		led, | ||||
| +gpio4		4		led, | ||||
| +gpio5		5		led, | ||||
| +gpio6		6		led, | ||||
| +gpio7		7		led, | ||||
| +gpio8		8		led, hsspi_cs6 | ||||
| +gpio9		9		led, hsspi_cs7 | ||||
| +gpio10		10		led, uart1_scts | ||||
| +gpio11		11		led, uart1_srts | ||||
| +gpio12		12		led, uart1_sdin | ||||
| +gpio13		13		led, uart1_sdout | ||||
| +gpio14		14		led, ntr_pulse_in | ||||
| +gpio15		15		led, dsl_ntr_pulse_out | ||||
| +gpio16		16		led, hsspi_cs4 | ||||
| +gpio17		17		led, hsspi_cs5 | ||||
| +gpio18		18		led, adsl_spi_miso | ||||
| +gpio19		19		led, adsl_spi_mosi | ||||
| +gpio20		20		led, | ||||
| +gpio21		21		led, | ||||
| +gpio22		22		led, vreg_clk | ||||
| +gpio23		23		led, pcie_clkreq_b | ||||
| +gpio24		24		uart1_scts | ||||
| +gpio25		25		uart1_srts | ||||
| +gpio26		26		uart1_sdin | ||||
| +gpio27		27		uart1_sdout | ||||
| +gpio28		28		ntr_pulse_in | ||||
| +gpio29		29		dsl_ntr_pulse_out | ||||
| +gpio30		30		switch_led_clk | ||||
| +gpio31		31		switch_led_data | ||||
| +gpio32		32		wifi | ||||
| +gpio33		33		wifi | ||||
| +gpio34		34		wifi | ||||
| +gpio35		35		wifi | ||||
| +gpio36		36		wifi | ||||
| +gpio37		37		wifi | ||||
| +gpio38		38		wifi | ||||
| +gpio39		39		wifi | ||||
| +gpio40		40		wifi | ||||
| +gpio41		41		wifi | ||||
| +gpio42		42		wifi | ||||
| +gpio43		43		wifi | ||||
| +gpio44		44		wifi | ||||
| +gpio45		45		wifi | ||||
| +gpio46		46		wifi | ||||
| +gpio47		47		wifi | ||||
| +gpio48		48		wifi | ||||
| +gpio49		49		wifi | ||||
| +gpio50		50		wifi | ||||
| +gpio51		51		wifi | ||||
| +nand_grp	2-7,24-31	nand | ||||
| +dect_pd_grp	8-9		dect_pd | ||||
| +vdsl_phy0_grp	10-11		vdsl_phy0 | ||||
| +vdsl_phy1_grp	12-13		vdsl_phy1 | ||||
| +vdsl_phy2_grp	24-25		vdsl_phy2 | ||||
| +vdsl_phy3_grp	26-27		vdsl_phy3 | ||||
| @@ -0,0 +1,749 @@ | ||||
| From 8665d3ea63649cc155286c75f83f694a930580e5 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Fri, 24 Jun 2016 22:19:12 +0200 | ||||
| Subject: [PATCH 13/16] pinctrl: add a pincontrol driver for BCM63268 | ||||
|  | ||||
| Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs | ||||
| to different functions. Depending on the mux, these are either single | ||||
| pin configurations or whole pin groups. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  drivers/pinctrl/bcm63xx/Makefile           |   1 + | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c | 710 +++++++++++++++++++++++++++++ | ||||
|  2 files changed, 711 insertions(+) | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c | ||||
|  | ||||
| --- a/drivers/pinctrl/bcm63xx/Kconfig | ||||
| +++ b/drivers/pinctrl/bcm63xx/Kconfig | ||||
| @@ -31,3 +31,10 @@ config PINCTRL_BCM6368 | ||||
|  	select PINCTRL_BCM63XX | ||||
|  	select GENERIC_PINCONF | ||||
|  	select MFD_SYSCON | ||||
| + | ||||
| +config PINCTRL_BCM63268 | ||||
| +	bool "BCM63268 pincontrol driver" | ||||
| +	select PINMUX | ||||
| +	select PINCONF | ||||
| +	select PINCTRL_BCM63XX | ||||
| +	select GENERIC_PINCONF | ||||
| --- a/drivers/pinctrl/bcm63xx/Makefile | ||||
| +++ b/drivers/pinctrl/bcm63xx/Makefile | ||||
| @@ -3,3 +3,4 @@ obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl | ||||
|  obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6368)	+= pinctrl-bcm6368.o | ||||
| +obj-$(CONFIG_PINCTRL_BCM63268)	+= pinctrl-bcm63268.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c | ||||
| @@ -0,0 +1,710 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/spinlock.h> | ||||
| +#include <linux/bitops.h> | ||||
| +#include <linux/gpio.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_gpio.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#include <linux/pinctrl/pinconf.h> | ||||
| +#include <linux/pinctrl/pinconf-generic.h> | ||||
| +#include <linux/pinctrl/pinmux.h> | ||||
| +#include <linux/pinctrl/machine.h> | ||||
| + | ||||
| +#include "../core.h" | ||||
| +#include "../pinctrl-utils.h" | ||||
| + | ||||
| +#include "pinctrl-bcm63xx.h" | ||||
| + | ||||
| +#define BCM63268_NGPIO			52 | ||||
| + | ||||
| +/* GPIO_BASEMODE register */ | ||||
| +#define BASEMODE_NAND			BIT(2) /* GPIOs 2-7, 24-31 */ | ||||
| +#define BASEMODE_GPIO35			BIT(4) /* GPIO 35 */ | ||||
| +#define BASEMODE_DECTPD			BIT(5) /* GPIOs 8/9 */ | ||||
| +#define BASEMODE_VDSL_PHY_0		BIT(6) /* GPIOs 10/11 */ | ||||
| +#define BASEMODE_VDSL_PHY_1		BIT(7) /* GPIOs 12/13 */ | ||||
| +#define BASEMODE_VDSL_PHY_2		BIT(8) /* GPIOs 24/25 */ | ||||
| +#define BASEMODE_VDSL_PHY_3		BIT(9) /* GPIOs 26/27 */ | ||||
| + | ||||
| +enum bcm63268_pinctrl_reg { | ||||
| +	BCM63268_LEDCTRL, | ||||
| +	BCM63268_MODE, | ||||
| +	BCM63268_CTRL, | ||||
| +	BCM63268_BASEMODE, | ||||
| +}; | ||||
| + | ||||
| +struct bcm63268_pingroup { | ||||
| +	const char *name; | ||||
| +	const unsigned * const pins; | ||||
| +	const unsigned num_pins; | ||||
| +}; | ||||
| + | ||||
| +struct bcm63268_function { | ||||
| +	const char *name; | ||||
| +	const char * const *groups; | ||||
| +	const unsigned num_groups; | ||||
| + | ||||
| +	enum bcm63268_pinctrl_reg reg; | ||||
| +	u32 mask; | ||||
| +}; | ||||
| + | ||||
| +struct bcm63268_pinctrl { | ||||
| +	struct pinctrl_dev *pctldev; | ||||
| +	struct pinctrl_desc desc; | ||||
| + | ||||
| +	void __iomem *led; | ||||
| +	void __iomem *mode; | ||||
| +	void __iomem *ctrl; | ||||
| +	void __iomem *basemode; | ||||
| + | ||||
| +	/* register access lock */ | ||||
| +	spinlock_t lock; | ||||
| + | ||||
| +	struct gpio_chip gpio[2]; | ||||
| +}; | ||||
| + | ||||
| +#define BCM63268_PIN(a, b, basemode)			\ | ||||
| +	{						\ | ||||
| +		.number = a,				\ | ||||
| +		.name = b,				\ | ||||
| +		.drv_data = (void *)(basemode)		\ | ||||
| +	} | ||||
| + | ||||
| +static const struct pinctrl_pin_desc bcm63268_pins[] = { | ||||
| +	PINCTRL_PIN(0, "gpio0"), | ||||
| +	PINCTRL_PIN(1, "gpio1"), | ||||
| +	BCM63268_PIN(2, "gpio2", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(3, "gpio3", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(4, "gpio4", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(5, "gpio5", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(6, "gpio6", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(7, "gpio7", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(8, "gpio8", BASEMODE_DECTPD), | ||||
| +	BCM63268_PIN(9, "gpio9", BASEMODE_DECTPD), | ||||
| +	BCM63268_PIN(10, "gpio10", BASEMODE_VDSL_PHY_0), | ||||
| +	BCM63268_PIN(11, "gpio11", BASEMODE_VDSL_PHY_0), | ||||
| +	BCM63268_PIN(12, "gpio12", BASEMODE_VDSL_PHY_1), | ||||
| +	BCM63268_PIN(13, "gpio13", BASEMODE_VDSL_PHY_1), | ||||
| +	PINCTRL_PIN(14, "gpio14"), | ||||
| +	PINCTRL_PIN(15, "gpio15"), | ||||
| +	PINCTRL_PIN(16, "gpio16"), | ||||
| +	PINCTRL_PIN(17, "gpio17"), | ||||
| +	PINCTRL_PIN(18, "gpio18"), | ||||
| +	PINCTRL_PIN(19, "gpio19"), | ||||
| +	PINCTRL_PIN(20, "gpio20"), | ||||
| +	PINCTRL_PIN(21, "gpio21"), | ||||
| +	PINCTRL_PIN(22, "gpio22"), | ||||
| +	PINCTRL_PIN(23, "gpio23"), | ||||
| +	BCM63268_PIN(24, "gpio24", BASEMODE_NAND | BASEMODE_VDSL_PHY_2), | ||||
| +	BCM63268_PIN(25, "gpio25", BASEMODE_NAND | BASEMODE_VDSL_PHY_2), | ||||
| +	BCM63268_PIN(26, "gpio26", BASEMODE_NAND | BASEMODE_VDSL_PHY_3), | ||||
| +	BCM63268_PIN(27, "gpio27", BASEMODE_NAND | BASEMODE_VDSL_PHY_3), | ||||
| +	BCM63268_PIN(28, "gpio28", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(29, "gpio29", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(30, "gpio30", BASEMODE_NAND), | ||||
| +	BCM63268_PIN(31, "gpio31", BASEMODE_NAND), | ||||
| +	PINCTRL_PIN(32, "gpio32"), | ||||
| +	PINCTRL_PIN(33, "gpio33"), | ||||
| +	PINCTRL_PIN(34, "gpio34"), | ||||
| +	PINCTRL_PIN(35, "gpio35"), | ||||
| +	PINCTRL_PIN(36, "gpio36"), | ||||
| +	PINCTRL_PIN(37, "gpio37"), | ||||
| +	PINCTRL_PIN(38, "gpio38"), | ||||
| +	PINCTRL_PIN(39, "gpio39"), | ||||
| +	PINCTRL_PIN(40, "gpio40"), | ||||
| +	PINCTRL_PIN(41, "gpio41"), | ||||
| +	PINCTRL_PIN(42, "gpio42"), | ||||
| +	PINCTRL_PIN(43, "gpio43"), | ||||
| +	PINCTRL_PIN(44, "gpio44"), | ||||
| +	PINCTRL_PIN(45, "gpio45"), | ||||
| +	PINCTRL_PIN(46, "gpio46"), | ||||
| +	PINCTRL_PIN(47, "gpio47"), | ||||
| +	PINCTRL_PIN(48, "gpio48"), | ||||
| +	PINCTRL_PIN(49, "gpio49"), | ||||
| +	PINCTRL_PIN(50, "gpio50"), | ||||
| +	PINCTRL_PIN(51, "gpio51"), | ||||
| +}; | ||||
| + | ||||
| +static unsigned gpio0_pins[] = { 0 }; | ||||
| +static unsigned gpio1_pins[] = { 1 }; | ||||
| +static unsigned gpio2_pins[] = { 2 }; | ||||
| +static unsigned gpio3_pins[] = { 3 }; | ||||
| +static unsigned gpio4_pins[] = { 4 }; | ||||
| +static unsigned gpio5_pins[] = { 5 }; | ||||
| +static unsigned gpio6_pins[] = { 6 }; | ||||
| +static unsigned gpio7_pins[] = { 7 }; | ||||
| +static unsigned gpio8_pins[] = { 8 }; | ||||
| +static unsigned gpio9_pins[] = { 9 }; | ||||
| +static unsigned gpio10_pins[] = { 10 }; | ||||
| +static unsigned gpio11_pins[] = { 11 }; | ||||
| +static unsigned gpio12_pins[] = { 12 }; | ||||
| +static unsigned gpio13_pins[] = { 13 }; | ||||
| +static unsigned gpio14_pins[] = { 14 }; | ||||
| +static unsigned gpio15_pins[] = { 15 }; | ||||
| +static unsigned gpio16_pins[] = { 16 }; | ||||
| +static unsigned gpio17_pins[] = { 17 }; | ||||
| +static unsigned gpio18_pins[] = { 18 }; | ||||
| +static unsigned gpio19_pins[] = { 19 }; | ||||
| +static unsigned gpio20_pins[] = { 20 }; | ||||
| +static unsigned gpio21_pins[] = { 21 }; | ||||
| +static unsigned gpio22_pins[] = { 22 }; | ||||
| +static unsigned gpio23_pins[] = { 23 }; | ||||
| +static unsigned gpio24_pins[] = { 24 }; | ||||
| +static unsigned gpio25_pins[] = { 25 }; | ||||
| +static unsigned gpio26_pins[] = { 26 }; | ||||
| +static unsigned gpio27_pins[] = { 27 }; | ||||
| +static unsigned gpio28_pins[] = { 28 }; | ||||
| +static unsigned gpio29_pins[] = { 29 }; | ||||
| +static unsigned gpio30_pins[] = { 30 }; | ||||
| +static unsigned gpio31_pins[] = { 31 }; | ||||
| +static unsigned gpio32_pins[] = { 32 }; | ||||
| +static unsigned gpio33_pins[] = { 33 }; | ||||
| +static unsigned gpio34_pins[] = { 34 }; | ||||
| +static unsigned gpio35_pins[] = { 35 }; | ||||
| +static unsigned gpio36_pins[] = { 36 }; | ||||
| +static unsigned gpio37_pins[] = { 37 }; | ||||
| +static unsigned gpio38_pins[] = { 38 }; | ||||
| +static unsigned gpio39_pins[] = { 39 }; | ||||
| +static unsigned gpio40_pins[] = { 40 }; | ||||
| +static unsigned gpio41_pins[] = { 41 }; | ||||
| +static unsigned gpio42_pins[] = { 42 }; | ||||
| +static unsigned gpio43_pins[] = { 43 }; | ||||
| +static unsigned gpio44_pins[] = { 44 }; | ||||
| +static unsigned gpio45_pins[] = { 45 }; | ||||
| +static unsigned gpio46_pins[] = { 46 }; | ||||
| +static unsigned gpio47_pins[] = { 47 }; | ||||
| +static unsigned gpio48_pins[] = { 48 }; | ||||
| +static unsigned gpio49_pins[] = { 49 }; | ||||
| +static unsigned gpio50_pins[] = { 50 }; | ||||
| +static unsigned gpio51_pins[] = { 51 }; | ||||
| + | ||||
| +static unsigned nand_grp_pins[] = { | ||||
| +	2, 3, 4, 5, 6, 7, 24, | ||||
| +	25, 26, 27, 28, 29, 30, 31, | ||||
| +}; | ||||
| + | ||||
| +static unsigned dectpd_grp_pins[] = { 8, 9 }; | ||||
| +static unsigned vdsl_phy0_grp_pins[] = { 10, 11 }; | ||||
| +static unsigned vdsl_phy1_grp_pins[] = { 12, 13 }; | ||||
| +static unsigned vdsl_phy2_grp_pins[] = { 24, 25 }; | ||||
| +static unsigned vdsl_phy3_grp_pins[] = { 26, 27 }; | ||||
| + | ||||
| +#define BCM63268_GROUP(n)					\ | ||||
| +	{							\ | ||||
| +		.name = #n,					\ | ||||
| +		.pins = n##_pins,				\ | ||||
| +		.num_pins = ARRAY_SIZE(n##_pins),		\ | ||||
| +	} | ||||
| + | ||||
| +static struct bcm63268_pingroup bcm63268_groups[] = { | ||||
| +	BCM63268_GROUP(gpio0), | ||||
| +	BCM63268_GROUP(gpio1), | ||||
| +	BCM63268_GROUP(gpio2), | ||||
| +	BCM63268_GROUP(gpio3), | ||||
| +	BCM63268_GROUP(gpio4), | ||||
| +	BCM63268_GROUP(gpio5), | ||||
| +	BCM63268_GROUP(gpio6), | ||||
| +	BCM63268_GROUP(gpio7), | ||||
| +	BCM63268_GROUP(gpio8), | ||||
| +	BCM63268_GROUP(gpio9), | ||||
| +	BCM63268_GROUP(gpio10), | ||||
| +	BCM63268_GROUP(gpio11), | ||||
| +	BCM63268_GROUP(gpio12), | ||||
| +	BCM63268_GROUP(gpio13), | ||||
| +	BCM63268_GROUP(gpio14), | ||||
| +	BCM63268_GROUP(gpio15), | ||||
| +	BCM63268_GROUP(gpio16), | ||||
| +	BCM63268_GROUP(gpio17), | ||||
| +	BCM63268_GROUP(gpio18), | ||||
| +	BCM63268_GROUP(gpio19), | ||||
| +	BCM63268_GROUP(gpio20), | ||||
| +	BCM63268_GROUP(gpio21), | ||||
| +	BCM63268_GROUP(gpio22), | ||||
| +	BCM63268_GROUP(gpio23), | ||||
| +	BCM63268_GROUP(gpio24), | ||||
| +	BCM63268_GROUP(gpio25), | ||||
| +	BCM63268_GROUP(gpio26), | ||||
| +	BCM63268_GROUP(gpio27), | ||||
| +	BCM63268_GROUP(gpio28), | ||||
| +	BCM63268_GROUP(gpio29), | ||||
| +	BCM63268_GROUP(gpio30), | ||||
| +	BCM63268_GROUP(gpio31), | ||||
| +	BCM63268_GROUP(gpio32), | ||||
| +	BCM63268_GROUP(gpio33), | ||||
| +	BCM63268_GROUP(gpio34), | ||||
| +	BCM63268_GROUP(gpio35), | ||||
| +	BCM63268_GROUP(gpio36), | ||||
| +	BCM63268_GROUP(gpio37), | ||||
| +	BCM63268_GROUP(gpio38), | ||||
| +	BCM63268_GROUP(gpio39), | ||||
| +	BCM63268_GROUP(gpio40), | ||||
| +	BCM63268_GROUP(gpio41), | ||||
| +	BCM63268_GROUP(gpio42), | ||||
| +	BCM63268_GROUP(gpio43), | ||||
| +	BCM63268_GROUP(gpio44), | ||||
| +	BCM63268_GROUP(gpio45), | ||||
| +	BCM63268_GROUP(gpio46), | ||||
| +	BCM63268_GROUP(gpio47), | ||||
| +	BCM63268_GROUP(gpio48), | ||||
| +	BCM63268_GROUP(gpio49), | ||||
| +	BCM63268_GROUP(gpio50), | ||||
| +	BCM63268_GROUP(gpio51), | ||||
| + | ||||
| +	/* multi pin groups */ | ||||
| +	BCM63268_GROUP(nand_grp), | ||||
| +	BCM63268_GROUP(dectpd_grp), | ||||
| +	BCM63268_GROUP(vdsl_phy0_grp), | ||||
| +	BCM63268_GROUP(vdsl_phy1_grp), | ||||
| +	BCM63268_GROUP(vdsl_phy2_grp), | ||||
| +	BCM63268_GROUP(vdsl_phy3_grp), | ||||
| +}; | ||||
| + | ||||
| +static const char * const led_groups[] = { | ||||
| +	"gpio0", | ||||
| +	"gpio1", | ||||
| +	"gpio2", | ||||
| +	"gpio3", | ||||
| +	"gpio4", | ||||
| +	"gpio5", | ||||
| +	"gpio6", | ||||
| +	"gpio7", | ||||
| +	"gpio8", | ||||
| +	"gpio9", | ||||
| +	"gpio10", | ||||
| +	"gpio11", | ||||
| +	"gpio12", | ||||
| +	"gpio13", | ||||
| +	"gpio14", | ||||
| +	"gpio15", | ||||
| +	"gpio16", | ||||
| +	"gpio17", | ||||
| +	"gpio18", | ||||
| +	"gpio19", | ||||
| +	"gpio20", | ||||
| +	"gpio21", | ||||
| +	"gpio22", | ||||
| +	"gpio23", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_clk_groups[] = { | ||||
| +	"gpio0", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_data_groups[] = { | ||||
| +	"gpio1", | ||||
| +}; | ||||
| + | ||||
| +static const char * const hsspi_cs4_groups[] = { | ||||
| +	"gpio16", | ||||
| +}; | ||||
| + | ||||
| +static const char * const hsspi_cs5_groups[] = { | ||||
| +	"gpio17", | ||||
| +}; | ||||
| + | ||||
| +static const char * const hsspi_cs6_groups[] = { | ||||
| +	"gpio8", | ||||
| +}; | ||||
| + | ||||
| +static const char * const hsspi_cs7_groups[] = { | ||||
| +	"gpio9", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_scts_groups[] = { | ||||
| +	"gpio10", | ||||
| +	"gpio24", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_srts_groups[] = { | ||||
| +	"gpio11", | ||||
| +	"gpio25", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_sdin_groups[] = { | ||||
| +	"gpio12", | ||||
| +	"gpio26", | ||||
| +}; | ||||
| + | ||||
| +static const char * const uart1_sdout_groups[] = { | ||||
| +	"gpio13", | ||||
| +	"gpio27", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ntr_pulse_in_groups[] = { | ||||
| +	"gpio14", | ||||
| +	"gpio28", | ||||
| +}; | ||||
| + | ||||
| +static const char * const dsl_ntr_pulse_out_groups[] = { | ||||
| +	"gpio15", | ||||
| +	"gpio29", | ||||
| +}; | ||||
| + | ||||
| +static const char * const adsl_spi_miso_groups[] = { | ||||
| +	"gpio18", | ||||
| +}; | ||||
| + | ||||
| +static const char * const adsl_spi_mosi_groups[] = { | ||||
| +	"gpio19", | ||||
| +}; | ||||
| + | ||||
| +static const char * const vreg_clk_groups[] = { | ||||
| +	"gpio22", | ||||
| +}; | ||||
| + | ||||
| +static const char * const pcie_clkreq_b_groups[] = { | ||||
| +	"gpio23", | ||||
| +}; | ||||
| + | ||||
| +static const char * const switch_led_clk_groups[] = { | ||||
| +	"gpio30", | ||||
| +}; | ||||
| + | ||||
| +static const char * const switch_led_data_groups[] = { | ||||
| +	"gpio31", | ||||
| +}; | ||||
| + | ||||
| +static const char * const wifi_groups[] = { | ||||
| +	"gpio32", | ||||
| +	"gpio33", | ||||
| +	"gpio34", | ||||
| +	"gpio35", | ||||
| +	"gpio36", | ||||
| +	"gpio37", | ||||
| +	"gpio38", | ||||
| +	"gpio39", | ||||
| +	"gpio40", | ||||
| +	"gpio41", | ||||
| +	"gpio42", | ||||
| +	"gpio43", | ||||
| +	"gpio44", | ||||
| +	"gpio45", | ||||
| +	"gpio46", | ||||
| +	"gpio47", | ||||
| +	"gpio48", | ||||
| +	"gpio49", | ||||
| +	"gpio50", | ||||
| +	"gpio51", | ||||
| +}; | ||||
| + | ||||
| +static const char * const nand_groups[] = { | ||||
| +	"nand_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const dectpd_groups[] = { | ||||
| +	"dectpd_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const vdsl_phy_override_0_groups[] = { | ||||
| +	"vdsl_phy_override_0_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const vdsl_phy_override_1_groups[] = { | ||||
| +	"vdsl_phy_override_1_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const vdsl_phy_override_2_groups[] = { | ||||
| +	"vdsl_phy_override_2_grp", | ||||
| +}; | ||||
| + | ||||
| +static const char * const vdsl_phy_override_3_groups[] = { | ||||
| +	"vdsl_phy_override_3_grp", | ||||
| +}; | ||||
| + | ||||
| +#define BCM63268_LED_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM63268_LEDCTRL,		\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM63268_MODE_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM63268_MODE,			\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM63268_CTRL_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM63268_CTRL,			\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM63268_BASEMODE_FUN(n, val)			\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.reg = BCM63268_BASEMODE,		\ | ||||
| +		.mask = val,				\ | ||||
| +	} | ||||
| + | ||||
| +static const struct bcm63268_function bcm63268_funcs[] = { | ||||
| +	BCM63268_LED_FUN(led), | ||||
| +	BCM63268_MODE_FUN(serial_led_clk), | ||||
| +	BCM63268_MODE_FUN(serial_led_data), | ||||
| +	BCM63268_MODE_FUN(hsspi_cs6), | ||||
| +	BCM63268_MODE_FUN(hsspi_cs7), | ||||
| +	BCM63268_MODE_FUN(uart1_scts), | ||||
| +	BCM63268_MODE_FUN(uart1_srts), | ||||
| +	BCM63268_MODE_FUN(uart1_sdin), | ||||
| +	BCM63268_MODE_FUN(uart1_sdout), | ||||
| +	BCM63268_MODE_FUN(ntr_pulse_in), | ||||
| +	BCM63268_MODE_FUN(dsl_ntr_pulse_out), | ||||
| +	BCM63268_MODE_FUN(hsspi_cs4), | ||||
| +	BCM63268_MODE_FUN(hsspi_cs5), | ||||
| +	BCM63268_MODE_FUN(adsl_spi_miso), | ||||
| +	BCM63268_MODE_FUN(adsl_spi_mosi), | ||||
| +	BCM63268_MODE_FUN(vreg_clk), | ||||
| +	BCM63268_MODE_FUN(pcie_clkreq_b), | ||||
| +	BCM63268_MODE_FUN(switch_led_clk), | ||||
| +	BCM63268_MODE_FUN(switch_led_data), | ||||
| +	BCM63268_CTRL_FUN(wifi), | ||||
| +	BCM63268_BASEMODE_FUN(nand, BASEMODE_NAND), | ||||
| +	BCM63268_BASEMODE_FUN(dectpd, BASEMODE_DECTPD), | ||||
| +	BCM63268_BASEMODE_FUN(vdsl_phy_override_0, BASEMODE_VDSL_PHY_0), | ||||
| +	BCM63268_BASEMODE_FUN(vdsl_phy_override_1, BASEMODE_VDSL_PHY_1), | ||||
| +	BCM63268_BASEMODE_FUN(vdsl_phy_override_2, BASEMODE_VDSL_PHY_2), | ||||
| +	BCM63268_BASEMODE_FUN(vdsl_phy_override_3, BASEMODE_VDSL_PHY_3), | ||||
| +}; | ||||
| + | ||||
| +static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm63268_groups); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||||
| +						   unsigned group) | ||||
| +{ | ||||
| +	return bcm63268_groups[group].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||||
| +					   unsigned group, | ||||
| +					   const unsigned **pins, | ||||
| +					   unsigned *num_pins) | ||||
| +{ | ||||
| +	*pins = bcm63268_groups[group].pins; | ||||
| +	*num_pins = bcm63268_groups[group].num_pins; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm63268_funcs); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev, | ||||
| +						  unsigned selector) | ||||
| +{ | ||||
| +	return bcm63268_funcs[selector].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev, | ||||
| +				       unsigned selector, | ||||
| +				       const char * const **groups, | ||||
| +				       unsigned * const num_groups) | ||||
| +{ | ||||
| +	*groups = bcm63268_funcs[selector].groups; | ||||
| +	*num_groups = bcm63268_funcs[selector].num_groups; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void bcm63268_rmw_mux(struct bcm63268_pinctrl *pctl, void __iomem *reg, | ||||
| +			     u32 mask, u32 val) | ||||
| +{ | ||||
| +	unsigned long flags; | ||||
| +	u32 tmp; | ||||
| + | ||||
| +	spin_lock_irqsave(&pctl->lock, flags); | ||||
| +	tmp = __raw_readl(reg); | ||||
| +	tmp &= ~mask; | ||||
| +	tmp |= val; | ||||
| +	__raw_writel(tmp, reg); | ||||
| + | ||||
| +	spin_unlock_irqrestore(&pctl->lock, flags); | ||||
| +} | ||||
| + | ||||
| +static void bcm63268_set_gpio(struct bcm63268_pinctrl *pctl, unsigned pin) | ||||
| +{ | ||||
| +	const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin]; | ||||
| +	u32 basemode = (unsigned long)desc->drv_data; | ||||
| +	u32 mask = BIT(pin % 32); | ||||
| + | ||||
| +	if (basemode) | ||||
| +		bcm63268_rmw_mux(pctl, pctl->basemode, basemode, 0); | ||||
| + | ||||
| +	if (pin < 32) { | ||||
| +		/* base mode: 0 => gpio, 1 => mux function */ | ||||
| +		bcm63268_rmw_mux(pctl, pctl->mode, mask, 0); | ||||
| + | ||||
| +		/* pins 0-23 might be muxed to led */ | ||||
| +		if (pin < 24) | ||||
| +			bcm63268_rmw_mux(pctl, pctl->led, mask, 0); | ||||
| +	} else if (pin < 52) { | ||||
| +		/* ctrl reg: 0 => wifi function, 1 => gpio */ | ||||
| +		bcm63268_rmw_mux(pctl, pctl->ctrl, mask, mask); | ||||
| +	} | ||||
| +} | ||||
| + | ||||
| +static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev, | ||||
| +				    unsigned selector, unsigned group) | ||||
| +{ | ||||
| +	struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	const struct bcm63268_pingroup *grp = &bcm63268_groups[group]; | ||||
| +	const struct bcm63268_function *f = &bcm63268_funcs[selector]; | ||||
| +	unsigned i; | ||||
| +	void __iomem *reg; | ||||
| +	u32 val, mask; | ||||
| + | ||||
| +	for (i = 0; i < grp->num_pins; i++) | ||||
| +		bcm63268_set_gpio(pctl, grp->pins[i]); | ||||
| + | ||||
| +	switch (f->reg) { | ||||
| +	case BCM63268_LEDCTRL: | ||||
| +		reg = pctl->led; | ||||
| +		mask = BIT(grp->pins[0]); | ||||
| +		val = BIT(grp->pins[0]); | ||||
| +		break; | ||||
| +	case BCM63268_MODE: | ||||
| +		reg = pctl->mode; | ||||
| +		mask = BIT(grp->pins[0]); | ||||
| +		val = BIT(grp->pins[0]); | ||||
| +		break; | ||||
| +	case BCM63268_CTRL: | ||||
| +		reg = pctl->ctrl; | ||||
| +		mask = BIT(grp->pins[0]); | ||||
| +		val = 0; | ||||
| +		break; | ||||
| +	case BCM63268_BASEMODE: | ||||
| +		reg = pctl->basemode; | ||||
| +		mask = f->mask; | ||||
| +		val = f->mask; | ||||
| +		break; | ||||
| +	default: | ||||
| +		WARN_ON(1); | ||||
| +		return -EINVAL; | ||||
| +	} | ||||
| + | ||||
| +	bcm63268_rmw_mux(pctl, reg, mask, val); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev, | ||||
| +					struct pinctrl_gpio_range *range, | ||||
| +					unsigned offset) | ||||
| +{ | ||||
| +	struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| + | ||||
| +	/* disable all functions using this pin */ | ||||
| +	bcm63268_set_gpio(pctl, offset); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct pinctrl_ops bcm63268_pctl_ops = { | ||||
| +	.get_groups_count	= bcm63268_pinctrl_get_group_count, | ||||
| +	.get_group_name		= bcm63268_pinctrl_get_group_name, | ||||
| +	.get_group_pins		= bcm63268_pinctrl_get_group_pins, | ||||
| +#ifdef CONFIG_OF | ||||
| +	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin, | ||||
| +	.dt_free_map		= pinctrl_utils_free_map, | ||||
| +#endif | ||||
| +}; | ||||
| + | ||||
| +static struct pinmux_ops bcm63268_pmx_ops = { | ||||
| +	.get_functions_count	= bcm63268_pinctrl_get_func_count, | ||||
| +	.get_function_name	= bcm63268_pinctrl_get_func_name, | ||||
| +	.get_function_groups	= bcm63268_pinctrl_get_groups, | ||||
| +	.set_mux		= bcm63268_pinctrl_set_mux, | ||||
| +	.gpio_request_enable	= bcm63268_gpio_request_enable, | ||||
| +	.strict			= true, | ||||
| +}; | ||||
| + | ||||
| +static int bcm63268_pinctrl_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct bcm63268_pinctrl *pctl; | ||||
| +	struct resource *res; | ||||
| +	void __iomem *led, *mode, *ctrl, *basemode; | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led"); | ||||
| +	led = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(led)) | ||||
| +		return PTR_ERR(led); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); | ||||
| +	mode = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(mode)) | ||||
| +		return PTR_ERR(mode); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); | ||||
| +	ctrl = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(ctrl)) | ||||
| +		return PTR_ERR(ctrl); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode"); | ||||
| +	basemode = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(basemode)) | ||||
| +		return PTR_ERR(basemode); | ||||
| + | ||||
| +	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); | ||||
| +	if (!pctl) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	spin_lock_init(&pctl->lock); | ||||
| + | ||||
| +	pctl->led = led; | ||||
| +	pctl->mode = mode; | ||||
| +	pctl->ctrl = ctrl; | ||||
| +	pctl->basemode = basemode; | ||||
| + | ||||
| +	pctl->desc.name = dev_name(&pdev->dev); | ||||
| +	pctl->desc.owner = THIS_MODULE; | ||||
| +	pctl->desc.pctlops = &bcm63268_pctl_ops; | ||||
| +	pctl->desc.pmxops = &bcm63268_pmx_ops; | ||||
| + | ||||
| +	pctl->desc.npins = ARRAY_SIZE(bcm63268_pins); | ||||
| +	pctl->desc.pins = bcm63268_pins; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, pctl); | ||||
| + | ||||
| +	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, | ||||
| +						 pctl->gpio, BCM63268_NGPIO); | ||||
| +	if (IS_ERR(pctl->pctldev)) | ||||
| +		return PTR_ERR(pctl->pctldev); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id bcm63268_pinctrl_match[] = { | ||||
| +	{ .compatible = "brcm,bcm63268-pinctrl", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_driver bcm63268_pinctrl_driver = { | ||||
| +	.probe = bcm63268_pinctrl_probe, | ||||
| +	.driver = { | ||||
| +		.name = "bcm63268-pinctrl", | ||||
| +		.of_match_table = bcm63268_pinctrl_match, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +builtin_platform_driver(bcm63268_pinctrl_driver); | ||||
| @@ -0,0 +1,96 @@ | ||||
| From 8439e5d2e69f54a532bb5f8ec001b4b5a3035574 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Wed, 27 Jul 2016 11:38:05 +0200 | ||||
| Subject: [PATCH 14/16] Documentation: add BCM6318 pincontroller binding | ||||
|  documentation | ||||
|  | ||||
| Add binding documentation for the pincontrol core found in BCM6318 SoCs. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  .../bindings/pinctrl/brcm,bcm6318-pinctrl.txt      | 79 ++++++++++++++++++++++ | ||||
|  1 file changed, 79 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.txt | ||||
| @@ -0,0 +1,79 @@ | ||||
| +* Broadcom BCM6318 pin controller | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible: Must be "brcm,bcm6318-pinctrl". | ||||
| +- regs: Register specifiers of dirout, dat, mode, mux, and pad registers. | ||||
| +- reg-names: Must be "dirout", "dat", "mode", "mux", "pad". | ||||
| +- gpio-controller: Identifies this node as a gpio controller. | ||||
| +- #gpio-cells: Must be <2>. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +pinctrl: pin-controller@10000080 { | ||||
| +	compatible = "brcm,bcm6318-pinctrl"; | ||||
| +	reg = <0x10000080 0x08>, | ||||
| +	      <0x10000088 0x08>, | ||||
| +	      <0x10000098 0x04>, | ||||
| +	      <0x1000009c 0x0c>, | ||||
| +	      <0x100000d4 0x18>; | ||||
| +	reg-names = "dirout", "dat", "mode", "mux", "pad"; | ||||
| + | ||||
| +	gpio-controller; | ||||
| +	#gpio-cells = <2>; | ||||
| +}; | ||||
| + | ||||
| + | ||||
| +Available pins/groups and functions: | ||||
| + | ||||
| +name		pins	functions | ||||
| +----------------------------------------------------------- | ||||
| +gpio0		0	led, ephy0_spd_led | ||||
| +gpio1		1	led, ephy1_spd_led | ||||
| +gpio2		2	led, ephy2_spd_led | ||||
| +gpio3		3	led, ephy3_spd_led | ||||
| +gpio4		4	led, ephy0_act_led | ||||
| +gpio5		5	led, ephy1_act_led | ||||
| +gpio6		6	led, ephy2_act_led, serial_led_data | ||||
| +gpio7		7	led, ephy3_act_led, serial_led_clk | ||||
| +gpio8		8	led, inet_act_led | ||||
| +gpio9		9	led, inet_fail_led | ||||
| +gpio10		10	led, dsl_led | ||||
| +gpio11		11	led, post_fail_led | ||||
| +gpio12		12	led, wlan_wps_led | ||||
| +gpio13		13	led, usb_pwron, usb_device_led | ||||
| +gpio14		14	led | ||||
| +gpio15		15	led | ||||
| +gpio16		16	led | ||||
| +gpio17		17	led | ||||
| +gpio18		18	led | ||||
| +gpio19		19	led | ||||
| +gpio20		20	led | ||||
| +gpio21		21	led | ||||
| +gpio22		22	led | ||||
| +gpio23		23	led | ||||
| +gpio24		24	- | ||||
| +gpio25		25	- | ||||
| +gpio26		26	- | ||||
| +gpio27		27	- | ||||
| +gpio28		28	- | ||||
| +gpio29		29	- | ||||
| +gpio30		30	- | ||||
| +gpio31		31	- | ||||
| +gpio32		32	- | ||||
| +gpio33		33	- | ||||
| +gpio34		34	- | ||||
| +gpio35		35	- | ||||
| +gpio36		36	- | ||||
| +gpio37		37	- | ||||
| +gpio38		38	- | ||||
| +gpio39		39	- | ||||
| +gpio40		40	usb_active | ||||
| +gpio41		41	- | ||||
| +gpio42		42	- | ||||
| +gpio43		43	- | ||||
| +gpio44		44	- | ||||
| +gpio45		45	- | ||||
| +gpio46		46	- | ||||
| +gpio47		47	- | ||||
| +gpio48		48	- | ||||
| +gpio49		49	- | ||||
| @@ -0,0 +1,609 @@ | ||||
| From bd9c250ef85e6f99aa5d59b21abb87d0a48f2f61 Mon Sep 17 00:00:00 2001 | ||||
| From: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Date: Fri, 24 Jun 2016 22:20:39 +0200 | ||||
| Subject: [PATCH 15/16] pinctrl: add a pincontrol driver for BCM6318 | ||||
|  | ||||
| Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs | ||||
| to different functions. BCM6318 is similar to BCM6328 with the addition | ||||
| of a pad register, and the GPIO meaning of the mux register changes | ||||
| based on the GPIO number. | ||||
|  | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| --- | ||||
|  drivers/pinctrl/bcm63xx/Kconfig           |   7 + | ||||
|  drivers/pinctrl/bcm63xx/Makefile          |   1 + | ||||
|  drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c | 564 ++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 572 insertions(+) | ||||
|  create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c | ||||
|  | ||||
| --- a/drivers/pinctrl/bcm63xx/Kconfig | ||||
| +++ b/drivers/pinctrl/bcm63xx/Kconfig | ||||
| @@ -2,6 +2,13 @@ config PINCTRL_BCM63XX | ||||
|  	bool | ||||
|  	select GPIO_GENERIC | ||||
|   | ||||
| +config PINCTRL_BCM6318 | ||||
| +	bool "BCM6318 pincontrol driver" | ||||
| +	select PINMUX | ||||
| +	select PINCONF | ||||
| +	select PINCTRL_BCM63XX | ||||
| +	select GENERIC_PINCONF | ||||
| + | ||||
|  config PINCTRL_BCM6328 | ||||
|  	bool "BCM6328 pincontrol driver" | ||||
|  	select PINMUX | ||||
| --- a/drivers/pinctrl/bcm63xx/Makefile | ||||
| +++ b/drivers/pinctrl/bcm63xx/Makefile | ||||
| @@ -1,4 +1,5 @@ | ||||
|  obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o | ||||
| +obj-$(CONFIG_PINCTRL_BCM6318)	+= pinctrl-bcm6318.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o | ||||
|  obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c | ||||
| @@ -0,0 +1,564 @@ | ||||
| +/* | ||||
| + * This file is subject to the terms and conditions of the GNU General Public | ||||
| + * License.  See the file "COPYING" in the main directory of this archive | ||||
| + * for more details. | ||||
| + * | ||||
| + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/spinlock.h> | ||||
| +#include <linux/bitops.h> | ||||
| +#include <linux/gpio.h> | ||||
| +#include <linux/gpio/driver.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_gpio.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#include <linux/pinctrl/pinconf.h> | ||||
| +#include <linux/pinctrl/pinconf-generic.h> | ||||
| +#include <linux/pinctrl/pinmux.h> | ||||
| +#include <linux/pinctrl/machine.h> | ||||
| + | ||||
| +#include "../core.h" | ||||
| +#include "../pinctrl-utils.h" | ||||
| + | ||||
| +#include "pinctrl-bcm63xx.h" | ||||
| + | ||||
| +#define BCM6318_NGPIO		50 | ||||
| + | ||||
| +struct bcm6318_pingroup { | ||||
| +	const char *name; | ||||
| +	const unsigned * const pins; | ||||
| +	const unsigned num_pins; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6318_function { | ||||
| +	const char *name; | ||||
| +	const char * const *groups; | ||||
| +	const unsigned num_groups; | ||||
| + | ||||
| +	unsigned mode_val:1; | ||||
| +	unsigned mux_val:2; | ||||
| +}; | ||||
| + | ||||
| +struct bcm6318_pinctrl { | ||||
| +	struct pinctrl_dev *pctldev; | ||||
| +	struct pinctrl_desc desc; | ||||
| + | ||||
| +	void __iomem *mode; | ||||
| +	void __iomem *mux[3]; | ||||
| +	void __iomem *pad[6]; | ||||
| + | ||||
| +	/* register access lock */ | ||||
| +	spinlock_t lock; | ||||
| + | ||||
| +	struct gpio_chip gpio[2]; | ||||
| +}; | ||||
| + | ||||
| +static const struct pinctrl_pin_desc bcm6318_pins[] = { | ||||
| +	PINCTRL_PIN(0, "gpio0"), | ||||
| +	PINCTRL_PIN(1, "gpio1"), | ||||
| +	PINCTRL_PIN(2, "gpio2"), | ||||
| +	PINCTRL_PIN(3, "gpio3"), | ||||
| +	PINCTRL_PIN(4, "gpio4"), | ||||
| +	PINCTRL_PIN(5, "gpio5"), | ||||
| +	PINCTRL_PIN(6, "gpio6"), | ||||
| +	PINCTRL_PIN(7, "gpio7"), | ||||
| +	PINCTRL_PIN(8, "gpio8"), | ||||
| +	PINCTRL_PIN(9, "gpio9"), | ||||
| +	PINCTRL_PIN(10, "gpio10"), | ||||
| +	PINCTRL_PIN(11, "gpio11"), | ||||
| +	PINCTRL_PIN(12, "gpio12"), | ||||
| +	PINCTRL_PIN(13, "gpio13"), | ||||
| +	PINCTRL_PIN(14, "gpio14"), | ||||
| +	PINCTRL_PIN(15, "gpio15"), | ||||
| +	PINCTRL_PIN(16, "gpio16"), | ||||
| +	PINCTRL_PIN(17, "gpio17"), | ||||
| +	PINCTRL_PIN(18, "gpio18"), | ||||
| +	PINCTRL_PIN(19, "gpio19"), | ||||
| +	PINCTRL_PIN(20, "gpio20"), | ||||
| +	PINCTRL_PIN(21, "gpio21"), | ||||
| +	PINCTRL_PIN(22, "gpio22"), | ||||
| +	PINCTRL_PIN(23, "gpio23"), | ||||
| +	PINCTRL_PIN(24, "gpio24"), | ||||
| +	PINCTRL_PIN(25, "gpio25"), | ||||
| +	PINCTRL_PIN(26, "gpio26"), | ||||
| +	PINCTRL_PIN(27, "gpio27"), | ||||
| +	PINCTRL_PIN(28, "gpio28"), | ||||
| +	PINCTRL_PIN(29, "gpio29"), | ||||
| +	PINCTRL_PIN(30, "gpio30"), | ||||
| +	PINCTRL_PIN(31, "gpio31"), | ||||
| +	PINCTRL_PIN(32, "gpio32"), | ||||
| +	PINCTRL_PIN(33, "gpio33"), | ||||
| +	PINCTRL_PIN(34, "gpio34"), | ||||
| +	PINCTRL_PIN(35, "gpio35"), | ||||
| +	PINCTRL_PIN(36, "gpio36"), | ||||
| +	PINCTRL_PIN(37, "gpio37"), | ||||
| +	PINCTRL_PIN(38, "gpio38"), | ||||
| +	PINCTRL_PIN(39, "gpio39"), | ||||
| +	PINCTRL_PIN(40, "gpio40"), | ||||
| +	PINCTRL_PIN(41, "gpio41"), | ||||
| +	PINCTRL_PIN(42, "gpio42"), | ||||
| +	PINCTRL_PIN(43, "gpio43"), | ||||
| +	PINCTRL_PIN(44, "gpio44"), | ||||
| +	PINCTRL_PIN(45, "gpio45"), | ||||
| +	PINCTRL_PIN(46, "gpio46"), | ||||
| +	PINCTRL_PIN(47, "gpio47"), | ||||
| +	PINCTRL_PIN(48, "gpio48"), | ||||
| +	PINCTRL_PIN(49, "gpio49"), | ||||
| +}; | ||||
| + | ||||
| +static unsigned gpio0_pins[] = { 0 }; | ||||
| +static unsigned gpio1_pins[] = { 1 }; | ||||
| +static unsigned gpio2_pins[] = { 2 }; | ||||
| +static unsigned gpio3_pins[] = { 3 }; | ||||
| +static unsigned gpio4_pins[] = { 4 }; | ||||
| +static unsigned gpio5_pins[] = { 5 }; | ||||
| +static unsigned gpio6_pins[] = { 6 }; | ||||
| +static unsigned gpio7_pins[] = { 7 }; | ||||
| +static unsigned gpio8_pins[] = { 8 }; | ||||
| +static unsigned gpio9_pins[] = { 9 }; | ||||
| +static unsigned gpio10_pins[] = { 10 }; | ||||
| +static unsigned gpio11_pins[] = { 11 }; | ||||
| +static unsigned gpio12_pins[] = { 12 }; | ||||
| +static unsigned gpio13_pins[] = { 13 }; | ||||
| +static unsigned gpio14_pins[] = { 14 }; | ||||
| +static unsigned gpio15_pins[] = { 15 }; | ||||
| +static unsigned gpio16_pins[] = { 16 }; | ||||
| +static unsigned gpio17_pins[] = { 17 }; | ||||
| +static unsigned gpio18_pins[] = { 18 }; | ||||
| +static unsigned gpio19_pins[] = { 19 }; | ||||
| +static unsigned gpio20_pins[] = { 20 }; | ||||
| +static unsigned gpio21_pins[] = { 21 }; | ||||
| +static unsigned gpio22_pins[] = { 22 }; | ||||
| +static unsigned gpio23_pins[] = { 23 }; | ||||
| +static unsigned gpio24_pins[] = { 24 }; | ||||
| +static unsigned gpio25_pins[] = { 25 }; | ||||
| +static unsigned gpio26_pins[] = { 26 }; | ||||
| +static unsigned gpio27_pins[] = { 27 }; | ||||
| +static unsigned gpio28_pins[] = { 28 }; | ||||
| +static unsigned gpio29_pins[] = { 29 }; | ||||
| +static unsigned gpio30_pins[] = { 30 }; | ||||
| +static unsigned gpio31_pins[] = { 31 }; | ||||
| +static unsigned gpio32_pins[] = { 32 }; | ||||
| +static unsigned gpio33_pins[] = { 33 }; | ||||
| +static unsigned gpio34_pins[] = { 34 }; | ||||
| +static unsigned gpio35_pins[] = { 35 }; | ||||
| +static unsigned gpio36_pins[] = { 36 }; | ||||
| +static unsigned gpio37_pins[] = { 37 }; | ||||
| +static unsigned gpio38_pins[] = { 38 }; | ||||
| +static unsigned gpio39_pins[] = { 39 }; | ||||
| +static unsigned gpio40_pins[] = { 40 }; | ||||
| +static unsigned gpio41_pins[] = { 41 }; | ||||
| +static unsigned gpio42_pins[] = { 42 }; | ||||
| +static unsigned gpio43_pins[] = { 43 }; | ||||
| +static unsigned gpio44_pins[] = { 44 }; | ||||
| +static unsigned gpio45_pins[] = { 45 }; | ||||
| +static unsigned gpio46_pins[] = { 46 }; | ||||
| +static unsigned gpio47_pins[] = { 47 }; | ||||
| +static unsigned gpio48_pins[] = { 48 }; | ||||
| +static unsigned gpio49_pins[] = { 49 }; | ||||
| + | ||||
| +#define BCM6318_GROUP(n)					\ | ||||
| +	{							\ | ||||
| +		.name = #n,					\ | ||||
| +		.pins = n##_pins,				\ | ||||
| +		.num_pins = ARRAY_SIZE(n##_pins),		\ | ||||
| +	} | ||||
| + | ||||
| +static struct bcm6318_pingroup bcm6318_groups[] = { | ||||
| +	BCM6318_GROUP(gpio0), | ||||
| +	BCM6318_GROUP(gpio1), | ||||
| +	BCM6318_GROUP(gpio2), | ||||
| +	BCM6318_GROUP(gpio3), | ||||
| +	BCM6318_GROUP(gpio4), | ||||
| +	BCM6318_GROUP(gpio5), | ||||
| +	BCM6318_GROUP(gpio6), | ||||
| +	BCM6318_GROUP(gpio7), | ||||
| +	BCM6318_GROUP(gpio8), | ||||
| +	BCM6318_GROUP(gpio9), | ||||
| +	BCM6318_GROUP(gpio10), | ||||
| +	BCM6318_GROUP(gpio11), | ||||
| +	BCM6318_GROUP(gpio12), | ||||
| +	BCM6318_GROUP(gpio13), | ||||
| +	BCM6318_GROUP(gpio14), | ||||
| +	BCM6318_GROUP(gpio15), | ||||
| +	BCM6318_GROUP(gpio16), | ||||
| +	BCM6318_GROUP(gpio17), | ||||
| +	BCM6318_GROUP(gpio18), | ||||
| +	BCM6318_GROUP(gpio19), | ||||
| +	BCM6318_GROUP(gpio20), | ||||
| +	BCM6318_GROUP(gpio21), | ||||
| +	BCM6318_GROUP(gpio22), | ||||
| +	BCM6318_GROUP(gpio23), | ||||
| +	BCM6318_GROUP(gpio24), | ||||
| +	BCM6318_GROUP(gpio25), | ||||
| +	BCM6318_GROUP(gpio26), | ||||
| +	BCM6318_GROUP(gpio27), | ||||
| +	BCM6318_GROUP(gpio28), | ||||
| +	BCM6318_GROUP(gpio29), | ||||
| +	BCM6318_GROUP(gpio30), | ||||
| +	BCM6318_GROUP(gpio31), | ||||
| +	BCM6318_GROUP(gpio32), | ||||
| +	BCM6318_GROUP(gpio33), | ||||
| +	BCM6318_GROUP(gpio34), | ||||
| +	BCM6318_GROUP(gpio35), | ||||
| +	BCM6318_GROUP(gpio36), | ||||
| +	BCM6318_GROUP(gpio37), | ||||
| +	BCM6318_GROUP(gpio38), | ||||
| +	BCM6318_GROUP(gpio39), | ||||
| +	BCM6318_GROUP(gpio40), | ||||
| +	BCM6318_GROUP(gpio41), | ||||
| +	BCM6318_GROUP(gpio42), | ||||
| +	BCM6318_GROUP(gpio43), | ||||
| +	BCM6318_GROUP(gpio44), | ||||
| +	BCM6318_GROUP(gpio45), | ||||
| +	BCM6318_GROUP(gpio46), | ||||
| +	BCM6318_GROUP(gpio47), | ||||
| +	BCM6318_GROUP(gpio48), | ||||
| +	BCM6318_GROUP(gpio49), | ||||
| +}; | ||||
| + | ||||
| +/* GPIO_MODE */ | ||||
| +static const char * const led_groups[] = { | ||||
| +	"gpio0", | ||||
| +	"gpio1", | ||||
| +	"gpio2", | ||||
| +	"gpio3", | ||||
| +	"gpio4", | ||||
| +	"gpio5", | ||||
| +	"gpio6", | ||||
| +	"gpio7", | ||||
| +	"gpio8", | ||||
| +	"gpio9", | ||||
| +	"gpio10", | ||||
| +	"gpio11", | ||||
| +	"gpio12", | ||||
| +	"gpio13", | ||||
| +	"gpio14", | ||||
| +	"gpio15", | ||||
| +	"gpio16", | ||||
| +	"gpio17", | ||||
| +	"gpio18", | ||||
| +	"gpio19", | ||||
| +	"gpio20", | ||||
| +	"gpio21", | ||||
| +	"gpio22", | ||||
| +	"gpio23", | ||||
| +}; | ||||
| + | ||||
| +/* PINMUX_SEL */ | ||||
| +static const char * const ephy0_spd_led_groups[] = { | ||||
| +	"gpio0", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy1_spd_led_groups[] = { | ||||
| +	"gpio1", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy2_spd_led_groups[] = { | ||||
| +	"gpio2", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy3_spd_led_groups[] = { | ||||
| +	"gpio3", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy0_act_led_groups[] = { | ||||
| +	"gpio4", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy1_act_led_groups[] = { | ||||
| +	"gpio5", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy2_act_led_groups[] = { | ||||
| +	"gpio6", | ||||
| +}; | ||||
| + | ||||
| +static const char * const ephy3_act_led_groups[] = { | ||||
| +	"gpio7", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_data_groups[] = { | ||||
| +	"gpio6", | ||||
| +}; | ||||
| + | ||||
| +static const char * const serial_led_clk_groups[] = { | ||||
| +	"gpio7", | ||||
| +}; | ||||
| + | ||||
| +static const char * const inet_act_led_groups[] = { | ||||
| +	"gpio8", | ||||
| +}; | ||||
| + | ||||
| +static const char * const inet_fail_led_groups[] = { | ||||
| +	"gpio9", | ||||
| +}; | ||||
| + | ||||
| +static const char * const dsl_led_groups[] = { | ||||
| +	"gpio10", | ||||
| +}; | ||||
| + | ||||
| +static const char * const post_fail_led_groups[] = { | ||||
| +	"gpio11", | ||||
| +}; | ||||
| + | ||||
| +static const char * const wlan_wps_led_groups[] = { | ||||
| +	"gpio12", | ||||
| +}; | ||||
| + | ||||
| +static const char * const usb_pwron_groups[] = { | ||||
| +	"gpio13", | ||||
| +}; | ||||
| + | ||||
| +static const char * const usb_device_led_groups[] = { | ||||
| +	"gpio13", | ||||
| +}; | ||||
| + | ||||
| +static const char * const usb_active_groups[] = { | ||||
| +	"gpio40", | ||||
| +}; | ||||
| + | ||||
| +#define BCM6318_MODE_FUN(n)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.mode_val = 1,				\ | ||||
| +	} | ||||
| + | ||||
| +#define BCM6318_MUX_FUN(n, mux)				\ | ||||
| +	{						\ | ||||
| +		.name = #n,				\ | ||||
| +		.groups = n##_groups,			\ | ||||
| +		.num_groups = ARRAY_SIZE(n##_groups),	\ | ||||
| +		.mux_val = mux,				\ | ||||
| +	} | ||||
| + | ||||
| +static const struct bcm6318_function bcm6318_funcs[] = { | ||||
| +	BCM6318_MODE_FUN(led), | ||||
| +	BCM6318_MUX_FUN(ephy0_spd_led, 1), | ||||
| +	BCM6318_MUX_FUN(ephy1_spd_led, 1), | ||||
| +	BCM6318_MUX_FUN(ephy2_spd_led, 1), | ||||
| +	BCM6318_MUX_FUN(ephy3_spd_led, 1), | ||||
| +	BCM6318_MUX_FUN(ephy0_act_led, 1), | ||||
| +	BCM6318_MUX_FUN(ephy1_act_led, 1), | ||||
| +	BCM6318_MUX_FUN(ephy2_act_led, 1), | ||||
| +	BCM6318_MUX_FUN(ephy3_act_led, 1), | ||||
| +	BCM6318_MUX_FUN(serial_led_data, 3), | ||||
| +	BCM6318_MUX_FUN(serial_led_clk, 3), | ||||
| +	BCM6318_MUX_FUN(inet_act_led, 1), | ||||
| +	BCM6318_MUX_FUN(inet_fail_led, 1), | ||||
| +	BCM6318_MUX_FUN(dsl_led, 1), | ||||
| +	BCM6318_MUX_FUN(post_fail_led, 1), | ||||
| +	BCM6318_MUX_FUN(wlan_wps_led, 1), | ||||
| +	BCM6318_MUX_FUN(usb_pwron, 1), | ||||
| +	BCM6318_MUX_FUN(usb_device_led, 2), | ||||
| +	BCM6318_MUX_FUN(usb_active, 2), | ||||
| +}; | ||||
| + | ||||
| +static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6318_groups); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||||
| +						  unsigned group) | ||||
| +{ | ||||
| +	return bcm6318_groups[group].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||||
| +					  unsigned group, const unsigned **pins, | ||||
| +					  unsigned *num_pins) | ||||
| +{ | ||||
| +	*pins = bcm6318_groups[group].pins; | ||||
| +	*num_pins = bcm6318_groups[group].num_pins; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev) | ||||
| +{ | ||||
| +	return ARRAY_SIZE(bcm6318_funcs); | ||||
| +} | ||||
| + | ||||
| +static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev, | ||||
| +						 unsigned selector) | ||||
| +{ | ||||
| +	return bcm6318_funcs[selector].name; | ||||
| +} | ||||
| + | ||||
| +static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev, | ||||
| +				      unsigned selector, | ||||
| +				      const char * const **groups, | ||||
| +				      unsigned * const num_groups) | ||||
| +{ | ||||
| +	*groups = bcm6318_funcs[selector].groups; | ||||
| +	*num_groups = bcm6318_funcs[selector].num_groups; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void bcm6318_rmw_mux(struct bcm6318_pinctrl *pctl, unsigned pin, | ||||
| +			    u32 mode, u32 mux) | ||||
| +{ | ||||
| +	unsigned long flags; | ||||
| +	u32 reg; | ||||
| + | ||||
| +	spin_lock_irqsave(&pctl->lock, flags); | ||||
| +	if (pin < 32) { | ||||
| +		reg = __raw_readl(pctl->mode); | ||||
| +		reg &= ~BIT(pin); | ||||
| +		if (mode) | ||||
| +			reg |= BIT(pin); | ||||
| +		__raw_writel(reg, pctl->mode); | ||||
| +	} | ||||
| + | ||||
| +	if (pin < 48) { | ||||
| +		reg = __raw_readl(pctl->mux[pin / 16]); | ||||
| +		reg &= ~(3UL << ((pin % 16) * 2)); | ||||
| +		reg |= mux << ((pin % 16) * 2); | ||||
| +		__raw_writel(reg, pctl->mux[pin / 16]); | ||||
| +	} | ||||
| +	spin_unlock_irqrestore(&pctl->lock, flags); | ||||
| +} | ||||
| + | ||||
| +static void bcm6318_set_pad(struct bcm6318_pinctrl *pctl, unsigned pin, u8 val) | ||||
| +{ | ||||
| +	unsigned long flags; | ||||
| +	u32 reg; | ||||
| + | ||||
| +	spin_lock_irqsave(&pctl->lock, flags); | ||||
| +	reg = __raw_readl(pctl->pad[pin / 8]); | ||||
| +	reg &= ~(0xfUL << ((pin % 8) * 4)); | ||||
| +	reg |= val << ((pin % 8) * 4); | ||||
| +	__raw_writel(reg, pctl->pad[pin / 8]); | ||||
| +	spin_unlock_irqrestore(&pctl->lock, flags); | ||||
| +} | ||||
| + | ||||
| +static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev, | ||||
| +				   unsigned selector, unsigned group) | ||||
| +{ | ||||
| +	struct bcm6318_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| +	const struct bcm6318_pingroup *grp = &bcm6318_groups[group]; | ||||
| +	const struct bcm6318_function *f = &bcm6318_funcs[selector]; | ||||
| + | ||||
| +	bcm6318_rmw_mux(pctl, grp->pins[0], f->mode_val, f->mux_val); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev, | ||||
| +				       struct pinctrl_gpio_range *range, | ||||
| +				       unsigned offset) | ||||
| +{ | ||||
| +	struct bcm6318_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||||
| + | ||||
| +	/* disable all functions using this pin */ | ||||
| +	if (offset < 13) { | ||||
| +		/* GPIOs 0-12 use mux 0 as GPIO function */ | ||||
| +		bcm6318_rmw_mux(pctl, offset, 0, 0); | ||||
| +	} else if (offset < 42) { | ||||
| +		/* GPIOs 13-41 use mux 3 as GPIO function */ | ||||
| +		bcm6318_rmw_mux(pctl, offset, 0, 3); | ||||
| + | ||||
| +		/* FIXME: revert to old value for non gpio? */ | ||||
| +		bcm6318_set_pad(pctl, offset, 0); | ||||
| +	} else { | ||||
| +		/* no idea, really */ | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct pinctrl_ops bcm6318_pctl_ops = { | ||||
| +	.get_groups_count	= bcm6318_pinctrl_get_group_count, | ||||
| +	.get_group_name		= bcm6318_pinctrl_get_group_name, | ||||
| +	.get_group_pins		= bcm6318_pinctrl_get_group_pins, | ||||
| +#ifdef CONFIG_OF | ||||
| +	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin, | ||||
| +	.dt_free_map		= pinctrl_utils_free_map, | ||||
| +#endif | ||||
| +}; | ||||
| + | ||||
| +static struct pinmux_ops bcm6318_pmx_ops = { | ||||
| +	.get_functions_count	= bcm6318_pinctrl_get_func_count, | ||||
| +	.get_function_name	= bcm6318_pinctrl_get_func_name, | ||||
| +	.get_function_groups	= bcm6318_pinctrl_get_groups, | ||||
| +	.set_mux		= bcm6318_pinctrl_set_mux, | ||||
| +	.gpio_request_enable	= bcm6318_gpio_request_enable, | ||||
| +	.strict 		= true, | ||||
| +}; | ||||
| + | ||||
| +static int bcm6318_pinctrl_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct bcm6318_pinctrl *pctl; | ||||
| +	struct resource *res; | ||||
| +	void __iomem *mode, *mux, *pad; | ||||
| +	unsigned i; | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); | ||||
| +	mode = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(mode)) | ||||
| +		return PTR_ERR(mode); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux"); | ||||
| +	mux = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(mux)) | ||||
| +		return PTR_ERR(mux); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pad"); | ||||
| +	pad = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(pad)) | ||||
| +		return PTR_ERR(pad); | ||||
| + | ||||
| +	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); | ||||
| +	if (!pctl) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	spin_lock_init(&pctl->lock); | ||||
| + | ||||
| +	pctl->mode = mode; | ||||
| + | ||||
| +	for (i = 0; i < 3; i++) | ||||
| +		pctl->mux[i] = mux + (i * 4); | ||||
| + | ||||
| +	for (i = 0; i < 6; i++) | ||||
| +		pctl->pad[i] = pad + (i * 4); | ||||
| + | ||||
| +	pctl->desc.name = dev_name(&pdev->dev); | ||||
| +	pctl->desc.owner = THIS_MODULE; | ||||
| +	pctl->desc.pctlops = &bcm6318_pctl_ops; | ||||
| +	pctl->desc.pmxops = &bcm6318_pmx_ops; | ||||
| + | ||||
| +	pctl->desc.npins = ARRAY_SIZE(bcm6318_pins); | ||||
| +	pctl->desc.pins = bcm6318_pins; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, pctl); | ||||
| + | ||||
| +	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, | ||||
| +						 pctl->gpio, BCM6318_NGPIO); | ||||
| +	if (IS_ERR(pctl->pctldev)) | ||||
| +		return PTR_ERR(pctl->pctldev); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id bcm6318_pinctrl_match[] = { | ||||
| +	{ .compatible = "brcm,bcm6318-pinctrl", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_driver bcm6318_pinctrl_driver = { | ||||
| +	.probe = bcm6318_pinctrl_probe, | ||||
| +	.driver = { | ||||
| +		.name = "bcm6318-pinctrl", | ||||
| +		.of_match_table = bcm6318_pinctrl_match, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +builtin_platform_driver(bcm6318_pinctrl_driver); | ||||
							
								
								
									
										10
									
								
								target/linux/bmips/profiles/default.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								target/linux/bmips/profiles/default.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| define Profile/Default | ||||
|   NAME:=Default Profile | ||||
|   PRIORITY:=1 | ||||
| endef | ||||
|  | ||||
| define Profile/Default/Description | ||||
|   Default package set compatible with most boards. | ||||
| endef | ||||
|  | ||||
| $(eval $(call Profile,Default)) | ||||
		Reference in New Issue
	
	Block a user
	 Álvaro Fernández Rojas
					Álvaro Fernández Rojas