mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
target: add Apple Silicon SoC platform (M1/M2) family init support
This commit is contained in:
parent
960844ee21
commit
bbdcf9095c
29
target/linux/silicon/Makefile
Normal file
29
target/linux/silicon/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=arm
|
||||
BOARD:=silicon
|
||||
BOARDNAME:=Apple Silicon family
|
||||
FEATURES:=audio boot-part ext4 fpu squashfs usbgadget
|
||||
SUBTARGETS:=armv8
|
||||
|
||||
KERNEL_PATCHVER:=5.19
|
||||
|
||||
define Target/Description
|
||||
Build firmware image for Apple Silicon family
|
||||
endef
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
|
||||
DEFAULT_PACKAGES += \
|
||||
e2fsprogs \
|
||||
kmod-sound-core \
|
||||
kmod-usb-hid \
|
||||
mkf2fs \
|
||||
partx-utils
|
||||
|
||||
KERNELNAME:=Image dtbs
|
||||
|
||||
$(eval $(call BuildTarget))
|
510
target/linux/silicon/armv8/config-5.19
Normal file
510
target/linux/silicon/armv8/config-5.19
Normal file
@ -0,0 +1,510 @@
|
||||
CONFIG_64BIT=y
|
||||
# CONFIG_AIO is not set
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
CONFIG_ARCH_APPLE=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=18
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=33
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||
CONFIG_ARCH_PROC_KCORE_TEXT=y
|
||||
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARM64=y
|
||||
CONFIG_ARM64_4K_PAGES=y
|
||||
CONFIG_ARM64_CNP=y
|
||||
CONFIG_ARM64_ERRATUM_1165522=y
|
||||
CONFIG_ARM64_ERRATUM_1286807=y
|
||||
CONFIG_ARM64_ERRATUM_819472=y
|
||||
CONFIG_ARM64_ERRATUM_824069=y
|
||||
CONFIG_ARM64_ERRATUM_826319=y
|
||||
CONFIG_ARM64_ERRATUM_827319=y
|
||||
CONFIG_ARM64_ERRATUM_843419=y
|
||||
CONFIG_ARM64_ERRATUM_858921=y
|
||||
CONFIG_ARM64_HW_AFDBM=y
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
CONFIG_ARM64_PAGE_SHIFT=12
|
||||
CONFIG_ARM64_PAN=y
|
||||
CONFIG_ARM64_PA_BITS=48
|
||||
CONFIG_ARM64_PA_BITS_48=y
|
||||
CONFIG_ARM64_PMEM=y
|
||||
CONFIG_ARM64_PTR_AUTH=y
|
||||
CONFIG_ARM64_SVE=y
|
||||
# CONFIG_ARM64_SW_TTBR0_PAN is not set
|
||||
CONFIG_ARM64_TAGGED_ADDR_ABI=y
|
||||
CONFIG_ARM64_UAO=y
|
||||
CONFIG_ARM64_VA_BITS=48
|
||||
# CONFIG_ARM64_VA_BITS_39 is not set
|
||||
CONFIG_ARM64_VA_BITS_48=y
|
||||
CONFIG_ARM64_VHE=y
|
||||
CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
|
||||
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
|
||||
CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
|
||||
CONFIG_ARM_AMBA=y
|
||||
CONFIG_ARM_ARCH_TIMER=y
|
||||
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
||||
CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
|
||||
CONFIG_ARM_GIC=y
|
||||
CONFIG_ARM_GIC_V3=y
|
||||
CONFIG_ARM_GIC_V3_ITS=y
|
||||
CONFIG_ARM_PSCI_FW=y
|
||||
# CONFIG_ARM_SCMI_PROTOCOL is not set
|
||||
CONFIG_ARM_SCPI_POWER_DOMAIN=y
|
||||
CONFIG_ARM_SCPI_PROTOCOL=y
|
||||
CONFIG_ASN1=y
|
||||
CONFIG_ASSOCIATIVE_ARRAY=y
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
|
||||
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
|
||||
CONFIG_BLK_DEBUG_FS=y
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_PM=y
|
||||
CONFIG_BLK_SCSI_REQUEST=y
|
||||
CONFIG_CAVIUM_TX2_ERRATUM_219=y
|
||||
# CONFIG_CEC_CH7322 is not set
|
||||
# CONFIG_CEC_MESON_AO is not set
|
||||
# CONFIG_CEC_MESON_G12A_AO is not set
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLK_QORIQ=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CLZ_TAB=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_ALIGNMENT=8
|
||||
CONFIG_CMA_AREAS=7
|
||||
# CONFIG_CMA_DEBUG is not set
|
||||
# CONFIG_CMA_DEBUGFS is not set
|
||||
CONFIG_CMA_SIZE_MBYTES=16
|
||||
# CONFIG_CMA_SIZE_SEL_MAX is not set
|
||||
CONFIG_CMA_SIZE_SEL_MBYTES=y
|
||||
# CONFIG_CMA_SIZE_SEL_MIN is not set
|
||||
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMMON_CLK_AXG=y
|
||||
# CONFIG_COMMON_CLK_AXG_AUDIO is not set
|
||||
CONFIG_COMMON_CLK_CS2000_CP=y
|
||||
CONFIG_COMMON_CLK_G12A=y
|
||||
CONFIG_COMMON_CLK_GXBB=y
|
||||
CONFIG_COMMON_CLK_MESON_AO_CLKC=y
|
||||
CONFIG_COMMON_CLK_MESON_CPU_DYNDIV=y
|
||||
CONFIG_COMMON_CLK_MESON_DUALDIV=y
|
||||
CONFIG_COMMON_CLK_MESON_EE_CLKC=y
|
||||
CONFIG_COMMON_CLK_MESON_MPLL=y
|
||||
CONFIG_COMMON_CLK_MESON_PLL=y
|
||||
CONFIG_COMMON_CLK_MESON_REGMAP=y
|
||||
CONFIG_COMMON_CLK_MESON_VID_PLL_DIV=y
|
||||
CONFIG_COMMON_CLK_PWM=y
|
||||
CONFIG_COMMON_CLK_SCPI=y
|
||||
CONFIG_COMMON_CLK_XGENE=y
|
||||
# CONFIG_COMPAT_32BIT_TIME is not set
|
||||
CONFIG_CONSOLE_TRANSLATIONS=y
|
||||
CONFIG_CONTIG_ALLOC=y
|
||||
CONFIG_COREDUMP=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRC7=y
|
||||
CONFIG_CRC_ITU_T=y
|
||||
CONFIG_CRYPTO_AEAD=y
|
||||
CONFIG_CRYPTO_AEAD2=y
|
||||
CONFIG_CRYPTO_AKCIPHER=y
|
||||
CONFIG_CRYPTO_AKCIPHER2=y
|
||||
CONFIG_CRYPTO_CCM=y
|
||||
CONFIG_CRYPTO_CMAC=y
|
||||
CONFIG_CRYPTO_CRC32=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_CTR=y
|
||||
CONFIG_CRYPTO_DRBG=y
|
||||
CONFIG_CRYPTO_DRBG_HMAC=y
|
||||
CONFIG_CRYPTO_DRBG_MENU=y
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_GF128MUL=y
|
||||
CONFIG_CRYPTO_GHASH=y
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_HASH2=y
|
||||
CONFIG_CRYPTO_HASH_INFO=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_MANAGER=y
|
||||
CONFIG_CRYPTO_MANAGER2=y
|
||||
CONFIG_CRYPTO_NULL=y
|
||||
CONFIG_CRYPTO_NULL2=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RNG_DEFAULT=y
|
||||
CONFIG_CRYPTO_RSA=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_DMA_DIRECT_REMAP=y
|
||||
CONFIG_DMA_REMAP=y
|
||||
CONFIG_DMA_SHARED_BUFFER=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_BRIDGE=y
|
||||
CONFIG_DRM_DW_HDMI=y
|
||||
# CONFIG_DRM_DW_HDMI_I2S_AUDIO is not set
|
||||
CONFIG_DRM_FBDEV_EMULATION=y
|
||||
CONFIG_DRM_FBDEV_OVERALLOC=100
|
||||
CONFIG_DRM_GEM_CMA_HELPER=y
|
||||
CONFIG_DRM_KMS_CMA_HELPER=y
|
||||
CONFIG_DRM_KMS_FB_HELPER=y
|
||||
CONFIG_DRM_KMS_HELPER=y
|
||||
CONFIG_DRM_MALI_DISPLAY=y
|
||||
CONFIG_DRM_MESON=y
|
||||
CONFIG_DRM_MESON_DW_HDMI=y
|
||||
CONFIG_DRM_PANEL=y
|
||||
CONFIG_DRM_PANEL_BRIDGE=y
|
||||
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
CONFIG_DVB_CORE=y
|
||||
CONFIG_DWMAC_DWC_QOS_ETH=y
|
||||
# CONFIG_DWMAC_GENERIC is not set
|
||||
CONFIG_DWMAC_MESON=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_ELF_CORE=y
|
||||
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_FS_POSIX_ACL=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_CFB_COPYAREA=y
|
||||
CONFIG_FB_CFB_FILLRECT=y
|
||||
CONFIG_FB_CFB_IMAGEBLIT=y
|
||||
CONFIG_FB_CMDLINE=y
|
||||
CONFIG_FB_DEFERRED_IO=y
|
||||
CONFIG_FB_SYS_COPYAREA=y
|
||||
CONFIG_FB_SYS_FILLRECT=y
|
||||
CONFIG_FB_SYS_FOPS=y
|
||||
CONFIG_FB_SYS_IMAGEBLIT=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FIX_EARLYCON_MEM=y
|
||||
# CONFIG_FLATMEM_MANUAL is not set
|
||||
CONFIG_FONT_8x16=y
|
||||
CONFIG_FONT_8x8=y
|
||||
CONFIG_FONT_SUPPORT=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_FSL_ERRATUM_A008585=y
|
||||
CONFIG_FS_IOMAP=y
|
||||
CONFIG_FS_MBCACHE=y
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
CONFIG_FTRACE=y
|
||||
# CONFIG_FTRACE_SYSCALLS is not set
|
||||
CONFIG_FUJITSU_ERRATUM_010001=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ARCH_TOPOLOGY=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_CPU_VULNERABILITIES=y
|
||||
CONFIG_GENERIC_CSUM=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_MSI_IRQ_DOMAIN=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_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GLOB=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HDMI=y
|
||||
CONFIG_HISILICON_ERRATUM_161010101=y
|
||||
# CONFIG_HIST_TRIGGERS is not set
|
||||
CONFIG_HOLES_IN_ZONE=y
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HW_CONSOLE=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_MESON=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_ALGOBIT=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_MESON=y
|
||||
CONFIG_ICPLUS_PHY=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
|
||||
CONFIG_INPUT=y
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_IPV6_MROUTE=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
# CONFIG_IPV6_PIMSM_V2 is not set
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_IP_MROUTE_COMMON=y
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
# CONFIG_IR_IMON_RAW is not set
|
||||
CONFIG_IR_MESON=y
|
||||
# CONFIG_IR_SERIAL is not set
|
||||
# CONFIG_IR_SIR is not set
|
||||
# CONFIG_IR_TOY is not set
|
||||
CONFIG_JBD2=y
|
||||
CONFIG_KCMP=y
|
||||
CONFIG_KEYS=y
|
||||
# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
|
||||
CONFIG_LEDS_GPIO=y
|
||||
CONFIG_LIBFDT=y
|
||||
# CONFIG_LIRC is not set
|
||||
CONFIG_LLD_VERSION=0
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_MAILBOX=y
|
||||
# CONFIG_MAILBOX_TEST is not set
|
||||
CONFIG_MDIO_BITBANG=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_BUS_MUX=y
|
||||
# CONFIG_MDIO_BUS_MUX_MESON_G12A is not set
|
||||
CONFIG_MDIO_BUS_MUX_MMIOREG=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
# CONFIG_MDIO_GPIO is not set
|
||||
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
|
||||
CONFIG_MEDIA_ATTACH=y
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_CEC_SUPPORT=y
|
||||
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
|
||||
CONFIG_MEDIA_PLATFORM_SUPPORT=y
|
||||
CONFIG_MEDIA_RADIO_SUPPORT=y
|
||||
CONFIG_MEDIA_SDR_SUPPORT=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_MEDIA_TEST_SUPPORT=y
|
||||
CONFIG_MEDIA_TUNER=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MEMORY_ISOLATION=y
|
||||
CONFIG_MESON_CANVAS=y
|
||||
CONFIG_MESON_CLK_MEASURE=y
|
||||
CONFIG_MESON_EE_PM_DOMAINS=y
|
||||
CONFIG_MESON_EFUSE=y
|
||||
CONFIG_MESON_GXBB_WATCHDOG=y
|
||||
CONFIG_MESON_GXL_PHY=y
|
||||
CONFIG_MESON_GX_PM_DOMAINS=y
|
||||
CONFIG_MESON_GX_SOCINFO=y
|
||||
CONFIG_MESON_IRQ_GPIO=y
|
||||
# CONFIG_MESON_MX_EFUSE is not set
|
||||
CONFIG_MESON_MX_SOCINFO=y
|
||||
CONFIG_MESON_SARADC=y
|
||||
CONFIG_MESON_SECURE_PM_DOMAINS=y
|
||||
CONFIG_MESON_SM=y
|
||||
CONFIG_MESON_WATCHDOG=y
|
||||
# CONFIG_MFD_KHADAS_MCU is not set
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_ARMMMCI=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
CONFIG_MMC_BLOCK_MINORS=32
|
||||
CONFIG_MMC_CQHCI=y
|
||||
CONFIG_MMC_DW=y
|
||||
# CONFIG_MMC_DW_BLUEFIELD is not set
|
||||
# CONFIG_MMC_DW_EXYNOS is not set
|
||||
# CONFIG_MMC_DW_HI3798CV200 is not set
|
||||
CONFIG_MMC_DW_K3=y
|
||||
CONFIG_MMC_DW_PLTFM=y
|
||||
CONFIG_MMC_MESON_GX=y
|
||||
# CONFIG_MMC_MESON_MX_SDIO is not set
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_OF_ARASAN=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SPI=y
|
||||
CONFIG_MMC_STM32_SDMMC=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MPILIB=y
|
||||
CONFIG_MQ_IOSCHED_DEADLINE=y
|
||||
CONFIG_MQ_IOSCHED_KYBER=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_PTP_CLASSIFY=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NO_IOPORT_MAP=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_NVMEM=y
|
||||
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_OID_REGISTRY=y
|
||||
CONFIG_PADATA=y
|
||||
CONFIG_PAGE_POOL=y
|
||||
CONFIG_PARTITION_PERCPU=y
|
||||
CONFIG_PCS_XPCS=y
|
||||
CONFIG_PGTABLE_LEVELS=4
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYLINK=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_PHY_MESON8B_USB2=y
|
||||
CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=y
|
||||
CONFIG_PHY_MESON_AXG_PCIE=y
|
||||
# CONFIG_PHY_MESON_G12A_USB2 is not set
|
||||
# CONFIG_PHY_MESON_G12A_USB3_PCIE is not set
|
||||
CONFIG_PHY_MESON_GXL_USB2=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_MESON=y
|
||||
CONFIG_PINCTRL_MESON8_PMX=y
|
||||
# CONFIG_PINCTRL_MESON_A1 is not set
|
||||
# CONFIG_PINCTRL_MESON_AXG is not set
|
||||
# CONFIG_PINCTRL_MESON_G12A is not set
|
||||
CONFIG_PINCTRL_MESON_GXBB=y
|
||||
CONFIG_PINCTRL_MESON_GXL=y
|
||||
CONFIG_PKCS7_MESSAGE_PARSER=y
|
||||
# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set
|
||||
CONFIG_PLATFORM_MHU=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_SUPPLY=y
|
||||
CONFIG_POWER_SUPPLY_HWMON=y
|
||||
CONFIG_PPS=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_PTP_1588_CLOCK=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_MESON=y
|
||||
CONFIG_PWM_SYSFS=y
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_QUEUED_SPINLOCKS=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_RCU_NEED_SEGCBLIST=y
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RC_CORE=y
|
||||
CONFIG_RC_DEVICES=y
|
||||
# CONFIG_RC_XBOX_DVD is not set
|
||||
CONFIG_REALTEK_AUTOPM=y
|
||||
CONFIG_REALTEK_PHY=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_DEBUG=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_GPIO=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RESET_MESON=y
|
||||
# CONFIG_RESET_MESON_AUDIO_ARB is not set
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SDIO_UART=y
|
||||
# CONFIG_SECONDARY_TRUSTED_KEYRING is not set
|
||||
CONFIG_SENSORS_ARM_SCPI=y
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_MESON=y
|
||||
CONFIG_SERIAL_MESON_CONSOLE=y
|
||||
CONFIG_SG_POOL=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SOC_BUS=y
|
||||
CONFIG_SPARSEMEM=y
|
||||
CONFIG_SPARSEMEM_EXTREME=y
|
||||
CONFIG_SPARSEMEM_MANUAL=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MESON_SPICC=y
|
||||
CONFIG_SPI_MESON_SPIFC=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_STACKTRACE=y
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_STMMAC_PLATFORM=y
|
||||
# CONFIG_STMMAC_SELFTESTS is not set
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYNC_FILE=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
|
||||
CONFIG_SYSTEM_TRUSTED_KEYRING=y
|
||||
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_TUN=y
|
||||
CONFIG_UNMAP_KERNEL_AT_EL0=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_DWC2=y
|
||||
CONFIG_USB_DWC2_DUAL_ROLE=y
|
||||
CONFIG_USB_DWC3=y
|
||||
CONFIG_USB_DWC3_DUAL_ROLE=y
|
||||
# CONFIG_USB_DWC3_GADGET is not set
|
||||
# CONFIG_USB_DWC3_HOST is not set
|
||||
CONFIG_USB_DWC3_MESON_G12A=y
|
||||
CONFIG_USB_DWC3_OF_SIMPLE=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
# CONFIG_USB_ETH is not set
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_OTG=y
|
||||
CONFIG_USB_OTG_FSM=y
|
||||
CONFIG_USB_PHY=y
|
||||
# CONFIG_USB_PULSE8_CEC is not set
|
||||
# CONFIG_USB_RAINSHADOW_CEC is not set
|
||||
CONFIG_USB_ROLE_SWITCH=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_REALTEK=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USB_ULPI=y
|
||||
CONFIG_USB_ULPI_VIEWPORT=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_PLATFORM=y
|
||||
CONFIG_VIDEOMODE_HELPERS=y
|
||||
CONFIG_VMAP_STACK=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_X509_CERTIFICATE_PARSER=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_ZONE_DMA32=y
|
@ -0,0 +1,313 @@
|
||||
From 6515c017a89844b13e041b739cba63ca1fd5dcb2 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 3 May 2022 00:08:56 +0900
|
||||
Subject: [PATCH 001/171] arm64: dts: apple: Add CPU topology & cpufreq nodes
|
||||
for t8103
|
||||
|
||||
Add the missing CPU topology/capacity information and the cpufreq nodes,
|
||||
so we can have CPU frequency scaling and the scheduler has the
|
||||
information it needs to make the correct decisions.
|
||||
|
||||
Boost states are commented out, as they are not yet available (that
|
||||
requires CPU deep sleep support, to be eventually done via PSCI).
|
||||
The driver supports them fine; the hardware will just refuse to ever
|
||||
go into them at this time, so don't expose them to users until that's
|
||||
done.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 203 +++++++++++++++++++++++++--
|
||||
1 file changed, 193 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index 9f8f4145db88..3df126a5a7dd 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -22,71 +22,245 @@ cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
- cpu0: cpu@0 {
|
||||
+ cpu-map {
|
||||
+ cluster0 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_e0>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_e1>;
|
||||
+ };
|
||||
+ core2 {
|
||||
+ cpu = <&cpu_e2>;
|
||||
+ };
|
||||
+ core3 {
|
||||
+ cpu = <&cpu_e3>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cluster1 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_p0>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_p1>;
|
||||
+ };
|
||||
+ core2 {
|
||||
+ cpu = <&cpu_p2>;
|
||||
+ };
|
||||
+ core3 {
|
||||
+ cpu = <&cpu_p3>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cpu_e0: cpu@0 {
|
||||
compatible = "apple,icestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&ecluster_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 0>;
|
||||
};
|
||||
|
||||
- cpu1: cpu@1 {
|
||||
+ cpu_e1: cpu@1 {
|
||||
compatible = "apple,icestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&ecluster_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 0>;
|
||||
};
|
||||
|
||||
- cpu2: cpu@2 {
|
||||
+ cpu_e2: cpu@2 {
|
||||
compatible = "apple,icestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x2>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&ecluster_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 0>;
|
||||
};
|
||||
|
||||
- cpu3: cpu@3 {
|
||||
+ cpu_e3: cpu@3 {
|
||||
compatible = "apple,icestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x3>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&ecluster_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 0>;
|
||||
};
|
||||
|
||||
- cpu4: cpu@10100 {
|
||||
+ cpu_p0: cpu@10100 {
|
||||
compatible = "apple,firestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x10100>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&pcluster_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
};
|
||||
|
||||
- cpu5: cpu@10101 {
|
||||
+ cpu_p1: cpu@10101 {
|
||||
compatible = "apple,firestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x10101>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&pcluster_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
};
|
||||
|
||||
- cpu6: cpu@10102 {
|
||||
+ cpu_p2: cpu@10102 {
|
||||
compatible = "apple,firestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x10102>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&pcluster_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
};
|
||||
|
||||
- cpu7: cpu@10103 {
|
||||
+ cpu_p3: cpu@10103 {
|
||||
compatible = "apple,firestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x10103>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&pcluster_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ ecluster_opp: opp-table-0 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp01 {
|
||||
+ opp-hz = /bits/ 64 <600000000>;
|
||||
+ opp-level = <1>;
|
||||
+ clock-latency-ns = <7500>;
|
||||
+ };
|
||||
+ opp02 {
|
||||
+ opp-hz = /bits/ 64 <972000000>;
|
||||
+ opp-level = <2>;
|
||||
+ clock-latency-ns = <22000>;
|
||||
+ };
|
||||
+ opp03 {
|
||||
+ opp-hz = /bits/ 64 <1332000000>;
|
||||
+ opp-level = <3>;
|
||||
+ clock-latency-ns = <27000>;
|
||||
+ };
|
||||
+ opp04 {
|
||||
+ opp-hz = /bits/ 64 <1704000000>;
|
||||
+ opp-level = <4>;
|
||||
+ clock-latency-ns = <33000>;
|
||||
+ };
|
||||
+ opp05 {
|
||||
+ opp-hz = /bits/ 64 <2064000000>;
|
||||
+ opp-level = <5>;
|
||||
+ clock-latency-ns = <50000>;
|
||||
};
|
||||
};
|
||||
|
||||
+ pcluster_opp: opp-table-1 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp01 {
|
||||
+ opp-hz = /bits/ 64 <600000000>;
|
||||
+ opp-level = <1>;
|
||||
+ clock-latency-ns = <8000>;
|
||||
+ };
|
||||
+ opp02 {
|
||||
+ opp-hz = /bits/ 64 <828000000>;
|
||||
+ opp-level = <2>;
|
||||
+ clock-latency-ns = <19000>;
|
||||
+ };
|
||||
+ opp03 {
|
||||
+ opp-hz = /bits/ 64 <1056000000>;
|
||||
+ opp-level = <3>;
|
||||
+ clock-latency-ns = <21000>;
|
||||
+ };
|
||||
+ opp04 {
|
||||
+ opp-hz = /bits/ 64 <1284000000>;
|
||||
+ opp-level = <4>;
|
||||
+ clock-latency-ns = <23000>;
|
||||
+ };
|
||||
+ opp05 {
|
||||
+ opp-hz = /bits/ 64 <1500000000>;
|
||||
+ opp-level = <5>;
|
||||
+ clock-latency-ns = <24000>;
|
||||
+ };
|
||||
+ opp06 {
|
||||
+ opp-hz = /bits/ 64 <1728000000>;
|
||||
+ opp-level = <6>;
|
||||
+ clock-latency-ns = <29000>;
|
||||
+ };
|
||||
+ opp07 {
|
||||
+ opp-hz = /bits/ 64 <1956000000>;
|
||||
+ opp-level = <7>;
|
||||
+ clock-latency-ns = <31000>;
|
||||
+ };
|
||||
+ opp08 {
|
||||
+ opp-hz = /bits/ 64 <2184000000>;
|
||||
+ opp-level = <8>;
|
||||
+ clock-latency-ns = <34000>;
|
||||
+ };
|
||||
+ opp09 {
|
||||
+ opp-hz = /bits/ 64 <2388000000>;
|
||||
+ opp-level = <9>;
|
||||
+ clock-latency-ns = <36000>;
|
||||
+ };
|
||||
+ opp10 {
|
||||
+ opp-hz = /bits/ 64 <2592000000>;
|
||||
+ opp-level = <10>;
|
||||
+ clock-latency-ns = <51000>;
|
||||
+ };
|
||||
+ opp11 {
|
||||
+ opp-hz = /bits/ 64 <2772000000>;
|
||||
+ opp-level = <11>;
|
||||
+ clock-latency-ns = <54000>;
|
||||
+ };
|
||||
+ opp12 {
|
||||
+ opp-hz = /bits/ 64 <2988000000>;
|
||||
+ opp-level = <12>;
|
||||
+ clock-latency-ns = <55000>;
|
||||
+ };
|
||||
+#if 0
|
||||
+ /* Not available until CPU deep sleep is implemented */
|
||||
+ opp13 {
|
||||
+ opp-hz = /bits/ 64 <3096000000>;
|
||||
+ opp-level = <13>;
|
||||
+ clock-latency-ns = <55000>;
|
||||
+ turbo-mode;
|
||||
+ };
|
||||
+ opp14 {
|
||||
+ opp-hz = /bits/ 64 <3144000000>;
|
||||
+ opp-level = <14>;
|
||||
+ clock-latency-ns = <56000>;
|
||||
+ turbo-mode;
|
||||
+ };
|
||||
+ opp15 {
|
||||
+ opp-hz = /bits/ 64 <3204000000>;
|
||||
+ opp-level = <15>;
|
||||
+ clock-latency-ns = <56000>;
|
||||
+ turbo-mode;
|
||||
+ };
|
||||
+#endif
|
||||
+ };
|
||||
+
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupt-parent = <&aic>;
|
||||
@@ -124,6 +298,15 @@ soc {
|
||||
ranges;
|
||||
nonposted-mmio;
|
||||
|
||||
+ cpufreq_hw: cpufreq@210e20000 {
|
||||
+ compatible = "apple,t8103-soc-cpufreq", "apple,soc-cpufreq";
|
||||
+ reg = <0x2 0x10e20000 0 0x1000>,
|
||||
+ <0x2 0x11e20000 0 0x1000>;
|
||||
+ reg-names = "cluster0", "cluster1";
|
||||
+
|
||||
+ #freq-domain-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
i2c0: i2c@235010000 {
|
||||
compatible = "apple,t8103-i2c", "apple,i2c";
|
||||
reg = <0x2 0x35010000 0x0 0x4000>;
|
||||
@@ -229,12 +412,12 @@ aic: interrupt-controller@23b100000 {
|
||||
affinities {
|
||||
e-core-pmu-affinity {
|
||||
apple,fiq-index = <AIC_CPU_PMU_E>;
|
||||
- cpus = <&cpu0 &cpu1 &cpu2 &cpu3>;
|
||||
+ cpus = <&cpu_e0 &cpu_e1 &cpu_e2 &cpu_e3>;
|
||||
};
|
||||
|
||||
p-core-pmu-affinity {
|
||||
apple,fiq-index = <AIC_CPU_PMU_P>;
|
||||
- cpus = <&cpu4 &cpu5 &cpu6 &cpu7>;
|
||||
+ cpus = <&cpu_p0 &cpu_p1 &cpu_p2 &cpu_p3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,56 @@
|
||||
From a994e9c9c1e45fbffeb9844c182e27c58c208404 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Thu, 9 Dec 2021 17:22:51 +0100
|
||||
Subject: [PATCH 002/171] arm64: dts: apple: t8103: Add ANS2 nodes
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 33 ++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index 3df126a5a7dd..66544e39a20a 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -561,6 +561,39 @@ pinctrl_aop: pinctrl@24a820000 {
|
||||
<AIC_IRQ 274 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
+ ans_mbox: mbox@277408000 {
|
||||
+ compatible = "apple,t8103-asc-mailbox", "apple,asc-mailbox-v4";
|
||||
+ reg = <0x2 0x77408000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 583 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 584 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 585 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 586 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "send-empty", "send-not-empty",
|
||||
+ "recv-empty", "recv-not-empty";
|
||||
+ #mbox-cells = <0>;
|
||||
+ power-domains = <&ps_ans2>;
|
||||
+ };
|
||||
+
|
||||
+ sart: sart@27bc50000 {
|
||||
+ compatible = "apple,t8103-sart", "apple,sart2";
|
||||
+ reg = <0x2 0x7bc50000 0x0 0x10000>;
|
||||
+ power-domains = <&ps_ans2>;
|
||||
+ };
|
||||
+
|
||||
+ nvme@27bcc0000 {
|
||||
+ compatible = "apple,t8103-nvme-ans2", "apple,nvme-ans2";
|
||||
+ reg = <0x2 0x7bcc0000 0x0 0x40000>,
|
||||
+ <0x2 0x77400000 0x0 0x4000>;
|
||||
+ reg-names = "nvme", "ans";
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 590 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ mboxes = <&ans_mbox>;
|
||||
+ apple,sart = <&sart>;
|
||||
+ power-domains = <&ps_ans2>;
|
||||
+ resets = <&ps_ans2>;
|
||||
+ };
|
||||
+
|
||||
pcie0_dart_0: dart@681008000 {
|
||||
compatible = "apple,t8103-dart";
|
||||
reg = <0x6 0x81008000 0x0 0x4000>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,274 @@
|
||||
From ba2a0e6cfe463e97ee1056dd45d7fd4eee24bf09 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Fri, 26 Nov 2021 15:37:23 +0900
|
||||
Subject: [PATCH 003/171] arm64: dts: apple: t8103: Add dwc3 nodes
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j274.dts | 12 +++++
|
||||
arch/arm64/boot/dts/apple/t8103-j293.dts | 12 +++++
|
||||
arch/arm64/boot/dts/apple/t8103-j313.dts | 12 +++++
|
||||
arch/arm64/boot/dts/apple/t8103-j456.dts | 12 +++++
|
||||
arch/arm64/boot/dts/apple/t8103-j457.dts | 12 +++++
|
||||
arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 51 +++++++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 60 +++++++++++++++++++++++
|
||||
7 files changed, 171 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
index 2cd429efba5b..214476814797 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
@@ -21,6 +21,18 @@ aliases {
|
||||
};
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Provide labels for the USB type C ports.
|
||||
+ */
|
||||
+
|
||||
+&typec0 {
|
||||
+ label = "USB-C Back-left";
|
||||
+};
|
||||
+
|
||||
+&typec1 {
|
||||
+ label = "USB-C Back-right";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Force the bus number assignments so that we can declare some of the
|
||||
* on-board devices and properties that are populated by the bootloader
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
index 49cdf4b560a3..6f08fd64f482 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
@@ -17,6 +17,18 @@ / {
|
||||
model = "Apple MacBook Pro (13-inch, M1, 2020)";
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Provide labels for the USB type C ports.
|
||||
+ */
|
||||
+
|
||||
+&typec0 {
|
||||
+ label = "USB-C Left-back";
|
||||
+};
|
||||
+
|
||||
+&typec1 {
|
||||
+ label = "USB-C Left-front";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Remove unused PCIe ports and disable the associated DARTs.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
index b0ebb45bdb6f..114aa87c8cb4 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
@@ -17,6 +17,18 @@ / {
|
||||
model = "Apple MacBook Air (M1, 2020)";
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Provide labels for the USB type C ports.
|
||||
+ */
|
||||
+
|
||||
+&typec0 {
|
||||
+ label = "USB-C Left-back";
|
||||
+};
|
||||
+
|
||||
+&typec1 {
|
||||
+ label = "USB-C Left-front";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Remove unused PCIe ports and disable the associated DARTs.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
index 884fddf7d363..9814c97cd9ba 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
@@ -39,6 +39,18 @@ hpm3: usb-pd@3c {
|
||||
};
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Provide labels for the USB type C ports.
|
||||
+ */
|
||||
+
|
||||
+&typec0 {
|
||||
+ label = "USB-C Back-right";
|
||||
+};
|
||||
+
|
||||
+&typec1 {
|
||||
+ label = "USB-C Back-right-middle";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Force the bus number assignments so that we can declare some of the
|
||||
* on-board devices and properties that are populated by the bootloader
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
index d7c622931627..0f4cc643741c 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
@@ -21,6 +21,18 @@ aliases {
|
||||
};
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Provide labels for the USB type C ports.
|
||||
+ */
|
||||
+
|
||||
+&typec0 {
|
||||
+ label = "USB-C Back-right";
|
||||
+};
|
||||
+
|
||||
+&typec1 {
|
||||
+ label = "USB-C Back-left";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Force the bus number assignments so that we can declare some of the
|
||||
* on-board devices and properties that are populated by the bootloader
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
index fe2ae40fa9dd..020a9d8b31e9 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
@@ -52,6 +52,23 @@ hpm0: usb-pd@38 {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <106 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec0: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec0_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm1: usb-pd@3f {
|
||||
@@ -60,6 +77,40 @@ hpm1: usb-pd@3f {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <106 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec1: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec1_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* USB controllers */
|
||||
+&dwc3_0 {
|
||||
+ port {
|
||||
+ typec0_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_1 {
|
||||
+ port {
|
||||
+ typec1_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_con_hs>;
|
||||
+ };
|
||||
};
|
||||
};
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index 66544e39a20a..ec7234cdc861 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -594,6 +594,66 @@ nvme@27bcc0000 {
|
||||
resets = <&ps_ans2>;
|
||||
};
|
||||
|
||||
+ dwc3_0: usb@382280000 {
|
||||
+ compatible = "apple,t8103-dwc3", "apple,dwc3", "snps,dwc3";
|
||||
+ reg = <0x3 0x82280000 0x0 0x100000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 777 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ dr_mode = "otg";
|
||||
+ usb-role-switch;
|
||||
+ role-switch-default-mode = "host";
|
||||
+ iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>;
|
||||
+ power-domains = <&ps_atc0_usb>;
|
||||
+ };
|
||||
+
|
||||
+ dwc3_0_dart_0: iommu@382f00000 {
|
||||
+ compatible = "apple,t8103-dart";
|
||||
+ reg = <0x3 0x82f00000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ power-domains = <&ps_atc0_usb>;
|
||||
+ };
|
||||
+
|
||||
+ dwc3_0_dart_1: iommu@382f80000 {
|
||||
+ compatible = "apple,t8103-dart";
|
||||
+ reg = <0x3 0x82f80000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ power-domains = <&ps_atc0_usb>;
|
||||
+ };
|
||||
+
|
||||
+ dwc3_1: usb@502280000 {
|
||||
+ compatible = "apple,t8103-dwc3", "apple,dwc3", "snps,dwc3";
|
||||
+ reg = <0x5 0x02280000 0x0 0x100000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 857 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ dr_mode = "otg";
|
||||
+ usb-role-switch;
|
||||
+ role-switch-default-mode = "host";
|
||||
+ iommus = <&dwc3_1_dart_0 0>, <&dwc3_1_dart_1 1>;
|
||||
+ power-domains = <&ps_atc1_usb>;
|
||||
+ };
|
||||
+
|
||||
+ dwc3_1_dart_0: iommu@502f00000 {
|
||||
+ compatible = "apple,t8103-dart";
|
||||
+ reg = <0x5 0x02f00000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ power-domains = <&ps_atc1_usb>;
|
||||
+ };
|
||||
+
|
||||
+ dwc3_1_dart_1: iommu@502f80000 {
|
||||
+ compatible = "apple,t8103-dart";
|
||||
+ reg = <0x5 0x02f80000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ power-domains = <&ps_atc1_usb>;
|
||||
+ };
|
||||
+
|
||||
pcie0_dart_0: dart@681008000 {
|
||||
compatible = "apple,t8103-dart";
|
||||
reg = <0x6 0x81008000 0x0 0x4000>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,133 @@
|
||||
From 226311814eda36c1ad693189e5402ced55e91f11 Mon Sep 17 00:00:00 2001
|
||||
From: Janne Grunau <j@jannau.net>
|
||||
Date: Fri, 26 Nov 2021 00:24:15 +0100
|
||||
Subject: [PATCH 004/171] arm64: dts: apple: t8103: Add spi3/keyboard nodes
|
||||
|
||||
Enables keyboard and touchpad input on MacBook Air (M1, 2020) and
|
||||
MacBook Pro (13-inch, M1, 2020).
|
||||
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j293.dts | 20 +++++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103-j313.dts | 20 +++++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 28 ++++++++++++++++++++++++
|
||||
3 files changed, 68 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
index 6f08fd64f482..9405e97a85f2 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
@@ -29,6 +29,26 @@ &typec1 {
|
||||
label = "USB-C Left-front";
|
||||
};
|
||||
|
||||
+&spi3 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ hid-transport@0 {
|
||||
+ compatible = "apple,spi-hid-transport";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <8000000>;
|
||||
+ /*
|
||||
+ * cs-setup and cs-hold delays are derived from Apple's ADT
|
||||
+ * Mac OS driver meta data secify 45 us for 'cs to clock' and
|
||||
+ * 'clock to cs' delays.
|
||||
+ */
|
||||
+ spi-cs-setup-delay-ns = <20000>;
|
||||
+ spi-cs-hold-delay-ns = <20000>;
|
||||
+ spi-cs-inactive-delay-ns = <250000>;
|
||||
+ spien-gpios = <&pinctrl_ap 195 0>;
|
||||
+ interrupts-extended = <&pinctrl_nub 13 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Remove unused PCIe ports and disable the associated DARTs.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
index 114aa87c8cb4..bc84f8af0b1d 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
@@ -29,6 +29,26 @@ &typec1 {
|
||||
label = "USB-C Left-front";
|
||||
};
|
||||
|
||||
+&spi3 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ hid-transport@0 {
|
||||
+ compatible = "apple,spi-hid-transport";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <8000000>;
|
||||
+ /*
|
||||
+ * cs-setup and cs-hold delays are derived from Apple's ADT
|
||||
+ * Mac OS driver meta data secify 45 us for 'cs to clock' and
|
||||
+ * 'clock to cs' delays.
|
||||
+ */
|
||||
+ spi-cs-setup-delay-ns = <20000>;
|
||||
+ spi-cs-hold-delay-ns = <20000>;
|
||||
+ spi-cs-inactive-delay-ns = <250000>;
|
||||
+ spien-gpios = <&pinctrl_ap 195 0>;
|
||||
+ interrupts-extended = <&pinctrl_nub 13 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Remove unused PCIe ports and disable the associated DARTs.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index ec7234cdc861..9750438c30dd 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -290,6 +290,13 @@ clkref: clock-ref {
|
||||
clock-output-names = "clkref";
|
||||
};
|
||||
|
||||
+ clk_120m: clock-120m {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <120000000>;
|
||||
+ clock-output-names = "clk_120m";
|
||||
+ };
|
||||
+
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <2>;
|
||||
@@ -374,6 +381,20 @@ i2c4: i2c@235020000 {
|
||||
status = "disabled"; /* only used in J293 */
|
||||
};
|
||||
|
||||
+ spi3: spi@23510c000 {
|
||||
+ compatible = "apple,t8103-spi", "apple,spi";
|
||||
+ reg = <0x2 0x3510c000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 617 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&clk_120m>;
|
||||
+ pinctrl-0 = <&spi3_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ power-domains = <&ps_spi3>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled"; /* only used in J293/J313 */
|
||||
+ };
|
||||
+
|
||||
serial0: serial@235200000 {
|
||||
compatible = "apple,s5l-uart";
|
||||
reg = <0x2 0x35200000 0x0 0x1000>;
|
||||
@@ -475,6 +496,13 @@ i2c4_pins: i2c4-pins {
|
||||
<APPLE_PINMUX(134, 1)>;
|
||||
};
|
||||
|
||||
+ spi3_pins: spi3-pins {
|
||||
+ pinmux = <APPLE_PINMUX(46, 1)>,
|
||||
+ <APPLE_PINMUX(47, 1)>,
|
||||
+ <APPLE_PINMUX(48, 1)>,
|
||||
+ <APPLE_PINMUX(49, 1)>;
|
||||
+ };
|
||||
+
|
||||
pcie_pins: pcie-pins {
|
||||
pinmux = <APPLE_PINMUX(150, 1)>,
|
||||
<APPLE_PINMUX(151, 1)>,
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,40 @@
|
||||
From d1cc45edca0943c77a7125cb9de0300329314169 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sat, 19 Mar 2022 05:50:47 +0900
|
||||
Subject: [PATCH 005/171] arm64: dts: apple: Fix j45x model years
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j456.dts | 2 +-
|
||||
arch/arm64/boot/dts/apple/t8103-j457.dts | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
index 9814c97cd9ba..bb48255250c7 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/ {
|
||||
compatible = "apple,j456", "apple,t8103", "apple,arm-platform";
|
||||
- model = "Apple iMac (24-inch, 4x USB-C, M1, 2020)";
|
||||
+ model = "Apple iMac (24-inch, 4x USB-C, M1, 2021)";
|
||||
|
||||
aliases {
|
||||
ethernet0 = ðernet0;
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
index 0f4cc643741c..80600c3fa769 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/ {
|
||||
compatible = "apple,j457", "apple,t8103", "apple,arm-platform";
|
||||
- model = "Apple iMac (24-inch, 2x USB-C, M1, 2020)";
|
||||
+ model = "Apple iMac (24-inch, 2x USB-C, M1, 2021)";
|
||||
|
||||
aliases {
|
||||
ethernet0 = ðernet0;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,112 @@
|
||||
From 30c1cffd27d0154787eba4a4a2e9c6a3e7504879 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:07:17 +0900
|
||||
Subject: [PATCH 006/171] arm64: dts: apple: Add WiFi module and antenna
|
||||
properties
|
||||
|
||||
Add the new module-instance/antenna-sku properties required to select
|
||||
WiFi firmwares properly to all board device trees.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j274.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j293.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j313.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j456.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j457.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 2 ++
|
||||
6 files changed, 22 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
index 214476814797..aaa3019a4db2 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
@@ -21,6 +21,10 @@ aliases {
|
||||
};
|
||||
};
|
||||
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,atlantisb";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
index 9405e97a85f2..4f5f7d38e799 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
@@ -17,6 +17,10 @@ / {
|
||||
model = "Apple MacBook Pro (13-inch, M1, 2020)";
|
||||
};
|
||||
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,honshu";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
index bc84f8af0b1d..d6722d8809d1 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
@@ -17,6 +17,10 @@ / {
|
||||
model = "Apple MacBook Air (M1, 2020)";
|
||||
};
|
||||
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,shikoku";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
index bb48255250c7..3d0a91ac29ae 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
@@ -21,6 +21,10 @@ aliases {
|
||||
};
|
||||
};
|
||||
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,capri";
|
||||
+};
|
||||
+
|
||||
&i2c0 {
|
||||
hpm2: usb-pd@3b {
|
||||
compatible = "apple,cd321x";
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
index 80600c3fa769..7e3a0e95e837 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
@@ -21,6 +21,10 @@ aliases {
|
||||
};
|
||||
};
|
||||
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,santorini";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
index 020a9d8b31e9..4fb89066bd17 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
@@ -122,8 +122,10 @@ typec1_usb_hs: endpoint {
|
||||
&port00 {
|
||||
bus-range = <1 1>;
|
||||
wifi0: network@0,0 {
|
||||
+ compatible = "pci14e4,4425";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
/* To be filled by the loader */
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
+ apple,antenna-sku = "XX";
|
||||
};
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 8d2ddaeace21e3960326fb52a052083b5a1f5e1d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 6 Feb 2022 21:22:29 +0900
|
||||
Subject: [PATCH 007/171] arm64: dts: apple: Add PCI power enable GPIOs
|
||||
|
||||
t8103:
|
||||
- WLAN (SMC PMU GPIO #13)
|
||||
t600x:
|
||||
- WLAN (SMC PMU GPIO #13)
|
||||
- SD (SMC PMU GPIO #26)
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
index 4fb89066bd17..e62664b6e450 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
@@ -121,6 +121,7 @@ typec1_usb_hs: endpoint {
|
||||
*/
|
||||
&port00 {
|
||||
bus-range = <1 1>;
|
||||
+ pwren-gpios = <&smc_gpio 13 GPIO_ACTIVE_HIGH>;
|
||||
wifi0: network@0,0 {
|
||||
compatible = "pci14e4,4425";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,51 @@
|
||||
From 6728598e7a5a5fb2cb05c65294269b6844b1ea5d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Fri, 4 Feb 2022 12:59:39 +0900
|
||||
Subject: [PATCH 008/171] arm64: dts: apple: Add SMC node to t8103/t6001
|
||||
devicetrees
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 26 ++++++++++++++++++++++++++
|
||||
1 file changed, 26 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index 9750438c30dd..23cc325a49bb 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -547,6 +547,32 @@ wdt: watchdog@23d2b0000 {
|
||||
interrupts = <AIC_IRQ 338 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
+ smc_mbox: mbox@23e408000 {
|
||||
+ compatible = "apple,t8103-asc-mailbox", "apple,asc-mailbox-v4";
|
||||
+ reg = <0x2 0x3e408000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 400 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 401 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 402 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 403 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "send-empty", "send-not-empty",
|
||||
+ "recv-empty", "recv-not-empty";
|
||||
+ #mbox-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ smc: smc@23e400000 {
|
||||
+ compatible = "apple,t8103-smc", "apple,smc";
|
||||
+ reg = <0x2 0x3e400000 0x0 0x4000>,
|
||||
+ <0x2 0x3fe00000 0x0 0x100000>;
|
||||
+ reg-names = "smc", "sram";
|
||||
+ mboxes = <&smc_mbox>;
|
||||
+
|
||||
+ smc_gpio: gpio {
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
pinctrl_smc: pinctrl@23e820000 {
|
||||
compatible = "apple,t8103-pinctrl", "apple,pinctrl";
|
||||
reg = <0x2 0x3e820000 0x0 0x4000>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,127 @@
|
||||
From aee7c563697559e06f306d8a9e1b5a33c5c330d9 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 15 Feb 2022 18:54:35 +0900
|
||||
Subject: [PATCH 009/171] arm64: dts: apple: Add PMU NVMEM and SMC RTC/reboot
|
||||
nodes
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 88 ++++++++++++++++++++++++++++
|
||||
1 file changed, 88 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index 23cc325a49bb..c2fb4f32590c 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <dt-bindings/interrupt-controller/apple-aic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/pinctrl/apple.h>
|
||||
+#include <dt-bindings/spmi/spmi.h>
|
||||
|
||||
/ {
|
||||
compatible = "apple,t8103", "apple,arm-platform";
|
||||
@@ -510,6 +511,81 @@ pcie_pins: pcie-pins {
|
||||
};
|
||||
};
|
||||
|
||||
+ nub_spmi: spmi@23d0d9300 {
|
||||
+ compatible = "apple,t8103-spmi", "apple,spmi";
|
||||
+ reg = <0x2 0x3d0d9300 0x0 0x100>;
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ pmu1: pmu@f {
|
||||
+ compatible = "apple,sera-pmu", "apple,spmi-pmu";
|
||||
+ reg = <0xf SPMI_USID>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ rtc_nvmem@d000 {
|
||||
+ compatible = "apple,spmi-pmu-nvmem";
|
||||
+ reg = <0xd000 0x300>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ pm_setting: pm-setting@1 {
|
||||
+ reg = <0x1 0x1>;
|
||||
+ };
|
||||
+
|
||||
+ rtc_offset: rtc-offset@100 {
|
||||
+ reg = <0x100 0x6>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ legacy_nvmem@9f00 {
|
||||
+ compatible = "apple,spmi-pmu-nvmem";
|
||||
+ reg = <0x9f00 0x20>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ boot_stage: boot-stage@1 {
|
||||
+ reg = <0x1 0x1>;
|
||||
+ };
|
||||
+
|
||||
+ boot_error_count: boot-error-count@2 {
|
||||
+ reg = <0x2 0x1>;
|
||||
+ bits = <0 4>;
|
||||
+ };
|
||||
+
|
||||
+ panic_count: panic-count@2 {
|
||||
+ reg = <0x2 0x1>;
|
||||
+ bits = <4 4>;
|
||||
+ };
|
||||
+
|
||||
+ boot_error_stage: boot-error-stage@3 {
|
||||
+ reg = <0x3 0x1>;
|
||||
+ };
|
||||
+
|
||||
+ shutdown_flag: shutdown-flag@f {
|
||||
+ reg = <0xf 0x1>;
|
||||
+ bits = <3 1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ scrpad_nvmem@a000 {
|
||||
+ compatible = "apple,spmi-pmu-nvmem";
|
||||
+ reg = <0xa000 0x1000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ fault_shadow: fault-shadow@67b {
|
||||
+ reg = <0x67b 0x10>;
|
||||
+ };
|
||||
+
|
||||
+ socd: socd@b00 {
|
||||
+ reg = <0xb00 0x400>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
pinctrl_nub: pinctrl@23d1f0000 {
|
||||
compatible = "apple,t8103-pinctrl", "apple,pinctrl";
|
||||
reg = <0x2 0x3d1f0000 0x0 0x4000>;
|
||||
@@ -571,6 +647,18 @@ smc_gpio: gpio {
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
+
|
||||
+ smc_rtc: rtc {
|
||||
+ nvmem-cells = <&rtc_offset>;
|
||||
+ nvmem-cell-names = "rtc_offset";
|
||||
+ };
|
||||
+
|
||||
+ smc_reboot: reboot {
|
||||
+ nvmem-cells = <&shutdown_flag>, <&boot_stage>,
|
||||
+ <&boot_error_count>, <&panic_count>, <&pm_setting>;
|
||||
+ nvmem-cell-names = "shutdown_flag", "boot_stage",
|
||||
+ "boot_error_count", "panic_count", "pm_setting";
|
||||
+ };
|
||||
};
|
||||
|
||||
pinctrl_smc: pinctrl@23e820000 {
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,56 @@
|
||||
From ed05baab200d58bdc024e7797780a1d95677dce3 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Wed, 2 Mar 2022 23:23:51 +0900
|
||||
Subject: [PATCH 010/171] arm64: dts: apple: Re-parent ANS2 power domains
|
||||
|
||||
Turns out that the APCIE_ST*_SYS domains do hard-depend on ANS2, so
|
||||
without this they refuse to power up.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-pmgr.dtsi | 7 +------
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 3 ++-
|
||||
2 files changed, 3 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
index fc51bc872468..a6dbb1f485d8 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
@@ -725,11 +725,6 @@ ps_ans2: power-controller@3f0 {
|
||||
#power-domain-cells = <0>;
|
||||
#reset-cells = <0>;
|
||||
label = "ans2";
|
||||
- /*
|
||||
- * The ADT makes ps_apcie_st depend on ps_ans2 instead, but this
|
||||
- * doesn't make much sense since ANS2 uses APCIE_ST.
|
||||
- */
|
||||
- power-domains = <&ps_apcie_st>;
|
||||
};
|
||||
|
||||
ps_gfx: power-controller@3f8 {
|
||||
@@ -836,7 +831,7 @@ ps_apcie_st: power-controller@418 {
|
||||
#power-domain-cells = <0>;
|
||||
#reset-cells = <0>;
|
||||
label = "apcie_st";
|
||||
- power-domains = <&ps_apcie>;
|
||||
+ power-domains = <&ps_apcie>, <&ps_ans2>;
|
||||
};
|
||||
|
||||
ps_ane_sys: power-controller@470 {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index c2fb4f32590c..f96a732e6211 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -732,7 +732,8 @@ nvme@27bcc0000 {
|
||||
interrupts = <AIC_IRQ 590 IRQ_TYPE_LEVEL_HIGH>;
|
||||
mboxes = <&ans_mbox>;
|
||||
apple,sart = <&sart>;
|
||||
- power-domains = <&ps_ans2>;
|
||||
+ power-domains = <&ps_ans2>, <&ps_apcie_st>;
|
||||
+ power-domain-names = "ans", "apcie0";
|
||||
resets = <&ps_ans2>;
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,39 @@
|
||||
From b348548945561245a2aea95ef9a9b5afe1efa78c Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 3 Mar 2022 02:20:39 +0900
|
||||
Subject: [PATCH 011/171] arm64: dts: apple: Mark ATC USB AON domains as
|
||||
always-on
|
||||
|
||||
Shutting these down breaks dwc3 init done by the firmware. We probably
|
||||
never want to do this anyway. It might be possible remove this once
|
||||
a PHY driver is in place to do the init properly, but it may not be
|
||||
worth it.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-pmgr.dtsi | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
index a6dbb1f485d8..926b1e54b64b 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
@@ -1103,6 +1103,7 @@ ps_atc0_usb_aon: power-controller@88 {
|
||||
#power-domain-cells = <0>;
|
||||
#reset-cells = <0>;
|
||||
label = "atc0_usb_aon";
|
||||
+ apple,always-on; /* Needs to stay on for dwc3 to work */
|
||||
};
|
||||
|
||||
ps_atc1_usb_aon: power-controller@90 {
|
||||
@@ -1111,6 +1112,7 @@ ps_atc1_usb_aon: power-controller@90 {
|
||||
#power-domain-cells = <0>;
|
||||
#reset-cells = <0>;
|
||||
label = "atc1_usb_aon";
|
||||
+ apple,always-on; /* Needs to stay on for dwc3 to work */
|
||||
};
|
||||
|
||||
ps_atc0_usb: power-controller@98 {
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 470d9385f7c772c4cb88e0fdfa3484baba9d15c9 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Glanzmann <thomas@glanzmann.de>
|
||||
Date: Mon, 21 Feb 2022 23:01:36 +0100
|
||||
Subject: [PATCH 012/171] arm64: dts: apple: Add backlight node to j293/j313
|
||||
|
||||
It can be turned off with:
|
||||
|
||||
echo 1 > /sys/class/backlight/backlight/bl_power
|
||||
|
||||
It can be turned on with:
|
||||
|
||||
echo 0 > /sys/class/backlight/backlight/bl_power
|
||||
|
||||
Needs CONFIG_BACKLIGHT_GPIO=m.
|
||||
|
||||
Signed-off-by: Thomas Glanzmann <thomas@glanzmann.de>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j293.dts | 12 ++++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103-j313.dts | 12 ++++++++++++
|
||||
2 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
index 4f5f7d38e799..6f1050185a80 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
@@ -75,3 +75,15 @@ &i2c2 {
|
||||
&i2c4 {
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+/ {
|
||||
+ backlight: gpio-bl {
|
||||
+ compatible = "gpio-backlight";
|
||||
+ gpios = <&smc_gpio 18 GPIO_ACTIVE_HIGH>;
|
||||
+ default-on;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&framebuffer0 {
|
||||
+ backlight = <&backlight>;
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
index d6722d8809d1..3e4045c05905 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
@@ -67,3 +67,15 @@ &pcie0_dart_2 {
|
||||
|
||||
/delete-node/ &port01;
|
||||
/delete-node/ &port02;
|
||||
+
|
||||
+/ {
|
||||
+ backlight: gpio-bl {
|
||||
+ compatible = "gpio-backlight";
|
||||
+ gpios = <&smc_gpio 18 GPIO_ACTIVE_HIGH>;
|
||||
+ default-on;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&framebuffer0 {
|
||||
+ backlight = <&backlight>;
|
||||
+};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,438 @@
|
||||
From 3af244a2705f3894814a305428501a614c26fb7a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:49:59 +0100
|
||||
Subject: [PATCH 013/171] arm64: dts: apple: t8103*: Put in audio nodes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j274.dts | 52 +++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103-j293.dts | 85 ++++++++++++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103-j313.dts | 61 +++++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103-j456.dts | 31 +++++++++
|
||||
arch/arm64/boot/dts/apple/t8103-j457.dts | 40 +++++++++++
|
||||
arch/arm64/boot/dts/apple/t8103.dtsi | 73 ++++++++++++++++++++
|
||||
6 files changed, 342 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
index aaa3019a4db2..811008bd73f3 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
@@ -56,6 +56,58 @@ ethernet0: ethernet@0,0 {
|
||||
};
|
||||
};
|
||||
|
||||
+&i2c1 {
|
||||
+ speaker_amp: codec@31 {
|
||||
+ compatible = "ti,tas5770l", "ti,tas2770";
|
||||
+ reg = <0x31>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&i2c2 {
|
||||
status = "okay";
|
||||
+
|
||||
+ jack_codec: codec@48 {
|
||||
+ compatible = "cirrus,cs42l83", "cirrus,cs42l42";
|
||||
+ reg = <0x48>;
|
||||
+ reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <183 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ cirrus,ts-inv = <1>;
|
||||
+ sound-name-prefix = "Jack";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/ {
|
||||
+ sound {
|
||||
+ compatible = "apple,j274-macaudio", "apple,macaudio";
|
||||
+ model = "Mac mini J274 integrated audio";
|
||||
+
|
||||
+ dai-link@0 {
|
||||
+ link-name = "Speaker";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 0>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&speaker_amp>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ dai-link@1 {
|
||||
+ link-name = "Headphone Jack";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 2>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&jack_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
index 6f1050185a80..7eb98e6b947c 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
@@ -68,8 +68,54 @@ &pcie0_dart_2 {
|
||||
/delete-node/ &port01;
|
||||
/delete-node/ &port02;
|
||||
|
||||
+&i2c1 {
|
||||
+ speaker_left_rear: codec@31 {
|
||||
+ compatible = "ti,tas5770l", "ti,tas2770";
|
||||
+ reg = <0x31>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Left Rear";
|
||||
+ };
|
||||
+
|
||||
+ speaker_left_front: codec@32 {
|
||||
+ compatible = "ti,tas5770l", "ti,tas2770";
|
||||
+ reg = <0x32>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Left Front";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&i2c2 {
|
||||
status = "okay";
|
||||
+
|
||||
+ jack_codec: codec@48 {
|
||||
+ compatible = "cirrus,cs42l83", "cirrus,cs42l42";
|
||||
+ reg = <0x48>;
|
||||
+ reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <183 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ cirrus,ts-inv = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c3 {
|
||||
+ speaker_right_rear: codec@34 {
|
||||
+ compatible = "ti,tas5770l", "ti,tas2770";
|
||||
+ reg = <0x34>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Right Rear";
|
||||
+ };
|
||||
+
|
||||
+ speaker_right_front: codec@35 {
|
||||
+ compatible = "ti,tas5770l", "ti,tas2770";
|
||||
+ reg = <0x35>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Right Front";
|
||||
+ };
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
@@ -82,6 +128,45 @@ backlight: gpio-bl {
|
||||
gpios = <&smc_gpio 18 GPIO_ACTIVE_HIGH>;
|
||||
default-on;
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "apple,j293-macaudio", "apple,macaudio";
|
||||
+ model = "MacBook Pro J293 integrated audio";
|
||||
+
|
||||
+ dai-link@0 {
|
||||
+ /*
|
||||
+ * DANGER ZONE: You can blow your speakers!
|
||||
+ *
|
||||
+ * The drivers are not ready, and unless you are careful
|
||||
+ * to attenuate the audio stream, you run the risk of
|
||||
+ * blowing your speakers.
|
||||
+ */
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ link-name = "Speakers";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 0>, <&mca 1>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&speaker_left_front>, <&speaker_right_front>,
|
||||
+ <&speaker_left_rear>, <&speaker_right_rear>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ dai-link@1 {
|
||||
+ link-name = "Headphone Jack";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 2>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&jack_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&framebuffer0 {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
index 3e4045c05905..ad3a6edeb651 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
@@ -68,12 +68,73 @@ &pcie0_dart_2 {
|
||||
/delete-node/ &port01;
|
||||
/delete-node/ &port02;
|
||||
|
||||
+&i2c1 {
|
||||
+ speaker_left: codec@31 {
|
||||
+ compatible = "ti,tas5770l", "ti,tas2770";
|
||||
+ reg = <0x31>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Left";
|
||||
+
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c3 {
|
||||
+ speaker_right: codec@34 {
|
||||
+ compatible = "ti,tas5770l", "ti,tas2770";
|
||||
+ reg = <0x34>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Right";
|
||||
+ };
|
||||
+
|
||||
+ jack_codec: codec@48 {
|
||||
+ compatible = "cirrus,cs42l83", "cirrus,cs42l42";
|
||||
+ reg = <0x48>;
|
||||
+ reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <183 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ cirrus,ts-inv = <1>;
|
||||
+ sound-name-prefix = "Jack";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
/ {
|
||||
backlight: gpio-bl {
|
||||
compatible = "gpio-backlight";
|
||||
gpios = <&smc_gpio 18 GPIO_ACTIVE_HIGH>;
|
||||
default-on;
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "apple,j313-macaudio", "apple,macaudio";
|
||||
+ model = "MacBook Air J313 integrated audio";
|
||||
+
|
||||
+ dai-link@0 {
|
||||
+ link-name = "Speakers";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 0>, <&mca 1>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&speaker_left>, <&speaker_right>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ dai-link@1 {
|
||||
+ link-name = "Headphone Jack";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 2>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&jack_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&framebuffer0 {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
index 3d0a91ac29ae..e65053f3bd2c 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
@@ -73,3 +73,34 @@ ethernet0: ethernet@0,0 {
|
||||
local-mac-address = [00 10 18 00 00 00];
|
||||
};
|
||||
};
|
||||
+
|
||||
+&i2c1 {
|
||||
+ jack_codec: codec@48 {
|
||||
+ compatible = "cirrus,cs42l83", "cirrus,cs42l42";
|
||||
+ reg = <0x48>;
|
||||
+ reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <183 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ cirrus,ts-inv = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/ {
|
||||
+ sound {
|
||||
+ compatible = "apple,j456-macaudio", "apple,macaudio";
|
||||
+ model = "iMac J456 integrated audio";
|
||||
+
|
||||
+ dai-link@0 {
|
||||
+ link-name = "Headphone Jack";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 2>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&jack_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
index 7e3a0e95e837..925fe4058055 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
@@ -61,3 +61,43 @@ &pcie0_dart_1 {
|
||||
};
|
||||
|
||||
/delete-node/ &port01;
|
||||
+
|
||||
+&i2c1 {
|
||||
+ jack_codec: codec@48 {
|
||||
+ compatible = "cirrus,cs42l83", "cirrus,cs42l42";
|
||||
+ reg = <0x48>;
|
||||
+ reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <183 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ cirrus,ts-inv = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/ {
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "iMac integrated audio";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ bitclock-inversion;
|
||||
+ frame-inversion;
|
||||
+ reg = <0>;
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <64>;
|
||||
+ tdm-slot-width = <32>;
|
||||
+
|
||||
+ link0_cpu: cpu {
|
||||
+ sound-dai = <&mca 2>;
|
||||
+ bitclock-master;
|
||||
+ frame-master;
|
||||
+ };
|
||||
+
|
||||
+ link0_codec: codec {
|
||||
+ sound-dai = <&jack_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
index f96a732e6211..afb0688cb1c2 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
|
||||
@@ -917,6 +917,79 @@ port02: pci@2,0 {
|
||||
<0 0 0 4 &port02 0 0 0 3>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ dart_sio: iommu@235004000 {
|
||||
+ compatible = "apple,t8103-dart", "apple,dart";
|
||||
+ reg = <0x2 0x35004000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 635 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ power-domains = <&ps_sio_cpu>;
|
||||
+ };
|
||||
+
|
||||
+ nco_inp: clock-ref {
|
||||
+ compatible = "fixed-factor-clock";
|
||||
+ clocks = <&clkref>;
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-mult = <75>;
|
||||
+ clock-div = <2>; // 24 MHz * (75/2) = 900 MHz
|
||||
+ clock-output-names = "nco_inp";
|
||||
+ };
|
||||
+
|
||||
+ nco: nco@23b044000 {
|
||||
+ compatible = "apple,t8103-nco", "apple,nco";
|
||||
+ reg = <0x2 0x3b044000 0x0 0x14000>;
|
||||
+ clocks = <&nco_inp>;
|
||||
+ #clock-cells = <1>;
|
||||
+ apple,nchannels = <5>;
|
||||
+ };
|
||||
+
|
||||
+ admac: dma-controller@238200000 {
|
||||
+ compatible = "apple,t8103-admac", "apple,admac";
|
||||
+ reg = <0x2 0x38200000 0x0 0x34000>;
|
||||
+ dma-channels = <24>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 626 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #dma-cells = <1>;
|
||||
+ iommus = <&dart_sio 2>;
|
||||
+ power-domains = <&ps_sio_adma>;
|
||||
+ apple,internal-irq-destination = <1>;
|
||||
+ };
|
||||
+
|
||||
+ mca: mca@38400000 {
|
||||
+ compatible = "apple,t8103-mca", "apple,mca";
|
||||
+ reg = <0x2 0x38400000 0x0 0x18000>,
|
||||
+ <0x2 0x38300000 0x0 0x30000>;
|
||||
+ reg-names = "clusters", "switch";
|
||||
+
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 619 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 620 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 621 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 622 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 623 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 624 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+
|
||||
+ clocks = <&nco 0>, <&nco 1>, <&nco 2>,
|
||||
+ <&nco 3>, <&nco 4>, <&nco 4>;
|
||||
+ power-domains = <&ps_audio_p>, <&ps_mca0>, <&ps_mca1>,
|
||||
+ <&ps_mca2>, <&ps_mca3>, <&ps_mca4>, <&ps_mca5>;
|
||||
+ dmas = <&admac 0>, <&admac 1>, <&admac 2>, <&admac 3>,
|
||||
+ <&admac 4>, <&admac 5>, <&admac 6>, <&admac 7>,
|
||||
+ <&admac 8>, <&admac 9>, <&admac 10>, <&admac 11>,
|
||||
+ <&admac 12>, <&admac 13>, <&admac 14>, <&admac 15>,
|
||||
+ <&admac 16>, <&admac 17>, <&admac 18>, <&admac 19>,
|
||||
+ <&admac 20>, <&admac 21>, <&admac 22>, <&admac 23>;
|
||||
+ dma-names = "tx0a", "rx0a", "tx0b", "rx0b",
|
||||
+ "tx1a", "rx1a", "tx1b", "rx1b",
|
||||
+ "tx2a", "rx2a", "tx2b", "rx2b",
|
||||
+ "tx3a", "rx3a", "tx3b", "rx3b",
|
||||
+ "tx4a", "rx4a", "tx4b", "rx4b",
|
||||
+ "tx5a", "rx5a", "tx5b", "rx5b";
|
||||
+
|
||||
+ #sound-dai-cells = <1>;
|
||||
+ apple,nclusters = <6>;
|
||||
+ };
|
||||
};
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 461322f8b15d66dc8860c4f940c3f8f4f36bb3a3 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sat, 12 Mar 2022 21:00:22 +0900
|
||||
Subject: [PATCH 014/171] arm64: dts: apple: t8103-j313: Also disable speakers
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j313.dts | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
index ad3a6edeb651..d1f65e48699f 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
@@ -112,6 +112,15 @@ sound {
|
||||
model = "MacBook Air J313 integrated audio";
|
||||
|
||||
dai-link@0 {
|
||||
+ /*
|
||||
+ * DANGER ZONE: You can blow your speakers!
|
||||
+ *
|
||||
+ * The drivers are not ready, and unless you are careful
|
||||
+ * to attenuate the audio stream, you run the risk of
|
||||
+ * blowing your speakers.
|
||||
+ */
|
||||
+ status = "disabled";
|
||||
+
|
||||
link-name = "Speakers";
|
||||
mclk-fs = <64>;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 79b1406346a1f0bdf8bd326a005e288511ebfaf6 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 17 Mar 2022 23:49:07 +0900
|
||||
Subject: [PATCH 015/171] arm64: dts: apple: Keep PCIe power domain on
|
||||
|
||||
This causes flakiness if shut down; don't do it until we find out
|
||||
what's going on.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-pmgr.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
index 926b1e54b64b..68ae594bf5e9 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
@@ -717,6 +717,7 @@ ps_apcie_gp: power-controller@3e8 {
|
||||
#reset-cells = <0>;
|
||||
label = "apcie_gp";
|
||||
power-domains = <&ps_apcie>;
|
||||
+ apple,always-on; /* Breaks things if shut down */
|
||||
};
|
||||
|
||||
ps_ans2: power-controller@3f0 {
|
||||
--
|
||||
2.34.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,250 @@
|
||||
From ea9e6404ec5b3f1ce636e0ac67293528b87c8578 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Wed, 10 Nov 2021 19:08:25 +0900
|
||||
Subject: [PATCH 017/171] arm64: dts: apple: Add J314 and J316 devicetrees
|
||||
|
||||
These are the 14-inch and 16-inch 2021 MacBooks, in both M1 Pro and M1
|
||||
Max variants (t6000 and t6001).
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/Makefile | 4 +
|
||||
arch/arm64/boot/dts/apple/t6000-j314s.dts | 18 +++
|
||||
arch/arm64/boot/dts/apple/t6000-j316s.dts | 18 +++
|
||||
arch/arm64/boot/dts/apple/t6001-j314c.dts | 18 +++
|
||||
arch/arm64/boot/dts/apple/t6001-j316c.dts | 18 +++
|
||||
.../arm64/boot/dts/apple/t600x-j314-j316.dtsi | 110 ++++++++++++++++++
|
||||
6 files changed, 186 insertions(+)
|
||||
create mode 100644 arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
create mode 100644 arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
create mode 100644 arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
create mode 100644 arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
create mode 100644 arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
|
||||
index c0510c25ca6a..b021931b0a17 100644
|
||||
--- a/arch/arm64/boot/dts/apple/Makefile
|
||||
+++ b/arch/arm64/boot/dts/apple/Makefile
|
||||
@@ -4,3 +4,7 @@ dtb-$(CONFIG_ARCH_APPLE) += t8103-j293.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t8103-j313.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t8103-j456.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t8103-j457.dtb
|
||||
+dtb-$(CONFIG_ARCH_APPLE) += t6000-j314s.dtb
|
||||
+dtb-$(CONFIG_ARCH_APPLE) += t6001-j314c.dtb
|
||||
+dtb-$(CONFIG_ARCH_APPLE) += t6000-j316s.dtb
|
||||
+dtb-$(CONFIG_ARCH_APPLE) += t6001-j316c.dtb
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6000-j314s.dts b/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
new file mode 100644
|
||||
index 000000000000..c9e192848fe3
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
@@ -0,0 +1,18 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
+/*
|
||||
+ * MacBook Pro (14-inch, M1 Pro, 2021)
|
||||
+ *
|
||||
+ * target-type: J314s
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "t6000.dtsi"
|
||||
+#include "t600x-j314-j316.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "apple,j314s", "apple,t6000", "apple,arm-platform";
|
||||
+ model = "Apple MacBook Pro (14-inch, M1 Pro, 2021)";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6000-j316s.dts b/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
new file mode 100644
|
||||
index 000000000000..ff1803ce2300
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
@@ -0,0 +1,18 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
+/*
|
||||
+ * MacBook Pro (16-inch, M1 Pro, 2021)
|
||||
+ *
|
||||
+ * target-type: J316s
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "t6000.dtsi"
|
||||
+#include "t600x-j314-j316.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "apple,j316s", "apple,t6000", "apple,arm-platform";
|
||||
+ model = "Apple MacBook Pro (16-inch, M1 Pro, 2021)";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j314c.dts b/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
new file mode 100644
|
||||
index 000000000000..1761d15b98c1
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
@@ -0,0 +1,18 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
+/*
|
||||
+ * MacBook Pro (14-inch, M1 Max, 2021)
|
||||
+ *
|
||||
+ * target-type: J314c
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "t6001.dtsi"
|
||||
+#include "t600x-j314-j316.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "apple,j314c", "apple,t6001", "apple,arm-platform";
|
||||
+ model = "Apple MacBook Pro (14-inch, M1 Max, 2021)";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j316c.dts b/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
new file mode 100644
|
||||
index 000000000000..750e9beeffc0
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
@@ -0,0 +1,18 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
+/*
|
||||
+ * MacBook Pro (16-inch, M1 Max, 2021)
|
||||
+ *
|
||||
+ * target-type: J316c
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "t6001.dtsi"
|
||||
+#include "t600x-j314-j316.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "apple,j316c", "apple,t6001", "apple,arm-platform";
|
||||
+ model = "Apple MacBook Pro (16-inch, M1 Max, 2021)";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
new file mode 100644
|
||||
index 000000000000..8079200aeb12
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -0,0 +1,110 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
+/*
|
||||
+ * MacBook Pro (14/16-inch, 2021)
|
||||
+ *
|
||||
+ * This file contains the parts common to J314 and J316 devices with both t6000 and t6001.
|
||||
+ *
|
||||
+ * target-type: J314s / J314c / J316s / J316c
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+/ {
|
||||
+ aliases {
|
||||
+ serial0 = &serial0;
|
||||
+ wifi0 = &wifi0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ stdout-path = "serial0";
|
||||
+
|
||||
+ framebuffer0: framebuffer@0 {
|
||||
+ compatible = "apple,simple-framebuffer", "simple-framebuffer";
|
||||
+ reg = <0 0 0 0>; /* To be filled by loader */
|
||||
+ /* Format properties will be added by loader */
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ memory@10000000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x100 0 0x2 0>; /* To be filled by loader */
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&serial0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+/* USB Type C */
|
||||
+&i2c0 {
|
||||
+ hpm0: usb-pd@38 {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x38>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm1: usb-pd@3f {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3f>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm2: usb-pd@3b {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3b>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ /* MagSafe port */
|
||||
+ hpm5: usb-pd@3a {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3a>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* PCIe devices */
|
||||
+&port00 {
|
||||
+ /* WLAN */
|
||||
+ bus-range = <1 1>;
|
||||
+ wifi0: wifi@0,0 {
|
||||
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-mac-address = [00 10 18 00 00 10];
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&port01 {
|
||||
+ /* SD card reader */
|
||||
+ bus-range = <2 2>;
|
||||
+ sdhci0: mmc@0,0 {
|
||||
+ compatible = "pci17a0,9755";
|
||||
+ reg = <0x20000 0x0 0x0 0x0 0x0>;
|
||||
+ cd-inverted;
|
||||
+ wp-inverted;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pcie0_dart_2 {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&pcie0_dart_3 {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+/delete-node/ &port02;
|
||||
+/delete-node/ &port03;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,149 @@
|
||||
From ab01e260000502f8e1f814e05fcbf35667cc1167 Mon Sep 17 00:00:00 2001
|
||||
From: Janne Grunau <j@jannau.net>
|
||||
Date: Tue, 3 May 2022 22:05:25 +0200
|
||||
Subject: [PATCH 018/171] arm64: dts: apple: Add devicetree for Apple Mac
|
||||
Studio M1 Max
|
||||
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/Makefile | 1 +
|
||||
arch/arm64/boot/dts/apple/t6001-j375c.dts | 118 ++++++++++++++++++++++
|
||||
2 files changed, 119 insertions(+)
|
||||
create mode 100644 arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
|
||||
index b021931b0a17..b3ed42594ecd 100644
|
||||
--- a/arch/arm64/boot/dts/apple/Makefile
|
||||
+++ b/arch/arm64/boot/dts/apple/Makefile
|
||||
@@ -8,3 +8,4 @@ dtb-$(CONFIG_ARCH_APPLE) += t6000-j314s.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t6001-j314c.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t6000-j316s.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t6001-j316c.dtb
|
||||
+dtb-$(CONFIG_ARCH_APPLE) += t6001-j375c.dtb
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j375c.dts b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
new file mode 100644
|
||||
index 000000000000..961104d6bd9a
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
@@ -0,0 +1,118 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
+/*
|
||||
+ * Mac Studio (M1 Max, 2022)
|
||||
+ *
|
||||
+ * target-type: J375c
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "t6001.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "apple,j375c", "apple,t6001", "apple,arm-platform";
|
||||
+ model = "Apple Mac Studio (M1 Max, 2022)";
|
||||
+
|
||||
+ aliases {
|
||||
+ serial0 = &serial0;
|
||||
+ wifi0 = &wifi0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ stdout-path = "serial0";
|
||||
+
|
||||
+ framebuffer0: framebuffer@0 {
|
||||
+ compatible = "apple,simple-framebuffer", "simple-framebuffer";
|
||||
+ reg = <0 0 0 0>; /* To be filled by loader */
|
||||
+ /* Format properties will be added by loader */
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ memory@10000000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x100 0 0x2 0>; /* To be filled by loader */
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&serial0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+/* USB Type C */
|
||||
+&i2c0 {
|
||||
+ hpm0: usb-pd@38 {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x38>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm1: usb-pd@3f {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3f>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm2: usb-pd@3b {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3b>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm3: usb-pd@3c {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3c>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* PCIe devices */
|
||||
+&port00 {
|
||||
+ /* WLAN */
|
||||
+ bus-range = <1 1>;
|
||||
+ wifi0: wifi@0,0 {
|
||||
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-mac-address = [00 10 18 00 00 10];
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&port01 {
|
||||
+ /* SD card reader */
|
||||
+ bus-range = <2 2>;
|
||||
+ sdhci0: mmc@0,0 {
|
||||
+ compatible = "pci17a0,9755";
|
||||
+ reg = <0x20000 0x0 0x0 0x0 0x0>;
|
||||
+ cd-inverted;
|
||||
+ wp-inverted;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&port02 {
|
||||
+ /* 10 Gbit Ethernet */
|
||||
+ bus-range = <3 3>;
|
||||
+ ethernet0: ethernet@0,0 {
|
||||
+ reg = <0x30000 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-mac-address = [00 10 18 00 00 00];
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&port03 {
|
||||
+ /* USB xHCI */
|
||||
+ bus-range = <4 4>;
|
||||
+};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,178 @@
|
||||
From 973a9df0042bad7ee5fa7534f4d74f6f5d44f1c8 Mon Sep 17 00:00:00 2001
|
||||
From: Janne Grunau <j@jannau.net>
|
||||
Date: Thu, 24 Mar 2022 17:04:24 +0100
|
||||
Subject: [PATCH 019/171] arm64: dts: apple: Add devicetree for Apple Mac
|
||||
Studio M1 Ultra
|
||||
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/Makefile | 1 +
|
||||
arch/arm64/boot/dts/apple/t6002-j375d.dts | 147 ++++++++++++++++++++++
|
||||
2 files changed, 148 insertions(+)
|
||||
create mode 100644 arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
|
||||
index b3ed42594ecd..5a7506ff5ea3 100644
|
||||
--- a/arch/arm64/boot/dts/apple/Makefile
|
||||
+++ b/arch/arm64/boot/dts/apple/Makefile
|
||||
@@ -9,3 +9,4 @@ dtb-$(CONFIG_ARCH_APPLE) += t6001-j314c.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t6000-j316s.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t6001-j316c.dtb
|
||||
dtb-$(CONFIG_ARCH_APPLE) += t6001-j375c.dtb
|
||||
+dtb-$(CONFIG_ARCH_APPLE) += t6002-j375d.dtb
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
new file mode 100644
|
||||
index 000000000000..95e0c3243818
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
@@ -0,0 +1,147 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
+/*
|
||||
+ * Mac Studio (M1 Ultra, 2022)
|
||||
+ *
|
||||
+ * target-type: J375d
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "t6002.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "apple,j375d", "apple,t6002", "apple,arm-platform";
|
||||
+ model = "Apple Mac Studio (M1 Ultra, 2022)";
|
||||
+
|
||||
+ aliases {
|
||||
+ serial0 = &serial0;
|
||||
+ wifi0 = &wifi0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ stdout-path = "serial0";
|
||||
+
|
||||
+ framebuffer0: framebuffer@0 {
|
||||
+ compatible = "apple,simple-framebuffer", "simple-framebuffer";
|
||||
+ reg = <0 0 0 0>; /* To be filled by loader */
|
||||
+ /* Format properties will be added by loader */
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ memory@10000000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x100 0 0x2 0>; /* To be filled by loader */
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&serial0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+/* USB Type C */
|
||||
+&i2c0 {
|
||||
+ hpm0: usb-pd@38 {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x38>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm1: usb-pd@3f {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3f>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm2: usb-pd@3b {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3b>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ hpm3: usb-pd@3c {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3c>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ /* front-right */
|
||||
+ hpm4: usb-pd@39 {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x39>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+
|
||||
+ /* front-left */
|
||||
+ hpm5: usb-pd@3a {
|
||||
+ compatible = "apple,cd321x";
|
||||
+ reg = <0x3a>;
|
||||
+ interrupt-parent = <&pinctrl_ap>;
|
||||
+ interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "irq";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* PCIe devices */
|
||||
+&port00 {
|
||||
+ /* WLAN */
|
||||
+ bus-range = <1 1>;
|
||||
+ wifi0: wifi@0,0 {
|
||||
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-mac-address = [00 10 18 00 00 10];
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&port01 {
|
||||
+ /* SD card reader */
|
||||
+ bus-range = <2 2>;
|
||||
+ sdhci0: mmc@0,0 {
|
||||
+ compatible = "pci17a0,9755";
|
||||
+ reg = <0x20000 0x0 0x0 0x0 0x0>;
|
||||
+ cd-inverted;
|
||||
+ wp-inverted;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&port02 {
|
||||
+ /* 10 Gbit Ethernet */
|
||||
+ bus-range = <3 3>;
|
||||
+ ethernet0: ethernet@0,0 {
|
||||
+ reg = <0x30000 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-mac-address = [00 10 18 00 00 00];
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&port03 {
|
||||
+ /* USB xHCI */
|
||||
+ bus-range = <4 4>;
|
||||
+};
|
||||
+
|
||||
+/* delete unused always-on power-domains on die 1 */
|
||||
+
|
||||
+/delete-node/ &ps_atc2_usb_aon_die1;
|
||||
+/delete-node/ &ps_atc2_usb_die1;
|
||||
+
|
||||
+/delete-node/ &ps_atc3_usb_aon_die1;
|
||||
+/delete-node/ &ps_atc3_usb_die1;
|
||||
+
|
||||
+/delete-node/ &ps_disp0_cpu0_die1;
|
||||
+/delete-node/ &ps_disp0_fe_die1;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,486 @@
|
||||
From 0bea0800d5e0e32323bbbe2b2edfe16e08116bc9 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 15 Feb 2022 21:34:10 +0900
|
||||
Subject: [PATCH 020/171] arm64: dts: apple: Add CPUfreq nodes for t6001
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t6001.dtsi | 7 +
|
||||
arch/arm64/boot/dts/apple/t6002.dtsi | 81 +++++++++
|
||||
arch/arm64/boot/dts/apple/t600x-common.dtsi | 188 ++++++++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t600x-die0.dtsi | 4 +
|
||||
4 files changed, 280 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001.dtsi b/arch/arm64/boot/dts/apple/t6001.dtsi
|
||||
index 620b17e4031f..832e9bedc1fb 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001.dtsi
|
||||
@@ -47,6 +47,13 @@ soc {
|
||||
#undef DIE_NO
|
||||
|
||||
|
||||
+&cpufreq_hw {
|
||||
+ reg = <0x2 0x10e20000 0 0x1000>,
|
||||
+ <0x2 0x11e20000 0 0x1000>,
|
||||
+ <0x2 0x12e20000 0 0x1000>;
|
||||
+ reg-names = "cluster0", "cluster1", "cluster2";
|
||||
+};
|
||||
+
|
||||
&aic {
|
||||
affinities {
|
||||
e-core-pmu-affinity {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002.dtsi b/arch/arm64/boot/dts/apple/t6002.dtsi
|
||||
index 736f16aad70f..f3618df00518 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6002.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002.dtsi
|
||||
@@ -23,12 +23,56 @@ / {
|
||||
#size-cells = <2>;
|
||||
|
||||
cpus {
|
||||
+ cpu-map {
|
||||
+ cluster3 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_e10>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_e11>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cluster4 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_p20>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_p21>;
|
||||
+ };
|
||||
+ core2 {
|
||||
+ cpu = <&cpu_p22>;
|
||||
+ };
|
||||
+ core3 {
|
||||
+ cpu = <&cpu_p23>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cluster5 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_p30>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_p31>;
|
||||
+ };
|
||||
+ core2 {
|
||||
+ cpu = <&cpu_p32>;
|
||||
+ };
|
||||
+ core3 {
|
||||
+ cpu = <&cpu_p33>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
cpu_e10: cpu@800 {
|
||||
compatible = "apple,icestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x800>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&icestorm_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 3>;
|
||||
};
|
||||
|
||||
cpu_e11: cpu@801 {
|
||||
@@ -37,6 +81,9 @@ cpu_e11: cpu@801 {
|
||||
reg = <0x0 0x801>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&icestorm_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 3>;
|
||||
};
|
||||
|
||||
cpu_p20: cpu@10900 {
|
||||
@@ -45,6 +92,9 @@ cpu_p20: cpu@10900 {
|
||||
reg = <0x0 0x10900>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 4>;
|
||||
};
|
||||
|
||||
cpu_p21: cpu@10901 {
|
||||
@@ -53,6 +103,9 @@ cpu_p21: cpu@10901 {
|
||||
reg = <0x0 0x10901>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 4>;
|
||||
};
|
||||
|
||||
cpu_p22: cpu@10902 {
|
||||
@@ -61,6 +114,9 @@ cpu_p22: cpu@10902 {
|
||||
reg = <0x0 0x10902>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 4>;
|
||||
};
|
||||
|
||||
cpu_p23: cpu@10903 {
|
||||
@@ -69,6 +125,9 @@ cpu_p23: cpu@10903 {
|
||||
reg = <0x0 0x10903>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 4>;
|
||||
};
|
||||
|
||||
cpu_p30: cpu@10a00 {
|
||||
@@ -77,6 +136,9 @@ cpu_p30: cpu@10a00 {
|
||||
reg = <0x0 0x10a00>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 5>;
|
||||
};
|
||||
|
||||
cpu_p31: cpu@10a01 {
|
||||
@@ -85,6 +147,9 @@ cpu_p31: cpu@10a01 {
|
||||
reg = <0x0 0x10a01>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 5>;
|
||||
};
|
||||
|
||||
cpu_p32: cpu@10a02 {
|
||||
@@ -93,6 +158,9 @@ cpu_p32: cpu@10a02 {
|
||||
reg = <0x0 0x10a02>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 5>;
|
||||
};
|
||||
|
||||
cpu_p33: cpu@10a03 {
|
||||
@@ -101,6 +169,9 @@ cpu_p33: cpu@10a03 {
|
||||
reg = <0x0 0x10a03>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 5>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -162,6 +233,16 @@ die1 {
|
||||
#undef DIE
|
||||
#undef DIE_NO
|
||||
|
||||
+&cpufreq_hw {
|
||||
+ reg = <0x2 0x10e20000 0 0x1000>,
|
||||
+ <0x2 0x11e20000 0 0x1000>,
|
||||
+ <0x2 0x12e20000 0 0x1000>,
|
||||
+ <0x22 0x10e20000 0 0x1000>,
|
||||
+ <0x22 0x11e20000 0 0x1000>,
|
||||
+ <0x22 0x12e20000 0 0x1000>;
|
||||
+ reg-names = "cluster0", "cluster1", "cluster2",
|
||||
+ "cluster3", "cluster4", "cluster5";
|
||||
+};
|
||||
|
||||
&aic {
|
||||
affinities {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-common.dtsi b/arch/arm64/boot/dts/apple/t600x-common.dtsi
|
||||
index e29b88e2c853..06e160880407 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-common.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-common.dtsi
|
||||
@@ -15,12 +15,56 @@ cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
+ cpu-map {
|
||||
+ cluster0 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_e00>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_e01>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cluster1 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_p00>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_p01>;
|
||||
+ };
|
||||
+ core2 {
|
||||
+ cpu = <&cpu_p02>;
|
||||
+ };
|
||||
+ core3 {
|
||||
+ cpu = <&cpu_p03>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cluster2 {
|
||||
+ core0 {
|
||||
+ cpu = <&cpu_p10>;
|
||||
+ };
|
||||
+ core1 {
|
||||
+ cpu = <&cpu_p11>;
|
||||
+ };
|
||||
+ core2 {
|
||||
+ cpu = <&cpu_p12>;
|
||||
+ };
|
||||
+ core3 {
|
||||
+ cpu = <&cpu_p13>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
cpu_e00: cpu@0 {
|
||||
compatible = "apple,icestorm";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&icestorm_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 0>;
|
||||
};
|
||||
|
||||
cpu_e01: cpu@1 {
|
||||
@@ -29,6 +73,9 @@ cpu_e01: cpu@1 {
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&icestorm_opp>;
|
||||
+ capacity-dmips-mhz = <714>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 0>;
|
||||
};
|
||||
|
||||
cpu_p00: cpu@10100 {
|
||||
@@ -37,6 +84,9 @@ cpu_p00: cpu@10100 {
|
||||
reg = <0x0 0x10100>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
};
|
||||
|
||||
cpu_p01: cpu@10101 {
|
||||
@@ -45,6 +95,9 @@ cpu_p01: cpu@10101 {
|
||||
reg = <0x0 0x10101>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
};
|
||||
|
||||
cpu_p02: cpu@10102 {
|
||||
@@ -53,6 +106,9 @@ cpu_p02: cpu@10102 {
|
||||
reg = <0x0 0x10102>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
};
|
||||
|
||||
cpu_p03: cpu@10103 {
|
||||
@@ -61,6 +117,9 @@ cpu_p03: cpu@10103 {
|
||||
reg = <0x0 0x10103>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 1>;
|
||||
};
|
||||
|
||||
cpu_p10: cpu@10200 {
|
||||
@@ -69,6 +128,9 @@ cpu_p10: cpu@10200 {
|
||||
reg = <0x0 0x10200>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 2>;
|
||||
};
|
||||
|
||||
cpu_p11: cpu@10201 {
|
||||
@@ -77,6 +139,9 @@ cpu_p11: cpu@10201 {
|
||||
reg = <0x0 0x10201>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 2>;
|
||||
};
|
||||
|
||||
cpu_p12: cpu@10202 {
|
||||
@@ -85,6 +150,9 @@ cpu_p12: cpu@10202 {
|
||||
reg = <0x0 0x10202>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 2>;
|
||||
};
|
||||
|
||||
cpu_p13: cpu@10203 {
|
||||
@@ -93,7 +161,127 @@ cpu_p13: cpu@10203 {
|
||||
reg = <0x0 0x10203>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0 0>; /* To be filled by loader */
|
||||
+ operating-points-v2 = <&firestorm_opp>;
|
||||
+ capacity-dmips-mhz = <1024>;
|
||||
+ apple,freq-domain = <&cpufreq_hw 2>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ icestorm_opp: opp-table-0 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp01 {
|
||||
+ opp-hz = /bits/ 64 <600000000>;
|
||||
+ opp-level = <1>;
|
||||
+ clock-latency-ns = <7500>;
|
||||
+ };
|
||||
+ opp02 {
|
||||
+ opp-hz = /bits/ 64 <972000000>;
|
||||
+ opp-level = <2>;
|
||||
+ clock-latency-ns = <23000>;
|
||||
+ };
|
||||
+ opp03 {
|
||||
+ opp-hz = /bits/ 64 <1332000000>;
|
||||
+ opp-level = <3>;
|
||||
+ clock-latency-ns = <29000>;
|
||||
+ };
|
||||
+ opp04 {
|
||||
+ opp-hz = /bits/ 64 <1704000000>;
|
||||
+ opp-level = <4>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp05 {
|
||||
+ opp-hz = /bits/ 64 <2064000000>;
|
||||
+ opp-level = <5>;
|
||||
+ clock-latency-ns = <50000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ firestorm_opp: opp-table-1 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp01 {
|
||||
+ opp-hz = /bits/ 64 <600000000>;
|
||||
+ opp-level = <1>;
|
||||
+ clock-latency-ns = <8000>;
|
||||
+ };
|
||||
+ opp02 {
|
||||
+ opp-hz = /bits/ 64 <828000000>;
|
||||
+ opp-level = <2>;
|
||||
+ clock-latency-ns = <18000>;
|
||||
+ };
|
||||
+ opp03 {
|
||||
+ opp-hz = /bits/ 64 <1056000000>;
|
||||
+ opp-level = <3>;
|
||||
+ clock-latency-ns = <19000>;
|
||||
+ };
|
||||
+ opp04 {
|
||||
+ opp-hz = /bits/ 64 <1296000000>;
|
||||
+ opp-level = <4>;
|
||||
+ clock-latency-ns = <23000>;
|
||||
+ };
|
||||
+ opp05 {
|
||||
+ opp-hz = /bits/ 64 <1524000000>;
|
||||
+ opp-level = <5>;
|
||||
+ clock-latency-ns = <24000>;
|
||||
+ };
|
||||
+ opp06 {
|
||||
+ opp-hz = /bits/ 64 <1752000000>;
|
||||
+ opp-level = <6>;
|
||||
+ clock-latency-ns = <28000>;
|
||||
+ };
|
||||
+ opp07 {
|
||||
+ opp-hz = /bits/ 64 <1980000000>;
|
||||
+ opp-level = <7>;
|
||||
+ clock-latency-ns = <31000>;
|
||||
+ };
|
||||
+ opp08 {
|
||||
+ opp-hz = /bits/ 64 <2208000000>;
|
||||
+ opp-level = <8>;
|
||||
+ clock-latency-ns = <45000>;
|
||||
+ };
|
||||
+ opp09 {
|
||||
+ opp-hz = /bits/ 64 <2448000000>;
|
||||
+ opp-level = <9>;
|
||||
+ clock-latency-ns = <49000>;
|
||||
+ };
|
||||
+ opp10 {
|
||||
+ opp-hz = /bits/ 64 <2676000000>;
|
||||
+ opp-level = <10>;
|
||||
+ clock-latency-ns = <53000>;
|
||||
+ };
|
||||
+ opp11 {
|
||||
+ opp-hz = /bits/ 64 <2904000000>;
|
||||
+ opp-level = <11>;
|
||||
+ clock-latency-ns = <56000>;
|
||||
+ };
|
||||
+ opp12 {
|
||||
+ opp-hz = /bits/ 64 <3036000000>;
|
||||
+ opp-level = <12>;
|
||||
+ clock-latency-ns = <56000>;
|
||||
+ };
|
||||
+ /* Not available until CPU deep sleep is implemented
|
||||
+ opp13 {
|
||||
+ opp-hz = /bits/ 64 <3132000000>;
|
||||
+ opp-level = <13>;
|
||||
+ clock-latency-ns = <56000>;
|
||||
+ turbo-mode;
|
||||
+ };
|
||||
+ opp14 {
|
||||
+ opp-hz = /bits/ 64 <3168000000>;
|
||||
+ opp-level = <14>;
|
||||
+ clock-latency-ns = <56000>;
|
||||
+ turbo-mode;
|
||||
+ };
|
||||
+ opp15 {
|
||||
+ opp-hz = /bits/ 64 <3228000000>;
|
||||
+ opp-level = <15>;
|
||||
+ clock-latency-ns = <56000>;
|
||||
+ turbo-mode;
|
||||
};
|
||||
+ */
|
||||
};
|
||||
|
||||
pmu-e {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
index 8131352e3ccd..129984bd9a8b 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
@@ -6,6 +6,10 @@
|
||||
* Copyright The Asahi Linux Contributors
|
||||
*/
|
||||
|
||||
+ cpufreq_hw: cpufreq@210e20000 {
|
||||
+ compatible = "apple,t6000-soc-cpufreq", "apple,soc-cpufreq";
|
||||
+ #freq-domain-cells = <1>;
|
||||
+ };
|
||||
|
||||
aic: interrupt-controller@28e100000 {
|
||||
compatible = "apple,t6000-aic", "apple,aic2";
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,50 @@
|
||||
From 7946dbabbfec3116b542268cbb3dcb6b4a5bd9c2 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Fri, 4 Feb 2022 12:59:39 +0900
|
||||
Subject: [PATCH 021/171] arm64: dts: apple: Add SMC node to t600x devicetrees
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t600x-die0.dtsi | 26 +++++++++++++++++++++++
|
||||
1 file changed, 26 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
index 129984bd9a8b..6c9649d5a26c 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
@@ -21,6 +21,32 @@ aic: interrupt-controller@28e100000 {
|
||||
power-domains = <&ps_aic>;
|
||||
};
|
||||
|
||||
+ smc_mbox: mbox@290408000 {
|
||||
+ compatible = "apple,t6000-asc-mailbox", "apple,asc-mailbox-v4";
|
||||
+ reg = <0x2 0x90408000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 0 754 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 0 755 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 0 756 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 0 757 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "send-empty", "send-not-empty",
|
||||
+ "recv-empty", "recv-not-empty";
|
||||
+ #mbox-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ smc: smc@290400000 {
|
||||
+ compatible = "apple,t6000-smc", "apple,smc";
|
||||
+ reg = <0x2 0x90400000 0x0 0x4000>,
|
||||
+ <0x2 0x91e00000 0x0 0x100000>;
|
||||
+ reg-names = "smc", "sram";
|
||||
+ mboxes = <&smc_mbox>;
|
||||
+
|
||||
+ smc_gpio: gpio {
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
pinctrl_smc: pinctrl@290820000 {
|
||||
compatible = "apple,t6000-pinctrl", "apple,pinctrl";
|
||||
reg = <0x2 0x90820000 0x0 0x4000>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,145 @@
|
||||
From d2759ec3852ae04e5a6a87d78dd5a52e67e36bbf Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 15 Feb 2022 18:54:35 +0900
|
||||
Subject: [PATCH 022/171] arm64: dts: apple: Add PMU NVMEM and SMC RTC/reboot
|
||||
nodes
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t6001.dtsi | 1 +
|
||||
arch/arm64/boot/dts/apple/t6002.dtsi | 1 +
|
||||
arch/arm64/boot/dts/apple/t600x-die0.dtsi | 87 +++++++++++++++++++++++
|
||||
3 files changed, 89 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001.dtsi b/arch/arm64/boot/dts/apple/t6001.dtsi
|
||||
index 832e9bedc1fb..6b50a9fa68e7 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001.dtsi
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <dt-bindings/interrupt-controller/apple-aic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/pinctrl/apple.h>
|
||||
+#include <dt-bindings/spmi/spmi.h>
|
||||
|
||||
#include "multi-die-cpp.h"
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002.dtsi b/arch/arm64/boot/dts/apple/t6002.dtsi
|
||||
index f3618df00518..31e2de7fb2ea 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6002.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002.dtsi
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <dt-bindings/interrupt-controller/apple-aic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/pinctrl/apple.h>
|
||||
+#include <dt-bindings/spmi/spmi.h>
|
||||
|
||||
#include "multi-die-cpp.h"
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
index 6c9649d5a26c..928da6734371 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
@@ -45,6 +45,18 @@ smc_gpio: gpio {
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
+
|
||||
+ smc_rtc: rtc {
|
||||
+ nvmem-cells = <&rtc_offset>;
|
||||
+ nvmem-cell-names = "rtc_offset";
|
||||
+ };
|
||||
+
|
||||
+ smc_reboot: reboot {
|
||||
+ nvmem-cells = <&shutdown_flag>, <&boot_stage>,
|
||||
+ <&boot_error_count>, <&panic_count>, <&pm_setting>;
|
||||
+ nvmem-cell-names = "shutdown_flag", "boot_stage",
|
||||
+ "boot_error_count", "panic_count", "pm_setting";
|
||||
+ };
|
||||
};
|
||||
|
||||
pinctrl_smc: pinctrl@290820000 {
|
||||
@@ -76,6 +88,81 @@ wdt: watchdog@2922b0000 {
|
||||
interrupts = <AIC_IRQ 0 631 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
+ nub_spmi0: spmi@2920a1300 {
|
||||
+ compatible = "apple,t6000-spmi", "apple,spmi";
|
||||
+ reg = <0x2 0x920a1300 0x0 0x100>;
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ pmu1: pmu@f {
|
||||
+ compatible = "apple,maverick-pmu", "apple,spmi-pmu";
|
||||
+ reg = <0xf SPMI_USID>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ rtc_nvmem@1400 {
|
||||
+ compatible = "apple,spmi-pmu-nvmem";
|
||||
+ reg = <0x1400 0x20>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ pm_setting: pm-setting@5 {
|
||||
+ reg = <0x5 0x1>;
|
||||
+ };
|
||||
+
|
||||
+ rtc_offset: rtc-offset@11 {
|
||||
+ reg = <0x11 0x6>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ legacy_nvmem@6000 {
|
||||
+ compatible = "apple,spmi-pmu-nvmem";
|
||||
+ reg = <0x6000 0x20>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ boot_stage: boot-stage@1 {
|
||||
+ reg = <0x1 0x1>;
|
||||
+ };
|
||||
+
|
||||
+ boot_error_count: boot-error-count@2 {
|
||||
+ reg = <0x2 0x1>;
|
||||
+ bits = <0 4>;
|
||||
+ };
|
||||
+
|
||||
+ panic_count: panic-count@2 {
|
||||
+ reg = <0x2 0x1>;
|
||||
+ bits = <4 4>;
|
||||
+ };
|
||||
+
|
||||
+ boot_error_stage: boot-error-stage@3 {
|
||||
+ reg = <0x3 0x1>;
|
||||
+ };
|
||||
+
|
||||
+ shutdown_flag: shutdown-flag@f {
|
||||
+ reg = <0xf 0x1>;
|
||||
+ bits = <3 1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ scrpad_nvmem@8000 {
|
||||
+ compatible = "apple,spmi-pmu-nvmem";
|
||||
+ reg = <0x8000 0x1000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ fault_shadow: fault-shadow@67b {
|
||||
+ reg = <0x67b 0x10>;
|
||||
+ };
|
||||
+
|
||||
+ socd: socd@b00 {
|
||||
+ reg = <0xb00 0x400>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
i2c0: i2c@39b040000 {
|
||||
compatible = "apple,t6000-i2c", "apple,i2c";
|
||||
reg = <0x3 0x9b040000 0x0 0x4000>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,74 @@
|
||||
From b04e8cf77375704a101a7bcaa485973702cbbc92 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 9 Dec 2021 21:58:10 +0900
|
||||
Subject: [PATCH 023/171] arm64: dts: apple: t6000: Add spi1 node
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t600x-common.dtsi | 7 +++++++
|
||||
arch/arm64/boot/dts/apple/t600x-die0.dtsi | 14 ++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi | 7 +++++++
|
||||
3 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-common.dtsi b/arch/arm64/boot/dts/apple/t600x-common.dtsi
|
||||
index 06e160880407..c5ee0c2da778 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-common.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-common.dtsi
|
||||
@@ -313,4 +313,11 @@ clkref: clock-ref {
|
||||
clock-output-names = "clkref";
|
||||
};
|
||||
|
||||
+ clk_200m: clock-200m {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <200000000>;
|
||||
+ clock-output-names = "clk_200m";
|
||||
+ };
|
||||
+
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
index 928da6734371..96f8c2189f03 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
@@ -246,6 +246,20 @@ i2c5: i2c@39b054000 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ spi1: spi@39b104000 {
|
||||
+ compatible = "apple,t6000-spi", "apple,spi";
|
||||
+ reg = <0x3 0x9b104000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 0 1107 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ clocks = <&clk_200m>;
|
||||
+ pinctrl-0 = <&spi1_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ power-domains = <&ps_spi1>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
serial0: serial@39b200000 {
|
||||
compatible = "apple,s5l-uart";
|
||||
reg = <0x3 0x9b200000 0x0 0x1000>;
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi b/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
|
||||
index b31f1a7a2b3f..855dcf30a502 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
|
||||
@@ -36,6 +36,13 @@ i2c5_pins: i2c5-pins {
|
||||
<APPLE_PINMUX(101, 1)>;
|
||||
};
|
||||
|
||||
+ spi1_pins: spi1-pins {
|
||||
+ pinmux = <APPLE_PINMUX(10, 1)>,
|
||||
+ <APPLE_PINMUX(11, 1)>,
|
||||
+ <APPLE_PINMUX(32, 1)>,
|
||||
+ <APPLE_PINMUX(33, 1)>;
|
||||
+ };
|
||||
+
|
||||
pcie_pins: pcie-pins {
|
||||
pinmux = <APPLE_PINMUX(0, 1)>,
|
||||
<APPLE_PINMUX(1, 1)>,
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,37 @@
|
||||
From e2a083f709ff6669836587d592b313d7349d0525 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 9 Dec 2021 21:58:29 +0900
|
||||
Subject: [PATCH 024/171] arm64: dts: apple: t600x-j314-j316: Add NOR flash
|
||||
node
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index 8079200aeb12..55457892c38e 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -76,6 +76,18 @@ hpm5: usb-pd@3a {
|
||||
};
|
||||
};
|
||||
|
||||
+&spi1 {
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ flash@0 {
|
||||
+ compatible = "jedec,spi-nor";
|
||||
+ reg = <0x0>;
|
||||
+ spi-max-frequency = <25000000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
/* PCIe devices */
|
||||
&port00 {
|
||||
/* WLAN */
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 2beaa67dcf1275232f6f52f104d321818289c159 Mon Sep 17 00:00:00 2001
|
||||
From: Janne Grunau <j@jannau.net>
|
||||
Date: Thu, 11 Nov 2021 21:31:21 +0100
|
||||
Subject: [PATCH 025/171] arm64: dts: apple: t600x: Add spi3 node
|
||||
|
||||
Used for keyboard and touchpad input on MacBook Pro (14/16-inch,
|
||||
M1 Pro/Max, 2021).
|
||||
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t600x-die0.dtsi | 14 ++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi | 7 +++++++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
index 96f8c2189f03..b549059a3320 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
@@ -260,6 +260,20 @@ spi1: spi@39b104000 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ spi3: spi@39b10c000 {
|
||||
+ compatible = "apple,t6000-spi", "apple,spi";
|
||||
+ reg = <0x3 0x9b10c000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 0 1109 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ clocks = <&clkref>;
|
||||
+ pinctrl-0 = <&spi3_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ power-domains = <&ps_spi3>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
serial0: serial@39b200000 {
|
||||
compatible = "apple,s5l-uart";
|
||||
reg = <0x3 0x9b200000 0x0 0x1000>;
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi b/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
|
||||
index 855dcf30a502..1a994c3c1b79 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
|
||||
@@ -43,6 +43,13 @@ spi1_pins: spi1-pins {
|
||||
<APPLE_PINMUX(33, 1)>;
|
||||
};
|
||||
|
||||
+ spi3_pins: spi3-pins {
|
||||
+ pinmux = <APPLE_PINMUX(52, 1)>,
|
||||
+ <APPLE_PINMUX(53, 1)>,
|
||||
+ <APPLE_PINMUX(54, 1)>,
|
||||
+ <APPLE_PINMUX(55, 1)>;
|
||||
+ };
|
||||
+
|
||||
pcie_pins: pcie-pins {
|
||||
pinmux = <APPLE_PINMUX(0, 1)>,
|
||||
<APPLE_PINMUX(1, 1)>,
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,47 @@
|
||||
From aec68ba09ead15a0b2b0fc47809146e2fa28ccf5 Mon Sep 17 00:00:00 2001
|
||||
From: Janne Grunau <j@jannau.net>
|
||||
Date: Thu, 11 Nov 2021 21:31:21 +0100
|
||||
Subject: [PATCH 026/171] arm64: dts: apple: j31[46]: Add keyboard nodes
|
||||
|
||||
Enables keyboard and touchpad input on MacBook Pro (14/16-inch,
|
||||
M1 Pro/Max, 2021).
|
||||
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
---
|
||||
.../arm64/boot/dts/apple/t600x-j314-j316.dtsi | 20 +++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index 55457892c38e..64280ed76feb 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -88,6 +88,26 @@ flash@0 {
|
||||
};
|
||||
};
|
||||
|
||||
+&spi3 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ hid-transport@0 {
|
||||
+ compatible = "apple,spi-hid-transport";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <8000000>;
|
||||
+ /*
|
||||
+ * cs-setup and cs-hold delays are derived from Apple's ADT
|
||||
+ * Mac OS driver meta data secify 45 us for 'cs to clock' and
|
||||
+ * 'clock to cs' delays.
|
||||
+ */
|
||||
+ spi-cs-setup-delay-ns = <20000>;
|
||||
+ spi-cs-hold-delay-ns = <20000>;
|
||||
+ spi-cs-inactive-delay-ns = <250000>;
|
||||
+ spien-gpios = <&pinctrl_ap 194 0>;
|
||||
+ interrupts-extended = <&pinctrl_nub 6 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
/* PCIe devices */
|
||||
&port00 {
|
||||
/* WLAN */
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,631 @@
|
||||
From e000de0d79a99fe707b8c86b8ae4f19b6e6cc78e Mon Sep 17 00:00:00 2001
|
||||
From: Janne Grunau <j@jannau.net>
|
||||
Date: Tue, 17 May 2022 23:54:26 +0200
|
||||
Subject: [PATCH 027/171] arm64: dts: apple: t600x: Add dwc3 nodes
|
||||
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t6001-j375c.dts | 105 +++++++++++
|
||||
arch/arm64/boot/dts/apple/t6002-j375d.dts | 168 ++++++++++++++++++
|
||||
arch/arm64/boot/dts/apple/t600x-dieX.dtsi | 124 +++++++++++++
|
||||
.../arm64/boot/dts/apple/t600x-j314-j316.dtsi | 92 ++++++++++
|
||||
4 files changed, 489 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j375c.dts b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
index 961104d6bd9a..7ab07808a5e9 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
@@ -53,6 +53,24 @@ hpm0: usb-pd@38 {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec0: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Left";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec0_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm1: usb-pd@3f {
|
||||
@@ -61,6 +79,24 @@ hpm1: usb-pd@3f {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec1: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Left Middle";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec1_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm2: usb-pd@3b {
|
||||
@@ -69,6 +105,24 @@ hpm2: usb-pd@3b {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec2: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Right Middle";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec2_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec2_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm3: usb-pd@3c {
|
||||
@@ -77,6 +131,24 @@ hpm3: usb-pd@3c {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec3: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Right";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec3_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec3_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
};
|
||||
|
||||
@@ -116,3 +188,36 @@ &port03 {
|
||||
/* USB xHCI */
|
||||
bus-range = <4 4>;
|
||||
};
|
||||
+
|
||||
+/* USB controllers */
|
||||
+&dwc3_0 {
|
||||
+ port {
|
||||
+ typec0_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_1 {
|
||||
+ port {
|
||||
+ typec1_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_2 {
|
||||
+ port {
|
||||
+ typec2_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec2_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_3 {
|
||||
+ port {
|
||||
+ typec3_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec3_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
index 95e0c3243818..ed88e1eaf7bb 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
@@ -53,6 +53,24 @@ hpm0: usb-pd@38 {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec0: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Left";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec0_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm1: usb-pd@3f {
|
||||
@@ -61,6 +79,24 @@ hpm1: usb-pd@3f {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec1: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Left Middle";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec1_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm2: usb-pd@3b {
|
||||
@@ -69,6 +105,24 @@ hpm2: usb-pd@3b {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec2: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Right Middle";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec2_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec2_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm3: usb-pd@3c {
|
||||
@@ -77,6 +131,24 @@ hpm3: usb-pd@3c {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec3: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Back Right";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec3_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec3_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
/* front-right */
|
||||
@@ -86,6 +158,24 @@ hpm4: usb-pd@39 {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec4: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Front Right";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec4_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec4_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
/* front-left */
|
||||
@@ -95,6 +185,24 @@ hpm5: usb-pd@3a {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec5: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Front Left";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec5_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec5_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
};
|
||||
|
||||
@@ -135,6 +243,66 @@ &port03 {
|
||||
bus-range = <4 4>;
|
||||
};
|
||||
|
||||
+/* USB controllers */
|
||||
+&dwc3_0 {
|
||||
+ port {
|
||||
+ typec0_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_1 {
|
||||
+ port {
|
||||
+ typec1_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_2 {
|
||||
+ port {
|
||||
+ typec2_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec2_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_3 {
|
||||
+ port {
|
||||
+ typec3_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec3_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_0_die1 {
|
||||
+ port {
|
||||
+ typec4_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec4_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_1_die1 {
|
||||
+ port {
|
||||
+ typec5_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec5_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* delete unused USB nodes on die 1 */
|
||||
+
|
||||
+/delete-node/ &dwc3_2_dart_0_die1;
|
||||
+/delete-node/ &dwc3_2_dart_1_die1;
|
||||
+/delete-node/ &dwc3_2_die1;
|
||||
+
|
||||
+/delete-node/ &dwc3_3_dart_0_die1;
|
||||
+/delete-node/ &dwc3_3_dart_1_die1;
|
||||
+/delete-node/ &dwc3_3_die1;
|
||||
+
|
||||
+
|
||||
/* delete unused always-on power-domains on die 1 */
|
||||
|
||||
/delete-node/ &ps_atc2_usb_aon_die1;
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi b/arch/arm64/boot/dts/apple/t600x-dieX.dtsi
|
||||
index 0a437b68e86c..6ada6c7f50fa 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-dieX.dtsi
|
||||
@@ -101,3 +101,127 @@ DIE_NODE(pinctrl_ap): pinctrl@39b028000 {
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
+
|
||||
+ DIE_NODE(dwc3_0_dart_0): iommu@702f00000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0x7 0x02f00000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1194 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc0_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_0_dart_1): iommu@702f80000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0x7 0x02f80000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1194 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc0_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_0): usb@702280000 {
|
||||
+ compatible = "apple,t6000-dwc3", "apple,dwc3", "snps,dwc3";
|
||||
+ reg = <0x7 0x02280000 0x0 0x100000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1190 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ /* dr_mode = "otg"; */
|
||||
+ usb-role-switch;
|
||||
+ role-switch-default-mode = "host";
|
||||
+ iommus = <&DIE_NODE(dwc3_0_dart_0) 0>,
|
||||
+ <&DIE_NODE(dwc3_0_dart_1) 1>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc0_usb)>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_1_dart_0): iommu@b02f00000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0xb 0x02f00000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1211 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc1_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_1_dart_1): iommu@b02f80000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0xb 0x02f80000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1211 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc1_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_1): usb@b02280000 {
|
||||
+ compatible = "apple,t6000-dwc3", "apple,dwc3", "snps,dwc3";
|
||||
+ reg = <0xb 0x02280000 0x0 0x100000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1207 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ /* dr_mode = "otg"; */
|
||||
+ usb-role-switch;
|
||||
+ role-switch-default-mode = "host";
|
||||
+ iommus = <&DIE_NODE(dwc3_1_dart_0) 0>,
|
||||
+ <&DIE_NODE(dwc3_1_dart_1) 1>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc1_usb)>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_2_dart_0): iommu@f02f00000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0xf 0x02f00000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1228 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc2_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_2_dart_1): iommu@f02f80000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0xf 0x02f80000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1228 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc2_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_2): usb@f02280000 {
|
||||
+ compatible = "apple,t6000-dwc3", "apple,dwc3", "snps,dwc3";
|
||||
+ reg = <0xf 0x02280000 0x0 0x100000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1224 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ /* dr_mode = "otg"; */
|
||||
+ usb-role-switch;
|
||||
+ role-switch-default-mode = "host";
|
||||
+ iommus = <&DIE_NODE(dwc3_2_dart_0) 0>,
|
||||
+ <&DIE_NODE(dwc3_2_dart_1) 1>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc2_usb)>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_3_dart_0): iommu@1302f00000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0x13 0x02f00000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1245 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc3_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_3_dart_1): iommu@1302f80000 {
|
||||
+ compatible = "apple,t6000-dart";
|
||||
+ reg = <0x13 0x02f80000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1245 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc3_usb)>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ DIE_NODE(dwc3_3): usb@1302280000 {
|
||||
+ compatible = "apple,t6000-dwc3", "apple,dwc3", "snps,dwc3";
|
||||
+ reg = <0x13 0x02280000 0x0 0x100000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ DIE_NO 1241 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ /* dr_mode = "otg"; */
|
||||
+ usb-role-switch;
|
||||
+ role-switch-default-mode = "host";
|
||||
+ iommus = <&DIE_NODE(dwc3_3_dart_0) 0>,
|
||||
+ <&DIE_NODE(dwc3_3_dart_1) 1>;
|
||||
+ power-domains = <&DIE_NODE(ps_atc3_usb)>;
|
||||
+ };
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index 64280ed76feb..1582a4caccdb 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -48,6 +48,24 @@ hpm0: usb-pd@38 {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec0: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Left Rear";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec0_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm1: usb-pd@3f {
|
||||
@@ -56,6 +74,24 @@ hpm1: usb-pd@3f {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec1: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Left Front";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec1_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
hpm2: usb-pd@3b {
|
||||
@@ -64,6 +100,24 @@ hpm2: usb-pd@3b {
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
+
|
||||
+ typec2: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C Right";
|
||||
+ power-role = "dual";
|
||||
+ data-role = "dual";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ typec2_con_hs: endpoint {
|
||||
+ remote-endpoint = <&typec2_usb_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
/* MagSafe port */
|
||||
@@ -140,3 +194,41 @@ &pcie0_dart_3 {
|
||||
|
||||
/delete-node/ &port02;
|
||||
/delete-node/ &port03;
|
||||
+
|
||||
+/* USB controllers */
|
||||
+&dwc3_0 {
|
||||
+ port {
|
||||
+ typec0_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec0_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_1 {
|
||||
+ port {
|
||||
+ typec1_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec1_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&dwc3_2 {
|
||||
+ port {
|
||||
+ typec2_usb_hs: endpoint {
|
||||
+ remote-endpoint = <&typec2_con_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* ATC3 is used for DisplayPort -> HDMI only */
|
||||
+&dwc3_3_dart_0 {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&dwc3_3_dart_1 {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&dwc3_3 {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,141 @@
|
||||
From 114701eecdf46c638d373e6cd3c7af3a6f61dbfe Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:07:17 +0900
|
||||
Subject: [PATCH 028/171] arm64: dts: apple: Add WiFi module and antenna
|
||||
properties
|
||||
|
||||
Add the new module-instance/antenna-sku properties required to select
|
||||
WiFi firmwares properly to all board device trees.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t6000-j314s.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6000-j316s.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6001-j314c.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6001-j316c.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6001-j375c.dts | 6 ++++++
|
||||
arch/arm64/boot/dts/apple/t6002-j375d.dts | 6 ++++++
|
||||
arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi | 2 ++
|
||||
7 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6000-j314s.dts b/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
index c9e192848fe3..ac35870ca129 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
@@ -16,3 +16,7 @@ / {
|
||||
compatible = "apple,j314s", "apple,t6000", "apple,arm-platform";
|
||||
model = "Apple MacBook Pro (14-inch, M1 Pro, 2021)";
|
||||
};
|
||||
+
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,maldives";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6000-j316s.dts b/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
index ff1803ce2300..77d6d8c14d74 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
@@ -16,3 +16,7 @@ / {
|
||||
compatible = "apple,j316s", "apple,t6000", "apple,arm-platform";
|
||||
model = "Apple MacBook Pro (16-inch, M1 Pro, 2021)";
|
||||
};
|
||||
+
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,madagascar";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j314c.dts b/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
index 1761d15b98c1..0a5655792a8f 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
@@ -16,3 +16,7 @@ / {
|
||||
compatible = "apple,j314c", "apple,t6001", "apple,arm-platform";
|
||||
model = "Apple MacBook Pro (14-inch, M1 Max, 2021)";
|
||||
};
|
||||
+
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,maldives";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j316c.dts b/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
index 750e9beeffc0..9c215531ea54 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
@@ -16,3 +16,7 @@ / {
|
||||
compatible = "apple,j316c", "apple,t6001", "apple,arm-platform";
|
||||
model = "Apple MacBook Pro (16-inch, M1 Max, 2021)";
|
||||
};
|
||||
+
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,madagascar";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j375c.dts b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
index 7ab07808a5e9..15d26674a310 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
@@ -157,9 +157,11 @@ &port00 {
|
||||
/* WLAN */
|
||||
bus-range = <1 1>;
|
||||
wifi0: wifi@0,0 {
|
||||
+ compatible = "pci14e4,4433";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
/* To be filled by the loader */
|
||||
local-mac-address = [00 10 18 00 00 10];
|
||||
+ apple,antenna-sku = "XX";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -189,6 +191,10 @@ &port03 {
|
||||
bus-range = <4 4>;
|
||||
};
|
||||
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,okinawa";
|
||||
+};
|
||||
+
|
||||
/* USB controllers */
|
||||
&dwc3_0 {
|
||||
port {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
index ed88e1eaf7bb..4b84652e0334 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
@@ -211,9 +211,11 @@ &port00 {
|
||||
/* WLAN */
|
||||
bus-range = <1 1>;
|
||||
wifi0: wifi@0,0 {
|
||||
+ compatible = "pci14e4,4433";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
/* To be filled by the loader */
|
||||
local-mac-address = [00 10 18 00 00 10];
|
||||
+ apple,antenna-sku = "XX";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -243,6 +245,10 @@ &port03 {
|
||||
bus-range = <4 4>;
|
||||
};
|
||||
|
||||
+&wifi0 {
|
||||
+ brcm,board-type = "apple,okinawa";
|
||||
+};
|
||||
+
|
||||
/* USB controllers */
|
||||
&dwc3_0 {
|
||||
port {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index 1582a4caccdb..0296506c043b 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -167,9 +167,11 @@ &port00 {
|
||||
/* WLAN */
|
||||
bus-range = <1 1>;
|
||||
wifi0: wifi@0,0 {
|
||||
+ compatible = "pci14e4,4433";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
/* To be filled by the loader */
|
||||
local-mac-address = [00 10 18 00 00 10];
|
||||
+ apple,antenna-sku = "XX";
|
||||
};
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,97 @@
|
||||
From e1a42fe74f4db0536b104053abc6e28097803873 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 6 Feb 2022 21:22:29 +0900
|
||||
Subject: [PATCH 029/171] arm64: dts: apple: Add PCI power enable GPIOs
|
||||
|
||||
t8103:
|
||||
- WLAN (SMC PMU GPIO #13)
|
||||
t600x:
|
||||
- WLAN (SMC PMU GPIO #13)
|
||||
- SD (SMC PMU GPIO #26)
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t6001-j375c.dts | 3 +++
|
||||
arch/arm64/boot/dts/apple/t6002-j375d.dts | 3 +++
|
||||
arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi | 2 ++
|
||||
3 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j375c.dts b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
index 15d26674a310..561a9a4c2bc1 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
@@ -156,6 +156,7 @@ typec3_con_hs: endpoint {
|
||||
&port00 {
|
||||
/* WLAN */
|
||||
bus-range = <1 1>;
|
||||
+ pwren-gpios = <&smc_gpio 13 GPIO_ACTIVE_HIGH>;
|
||||
wifi0: wifi@0,0 {
|
||||
compatible = "pci14e4,4433";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
@@ -168,6 +169,7 @@ wifi0: wifi@0,0 {
|
||||
&port01 {
|
||||
/* SD card reader */
|
||||
bus-range = <2 2>;
|
||||
+ pwren-gpios = <&smc_gpio 26 GPIO_ACTIVE_HIGH>;
|
||||
sdhci0: mmc@0,0 {
|
||||
compatible = "pci17a0,9755";
|
||||
reg = <0x20000 0x0 0x0 0x0 0x0>;
|
||||
@@ -189,6 +191,7 @@ ethernet0: ethernet@0,0 {
|
||||
&port03 {
|
||||
/* USB xHCI */
|
||||
bus-range = <4 4>;
|
||||
+ pwren-gpios = <&smc_gpio 20 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
index 4b84652e0334..72070e9a3277 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
@@ -210,6 +210,7 @@ typec5_con_hs: endpoint {
|
||||
&port00 {
|
||||
/* WLAN */
|
||||
bus-range = <1 1>;
|
||||
+ pwren-gpios = <&smc_gpio 13 GPIO_ACTIVE_HIGH>;
|
||||
wifi0: wifi@0,0 {
|
||||
compatible = "pci14e4,4433";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
@@ -222,6 +223,7 @@ wifi0: wifi@0,0 {
|
||||
&port01 {
|
||||
/* SD card reader */
|
||||
bus-range = <2 2>;
|
||||
+ pwren-gpios = <&smc_gpio 26 GPIO_ACTIVE_HIGH>;
|
||||
sdhci0: mmc@0,0 {
|
||||
compatible = "pci17a0,9755";
|
||||
reg = <0x20000 0x0 0x0 0x0 0x0>;
|
||||
@@ -243,6 +245,7 @@ ethernet0: ethernet@0,0 {
|
||||
&port03 {
|
||||
/* USB xHCI */
|
||||
bus-range = <4 4>;
|
||||
+ pwren-gpios = <&smc_gpio 20 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index 0296506c043b..21608ca46a55 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -166,6 +166,7 @@ hid-transport@0 {
|
||||
&port00 {
|
||||
/* WLAN */
|
||||
bus-range = <1 1>;
|
||||
+ pwren-gpios = <&smc_gpio 13 GPIO_ACTIVE_HIGH>;
|
||||
wifi0: wifi@0,0 {
|
||||
compatible = "pci14e4,4433";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
@@ -178,6 +179,7 @@ wifi0: wifi@0,0 {
|
||||
&port01 {
|
||||
/* SD card reader */
|
||||
bus-range = <2 2>;
|
||||
+ pwren-gpios = <&smc_gpio 26 GPIO_ACTIVE_HIGH>;
|
||||
sdhci0: mmc@0,0 {
|
||||
compatible = "pci17a0,9755";
|
||||
reg = <0x20000 0x0 0x0 0x0 0x0>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,37 @@
|
||||
From fa4bcbf275b4c864bdf5506e44369e9a982d8bc4 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 3 Mar 2022 03:24:36 +0900
|
||||
Subject: [PATCH 030/171] arm64: dts: apple: Add backlight node to j314/j316
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index 21608ca46a55..c5241d5515cf 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -26,6 +26,7 @@ framebuffer0: framebuffer@0 {
|
||||
compatible = "apple,simple-framebuffer", "simple-framebuffer";
|
||||
reg = <0 0 0 0>; /* To be filled by loader */
|
||||
/* Format properties will be added by loader */
|
||||
+ backlight = <&backlight>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
@@ -236,3 +237,11 @@ &dwc3_3_dart_1 {
|
||||
&dwc3_3 {
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
+/ {
|
||||
+ backlight: gpio-bl {
|
||||
+ compatible = "gpio-backlight";
|
||||
+ gpios = <&smc_gpio 19 GPIO_ACTIVE_HIGH>;
|
||||
+ default-on;
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,96 @@
|
||||
From c0ab64753e9a149b5c97f42110b5ff21d0d6322f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Fri, 11 Mar 2022 22:16:25 +0100
|
||||
Subject: [PATCH 031/171] arm64: dts: apple: t600*: Put in audio nodes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t600x-die0.dtsi | 72 +++++++++++++++++++++++
|
||||
1 file changed, 72 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
index b549059a3320..b24dd6ed0a37 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
@@ -441,3 +441,75 @@ port03: pci@3,0 {
|
||||
<0 0 0 4 &port03 0 0 0 3>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ dart_sio_0: iommu@39b004000 {
|
||||
+ compatible = "apple,t6000-dart", "apple,dart";
|
||||
+ reg = <0x3 0x9b004000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 0 1130 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ power-domains = <&ps_sio_cpu>;
|
||||
+ };
|
||||
+
|
||||
+ dart_sio_1: iommu@39b008000 {
|
||||
+ compatible = "apple,t6000-dart", "apple,dart";
|
||||
+ reg = <0x3 0x9b008000 0x0 0x8000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 0 1130 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ power-domains = <&ps_sio_cpu>;
|
||||
+ };
|
||||
+
|
||||
+ nco_clkref: clock-ref {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <1068000000>;
|
||||
+ clock-output-names = "nco_ref";
|
||||
+ };
|
||||
+
|
||||
+ nco: nco@28e03c000 {
|
||||
+ compatible = "apple,t6000-nco", "apple,nco";
|
||||
+ reg = <0x2 0x8e03c000 0x0 0x14000>;
|
||||
+ clocks = <&nco_clkref>;
|
||||
+ #clock-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ admac: dma-controller@39b400000 {
|
||||
+ compatible = "apple,t6000-admac", "apple,admac";
|
||||
+ reg = <0x3 0x9b400000 0x0 0x34000>;
|
||||
+ dma-channels = <16>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 0 1118 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #dma-cells = <1>;
|
||||
+ iommus = <&dart_sio_0 2>, <&dart_sio_1 2>;
|
||||
+ power-domains = <&ps_sio_adma>;
|
||||
+ apple,internal-irq-destination = <1>;
|
||||
+ };
|
||||
+
|
||||
+ mca: mca@9b600000 {
|
||||
+ compatible = "apple,t6000-mca", "apple,mca";
|
||||
+ reg = <0x3 0x9b600000 0x0 0x10000>,
|
||||
+ <0x3 0x9b500000 0x0 0x20000>;
|
||||
+ reg-names = "clusters", "switch";
|
||||
+
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 1112 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 1113 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 1114 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <AIC_IRQ 1115 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+
|
||||
+ clocks = <&nco 0>, <&nco 1>, <&nco 2>, <&nco 3>;
|
||||
+ power-domains = <&ps_audio_p>, <&ps_mca0>, <&ps_mca1>,
|
||||
+ <&ps_mca2>, <&ps_mca3>;
|
||||
+ dmas = <&admac 0>, <&admac 1>, <&admac 2>, <&admac 3>,
|
||||
+ <&admac 4>, <&admac 5>, <&admac 6>, <&admac 7>,
|
||||
+ <&admac 8>, <&admac 9>, <&admac 10>, <&admac 11>,
|
||||
+ <&admac 12>, <&admac 13>, <&admac 14>, <&admac 15>;
|
||||
+ dma-names = "tx0a", "rx0a", "tx0b", "rx0b",
|
||||
+ "tx1a", "rx1a", "tx1b", "rx1b",
|
||||
+ "tx2a", "rx2a", "tx2b", "rx2b",
|
||||
+ "tx3a", "rx3a", "tx3b", "rx3b";
|
||||
+
|
||||
+ #sound-dai-cells = <1>;
|
||||
+ apple,nclusters = <4>;
|
||||
+ };
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,231 @@
|
||||
From c390136c1f033e36969ea59352034603aca42071 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Fri, 11 Mar 2022 22:16:25 +0100
|
||||
Subject: [PATCH 032/171] arm64: dts: apple: t600*: Put in audio nodes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t6001-j375c.dts | 40 +++++++++
|
||||
arch/arm64/boot/dts/apple/t6002-j375d.dts | 40 +++++++++
|
||||
.../arm64/boot/dts/apple/t600x-j314-j316.dtsi | 87 +++++++++++++++++++
|
||||
3 files changed, 167 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j375c.dts b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
index 561a9a4c2bc1..84be4c83f4d4 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
@@ -152,6 +152,18 @@ typec3_con_hs: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
+/* Audio */
|
||||
+&i2c1 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ speaker: codec@38 {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x38>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
/* PCIe devices */
|
||||
&port00 {
|
||||
/* WLAN */
|
||||
@@ -230,3 +242,31 @@ typec3_usb_hs: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+/ {
|
||||
+ sound {
|
||||
+ compatible = "apple,j375-macaudio", "apple,macaudio";
|
||||
+ model = "Mac Studio J375 integrated audio";
|
||||
+
|
||||
+ /*
|
||||
+ * DANGER ZONE: You can blow your speakers!
|
||||
+ *
|
||||
+ * The drivers are not ready, and unless you are careful
|
||||
+ * to attenuate the audio stream, you run the risk of
|
||||
+ * blowing your speakers.
|
||||
+ */
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ dai-link@0 {
|
||||
+ link-name = "Speaker";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 0>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&speaker>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
index 72070e9a3277..58463d957d09 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
@@ -206,6 +206,18 @@ typec5_con_hs: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
+/* Audio */
|
||||
+&i2c1 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ speaker: codec@38 {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x38>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
/* PCIe devices */
|
||||
&port00 {
|
||||
/* WLAN */
|
||||
@@ -322,3 +334,31 @@ typec5_usb_hs: endpoint {
|
||||
|
||||
/delete-node/ &ps_disp0_cpu0_die1;
|
||||
/delete-node/ &ps_disp0_fe_die1;
|
||||
+
|
||||
+/ {
|
||||
+ sound {
|
||||
+ compatible = "apple,j375-macaudio", "apple,macaudio";
|
||||
+ model = "Mac Studio J375 integrated audio";
|
||||
+
|
||||
+ /*
|
||||
+ * DANGER ZONE: You can blow your speakers!
|
||||
+ *
|
||||
+ * The drivers are not ready, and unless you are careful
|
||||
+ * to attenuate the audio stream, you run the risk of
|
||||
+ * blowing your speakers.
|
||||
+ */
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ dai-link@0 {
|
||||
+ link-name = "Speaker";
|
||||
+ mclk-fs = <64>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 0>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&speaker>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index c5241d5515cf..666183f385b5 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -131,6 +131,62 @@ hpm5: usb-pd@3a {
|
||||
};
|
||||
};
|
||||
|
||||
+&i2c1 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ speaker_left_tweet: codec@3a {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x3a>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Left Tweeter";
|
||||
+ };
|
||||
+
|
||||
+ speaker_left_woof1: codec@38 {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x38>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Left Woofer 1";
|
||||
+ };
|
||||
+
|
||||
+ speaker_left_woof2: codec@39 {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x39>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Left Woofer 2";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ speaker_right_tweet: codec@3d {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x3d>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Right Tweeter";
|
||||
+ };
|
||||
+
|
||||
+ speaker_right_woof1: codec@3b {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x3b>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Right Woofer 1";
|
||||
+ };
|
||||
+
|
||||
+ speaker_right_woof2: codec@3c {
|
||||
+ compatible = "ti,sn012776", "ti,tas2764";
|
||||
+ reg = <0x3c>;
|
||||
+ shutdown-gpios = <&pinctrl_ap 178 GPIO_ACTIVE_HIGH>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "Right Woofer 2";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&spi1 {
|
||||
status = "disabled";
|
||||
|
||||
@@ -244,4 +300,35 @@ backlight: gpio-bl {
|
||||
gpios = <&smc_gpio 19 GPIO_ACTIVE_HIGH>;
|
||||
default-on;
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "apple,j314-macaudio", "apple,macaudio";
|
||||
+ model = "MacBook Pro J314/6 integrated audio";
|
||||
+
|
||||
+ /*
|
||||
+ * DANGER ZONE: You can blow your speakers!
|
||||
+ *
|
||||
+ * The drivers are not ready, and unless you are careful
|
||||
+ * to attenuate the audio stream, you run the risk of
|
||||
+ * blowing your speakers.
|
||||
+ */
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ dai-link@0 {
|
||||
+ link-name = "Speakers";
|
||||
+ mclk-fs = <256>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&mca 0>, <&mca 1>;
|
||||
+ };
|
||||
+ codec {
|
||||
+ sound-dai = <&speaker_left_woof1>,
|
||||
+ <&speaker_right_woof1>,
|
||||
+ <&speaker_left_tweet>,
|
||||
+ <&speaker_right_tweet>,
|
||||
+ <&speaker_left_woof2>,
|
||||
+ <&speaker_right_woof2>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 0672eebb472aaef8449aec4cb064acc86e3aae37 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 30 Jun 2022 21:48:46 +0900
|
||||
Subject: [PATCH 033/171] arm64: dts: apple: t600*: Add t8103 compat to cpufreq
|
||||
node
|
||||
|
||||
t600x seems to be fully compatible with t8103, but t8112 introduced
|
||||
minor changes which means we can't provide full functionality with the
|
||||
common compatible. Let t600x claim t8103 compatibility, treating the
|
||||
latter as the common baseline for this SoC family.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t600x-die0.dtsi | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
index b24dd6ed0a37..4c203778aa89 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
cpufreq_hw: cpufreq@210e20000 {
|
||||
- compatible = "apple,t6000-soc-cpufreq", "apple,soc-cpufreq";
|
||||
+ compatible = "apple,t6000-soc-cpufreq", "apple,t8103-soc-cpufreq", "apple,soc-cpufreq";
|
||||
#freq-domain-cells = <1>;
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,50 @@
|
||||
From 6b11a54eb684f097803307b96eb5681c9168b506 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Mon, 27 Jun 2022 22:21:34 +0900
|
||||
Subject: [PATCH 034/171] arm64: dts: apple: t8103: Fix spi4 power domain sort
|
||||
order
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-pmgr.dtsi | 18 +++++++++---------
|
||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
index 68ae594bf5e9..df7f56483ee8 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
|
||||
@@ -387,6 +387,15 @@ ps_spi3: power-controller@258 {
|
||||
power-domains = <&ps_sio>, <&ps_spi_p>;
|
||||
};
|
||||
|
||||
+ ps_spi4: power-controller@260 {
|
||||
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
|
||||
+ reg = <0x260 4>;
|
||||
+ #power-domain-cells = <0>;
|
||||
+ #reset-cells = <0>;
|
||||
+ label = "spi4";
|
||||
+ power-domains = <&ps_sio>, <&ps_spi_p>;
|
||||
+ };
|
||||
+
|
||||
ps_uart_n: power-controller@268 {
|
||||
compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
|
||||
reg = <0x268 4>;
|
||||
@@ -558,15 +567,6 @@ ps_mcc: power-controller@2f8 {
|
||||
apple,always-on; /* Memory controller */
|
||||
};
|
||||
|
||||
- ps_spi4: power-controller@260 {
|
||||
- compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
|
||||
- reg = <0x260 4>;
|
||||
- #power-domain-cells = <0>;
|
||||
- #reset-cells = <0>;
|
||||
- label = "spi4";
|
||||
- power-domains = <&ps_sio>, <&ps_spi_p>;
|
||||
- };
|
||||
-
|
||||
ps_dcs0: power-controller@300 {
|
||||
compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
|
||||
reg = <0x300 4>;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,117 @@
|
||||
From 3b6593525fd6fe8d09e46e8543fcce20088de1e0 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Wed, 6 Jul 2022 20:04:20 +0200
|
||||
Subject: [PATCH 035/171] arm64: dts: apple: t8103: Add bluetooth device trees
|
||||
|
||||
Signed-off-by: Sven Peter <sven@svenpeter.dev>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8103-j274.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j293.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j313.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j456.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-j457.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 8 ++++++++
|
||||
6 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
index 811008bd73f3..4efbb085e407 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
|
||||
@@ -25,6 +25,10 @@ &wifi0 {
|
||||
brcm,board-type = "apple,atlantisb";
|
||||
};
|
||||
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,atlantisb";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
index 7eb98e6b947c..3a5ae54f0b9f 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
|
||||
@@ -21,6 +21,10 @@ &wifi0 {
|
||||
brcm,board-type = "apple,honshu";
|
||||
};
|
||||
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,honshu";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
index d1f65e48699f..b51f651d2326 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
|
||||
@@ -21,6 +21,10 @@ &wifi0 {
|
||||
brcm,board-type = "apple,shikoku";
|
||||
};
|
||||
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,shikoku";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
index e65053f3bd2c..5e098e8056e1 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j456.dts
|
||||
@@ -25,6 +25,10 @@ &wifi0 {
|
||||
brcm,board-type = "apple,capri";
|
||||
};
|
||||
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,capri";
|
||||
+};
|
||||
+
|
||||
&i2c0 {
|
||||
hpm2: usb-pd@3b {
|
||||
compatible = "apple,cd321x";
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
index 925fe4058055..f67c0b52075a 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-j457.dts
|
||||
@@ -25,6 +25,10 @@ &wifi0 {
|
||||
brcm,board-type = "apple,santorini";
|
||||
};
|
||||
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,santorini";
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Provide labels for the USB type C ports.
|
||||
*/
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
index e62664b6e450..7a814c7abe0c 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
+ bluetooth0 = &bluetooth0;
|
||||
serial0 = &serial0;
|
||||
serial2 = &serial2;
|
||||
wifi0 = &wifi0;
|
||||
@@ -129,4 +130,11 @@ wifi0: network@0,0 {
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
apple,antenna-sku = "XX";
|
||||
};
|
||||
+
|
||||
+ bluetooth0: network@0,1 {
|
||||
+ compatible = "pci14e4,5f69";
|
||||
+ reg = <0x10100 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-bd-address = [00 00 00 00 00 00];
|
||||
+ };
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,167 @@
|
||||
From 14fa82e8f1e6e379983d8222ed3214552c4b5c48 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Mon, 11 Jul 2022 20:05:02 +0900
|
||||
Subject: [PATCH 036/171] arm64: dts: apple: t600x: Add bluetooth device trees
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t6000-j314s.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6000-j316s.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6001-j314c.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6001-j316c.dts | 4 ++++
|
||||
arch/arm64/boot/dts/apple/t6001-j375c.dts | 12 ++++++++++++
|
||||
arch/arm64/boot/dts/apple/t6002-j375d.dts | 12 ++++++++++++
|
||||
arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi | 8 ++++++++
|
||||
7 files changed, 48 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6000-j314s.dts b/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
index ac35870ca129..1430b91ff1b1 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6000-j314s.dts
|
||||
@@ -20,3 +20,7 @@ / {
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,maldives";
|
||||
};
|
||||
+
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,maldives";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6000-j316s.dts b/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
index 77d6d8c14d74..da0cbe7d9673 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6000-j316s.dts
|
||||
@@ -20,3 +20,7 @@ / {
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,madagascar";
|
||||
};
|
||||
+
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,madagascar";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j314c.dts b/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
index 0a5655792a8f..c37097dcfdb3 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j314c.dts
|
||||
@@ -20,3 +20,7 @@ / {
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,maldives";
|
||||
};
|
||||
+
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,maldives";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j316c.dts b/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
index 9c215531ea54..3bc6e0c3294c 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j316c.dts
|
||||
@@ -20,3 +20,7 @@ / {
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,madagascar";
|
||||
};
|
||||
+
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,madagascar";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6001-j375c.dts b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
index 84be4c83f4d4..0f278170bd7a 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6001-j375c.dts
|
||||
@@ -18,6 +18,7 @@ / {
|
||||
aliases {
|
||||
serial0 = &serial0;
|
||||
wifi0 = &wifi0;
|
||||
+ bluetooth0 = &bluetooth0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -176,6 +177,13 @@ wifi0: wifi@0,0 {
|
||||
local-mac-address = [00 10 18 00 00 10];
|
||||
apple,antenna-sku = "XX";
|
||||
};
|
||||
+
|
||||
+ bluetooth0: network@0,1 {
|
||||
+ compatible = "pci14e4,5f71";
|
||||
+ reg = <0x10100 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-bd-address = [00 00 00 00 00 00];
|
||||
+ };
|
||||
};
|
||||
|
||||
&port01 {
|
||||
@@ -210,6 +218,10 @@ &wifi0 {
|
||||
brcm,board-type = "apple,okinawa";
|
||||
};
|
||||
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,okinawa";
|
||||
+};
|
||||
+
|
||||
/* USB controllers */
|
||||
&dwc3_0 {
|
||||
port {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
index 58463d957d09..e3a554c6aa5e 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts
|
||||
@@ -18,6 +18,7 @@ / {
|
||||
aliases {
|
||||
serial0 = &serial0;
|
||||
wifi0 = &wifi0;
|
||||
+ bluetooth0 = &bluetooth0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -230,6 +231,13 @@ wifi0: wifi@0,0 {
|
||||
local-mac-address = [00 10 18 00 00 10];
|
||||
apple,antenna-sku = "XX";
|
||||
};
|
||||
+
|
||||
+ bluetooth0: network@0,1 {
|
||||
+ compatible = "pci14e4,5f71";
|
||||
+ reg = <0x10100 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-bd-address = [00 00 00 00 00 00];
|
||||
+ };
|
||||
};
|
||||
|
||||
&port01 {
|
||||
@@ -264,6 +272,10 @@ &wifi0 {
|
||||
brcm,board-type = "apple,okinawa";
|
||||
};
|
||||
|
||||
+&bluetooth0 {
|
||||
+ brcm,board-type = "apple,okinawa";
|
||||
+};
|
||||
+
|
||||
/* USB controllers */
|
||||
&dwc3_0 {
|
||||
port {
|
||||
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
index 666183f385b5..bbe66ea64f09 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
|
||||
@@ -13,6 +13,7 @@ / {
|
||||
aliases {
|
||||
serial0 = &serial0;
|
||||
wifi0 = &wifi0;
|
||||
+ bluetooth0 = &bluetooth0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -231,6 +232,13 @@ wifi0: wifi@0,0 {
|
||||
local-mac-address = [00 10 18 00 00 10];
|
||||
apple,antenna-sku = "XX";
|
||||
};
|
||||
+
|
||||
+ bluetooth0: network@0,1 {
|
||||
+ compatible = "pci14e4,5f71";
|
||||
+ reg = <0x10100 0x0 0x0 0x0 0x0>;
|
||||
+ /* To be filled by the loader */
|
||||
+ local-bd-address = [00 00 00 00 00 00];
|
||||
+ };
|
||||
};
|
||||
|
||||
&port01 {
|
||||
--
|
||||
2.34.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,26 @@
|
||||
From 792f2972bf4474af46468ab83cc7e0ab91469f2c Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 24 Jul 2022 00:11:49 +0900
|
||||
Subject: [PATCH 038/171] arm64: dts: apple: t8112-j413: Fix IRQ for hpm5
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
arch/arm64/boot/dts/apple/t8112-j413.dts | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/apple/t8112-j413.dts b/arch/arm64/boot/dts/apple/t8112-j413.dts
|
||||
index 0cc993c0a5b4..0d4306a39fe8 100644
|
||||
--- a/arch/arm64/boot/dts/apple/t8112-j413.dts
|
||||
+++ b/arch/arm64/boot/dts/apple/t8112-j413.dts
|
||||
@@ -74,7 +74,7 @@ hpm5: usb-pd@3a {
|
||||
compatible = "apple,cd321x";
|
||||
reg = <0x3a>;
|
||||
interrupt-parent = <&pinctrl_ap>;
|
||||
- interrupts = <174 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "irq";
|
||||
};
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,30 @@
|
||||
From aa4f300d5409c9a3d21787d170755ed417f95157 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 12 Dec 2021 12:28:41 +0900
|
||||
Subject: [PATCH 039/171] MAINTAINERS: Add Apple dwc3 bindings to ARM/APPLE
|
||||
|
||||
This Apple dwc3 controller variance is present on Apple ARM SoCs (t8103/t600x).
|
||||
|
||||
Splitting this change from the binding/driver commits to avoid merge
|
||||
conflicts with other things touching this section, as usual.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 64379c699903..b346659f9562 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -1843,6 +1843,7 @@ F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
|
||||
F: Documentation/devicetree/bindings/pci/apple,pcie.yaml
|
||||
F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
|
||||
F: Documentation/devicetree/bindings/power/apple*
|
||||
+F: Documentation/devicetree/bindings/usb/apple,dwc3.yaml
|
||||
F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
|
||||
F: arch/arm64/boot/dts/apple/
|
||||
F: drivers/clk/clk-apple-nco.c
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,38 @@
|
||||
From fa0ce4da1a4d60e003f808c21c008fb19ee31152 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 12 Dec 2021 12:28:41 +0900
|
||||
Subject: [PATCH 040/171] MAINTAINERS: Add apple-spi driver & binding files
|
||||
|
||||
This Apple SPI controller is present on Apple ARM SoCs (t8103/t6000).
|
||||
|
||||
Splitting this change from the binding/driver commits to avoid merge
|
||||
conflicts with other things touching this section, as usual.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
MAINTAINERS | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index b346659f9562..629c1a177d3f 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -1843,6 +1843,7 @@ F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
|
||||
F: Documentation/devicetree/bindings/pci/apple,pcie.yaml
|
||||
F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
|
||||
F: Documentation/devicetree/bindings/power/apple*
|
||||
+F: Documentation/devicetree/bindings/spi/apple,spi.yaml
|
||||
F: Documentation/devicetree/bindings/usb/apple,dwc3.yaml
|
||||
F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
|
||||
F: arch/arm64/boot/dts/apple/
|
||||
@@ -1856,6 +1857,7 @@ F: drivers/nvme/host/apple.c
|
||||
F: drivers/nvmem/apple-efuses.c
|
||||
F: drivers/pinctrl/pinctrl-apple-gpio.c
|
||||
F: drivers/soc/apple/*
|
||||
+F: drivers/spi/spi-apple.c
|
||||
F: drivers/watchdog/apple_wdt.c
|
||||
F: include/dt-bindings/interrupt-controller/apple-aic.h
|
||||
F: include/dt-bindings/pinctrl/apple.h
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,74 @@
|
||||
From 8a4bb71a27420d66c52e0b0347dddb5853c69a15 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 8 Feb 2022 16:57:47 +0900
|
||||
Subject: [PATCH 041/171] mailbox: apple: Implement flush() operation
|
||||
|
||||
This allows clients to use the atomic-safe mailbox API style.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/mailbox/apple-mailbox.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c
|
||||
index 496c4951ccb1..33e7acf71e3e 100644
|
||||
--- a/drivers/mailbox/apple-mailbox.c
|
||||
+++ b/drivers/mailbox/apple-mailbox.c
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/apple-mailbox.h>
|
||||
+#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -112,6 +113,14 @@ static bool apple_mbox_hw_can_send(struct apple_mbox *apple_mbox)
|
||||
return !(mbox_ctrl & apple_mbox->hw->control_full);
|
||||
}
|
||||
|
||||
+static bool apple_mbox_hw_send_empty(struct apple_mbox *apple_mbox)
|
||||
+{
|
||||
+ u32 mbox_ctrl =
|
||||
+ readl_relaxed(apple_mbox->regs + apple_mbox->hw->a2i_control);
|
||||
+
|
||||
+ return mbox_ctrl & apple_mbox->hw->control_empty;
|
||||
+}
|
||||
+
|
||||
static int apple_mbox_hw_send(struct apple_mbox *apple_mbox,
|
||||
struct apple_mbox_msg *msg)
|
||||
{
|
||||
@@ -219,6 +228,23 @@ static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout)
|
||||
+{
|
||||
+ struct apple_mbox *apple_mbox = chan->con_priv;
|
||||
+ unsigned long deadline = jiffies + msecs_to_jiffies(timeout);
|
||||
+
|
||||
+ while (time_before(jiffies, deadline)) {
|
||||
+ if (apple_mbox_hw_send_empty(apple_mbox)) {
|
||||
+ mbox_chan_txdone(&apple_mbox->chan, 0);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+
|
||||
+ return -ETIME;
|
||||
+}
|
||||
+
|
||||
static int apple_mbox_chan_startup(struct mbox_chan *chan)
|
||||
{
|
||||
struct apple_mbox *apple_mbox = chan->con_priv;
|
||||
@@ -250,6 +276,7 @@ static void apple_mbox_chan_shutdown(struct mbox_chan *chan)
|
||||
|
||||
static const struct mbox_chan_ops apple_mbox_ops = {
|
||||
.send_data = apple_mbox_chan_send_data,
|
||||
+ .flush = apple_mbox_chan_flush,
|
||||
.startup = apple_mbox_chan_startup,
|
||||
.shutdown = apple_mbox_chan_shutdown,
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,106 @@
|
||||
From fa28fb2edcc310f9038538b2f1d27998b01c7db7 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 8 Feb 2022 19:16:08 +0900
|
||||
Subject: [PATCH 042/171] mailbox: apple: Implement poll_data() operation
|
||||
|
||||
This allows clients running in atomic context to poll for messages to
|
||||
arrive.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/mailbox/apple-mailbox.c | 37 ++++++++++++++++++++++++++++++---
|
||||
1 file changed, 34 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c
|
||||
index 33e7acf71e3e..1c14ff63f3d3 100644
|
||||
--- a/drivers/mailbox/apple-mailbox.c
|
||||
+++ b/drivers/mailbox/apple-mailbox.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define APPLE_ASC_MBOX_CONTROL_FULL BIT(16)
|
||||
@@ -101,6 +102,7 @@ struct apple_mbox {
|
||||
|
||||
struct device *dev;
|
||||
struct mbox_controller controller;
|
||||
+ spinlock_t rx_lock;
|
||||
};
|
||||
|
||||
static const struct of_device_id apple_mbox_of_match[];
|
||||
@@ -204,13 +206,16 @@ static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
|
||||
+static int apple_mbox_poll(struct apple_mbox *apple_mbox)
|
||||
{
|
||||
- struct apple_mbox *apple_mbox = data;
|
||||
+
|
||||
struct apple_mbox_msg msg;
|
||||
+ int ret = 0;
|
||||
|
||||
- while (apple_mbox_hw_recv(apple_mbox, &msg) == 0)
|
||||
+ while (apple_mbox_hw_recv(apple_mbox, &msg) == 0) {
|
||||
mbox_chan_received_data(&apple_mbox->chan, (void *)&msg);
|
||||
+ ret++;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* The interrupt will keep firing even if there are no more messages
|
||||
@@ -225,9 +230,33 @@ static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
|
||||
apple_mbox->regs + apple_mbox->hw->irq_ack);
|
||||
}
|
||||
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
|
||||
+{
|
||||
+ struct apple_mbox *apple_mbox = data;
|
||||
+
|
||||
+ spin_lock(&apple_mbox->rx_lock);
|
||||
+ apple_mbox_poll(apple_mbox);
|
||||
+ spin_unlock(&apple_mbox->rx_lock);
|
||||
+
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static bool apple_mbox_chan_peek_data(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct apple_mbox *apple_mbox = chan->con_priv;
|
||||
+ unsigned long flags;
|
||||
+ int ret;
|
||||
+
|
||||
+ spin_lock_irqsave(&apple_mbox->rx_lock, flags);
|
||||
+ ret = apple_mbox_poll(apple_mbox);
|
||||
+ spin_unlock_irqrestore(&apple_mbox->rx_lock, flags);
|
||||
+
|
||||
+ return ret > 0;
|
||||
+}
|
||||
+
|
||||
static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout)
|
||||
{
|
||||
struct apple_mbox *apple_mbox = chan->con_priv;
|
||||
@@ -276,6 +305,7 @@ static void apple_mbox_chan_shutdown(struct mbox_chan *chan)
|
||||
|
||||
static const struct mbox_chan_ops apple_mbox_ops = {
|
||||
.send_data = apple_mbox_chan_send_data,
|
||||
+ .peek_data = apple_mbox_chan_peek_data,
|
||||
.flush = apple_mbox_chan_flush,
|
||||
.startup = apple_mbox_chan_startup,
|
||||
.shutdown = apple_mbox_chan_shutdown,
|
||||
@@ -331,6 +361,7 @@ static int apple_mbox_probe(struct platform_device *pdev)
|
||||
mbox->controller.txdone_irq = true;
|
||||
mbox->controller.of_xlate = apple_mbox_of_xlate;
|
||||
mbox->chan.con_priv = mbox;
|
||||
+ spin_lock_init(&mbox->rx_lock);
|
||||
|
||||
irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-recv", dev_name(dev));
|
||||
if (!irqname)
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,45 @@
|
||||
From 9a204cb4333ca42ebc6401f8c782f99c82f3a75d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sat, 5 Mar 2022 01:08:33 +0900
|
||||
Subject: [PATCH 043/171] mailbox: apple: Keep IRQs active in suspend
|
||||
|
||||
Some consumers (notably SMC) need to be wakeup sources for s2idle,
|
||||
so the IRQs need to stay enabled during suspend. We expect
|
||||
consumers to properly suspend coprocessors such that no IRQs would
|
||||
be triggered where not necessary, so this can be done unconditionally.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/mailbox/apple-mailbox.c | 9 ++++-----
|
||||
1 file changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c
|
||||
index 1c14ff63f3d3..4b34b4d11bd6 100644
|
||||
--- a/drivers/mailbox/apple-mailbox.c
|
||||
+++ b/drivers/mailbox/apple-mailbox.c
|
||||
@@ -369,8 +369,8 @@ static int apple_mbox_probe(struct platform_device *pdev)
|
||||
|
||||
ret = devm_request_threaded_irq(dev, mbox->irq_recv_not_empty, NULL,
|
||||
apple_mbox_recv_irq,
|
||||
- IRQF_NO_AUTOEN | IRQF_ONESHOT, irqname,
|
||||
- mbox);
|
||||
+ IRQF_NO_AUTOEN | IRQF_ONESHOT | IRQF_NO_SUSPEND,
|
||||
+ irqname, mbox);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -378,9 +378,8 @@ static int apple_mbox_probe(struct platform_device *pdev)
|
||||
if (!irqname)
|
||||
return -ENOMEM;
|
||||
|
||||
- ret = devm_request_irq(dev, mbox->irq_send_empty,
|
||||
- apple_mbox_send_empty_irq, IRQF_NO_AUTOEN,
|
||||
- irqname, mbox);
|
||||
+ ret = devm_request_irq(dev, mbox->irq_send_empty, apple_mbox_send_empty_irq,
|
||||
+ IRQF_NO_AUTOEN | IRQF_NO_SUSPEND, irqname, mbox);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,101 @@
|
||||
From f30928052eeecd551f0d3bbf5a7ac63913cbf6ae Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 5 May 2022 01:36:27 +0900
|
||||
Subject: [PATCH 044/171] mailbox: apple: Fix races around poll/tx
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/mailbox/apple-mailbox.c | 33 +++++++++++++++++++++++++++++----
|
||||
1 file changed, 29 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c
|
||||
index 4b34b4d11bd6..06c7ad3b1c03 100644
|
||||
--- a/drivers/mailbox/apple-mailbox.c
|
||||
+++ b/drivers/mailbox/apple-mailbox.c
|
||||
@@ -103,6 +103,8 @@ struct apple_mbox {
|
||||
struct device *dev;
|
||||
struct mbox_controller controller;
|
||||
spinlock_t rx_lock;
|
||||
+ spinlock_t tx_lock;
|
||||
+ bool tx_pending;
|
||||
};
|
||||
|
||||
static const struct of_device_id apple_mbox_of_match[];
|
||||
@@ -166,11 +168,15 @@ static int apple_mbox_chan_send_data(struct mbox_chan *chan, void *data)
|
||||
{
|
||||
struct apple_mbox *apple_mbox = chan->con_priv;
|
||||
struct apple_mbox_msg *msg = data;
|
||||
+ unsigned long flags;
|
||||
int ret;
|
||||
|
||||
+ spin_lock_irqsave(&apple_mbox->tx_lock, flags);
|
||||
+ WARN_ON(apple_mbox->tx_pending);
|
||||
+
|
||||
ret = apple_mbox_hw_send(apple_mbox, msg);
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto err_unlock;
|
||||
|
||||
/*
|
||||
* The interrupt is level triggered and will keep firing as long as the
|
||||
@@ -185,9 +191,13 @@ static int apple_mbox_chan_send_data(struct mbox_chan *chan, void *data)
|
||||
writel_relaxed(apple_mbox->hw->irq_bit_send_empty,
|
||||
apple_mbox->regs + apple_mbox->hw->irq_ack);
|
||||
}
|
||||
+ apple_mbox->tx_pending = true;
|
||||
enable_irq(apple_mbox->irq_send_empty);
|
||||
|
||||
- return 0;
|
||||
+err_unlock:
|
||||
+ spin_unlock_irqrestore(&apple_mbox->tx_lock, flags);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data)
|
||||
@@ -202,7 +212,14 @@ static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data)
|
||||
* it at the main controller again.
|
||||
*/
|
||||
disable_irq_nosync(apple_mbox->irq_send_empty);
|
||||
- mbox_chan_txdone(&apple_mbox->chan, 0);
|
||||
+ spin_lock(&apple_mbox->tx_lock);
|
||||
+ if (apple_mbox->tx_pending) {
|
||||
+ apple_mbox->tx_pending = false;
|
||||
+ spin_unlock(&apple_mbox->tx_lock);
|
||||
+ mbox_chan_txdone(&apple_mbox->chan, 0);
|
||||
+ } else {
|
||||
+ spin_unlock(&apple_mbox->tx_lock);
|
||||
+ }
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -261,10 +278,17 @@ static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout)
|
||||
{
|
||||
struct apple_mbox *apple_mbox = chan->con_priv;
|
||||
unsigned long deadline = jiffies + msecs_to_jiffies(timeout);
|
||||
+ unsigned long flags;
|
||||
|
||||
while (time_before(jiffies, deadline)) {
|
||||
if (apple_mbox_hw_send_empty(apple_mbox)) {
|
||||
- mbox_chan_txdone(&apple_mbox->chan, 0);
|
||||
+ spin_lock_irqsave(&apple_mbox->tx_lock, flags);
|
||||
+ if (apple_mbox->tx_pending) {
|
||||
+ apple_mbox->tx_pending = false;
|
||||
+ disable_irq_nosync(apple_mbox->irq_send_empty);
|
||||
+ }
|
||||
+ /* Mailbox subsystem will call txdone for us */
|
||||
+ spin_unlock_irqrestore(&apple_mbox->tx_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -362,6 +386,7 @@ static int apple_mbox_probe(struct platform_device *pdev)
|
||||
mbox->controller.of_xlate = apple_mbox_of_xlate;
|
||||
mbox->chan.con_priv = mbox;
|
||||
spin_lock_init(&mbox->rx_lock);
|
||||
+ spin_lock_init(&mbox->tx_lock);
|
||||
|
||||
irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-recv", dev_name(dev));
|
||||
if (!irqname)
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 34019420175a9edf6d35b567815757eee727f078 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 5 May 2022 01:37:01 +0900
|
||||
Subject: [PATCH 045/171] WIP: mailbox: fix poll
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/mailbox/mailbox.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
|
||||
index 4229b9b5da98..e27500e8cba9 100644
|
||||
--- a/drivers/mailbox/mailbox.c
|
||||
+++ b/drivers/mailbox/mailbox.c
|
||||
@@ -310,7 +310,7 @@ int mbox_flush(struct mbox_chan *chan, unsigned long timeout)
|
||||
return -ENOTSUPP;
|
||||
|
||||
ret = chan->mbox->ops->flush(chan, timeout);
|
||||
- if (ret < 0)
|
||||
+ if (ret >= 0)
|
||||
tx_tick(chan, ret);
|
||||
|
||||
return ret;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,37 @@
|
||||
From 88e0c4540822cbd63ec7618eaed2279126bdd042 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Tue, 2 Nov 2021 18:10:51 +0100
|
||||
Subject: [PATCH 046/171] dt-bindings: iommu: dart: add t6000 compatible
|
||||
|
||||
The M1 Max/Pro SoCs come with a new DART variant that is incompatible with
|
||||
the previous one. Add a new compatible for those.
|
||||
|
||||
Signed-off-by: Sven Peter <sven@svenpeter.dev>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
|
||||
Series-changes: 2
|
||||
- added Rob's Acked-by:
|
||||
|
||||
Patch-cc: Mark Kettenis <mark.kettenis@xs4all.nl>
|
||||
---
|
||||
Documentation/devicetree/bindings/iommu/apple,dart.yaml | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/iommu/apple,dart.yaml b/Documentation/devicetree/bindings/iommu/apple,dart.yaml
|
||||
index 82ad669feef7..06af2bacbe97 100644
|
||||
--- a/Documentation/devicetree/bindings/iommu/apple,dart.yaml
|
||||
+++ b/Documentation/devicetree/bindings/iommu/apple,dart.yaml
|
||||
@@ -22,7 +22,9 @@ description: |+
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
- const: apple,t8103-dart
|
||||
+ enum:
|
||||
+ - apple,t8103-dart
|
||||
+ - apple,t6000-dart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,825 @@
|
||||
From 799fd906a17a263eaad29e3246dc4b468bb1edc6 Mon Sep 17 00:00:00 2001
|
||||
From: Janne Grunau <j@jannau.net>
|
||||
Date: Wed, 8 Jun 2022 19:07:49 +0200
|
||||
Subject: [PATCH 047/171] iommu/io-pgtable: Move Apple DART support to its own
|
||||
file
|
||||
|
||||
The pte format used by the DARTs found in the Apple M1 (t8103) is not
|
||||
fully compatible with io-pgtable-arm. The 24 MSB are used for subpage
|
||||
protection (mapping only parts of page) and conflict with the address
|
||||
mask. In addition bit 1 is not available for tagging entries but disables
|
||||
subpage protection. Subpage protection could be useful to support a CPU
|
||||
granule of 4k with the fixed IOMMU page size of 16k.
|
||||
|
||||
The DARTs found on Apple M1 Pro/Max/Ultra use another different pte
|
||||
format which is even less compatible. To support an output address size
|
||||
of 42 bit the address is shifted down by 4. Subpage protection is
|
||||
mandatory and bit 1 signifies uncached mappings used by the display
|
||||
controller.
|
||||
|
||||
It would be advantageous to share code for all known Apple DART
|
||||
variants to support common features. The page table allocator for DARTs
|
||||
is less complex since it uses a two levels of translation table without
|
||||
support for huge pages.
|
||||
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
|
||||
Series-changes: 2
|
||||
- add APPLE_DART2 io-pgtable format
|
||||
|
||||
Series-changes: 3
|
||||
- move APPLE_DART to its own io-pgtable implementation, copied from
|
||||
io-pgtable-arm and simplified
|
||||
|
||||
Series-version: 3
|
||||
Cover-letter:
|
||||
iommu: M1 Pro/Max DART support
|
||||
Hej,
|
||||
|
||||
this is the next attempt adding support for the DART found in Apple's
|
||||
M1 Pro/Max/Ultra. This adds a separate io-pgtable implementation for
|
||||
DART. As already mentioned in v2 the pte format is not fully compatible
|
||||
with io-pgtable-arm. Especially the 2nd least significant bit is used
|
||||
and is not available to tag tables/pages.
|
||||
io-pgtable-dart.c is copied from io-pgtable-arm.c and support for
|
||||
unused features is removed. Support for 4k IO pages is left for A7 to
|
||||
A11 SoCs as there's work underway to run Linux on them.
|
||||
|
||||
The incompatibilities between both Apple DART pte seems manageable in
|
||||
their own io-pgtable implementation. A short list of the known
|
||||
differences:
|
||||
|
||||
- the physical addresses are shifted left by 4 bits and and have 2 more
|
||||
bits inside the PTE entries
|
||||
- the read/write protection flags are at a different position
|
||||
- the subpage protection feature is now mandatory. For Linux we can
|
||||
just configure it to always allow access to the entire page.
|
||||
- BIT(1) tags "uncached" mappings (used for the display controller)
|
||||
|
||||
There is second type of DART (t8110) present on M1 Pro/Max SoCs which
|
||||
uses the same PTE format as t6000.
|
||||
END
|
||||
|
||||
Series-to: iommu@lists.linux-foundation.org
|
||||
Series-cc: asahi@lists.linux.dev
|
||||
Series-cc: Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/iommu/Kconfig | 11 +-
|
||||
drivers/iommu/Makefile | 1 +
|
||||
drivers/iommu/io-pgtable-arm.c | 63 ----
|
||||
drivers/iommu/io-pgtable-dart.c | 580 ++++++++++++++++++++++++++++++++
|
||||
drivers/iommu/io-pgtable.c | 2 +
|
||||
6 files changed, 594 insertions(+), 64 deletions(-)
|
||||
create mode 100644 drivers/iommu/io-pgtable-dart.c
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 64379c699903..cb0ceb0b2cfc 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -1849,6 +1849,7 @@ F: drivers/clk/clk-apple-nco.c
|
||||
F: drivers/i2c/busses/i2c-pasemi-core.c
|
||||
F: drivers/i2c/busses/i2c-pasemi-platform.c
|
||||
F: drivers/iommu/apple-dart.c
|
||||
+F: drivers/iommu/io-pgtable-dart.c
|
||||
F: drivers/irqchip/irq-apple-aic.c
|
||||
F: drivers/mailbox/apple-mailbox.c
|
||||
F: drivers/nvme/host/apple.c
|
||||
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
|
||||
index c79a0df090c0..58603124dd42 100644
|
||||
--- a/drivers/iommu/Kconfig
|
||||
+++ b/drivers/iommu/Kconfig
|
||||
@@ -67,6 +67,15 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
|
||||
|
||||
If unsure, say N here.
|
||||
|
||||
+config IOMMU_IO_PGTABLE_DART
|
||||
+ bool "Apple DART Formats"
|
||||
+ select IOMMU_IO_PGTABLE
|
||||
+ depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
|
||||
+ help
|
||||
+ Enable support for the Apple DART pagetable formats. These include
|
||||
+ the t8020 and t6000/t8110 DART formats used in Apple M1/M2 family
|
||||
+ SoCs.
|
||||
+
|
||||
endmenu
|
||||
|
||||
config IOMMU_DEBUGFS
|
||||
@@ -294,7 +303,7 @@ config APPLE_DART
|
||||
tristate "Apple DART IOMMU Support"
|
||||
depends on ARCH_APPLE || (COMPILE_TEST && !GENERIC_ATOMIC64)
|
||||
select IOMMU_API
|
||||
- select IOMMU_IO_PGTABLE_LPAE
|
||||
+ select IOMMU_IO_PGTABLE_DART
|
||||
default ARCH_APPLE
|
||||
help
|
||||
Support for Apple DART (Device Address Resolution Table) IOMMUs
|
||||
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
|
||||
index 44475a9b3eea..cc9f381013c3 100644
|
||||
--- a/drivers/iommu/Makefile
|
||||
+++ b/drivers/iommu/Makefile
|
||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
|
||||
obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
|
||||
obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
|
||||
obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
|
||||
+obj-$(CONFIG_IOMMU_IO_PGTABLE_DART) += io-pgtable-dart.o
|
||||
obj-$(CONFIG_IOASID) += ioasid.o
|
||||
obj-$(CONFIG_IOMMU_IOVA) += iova.o
|
||||
obj-$(CONFIG_OF_IOMMU) += of_iommu.o
|
||||
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
|
||||
index 94ff319ae8ac..d7f5e23da643 100644
|
||||
--- a/drivers/iommu/io-pgtable-arm.c
|
||||
+++ b/drivers/iommu/io-pgtable-arm.c
|
||||
@@ -130,9 +130,6 @@
|
||||
#define ARM_MALI_LPAE_MEMATTR_IMP_DEF 0x88ULL
|
||||
#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL
|
||||
|
||||
-#define APPLE_DART_PTE_PROT_NO_WRITE (1<<7)
|
||||
-#define APPLE_DART_PTE_PROT_NO_READ (1<<8)
|
||||
-
|
||||
/* IOPTE accessors */
|
||||
#define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
|
||||
|
||||
@@ -406,15 +403,6 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
|
||||
{
|
||||
arm_lpae_iopte pte;
|
||||
|
||||
- if (data->iop.fmt == APPLE_DART) {
|
||||
- pte = 0;
|
||||
- if (!(prot & IOMMU_WRITE))
|
||||
- pte |= APPLE_DART_PTE_PROT_NO_WRITE;
|
||||
- if (!(prot & IOMMU_READ))
|
||||
- pte |= APPLE_DART_PTE_PROT_NO_READ;
|
||||
- return pte;
|
||||
- }
|
||||
-
|
||||
if (data->iop.fmt == ARM_64_LPAE_S1 ||
|
||||
data->iop.fmt == ARM_32_LPAE_S1) {
|
||||
pte = ARM_LPAE_PTE_nG;
|
||||
@@ -1107,52 +1095,6 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static struct io_pgtable *
|
||||
-apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
|
||||
-{
|
||||
- struct arm_lpae_io_pgtable *data;
|
||||
- int i;
|
||||
-
|
||||
- if (cfg->oas > 36)
|
||||
- return NULL;
|
||||
-
|
||||
- data = arm_lpae_alloc_pgtable(cfg);
|
||||
- if (!data)
|
||||
- return NULL;
|
||||
-
|
||||
- /*
|
||||
- * The table format itself always uses two levels, but the total VA
|
||||
- * space is mapped by four separate tables, making the MMIO registers
|
||||
- * an effective "level 1". For simplicity, though, we treat this
|
||||
- * equivalently to LPAE stage 2 concatenation at level 2, with the
|
||||
- * additional TTBRs each just pointing at consecutive pages.
|
||||
- */
|
||||
- if (data->start_level < 1)
|
||||
- goto out_free_data;
|
||||
- if (data->start_level == 1 && data->pgd_bits > 2)
|
||||
- goto out_free_data;
|
||||
- if (data->start_level > 1)
|
||||
- data->pgd_bits = 0;
|
||||
- data->start_level = 2;
|
||||
- cfg->apple_dart_cfg.n_ttbrs = 1 << data->pgd_bits;
|
||||
- data->pgd_bits += data->bits_per_level;
|
||||
-
|
||||
- data->pgd = __arm_lpae_alloc_pages(ARM_LPAE_PGD_SIZE(data), GFP_KERNEL,
|
||||
- cfg);
|
||||
- if (!data->pgd)
|
||||
- goto out_free_data;
|
||||
-
|
||||
- for (i = 0; i < cfg->apple_dart_cfg.n_ttbrs; ++i)
|
||||
- cfg->apple_dart_cfg.ttbr[i] =
|
||||
- virt_to_phys(data->pgd + i * ARM_LPAE_GRANULE(data));
|
||||
-
|
||||
- return &data->iop;
|
||||
-
|
||||
-out_free_data:
|
||||
- kfree(data);
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {
|
||||
.alloc = arm_64_lpae_alloc_pgtable_s1,
|
||||
.free = arm_lpae_free_pgtable,
|
||||
@@ -1178,11 +1120,6 @@ struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns = {
|
||||
.free = arm_lpae_free_pgtable,
|
||||
};
|
||||
|
||||
-struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns = {
|
||||
- .alloc = apple_dart_alloc_pgtable,
|
||||
- .free = arm_lpae_free_pgtable,
|
||||
-};
|
||||
-
|
||||
#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST
|
||||
|
||||
static struct io_pgtable_cfg *cfg_cookie __initdata;
|
||||
diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
|
||||
new file mode 100644
|
||||
index 000000000000..0c5222942c65
|
||||
--- /dev/null
|
||||
+++ b/drivers/iommu/io-pgtable-dart.c
|
||||
@@ -0,0 +1,580 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Apple DART page table allocator.
|
||||
+ *
|
||||
+ * Copyright (C) 2022 The Asahi Linux Contributors
|
||||
+ *
|
||||
+ * Based on io-pgtable-arm.
|
||||
+ *
|
||||
+ * Copyright (C) 2014 ARM Limited
|
||||
+ *
|
||||
+ * Author: Will Deacon <will.deacon@arm.com>
|
||||
+ */
|
||||
+
|
||||
+#define pr_fmt(fmt) "dart io-pgtable: " fmt
|
||||
+
|
||||
+#include <linux/atomic.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/io-pgtable.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/sizes.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+#include <asm/barrier.h>
|
||||
+
|
||||
+#define DART_MAX_ADDR_BITS 52
|
||||
+#define DART_MAX_LEVELS 3
|
||||
+
|
||||
+/* Struct accessors */
|
||||
+#define io_pgtable_to_data(x) \
|
||||
+ container_of((x), struct dart_io_pgtable, iop)
|
||||
+
|
||||
+#define io_pgtable_ops_to_data(x) \
|
||||
+ io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
|
||||
+
|
||||
+/*
|
||||
+ * Calculate the right shift amount to get to the portion describing level l
|
||||
+ * in a virtual address mapped by the pagetable in d.
|
||||
+ */
|
||||
+#define DART_LVL_SHIFT(l, d) \
|
||||
+ (((DART_MAX_LEVELS - (l)) * (d)->bits_per_level) + \
|
||||
+ ilog2(sizeof(dart_iopte)))
|
||||
+
|
||||
+#define DART_GRANULE(d) \
|
||||
+ (sizeof(dart_iopte) << (d)->bits_per_level)
|
||||
+#define DART_PGD_SIZE(d) \
|
||||
+ (sizeof(dart_iopte) << (d)->pgd_bits)
|
||||
+
|
||||
+#define DART_PTES_PER_TABLE(d) \
|
||||
+ (DART_GRANULE(d) >> ilog2(sizeof(dart_iopte)))
|
||||
+
|
||||
+/*
|
||||
+ * Calculate the index at level l used to map virtual address a using the
|
||||
+ * pagetable in d.
|
||||
+ */
|
||||
+#define DART_PGD_IDX(l, d) \
|
||||
+ ((l) == (d)->start_level ? (d)->pgd_bits - (d)->bits_per_level : 0)
|
||||
+
|
||||
+#define DART_LVL_IDX(a, l, d) \
|
||||
+ (((u64)(a) >> DART_LVL_SHIFT(l, d)) & \
|
||||
+ ((1 << ((d)->bits_per_level + DART_PGD_IDX(l, d))) - 1))
|
||||
+
|
||||
+/* Calculate the block/page mapping size at level l for pagetable in d. */
|
||||
+#define DART_BLOCK_SIZE(l, d) (1ULL << DART_LVL_SHIFT(l, d))
|
||||
+
|
||||
+#define APPLE_DART1_PADDR_MASK GENMASK_ULL(35, 12)
|
||||
+
|
||||
+/* Apple DART1 protection bits */
|
||||
+#define APPLE_DART1_PTE_PROT_NO_READ BIT(8)
|
||||
+#define APPLE_DART1_PTE_PROT_NO_WRITE BIT(7)
|
||||
+#define APPLE_DART1_PTE_PROT_SP_DIS BIT(1)
|
||||
+
|
||||
+/* marks PTE as valid */
|
||||
+#define APPLE_DART_PTE_VALID BIT(0)
|
||||
+
|
||||
+/* IOPTE accessors */
|
||||
+#define iopte_deref(pte, d) __va(iopte_to_paddr(pte, d))
|
||||
+
|
||||
+struct dart_io_pgtable {
|
||||
+ struct io_pgtable iop;
|
||||
+
|
||||
+ int pgd_bits;
|
||||
+ int start_level;
|
||||
+ int bits_per_level;
|
||||
+
|
||||
+ void *pgd;
|
||||
+};
|
||||
+
|
||||
+typedef u64 dart_iopte;
|
||||
+
|
||||
+static inline bool iopte_leaf(dart_iopte pte, int lvl,
|
||||
+ enum io_pgtable_fmt fmt)
|
||||
+{
|
||||
+ return (lvl == (DART_MAX_LEVELS - 1)) && (pte & APPLE_DART_PTE_VALID);
|
||||
+}
|
||||
+
|
||||
+static dart_iopte paddr_to_iopte(phys_addr_t paddr,
|
||||
+ struct dart_io_pgtable *data)
|
||||
+{
|
||||
+ return paddr & APPLE_DART1_PADDR_MASK;
|
||||
+}
|
||||
+
|
||||
+static phys_addr_t iopte_to_paddr(dart_iopte pte,
|
||||
+ struct dart_io_pgtable *data)
|
||||
+{
|
||||
+ return pte & APPLE_DART1_PADDR_MASK;
|
||||
+}
|
||||
+
|
||||
+static void *__dart_alloc_pages(size_t size, gfp_t gfp,
|
||||
+ struct io_pgtable_cfg *cfg)
|
||||
+{
|
||||
+ struct device *dev = cfg->iommu_dev;
|
||||
+ int order = get_order(size);
|
||||
+ struct page *p;
|
||||
+
|
||||
+ VM_BUG_ON((gfp & __GFP_HIGHMEM));
|
||||
+ p = alloc_pages_node(dev ? dev_to_node(dev) : NUMA_NO_NODE,
|
||||
+ gfp | __GFP_ZERO, order);
|
||||
+ if (!p)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return page_address(p);
|
||||
+}
|
||||
+
|
||||
+static void __dart_free_pages(void *pages, size_t size)
|
||||
+{
|
||||
+ free_pages((unsigned long)pages, get_order(size));
|
||||
+}
|
||||
+
|
||||
+static void __dart_init_pte(struct dart_io_pgtable *data,
|
||||
+ phys_addr_t paddr, dart_iopte prot,
|
||||
+ int lvl, int num_entries, dart_iopte *ptep)
|
||||
+{
|
||||
+ dart_iopte pte = prot;
|
||||
+ size_t sz = DART_BLOCK_SIZE(lvl, data);
|
||||
+ int i;
|
||||
+
|
||||
+ if (lvl == DART_MAX_LEVELS - 1)
|
||||
+ pte |= APPLE_DART1_PTE_PROT_SP_DIS;
|
||||
+
|
||||
+ pte |= APPLE_DART_PTE_VALID;
|
||||
+
|
||||
+ for (i = 0; i < num_entries; i++)
|
||||
+ ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);
|
||||
+}
|
||||
+
|
||||
+static int dart_init_pte(struct dart_io_pgtable *data,
|
||||
+ unsigned long iova, phys_addr_t paddr,
|
||||
+ dart_iopte prot, int lvl, int num_entries,
|
||||
+ dart_iopte *ptep)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < num_entries; i++)
|
||||
+ if (iopte_leaf(ptep[i], lvl, data->iop.fmt)) {
|
||||
+ /* We require an unmap first */
|
||||
+ WARN_ON(iopte_leaf(ptep[i], lvl, data->iop.fmt));
|
||||
+ return -EEXIST;
|
||||
+ }
|
||||
+
|
||||
+ __dart_init_pte(data, paddr, prot, lvl, num_entries, ptep);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static dart_iopte dart_install_table(dart_iopte *table,
|
||||
+ dart_iopte *ptep,
|
||||
+ dart_iopte curr,
|
||||
+ struct dart_io_pgtable *data)
|
||||
+{
|
||||
+ dart_iopte old, new;
|
||||
+
|
||||
+ new = paddr_to_iopte(__pa(table), data) | APPLE_DART_PTE_VALID;
|
||||
+
|
||||
+ /*
|
||||
+ * Ensure the table itself is visible before its PTE can be.
|
||||
+ * Whilst we could get away with cmpxchg64_release below, this
|
||||
+ * doesn't have any ordering semantics when !CONFIG_SMP.
|
||||
+ */
|
||||
+ dma_wmb();
|
||||
+
|
||||
+ old = cmpxchg64_relaxed(ptep, curr, new);
|
||||
+
|
||||
+ return old;
|
||||
+}
|
||||
+
|
||||
+static int __dart_map(struct dart_io_pgtable *data, unsigned long iova,
|
||||
+ phys_addr_t paddr, size_t size, size_t pgcount,
|
||||
+ dart_iopte prot, int lvl, dart_iopte *ptep,
|
||||
+ gfp_t gfp, size_t *mapped)
|
||||
+{
|
||||
+ dart_iopte *cptep, pte;
|
||||
+ size_t block_size = DART_BLOCK_SIZE(lvl, data);
|
||||
+ size_t tblsz = DART_GRANULE(data);
|
||||
+ struct io_pgtable_cfg *cfg = &data->iop.cfg;
|
||||
+ int ret = 0, num_entries, max_entries, map_idx_start;
|
||||
+
|
||||
+ /* Find our entry at the current level */
|
||||
+ map_idx_start = DART_LVL_IDX(iova, lvl, data);
|
||||
+ ptep += map_idx_start;
|
||||
+
|
||||
+ /* If we can install a leaf entry at this level, then do so */
|
||||
+ if (size == block_size) {
|
||||
+ max_entries = DART_PTES_PER_TABLE(data) - map_idx_start;
|
||||
+ num_entries = min_t(int, pgcount, max_entries);
|
||||
+ ret = dart_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep);
|
||||
+ if (!ret && mapped)
|
||||
+ *mapped += num_entries * size;
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* We can't allocate tables at the final level */
|
||||
+ if (WARN_ON(lvl >= DART_MAX_LEVELS - 1))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Grab a pointer to the next level */
|
||||
+ pte = READ_ONCE(*ptep);
|
||||
+ if (!pte) {
|
||||
+ cptep = __dart_alloc_pages(tblsz, gfp, cfg);
|
||||
+ if (!cptep)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pte = dart_install_table(cptep, ptep, 0, data);
|
||||
+ if (pte)
|
||||
+ __dart_free_pages(cptep, tblsz);
|
||||
+ }
|
||||
+
|
||||
+ if (pte && !iopte_leaf(pte, lvl, data->iop.fmt)) {
|
||||
+ cptep = iopte_deref(pte, data);
|
||||
+ } else if (pte) {
|
||||
+ /* We require an unmap first */
|
||||
+ WARN_ON(pte);
|
||||
+ return -EEXIST;
|
||||
+ }
|
||||
+
|
||||
+ /* Rinse, repeat */
|
||||
+ return __dart_map(data, iova, paddr, size, pgcount, prot, lvl + 1,
|
||||
+ cptep, gfp, mapped);
|
||||
+}
|
||||
+
|
||||
+static dart_iopte dart_prot_to_pte(struct dart_io_pgtable *data,
|
||||
+ int prot)
|
||||
+{
|
||||
+ dart_iopte pte = 0;
|
||||
+
|
||||
+ if (!(prot & IOMMU_WRITE))
|
||||
+ pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
|
||||
+ if (!(prot & IOMMU_READ))
|
||||
+ pte |= APPLE_DART1_PTE_PROT_NO_READ;
|
||||
+
|
||||
+ return pte;
|
||||
+}
|
||||
+
|
||||
+static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
+ phys_addr_t paddr, size_t pgsize, size_t pgcount,
|
||||
+ int iommu_prot, gfp_t gfp, size_t *mapped)
|
||||
+{
|
||||
+ struct dart_io_pgtable *data = io_pgtable_ops_to_data(ops);
|
||||
+ struct io_pgtable_cfg *cfg = &data->iop.cfg;
|
||||
+ dart_iopte *ptep = data->pgd;
|
||||
+ int ret, lvl = data->start_level;
|
||||
+ dart_iopte prot;
|
||||
+ long iaext = (s64)iova >> cfg->ias;
|
||||
+
|
||||
+ if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (WARN_ON(iaext || paddr >> cfg->oas))
|
||||
+ return -ERANGE;
|
||||
+
|
||||
+ /* If no access, then nothing to do */
|
||||
+ if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
|
||||
+ return 0;
|
||||
+
|
||||
+ prot = dart_prot_to_pte(data, iommu_prot);
|
||||
+ ret = __dart_map(data, iova, paddr, pgsize, pgcount, prot, lvl,
|
||||
+ ptep, gfp, mapped);
|
||||
+ /*
|
||||
+ * Synchronise all PTE updates for the new mapping before there's
|
||||
+ * a chance for anything to kick off a table walk for the new iova.
|
||||
+ */
|
||||
+ wmb();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int dart_map(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
+ phys_addr_t paddr, size_t size, int iommu_prot, gfp_t gfp)
|
||||
+{
|
||||
+ return dart_map_pages(ops, iova, paddr, size, 1, iommu_prot, gfp,
|
||||
+ NULL);
|
||||
+}
|
||||
+
|
||||
+static void __dart_free_pgtable(struct dart_io_pgtable *data, int lvl,
|
||||
+ dart_iopte *ptep)
|
||||
+{
|
||||
+ dart_iopte *start, *end;
|
||||
+ unsigned long table_size;
|
||||
+
|
||||
+ if (lvl == data->start_level)
|
||||
+ table_size = DART_PGD_SIZE(data);
|
||||
+ else
|
||||
+ table_size = DART_GRANULE(data);
|
||||
+
|
||||
+ start = ptep;
|
||||
+
|
||||
+ /* Only leaf entries at the last level */
|
||||
+ if (lvl == DART_MAX_LEVELS - 1)
|
||||
+ end = ptep;
|
||||
+ else
|
||||
+ end = (void *)ptep + table_size;
|
||||
+
|
||||
+ while (ptep != end) {
|
||||
+ dart_iopte pte = *ptep++;
|
||||
+
|
||||
+ if (!pte || iopte_leaf(pte, lvl, data->iop.fmt))
|
||||
+ continue;
|
||||
+
|
||||
+ __dart_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
|
||||
+ }
|
||||
+
|
||||
+ __dart_free_pages(start, table_size);
|
||||
+}
|
||||
+
|
||||
+static size_t __dart_unmap(struct dart_io_pgtable *data,
|
||||
+ struct iommu_iotlb_gather *gather,
|
||||
+ unsigned long iova, size_t size, size_t pgcount,
|
||||
+ int lvl, dart_iopte *ptep)
|
||||
+{
|
||||
+ dart_iopte pte;
|
||||
+ struct io_pgtable *iop = &data->iop;
|
||||
+ int i = 0, num_entries, max_entries, unmap_idx_start;
|
||||
+
|
||||
+ /* Something went horribly wrong and we ran out of page table */
|
||||
+ if (WARN_ON(lvl == DART_MAX_LEVELS))
|
||||
+ return 0;
|
||||
+
|
||||
+ unmap_idx_start = DART_LVL_IDX(iova, lvl, data);
|
||||
+ ptep += unmap_idx_start;
|
||||
+ pte = READ_ONCE(*ptep);
|
||||
+ if (WARN_ON(!pte))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* If the size matches this level, we're in the right place */
|
||||
+ if (size == DART_BLOCK_SIZE(lvl, data)) {
|
||||
+ max_entries = DART_PTES_PER_TABLE(data) - unmap_idx_start;
|
||||
+ num_entries = min_t(int, pgcount, max_entries);
|
||||
+
|
||||
+ while (i < num_entries) {
|
||||
+ pte = READ_ONCE(*ptep);
|
||||
+ if (WARN_ON(!pte))
|
||||
+ break;
|
||||
+
|
||||
+ /* clear pte */
|
||||
+ *ptep = 0;
|
||||
+
|
||||
+ if (!iopte_leaf(pte, lvl, iop->fmt)) {
|
||||
+ /* Also flush any partial walks */
|
||||
+ io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
|
||||
+ DART_GRANULE(data));
|
||||
+ __dart_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
|
||||
+ } else if (!iommu_iotlb_gather_queued(gather)) {
|
||||
+ io_pgtable_tlb_add_page(iop, gather, iova + i * size, size);
|
||||
+ }
|
||||
+
|
||||
+ ptep++;
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ return i * size;
|
||||
+ }
|
||||
+
|
||||
+ /* Keep on walkin' */
|
||||
+ ptep = iopte_deref(pte, data);
|
||||
+ return __dart_unmap(data, gather, iova, size, pgcount, lvl + 1, ptep);
|
||||
+}
|
||||
+
|
||||
+static size_t dart_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
+ size_t pgsize, size_t pgcount,
|
||||
+ struct iommu_iotlb_gather *gather)
|
||||
+{
|
||||
+ struct dart_io_pgtable *data = io_pgtable_ops_to_data(ops);
|
||||
+ struct io_pgtable_cfg *cfg = &data->iop.cfg;
|
||||
+ dart_iopte *ptep = data->pgd;
|
||||
+ long iaext = (s64)iova >> cfg->ias;
|
||||
+
|
||||
+ if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize || !pgcount))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (WARN_ON(iaext))
|
||||
+ return 0;
|
||||
+
|
||||
+ return __dart_unmap(data, gather, iova, pgsize, pgcount,
|
||||
+ data->start_level, ptep);
|
||||
+}
|
||||
+
|
||||
+static size_t dart_unmap(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
+ size_t size, struct iommu_iotlb_gather *gather)
|
||||
+{
|
||||
+ return dart_unmap_pages(ops, iova, size, 1, gather);
|
||||
+}
|
||||
+
|
||||
+static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops,
|
||||
+ unsigned long iova)
|
||||
+{
|
||||
+ struct dart_io_pgtable *data = io_pgtable_ops_to_data(ops);
|
||||
+ dart_iopte pte, *ptep = data->pgd;
|
||||
+ int lvl = data->start_level;
|
||||
+
|
||||
+ do {
|
||||
+ /* Valid IOPTE pointer? */
|
||||
+ if (!ptep)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Grab the IOPTE we're interested in */
|
||||
+ ptep += DART_LVL_IDX(iova, lvl, data);
|
||||
+ pte = READ_ONCE(*ptep);
|
||||
+
|
||||
+ /* Valid entry? */
|
||||
+ if (!pte)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Leaf entry? */
|
||||
+ if (iopte_leaf(pte, lvl, data->iop.fmt))
|
||||
+ goto found_translation;
|
||||
+
|
||||
+ /* Take it to the next level */
|
||||
+ ptep = iopte_deref(pte, data);
|
||||
+ } while (++lvl < DART_MAX_LEVELS);
|
||||
+
|
||||
+ /* Ran out of page tables to walk */
|
||||
+ return 0;
|
||||
+
|
||||
+found_translation:
|
||||
+ iova &= (DART_BLOCK_SIZE(lvl, data) - 1);
|
||||
+ return iopte_to_paddr(pte, data) | iova;
|
||||
+}
|
||||
+
|
||||
+static void dart_restrict_pgsizes(struct io_pgtable_cfg *cfg)
|
||||
+{
|
||||
+ unsigned long granule, page_sizes;
|
||||
+ unsigned int max_addr_bits = 48;
|
||||
+
|
||||
+ /*
|
||||
+ * We need to restrict the supported page sizes to match the
|
||||
+ * translation regime for a particular granule. Aim to match
|
||||
+ * the CPU page size if possible, otherwise prefer smaller sizes.
|
||||
+ * While we're at it, restrict the block sizes to match the
|
||||
+ * chosen granule.
|
||||
+ */
|
||||
+ if (cfg->pgsize_bitmap & PAGE_SIZE)
|
||||
+ granule = PAGE_SIZE;
|
||||
+ else if (cfg->pgsize_bitmap & ~PAGE_MASK)
|
||||
+ granule = 1UL << __fls(cfg->pgsize_bitmap & ~PAGE_MASK);
|
||||
+ else if (cfg->pgsize_bitmap & PAGE_MASK)
|
||||
+ granule = 1UL << __ffs(cfg->pgsize_bitmap & PAGE_MASK);
|
||||
+ else
|
||||
+ granule = 0;
|
||||
+
|
||||
+ switch (granule) {
|
||||
+ case SZ_4K:
|
||||
+ page_sizes = (SZ_4K | SZ_2M | SZ_1G);
|
||||
+ break;
|
||||
+ case SZ_16K:
|
||||
+ page_sizes = (SZ_16K | SZ_32M);
|
||||
+ break;
|
||||
+ default:
|
||||
+ page_sizes = 0;
|
||||
+ }
|
||||
+
|
||||
+ cfg->pgsize_bitmap &= page_sizes;
|
||||
+ cfg->ias = min(cfg->ias, max_addr_bits);
|
||||
+ cfg->oas = min(cfg->oas, max_addr_bits);
|
||||
+}
|
||||
+
|
||||
+static struct dart_io_pgtable *
|
||||
+dart_alloc_pgtable(struct io_pgtable_cfg *cfg)
|
||||
+{
|
||||
+ struct dart_io_pgtable *data;
|
||||
+ int bits_per_level, levels, va_bits, pg_shift;
|
||||
+
|
||||
+ dart_restrict_pgsizes(cfg);
|
||||
+
|
||||
+ if (!(cfg->pgsize_bitmap & (SZ_4K | SZ_16K)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (cfg->ias > DART_MAX_ADDR_BITS)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (cfg->oas > DART_MAX_ADDR_BITS)
|
||||
+ return NULL;
|
||||
+
|
||||
+ pg_shift = __ffs(cfg->pgsize_bitmap);
|
||||
+ bits_per_level = pg_shift - ilog2(sizeof(dart_iopte));
|
||||
+
|
||||
+ va_bits = cfg->ias - pg_shift;
|
||||
+ levels = DIV_ROUND_UP(va_bits, bits_per_level);
|
||||
+ if (levels > DART_MAX_LEVELS)
|
||||
+ return NULL;
|
||||
+
|
||||
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return NULL;
|
||||
+
|
||||
+ data->bits_per_level = bits_per_level;
|
||||
+ data->start_level = DART_MAX_LEVELS - levels;
|
||||
+
|
||||
+ /* Calculate the actual size of our pgd (without concatenation) */
|
||||
+ data->pgd_bits = va_bits - (data->bits_per_level * (levels - 1));
|
||||
+
|
||||
+ data->iop.ops = (struct io_pgtable_ops) {
|
||||
+ .map = dart_map,
|
||||
+ .map_pages = dart_map_pages,
|
||||
+ .unmap = dart_unmap,
|
||||
+ .unmap_pages = dart_unmap_pages,
|
||||
+ .iova_to_phys = dart_iova_to_phys,
|
||||
+ };
|
||||
+
|
||||
+ return data;
|
||||
+}
|
||||
+
|
||||
+static struct io_pgtable *
|
||||
+apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
|
||||
+{
|
||||
+ struct dart_io_pgtable *data;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!cfg->coherent_walk)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (cfg->oas > 36)
|
||||
+ return NULL;
|
||||
+
|
||||
+ data = dart_alloc_pgtable(cfg);
|
||||
+ if (!data)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * The table format itself always uses two levels, but the total VA
|
||||
+ * space is mapped by four separate tables, making the MMIO registers
|
||||
+ * an effective "level 1". For simplicity, though, we treat this
|
||||
+ * equivalently to LPAE stage 2 concatenation at level 2, with the
|
||||
+ * additional TTBRs each just pointing at consecutive pages.
|
||||
+ */
|
||||
+ if (data->start_level == 0 && data->pgd_bits > 2)
|
||||
+ goto out_free_data;
|
||||
+ if (data->start_level > 0)
|
||||
+ data->pgd_bits = 0;
|
||||
+ data->start_level = 1;
|
||||
+ cfg->apple_dart_cfg.n_ttbrs = 1 << data->pgd_bits;
|
||||
+ data->pgd_bits += data->bits_per_level;
|
||||
+
|
||||
+ data->pgd = __dart_alloc_pages(DART_PGD_SIZE(data), GFP_KERNEL,
|
||||
+ cfg);
|
||||
+ if (!data->pgd)
|
||||
+ goto out_free_data;
|
||||
+
|
||||
+ for (i = 0; i < cfg->apple_dart_cfg.n_ttbrs; ++i)
|
||||
+ cfg->apple_dart_cfg.ttbr[i] =
|
||||
+ virt_to_phys(data->pgd + i * DART_GRANULE(data));
|
||||
+
|
||||
+ return &data->iop;
|
||||
+
|
||||
+out_free_data:
|
||||
+ kfree(data);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void apple_dart_free_pgtable(struct io_pgtable *iop)
|
||||
+{
|
||||
+ struct dart_io_pgtable *data = io_pgtable_to_data(iop);
|
||||
+
|
||||
+ __dart_free_pgtable(data, data->start_level, data->pgd);
|
||||
+ kfree(data);
|
||||
+}
|
||||
+
|
||||
+struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns = {
|
||||
+ .alloc = apple_dart_alloc_pgtable,
|
||||
+ .free = apple_dart_free_pgtable,
|
||||
+};
|
||||
diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
|
||||
index f4bfcef98297..16205ea9272c 100644
|
||||
--- a/drivers/iommu/io-pgtable.c
|
||||
+++ b/drivers/iommu/io-pgtable.c
|
||||
@@ -20,6 +20,8 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
|
||||
[ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
|
||||
[ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
|
||||
[ARM_MALI_LPAE] = &io_pgtable_arm_mali_lpae_init_fns,
|
||||
+#endif
|
||||
+#ifdef CONFIG_IOMMU_IO_PGTABLE_DART
|
||||
[APPLE_DART] = &io_pgtable_apple_dart_init_fns,
|
||||
#endif
|
||||
#ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,54 @@
|
||||
From cd16901670e12ae1185f2488e74f50ce5d72c5fb Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Wed, 17 Nov 2021 19:40:16 +0100
|
||||
Subject: [PATCH 048/171] iommu/io-pgtable: Add DART subpage protection support
|
||||
|
||||
DART allows to only expose a subpage to the device. While this is an
|
||||
optional feature on the M1 DARTs the new ones present on the Pro/Max
|
||||
models require this field in every PTE.
|
||||
|
||||
Signed-off-by: Sven Peter <sven@svenpeter.dev>
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
|
||||
Commit-changes: 3
|
||||
- apply change to io-pgtable-dart.c
|
||||
---
|
||||
drivers/iommu/io-pgtable-dart.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
|
||||
index 0c5222942c65..fa8025c03bb5 100644
|
||||
--- a/drivers/iommu/io-pgtable-dart.c
|
||||
+++ b/drivers/iommu/io-pgtable-dart.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#define pr_fmt(fmt) "dart io-pgtable: " fmt
|
||||
|
||||
#include <linux/atomic.h>
|
||||
+#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/io-pgtable.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -63,6 +64,9 @@
|
||||
/* Calculate the block/page mapping size at level l for pagetable in d. */
|
||||
#define DART_BLOCK_SIZE(l, d) (1ULL << DART_LVL_SHIFT(l, d))
|
||||
|
||||
+#define APPLE_DART_PTE_SUBPAGE_START GENMASK_ULL(63, 52)
|
||||
+#define APPLE_DART_PTE_SUBPAGE_END GENMASK_ULL(51, 40)
|
||||
+
|
||||
#define APPLE_DART1_PADDR_MASK GENMASK_ULL(35, 12)
|
||||
|
||||
/* Apple DART1 protection bits */
|
||||
@@ -140,6 +144,10 @@ static void __dart_init_pte(struct dart_io_pgtable *data,
|
||||
|
||||
pte |= APPLE_DART_PTE_VALID;
|
||||
|
||||
+ /* subpage protection: always allow access to the entire page */
|
||||
+ pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_START, 0);
|
||||
+ pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_END, 0xfff);
|
||||
+
|
||||
for (i = 0; i < num_entries; i++)
|
||||
ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,158 @@
|
||||
From 318506bc8e5c558c1df0a964ce2fe112681d3452 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Tue, 2 Nov 2021 18:10:53 +0100
|
||||
Subject: [PATCH 049/171] iommu/io-pgtable-dart: Add DART PTE support for t6000
|
||||
|
||||
The DARTs present in the M1 Pro/Max/Ultra SoC use a diffent PTE format.
|
||||
They support a 42bit physical address space by shifting the paddr and
|
||||
extending its mask inside the PTE.
|
||||
They also come with mandatory sub-page protection now which we just
|
||||
configure to always allow access to the entire page. This feature is
|
||||
already present but optional on the previous DARTs which allows to
|
||||
unconditionally configure it.
|
||||
|
||||
Signed-off-by: Sven Peter <sven@svenpeter.dev>
|
||||
Co-developed-by: Janne Grunau <j@jannau.net>
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
|
||||
Commit-changes: 2
|
||||
- add APPLE_DART2 PTE format
|
||||
|
||||
Commit-changes: 3
|
||||
- apply change to io-pgtable-dart.c
|
||||
- handle pte <> paddr conversion based on the pte format instead of
|
||||
the output address size
|
||||
---
|
||||
drivers/iommu/io-pgtable-dart.c | 51 +++++++++++++++++++++++++++------
|
||||
drivers/iommu/io-pgtable.c | 1 +
|
||||
include/linux/io-pgtable.h | 1 +
|
||||
3 files changed, 45 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
|
||||
index fa8025c03bb5..9c3c2505f3dc 100644
|
||||
--- a/drivers/iommu/io-pgtable-dart.c
|
||||
+++ b/drivers/iommu/io-pgtable-dart.c
|
||||
@@ -68,12 +68,19 @@
|
||||
#define APPLE_DART_PTE_SUBPAGE_END GENMASK_ULL(51, 40)
|
||||
|
||||
#define APPLE_DART1_PADDR_MASK GENMASK_ULL(35, 12)
|
||||
+#define APPLE_DART2_PADDR_MASK GENMASK_ULL(37, 10)
|
||||
+#define APPLE_DART2_PADDR_SHIFT (4)
|
||||
|
||||
/* Apple DART1 protection bits */
|
||||
#define APPLE_DART1_PTE_PROT_NO_READ BIT(8)
|
||||
#define APPLE_DART1_PTE_PROT_NO_WRITE BIT(7)
|
||||
#define APPLE_DART1_PTE_PROT_SP_DIS BIT(1)
|
||||
|
||||
+/* Apple DART2 protection bits */
|
||||
+#define APPLE_DART2_PTE_PROT_NO_READ BIT(3)
|
||||
+#define APPLE_DART2_PTE_PROT_NO_WRITE BIT(2)
|
||||
+#define APPLE_DART2_PTE_PROT_NO_CACHE BIT(1)
|
||||
+
|
||||
/* marks PTE as valid */
|
||||
#define APPLE_DART_PTE_VALID BIT(0)
|
||||
|
||||
@@ -101,13 +108,31 @@ static inline bool iopte_leaf(dart_iopte pte, int lvl,
|
||||
static dart_iopte paddr_to_iopte(phys_addr_t paddr,
|
||||
struct dart_io_pgtable *data)
|
||||
{
|
||||
- return paddr & APPLE_DART1_PADDR_MASK;
|
||||
+ dart_iopte pte;
|
||||
+
|
||||
+ if (data->iop.fmt == APPLE_DART)
|
||||
+ return paddr & APPLE_DART1_PADDR_MASK;
|
||||
+
|
||||
+ /* format is APPLE_DART2 */
|
||||
+ pte = paddr >> APPLE_DART2_PADDR_SHIFT;
|
||||
+ pte &= APPLE_DART2_PADDR_MASK;
|
||||
+
|
||||
+ return pte;
|
||||
}
|
||||
|
||||
static phys_addr_t iopte_to_paddr(dart_iopte pte,
|
||||
struct dart_io_pgtable *data)
|
||||
{
|
||||
- return pte & APPLE_DART1_PADDR_MASK;
|
||||
+ u64 paddr;
|
||||
+
|
||||
+ if (data->iop.fmt == APPLE_DART)
|
||||
+ return pte & APPLE_DART1_PADDR_MASK;
|
||||
+
|
||||
+ /* format is APPLE_DART2 */
|
||||
+ paddr = pte & APPLE_DART2_PADDR_MASK;
|
||||
+ paddr <<= APPLE_DART2_PADDR_SHIFT;
|
||||
+
|
||||
+ return paddr;
|
||||
}
|
||||
|
||||
static void *__dart_alloc_pages(size_t size, gfp_t gfp,
|
||||
@@ -139,7 +164,7 @@ static void __dart_init_pte(struct dart_io_pgtable *data,
|
||||
size_t sz = DART_BLOCK_SIZE(lvl, data);
|
||||
int i;
|
||||
|
||||
- if (lvl == DART_MAX_LEVELS - 1)
|
||||
+ if (lvl == DART_MAX_LEVELS - 1 && data->iop.fmt == APPLE_DART)
|
||||
pte |= APPLE_DART1_PTE_PROT_SP_DIS;
|
||||
|
||||
pte |= APPLE_DART_PTE_VALID;
|
||||
@@ -251,10 +276,20 @@ static dart_iopte dart_prot_to_pte(struct dart_io_pgtable *data,
|
||||
{
|
||||
dart_iopte pte = 0;
|
||||
|
||||
- if (!(prot & IOMMU_WRITE))
|
||||
- pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
|
||||
- if (!(prot & IOMMU_READ))
|
||||
- pte |= APPLE_DART1_PTE_PROT_NO_READ;
|
||||
+ if (data->iop.fmt == APPLE_DART) {
|
||||
+ if (!(prot & IOMMU_WRITE))
|
||||
+ pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
|
||||
+ if (!(prot & IOMMU_READ))
|
||||
+ pte |= APPLE_DART1_PTE_PROT_NO_READ;
|
||||
+ }
|
||||
+ if (data->iop.fmt == APPLE_DART2) {
|
||||
+ if (!(prot & IOMMU_WRITE))
|
||||
+ pte |= APPLE_DART2_PTE_PROT_NO_WRITE;
|
||||
+ if (!(prot & IOMMU_READ))
|
||||
+ pte |= APPLE_DART2_PTE_PROT_NO_READ;
|
||||
+ if (!(prot & IOMMU_CACHE))
|
||||
+ pte |= APPLE_DART2_PTE_PROT_NO_CACHE;
|
||||
+ }
|
||||
|
||||
return pte;
|
||||
}
|
||||
@@ -536,7 +571,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
|
||||
if (!cfg->coherent_walk)
|
||||
return NULL;
|
||||
|
||||
- if (cfg->oas > 36)
|
||||
+ if (cfg->oas != 36 && cfg->oas != 42)
|
||||
return NULL;
|
||||
|
||||
data = dart_alloc_pgtable(cfg);
|
||||
diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
|
||||
index 16205ea9272c..49f46e1eabf7 100644
|
||||
--- a/drivers/iommu/io-pgtable.c
|
||||
+++ b/drivers/iommu/io-pgtable.c
|
||||
@@ -23,6 +23,7 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
|
||||
#endif
|
||||
#ifdef CONFIG_IOMMU_IO_PGTABLE_DART
|
||||
[APPLE_DART] = &io_pgtable_apple_dart_init_fns,
|
||||
+ [APPLE_DART2] = &io_pgtable_apple_dart_init_fns,
|
||||
#endif
|
||||
#ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S
|
||||
[ARM_V7S] = &io_pgtable_arm_v7s_init_fns,
|
||||
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
|
||||
index 86af6f0a00a2..76b98511cbc8 100644
|
||||
--- a/include/linux/io-pgtable.h
|
||||
+++ b/include/linux/io-pgtable.h
|
||||
@@ -17,6 +17,7 @@ enum io_pgtable_fmt {
|
||||
ARM_MALI_LPAE,
|
||||
AMD_IOMMU_V1,
|
||||
APPLE_DART,
|
||||
+ APPLE_DART2,
|
||||
IO_PGTABLE_NUM_FMTS,
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,99 @@
|
||||
From 69d73a2d8f767b1e1d4ea00fcd8be33f5fc8b7c0 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Tue, 2 Nov 2021 18:10:52 +0100
|
||||
Subject: [PATCH 050/171] iommu: dart: Support t6000 variant
|
||||
|
||||
The M1 Pro/Max/Ultra SoCs come with a new variant of DART which
|
||||
supports a larger physical address space with a different PTE format.
|
||||
Pass through the correct paddr address space size and the PTE format
|
||||
to the io-pgtable code which will take care of the rest.
|
||||
|
||||
Signed-off-by: Sven Peter <sven@svenpeter.dev>
|
||||
Co-developed-by: Janne Grunau <j@jannau.net>
|
||||
Signed-off-by: Janne Grunau <j@jannau.net>
|
||||
|
||||
Commit-changes: 2
|
||||
- use APPLE_DART2 PTE format for dart-t6000
|
||||
|
||||
Commit-changes: 3
|
||||
- apply change to io-pgtable-dart.c
|
||||
---
|
||||
drivers/iommu/apple-dart.c | 24 +++++++++++++++++++++---
|
||||
1 file changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
|
||||
index 8af0242a90d9..e5793c0d08b4 100644
|
||||
--- a/drivers/iommu/apple-dart.c
|
||||
+++ b/drivers/iommu/apple-dart.c
|
||||
@@ -81,10 +81,16 @@
|
||||
#define DART_TTBR_VALID BIT(31)
|
||||
#define DART_TTBR_SHIFT 12
|
||||
|
||||
+struct apple_dart_hw {
|
||||
+ u32 oas;
|
||||
+ enum io_pgtable_fmt fmt;
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Private structure associated with each DART device.
|
||||
*
|
||||
* @dev: device struct
|
||||
+ * @hw: SoC-specific hardware data
|
||||
* @regs: mapped MMIO region
|
||||
* @irq: interrupt number, can be shared with other DARTs
|
||||
* @clks: clocks associated with this DART
|
||||
@@ -98,6 +104,7 @@
|
||||
*/
|
||||
struct apple_dart {
|
||||
struct device *dev;
|
||||
+ const struct apple_dart_hw *hw;
|
||||
|
||||
void __iomem *regs;
|
||||
|
||||
@@ -421,13 +428,13 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
|
||||
pgtbl_cfg = (struct io_pgtable_cfg){
|
||||
.pgsize_bitmap = dart->pgsize,
|
||||
.ias = 32,
|
||||
- .oas = 36,
|
||||
+ .oas = dart->hw->oas,
|
||||
.coherent_walk = 1,
|
||||
.iommu_dev = dart->dev,
|
||||
};
|
||||
|
||||
dart_domain->pgtbl_ops =
|
||||
- alloc_io_pgtable_ops(APPLE_DART, &pgtbl_cfg, domain);
|
||||
+ alloc_io_pgtable_ops(dart->hw->fmt, &pgtbl_cfg, domain);
|
||||
if (!dart_domain->pgtbl_ops) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
@@ -858,6 +865,7 @@ static int apple_dart_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
dart->dev = dev;
|
||||
+ dart->hw = of_device_get_match_data(dev);
|
||||
spin_lock_init(&dart->lock);
|
||||
|
||||
dart->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
@@ -946,8 +954,18 @@ static int apple_dart_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct apple_dart_hw apple_dart_hw_t8103 = {
|
||||
+ .oas = 36,
|
||||
+ .fmt = APPLE_DART,
|
||||
+};
|
||||
+static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||
+ .oas = 42,
|
||||
+ .fmt = APPLE_DART2,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id apple_dart_of_match[] = {
|
||||
- { .compatible = "apple,t8103-dart", .data = NULL },
|
||||
+ { .compatible = "apple,t8103-dart", .data = &apple_dart_hw_t8103 },
|
||||
+ { .compatible = "apple,t6000-dart", .data = &apple_dart_hw_t6000 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, apple_dart_of_match);
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,91 @@
|
||||
From 6b1080a482294824b6dfb65501de061a86a1939d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sat, 5 Mar 2022 21:17:10 +0900
|
||||
Subject: [PATCH 051/171] iommu: dart: Add suspend/resume support
|
||||
|
||||
We need to save/restore the TCR/TTBR registers, since they are lost
|
||||
on power gate.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/iommu/apple-dart.c | 50 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
|
||||
index e5793c0d08b4..90aceb6ac774 100644
|
||||
--- a/drivers/iommu/apple-dart.c
|
||||
+++ b/drivers/iommu/apple-dart.c
|
||||
@@ -120,6 +120,9 @@ struct apple_dart {
|
||||
|
||||
struct iommu_group *sid2group[DART_MAX_STREAMS];
|
||||
struct iommu_device iommu;
|
||||
+
|
||||
+ u32 save_tcr[DART_MAX_STREAMS];
|
||||
+ u32 save_ttbr[DART_MAX_STREAMS][DART_MAX_TTBR];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -963,6 +966,50 @@ static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||
.fmt = APPLE_DART2,
|
||||
};
|
||||
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+static int apple_dart_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct apple_dart *dart = dev_get_drvdata(dev);
|
||||
+ unsigned int sid, idx;
|
||||
+
|
||||
+ for (sid = 0; sid < DART_MAX_STREAMS; sid++) {
|
||||
+ dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(sid));
|
||||
+ for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
||||
+ dart->save_ttbr[sid][idx] =
|
||||
+ readl_relaxed(dart->regs + DART_TTBR(sid, idx));
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int apple_dart_resume(struct device *dev)
|
||||
+{
|
||||
+ struct apple_dart *dart = dev_get_drvdata(dev);
|
||||
+ unsigned int sid, idx;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = apple_dart_hw_reset(dart);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to reset DART on resume\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (sid = 0; sid < DART_MAX_STREAMS; sid++) {
|
||||
+ for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
||||
+ writel_relaxed(dart->save_ttbr[sid][idx],
|
||||
+ dart->regs + DART_TTBR(sid, idx));
|
||||
+ writel_relaxed(dart->save_tcr[sid], dart->regs + DART_TCR(sid));
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct dev_pm_ops apple_dart_pm_ops = {
|
||||
+ .suspend = apple_dart_suspend,
|
||||
+ .resume = apple_dart_resume,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
static const struct of_device_id apple_dart_of_match[] = {
|
||||
{ .compatible = "apple,t8103-dart", .data = &apple_dart_hw_t8103 },
|
||||
{ .compatible = "apple,t6000-dart", .data = &apple_dart_hw_t6000 },
|
||||
@@ -975,6 +1022,9 @@ static struct platform_driver apple_dart_driver = {
|
||||
.name = "apple-dart",
|
||||
.of_match_table = apple_dart_of_match,
|
||||
.suppress_bind_attrs = true,
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+ .pm = &apple_dart_pm_ops,
|
||||
+#endif
|
||||
},
|
||||
.probe = apple_dart_probe,
|
||||
.remove = apple_dart_remove,
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,359 @@
|
||||
From 82d7ff6fe9af1e8cd39bce1d46a679074b8d7749 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 28 Jun 2022 01:07:20 +0900
|
||||
Subject: [PATCH 052/171] iommu: dart: Support >64 stream IDs
|
||||
|
||||
T8110 DARTs have up to 256 SIDs, so we need to switch to a bitmap to
|
||||
handle them properly.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/iommu/apple-dart.c | 113 +++++++++++++++++++++++--------------
|
||||
1 file changed, 70 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
|
||||
index 90aceb6ac774..39e6f86dd525 100644
|
||||
--- a/drivers/iommu/apple-dart.c
|
||||
+++ b/drivers/iommu/apple-dart.c
|
||||
@@ -33,11 +33,10 @@
|
||||
#include <linux/swab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
-#define DART_MAX_STREAMS 16
|
||||
+#define DART_MAX_STREAMS 256
|
||||
#define DART_MAX_TTBR 4
|
||||
#define MAX_DARTS_PER_DEVICE 2
|
||||
|
||||
-#define DART_STREAM_ALL 0xffff
|
||||
|
||||
#define DART_PARAMS1 0x00
|
||||
#define DART_PARAMS_PAGE_SHIFT GENMASK(27, 24)
|
||||
@@ -84,6 +83,8 @@
|
||||
struct apple_dart_hw {
|
||||
u32 oas;
|
||||
enum io_pgtable_fmt fmt;
|
||||
+
|
||||
+ int max_sid_count;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -115,6 +116,7 @@ struct apple_dart {
|
||||
spinlock_t lock;
|
||||
|
||||
u32 pgsize;
|
||||
+ u32 num_streams;
|
||||
u32 supports_bypass : 1;
|
||||
u32 force_bypass : 1;
|
||||
|
||||
@@ -142,11 +144,11 @@ struct apple_dart {
|
||||
*/
|
||||
struct apple_dart_stream_map {
|
||||
struct apple_dart *dart;
|
||||
- unsigned long sidmap;
|
||||
+ DECLARE_BITMAP(sidmap, DART_MAX_STREAMS);
|
||||
};
|
||||
struct apple_dart_atomic_stream_map {
|
||||
struct apple_dart *dart;
|
||||
- atomic64_t sidmap;
|
||||
+ atomic_long_t sidmap[BITS_TO_LONGS(DART_MAX_STREAMS)];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -204,50 +206,55 @@ static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom)
|
||||
static void
|
||||
apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map)
|
||||
{
|
||||
+ struct apple_dart *dart = stream_map->dart;
|
||||
int sid;
|
||||
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
writel(DART_TCR_TRANSLATE_ENABLE,
|
||||
- stream_map->dart->regs + DART_TCR(sid));
|
||||
+ dart->regs + DART_TCR(sid));
|
||||
}
|
||||
|
||||
static void apple_dart_hw_disable_dma(struct apple_dart_stream_map *stream_map)
|
||||
{
|
||||
+ struct apple_dart *dart = stream_map->dart;
|
||||
int sid;
|
||||
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
|
||||
- writel(0, stream_map->dart->regs + DART_TCR(sid));
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
+ writel(0, dart->regs + DART_TCR(sid));
|
||||
}
|
||||
|
||||
static void
|
||||
apple_dart_hw_enable_bypass(struct apple_dart_stream_map *stream_map)
|
||||
{
|
||||
+ struct apple_dart *dart = stream_map->dart;
|
||||
int sid;
|
||||
|
||||
WARN_ON(!stream_map->dart->supports_bypass);
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
writel(DART_TCR_BYPASS0_ENABLE | DART_TCR_BYPASS1_ENABLE,
|
||||
- stream_map->dart->regs + DART_TCR(sid));
|
||||
+ dart->regs + DART_TCR(sid));
|
||||
}
|
||||
|
||||
static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map,
|
||||
u8 idx, phys_addr_t paddr)
|
||||
{
|
||||
+ struct apple_dart *dart = stream_map->dart;
|
||||
int sid;
|
||||
|
||||
WARN_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1));
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT),
|
||||
- stream_map->dart->regs + DART_TTBR(sid, idx));
|
||||
+ dart->regs + DART_TTBR(sid, idx));
|
||||
}
|
||||
|
||||
static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map,
|
||||
u8 idx)
|
||||
{
|
||||
+ struct apple_dart *dart = stream_map->dart;
|
||||
int sid;
|
||||
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
|
||||
- writel(0, stream_map->dart->regs + DART_TTBR(sid, idx));
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
+ writel(0, dart->regs + DART_TTBR(sid, idx));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -269,7 +276,7 @@ apple_dart_hw_stream_command(struct apple_dart_stream_map *stream_map,
|
||||
|
||||
spin_lock_irqsave(&stream_map->dart->lock, flags);
|
||||
|
||||
- writel(stream_map->sidmap, stream_map->dart->regs + DART_STREAM_SELECT);
|
||||
+ writel(stream_map->sidmap[0], stream_map->dart->regs + DART_STREAM_SELECT);
|
||||
writel(command, stream_map->dart->regs + DART_STREAM_COMMAND);
|
||||
|
||||
ret = readl_poll_timeout_atomic(
|
||||
@@ -282,7 +289,7 @@ apple_dart_hw_stream_command(struct apple_dart_stream_map *stream_map,
|
||||
if (ret) {
|
||||
dev_err(stream_map->dart->dev,
|
||||
"busy bit did not clear after command %x for streams %lx\n",
|
||||
- command, stream_map->sidmap);
|
||||
+ command, stream_map->sidmap[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -300,6 +307,7 @@ static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
{
|
||||
u32 config;
|
||||
struct apple_dart_stream_map stream_map;
|
||||
+ int i;
|
||||
|
||||
config = readl(dart->regs + DART_CONFIG);
|
||||
if (config & DART_CONFIG_LOCK) {
|
||||
@@ -309,12 +317,14 @@ static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
}
|
||||
|
||||
stream_map.dart = dart;
|
||||
- stream_map.sidmap = DART_STREAM_ALL;
|
||||
+ bitmap_zero(stream_map.sidmap, DART_MAX_STREAMS);
|
||||
+ bitmap_set(stream_map.sidmap, 0, dart->num_streams);
|
||||
apple_dart_hw_disable_dma(&stream_map);
|
||||
apple_dart_hw_clear_all_ttbrs(&stream_map);
|
||||
|
||||
/* enable all streams globally since TCR is used to control isolation */
|
||||
- writel(DART_STREAM_ALL, dart->regs + DART_STREAMS_ENABLE);
|
||||
+ for (i = 0; i < BITS_TO_U32(dart->num_streams); i++)
|
||||
+ writel(U32_MAX, dart->regs + DART_STREAMS_ENABLE);
|
||||
|
||||
/* clear any pending errors before the interrupt is unmasked */
|
||||
writel(readl(dart->regs + DART_ERROR), dart->regs + DART_ERROR);
|
||||
@@ -324,13 +334,16 @@ static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
|
||||
static void apple_dart_domain_flush_tlb(struct apple_dart_domain *domain)
|
||||
{
|
||||
- int i;
|
||||
+ int i, j;
|
||||
struct apple_dart_atomic_stream_map *domain_stream_map;
|
||||
struct apple_dart_stream_map stream_map;
|
||||
|
||||
for_each_stream_map(i, domain, domain_stream_map) {
|
||||
stream_map.dart = domain_stream_map->dart;
|
||||
- stream_map.sidmap = atomic64_read(&domain_stream_map->sidmap);
|
||||
+
|
||||
+ for (j = 0; j < BITS_TO_LONGS(stream_map.dart->num_streams); j++)
|
||||
+ stream_map.sidmap[j] = atomic64_read(&domain_stream_map->sidmap[j]);
|
||||
+
|
||||
apple_dart_hw_invalidate_tlb(&stream_map);
|
||||
}
|
||||
}
|
||||
@@ -415,7 +428,7 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
|
||||
struct apple_dart *dart = cfg->stream_maps[0].dart;
|
||||
struct io_pgtable_cfg pgtbl_cfg;
|
||||
int ret = 0;
|
||||
- int i;
|
||||
+ int i, j;
|
||||
|
||||
mutex_lock(&dart_domain->init_lock);
|
||||
|
||||
@@ -424,8 +437,9 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
|
||||
|
||||
for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
|
||||
dart_domain->stream_maps[i].dart = cfg->stream_maps[i].dart;
|
||||
- atomic64_set(&dart_domain->stream_maps[i].sidmap,
|
||||
- cfg->stream_maps[i].sidmap);
|
||||
+ for (j = 0; j < BITS_TO_LONGS(dart->num_streams); j++)
|
||||
+ atomic64_set(&dart_domain->stream_maps[i].sidmap[j],
|
||||
+ cfg->stream_maps[i].sidmap[j]);
|
||||
}
|
||||
|
||||
pgtbl_cfg = (struct io_pgtable_cfg){
|
||||
@@ -460,7 +474,7 @@ apple_dart_mod_streams(struct apple_dart_atomic_stream_map *domain_maps,
|
||||
struct apple_dart_stream_map *master_maps,
|
||||
bool add_streams)
|
||||
{
|
||||
- int i;
|
||||
+ int i, j;
|
||||
|
||||
for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
|
||||
if (domain_maps[i].dart != master_maps[i].dart)
|
||||
@@ -470,12 +484,14 @@ apple_dart_mod_streams(struct apple_dart_atomic_stream_map *domain_maps,
|
||||
for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
|
||||
if (!domain_maps[i].dart)
|
||||
break;
|
||||
- if (add_streams)
|
||||
- atomic64_or(master_maps[i].sidmap,
|
||||
- &domain_maps[i].sidmap);
|
||||
- else
|
||||
- atomic64_and(~master_maps[i].sidmap,
|
||||
- &domain_maps[i].sidmap);
|
||||
+ for (j = 0; j < BITS_TO_LONGS(domain_maps[i].dart->num_streams); j++) {
|
||||
+ if (add_streams)
|
||||
+ atomic64_or(master_maps[i].sidmap[j],
|
||||
+ &domain_maps[i].sidmap[j]);
|
||||
+ else
|
||||
+ atomic64_and(~master_maps[i].sidmap[j],
|
||||
+ &domain_maps[i].sidmap[j]);
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -642,14 +658,14 @@ static int apple_dart_of_xlate(struct device *dev, struct of_phandle_args *args)
|
||||
|
||||
for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
|
||||
if (cfg->stream_maps[i].dart == dart) {
|
||||
- cfg->stream_maps[i].sidmap |= 1 << sid;
|
||||
+ set_bit(sid, cfg->stream_maps[i].sidmap);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
|
||||
if (!cfg->stream_maps[i].dart) {
|
||||
cfg->stream_maps[i].dart = dart;
|
||||
- cfg->stream_maps[i].sidmap = 1 << sid;
|
||||
+ set_bit(sid, cfg->stream_maps[i].sidmap);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -668,7 +684,7 @@ static void apple_dart_release_group(void *iommu_data)
|
||||
mutex_lock(&apple_dart_groups_lock);
|
||||
|
||||
for_each_stream_map(i, group_master_cfg, stream_map)
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, stream_map->dart->num_streams)
|
||||
stream_map->dart->sid2group[sid] = NULL;
|
||||
|
||||
kfree(iommu_data);
|
||||
@@ -687,7 +703,7 @@ static struct iommu_group *apple_dart_device_group(struct device *dev)
|
||||
mutex_lock(&apple_dart_groups_lock);
|
||||
|
||||
for_each_stream_map(i, cfg, stream_map) {
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) {
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, stream_map->dart->num_streams) {
|
||||
struct iommu_group *stream_group =
|
||||
stream_map->dart->sid2group[sid];
|
||||
|
||||
@@ -726,7 +742,7 @@ static struct iommu_group *apple_dart_device_group(struct device *dev)
|
||||
apple_dart_release_group);
|
||||
|
||||
for_each_stream_map(i, cfg, stream_map)
|
||||
- for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, stream_map->dart->num_streams)
|
||||
stream_map->dart->sid2group[sid] = group;
|
||||
|
||||
res = group;
|
||||
@@ -893,16 +909,25 @@ static int apple_dart_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = apple_dart_hw_reset(dart);
|
||||
- if (ret)
|
||||
- goto err_clk_disable;
|
||||
-
|
||||
dart_params[0] = readl(dart->regs + DART_PARAMS1);
|
||||
dart_params[1] = readl(dart->regs + DART_PARAMS2);
|
||||
dart->pgsize = 1 << FIELD_GET(DART_PARAMS_PAGE_SHIFT, dart_params[0]);
|
||||
dart->supports_bypass = dart_params[1] & DART_PARAMS_BYPASS_SUPPORT;
|
||||
+
|
||||
+ dart->num_streams = dart->hw->max_sid_count;
|
||||
+
|
||||
+ if (dart->num_streams > DART_MAX_STREAMS) {
|
||||
+ dev_err(&pdev->dev, "Too many streams (%d > %d)\n",
|
||||
+ dart->num_streams, DART_MAX_STREAMS);
|
||||
+ goto err_clk_disable;
|
||||
+ }
|
||||
+
|
||||
dart->force_bypass = dart->pgsize > PAGE_SIZE;
|
||||
|
||||
+ ret = apple_dart_hw_reset(dart);
|
||||
+ if (ret)
|
||||
+ goto err_clk_disable;
|
||||
+
|
||||
ret = request_irq(dart->irq, apple_dart_irq, IRQF_SHARED,
|
||||
"apple-dart fault handler", dart);
|
||||
if (ret)
|
||||
@@ -925,8 +950,8 @@ static int apple_dart_probe(struct platform_device *pdev)
|
||||
|
||||
dev_info(
|
||||
&pdev->dev,
|
||||
- "DART [pagesize %x, bypass support: %d, bypass forced: %d] initialized\n",
|
||||
- dart->pgsize, dart->supports_bypass, dart->force_bypass);
|
||||
+ "DART [pagesize %x, %d streams, bypass support: %d, bypass forced: %d] initialized\n",
|
||||
+ dart->pgsize, dart->num_streams, dart->supports_bypass, dart->force_bypass);
|
||||
return 0;
|
||||
|
||||
err_sysfs_remove:
|
||||
@@ -960,10 +985,12 @@ static int apple_dart_remove(struct platform_device *pdev)
|
||||
static const struct apple_dart_hw apple_dart_hw_t8103 = {
|
||||
.oas = 36,
|
||||
.fmt = APPLE_DART,
|
||||
+ .max_sid_count = 16,
|
||||
};
|
||||
static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||
.oas = 42,
|
||||
.fmt = APPLE_DART2,
|
||||
+ .max_sid_count = 16,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -972,7 +999,7 @@ static int apple_dart_suspend(struct device *dev)
|
||||
struct apple_dart *dart = dev_get_drvdata(dev);
|
||||
unsigned int sid, idx;
|
||||
|
||||
- for (sid = 0; sid < DART_MAX_STREAMS; sid++) {
|
||||
+ for (sid = 0; sid < dart->num_streams; sid++) {
|
||||
dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(sid));
|
||||
for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
||||
dart->save_ttbr[sid][idx] =
|
||||
@@ -994,7 +1021,7 @@ static int apple_dart_resume(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- for (sid = 0; sid < DART_MAX_STREAMS; sid++) {
|
||||
+ for (sid = 0; sid < dart->num_streams; sid++) {
|
||||
for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
||||
writel_relaxed(dart->save_ttbr[sid][idx],
|
||||
dart->regs + DART_TTBR(sid, idx));
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,119 @@
|
||||
From 180390038e38222406314cb6eea2182a7817b459 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 28 Jun 2022 01:16:28 +0900
|
||||
Subject: [PATCH 053/171] iommu: dart: Support a variable number of TTBRs per
|
||||
stream
|
||||
|
||||
T8110 only has one TTBR per stream, so un-hardcode that.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/iommu/apple-dart.c | 28 +++++++++++++++++++---------
|
||||
1 file changed, 19 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
|
||||
index 39e6f86dd525..9f2751c12070 100644
|
||||
--- a/drivers/iommu/apple-dart.c
|
||||
+++ b/drivers/iommu/apple-dart.c
|
||||
@@ -76,15 +76,21 @@
|
||||
#define DART_TCR_BYPASS0_ENABLE BIT(8)
|
||||
#define DART_TCR_BYPASS1_ENABLE BIT(12)
|
||||
|
||||
-#define DART_TTBR(sid, idx) (0x200 + 16 * (sid) + 4 * (idx))
|
||||
#define DART_TTBR_VALID BIT(31)
|
||||
#define DART_TTBR_SHIFT 12
|
||||
|
||||
+#define DART_TTBR(dart, sid, idx) (0x200 + \
|
||||
+ (((dart)->hw->ttbr_count * (sid)) << 2) + \
|
||||
+ ((idx) << 2))
|
||||
+
|
||||
+
|
||||
struct apple_dart_hw {
|
||||
u32 oas;
|
||||
enum io_pgtable_fmt fmt;
|
||||
|
||||
int max_sid_count;
|
||||
+
|
||||
+ int ttbr_count;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -244,7 +250,7 @@ static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map,
|
||||
WARN_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1));
|
||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT),
|
||||
- dart->regs + DART_TTBR(sid, idx));
|
||||
+ dart->regs + DART_TTBR(dart, sid, idx));
|
||||
}
|
||||
|
||||
static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map,
|
||||
@@ -254,7 +260,7 @@ static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map,
|
||||
int sid;
|
||||
|
||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
- writel(0, dart->regs + DART_TTBR(sid, idx));
|
||||
+ writel(0, dart->regs + DART_TTBR(dart, sid, idx));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -262,7 +268,7 @@ apple_dart_hw_clear_all_ttbrs(struct apple_dart_stream_map *stream_map)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < DART_MAX_TTBR; ++i)
|
||||
+ for (i = 0; i < stream_map->dart->hw->ttbr_count; ++i)
|
||||
apple_dart_hw_clear_ttbr(stream_map, i);
|
||||
}
|
||||
|
||||
@@ -414,7 +420,7 @@ apple_dart_setup_translation(struct apple_dart_domain *domain,
|
||||
for (i = 0; i < pgtbl_cfg->apple_dart_cfg.n_ttbrs; ++i)
|
||||
apple_dart_hw_set_ttbr(stream_map, i,
|
||||
pgtbl_cfg->apple_dart_cfg.ttbr[i]);
|
||||
- for (; i < DART_MAX_TTBR; ++i)
|
||||
+ for (; i < stream_map->dart->hw->ttbr_count; ++i)
|
||||
apple_dart_hw_clear_ttbr(stream_map, i);
|
||||
|
||||
apple_dart_hw_enable_translation(stream_map);
|
||||
@@ -986,11 +992,15 @@ static const struct apple_dart_hw apple_dart_hw_t8103 = {
|
||||
.oas = 36,
|
||||
.fmt = APPLE_DART,
|
||||
.max_sid_count = 16,
|
||||
+
|
||||
+ .ttbr_count = 4,
|
||||
};
|
||||
static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||
.oas = 42,
|
||||
.fmt = APPLE_DART2,
|
||||
.max_sid_count = 16,
|
||||
+
|
||||
+ .ttbr_count = 4,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -1001,9 +1011,9 @@ static int apple_dart_suspend(struct device *dev)
|
||||
|
||||
for (sid = 0; sid < dart->num_streams; sid++) {
|
||||
dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(sid));
|
||||
- for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
||||
+ for (idx = 0; idx < dart->hw->ttbr_count; idx++)
|
||||
dart->save_ttbr[sid][idx] =
|
||||
- readl_relaxed(dart->regs + DART_TTBR(sid, idx));
|
||||
+ readl_relaxed(dart->regs + DART_TTBR(dart, sid, idx));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1022,9 +1032,9 @@ static int apple_dart_resume(struct device *dev)
|
||||
}
|
||||
|
||||
for (sid = 0; sid < dart->num_streams; sid++) {
|
||||
- for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
||||
+ for (idx = 0; idx < dart->hw->ttbr_count; idx++)
|
||||
writel_relaxed(dart->save_ttbr[sid][idx],
|
||||
- dart->regs + DART_TTBR(sid, idx));
|
||||
+ dart->regs + DART_TTBR(dart, sid, idx));
|
||||
writel_relaxed(dart->save_tcr[sid], dart->regs + DART_TCR(sid));
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 85ab83f3cc7a4f0bfff8edd1662c2d98cda766a1 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 28 Jun 2022 01:20:52 +0900
|
||||
Subject: [PATCH 054/171] iommu: dart: Fix DART_PARAMS1/2 bit define names
|
||||
|
||||
They didn't have the PARAMS reg index in them, but they should.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/iommu/apple-dart.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
|
||||
index 9f2751c12070..e6b641037429 100644
|
||||
--- a/drivers/iommu/apple-dart.c
|
||||
+++ b/drivers/iommu/apple-dart.c
|
||||
@@ -39,10 +39,10 @@
|
||||
|
||||
|
||||
#define DART_PARAMS1 0x00
|
||||
-#define DART_PARAMS_PAGE_SHIFT GENMASK(27, 24)
|
||||
+#define DART_PARAMS1_PAGE_SHIFT GENMASK(27, 24)
|
||||
|
||||
#define DART_PARAMS2 0x04
|
||||
-#define DART_PARAMS_BYPASS_SUPPORT BIT(0)
|
||||
+#define DART_PARAMS2_BYPASS_SUPPORT BIT(0)
|
||||
|
||||
#define DART_STREAM_COMMAND 0x20
|
||||
#define DART_STREAM_COMMAND_BUSY BIT(2)
|
||||
@@ -917,8 +917,8 @@ static int apple_dart_probe(struct platform_device *pdev)
|
||||
|
||||
dart_params[0] = readl(dart->regs + DART_PARAMS1);
|
||||
dart_params[1] = readl(dart->regs + DART_PARAMS2);
|
||||
- dart->pgsize = 1 << FIELD_GET(DART_PARAMS_PAGE_SHIFT, dart_params[0]);
|
||||
- dart->supports_bypass = dart_params[1] & DART_PARAMS_BYPASS_SUPPORT;
|
||||
+ dart->pgsize = 1 << FIELD_GET(DART_PARAMS1_PAGE_SHIFT, dart_params[0]);
|
||||
+ dart->supports_bypass = dart_params[1] & DART_PARAMS2_BYPASS_SUPPORT;
|
||||
|
||||
dart->num_streams = dart->hw->max_sid_count;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,394 @@
|
||||
From fbe7133a9b1e71ee18185dd7c67712c909515bfd Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 28 Jun 2022 01:27:28 +0900
|
||||
Subject: [PATCH 055/171] iommu: dart: Support different variants with
|
||||
different registers
|
||||
|
||||
T8110 has a new register layout. To accomodate this, first move all the
|
||||
register offsets to the hw structure, and rename all the existing
|
||||
registers to DART_T8020_*.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/iommu/apple-dart.c | 188 ++++++++++++++++++++++++-------------
|
||||
1 file changed, 125 insertions(+), 63 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
|
||||
index e6b641037429..3f89db3f8e99 100644
|
||||
--- a/drivers/iommu/apple-dart.c
|
||||
+++ b/drivers/iommu/apple-dart.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#define DART_MAX_TTBR 4
|
||||
#define MAX_DARTS_PER_DEVICE 2
|
||||
|
||||
+/* Common registers */
|
||||
|
||||
#define DART_PARAMS1 0x00
|
||||
#define DART_PARAMS1_PAGE_SHIFT GENMASK(27, 24)
|
||||
@@ -44,52 +45,79 @@
|
||||
#define DART_PARAMS2 0x04
|
||||
#define DART_PARAMS2_BYPASS_SUPPORT BIT(0)
|
||||
|
||||
-#define DART_STREAM_COMMAND 0x20
|
||||
-#define DART_STREAM_COMMAND_BUSY BIT(2)
|
||||
-#define DART_STREAM_COMMAND_INVALIDATE BIT(20)
|
||||
+/* T8020/T6000 registers */
|
||||
|
||||
-#define DART_STREAM_SELECT 0x34
|
||||
+#define DART_T8020_STREAM_COMMAND 0x20
|
||||
+#define DART_T8020_STREAM_COMMAND_BUSY BIT(2)
|
||||
+#define DART_T8020_STREAM_COMMAND_INVALIDATE BIT(20)
|
||||
|
||||
-#define DART_ERROR 0x40
|
||||
-#define DART_ERROR_STREAM GENMASK(27, 24)
|
||||
-#define DART_ERROR_CODE GENMASK(11, 0)
|
||||
-#define DART_ERROR_FLAG BIT(31)
|
||||
+#define DART_T8020_STREAM_SELECT 0x34
|
||||
|
||||
-#define DART_ERROR_READ_FAULT BIT(4)
|
||||
-#define DART_ERROR_WRITE_FAULT BIT(3)
|
||||
-#define DART_ERROR_NO_PTE BIT(2)
|
||||
-#define DART_ERROR_NO_PMD BIT(1)
|
||||
-#define DART_ERROR_NO_TTBR BIT(0)
|
||||
+#define DART_T8020_ERROR 0x40
|
||||
+#define DART_T8020_ERROR_STREAM GENMASK(27, 24)
|
||||
+#define DART_T8020_ERROR_CODE GENMASK(11, 0)
|
||||
+#define DART_T8020_ERROR_FLAG BIT(31)
|
||||
|
||||
-#define DART_CONFIG 0x60
|
||||
-#define DART_CONFIG_LOCK BIT(15)
|
||||
+#define DART_T8020_ERROR_READ_FAULT BIT(4)
|
||||
+#define DART_T8020_ERROR_WRITE_FAULT BIT(3)
|
||||
+#define DART_T8020_ERROR_NO_PTE BIT(2)
|
||||
+#define DART_T8020_ERROR_NO_PMD BIT(1)
|
||||
+#define DART_T8020_ERROR_NO_TTBR BIT(0)
|
||||
+
|
||||
+#define DART_T8020_CONFIG 0x60
|
||||
+#define DART_T8020_CONFIG_LOCK BIT(15)
|
||||
|
||||
#define DART_STREAM_COMMAND_BUSY_TIMEOUT 100
|
||||
|
||||
-#define DART_ERROR_ADDR_HI 0x54
|
||||
-#define DART_ERROR_ADDR_LO 0x50
|
||||
+#define DART_T8020_ERROR_ADDR_HI 0x54
|
||||
+#define DART_T8020_ERROR_ADDR_LO 0x50
|
||||
+
|
||||
+#define DART_T8020_STREAMS_ENABLE 0xfc
|
||||
|
||||
-#define DART_STREAMS_ENABLE 0xfc
|
||||
+#define DART_T8020_TCR 0x100
|
||||
+#define DART_T8020_TCR_TRANSLATE_ENABLE BIT(7)
|
||||
+#define DART_T8020_TCR_BYPASS_DART BIT(8)
|
||||
+#define DART_T8020_TCR_BYPASS_DAPF BIT(12)
|
||||
|
||||
-#define DART_TCR(sid) (0x100 + 4 * (sid))
|
||||
-#define DART_TCR_TRANSLATE_ENABLE BIT(7)
|
||||
-#define DART_TCR_BYPASS0_ENABLE BIT(8)
|
||||
-#define DART_TCR_BYPASS1_ENABLE BIT(12)
|
||||
+#define DART_T8020_TTBR 0x200
|
||||
+#define DART_T8020_TTBR_VALID BIT(31)
|
||||
+#define DART_T8020_TTBR_ADDR_OFF 0
|
||||
+#define DART_T8020_TTBR_SHIFT 12
|
||||
|
||||
-#define DART_TTBR_VALID BIT(31)
|
||||
-#define DART_TTBR_SHIFT 12
|
||||
+#define DART_TCR(dart, sid) ((dart)->hw->tcr + ((sid) << 2))
|
||||
|
||||
-#define DART_TTBR(dart, sid, idx) (0x200 + \
|
||||
+#define DART_TTBR(dart, sid, idx) ((dart)->hw->ttbr + \
|
||||
(((dart)->hw->ttbr_count * (sid)) << 2) + \
|
||||
((idx) << 2))
|
||||
|
||||
+struct apple_dart_stream_map;
|
||||
|
||||
struct apple_dart_hw {
|
||||
+ irqreturn_t (*irq_handler)(int irq, void *dev);
|
||||
+ int (*invalidate_tlb)(struct apple_dart_stream_map *stream_map);
|
||||
+
|
||||
u32 oas;
|
||||
enum io_pgtable_fmt fmt;
|
||||
|
||||
int max_sid_count;
|
||||
|
||||
+ u64 lock;
|
||||
+ u64 lock_bit;
|
||||
+
|
||||
+ u64 error;
|
||||
+
|
||||
+ u64 enable_streams;
|
||||
+ u64 disable_streams;
|
||||
+
|
||||
+ u64 tcr;
|
||||
+ u64 tcr_enabled;
|
||||
+ u64 tcr_disabled;
|
||||
+ u64 tcr_bypass;
|
||||
+
|
||||
+ u64 ttbr;
|
||||
+ u64 ttbr_valid;
|
||||
+ u64 ttbr_addr_off;
|
||||
+ u64 ttbr_shift;
|
||||
int ttbr_count;
|
||||
};
|
||||
|
||||
@@ -216,8 +244,7 @@ apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map)
|
||||
int sid;
|
||||
|
||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
- writel(DART_TCR_TRANSLATE_ENABLE,
|
||||
- dart->regs + DART_TCR(sid));
|
||||
+ writel(dart->hw->tcr_enabled, dart->regs + DART_TCR(dart, sid));
|
||||
}
|
||||
|
||||
static void apple_dart_hw_disable_dma(struct apple_dart_stream_map *stream_map)
|
||||
@@ -226,7 +253,7 @@ static void apple_dart_hw_disable_dma(struct apple_dart_stream_map *stream_map)
|
||||
int sid;
|
||||
|
||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
- writel(0, dart->regs + DART_TCR(sid));
|
||||
+ writel(dart->hw->tcr_disabled, dart->regs + DART_TCR(dart, sid));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -237,8 +264,8 @@ apple_dart_hw_enable_bypass(struct apple_dart_stream_map *stream_map)
|
||||
|
||||
WARN_ON(!stream_map->dart->supports_bypass);
|
||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
- writel(DART_TCR_BYPASS0_ENABLE | DART_TCR_BYPASS1_ENABLE,
|
||||
- dart->regs + DART_TCR(sid));
|
||||
+ writel(dart->hw->tcr_bypass,
|
||||
+ dart->regs + DART_TCR(dart, sid));
|
||||
}
|
||||
|
||||
static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map,
|
||||
@@ -247,9 +274,10 @@ static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map,
|
||||
struct apple_dart *dart = stream_map->dart;
|
||||
int sid;
|
||||
|
||||
- WARN_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1));
|
||||
+ WARN_ON(paddr & ((1 << dart->hw->ttbr_shift) - 1));
|
||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||
- writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT),
|
||||
+ writel(dart->hw->ttbr_valid |
|
||||
+ (paddr >> dart->hw->ttbr_shift) << dart->hw->ttbr_addr_off,
|
||||
dart->regs + DART_TTBR(dart, sid, idx));
|
||||
}
|
||||
|
||||
@@ -273,7 +301,7 @@ apple_dart_hw_clear_all_ttbrs(struct apple_dart_stream_map *stream_map)
|
||||
}
|
||||
|
||||
static int
|
||||
-apple_dart_hw_stream_command(struct apple_dart_stream_map *stream_map,
|
||||
+apple_dart_t8020_hw_stream_command(struct apple_dart_stream_map *stream_map,
|
||||
u32 command)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -282,12 +310,12 @@ apple_dart_hw_stream_command(struct apple_dart_stream_map *stream_map,
|
||||
|
||||
spin_lock_irqsave(&stream_map->dart->lock, flags);
|
||||
|
||||
- writel(stream_map->sidmap[0], stream_map->dart->regs + DART_STREAM_SELECT);
|
||||
- writel(command, stream_map->dart->regs + DART_STREAM_COMMAND);
|
||||
+ writel(stream_map->sidmap[0], stream_map->dart->regs + DART_T8020_STREAM_SELECT);
|
||||
+ writel(command, stream_map->dart->regs + DART_T8020_STREAM_COMMAND);
|
||||
|
||||
ret = readl_poll_timeout_atomic(
|
||||
- stream_map->dart->regs + DART_STREAM_COMMAND, command_reg,
|
||||
- !(command_reg & DART_STREAM_COMMAND_BUSY), 1,
|
||||
+ stream_map->dart->regs + DART_T8020_STREAM_COMMAND, command_reg,
|
||||
+ !(command_reg & DART_T8020_STREAM_COMMAND_BUSY), 1,
|
||||
DART_STREAM_COMMAND_BUSY_TIMEOUT);
|
||||
|
||||
spin_unlock_irqrestore(&stream_map->dart->lock, flags);
|
||||
@@ -303,10 +331,10 @@ apple_dart_hw_stream_command(struct apple_dart_stream_map *stream_map,
|
||||
}
|
||||
|
||||
static int
|
||||
-apple_dart_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
|
||||
+apple_dart_t8020_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
|
||||
{
|
||||
- return apple_dart_hw_stream_command(stream_map,
|
||||
- DART_STREAM_COMMAND_INVALIDATE);
|
||||
+ return apple_dart_t8020_hw_stream_command(
|
||||
+ stream_map, DART_T8020_STREAM_COMMAND_INVALIDATE);
|
||||
}
|
||||
|
||||
static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
@@ -315,8 +343,8 @@ static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
struct apple_dart_stream_map stream_map;
|
||||
int i;
|
||||
|
||||
- config = readl(dart->regs + DART_CONFIG);
|
||||
- if (config & DART_CONFIG_LOCK) {
|
||||
+ config = readl(dart->regs + dart->hw->lock);
|
||||
+ if (config & dart->hw->lock_bit) {
|
||||
dev_err(dart->dev, "DART is locked down until reboot: %08x\n",
|
||||
config);
|
||||
return -EINVAL;
|
||||
@@ -330,12 +358,12 @@ static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
|
||||
/* enable all streams globally since TCR is used to control isolation */
|
||||
for (i = 0; i < BITS_TO_U32(dart->num_streams); i++)
|
||||
- writel(U32_MAX, dart->regs + DART_STREAMS_ENABLE);
|
||||
+ writel(U32_MAX, dart->regs + dart->hw->enable_streams);
|
||||
|
||||
/* clear any pending errors before the interrupt is unmasked */
|
||||
- writel(readl(dart->regs + DART_ERROR), dart->regs + DART_ERROR);
|
||||
+ writel(readl(dart->regs + dart->hw->error), dart->regs + dart->hw->error);
|
||||
|
||||
- return apple_dart_hw_invalidate_tlb(&stream_map);
|
||||
+ return dart->hw->invalidate_tlb(&stream_map);
|
||||
}
|
||||
|
||||
static void apple_dart_domain_flush_tlb(struct apple_dart_domain *domain)
|
||||
@@ -350,7 +378,7 @@ static void apple_dart_domain_flush_tlb(struct apple_dart_domain *domain)
|
||||
for (j = 0; j < BITS_TO_LONGS(stream_map.dart->num_streams); j++)
|
||||
stream_map.sidmap[j] = atomic64_read(&domain_stream_map->sidmap[j]);
|
||||
|
||||
- apple_dart_hw_invalidate_tlb(&stream_map);
|
||||
+ stream_map.dart->hw->invalidate_tlb(&stream_map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +452,7 @@ apple_dart_setup_translation(struct apple_dart_domain *domain,
|
||||
apple_dart_hw_clear_ttbr(stream_map, i);
|
||||
|
||||
apple_dart_hw_enable_translation(stream_map);
|
||||
- apple_dart_hw_invalidate_tlb(stream_map);
|
||||
+ stream_map->dart->hw->invalidate_tlb(stream_map);
|
||||
}
|
||||
|
||||
static int apple_dart_finalize_domain(struct iommu_domain *domain,
|
||||
@@ -819,30 +847,30 @@ static const struct iommu_ops apple_dart_iommu_ops = {
|
||||
}
|
||||
};
|
||||
|
||||
-static irqreturn_t apple_dart_irq(int irq, void *dev)
|
||||
+static irqreturn_t apple_dart_t8020_irq(int irq, void *dev)
|
||||
{
|
||||
struct apple_dart *dart = dev;
|
||||
const char *fault_name = NULL;
|
||||
- u32 error = readl(dart->regs + DART_ERROR);
|
||||
- u32 error_code = FIELD_GET(DART_ERROR_CODE, error);
|
||||
- u32 addr_lo = readl(dart->regs + DART_ERROR_ADDR_LO);
|
||||
- u32 addr_hi = readl(dart->regs + DART_ERROR_ADDR_HI);
|
||||
+ u32 error = readl(dart->regs + DART_T8020_ERROR);
|
||||
+ u32 error_code = FIELD_GET(DART_T8020_ERROR_CODE, error);
|
||||
+ u32 addr_lo = readl(dart->regs + DART_T8020_ERROR_ADDR_LO);
|
||||
+ u32 addr_hi = readl(dart->regs + DART_T8020_ERROR_ADDR_HI);
|
||||
u64 addr = addr_lo | (((u64)addr_hi) << 32);
|
||||
- u8 stream_idx = FIELD_GET(DART_ERROR_STREAM, error);
|
||||
+ u8 stream_idx = FIELD_GET(DART_T8020_ERROR_STREAM, error);
|
||||
|
||||
- if (!(error & DART_ERROR_FLAG))
|
||||
+ if (!(error & DART_T8020_ERROR_FLAG))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* there should only be a single bit set but let's use == to be sure */
|
||||
- if (error_code == DART_ERROR_READ_FAULT)
|
||||
+ if (error_code == DART_T8020_ERROR_READ_FAULT)
|
||||
fault_name = "READ FAULT";
|
||||
- else if (error_code == DART_ERROR_WRITE_FAULT)
|
||||
+ else if (error_code == DART_T8020_ERROR_WRITE_FAULT)
|
||||
fault_name = "WRITE FAULT";
|
||||
- else if (error_code == DART_ERROR_NO_PTE)
|
||||
+ else if (error_code == DART_T8020_ERROR_NO_PTE)
|
||||
fault_name = "NO PTE FOR IOVA";
|
||||
- else if (error_code == DART_ERROR_NO_PMD)
|
||||
+ else if (error_code == DART_T8020_ERROR_NO_PMD)
|
||||
fault_name = "NO PMD FOR IOVA";
|
||||
- else if (error_code == DART_ERROR_NO_TTBR)
|
||||
+ else if (error_code == DART_T8020_ERROR_NO_TTBR)
|
||||
fault_name = "NO TTBR FOR IOVA";
|
||||
else
|
||||
fault_name = "unknown";
|
||||
@@ -852,7 +880,7 @@ static irqreturn_t apple_dart_irq(int irq, void *dev)
|
||||
"translation fault: status:0x%x stream:%d code:0x%x (%s) at 0x%llx",
|
||||
error, stream_idx, error_code, fault_name, addr);
|
||||
|
||||
- writel(error, dart->regs + DART_ERROR);
|
||||
+ writel(error, dart->regs + DART_T8020_ERROR);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -934,7 +962,7 @@ static int apple_dart_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_clk_disable;
|
||||
|
||||
- ret = request_irq(dart->irq, apple_dart_irq, IRQF_SHARED,
|
||||
+ ret = request_irq(dart->irq, dart->hw->irq_handler, IRQF_SHARED,
|
||||
"apple-dart fault handler", dart);
|
||||
if (ret)
|
||||
goto err_clk_disable;
|
||||
@@ -989,17 +1017,51 @@ static int apple_dart_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct apple_dart_hw apple_dart_hw_t8103 = {
|
||||
+ .irq_handler = apple_dart_t8020_irq,
|
||||
+ .invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb,
|
||||
.oas = 36,
|
||||
.fmt = APPLE_DART,
|
||||
.max_sid_count = 16,
|
||||
|
||||
+ .enable_streams = DART_T8020_STREAMS_ENABLE,
|
||||
+ .lock = DART_T8020_CONFIG,
|
||||
+ .lock_bit = DART_T8020_CONFIG_LOCK,
|
||||
+
|
||||
+ .error = DART_T8020_ERROR,
|
||||
+
|
||||
+ .tcr = DART_T8020_TCR,
|
||||
+ .tcr_enabled = DART_T8020_TCR_TRANSLATE_ENABLE,
|
||||
+ .tcr_disabled = 0,
|
||||
+ .tcr_bypass = DART_T8020_TCR_BYPASS_DAPF | DART_T8020_TCR_BYPASS_DART,
|
||||
+
|
||||
+ .ttbr = DART_T8020_TTBR,
|
||||
+ .ttbr_valid = DART_T8020_TTBR_VALID,
|
||||
+ .ttbr_addr_off = DART_T8020_TTBR_ADDR_OFF,
|
||||
+ .ttbr_shift = DART_T8020_TTBR_SHIFT,
|
||||
.ttbr_count = 4,
|
||||
};
|
||||
static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||
+ .irq_handler = apple_dart_t8020_irq,
|
||||
+ .invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb,
|
||||
.oas = 42,
|
||||
.fmt = APPLE_DART2,
|
||||
.max_sid_count = 16,
|
||||
|
||||
+ .enable_streams = DART_T8020_STREAMS_ENABLE,
|
||||
+ .lock = DART_T8020_CONFIG,
|
||||
+ .lock_bit = DART_T8020_CONFIG_LOCK,
|
||||
+
|
||||
+ .error = DART_T8020_ERROR,
|
||||
+
|
||||
+ .tcr = DART_T8020_TCR,
|
||||
+ .tcr_enabled = DART_T8020_TCR_TRANSLATE_ENABLE,
|
||||
+ .tcr_disabled = 0,
|
||||
+ .tcr_bypass = DART_T8020_TCR_BYPASS_DAPF | DART_T8020_TCR_BYPASS_DART,
|
||||
+
|
||||
+ .ttbr = DART_T8020_TTBR,
|
||||
+ .ttbr_valid = DART_T8020_TTBR_VALID,
|
||||
+ .ttbr_addr_off = DART_T8020_TTBR_ADDR_OFF,
|
||||
+ .ttbr_shift = DART_T8020_TTBR_SHIFT,
|
||||
.ttbr_count = 4,
|
||||
};
|
||||
|
||||
@@ -1010,7 +1072,7 @@ static int apple_dart_suspend(struct device *dev)
|
||||
unsigned int sid, idx;
|
||||
|
||||
for (sid = 0; sid < dart->num_streams; sid++) {
|
||||
- dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(sid));
|
||||
+ dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(dart, sid));
|
||||
for (idx = 0; idx < dart->hw->ttbr_count; idx++)
|
||||
dart->save_ttbr[sid][idx] =
|
||||
readl_relaxed(dart->regs + DART_TTBR(dart, sid, idx));
|
||||
@@ -1035,7 +1097,7 @@ static int apple_dart_resume(struct device *dev)
|
||||
for (idx = 0; idx < dart->hw->ttbr_count; idx++)
|
||||
writel_relaxed(dart->save_ttbr[sid][idx],
|
||||
dart->regs + DART_TTBR(dart, sid, idx));
|
||||
- writel_relaxed(dart->save_tcr[sid], dart->regs + DART_TCR(sid));
|
||||
+ writel_relaxed(dart->save_tcr[sid], dart->regs + DART_TCR(dart, sid));
|
||||
}
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,316 @@
|
||||
From 50f73e1258c60ccd081a09339f77176f0f9bc49c Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 28 Jun 2022 01:33:40 +0900
|
||||
Subject: [PATCH 056/171] iommu: dart: Add t8110 support
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/iommu/apple-dart.c | 200 ++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 197 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
|
||||
index 3f89db3f8e99..249798e26e5d 100644
|
||||
--- a/drivers/iommu/apple-dart.c
|
||||
+++ b/drivers/iommu/apple-dart.c
|
||||
@@ -84,6 +84,62 @@
|
||||
#define DART_T8020_TTBR_ADDR_OFF 0
|
||||
#define DART_T8020_TTBR_SHIFT 12
|
||||
|
||||
+/* T8110 registers */
|
||||
+
|
||||
+#define DART_T8110_PARAMS3 0x08
|
||||
+#define DART_T8110_PARAMS3_PA_WIDTH GENMASK(29, 24)
|
||||
+#define DART_T8110_PARAMS3_VA_WIDTH GENMASK(21, 16)
|
||||
+#define DART_T8110_PARAMS3_VER_MAJ GENMASK(15, 8)
|
||||
+#define DART_T8110_PARAMS3_VER_MIN GENMASK(7, 0)
|
||||
+
|
||||
+#define DART_T8110_PARAMS4 0x0c
|
||||
+#define DART_T8110_PARAMS4_NUM_CLIENTS GENMASK(24, 16)
|
||||
+#define DART_T8110_PARAMS4_NUM_SIDS GENMASK(8, 0)
|
||||
+
|
||||
+#define DART_T8110_TLB_CMD 0x80
|
||||
+#define DART_T8110_TLB_CMD_BUSY BIT(31)
|
||||
+#define DART_T8110_TLB_CMD_OP GENMASK(10, 8)
|
||||
+#define DART_T8110_TLB_CMD_OP_FLUSH_ALL 0
|
||||
+#define DART_T8110_TLB_CMD_OP_FLUSH_SID 1
|
||||
+#define DART_T8110_TLB_CMD_STREAM GENMASK(7, 0)
|
||||
+
|
||||
+#define DART_T8110_ERROR 0x100
|
||||
+#define DART_T8110_ERROR_STREAM GENMASK(27, 20)
|
||||
+#define DART_T8110_ERROR_CODE GENMASK(14, 0)
|
||||
+#define DART_T8110_ERROR_FLAG BIT(31)
|
||||
+
|
||||
+#define DART_T8110_ERROR_MASK 0x104
|
||||
+
|
||||
+#define DART_T8110_ERROR_READ_FAULT BIT(4)
|
||||
+#define DART_T8110_ERROR_WRITE_FAULT BIT(3)
|
||||
+#define DART_T8110_ERROR_NO_PTE BIT(3)
|
||||
+#define DART_T8110_ERROR_NO_PMD BIT(2)
|
||||
+#define DART_T8110_ERROR_NO_PGD BIT(1)
|
||||
+#define DART_T8110_ERROR_NO_TTBR BIT(0)
|
||||
+
|
||||
+#define DART_T8110_ERROR_ADDR_LO 0x170
|
||||
+#define DART_T8110_ERROR_ADDR_HI 0x174
|
||||
+
|
||||
+#define DART_T8110_PROTECT 0x200
|
||||
+#define DART_T8110_UNPROTECT 0x204
|
||||
+#define DART_T8110_PROTECT_LOCK 0x208
|
||||
+#define DART_T8110_PROTECT_TTBR_TCR BIT(0)
|
||||
+
|
||||
+#define DART_T8110_ENABLE_STREAMS 0xc00
|
||||
+#define DART_T8110_DISABLE_STREAMS 0xc20
|
||||
+
|
||||
+#define DART_T8110_TCR 0x1000
|
||||
+#define DART_T8110_TCR_REMAP GENMASK(11, 8)
|
||||
+#define DART_T8110_TCR_REMAP_EN BIT(7)
|
||||
+#define DART_T8110_TCR_BYPASS_DAPF BIT(2)
|
||||
+#define DART_T8110_TCR_BYPASS_DART BIT(1)
|
||||
+#define DART_T8110_TCR_TRANSLATE_ENABLE BIT(0)
|
||||
+
|
||||
+#define DART_T8110_TTBR 0x1400
|
||||
+#define DART_T8110_TTBR_VALID BIT(0)
|
||||
+#define DART_T8110_TTBR_ADDR_OFF 2
|
||||
+#define DART_T8110_TTBR_SHIFT 14
|
||||
+
|
||||
#define DART_TCR(dart, sid) ((dart)->hw->tcr + ((sid) << 2))
|
||||
|
||||
#define DART_TTBR(dart, sid, idx) ((dart)->hw->ttbr + \
|
||||
@@ -92,7 +148,14 @@
|
||||
|
||||
struct apple_dart_stream_map;
|
||||
|
||||
+enum dart_type {
|
||||
+ DART_T8020,
|
||||
+ DART_T6000,
|
||||
+ DART_T8110,
|
||||
+};
|
||||
+
|
||||
struct apple_dart_hw {
|
||||
+ enum dart_type type;
|
||||
irqreturn_t (*irq_handler)(int irq, void *dev);
|
||||
int (*invalidate_tlb)(struct apple_dart_stream_map *stream_map);
|
||||
|
||||
@@ -149,6 +212,7 @@ struct apple_dart {
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
+ u32 oas;
|
||||
u32 pgsize;
|
||||
u32 num_streams;
|
||||
u32 supports_bypass : 1;
|
||||
@@ -330,6 +394,44 @@ apple_dart_t8020_hw_stream_command(struct apple_dart_stream_map *stream_map,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+apple_dart_t8110_hw_tlb_command(struct apple_dart_stream_map *stream_map,
|
||||
+ u32 command)
|
||||
+{
|
||||
+ struct apple_dart *dart = stream_map->dart;
|
||||
+ unsigned long flags;
|
||||
+ int ret = 0;
|
||||
+ int sid;
|
||||
+
|
||||
+ spin_lock_irqsave(&dart->lock, flags);
|
||||
+
|
||||
+ for_each_set_bit(sid, stream_map->sidmap, dart->num_streams) {
|
||||
+ u32 val = FIELD_PREP(DART_T8110_TLB_CMD_OP, command) |
|
||||
+ FIELD_PREP(DART_T8110_TLB_CMD_STREAM, sid);
|
||||
+ writel(val, dart->regs + DART_T8110_TLB_CMD);
|
||||
+
|
||||
+ ret = readl_poll_timeout_atomic(
|
||||
+ dart->regs + DART_T8110_TLB_CMD, val,
|
||||
+ !(val & DART_T8110_TLB_CMD_BUSY), 1,
|
||||
+ DART_STREAM_COMMAND_BUSY_TIMEOUT);
|
||||
+
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&dart->lock, flags);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ dev_err(stream_map->dart->dev,
|
||||
+ "busy bit did not clear after command %x for stream %d\n",
|
||||
+ command, sid);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
apple_dart_t8020_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
|
||||
{
|
||||
@@ -337,6 +439,13 @@ apple_dart_t8020_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
|
||||
stream_map, DART_T8020_STREAM_COMMAND_INVALIDATE);
|
||||
}
|
||||
|
||||
+static int
|
||||
+apple_dart_t8110_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
|
||||
+{
|
||||
+ return apple_dart_t8110_hw_tlb_command(
|
||||
+ stream_map, DART_T8110_TLB_CMD_OP_FLUSH_SID);
|
||||
+}
|
||||
+
|
||||
static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
{
|
||||
u32 config;
|
||||
@@ -363,6 +472,9 @@ static int apple_dart_hw_reset(struct apple_dart *dart)
|
||||
/* clear any pending errors before the interrupt is unmasked */
|
||||
writel(readl(dart->regs + dart->hw->error), dart->regs + dart->hw->error);
|
||||
|
||||
+ if (dart->hw->type == DART_T8110)
|
||||
+ writel(0, dart->regs + DART_T8110_ERROR_MASK);
|
||||
+
|
||||
return dart->hw->invalidate_tlb(&stream_map);
|
||||
}
|
||||
|
||||
@@ -479,7 +591,7 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
|
||||
pgtbl_cfg = (struct io_pgtable_cfg){
|
||||
.pgsize_bitmap = dart->pgsize,
|
||||
.ias = 32,
|
||||
- .oas = dart->hw->oas,
|
||||
+ .oas = dart->oas,
|
||||
.coherent_walk = 1,
|
||||
.iommu_dev = dart->dev,
|
||||
};
|
||||
@@ -884,6 +996,46 @@ static irqreturn_t apple_dart_t8020_irq(int irq, void *dev)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+
|
||||
+static irqreturn_t apple_dart_t8110_irq(int irq, void *dev)
|
||||
+{
|
||||
+ struct apple_dart *dart = dev;
|
||||
+ const char *fault_name = NULL;
|
||||
+ u32 error = readl(dart->regs + DART_T8110_ERROR);
|
||||
+ u32 error_code = FIELD_GET(DART_T8110_ERROR_CODE, error);
|
||||
+ u32 addr_lo = readl(dart->regs + DART_T8110_ERROR_ADDR_LO);
|
||||
+ u32 addr_hi = readl(dart->regs + DART_T8110_ERROR_ADDR_HI);
|
||||
+ u64 addr = addr_lo | (((u64)addr_hi) << 32);
|
||||
+ u8 stream_idx = FIELD_GET(DART_T8110_ERROR_STREAM, error);
|
||||
+
|
||||
+ if (!(error & DART_T8110_ERROR_FLAG))
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ /* there should only be a single bit set but let's use == to be sure */
|
||||
+ if (error_code == DART_T8110_ERROR_READ_FAULT)
|
||||
+ fault_name = "READ FAULT";
|
||||
+ else if (error_code == DART_T8110_ERROR_WRITE_FAULT)
|
||||
+ fault_name = "WRITE FAULT";
|
||||
+ else if (error_code == DART_T8110_ERROR_NO_PTE)
|
||||
+ fault_name = "NO PTE FOR IOVA";
|
||||
+ else if (error_code == DART_T8110_ERROR_NO_PMD)
|
||||
+ fault_name = "NO PMD FOR IOVA";
|
||||
+ else if (error_code == DART_T8110_ERROR_NO_PGD)
|
||||
+ fault_name = "NO PGD FOR IOVA";
|
||||
+ else if (error_code == DART_T8110_ERROR_NO_TTBR)
|
||||
+ fault_name = "NO TTBR FOR IOVA";
|
||||
+ else
|
||||
+ fault_name = "unknown";
|
||||
+
|
||||
+ dev_err_ratelimited(
|
||||
+ dart->dev,
|
||||
+ "translation fault: status:0x%x stream:%d code:0x%x (%s) at 0x%llx",
|
||||
+ error, stream_idx, error_code, fault_name, addr);
|
||||
+
|
||||
+ writel(error, dart->regs + DART_T8110_ERROR);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
static int apple_dart_set_bus_ops(const struct iommu_ops *ops)
|
||||
{
|
||||
int ret;
|
||||
@@ -908,7 +1060,7 @@ static int apple_dart_set_bus_ops(const struct iommu_ops *ops)
|
||||
static int apple_dart_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
- u32 dart_params[2];
|
||||
+ u32 dart_params[4];
|
||||
struct resource *res;
|
||||
struct apple_dart *dart;
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -948,7 +1100,20 @@ static int apple_dart_probe(struct platform_device *pdev)
|
||||
dart->pgsize = 1 << FIELD_GET(DART_PARAMS1_PAGE_SHIFT, dart_params[0]);
|
||||
dart->supports_bypass = dart_params[1] & DART_PARAMS2_BYPASS_SUPPORT;
|
||||
|
||||
- dart->num_streams = dart->hw->max_sid_count;
|
||||
+ switch (dart->hw->type) {
|
||||
+ case DART_T8020:
|
||||
+ case DART_T6000:
|
||||
+ dart->oas = dart->hw->oas;
|
||||
+ dart->num_streams = dart->hw->max_sid_count;
|
||||
+ break;
|
||||
+
|
||||
+ case DART_T8110:
|
||||
+ dart_params[2] = readl(dart->regs + DART_T8110_PARAMS3);
|
||||
+ dart_params[3] = readl(dart->regs + DART_T8110_PARAMS4);
|
||||
+ dart->oas = FIELD_GET(DART_T8110_PARAMS3_PA_WIDTH, dart_params[2]);
|
||||
+ dart->num_streams = FIELD_GET(DART_T8110_PARAMS4_NUM_SIDS, dart_params[3]);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if (dart->num_streams > DART_MAX_STREAMS) {
|
||||
dev_err(&pdev->dev, "Too many streams (%d > %d)\n",
|
||||
@@ -1017,6 +1182,7 @@ static int apple_dart_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct apple_dart_hw apple_dart_hw_t8103 = {
|
||||
+ .type = DART_T8020,
|
||||
.irq_handler = apple_dart_t8020_irq,
|
||||
.invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb,
|
||||
.oas = 36,
|
||||
@@ -1041,6 +1207,7 @@ static const struct apple_dart_hw apple_dart_hw_t8103 = {
|
||||
.ttbr_count = 4,
|
||||
};
|
||||
static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||
+ .type = DART_T6000,
|
||||
.irq_handler = apple_dart_t8020_irq,
|
||||
.invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb,
|
||||
.oas = 42,
|
||||
@@ -1065,6 +1232,32 @@ static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||
.ttbr_count = 4,
|
||||
};
|
||||
|
||||
+static const struct apple_dart_hw apple_dart_hw_t8110 = {
|
||||
+ .type = DART_T8110,
|
||||
+ .irq_handler = apple_dart_t8110_irq,
|
||||
+ .invalidate_tlb = apple_dart_t8110_hw_invalidate_tlb,
|
||||
+ .fmt = APPLE_DART2,
|
||||
+ .max_sid_count = 256,
|
||||
+
|
||||
+ .enable_streams = DART_T8110_ENABLE_STREAMS,
|
||||
+ .disable_streams = DART_T8110_DISABLE_STREAMS,
|
||||
+ .lock = DART_T8110_PROTECT,
|
||||
+ .lock_bit = DART_T8110_PROTECT_TTBR_TCR,
|
||||
+
|
||||
+ .error = DART_T8110_ERROR,
|
||||
+
|
||||
+ .tcr = DART_T8110_TCR,
|
||||
+ .tcr_enabled = DART_T8110_TCR_TRANSLATE_ENABLE,
|
||||
+ .tcr_disabled = 0,
|
||||
+ .tcr_bypass = DART_T8110_TCR_BYPASS_DAPF | DART_T8110_TCR_BYPASS_DART,
|
||||
+
|
||||
+ .ttbr = DART_T8110_TTBR,
|
||||
+ .ttbr_valid = DART_T8110_TTBR_VALID,
|
||||
+ .ttbr_addr_off = DART_T8110_TTBR_ADDR_OFF,
|
||||
+ .ttbr_shift = DART_T8110_TTBR_SHIFT,
|
||||
+ .ttbr_count = 1,
|
||||
+};
|
||||
+
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int apple_dart_suspend(struct device *dev)
|
||||
{
|
||||
@@ -1110,6 +1303,7 @@ static const struct dev_pm_ops apple_dart_pm_ops = {
|
||||
#endif
|
||||
|
||||
static const struct of_device_id apple_dart_of_match[] = {
|
||||
+ { .compatible = "apple,t8110-dart", .data = &apple_dart_hw_t8110 },
|
||||
{ .compatible = "apple,t8103-dart", .data = &apple_dart_hw_t8103 },
|
||||
{ .compatible = "apple,t6000-dart", .data = &apple_dart_hw_t6000 },
|
||||
{},
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,197 @@
|
||||
From e375f9d76a88bc847d44f38157c2dba1c7e02203 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Mon, 20 Sep 2021 02:23:11 +0900
|
||||
Subject: [PATCH 057/171] tty: serial: samsung_tty: Support runtime PM
|
||||
|
||||
This allows idle UART devices to be suspended using the standard
|
||||
runtime-PM framework. The logic is modeled after stm32-usart.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/tty/serial/samsung_tty.c | 92 ++++++++++++++++++++------------
|
||||
1 file changed, 59 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
|
||||
index 1afe47b62ad5..2a4ba4f3d23c 100644
|
||||
--- a/drivers/tty/serial/samsung_tty.c
|
||||
+++ b/drivers/tty/serial/samsung_tty.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/of.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/* UART name and device definitions */
|
||||
@@ -1354,30 +1355,49 @@ static int apple_s5l_serial_startup(struct uart_port *port)
|
||||
|
||||
/* power power management control */
|
||||
|
||||
+static int __maybe_unused s3c24xx_serial_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct uart_port *port = dev_get_drvdata(dev);
|
||||
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
+ int timeout = 10000;
|
||||
+
|
||||
+ while (--timeout && !s3c24xx_serial_txempty_nofifo(port))
|
||||
+ udelay(100);
|
||||
+
|
||||
+ if (!IS_ERR(ourport->baudclk))
|
||||
+ clk_disable_unprepare(ourport->baudclk);
|
||||
+
|
||||
+ clk_disable_unprepare(ourport->clk);
|
||||
+ return 0;
|
||||
+};
|
||||
+
|
||||
+static int __maybe_unused s3c24xx_serial_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct uart_port *port = dev_get_drvdata(dev);
|
||||
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
+
|
||||
+ clk_prepare_enable(ourport->clk);
|
||||
+
|
||||
+ if (!IS_ERR(ourport->baudclk))
|
||||
+ clk_prepare_enable(ourport->baudclk);
|
||||
+ return 0;
|
||||
+};
|
||||
+
|
||||
static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
|
||||
unsigned int old)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
- int timeout = 10000;
|
||||
|
||||
ourport->pm_level = level;
|
||||
|
||||
switch (level) {
|
||||
- case 3:
|
||||
- while (--timeout && !s3c24xx_serial_txempty_nofifo(port))
|
||||
- udelay(100);
|
||||
-
|
||||
- if (!IS_ERR(ourport->baudclk))
|
||||
- clk_disable_unprepare(ourport->baudclk);
|
||||
-
|
||||
- clk_disable_unprepare(ourport->clk);
|
||||
+ case UART_PM_STATE_OFF:
|
||||
+ pm_runtime_mark_last_busy(port->dev);
|
||||
+ pm_runtime_put_sync(port->dev);
|
||||
break;
|
||||
|
||||
- case 0:
|
||||
- clk_prepare_enable(ourport->clk);
|
||||
-
|
||||
- if (!IS_ERR(ourport->baudclk))
|
||||
- clk_prepare_enable(ourport->baudclk);
|
||||
+ case UART_PM_STATE_ON:
|
||||
+ pm_runtime_get_sync(port->dev);
|
||||
break;
|
||||
default:
|
||||
dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level);
|
||||
@@ -2248,18 +2268,15 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
+ pm_runtime_get_noresume(&pdev->dev);
|
||||
+ pm_runtime_set_active(&pdev->dev);
|
||||
+ pm_runtime_enable(&pdev->dev);
|
||||
+
|
||||
dev_dbg(&pdev->dev, "%s: adding port\n", __func__);
|
||||
uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
|
||||
platform_set_drvdata(pdev, &ourport->port);
|
||||
|
||||
- /*
|
||||
- * Deactivate the clock enabled in s3c24xx_serial_init_port here,
|
||||
- * so that a potential re-enablement through the pm-callback overlaps
|
||||
- * and keeps the clock enabled in this case.
|
||||
- */
|
||||
- clk_disable_unprepare(ourport->clk);
|
||||
- if (!IS_ERR(ourport->baudclk))
|
||||
- clk_disable_unprepare(ourport->baudclk);
|
||||
+ pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
ret = s3c24xx_serial_cpufreq_register(ourport);
|
||||
if (ret < 0)
|
||||
@@ -2273,10 +2290,21 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
|
||||
static int s3c24xx_serial_remove(struct platform_device *dev)
|
||||
{
|
||||
struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
|
||||
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
|
||||
if (port) {
|
||||
+ pm_runtime_get_sync(&dev->dev);
|
||||
+
|
||||
s3c24xx_serial_cpufreq_deregister(to_ourport(port));
|
||||
uart_remove_one_port(&s3c24xx_uart_drv, port);
|
||||
+
|
||||
+ clk_disable_unprepare(ourport->clk);
|
||||
+ if (!IS_ERR(ourport->baudclk))
|
||||
+ clk_disable_unprepare(ourport->baudclk);
|
||||
+
|
||||
+ pm_runtime_disable(&dev->dev);
|
||||
+ pm_runtime_set_suspended(&dev->dev);
|
||||
+ pm_runtime_put_noidle(&dev->dev);
|
||||
}
|
||||
|
||||
uart_unregister_driver(&s3c24xx_uart_drv);
|
||||
@@ -2285,8 +2313,8 @@ static int s3c24xx_serial_remove(struct platform_device *dev)
|
||||
}
|
||||
|
||||
/* UART power management code */
|
||||
-#ifdef CONFIG_PM_SLEEP
|
||||
-static int s3c24xx_serial_suspend(struct device *dev)
|
||||
+
|
||||
+static int __maybe_unused s3c24xx_serial_suspend(struct device *dev)
|
||||
{
|
||||
struct uart_port *port = s3c24xx_dev_to_port(dev);
|
||||
|
||||
@@ -2296,7 +2324,7 @@ static int s3c24xx_serial_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int s3c24xx_serial_resume(struct device *dev)
|
||||
+static int __maybe_unused s3c24xx_serial_resume(struct device *dev)
|
||||
{
|
||||
struct uart_port *port = s3c24xx_dev_to_port(dev);
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
@@ -2316,7 +2344,7 @@ static int s3c24xx_serial_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int s3c24xx_serial_resume_noirq(struct device *dev)
|
||||
+static int __maybe_unused s3c24xx_serial_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct uart_port *port = s3c24xx_dev_to_port(dev);
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
@@ -2386,16 +2414,14 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
.suspend = s3c24xx_serial_suspend,
|
||||
.resume = s3c24xx_serial_resume,
|
||||
.resume_noirq = s3c24xx_serial_resume_noirq,
|
||||
+#endif
|
||||
+ SET_RUNTIME_PM_OPS(s3c24xx_serial_runtime_suspend,
|
||||
+ s3c24xx_serial_runtime_resume, NULL)
|
||||
};
|
||||
-#define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops)
|
||||
-
|
||||
-#else /* !CONFIG_PM_SLEEP */
|
||||
-
|
||||
-#define SERIAL_SAMSUNG_PM_OPS NULL
|
||||
-#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
/* Console code */
|
||||
|
||||
@@ -2936,7 +2962,7 @@ static struct platform_driver samsung_serial_driver = {
|
||||
.id_table = s3c24xx_serial_driver_ids,
|
||||
.driver = {
|
||||
.name = "samsung-uart",
|
||||
- .pm = SERIAL_SAMSUNG_PM_OPS,
|
||||
+ .pm = &s3c24xx_serial_pm_ops,
|
||||
.of_match_table = of_match_ptr(s3c24xx_uart_dt_match),
|
||||
},
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,83 @@
|
||||
From 33d1d04ba47ab79e38400038347b1ef04aca10fc Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Fri, 4 Mar 2022 19:19:38 +0900
|
||||
Subject: [PATCH 058/171] drm/simpledrm: Add backlight support
|
||||
|
||||
Allows devicetrees to link the simplefb node to a backlight device,
|
||||
and toggles power to the backlight when the display pipe is
|
||||
enabled/disabled. This is sufficient for basic DPMS style functionality
|
||||
in trivial devices.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/gpu/drm/tiny/Kconfig | 1 +
|
||||
drivers/gpu/drm/tiny/simpledrm.c | 14 ++++++++++++++
|
||||
2 files changed, 15 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig
|
||||
index 627d637a1e7e..20c78bb1365d 100644
|
||||
--- a/drivers/gpu/drm/tiny/Kconfig
|
||||
+++ b/drivers/gpu/drm/tiny/Kconfig
|
||||
@@ -71,6 +71,7 @@ config DRM_SIMPLEDRM
|
||||
depends on DRM && MMU
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
+ select BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
DRM driver for simple platform-provided framebuffers.
|
||||
|
||||
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
|
||||
index 5422363690e7..40de01efbbd9 100644
|
||||
--- a/drivers/gpu/drm/tiny/simpledrm.c
|
||||
+++ b/drivers/gpu/drm/tiny/simpledrm.c
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
+#include <linux/backlight.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/minmax.h>
|
||||
@@ -225,6 +226,9 @@ struct simpledrm_device {
|
||||
size_t nformats;
|
||||
struct drm_connector connector;
|
||||
struct drm_simple_display_pipe pipe;
|
||||
+
|
||||
+ /* backlight */
|
||||
+ struct backlight_device *backlight;
|
||||
};
|
||||
|
||||
static struct simpledrm_device *simpledrm_device_of_dev(struct drm_device *dev)
|
||||
@@ -673,6 +677,9 @@ simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
|
||||
dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip);
|
||||
drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip);
|
||||
|
||||
+ if (sdev->backlight)
|
||||
+ backlight_enable(sdev->backlight);
|
||||
+
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
@@ -686,6 +693,9 @@ simpledrm_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
|
||||
if (!drm_dev_enter(dev, &idx))
|
||||
return;
|
||||
|
||||
+ if (sdev->backlight)
|
||||
+ backlight_disable(sdev->backlight);
|
||||
+
|
||||
/* Clear screen to black if disabled */
|
||||
memset_io(sdev->screen_base, 0, sdev->pitch * sdev->mode.vdisplay);
|
||||
|
||||
@@ -845,6 +855,10 @@ simpledrm_device_create(struct drm_driver *drv, struct platform_device *pdev)
|
||||
sdev->pdev = pdev;
|
||||
platform_set_drvdata(pdev, sdev);
|
||||
|
||||
+ sdev->backlight = devm_of_find_backlight(&pdev->dev);
|
||||
+ if (IS_ERR(sdev->backlight))
|
||||
+ sdev->backlight = NULL;
|
||||
+
|
||||
ret = simpledrm_device_init_clocks(sdev);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,29 @@
|
||||
From a9d5ced1ff2a58014dc850ece702cc194884870d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sat, 12 Mar 2022 00:07:09 +0900
|
||||
Subject: [PATCH 059/171] of: Demote "Bad cell count" to debug message
|
||||
|
||||
This happens on the SPMI bus... TODO: figure out what the right solution
|
||||
is here.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/of/address.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/of/address.c b/drivers/of/address.c
|
||||
index 94f017d808c4..68f54ec92496 100644
|
||||
--- a/drivers/of/address.c
|
||||
+++ b/drivers/of/address.c
|
||||
@@ -538,7 +538,7 @@ static u64 __of_translate_address(struct device_node *dev,
|
||||
pbus = of_match_bus(parent);
|
||||
pbus->count_cells(dev, &pna, &pns);
|
||||
if (!OF_CHECK_COUNTS(pna, pns)) {
|
||||
- pr_err("Bad cell count for %pOF\n", dev);
|
||||
+ pr_debug("Bad cell count for %pOF\n", dev);
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,37 @@
|
||||
From 2c80db171f88a2c7384cfefbd20ba4b2ed570e5c Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 5 May 2022 01:40:31 +0900
|
||||
Subject: [PATCH 060/171] mmc: sdhci-pci: Support external CD GPIO on all OF
|
||||
systems
|
||||
|
||||
Allow OF systems to specify an external CD GPIO on all devices,
|
||||
even if they have an internal CD feature.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/mmc/host/sdhci-pci-core.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
|
||||
index ed53276f6ad9..a711b4be3867 100644
|
||||
--- a/drivers/mmc/host/sdhci-pci-core.c
|
||||
+++ b/drivers/mmc/host/sdhci-pci-core.c
|
||||
@@ -2096,6 +2096,15 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
|
||||
dev_warn(&pdev->dev, "failed to setup card detect gpio\n");
|
||||
slot->cd_idx = -1;
|
||||
}
|
||||
+ } else if (is_of_node(pdev->dev.fwnode)) {
|
||||
+ /* Allow all OF systems to use a CD GPIO if provided */
|
||||
+
|
||||
+ ret = mmc_gpiod_request_cd(host->mmc, "cd", 0,
|
||||
+ slot->cd_override_level, 0);
|
||||
+ if (ret == -EPROBE_DEFER)
|
||||
+ goto remove;
|
||||
+ else if (ret == 0)
|
||||
+ slot->cd_idx = 0;
|
||||
}
|
||||
|
||||
if (chip->fixes && chip->fixes->add_host)
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 5f9f115872ee614c22a9417f68ae9100ec32b5c7 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 5 May 2022 02:27:35 +0900
|
||||
Subject: [PATCH 061/171] mmc: sdhci-pci: Support setting CD debounce delay
|
||||
|
||||
Some systems (e.g. 2021 MacBook Pro 14/16") have noncompliant connectors
|
||||
where CD activates before the card is fully inserted. We need debounce
|
||||
delay support on these to avoid detection failures when the card isn't
|
||||
inserted very quickly.
|
||||
|
||||
Set the default to 200ms for all systems instead of 0. This is the
|
||||
default on non-PCI platforms, and will probably help other systems too.
|
||||
The naughty MacBooks will need closer to 750ms in the device tree to
|
||||
be reliable...
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/mmc/host/sdhci-pci-core.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
|
||||
index a711b4be3867..2fd4221b24aa 100644
|
||||
--- a/drivers/mmc/host/sdhci-pci-core.c
|
||||
+++ b/drivers/mmc/host/sdhci-pci-core.c
|
||||
@@ -2015,6 +2015,7 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
|
||||
struct sdhci_host *host;
|
||||
int ret, bar = first_bar + slotno;
|
||||
size_t priv_size = chip->fixes ? chip->fixes->priv_size : 0;
|
||||
+ u32 cd_debounce_delay_ms;
|
||||
|
||||
if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
|
||||
dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
|
||||
@@ -2081,6 +2082,10 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
|
||||
if (host->mmc->caps & MMC_CAP_CD_WAKE)
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
|
||||
+ if (device_property_read_u32(&pdev->dev, "cd-debounce-delay-ms",
|
||||
+ &cd_debounce_delay_ms))
|
||||
+ cd_debounce_delay_ms = 200;
|
||||
+
|
||||
if (slot->cd_idx >= 0) {
|
||||
ret = mmc_gpiod_request_cd(host->mmc, "cd", slot->cd_idx,
|
||||
slot->cd_override_level, 0);
|
||||
@@ -2088,7 +2093,7 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
|
||||
ret = mmc_gpiod_request_cd(host->mmc, NULL,
|
||||
slot->cd_idx,
|
||||
slot->cd_override_level,
|
||||
- 0);
|
||||
+ cd_debounce_delay_ms * 1000);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
goto remove;
|
||||
|
||||
@@ -2100,7 +2105,8 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
|
||||
/* Allow all OF systems to use a CD GPIO if provided */
|
||||
|
||||
ret = mmc_gpiod_request_cd(host->mmc, "cd", 0,
|
||||
- slot->cd_override_level, 0);
|
||||
+ slot->cd_override_level,
|
||||
+ cd_debounce_delay_ms * 1000);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
goto remove;
|
||||
else if (ret == 0)
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,106 @@
|
||||
From f60e434c0766aaf5db2d775bbcba49d896e1f518 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Mon, 2 May 2022 19:46:47 +0900
|
||||
Subject: [PATCH 062/171] net: usb: ax88179_178a: Bind only to vendor-specific
|
||||
interface
|
||||
|
||||
The Anker PowerExpand USB-C to Gigabit Ethernet adapter uses this
|
||||
chipset, but exposes CDC Ethernet configurations as well as the
|
||||
vendor specific one. This driver ends up binding first to both CDC
|
||||
interfaces, tries to instantiate two Ethernet interfaces talking to
|
||||
the same device, and the result is a nice fireworks show.
|
||||
|
||||
Change all the ID matches to specifically match the vendor-specific
|
||||
interface. By default the device comes up in CDC mode and is bound by
|
||||
that driver (which works fine); users may switch it to the vendor
|
||||
interface using sysfs to set bConfigurationValue, at which point the
|
||||
device actually goes through a reconnect cycle and comes back as a
|
||||
vendor specific only device, and then this driver binds and works too.
|
||||
|
||||
The affected device uses VID/PID 0b95:1790, but we might as well change
|
||||
all of them for good measure, since there is no good reason for this
|
||||
driver to bind to standard CDC Ethernet interfaces.
|
||||
|
||||
v3: Added VID/PID info to commit message
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/net/usb/ax88179_178a.c | 26 +++++++++++++-------------
|
||||
1 file changed, 13 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
|
||||
index ac2d400d1d6c..aeb0294385ed 100644
|
||||
--- a/drivers/net/usb/ax88179_178a.c
|
||||
+++ b/drivers/net/usb/ax88179_178a.c
|
||||
@@ -1965,55 +1965,55 @@ static const struct driver_info at_umc2000sp_info = {
|
||||
static const struct usb_device_id products[] = {
|
||||
{
|
||||
/* ASIX AX88179 10/100/1000 */
|
||||
- USB_DEVICE(0x0b95, 0x1790),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x1790, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&ax88179_info,
|
||||
}, {
|
||||
/* ASIX AX88178A 10/100/1000 */
|
||||
- USB_DEVICE(0x0b95, 0x178a),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x178a, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&ax88178a_info,
|
||||
}, {
|
||||
/* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */
|
||||
- USB_DEVICE(0x04b4, 0x3610),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x04b4, 0x3610, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&cypress_GX3_info,
|
||||
}, {
|
||||
/* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */
|
||||
- USB_DEVICE(0x2001, 0x4a00),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x4a00, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&dlink_dub1312_info,
|
||||
}, {
|
||||
/* Sitecom USB 3.0 to Gigabit Adapter */
|
||||
- USB_DEVICE(0x0df6, 0x0072),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0072, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&sitecom_info,
|
||||
}, {
|
||||
/* Samsung USB Ethernet Adapter */
|
||||
- USB_DEVICE(0x04e8, 0xa100),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x04e8, 0xa100, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&samsung_info,
|
||||
}, {
|
||||
/* Lenovo OneLinkDock Gigabit LAN */
|
||||
- USB_DEVICE(0x17ef, 0x304b),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x17ef, 0x304b, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&lenovo_info,
|
||||
}, {
|
||||
/* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
|
||||
- USB_DEVICE(0x050d, 0x0128),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x0128, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&belkin_info,
|
||||
}, {
|
||||
/* Toshiba USB 3.0 GBit Ethernet Adapter */
|
||||
- USB_DEVICE(0x0930, 0x0a13),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x0a13, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&toshiba_info,
|
||||
}, {
|
||||
/* Magic Control Technology U3-A9003 USB 3.0 Gigabit Ethernet Adapter */
|
||||
- USB_DEVICE(0x0711, 0x0179),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x0711, 0x0179, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&mct_info,
|
||||
}, {
|
||||
/* Allied Telesis AT-UMC2000 USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
|
||||
- USB_DEVICE(0x07c9, 0x000e),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000e, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&at_umc2000_info,
|
||||
}, {
|
||||
/* Allied Telesis AT-UMC200 USB 3.0/USB 3.1 Gen 1 to Fast Ethernet Adapter */
|
||||
- USB_DEVICE(0x07c9, 0x000f),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000f, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&at_umc200_info,
|
||||
}, {
|
||||
/* Allied Telesis AT-UMC2000/SP USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
|
||||
- USB_DEVICE(0x07c9, 0x0010),
|
||||
+ USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x0010, 0xff, 0xff, 0),
|
||||
.driver_info = (unsigned long)&at_umc2000sp_info,
|
||||
},
|
||||
{ },
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 834ab8867f3537c2a1c40853309aeb63401f7b34 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Sun, 7 Nov 2021 11:21:19 +0100
|
||||
Subject: [PATCH 063/171] dt-bindings: usb: Add Apple dwc3 bindings
|
||||
|
||||
Apple Silicon SoCs such as the M1 have multiple USB controllers based on
|
||||
the Synopsys DesignWare USB3 controller.
|
||||
References to the ATC PHY required for SuperSpeed are left out for now
|
||||
until support has been upstreamed as well.
|
||||
|
||||
Signed-off-by: Sven Peter <sven@svenpeter.dev>
|
||||
---
|
||||
.../devicetree/bindings/usb/apple,dwc3.yaml | 64 +++++++++++++++++++
|
||||
1 file changed, 64 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/usb/apple,dwc3.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/usb/apple,dwc3.yaml b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..fb3b3489e6b2
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml
|
||||
@@ -0,0 +1,64 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/usb/apple,dwc3.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Apple Silicon DWC3 USB controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - Sven Peter <sven@svenpeter.dev>
|
||||
+
|
||||
+description:
|
||||
+ On Apple Silicon SoCs such as the M1 each Type-C port has a corresponding
|
||||
+ USB controller based on the Synopsys DesignWare USB3 controller.
|
||||
+
|
||||
+ The common content of this binding is defined in snps,dwc3.yaml.
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: snps,dwc3.yaml#
|
||||
+
|
||||
+select:
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ const: apple,dwc3
|
||||
+ required:
|
||||
+ - compatible
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - apple,t8103-dwc3
|
||||
+ - apple,t6000-dwc3
|
||||
+ - const: apple,dwc3
|
||||
+ - const: snps,dwc3
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - interrupts
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/interrupt-controller/apple-aic.h>
|
||||
+ #include <dt-bindings/interrupt-controller/irq.h>
|
||||
+
|
||||
+ usb@82280000 {
|
||||
+ compatible = "apple,t8103-dwc3", "apple,dwc3", "snps,dwc3";
|
||||
+ reg = <0x82280000 0x10000>;
|
||||
+ interrupts = <AIC_IRQ 777 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+
|
||||
+ dr_mode = "otg";
|
||||
+ usb-role-switch;
|
||||
+ role-switch-default-mode = "host";
|
||||
+ };
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,172 @@
|
||||
From bda2c5ab3f028f25bf7d0e8196ee1dee38973153 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Peter <sven@svenpeter.dev>
|
||||
Date: Sun, 7 Nov 2021 11:21:20 +0100
|
||||
Subject: [PATCH 064/171] usb: dwc3: Add role switch reset quirk for Apple DWC3
|
||||
|
||||
As mad as it sounds, the dwc3 controller present on the Apple M1 must be
|
||||
reset and reinitialized whenever a device is unplugged from the root port.
|
||||
The only reliable unplug/plug notification available comes from the USB
|
||||
PD controller through the role-switch infrastructure.
|
||||
|
||||
This is required for at least two reasons:
|
||||
|
||||
- The USB2 D+/D- lines are connected through a stateful eUSB2 repeater
|
||||
which in turn is controlled by a variant of the TI TPS6598x USB PD
|
||||
chip. When the USB PD controller detects a hotplug event it resets
|
||||
the eUSB2 repeater. Afterwards, no new device is recognized before
|
||||
the DWC3 core and PHY are reset as well.
|
||||
|
||||
- It's possible to completely break the dwc3 controller by switching
|
||||
it to device mode and unplugging the cable at just the wrong time.
|
||||
Even a CORESOFTRESET is not enough to allow new devices again.
|
||||
The only workaround is to trigger a hard reset of the entire
|
||||
dwc3 core.
|
||||
|
||||
Signed-off-by: Sven Peter <sven@svenpeter.dev>
|
||||
---
|
||||
drivers/usb/dwc3/core.c | 41 ++++++++++++++++++++++++++++++++++++++---
|
||||
drivers/usb/dwc3/core.h | 6 ++++++
|
||||
drivers/usb/dwc3/drd.c | 7 +++++++
|
||||
3 files changed, 51 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
|
||||
index 573421984948..b4c58deccabb 100644
|
||||
--- a/drivers/usb/dwc3/core.c
|
||||
+++ b/drivers/usb/dwc3/core.c
|
||||
@@ -116,6 +116,9 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
|
||||
dwc->current_dr_role = mode;
|
||||
}
|
||||
|
||||
+static void dwc3_core_exit(struct dwc3 *dwc);
|
||||
+static int dwc3_core_init_for_resume(struct dwc3 *dwc);
|
||||
+
|
||||
static void __dwc3_set_mode(struct work_struct *work)
|
||||
{
|
||||
struct dwc3 *dwc = work_to_dwc(work);
|
||||
@@ -130,10 +133,11 @@ static void __dwc3_set_mode(struct work_struct *work)
|
||||
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
|
||||
dwc3_otg_update(dwc, 0);
|
||||
|
||||
- if (!dwc->desired_dr_role)
|
||||
+ if (!dwc->desired_dr_role && !dwc->role_switch_reset_quirk)
|
||||
goto out;
|
||||
|
||||
- if (dwc->desired_dr_role == dwc->current_dr_role)
|
||||
+ if (dwc->desired_dr_role == dwc->current_dr_role &&
|
||||
+ !dwc->role_switch_reset_quirk)
|
||||
goto out;
|
||||
|
||||
if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
|
||||
@@ -158,6 +162,34 @@ static void __dwc3_set_mode(struct work_struct *work)
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (dwc->role_switch_reset_quirk) {
|
||||
+ if (dwc->current_dr_role) {
|
||||
+ dwc->current_dr_role = 0;
|
||||
+ dwc3_core_exit(dwc);
|
||||
+ }
|
||||
+
|
||||
+ if (dwc->desired_dr_role) {
|
||||
+ /*
|
||||
+ * the first call to __dwc3_set_mode comes from
|
||||
+ * dwc3_drd_init. In that case dwc3_core_init has been
|
||||
+ * called but dwc->current_dr_role is zero such that
|
||||
+ * we must not reinitialize the core again here.
|
||||
+ */
|
||||
+ if (dwc->role_switch_reset_quirk_initialized) {
|
||||
+ ret = dwc3_core_init_for_resume(dwc);
|
||||
+ if (ret) {
|
||||
+ dev_err(dwc->dev,
|
||||
+ "failed to reinitialize core\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dwc->role_switch_reset_quirk_initialized = 1;
|
||||
+ } else {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* For DRD host or device mode only */
|
||||
if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
|
||||
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
||||
@@ -1764,6 +1796,9 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
|
||||
"could not get suspend clock\n");
|
||||
}
|
||||
+
|
||||
+ if (of_device_is_compatible(dev->of_node, "apple,dwc3"))
|
||||
+ dwc->role_switch_reset_quirk = true;
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(dwc->reset);
|
||||
@@ -1900,7 +1935,6 @@ static int dwc3_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_PM
|
||||
static int dwc3_core_init_for_resume(struct dwc3 *dwc)
|
||||
{
|
||||
int ret;
|
||||
@@ -1927,6 +1961,7 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PM
|
||||
static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
{
|
||||
unsigned long flags;
|
||||
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
|
||||
index 81c486b3941c..ee0225ce2234 100644
|
||||
--- a/drivers/usb/dwc3/core.h
|
||||
+++ b/drivers/usb/dwc3/core.h
|
||||
@@ -1103,6 +1103,9 @@ struct dwc3_scratchpad_array {
|
||||
* 3 - Reserved
|
||||
* @dis_metastability_quirk: set to disable metastability quirk.
|
||||
* @dis_split_quirk: set to disable split boundary.
|
||||
+ * @role_switch_reset_quirk: set to force reinitialization after any role switch
|
||||
+ * @role_switch_reset_quirk_initialized: set to true after the first role switch
|
||||
+ * which is triggered from dwc3_drd_init directly
|
||||
* @imod_interval: set the interrupt moderation interval in 250ns
|
||||
* increments or 0 to disable.
|
||||
* @max_cfg_eps: current max number of IN eps used across all USB configs.
|
||||
@@ -1318,6 +1321,9 @@ struct dwc3 {
|
||||
unsigned dis_split_quirk:1;
|
||||
unsigned async_callbacks:1;
|
||||
|
||||
+ unsigned role_switch_reset_quirk:1;
|
||||
+ unsigned role_switch_reset_quirk_initialized:1;
|
||||
+
|
||||
u16 imod_interval;
|
||||
|
||||
int max_cfg_eps;
|
||||
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
|
||||
index 039bf241769a..4579505cac1f 100644
|
||||
--- a/drivers/usb/dwc3/drd.c
|
||||
+++ b/drivers/usb/dwc3/drd.c
|
||||
@@ -461,6 +461,9 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (dwc->role_switch_reset_quirk && role == USB_ROLE_NONE)
|
||||
+ mode = 0;
|
||||
+
|
||||
dwc3_set_mode(dwc, mode);
|
||||
return 0;
|
||||
}
|
||||
@@ -489,6 +492,10 @@ static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw)
|
||||
role = USB_ROLE_DEVICE;
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ if (dwc->role_switch_reset_quirk && !dwc->current_dr_role)
|
||||
+ role = USB_ROLE_NONE;
|
||||
+
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
return role;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,141 @@
|
||||
From 6c8c3ae8ce7813a315f4729865f99d0d318f678a Mon Sep 17 00:00:00 2001
|
||||
From: Jens Axboe <axboe@kernel.dk>
|
||||
Date: Wed, 16 Feb 2022 12:17:58 -0700
|
||||
Subject: [PATCH 065/171] apple-nvme: defer cache flushes by a specified amount
|
||||
|
||||
Cache flushes on the M1 nvme are really slow, taking 17-18 msec to
|
||||
complete. This can slow down workloads considerably, pure random writes
|
||||
end up being bound by the flush latency and hence run at 55-60 IOPS.
|
||||
|
||||
Add a deferred flush work around to provide better performance, at a
|
||||
minimal risk. By default, flushes are delayed at most 1 second, but this
|
||||
is configurable.
|
||||
|
||||
With this work-around, a pure random write workload runs at ~12K IOPS
|
||||
rather than 56 IOPS.
|
||||
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
---
|
||||
drivers/nvme/host/apple.c | 69 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 69 insertions(+)
|
||||
|
||||
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
|
||||
index d702d7d60235..46294f99a1b0 100644
|
||||
--- a/drivers/nvme/host/apple.c
|
||||
+++ b/drivers/nvme/host/apple.c
|
||||
@@ -195,8 +195,20 @@ struct apple_nvme {
|
||||
|
||||
int irq;
|
||||
spinlock_t lock;
|
||||
+
|
||||
+ /*
|
||||
+ * Delayed cache flush handling state
|
||||
+ */
|
||||
+ struct nvme_ns *flush_ns;
|
||||
+ unsigned long flush_interval;
|
||||
+ unsigned long last_flush;
|
||||
+ struct delayed_work flush_dwork;
|
||||
};
|
||||
|
||||
+unsigned int flush_interval = 1000;
|
||||
+module_param(flush_interval, uint, 0644);
|
||||
+MODULE_PARM_DESC(flush_interval, "Grace period in msecs between flushes");
|
||||
+
|
||||
static_assert(sizeof(struct nvme_command) == 64);
|
||||
static_assert(sizeof(struct apple_nvmmu_tcb) == 128);
|
||||
|
||||
@@ -729,6 +741,26 @@ static int apple_nvme_remove_sq(struct apple_nvme *anv)
|
||||
return nvme_submit_sync_cmd(anv->ctrl.admin_q, &c, NULL, 0);
|
||||
}
|
||||
|
||||
+static bool apple_nvme_delayed_flush(struct apple_nvme *anv, struct nvme_ns *ns,
|
||||
+ struct request *req)
|
||||
+{
|
||||
+ if (!anv->flush_interval || req_op(req) != REQ_OP_FLUSH)
|
||||
+ return false;
|
||||
+ if (delayed_work_pending(&anv->flush_dwork))
|
||||
+ return true;
|
||||
+ if (time_before(jiffies, anv->last_flush + anv->flush_interval)) {
|
||||
+ kblockd_mod_delayed_work_on(WORK_CPU_UNBOUND, &anv->flush_dwork,
|
||||
+ anv->flush_interval);
|
||||
+ if (WARN_ON_ONCE(anv->flush_ns && anv->flush_ns != ns))
|
||||
+ goto out;
|
||||
+ anv->flush_ns = ns;
|
||||
+ return true;
|
||||
+ }
|
||||
+out:
|
||||
+ anv->last_flush = jiffies;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
const struct blk_mq_queue_data *bd)
|
||||
{
|
||||
@@ -764,6 +796,12 @@ static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
}
|
||||
|
||||
blk_mq_start_request(req);
|
||||
+
|
||||
+ if (apple_nvme_delayed_flush(anv, ns, req)) {
|
||||
+ blk_mq_complete_request(req);
|
||||
+ return BLK_STS_OK;
|
||||
+ }
|
||||
+
|
||||
apple_nvme_submit_cmd(q, cmnd);
|
||||
return BLK_STS_OK;
|
||||
|
||||
@@ -1366,6 +1404,28 @@ static int apple_nvme_attach_genpd(struct apple_nvme *anv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void apple_nvme_flush_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct nvme_command c = { };
|
||||
+ struct apple_nvme *anv;
|
||||
+ struct nvme_ns *ns;
|
||||
+ int err;
|
||||
+
|
||||
+ anv = container_of(work, struct apple_nvme, flush_dwork.work);
|
||||
+ ns = anv->flush_ns;
|
||||
+ if (WARN_ON_ONCE(!ns))
|
||||
+ return;
|
||||
+
|
||||
+ c.common.opcode = nvme_cmd_flush;
|
||||
+ c.common.nsid = cpu_to_le32(anv->flush_ns->head->ns_id);
|
||||
+ err = nvme_submit_sync_cmd(ns->queue, &c, NULL, 0);
|
||||
+ if (err) {
|
||||
+ dev_err(anv->dev, "Deferred flush failed: %d\n", err);
|
||||
+ } else {
|
||||
+ anv->last_flush = jiffies;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int apple_nvme_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -1508,6 +1568,14 @@ static int apple_nvme_probe(struct platform_device *pdev)
|
||||
goto put_dev;
|
||||
}
|
||||
|
||||
+ if (flush_interval) {
|
||||
+ anv->flush_interval = msecs_to_jiffies(flush_interval);
|
||||
+ anv->flush_ns = NULL;
|
||||
+ anv->last_flush = jiffies - anv->flush_interval;
|
||||
+ }
|
||||
+
|
||||
+ INIT_DELAYED_WORK(&anv->flush_dwork, apple_nvme_flush_work);
|
||||
+
|
||||
nvme_reset_ctrl(&anv->ctrl);
|
||||
async_schedule(apple_nvme_async_probe, anv);
|
||||
|
||||
@@ -1541,6 +1609,7 @@ static void apple_nvme_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct apple_nvme *anv = platform_get_drvdata(pdev);
|
||||
|
||||
+ flush_delayed_work(&anv->flush_dwork);
|
||||
apple_nvme_disable(anv, true);
|
||||
if (apple_rtkit_is_running(anv->rtk))
|
||||
apple_rtkit_shutdown(anv->rtk);
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,25 @@
|
||||
From 17290bf07058d3b52c3a750be73831827af3f98d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Mon, 27 Jun 2022 21:47:43 +0900
|
||||
Subject: [PATCH 066/171] apple-nvme: Release power domains when probe fails
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/nvme/host/apple.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
|
||||
index 46294f99a1b0..67cef4dda24c 100644
|
||||
--- a/drivers/nvme/host/apple.c
|
||||
+++ b/drivers/nvme/host/apple.c
|
||||
@@ -1582,6 +1582,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
put_dev:
|
||||
+ apple_nvme_detach_genpd(anv);
|
||||
put_device(anv->dev);
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,39 @@
|
||||
From ef2e86f869f55da922fcb8235cd32ea78fe3e2b7 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 12 Dec 2021 12:28:41 +0900
|
||||
Subject: [PATCH 067/171] MAINTAINERS: Add apple-spi driver & binding files
|
||||
|
||||
This Apple SPI controller is present on Apple ARM SoCs (t8103/t6000).
|
||||
|
||||
Splitting this change from the binding/driver commits to avoid merge
|
||||
conflicts with other things touching this section, as usual.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
MAINTAINERS | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 64379c699903..629c1a177d3f 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -1843,6 +1843,8 @@ F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
|
||||
F: Documentation/devicetree/bindings/pci/apple,pcie.yaml
|
||||
F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
|
||||
F: Documentation/devicetree/bindings/power/apple*
|
||||
+F: Documentation/devicetree/bindings/spi/apple,spi.yaml
|
||||
+F: Documentation/devicetree/bindings/usb/apple,dwc3.yaml
|
||||
F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
|
||||
F: arch/arm64/boot/dts/apple/
|
||||
F: drivers/clk/clk-apple-nco.c
|
||||
@@ -1855,6 +1857,7 @@ F: drivers/nvme/host/apple.c
|
||||
F: drivers/nvmem/apple-efuses.c
|
||||
F: drivers/pinctrl/pinctrl-apple-gpio.c
|
||||
F: drivers/soc/apple/*
|
||||
+F: drivers/spi/spi-apple.c
|
||||
F: drivers/watchdog/apple_wdt.c
|
||||
F: include/dt-bindings/interrupt-controller/apple-aic.h
|
||||
F: include/dt-bindings/pinctrl/apple.h
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,88 @@
|
||||
From c26ea602ff1a0f7d01421320ed5bea2f611f73cd Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 12 Dec 2021 11:46:33 +0900
|
||||
Subject: [PATCH 068/171] dt-bindings: spi: apple,spi: Add binding for Apple
|
||||
SPI controllers
|
||||
|
||||
The Apple SPI controller is present in SoCs such as the M1 (t8103) and
|
||||
M1 Pro/Max (t600x). This controller uses one IRQ and one clock, and
|
||||
doesn't need any special properties, so the binding is trivial.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../devicetree/bindings/spi/apple,spi.yaml | 63 +++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/spi/apple,spi.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/spi/apple,spi.yaml b/Documentation/devicetree/bindings/spi/apple,spi.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..bcbdc8943e92
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/spi/apple,spi.yaml
|
||||
@@ -0,0 +1,63 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/spi/apple,spi.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Apple ARM SoC SPI controller
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: "spi-controller.yaml#"
|
||||
+
|
||||
+maintainers:
|
||||
+ - Hector Martin <marcan@marcan.st>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - apple,t8103-spi
|
||||
+ - apple,t6000-spi
|
||||
+ - const: apple,spi
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ power-domains:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - interrupts
|
||||
+ - '#address-cells'
|
||||
+ - '#size-cells'
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/interrupt-controller/apple-aic.h>
|
||||
+ #include <dt-bindings/interrupt-controller/irq.h>
|
||||
+
|
||||
+ soc {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ spi: spi@39b104000 {
|
||||
+ compatible = "apple,t6000-spi", "apple,spi";
|
||||
+ reg = <0x3 0x9b104000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 0 1107 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ clocks = <&clk>;
|
||||
+ };
|
||||
+ };
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,618 @@
|
||||
From 90521a1e8c3ebf5c2ee27d2e3f62bb81cf28e23f Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 9 Dec 2021 21:55:49 +0900
|
||||
Subject: [PATCH 069/171] spi: apple: Add driver for Apple SPI controller
|
||||
|
||||
This SPI controller is present in Apple SoCs such as the M1 (t8103) and
|
||||
M1 Pro/Max (t600x). It is a relatively straightforward design with two
|
||||
16-entry FIFOs, arbitrary transfer sizes (up to 2**32 - 1) and fully
|
||||
configurable word size up to 32 bits. It supports one hardware CS line
|
||||
which can also be driven via the pinctrl/GPIO driver instead, if
|
||||
desired. TX and RX can be independently enabled.
|
||||
|
||||
There are a surprising number of knobs for tweaking details of the
|
||||
transfer, most of which we do not use right now. Hardware CS control
|
||||
is available, but we haven't found a way to make it stay low across
|
||||
multiple logical transfers, so we just use software CS control for now.
|
||||
|
||||
There is also a shared DMA offload coprocessor that can be used to handle
|
||||
larger transfers without requiring an IRQ every 8-16 words, but that
|
||||
feature depends on a bunch of scaffolding that isn't ready to be
|
||||
upstreamed yet, so leave it for later.
|
||||
|
||||
The hardware shares some register bit definitions with spi-s3c24xx which
|
||||
suggests it has a shared legacy with Samsung SoCs, but it is too
|
||||
different to warrant sharing a driver.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/spi/Kconfig | 8 +
|
||||
drivers/spi/Makefile | 1 +
|
||||
drivers/spi/spi-apple.c | 544 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 553 insertions(+)
|
||||
create mode 100644 drivers/spi/spi-apple.c
|
||||
|
||||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
|
||||
index 3b1044ebc400..863e215a5127 100644
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -79,6 +79,14 @@ config SPI_ALTERA_DFL
|
||||
Altera SPI master controller. The SPI master is connected
|
||||
to a SPI slave to Avalon bridge in a Intel MAX BMC.
|
||||
|
||||
+config SPI_APPLE
|
||||
+ tristate "Apple SoC SPI Controller platform driver"
|
||||
+ depends on ARCH_APPLE || COMPILE_TEST
|
||||
+ help
|
||||
+ This enables support for the SPI controller present on
|
||||
+ many Apple SoCs, including the t8103 (M1) and t600x
|
||||
+ (M1 Pro/Max).
|
||||
+
|
||||
config SPI_AR934X
|
||||
tristate "Qualcomm Atheros AR934X/QCA95XX SPI controller driver"
|
||||
depends on ATH79 || COMPILE_TEST
|
||||
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
|
||||
index 0f44eb6083a5..f86ba8634f77 100644
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -17,6 +17,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o
|
||||
obj-$(CONFIG_SPI_ALTERA) += spi-altera-platform.o
|
||||
obj-$(CONFIG_SPI_ALTERA_CORE) += spi-altera-core.o
|
||||
obj-$(CONFIG_SPI_ALTERA_DFL) += spi-altera-dfl.o
|
||||
+obj-$(CONFIG_SPI_APPLE) += spi-apple.o
|
||||
obj-$(CONFIG_SPI_AR934X) += spi-ar934x.o
|
||||
obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o
|
||||
obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o
|
||||
diff --git a/drivers/spi/spi-apple.c b/drivers/spi/spi-apple.c
|
||||
new file mode 100644
|
||||
index 000000000000..c483ad3f69ef
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi-apple.c
|
||||
@@ -0,0 +1,544 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Apple SoC SPI device driver
|
||||
+ *
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ *
|
||||
+ * Based on spi-sifive.c, Copyright 2018 SiFive, Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/bits.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+
|
||||
+#define APPLE_SPI_CTRL 0x000
|
||||
+#define APPLE_SPI_CTRL_RUN BIT(0)
|
||||
+#define APPLE_SPI_CTRL_TX_RESET BIT(2)
|
||||
+#define APPLE_SPI_CTRL_RX_RESET BIT(3)
|
||||
+
|
||||
+#define APPLE_SPI_CFG 0x004
|
||||
+#define APPLE_SPI_CFG_CPHA BIT(1)
|
||||
+#define APPLE_SPI_CFG_CPOL BIT(2)
|
||||
+#define APPLE_SPI_CFG_MODE GENMASK(6, 5)
|
||||
+#define APPLE_SPI_CFG_MODE_POLLED 0
|
||||
+#define APPLE_SPI_CFG_MODE_IRQ 1
|
||||
+#define APPLE_SPI_CFG_MODE_DMA 2
|
||||
+#define APPLE_SPI_CFG_IE_RXCOMPLETE BIT(7)
|
||||
+#define APPLE_SPI_CFG_IE_TXRXTHRESH BIT(8)
|
||||
+#define APPLE_SPI_CFG_LSB_FIRST BIT(13)
|
||||
+#define APPLE_SPI_CFG_WORD_SIZE GENMASK(16, 15)
|
||||
+#define APPLE_SPI_CFG_WORD_SIZE_8B 0
|
||||
+#define APPLE_SPI_CFG_WORD_SIZE_16B 1
|
||||
+#define APPLE_SPI_CFG_WORD_SIZE_32B 2
|
||||
+#define APPLE_SPI_CFG_FIFO_THRESH GENMASK(18, 17)
|
||||
+#define APPLE_SPI_CFG_FIFO_THRESH_8B 0
|
||||
+#define APPLE_SPI_CFG_FIFO_THRESH_4B 1
|
||||
+#define APPLE_SPI_CFG_FIFO_THRESH_1B 2
|
||||
+#define APPLE_SPI_CFG_IE_TXCOMPLETE BIT(21)
|
||||
+
|
||||
+#define APPLE_SPI_STATUS 0x008
|
||||
+#define APPLE_SPI_STATUS_RXCOMPLETE BIT(0)
|
||||
+#define APPLE_SPI_STATUS_TXRXTHRESH BIT(1)
|
||||
+#define APPLE_SPI_STATUS_TXCOMPLETE BIT(2)
|
||||
+
|
||||
+#define APPLE_SPI_PIN 0x00c
|
||||
+#define APPLE_SPI_PIN_KEEP_MOSI BIT(0)
|
||||
+#define APPLE_SPI_PIN_CS BIT(1)
|
||||
+
|
||||
+#define APPLE_SPI_TXDATA 0x010
|
||||
+#define APPLE_SPI_RXDATA 0x020
|
||||
+#define APPLE_SPI_CLKDIV 0x030
|
||||
+#define APPLE_SPI_CLKDIV_MAX 0x7ff
|
||||
+#define APPLE_SPI_RXCNT 0x034
|
||||
+#define APPLE_SPI_WORD_DELAY 0x038
|
||||
+#define APPLE_SPI_TXCNT 0x04c
|
||||
+
|
||||
+#define APPLE_SPI_FIFOSTAT 0x10c
|
||||
+#define APPLE_SPI_FIFOSTAT_TXFULL BIT(4)
|
||||
+#define APPLE_SPI_FIFOSTAT_LEVEL_TX GENMASK(15, 8)
|
||||
+#define APPLE_SPI_FIFOSTAT_RXEMPTY BIT(20)
|
||||
+#define APPLE_SPI_FIFOSTAT_LEVEL_RX GENMASK(31, 24)
|
||||
+
|
||||
+#define APPLE_SPI_IE_XFER 0x130
|
||||
+#define APPLE_SPI_IF_XFER 0x134
|
||||
+#define APPLE_SPI_XFER_RXCOMPLETE BIT(0)
|
||||
+#define APPLE_SPI_XFER_TXCOMPLETE BIT(1)
|
||||
+
|
||||
+#define APPLE_SPI_IE_FIFO 0x138
|
||||
+#define APPLE_SPI_IF_FIFO 0x13c
|
||||
+#define APPLE_SPI_FIFO_RXTHRESH BIT(4)
|
||||
+#define APPLE_SPI_FIFO_TXTHRESH BIT(5)
|
||||
+#define APPLE_SPI_FIFO_RXFULL BIT(8)
|
||||
+#define APPLE_SPI_FIFO_TXEMPTY BIT(9)
|
||||
+#define APPLE_SPI_FIFO_RXUNDERRUN BIT(16)
|
||||
+#define APPLE_SPI_FIFO_TXOVERFLOW BIT(17)
|
||||
+
|
||||
+#define APPLE_SPI_SHIFTCFG 0x150
|
||||
+#define APPLE_SPI_SHIFTCFG_CLK_ENABLE BIT(0)
|
||||
+#define APPLE_SPI_SHIFTCFG_CS_ENABLE BIT(1)
|
||||
+#define APPLE_SPI_SHIFTCFG_AND_CLK_DATA BIT(8)
|
||||
+#define APPLE_SPI_SHIFTCFG_CS_AS_DATA BIT(9)
|
||||
+#define APPLE_SPI_SHIFTCFG_TX_ENABLE BIT(10)
|
||||
+#define APPLE_SPI_SHIFTCFG_RX_ENABLE BIT(11)
|
||||
+#define APPLE_SPI_SHIFTCFG_BITS GENMASK(21, 16)
|
||||
+#define APPLE_SPI_SHIFTCFG_OVERRIDE_CS BIT(24)
|
||||
+
|
||||
+#define APPLE_SPI_PINCFG 0x154
|
||||
+#define APPLE_SPI_PINCFG_KEEP_CLK BIT(0)
|
||||
+#define APPLE_SPI_PINCFG_KEEP_CS BIT(1)
|
||||
+#define APPLE_SPI_PINCFG_KEEP_MOSI BIT(2)
|
||||
+#define APPLE_SPI_PINCFG_CLK_IDLE_VAL BIT(8)
|
||||
+#define APPLE_SPI_PINCFG_CS_IDLE_VAL BIT(9)
|
||||
+#define APPLE_SPI_PINCFG_MOSI_IDLE_VAL BIT(10)
|
||||
+
|
||||
+#define APPLE_SPI_DELAY_PRE 0x160
|
||||
+#define APPLE_SPI_DELAY_POST 0x168
|
||||
+#define APPLE_SPI_DELAY_ENABLE BIT(0)
|
||||
+#define APPLE_SPI_DELAY_NO_INTERBYTE BIT(1)
|
||||
+#define APPLE_SPI_DELAY_SET_SCK BIT(4)
|
||||
+#define APPLE_SPI_DELAY_SET_MOSI BIT(6)
|
||||
+#define APPLE_SPI_DELAY_SCK_VAL BIT(8)
|
||||
+#define APPLE_SPI_DELAY_MOSI_VAL BIT(12)
|
||||
+
|
||||
+#define APPLE_SPI_FIFO_DEPTH 16
|
||||
+
|
||||
+/*
|
||||
+ * The slowest refclock available is 24MHz, the highest divider is 0x7ff,
|
||||
+ * the largest word size is 32 bits, the FIFO depth is 16, the maximum
|
||||
+ * intra-word delay is 0xffff refclocks. So the maximum time a transfer
|
||||
+ * cycle can take is:
|
||||
+ *
|
||||
+ * (0x7ff * 32 + 0xffff) * 16 / 24e6 Hz ~= 87ms
|
||||
+ *
|
||||
+ * Double it and round it up to 200ms for good measure.
|
||||
+ */
|
||||
+#define APPLE_SPI_TIMEOUT_MS 200
|
||||
+
|
||||
+struct apple_spi {
|
||||
+ void __iomem *regs; /* MMIO register address */
|
||||
+ struct clk *clk; /* bus clock */
|
||||
+ struct completion done; /* wake-up from interrupt */
|
||||
+};
|
||||
+
|
||||
+static inline void reg_write(struct apple_spi *spi, int offset, u32 value)
|
||||
+{
|
||||
+ writel_relaxed(value, spi->regs + offset);
|
||||
+}
|
||||
+
|
||||
+static inline u32 reg_read(struct apple_spi *spi, int offset)
|
||||
+{
|
||||
+ return readl_relaxed(spi->regs + offset);
|
||||
+}
|
||||
+
|
||||
+static inline void reg_mask(struct apple_spi *spi, int offset, u32 clear, u32 set)
|
||||
+{
|
||||
+ u32 val = reg_read(spi, offset);
|
||||
+
|
||||
+ val &= ~clear;
|
||||
+ val |= set;
|
||||
+ reg_write(spi, offset, val);
|
||||
+}
|
||||
+
|
||||
+static void apple_spi_init(struct apple_spi *spi)
|
||||
+{
|
||||
+ /* Set CS high (inactive) and disable override and auto-CS */
|
||||
+ reg_write(spi, APPLE_SPI_PIN, APPLE_SPI_PIN_CS);
|
||||
+ reg_mask(spi, APPLE_SPI_SHIFTCFG, APPLE_SPI_SHIFTCFG_OVERRIDE_CS, 0);
|
||||
+ reg_mask(spi, APPLE_SPI_PINCFG, APPLE_SPI_PINCFG_CS_IDLE_VAL, APPLE_SPI_PINCFG_KEEP_CS);
|
||||
+
|
||||
+ /* Reset FIFOs */
|
||||
+ reg_write(spi, APPLE_SPI_CTRL, APPLE_SPI_CTRL_RX_RESET | APPLE_SPI_CTRL_TX_RESET);
|
||||
+
|
||||
+ /* Configure defaults */
|
||||
+ reg_write(spi, APPLE_SPI_CFG,
|
||||
+ FIELD_PREP(APPLE_SPI_CFG_FIFO_THRESH, APPLE_SPI_CFG_FIFO_THRESH_8B) |
|
||||
+ FIELD_PREP(APPLE_SPI_CFG_MODE, APPLE_SPI_CFG_MODE_IRQ) |
|
||||
+ FIELD_PREP(APPLE_SPI_CFG_WORD_SIZE, APPLE_SPI_CFG_WORD_SIZE_8B));
|
||||
+
|
||||
+ /* Disable IRQs */
|
||||
+ reg_write(spi, APPLE_SPI_IE_FIFO, 0);
|
||||
+ reg_write(spi, APPLE_SPI_IE_XFER, 0);
|
||||
+
|
||||
+ /* Disable delays */
|
||||
+ reg_write(spi, APPLE_SPI_DELAY_PRE, 0);
|
||||
+ reg_write(spi, APPLE_SPI_DELAY_POST, 0);
|
||||
+}
|
||||
+
|
||||
+static int apple_spi_prepare_message(struct spi_controller *ctlr, struct spi_message *msg)
|
||||
+{
|
||||
+ struct apple_spi *spi = spi_controller_get_devdata(ctlr);
|
||||
+ struct spi_device *device = msg->spi;
|
||||
+
|
||||
+ u32 cfg = ((device->mode & SPI_CPHA ? APPLE_SPI_CFG_CPHA : 0) |
|
||||
+ (device->mode & SPI_CPOL ? APPLE_SPI_CFG_CPOL : 0) |
|
||||
+ (device->mode & SPI_LSB_FIRST ? APPLE_SPI_CFG_LSB_FIRST : 0));
|
||||
+
|
||||
+ /* Update core config */
|
||||
+ reg_mask(spi, APPLE_SPI_CFG,
|
||||
+ APPLE_SPI_CFG_CPHA | APPLE_SPI_CFG_CPOL | APPLE_SPI_CFG_LSB_FIRST, cfg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void apple_spi_set_cs(struct spi_device *device, bool is_high)
|
||||
+{
|
||||
+ struct apple_spi *spi = spi_controller_get_devdata(device->controller);
|
||||
+
|
||||
+ reg_mask(spi, APPLE_SPI_PIN, APPLE_SPI_PIN_CS, is_high ? APPLE_SPI_PIN_CS : 0);
|
||||
+}
|
||||
+
|
||||
+static bool apple_spi_prep_transfer(struct apple_spi *spi, struct spi_transfer *t)
|
||||
+{
|
||||
+ u32 cr, fifo_threshold;
|
||||
+
|
||||
+ /* Calculate and program the clock rate */
|
||||
+ cr = DIV_ROUND_UP(clk_get_rate(spi->clk), t->speed_hz);
|
||||
+ reg_write(spi, APPLE_SPI_CLKDIV, min_t(u32, cr, APPLE_SPI_CLKDIV_MAX));
|
||||
+
|
||||
+ /* Update bits per word */
|
||||
+ reg_mask(spi, APPLE_SPI_SHIFTCFG, APPLE_SPI_SHIFTCFG_BITS,
|
||||
+ FIELD_PREP(APPLE_SPI_SHIFTCFG_BITS, t->bits_per_word));
|
||||
+
|
||||
+ /* We will want to poll if the time we need to wait is
|
||||
+ * less than the context switching time.
|
||||
+ * Let's call that threshold 5us. The operation will take:
|
||||
+ * bits_per_word * fifo_threshold / hz <= 5 * 10^-6
|
||||
+ * 200000 * bits_per_word * fifo_threshold <= hz
|
||||
+ */
|
||||
+ fifo_threshold = APPLE_SPI_FIFO_DEPTH / 2;
|
||||
+ return (200000 * t->bits_per_word * fifo_threshold) <= t->speed_hz;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t apple_spi_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct apple_spi *spi = dev_id;
|
||||
+ u32 fifo = reg_read(spi, APPLE_SPI_IF_FIFO) & reg_read(spi, APPLE_SPI_IE_FIFO);
|
||||
+ u32 xfer = reg_read(spi, APPLE_SPI_IF_XFER) & reg_read(spi, APPLE_SPI_IE_XFER);
|
||||
+
|
||||
+ if (fifo || xfer) {
|
||||
+ /* Disable interrupts until next transfer */
|
||||
+ reg_write(spi, APPLE_SPI_IE_XFER, 0);
|
||||
+ reg_write(spi, APPLE_SPI_IE_FIFO, 0);
|
||||
+ complete(&spi->done);
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_NONE;
|
||||
+}
|
||||
+
|
||||
+static int apple_spi_wait(struct apple_spi *spi, u32 fifo_bit, u32 xfer_bit, int poll)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (poll) {
|
||||
+ u32 fifo, xfer;
|
||||
+ unsigned long timeout = jiffies + APPLE_SPI_TIMEOUT_MS * HZ / 1000;
|
||||
+
|
||||
+ do {
|
||||
+ fifo = reg_read(spi, APPLE_SPI_IF_FIFO);
|
||||
+ xfer = reg_read(spi, APPLE_SPI_IF_XFER);
|
||||
+ if (time_after(jiffies, timeout)) {
|
||||
+ ret = -ETIMEDOUT;
|
||||
+ break;
|
||||
+ }
|
||||
+ } while (!((fifo & fifo_bit) || (xfer & xfer_bit)));
|
||||
+ } else {
|
||||
+ reinit_completion(&spi->done);
|
||||
+ reg_write(spi, APPLE_SPI_IE_XFER, xfer_bit);
|
||||
+ reg_write(spi, APPLE_SPI_IE_FIFO, fifo_bit);
|
||||
+
|
||||
+ if (!wait_for_completion_timeout(&spi->done,
|
||||
+ msecs_to_jiffies(APPLE_SPI_TIMEOUT_MS)))
|
||||
+ ret = -ETIMEDOUT;
|
||||
+
|
||||
+ reg_write(spi, APPLE_SPI_IE_XFER, 0);
|
||||
+ reg_write(spi, APPLE_SPI_IE_FIFO, 0);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void apple_spi_tx(struct apple_spi *spi, const void **tx_ptr, u32 *left,
|
||||
+ unsigned int bytes_per_word)
|
||||
+{
|
||||
+ u32 inuse, words, wrote;
|
||||
+
|
||||
+ if (!*tx_ptr)
|
||||
+ return;
|
||||
+
|
||||
+ inuse = FIELD_GET(APPLE_SPI_FIFOSTAT_LEVEL_TX, reg_read(spi, APPLE_SPI_FIFOSTAT));
|
||||
+ words = wrote = min_t(u32, *left, APPLE_SPI_FIFO_DEPTH - inuse);
|
||||
+
|
||||
+ if (!words)
|
||||
+ return;
|
||||
+
|
||||
+ *left -= words;
|
||||
+
|
||||
+ switch (bytes_per_word) {
|
||||
+ case 1: {
|
||||
+ const u8 *p = *tx_ptr;
|
||||
+
|
||||
+ while (words--)
|
||||
+ reg_write(spi, APPLE_SPI_TXDATA, *p++);
|
||||
+ break;
|
||||
+ }
|
||||
+ case 2: {
|
||||
+ const u16 *p = *tx_ptr;
|
||||
+
|
||||
+ while (words--)
|
||||
+ reg_write(spi, APPLE_SPI_TXDATA, *p++);
|
||||
+ break;
|
||||
+ }
|
||||
+ case 4: {
|
||||
+ const u32 *p = *tx_ptr;
|
||||
+
|
||||
+ while (words--)
|
||||
+ reg_write(spi, APPLE_SPI_TXDATA, *p++);
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ WARN_ON(1);
|
||||
+ }
|
||||
+
|
||||
+ *tx_ptr = ((u8 *)*tx_ptr) + bytes_per_word * wrote;
|
||||
+}
|
||||
+
|
||||
+static void apple_spi_rx(struct apple_spi *spi, void **rx_ptr, u32 *left,
|
||||
+ unsigned int bytes_per_word)
|
||||
+{
|
||||
+ u32 words, read;
|
||||
+
|
||||
+ if (!*rx_ptr)
|
||||
+ return;
|
||||
+
|
||||
+ words = read = FIELD_GET(APPLE_SPI_FIFOSTAT_LEVEL_RX, reg_read(spi, APPLE_SPI_FIFOSTAT));
|
||||
+ WARN_ON(words > *left);
|
||||
+
|
||||
+ if (!words)
|
||||
+ return;
|
||||
+
|
||||
+ *left -= min_t(u32, *left, words);
|
||||
+
|
||||
+ switch (bytes_per_word) {
|
||||
+ case 1: {
|
||||
+ u8 *p = *rx_ptr;
|
||||
+
|
||||
+ while (words--)
|
||||
+ *p++ = reg_read(spi, APPLE_SPI_RXDATA);
|
||||
+ break;
|
||||
+ }
|
||||
+ case 2: {
|
||||
+ u16 *p = *rx_ptr;
|
||||
+
|
||||
+ while (words--)
|
||||
+ *p++ = reg_read(spi, APPLE_SPI_RXDATA);
|
||||
+ break;
|
||||
+ }
|
||||
+ case 4: {
|
||||
+ u32 *p = *rx_ptr;
|
||||
+
|
||||
+ while (words--)
|
||||
+ *p++ = reg_read(spi, APPLE_SPI_RXDATA);
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ WARN_ON(1);
|
||||
+ }
|
||||
+
|
||||
+ *rx_ptr = ((u8 *)*rx_ptr) + bytes_per_word * read;
|
||||
+}
|
||||
+
|
||||
+static int apple_spi_transfer_one(struct spi_controller *ctlr, struct spi_device *device,
|
||||
+ struct spi_transfer *t)
|
||||
+{
|
||||
+ struct apple_spi *spi = spi_controller_get_devdata(ctlr);
|
||||
+ bool poll = apple_spi_prep_transfer(spi, t);
|
||||
+ const void *tx_ptr = t->tx_buf;
|
||||
+ void *rx_ptr = t->rx_buf;
|
||||
+ unsigned int bytes_per_word;
|
||||
+ u32 words, remaining_tx, remaining_rx;
|
||||
+ u32 xfer_flags = 0;
|
||||
+ u32 fifo_flags;
|
||||
+ int retries = 100;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (t->bits_per_word > 16)
|
||||
+ bytes_per_word = 4;
|
||||
+ else if (t->bits_per_word > 8)
|
||||
+ bytes_per_word = 2;
|
||||
+ else
|
||||
+ bytes_per_word = 1;
|
||||
+
|
||||
+ words = t->len / bytes_per_word;
|
||||
+ remaining_tx = tx_ptr ? words : 0;
|
||||
+ remaining_rx = rx_ptr ? words : 0;
|
||||
+
|
||||
+ /* Reset FIFOs */
|
||||
+ reg_write(spi, APPLE_SPI_CTRL, APPLE_SPI_CTRL_RX_RESET | APPLE_SPI_CTRL_TX_RESET);
|
||||
+
|
||||
+ /* Clear IRQ flags */
|
||||
+ reg_write(spi, APPLE_SPI_IF_XFER, ~0);
|
||||
+ reg_write(spi, APPLE_SPI_IF_FIFO, ~0);
|
||||
+
|
||||
+ /* Determine transfer completion flags we wait for */
|
||||
+ if (tx_ptr)
|
||||
+ xfer_flags |= APPLE_SPI_XFER_TXCOMPLETE;
|
||||
+ if (rx_ptr)
|
||||
+ xfer_flags |= APPLE_SPI_XFER_RXCOMPLETE;
|
||||
+
|
||||
+ /* Set transfer length */
|
||||
+ reg_write(spi, APPLE_SPI_TXCNT, remaining_tx);
|
||||
+ reg_write(spi, APPLE_SPI_RXCNT, remaining_rx);
|
||||
+
|
||||
+ /* Prime transmit FIFO */
|
||||
+ apple_spi_tx(spi, &tx_ptr, &remaining_tx, bytes_per_word);
|
||||
+
|
||||
+ /* Start transfer */
|
||||
+ reg_write(spi, APPLE_SPI_CTRL, APPLE_SPI_CTRL_RUN);
|
||||
+
|
||||
+ /* TX again since a few words get popped off immediately */
|
||||
+ apple_spi_tx(spi, &tx_ptr, &remaining_tx, bytes_per_word);
|
||||
+
|
||||
+ while (xfer_flags) {
|
||||
+ fifo_flags = 0;
|
||||
+
|
||||
+ if (remaining_tx)
|
||||
+ fifo_flags |= APPLE_SPI_FIFO_TXTHRESH;
|
||||
+ if (remaining_rx)
|
||||
+ fifo_flags |= APPLE_SPI_FIFO_RXTHRESH;
|
||||
+
|
||||
+ /* Wait for anything to happen */
|
||||
+ ret = apple_spi_wait(spi, fifo_flags, xfer_flags, poll);
|
||||
+ if (ret) {
|
||||
+ dev_err(&ctlr->dev, "transfer timed out (remaining %d tx, %d rx)\n",
|
||||
+ remaining_tx, remaining_rx);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ /* Stop waiting on transfer halves once they complete */
|
||||
+ xfer_flags &= ~reg_read(spi, APPLE_SPI_IF_XFER);
|
||||
+
|
||||
+ /* Transmit and receive everything we can */
|
||||
+ apple_spi_tx(spi, &tx_ptr, &remaining_tx, bytes_per_word);
|
||||
+ apple_spi_rx(spi, &rx_ptr, &remaining_rx, bytes_per_word);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Sometimes the transfer completes before the last word is in the RX FIFO.
|
||||
+ * Normally one retry is all it takes to get the last word out.
|
||||
+ */
|
||||
+ while (remaining_rx && retries--)
|
||||
+ apple_spi_rx(spi, &rx_ptr, &remaining_rx, bytes_per_word);
|
||||
+
|
||||
+ if (remaining_tx)
|
||||
+ dev_err(&ctlr->dev, "transfer completed with %d words left to transmit\n",
|
||||
+ remaining_tx);
|
||||
+ if (remaining_rx)
|
||||
+ dev_err(&ctlr->dev, "transfer completed with %d words left to receive\n",
|
||||
+ remaining_rx);
|
||||
+
|
||||
+err:
|
||||
+ fifo_flags = reg_read(spi, APPLE_SPI_IF_FIFO);
|
||||
+ WARN_ON(fifo_flags & APPLE_SPI_FIFO_TXOVERFLOW);
|
||||
+ WARN_ON(fifo_flags & APPLE_SPI_FIFO_RXUNDERRUN);
|
||||
+
|
||||
+ /* Stop transfer */
|
||||
+ reg_write(spi, APPLE_SPI_CTRL, 0);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void apple_spi_clk_disable_unprepare(void *data)
|
||||
+{
|
||||
+ clk_disable_unprepare(data);
|
||||
+}
|
||||
+
|
||||
+static int apple_spi_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct apple_spi *spi;
|
||||
+ int ret, irq;
|
||||
+ struct spi_controller *ctlr;
|
||||
+
|
||||
+ ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(struct apple_spi));
|
||||
+ if (!ctlr)
|
||||
+ return dev_err_probe(&pdev->dev, -ENOMEM, "out of memory\n");
|
||||
+
|
||||
+ spi = spi_controller_get_devdata(ctlr);
|
||||
+ init_completion(&spi->done);
|
||||
+ platform_set_drvdata(pdev, ctlr);
|
||||
+
|
||||
+ spi->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(spi->regs))
|
||||
+ return PTR_ERR(spi->regs);
|
||||
+
|
||||
+ spi->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(spi->clk))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(spi->clk), "Unable to find bus clock\n");
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0) {
|
||||
+ return irq;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, irq, apple_spi_irq, 0,
|
||||
+ dev_name(&pdev->dev), spi);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "Unable to bind to interrupt\n");
|
||||
+
|
||||
+ ret = clk_prepare_enable(spi->clk);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "Unable to enable bus clock\n");
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(&pdev->dev, apple_spi_clk_disable_unprepare, spi->clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ctlr->dev.of_node = pdev->dev.of_node;
|
||||
+ ctlr->bus_num = pdev->id;
|
||||
+ ctlr->num_chipselect = 1;
|
||||
+ ctlr->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST;
|
||||
+ ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
|
||||
+ ctlr->flags = 0;
|
||||
+ ctlr->prepare_message = apple_spi_prepare_message;
|
||||
+ ctlr->set_cs = apple_spi_set_cs;
|
||||
+ ctlr->transfer_one = apple_spi_transfer_one;
|
||||
+ ctlr->auto_runtime_pm = true;
|
||||
+
|
||||
+ pm_runtime_set_active(&pdev->dev);
|
||||
+ devm_pm_runtime_enable(&pdev->dev);
|
||||
+
|
||||
+ apple_spi_init(spi);
|
||||
+
|
||||
+ ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
+ if (ret < 0)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "devm_spi_register_controller failed\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id apple_spi_of_match[] = {
|
||||
+ { .compatible = "apple,spi", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, apple_spi_of_match);
|
||||
+
|
||||
+static struct platform_driver apple_spi_driver = {
|
||||
+ .probe = apple_spi_probe,
|
||||
+ .driver = {
|
||||
+ .name = "apple-spi",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = apple_spi_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(apple_spi_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
|
||||
+MODULE_DESCRIPTION("Apple SoC SPI driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,93 @@
|
||||
From c67e6dd3d9c5590394faf5138021ba7ebe306343 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:50:39 +0100
|
||||
Subject: [PATCH 070/171] dt-bindings: dma: Add apple,admac binding
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The Audio DMA Controller (ADMAC) is used to load and store audio
|
||||
samples from/to system memory. It is present on Apple SoCs from
|
||||
the "Apple Silicon" family.
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
.../devicetree/bindings/dma/apple,admac.yaml | 65 +++++++++++++++++++
|
||||
1 file changed, 65 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/dma/apple,admac.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/dma/apple,admac.yaml b/Documentation/devicetree/bindings/dma/apple,admac.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..34ede3b0de2c
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/dma/apple,admac.yaml
|
||||
@@ -0,0 +1,65 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/dma/apple,admac.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Apple Audio DMA Controller (ADMAC)
|
||||
+
|
||||
+description: |
|
||||
+ The Audio DMA Controller (ADMAC) is used to load and store audio
|
||||
+ samples from/to system memory. It is present on Apple SoCs
|
||||
+ from the "Apple Silicon" family.
|
||||
+
|
||||
+maintainers:
|
||||
+ - Martin Povišer <povik@protonmail.com>
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: "dma-controller.yaml#"
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ items:
|
||||
+ - const: apple,t8103-admac
|
||||
+ - const: apple,admac
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ '#dma-cells':
|
||||
+ const: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - interrupts
|
||||
+ - '#dma-cells'
|
||||
+ - dma-channels
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/interrupt-controller/apple-aic.h>
|
||||
+ #include <dt-bindings/interrupt-controller/irq.h>
|
||||
+
|
||||
+ dart_sio: iommu@235004000 {
|
||||
+ compatible = "apple,t8103-dart", "apple,dart";
|
||||
+ reg = <0x2 0x35004000 0x0 0x4000>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 635 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #iommu-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ admac: dma-controller@238200000 {
|
||||
+ compatible = "apple,t8103-admac", "apple,admac";
|
||||
+ reg = <0x2 0x38200000 0x0 0x34000>;
|
||||
+ dma-channels = <12>;
|
||||
+ interrupt-parent = <&aic>;
|
||||
+ interrupts = <AIC_IRQ 626 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ #dma-cells = <1>;
|
||||
+ iommus = <&dart_sio 2>;
|
||||
+ };
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,806 @@
|
||||
From 594ea25c7f3f1ee8d0e952c6547bcd06843f9045 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:49:23 +0100
|
||||
Subject: [PATCH 071/171] dmaengine: apple-admac: Add Apple ADMAC driver
|
||||
|
||||
Add driver for Audio DMA Controller present on Apple SoCs
|
||||
from the "Apple Silicon" family.
|
||||
---
|
||||
drivers/dma/Kconfig | 8 +
|
||||
drivers/dma/Makefile | 1 +
|
||||
drivers/dma/apple-admac.c | 752 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 761 insertions(+)
|
||||
create mode 100644 drivers/dma/apple-admac.c
|
||||
|
||||
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
|
||||
index 487ed4ddc3be..bda78b8172d4 100644
|
||||
--- a/drivers/dma/Kconfig
|
||||
+++ b/drivers/dma/Kconfig
|
||||
@@ -85,6 +85,14 @@ config AMCC_PPC440SPE_ADMA
|
||||
help
|
||||
Enable support for the AMCC PPC440SPe RAID engines.
|
||||
|
||||
+config APPLE_ADMAC
|
||||
+ tristate "Apple ADMAC support"
|
||||
+ depends on ARCH_APPLE || COMPILE_TEST
|
||||
+ select DMA_ENGINE
|
||||
+ default ARCH_APPLE
|
||||
+ help
|
||||
+ Enable support for Audio DMA Controller found on Apple Silicon chips.
|
||||
+
|
||||
config AT_HDMAC
|
||||
tristate "Atmel AHB DMA support"
|
||||
depends on ARCH_AT91
|
||||
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
|
||||
index 2f1b87ffd7ab..10f7d4241001 100644
|
||||
--- a/drivers/dma/Makefile
|
||||
+++ b/drivers/dma/Makefile
|
||||
@@ -17,6 +17,7 @@ obj-$(CONFIG_ALTERA_MSGDMA) += altera-msgdma.o
|
||||
obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
|
||||
obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
|
||||
obj-$(CONFIG_AMD_PTDMA) += ptdma/
|
||||
+obj-$(CONFIG_APPLE_ADMAC) += apple-admac.o
|
||||
obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
|
||||
obj-$(CONFIG_AT_XDMAC) += at_xdmac.o
|
||||
obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o
|
||||
diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
|
||||
new file mode 100644
|
||||
index 000000000000..aa4c07bcb72a
|
||||
--- /dev/null
|
||||
+++ b/drivers/dma/apple-admac.c
|
||||
@@ -0,0 +1,752 @@
|
||||
+#include <linux/bits.h>
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/of_dma.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+
|
||||
+#include "dmaengine.h"
|
||||
+
|
||||
+#define NCHANNELS_MAX 64
|
||||
+
|
||||
+#define RING_WRITE_SLOT GENMASK(1, 0)
|
||||
+#define RING_READ_SLOT GENMASK(5, 4)
|
||||
+#define RING_FULL BIT(9)
|
||||
+#define RING_EMPTY BIT(8)
|
||||
+#define RING_ERR BIT(10)
|
||||
+
|
||||
+#define STATUS_DESC_DONE BIT(0)
|
||||
+#define STATUS_ERR BIT(6)
|
||||
+
|
||||
+#define FLAG_DESC_NOTIFY BIT(16)
|
||||
+
|
||||
+#define REG_TX_START 0x0000
|
||||
+#define REG_TX_STOP 0x0004
|
||||
+#define REG_RX_START 0x0008
|
||||
+#define REG_RX_STOP 0x000c
|
||||
+
|
||||
+#define REG_CHAN_CTL(ch) (0x8000 + (ch)*0x200)
|
||||
+#define REG_CHAN_CTL_RST_RINGS BIT(0)
|
||||
+
|
||||
+#define REG_DESC_RING(ch) (0x8070 + (ch)*0x200)
|
||||
+#define REG_REPORT_RING(ch) (0x8074 + (ch)*0x200)
|
||||
+
|
||||
+#define REG_RESIDUE(ch) (0x8064 + (ch)*0x200)
|
||||
+
|
||||
+#define REG_BUS_WIDTH(ch) (0x8040 + (ch)*0x200)
|
||||
+
|
||||
+#define BUS_WIDTH_8BIT 0x00
|
||||
+#define BUS_WIDTH_16BIT 0x01
|
||||
+#define BUS_WIDTH_32BIT 0x02
|
||||
+#define BUS_WIDTH_FRAME_2_WORDS 0x10
|
||||
+#define BUS_WIDTH_FRAME_4_WORDS 0x20
|
||||
+
|
||||
+#define REG_CHAN_BURSTSIZE(ch) (0x8054 + (ch)*0x200)
|
||||
+
|
||||
+#define REG_DESC_WRITE(ch) (0x10000 + (ch / 2) * 0x4 + (ch & 1) * 0x4000)
|
||||
+#define REG_REPORT_READ(ch) (0x10100 + (ch / 2) * 0x4 + (ch & 1) * 0x4000)
|
||||
+
|
||||
+#define IRQ_INDEX_MAX 3
|
||||
+
|
||||
+#define REG_TX_INTSTATE(idx) (0x0030 + (idx) * 4)
|
||||
+#define REG_RX_INTSTATE(idx) (0x0040 + (idx) * 4)
|
||||
+#define REG_CHAN_INTSTATUS(ch,idx) (0x8010 + (ch) * 0x200 + (idx) * 4)
|
||||
+#define REG_CHAN_INTMASK(ch,idx) (0x8020 + (ch) * 0x200 + (idx) * 4)
|
||||
+
|
||||
+struct admac_data;
|
||||
+struct admac_tx;
|
||||
+
|
||||
+struct admac_chan {
|
||||
+ int no;
|
||||
+ struct admac_data *host;
|
||||
+ struct dma_chan chan;
|
||||
+ struct tasklet_struct tasklet;
|
||||
+
|
||||
+ spinlock_t lock;
|
||||
+ struct admac_tx *current_tx;
|
||||
+ int nperiod_acks;
|
||||
+
|
||||
+ struct list_head submitted;
|
||||
+ struct list_head issued;
|
||||
+};
|
||||
+
|
||||
+struct admac_data {
|
||||
+ struct dma_device dma;
|
||||
+ struct device *dev;
|
||||
+ __iomem void *base;
|
||||
+
|
||||
+ int irq_index;
|
||||
+ int nchannels;
|
||||
+ struct admac_chan channels[];
|
||||
+};
|
||||
+
|
||||
+struct admac_tx {
|
||||
+ struct dma_async_tx_descriptor tx;
|
||||
+ bool cyclic;
|
||||
+ dma_addr_t buf_addr;
|
||||
+ dma_addr_t buf_end;
|
||||
+ size_t buf_len;
|
||||
+ size_t period_len;
|
||||
+
|
||||
+ size_t submitted_pos;
|
||||
+ size_t reclaimed_pos;
|
||||
+
|
||||
+ struct list_head node;
|
||||
+};
|
||||
+
|
||||
+static void admac_poke(struct admac_data *ad, int reg, u32 val)
|
||||
+{
|
||||
+ writel_relaxed(val, ad->base + reg);
|
||||
+}
|
||||
+
|
||||
+static u32 admac_peek(struct admac_data *ad, int reg)
|
||||
+{
|
||||
+ return readl_relaxed(ad->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void admac_modify(struct admac_data *ad, int reg, u32 mask, u32 val)
|
||||
+{
|
||||
+ void __iomem *addr = ad->base + reg;
|
||||
+ u32 curr = readl_relaxed(addr);
|
||||
+
|
||||
+ writel_relaxed((curr & ~mask) | (val & mask), addr);
|
||||
+}
|
||||
+
|
||||
+static struct admac_chan *to_admac_chan(struct dma_chan *chan)
|
||||
+{
|
||||
+ return container_of(chan, struct admac_chan, chan);
|
||||
+}
|
||||
+
|
||||
+static struct admac_tx *to_admac_tx(struct dma_async_tx_descriptor *tx)
|
||||
+{
|
||||
+ return container_of(tx, struct admac_tx, tx);
|
||||
+}
|
||||
+
|
||||
+static enum dma_transfer_direction admac_chan_direction(int channo)
|
||||
+{
|
||||
+ return (channo & 1) ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
|
||||
+}
|
||||
+
|
||||
+static dma_cookie_t admac_tx_submit(struct dma_async_tx_descriptor *tx)
|
||||
+{
|
||||
+ struct admac_tx *adtx = to_admac_tx(tx);
|
||||
+ struct admac_chan *adchan = to_admac_chan(tx->chan);
|
||||
+ unsigned long flags;
|
||||
+ dma_cookie_t cookie;
|
||||
+
|
||||
+ spin_lock_irqsave(&adchan->lock, flags);
|
||||
+ cookie = dma_cookie_assign(tx);
|
||||
+ list_add_tail(&adtx->node, &adchan->submitted);
|
||||
+ spin_unlock_irqrestore(&adchan->lock, flags);
|
||||
+
|
||||
+ return cookie;
|
||||
+}
|
||||
+
|
||||
+static int admac_desc_free(struct dma_async_tx_descriptor *tx)
|
||||
+{
|
||||
+ struct admac_tx *adtx = to_admac_tx(tx);
|
||||
+ devm_kfree(to_admac_chan(tx->chan)->host->dev, adtx);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct dma_async_tx_descriptor *admac_prep_dma_cyclic(
|
||||
+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
|
||||
+ size_t period_len, enum dma_transfer_direction direction,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct admac_chan *adchan = container_of(chan, struct admac_chan, chan);
|
||||
+ struct admac_tx *adtx;
|
||||
+
|
||||
+ if (direction != admac_chan_direction(adchan->no))
|
||||
+ return NULL;
|
||||
+
|
||||
+ adtx = devm_kzalloc(adchan->host->dev, sizeof(*adtx), GFP_NOWAIT);
|
||||
+ if (!adtx)
|
||||
+ return NULL;
|
||||
+
|
||||
+ adtx->cyclic = true;
|
||||
+
|
||||
+ adtx->buf_addr = buf_addr;
|
||||
+ adtx->buf_len = buf_len;
|
||||
+ adtx->buf_end = buf_addr + buf_len;
|
||||
+ adtx->period_len = period_len;
|
||||
+
|
||||
+ adtx->submitted_pos = 0;
|
||||
+ adtx->reclaimed_pos = 0;
|
||||
+
|
||||
+ dma_async_tx_descriptor_init(&adtx->tx, chan);
|
||||
+ adtx->tx.tx_submit = admac_tx_submit;
|
||||
+ adtx->tx.desc_free = admac_desc_free;
|
||||
+
|
||||
+ return &adtx->tx;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Write one hardware descriptor for a dmaegine cyclic transaction.
|
||||
+ */
|
||||
+static void admac_cyclic_write_one_desc(struct admac_data *ad, int channo,
|
||||
+ struct admac_tx *tx)
|
||||
+{
|
||||
+ dma_addr_t addr;
|
||||
+
|
||||
+ if (WARN_ON(!tx->cyclic))
|
||||
+ return;
|
||||
+
|
||||
+ addr = tx->buf_addr + (tx->submitted_pos % tx->buf_len);
|
||||
+ WARN_ON(addr + tx->period_len > tx->buf_end);
|
||||
+
|
||||
+ dev_dbg(ad->dev, "ch%d descriptor: addr=0x%llx len=0x%x flags=0x%lx\n",
|
||||
+ channo, addr, (u32) tx->period_len, FLAG_DESC_NOTIFY);
|
||||
+
|
||||
+ admac_poke(ad, REG_DESC_WRITE(channo), addr);
|
||||
+ admac_poke(ad, REG_DESC_WRITE(channo), addr >> 32);
|
||||
+ admac_poke(ad, REG_DESC_WRITE(channo), tx->period_len);
|
||||
+ admac_poke(ad, REG_DESC_WRITE(channo), FLAG_DESC_NOTIFY);
|
||||
+
|
||||
+ tx->submitted_pos += tx->period_len;
|
||||
+ tx->submitted_pos %= 2 * tx->buf_len;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Write all the hardware descriptors for a cyclic transaction
|
||||
+ * there is space for.
|
||||
+ */
|
||||
+static void admac_cyclic_write_desc(struct admac_data *ad, int channo,
|
||||
+ struct admac_tx *tx)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 4; i++) {
|
||||
+ if (admac_peek(ad, REG_DESC_RING(channo)) & RING_FULL)
|
||||
+ break;
|
||||
+ admac_cyclic_write_one_desc(ad, channo, tx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int admac_alloc_chan_resources(struct dma_chan *chan)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void admac_free_chan_resources(struct dma_chan *chan)
|
||||
+{
|
||||
+ // TODO
|
||||
+}
|
||||
+
|
||||
+static int admac_ring_noccupied_slots(int ringval)
|
||||
+{
|
||||
+ int wrslot = FIELD_GET(RING_WRITE_SLOT, ringval);
|
||||
+ int rdslot = FIELD_GET(RING_READ_SLOT, ringval);
|
||||
+
|
||||
+ if (wrslot != rdslot) {
|
||||
+ return (wrslot + 4 - rdslot) % 4;
|
||||
+ } else {
|
||||
+ WARN_ON((ringval & (RING_FULL | RING_EMPTY)) == 0);
|
||||
+
|
||||
+ if (ringval & RING_FULL)
|
||||
+ return 4;
|
||||
+ else
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Read from hardware the residue of a cyclic dmaengine transaction.
|
||||
+ */
|
||||
+u32 admac_cyclic_read_residue(struct admac_data *ad, int channo, struct admac_tx *adtx)
|
||||
+{
|
||||
+ u32 ring1, ring2;
|
||||
+ u32 residue1, residue2;
|
||||
+ int nreports;
|
||||
+ size_t pos;
|
||||
+
|
||||
+ ring1 = admac_peek(ad, REG_REPORT_RING(channo));
|
||||
+ residue1 = admac_peek(ad, REG_RESIDUE(channo));
|
||||
+ ring2 = admac_peek(ad, REG_REPORT_RING(channo));
|
||||
+ residue2 = admac_peek(ad, REG_RESIDUE(channo));
|
||||
+
|
||||
+ if (residue2 > residue1) {
|
||||
+ // engine must have loaded next descriptor between the two residue reads
|
||||
+ nreports = admac_ring_noccupied_slots(ring1) + 1;
|
||||
+ } else {
|
||||
+ // no descriptor load between the two reads, ring2 is safe to use
|
||||
+ nreports = admac_ring_noccupied_slots(ring2);
|
||||
+ }
|
||||
+
|
||||
+ pos = adtx->reclaimed_pos + adtx->period_len * (nreports + 1) \
|
||||
+ - residue2;
|
||||
+
|
||||
+ return adtx->buf_len - pos % adtx->buf_len;
|
||||
+}
|
||||
+
|
||||
+static enum dma_status admac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
||||
+ struct dma_tx_state *txstate)
|
||||
+{
|
||||
+ struct admac_chan *adchan = to_admac_chan(chan);
|
||||
+ struct admac_data *ad = adchan->host;
|
||||
+ struct admac_tx *adtx;
|
||||
+
|
||||
+ enum dma_status ret;
|
||||
+ size_t residue;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ ret = dma_cookie_status(chan, cookie, txstate);
|
||||
+ if (ret == DMA_COMPLETE || !txstate)
|
||||
+ return ret;
|
||||
+
|
||||
+ spin_lock_irqsave(&adchan->lock, flags);
|
||||
+ adtx = adchan->current_tx;
|
||||
+
|
||||
+ if (adtx && adtx->tx.cookie == cookie) {
|
||||
+ ret = DMA_IN_PROGRESS;
|
||||
+ residue = admac_cyclic_read_residue(ad, adchan->no, adtx);
|
||||
+ } else {
|
||||
+ ret = DMA_IN_PROGRESS;
|
||||
+ residue = 0;
|
||||
+ list_for_each_entry(adtx, &adchan->issued, node) {
|
||||
+ if (adtx->tx.cookie == cookie) {
|
||||
+ residue = adtx->buf_len;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&adchan->lock, flags);
|
||||
+
|
||||
+ dma_set_residue(txstate, residue);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void admac_start_chan(struct admac_chan *adchan)
|
||||
+{
|
||||
+ u32 startbit = 1 << (adchan->no / 2);
|
||||
+ switch (admac_chan_direction(adchan->no)) {
|
||||
+ case DMA_MEM_TO_DEV:
|
||||
+ admac_poke(adchan->host, REG_TX_START, startbit);
|
||||
+ break;
|
||||
+ case DMA_DEV_TO_MEM:
|
||||
+ admac_poke(adchan->host, REG_RX_START, startbit);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ dev_dbg(adchan->host->dev, "ch%d start\n", adchan->no);
|
||||
+}
|
||||
+
|
||||
+static void admac_stop_chan(struct admac_chan *adchan)
|
||||
+{
|
||||
+ u32 stopbit = 1 << (adchan->no / 2);
|
||||
+ switch (admac_chan_direction(adchan->no)) {
|
||||
+ case DMA_MEM_TO_DEV:
|
||||
+ admac_poke(adchan->host, REG_TX_STOP, stopbit);
|
||||
+ break;
|
||||
+ case DMA_DEV_TO_MEM:
|
||||
+ admac_poke(adchan->host, REG_RX_STOP, stopbit);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ dev_dbg(adchan->host->dev, "ch%d stop\n", adchan->no);
|
||||
+}
|
||||
+
|
||||
+static void admac_start_current_tx(struct admac_chan *adchan)
|
||||
+{
|
||||
+ struct admac_data *ad = adchan->host;
|
||||
+ int ch = adchan->no;
|
||||
+
|
||||
+ admac_poke(ad, REG_CHAN_INTSTATUS(ch, ad->irq_index),
|
||||
+ STATUS_DESC_DONE | STATUS_ERR);
|
||||
+ admac_poke(ad, REG_CHAN_CTL(ch), REG_CHAN_CTL_RST_RINGS);
|
||||
+ admac_poke(ad, REG_CHAN_CTL(ch), 0);
|
||||
+
|
||||
+ admac_cyclic_write_one_desc(ad, ch, adchan->current_tx);
|
||||
+ admac_start_chan(adchan);
|
||||
+ admac_cyclic_write_desc(ad, ch, adchan->current_tx);
|
||||
+}
|
||||
+
|
||||
+static void admac_issue_pending(struct dma_chan *chan)
|
||||
+{
|
||||
+ struct admac_chan *adchan = to_admac_chan(chan);
|
||||
+ struct admac_tx *tx;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&adchan->lock, flags);
|
||||
+ list_splice_tail_init(&adchan->submitted, &adchan->issued);
|
||||
+ if (!list_empty(&adchan->issued) && !adchan->current_tx) {
|
||||
+ tx = list_first_entry(&adchan->issued, struct admac_tx, node);
|
||||
+ list_del(&tx->node);
|
||||
+
|
||||
+ adchan->current_tx = tx;
|
||||
+ adchan->nperiod_acks = 0;
|
||||
+ admac_start_current_tx(adchan);
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&adchan->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int admac_pause(struct dma_chan *chan)
|
||||
+{
|
||||
+ struct admac_chan *adchan = to_admac_chan(chan);
|
||||
+
|
||||
+ admac_stop_chan(adchan);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int admac_resume(struct dma_chan *chan)
|
||||
+{
|
||||
+ struct admac_chan *adchan = to_admac_chan(chan);
|
||||
+
|
||||
+ admac_start_chan(adchan);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int admac_terminate_all(struct dma_chan *chan)
|
||||
+{
|
||||
+ struct admac_chan *adchan = to_admac_chan(chan);
|
||||
+ struct admac_tx *adtx, *_adtx;
|
||||
+ unsigned long flags;
|
||||
+ LIST_HEAD(head);
|
||||
+
|
||||
+ spin_lock_irqsave(&adchan->lock, flags);
|
||||
+ admac_stop_chan(adchan);
|
||||
+ adchan->current_tx = NULL;
|
||||
+ list_splice_tail_init(&adchan->submitted, &head);
|
||||
+ list_splice_tail_init(&adchan->issued, &head);
|
||||
+ spin_unlock_irqrestore(&adchan->lock, flags);
|
||||
+
|
||||
+ list_for_each_entry_safe(adtx, _adtx, &head, node) {
|
||||
+ list_del(&adtx->node);
|
||||
+ admac_desc_free(&adtx->tx);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec,
|
||||
+ struct of_dma *ofdma)
|
||||
+{
|
||||
+ struct admac_data *ad = (struct admac_data*) ofdma->of_dma_data;
|
||||
+ unsigned int index;
|
||||
+
|
||||
+ if (dma_spec->args_count != 1)
|
||||
+ return NULL;
|
||||
+
|
||||
+ index = dma_spec->args[0];
|
||||
+
|
||||
+ if (index >= ad->nchannels) {
|
||||
+ dev_err(ad->dev, "channel index %u out of bounds\n", index);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return &ad->channels[index].chan;
|
||||
+}
|
||||
+
|
||||
+static int admac_drain_reports(struct admac_data *ad, int channo)
|
||||
+{
|
||||
+ int count;
|
||||
+
|
||||
+ for (count = 0; count < 4; count++) {
|
||||
+ u32 countval_hi, countval_lo, unk1, flags;
|
||||
+
|
||||
+ if (admac_peek(ad, REG_REPORT_RING(channo)) & RING_EMPTY)
|
||||
+ break;
|
||||
+
|
||||
+ countval_lo = admac_peek(ad, REG_REPORT_READ(channo));
|
||||
+ countval_hi = admac_peek(ad, REG_REPORT_READ(channo));
|
||||
+ unk1 = admac_peek(ad, REG_REPORT_READ(channo));
|
||||
+ flags = admac_peek(ad, REG_REPORT_READ(channo));
|
||||
+
|
||||
+ dev_dbg(ad->dev, "ch%d report: countval=0x%llx unk1=0x%x flags=0x%x\n",
|
||||
+ channo, ((u64) countval_hi) << 32 | countval_lo, unk1, flags);
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static void admac_handle_status_err(struct admac_data *ad, int channo)
|
||||
+{
|
||||
+ bool handled = false;
|
||||
+
|
||||
+ if (admac_peek(ad, REG_DESC_RING(channo) & RING_ERR)) {
|
||||
+ admac_poke(ad, REG_DESC_RING(channo), RING_ERR);
|
||||
+ dev_err(ad->dev, "ch%d descriptor ring error\n", channo);
|
||||
+ handled = true;
|
||||
+ }
|
||||
+
|
||||
+ if (admac_peek(ad, REG_REPORT_RING(channo)) & RING_ERR) {
|
||||
+ admac_poke(ad, REG_REPORT_RING(channo), RING_ERR);
|
||||
+ dev_err(ad->dev, "ch%d report ring error\n", channo);
|
||||
+ handled = true;
|
||||
+ }
|
||||
+
|
||||
+ if (unlikely(!handled)) {
|
||||
+ dev_err(ad->dev, "ch%d unknown error, masking future error interrupts\n", channo);
|
||||
+ admac_modify(ad, REG_CHAN_INTMASK(channo, ad->irq_index), STATUS_ERR, 0);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void admac_handle_status_desc_done(struct admac_data *ad, int channo)
|
||||
+{
|
||||
+ struct admac_chan *adchan = &ad->channels[channo];
|
||||
+ unsigned long flags;
|
||||
+ int nreports;
|
||||
+
|
||||
+ admac_poke(ad, REG_CHAN_INTSTATUS(channo, ad->irq_index),
|
||||
+ STATUS_DESC_DONE);
|
||||
+
|
||||
+ spin_lock_irqsave(&adchan->lock, flags);
|
||||
+ nreports = admac_drain_reports(ad, channo);
|
||||
+
|
||||
+ if (adchan->current_tx) {
|
||||
+ struct admac_tx *tx = adchan->current_tx;
|
||||
+
|
||||
+ adchan->nperiod_acks += nreports;
|
||||
+ tx->reclaimed_pos += nreports * tx->period_len;
|
||||
+ tx->reclaimed_pos %= 2 * tx->buf_len;
|
||||
+
|
||||
+ admac_cyclic_write_desc(ad, channo, tx);
|
||||
+ tasklet_schedule(&adchan->tasklet);
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&adchan->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void admac_handle_chan_int(struct admac_data *ad, int no)
|
||||
+{
|
||||
+ u32 cause = admac_peek(ad, REG_CHAN_INTSTATUS(no, ad->irq_index));
|
||||
+
|
||||
+ if (cause & STATUS_ERR)
|
||||
+ admac_handle_status_err(ad, no);
|
||||
+
|
||||
+ if (cause & STATUS_DESC_DONE)
|
||||
+ admac_handle_status_desc_done(ad, no);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t admac_interrupt(int irq, void *devid)
|
||||
+{
|
||||
+ struct admac_data *ad = devid;
|
||||
+ u32 rx_intstate, tx_intstate;
|
||||
+ int i;
|
||||
+
|
||||
+ rx_intstate = admac_peek(ad, REG_RX_INTSTATE(ad->irq_index));
|
||||
+ tx_intstate = admac_peek(ad, REG_TX_INTSTATE(ad->irq_index));
|
||||
+
|
||||
+ for (i = 0; i < ad->nchannels; i += 2)
|
||||
+ if (tx_intstate & (1 << (i / 2)))
|
||||
+ admac_handle_chan_int(ad, i);
|
||||
+
|
||||
+ for (i = 1; i < ad->nchannels; i += 2)
|
||||
+ if (rx_intstate & (1 << (i / 2)))
|
||||
+ admac_handle_chan_int(ad, i);
|
||||
+
|
||||
+ return (tx_intstate | rx_intstate) != 0 ? IRQ_HANDLED : IRQ_NONE;
|
||||
+}
|
||||
+
|
||||
+static void admac_chan_tasklet(struct tasklet_struct *t)
|
||||
+{
|
||||
+ struct admac_chan *adchan = from_tasklet(adchan, t, tasklet);
|
||||
+ struct admac_tx *adtx;
|
||||
+ struct dmaengine_desc_callback cb;
|
||||
+ struct dmaengine_result tx_result;
|
||||
+ int nacks;
|
||||
+
|
||||
+ spin_lock_irq(&adchan->lock);
|
||||
+ adtx = adchan->current_tx;
|
||||
+ nacks = adchan->nperiod_acks;
|
||||
+ adchan->nperiod_acks = 0;
|
||||
+ spin_unlock_irq(&adchan->lock);
|
||||
+
|
||||
+ if (!adtx || !nacks)
|
||||
+ return;
|
||||
+
|
||||
+ tx_result.result = DMA_TRANS_NOERROR;
|
||||
+ tx_result.residue = 0;
|
||||
+
|
||||
+ dmaengine_desc_get_callback(&adtx->tx, &cb);
|
||||
+ while (nacks--)
|
||||
+ dmaengine_desc_callback_invoke(&cb, &tx_result);
|
||||
+}
|
||||
+
|
||||
+static int admac_device_config(struct dma_chan *chan,
|
||||
+ struct dma_slave_config *config)
|
||||
+{
|
||||
+ struct admac_chan *adchan = to_admac_chan(chan);
|
||||
+ struct admac_data *ad = adchan->host;
|
||||
+ bool is_tx = admac_chan_direction(adchan->no) == DMA_MEM_TO_DEV;
|
||||
+ u32 bus_width = 0;
|
||||
+
|
||||
+
|
||||
+ switch (is_tx ? config->dst_addr_width : config->src_addr_width) {
|
||||
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
|
||||
+ bus_width |= BUS_WIDTH_8BIT;
|
||||
+ break;
|
||||
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
|
||||
+ bus_width |= BUS_WIDTH_16BIT;
|
||||
+ break;
|
||||
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
|
||||
+ bus_width |= BUS_WIDTH_32BIT;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (is_tx ? config->dst_port_window_size : config->src_port_window_size) {
|
||||
+ case 0 ... 1:
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ bus_width |= BUS_WIDTH_FRAME_2_WORDS;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ bus_width |= BUS_WIDTH_FRAME_4_WORDS;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ admac_poke(adchan->host, REG_BUS_WIDTH(adchan->no), bus_width);
|
||||
+
|
||||
+ /* TODO: burst size */
|
||||
+
|
||||
+ admac_poke(adchan->host, REG_CHAN_BURSTSIZE(adchan->no), 0xc00060);
|
||||
+
|
||||
+ /* TODO: this belongs elsewhere */
|
||||
+ admac_poke(adchan->host, REG_CHAN_INTSTATUS(adchan->no, ad->irq_index),
|
||||
+ STATUS_DESC_DONE | STATUS_ERR);
|
||||
+ admac_poke(adchan->host, REG_CHAN_INTMASK(adchan->no, ad->irq_index),
|
||||
+ STATUS_DESC_DONE | STATUS_ERR);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int admac_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct admac_data *ad;
|
||||
+ struct dma_device *dma;
|
||||
+ int nchannels;
|
||||
+ int err, irq, i;
|
||||
+
|
||||
+ err = of_property_read_u32(np, "dma-channels", &nchannels);
|
||||
+ if (err || nchannels > NCHANNELS_MAX) {
|
||||
+ dev_err(&pdev->dev, "missing or invalid dma-channels property\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ad = devm_kzalloc(&pdev->dev, struct_size(ad, channels, nchannels), GFP_KERNEL);
|
||||
+ if (!ad)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, ad);
|
||||
+ ad->dev = &pdev->dev;
|
||||
+ ad->nchannels = nchannels;
|
||||
+
|
||||
+ err = of_property_read_u32(np, "apple,internal-irq-destination", &ad->irq_index);
|
||||
+ if (err || ad->irq_index > IRQ_INDEX_MAX) {
|
||||
+ dev_err(&pdev->dev, "missing or invalid apple,internal-irq-destination property\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0) {
|
||||
+ dev_err(&pdev->dev, "unable to obtain interrupt resource\n");
|
||||
+ return irq;
|
||||
+ }
|
||||
+
|
||||
+ err = devm_request_irq(&pdev->dev, irq, admac_interrupt,
|
||||
+ 0, dev_name(&pdev->dev), ad);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "unable to register interrupt: %d\n", err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ ad->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(ad->base)) {
|
||||
+ dev_err(&pdev->dev, "unable to obtain MMIO resource\n");
|
||||
+ return PTR_ERR(ad->base);
|
||||
+ }
|
||||
+
|
||||
+ dma = &ad->dma;
|
||||
+
|
||||
+ dma_cap_set(DMA_PRIVATE, dma->cap_mask);
|
||||
+ dma_cap_set(DMA_CYCLIC, dma->cap_mask);
|
||||
+
|
||||
+ dma->dev = &pdev->dev;
|
||||
+ dma->device_alloc_chan_resources = admac_alloc_chan_resources;
|
||||
+ dma->device_free_chan_resources = admac_free_chan_resources;
|
||||
+ dma->device_tx_status = admac_tx_status;
|
||||
+ dma->device_issue_pending = admac_issue_pending;
|
||||
+ dma->device_terminate_all = admac_terminate_all;
|
||||
+ dma->device_prep_dma_cyclic = admac_prep_dma_cyclic;
|
||||
+ dma->device_config = admac_device_config;
|
||||
+ dma->device_pause = admac_pause;
|
||||
+ dma->device_resume = admac_resume;
|
||||
+
|
||||
+ dma->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
|
||||
+ dma->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
|
||||
+ dma->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
|
||||
+
|
||||
+ INIT_LIST_HEAD(&dma->channels);
|
||||
+ for (i = 0; i < nchannels; i++) {
|
||||
+ struct admac_chan *adchan = &ad->channels[i];
|
||||
+ adchan->host = ad;
|
||||
+ adchan->no = i;
|
||||
+ adchan->chan.device = &ad->dma;
|
||||
+ dma_cookie_init(&adchan->chan);
|
||||
+ spin_lock_init(&adchan->lock);
|
||||
+ INIT_LIST_HEAD(&adchan->submitted);
|
||||
+ INIT_LIST_HEAD(&adchan->issued);
|
||||
+ list_add_tail(&adchan->chan.device_node, &dma->channels);
|
||||
+ tasklet_setup(&adchan->tasklet, admac_chan_tasklet);
|
||||
+ }
|
||||
+
|
||||
+ err = dma_async_device_register(&ad->dma);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "failed to register DMA device: %d\n", err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "failed to register with OF: %d\n", err);
|
||||
+ dma_async_device_unregister(&ad->dma);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(&pdev->dev, "all good, ready to go!\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int admac_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct admac_data *ad = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ of_dma_controller_free(pdev->dev.of_node);
|
||||
+ dma_async_device_unregister(&ad->dma);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id admac_of_match[] = {
|
||||
+ { .compatible = "apple,admac", },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, admac_of_match);
|
||||
+
|
||||
+static struct platform_driver apple_admac_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "apple-admac",
|
||||
+ .of_match_table = admac_of_match,
|
||||
+ },
|
||||
+ .probe = admac_probe,
|
||||
+ .remove = admac_remove,
|
||||
+};
|
||||
+module_platform_driver(apple_admac_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
|
||||
+MODULE_DESCRIPTION("Driver for Audio DMA Controller (ADMAC) in Apple SoCs");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.34.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,99 @@
|
||||
From 25cfbd57efaf69fbbf65c4db2c4d541b8715e5f8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:49:34 +0100
|
||||
Subject: [PATCH 073/171] ASoC: tas2770: Set correct FSYNC polarity
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fix setting of FSYNC polarity for DAI formats other than I2S. Also
|
||||
add support for polarity inversion.
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
sound/soc/codecs/tas2770.c | 21 ++++++++++++++++++++-
|
||||
sound/soc/codecs/tas2770.h | 3 +++
|
||||
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
|
||||
index c1dbd978d550..2b214223265e 100644
|
||||
--- a/sound/soc/codecs/tas2770.c
|
||||
+++ b/sound/soc/codecs/tas2770.c
|
||||
@@ -337,7 +337,7 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct tas2770_priv *tas2770 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
- u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
|
||||
+ u8 tdm_rx_start_slot = 0, invert_fpol = 0, fpol_preinv = 0, asi_cfg_1 = 0;
|
||||
int ret;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
@@ -349,9 +349,15 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
+ case SND_SOC_DAIFMT_NB_IF:
|
||||
+ invert_fpol = 1;
|
||||
+ fallthrough;
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_RSING;
|
||||
break;
|
||||
+ case SND_SOC_DAIFMT_IB_IF:
|
||||
+ invert_fpol = 1;
|
||||
+ fallthrough;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_FALING;
|
||||
break;
|
||||
@@ -369,15 +375,19 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
tdm_rx_start_slot = 1;
|
||||
+ fpol_preinv = 0;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
tdm_rx_start_slot = 0;
|
||||
+ fpol_preinv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
tdm_rx_start_slot = 1;
|
||||
+ fpol_preinv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
tdm_rx_start_slot = 0;
|
||||
+ fpol_preinv = 1;
|
||||
break;
|
||||
default:
|
||||
dev_err(tas2770->dev,
|
||||
@@ -391,6 +401,15 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+
|
||||
+ ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG0,
|
||||
+ TAS2770_TDM_CFG_REG0_FPOL_MASK,
|
||||
+ (fpol_preinv ^ invert_fpol)
|
||||
+ ? TAS2770_TDM_CFG_REG0_FPOL_RSING
|
||||
+ : TAS2770_TDM_CFG_REG0_FPOL_FALING);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/sound/soc/codecs/tas2770.h b/sound/soc/codecs/tas2770.h
|
||||
index d156666bcc55..42277fb6bc10 100644
|
||||
--- a/sound/soc/codecs/tas2770.h
|
||||
+++ b/sound/soc/codecs/tas2770.h
|
||||
@@ -41,6 +41,9 @@
|
||||
#define TAS2770_TDM_CFG_REG0_31_44_1_48KHZ 0x6
|
||||
#define TAS2770_TDM_CFG_REG0_31_88_2_96KHZ 0x8
|
||||
#define TAS2770_TDM_CFG_REG0_31_176_4_192KHZ 0xa
|
||||
+#define TAS2770_TDM_CFG_REG0_FPOL_MASK BIT(0)
|
||||
+#define TAS2770_TDM_CFG_REG0_FPOL_RSING 0
|
||||
+#define TAS2770_TDM_CFG_REG0_FPOL_FALING 1
|
||||
/* TDM Configuration Reg1 */
|
||||
#define TAS2770_TDM_CFG_REG1 TAS2770_REG(0X0, 0x0B)
|
||||
#define TAS2770_TDM_CFG_REG1_MASK GENMASK(5, 1)
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,27 @@
|
||||
From b65315774f730e0b8553230d6cff9912a0341ca9 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:49:45 +0100
|
||||
Subject: [PATCH 074/171] HACK: ASoC: tas2770: Set no of channels to 1
|
||||
|
||||
---
|
||||
sound/soc/codecs/tas2770.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
|
||||
index 2b214223265e..753e3f8d459a 100644
|
||||
--- a/sound/soc/codecs/tas2770.c
|
||||
+++ b/sound/soc/codecs/tas2770.c
|
||||
@@ -508,8 +508,8 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = {
|
||||
.id = 0,
|
||||
.playback = {
|
||||
.stream_name = "ASI1 Playback",
|
||||
- .channels_min = 2,
|
||||
- .channels_max = 2,
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 1,
|
||||
.rates = TAS2770_RATES,
|
||||
.formats = TAS2770_FORMATS,
|
||||
},
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 289067bf88e5b44f8e5a34535693bd01bb3adb97 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:49:48 +0100
|
||||
Subject: [PATCH 075/171] HACK: ASoC: cs42l42: Disable regcache
|
||||
|
||||
There's some issue that has yet to be pinned down.
|
||||
---
|
||||
sound/soc/codecs/cs42l42.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
|
||||
index 4fade2388797..5fb28df85b8a 100644
|
||||
--- a/sound/soc/codecs/cs42l42.c
|
||||
+++ b/sound/soc/codecs/cs42l42.c
|
||||
@@ -380,7 +380,7 @@ static const struct regmap_config cs42l42_regmap = {
|
||||
.max_register = CS42L42_MAX_REGISTER,
|
||||
.reg_defaults = cs42l42_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(cs42l42_reg_defaults),
|
||||
- .cache_type = REGCACHE_RBTREE,
|
||||
+ //.cache_type = REGCACHE_RBTREE,
|
||||
|
||||
.use_single_read = true,
|
||||
.use_single_write = true,
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 27fe5e0a4429c0a92635d1395a673fcea6289046 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:49:50 +0100
|
||||
Subject: [PATCH 076/171] ASoC: cs42l42: Bypass device ID check
|
||||
|
||||
The cs42l42 driver is also applicable to the cs42l83 part.
|
||||
---
|
||||
sound/soc/codecs/cs42l42.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
|
||||
index 5fb28df85b8a..2a98f9bc7144 100644
|
||||
--- a/sound/soc/codecs/cs42l42.c
|
||||
+++ b/sound/soc/codecs/cs42l42.c
|
||||
@@ -2273,13 +2273,10 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client)
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
- if (devid != CS42L42_CHIP_ID) {
|
||||
- ret = -ENODEV;
|
||||
- dev_err(&i2c_client->dev,
|
||||
+ if (devid != CS42L42_CHIP_ID)
|
||||
+ dev_warn(&i2c_client->dev,
|
||||
"CS42L42 Device ID (%X). Expected %X\n",
|
||||
devid, CS42L42_CHIP_ID);
|
||||
- goto err_disable;
|
||||
- }
|
||||
|
||||
ret = regmap_read(cs42l42->regmap, CS42L42_REVID, ®);
|
||||
if (ret < 0) {
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,205 @@
|
||||
From 170220fc8fb15839654131612ac3dc84bb4469ea Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sun, 20 Feb 2022 14:29:38 +0100
|
||||
Subject: [PATCH 077/171] HACK: ASoC: Add card->filter_controls hook
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add a new ASoC card callback for filtering the kcontrols of the card's
|
||||
constituent components. This lets the card take over some of the
|
||||
controls, deciding their value instead of leaving it up to userspace.
|
||||
|
||||
Also, and here's the HACK: part, move dapm_new_widgets call in front
|
||||
of the card's late_probe call. This way all kcontrols should have been
|
||||
crated by the time late_probe is called.
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
include/sound/soc.h | 3 +++
|
||||
sound/soc/soc-core.c | 45 +++++++++++++++++++++++++++-----------------
|
||||
sound/soc/soc-dapm.c | 34 ++++++++++++++++++++++++++++-----
|
||||
3 files changed, 60 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/include/sound/soc.h b/include/sound/soc.h
|
||||
index b276dcb5d4e8..7ef168a8c759 100644
|
||||
--- a/include/sound/soc.h
|
||||
+++ b/include/sound/soc.h
|
||||
@@ -916,6 +916,9 @@ struct snd_soc_card {
|
||||
int (*late_probe)(struct snd_soc_card *card);
|
||||
int (*remove)(struct snd_soc_card *card);
|
||||
|
||||
+ int (*filter_controls)(struct snd_soc_card *card,
|
||||
+ struct snd_kcontrol *kcontrol);
|
||||
+
|
||||
/* the pre and post PM functions are used to do any PM work before and
|
||||
* after the codec and DAI's do any PM work. */
|
||||
int (*suspend_pre)(struct snd_soc_card *card);
|
||||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
|
||||
index 9574f86dd4de..37e2a8b2af10 100644
|
||||
--- a/sound/soc/soc-core.c
|
||||
+++ b/sound/soc/soc-core.c
|
||||
@@ -2069,12 +2069,12 @@ static int snd_soc_bind_card(struct snd_soc_card *card)
|
||||
}
|
||||
}
|
||||
|
||||
+ snd_soc_dapm_new_widgets(card);
|
||||
+
|
||||
ret = snd_soc_card_late_probe(card);
|
||||
if (ret < 0)
|
||||
goto probe_end;
|
||||
|
||||
- snd_soc_dapm_new_widgets(card);
|
||||
-
|
||||
ret = snd_card_register(card->snd_card);
|
||||
if (ret < 0) {
|
||||
dev_err(card->dev, "ASoC: failed to register soundcard %d\n",
|
||||
@@ -2209,19 +2209,34 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_cnew);
|
||||
|
||||
-static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
|
||||
+static int snd_soc_add_controls(struct snd_soc_card *card, struct device *dev,
|
||||
const struct snd_kcontrol_new *controls, int num_controls,
|
||||
const char *prefix, void *data)
|
||||
{
|
||||
- int i;
|
||||
+ int i, err;
|
||||
|
||||
for (i = 0; i < num_controls; i++) {
|
||||
- const struct snd_kcontrol_new *control = &controls[i];
|
||||
- int err = snd_ctl_add(card, snd_soc_cnew(control, data,
|
||||
- control->name, prefix));
|
||||
+ const struct snd_kcontrol_new *control_new = &controls[i];
|
||||
+ struct snd_kcontrol *control;
|
||||
+
|
||||
+ control = snd_soc_cnew(control_new, data,
|
||||
+ control_new->name, prefix);
|
||||
+
|
||||
+ if (card->filter_controls) {
|
||||
+ err = card->filter_controls(card, control);
|
||||
+ if (err < 0) {
|
||||
+ snd_ctl_free_one(control);
|
||||
+ return err;
|
||||
+ } else if (err) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ err = snd_ctl_add(card->snd_card, control);
|
||||
+
|
||||
if (err < 0) {
|
||||
dev_err(dev, "ASoC: Failed to add %s: %d\n",
|
||||
- control->name, err);
|
||||
+ control_new->name, err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -2241,9 +2256,7 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
|
||||
int snd_soc_add_component_controls(struct snd_soc_component *component,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls)
|
||||
{
|
||||
- struct snd_card *card = component->card->snd_card;
|
||||
-
|
||||
- return snd_soc_add_controls(card, component->dev, controls,
|
||||
+ return snd_soc_add_controls(component->card, component->dev, controls,
|
||||
num_controls, component->name_prefix, component);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_add_component_controls);
|
||||
@@ -2258,13 +2271,11 @@ EXPORT_SYMBOL_GPL(snd_soc_add_component_controls);
|
||||
*
|
||||
* Return 0 for success, else error.
|
||||
*/
|
||||
-int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
|
||||
+int snd_soc_add_card_controls(struct snd_soc_card *card,
|
||||
const struct snd_kcontrol_new *controls, int num_controls)
|
||||
{
|
||||
- struct snd_card *card = soc_card->snd_card;
|
||||
-
|
||||
- return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,
|
||||
- NULL, soc_card);
|
||||
+ return snd_soc_add_controls(card, card->dev, controls, num_controls,
|
||||
+ NULL, card);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
|
||||
|
||||
@@ -2281,7 +2292,7 @@ EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
|
||||
int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
|
||||
const struct snd_kcontrol_new *controls, int num_controls)
|
||||
{
|
||||
- struct snd_card *card = dai->component->card->snd_card;
|
||||
+ struct snd_soc_card *card = dai->component->card;
|
||||
|
||||
return snd_soc_add_controls(card, dai->dev, controls, num_controls,
|
||||
NULL, dai);
|
||||
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
|
||||
index a8e842e02cdc..c87137f364da 100644
|
||||
--- a/sound/soc/soc-dapm.c
|
||||
+++ b/sound/soc/soc-dapm.c
|
||||
@@ -878,7 +878,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
|
||||
int kci)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||
- struct snd_card *card = dapm->card->snd_card;
|
||||
+ struct snd_soc_card *card = dapm->card;
|
||||
const char *prefix;
|
||||
size_t prefix_len;
|
||||
int shared;
|
||||
@@ -962,7 +962,19 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
- ret = snd_ctl_add(card, kcontrol);
|
||||
+ if (card->filter_controls) {
|
||||
+ ret = card->filter_controls(card, kcontrol);
|
||||
+ if (ret < 0) {
|
||||
+ snd_ctl_free_one(kcontrol);
|
||||
+ goto exit_free;
|
||||
+ }
|
||||
+
|
||||
+ if (!ret)
|
||||
+ ret = snd_ctl_add(card->snd_card, kcontrol);
|
||||
+ } else {
|
||||
+ ret = snd_ctl_add(card->snd_card, kcontrol);
|
||||
+ }
|
||||
+
|
||||
if (ret < 0) {
|
||||
dev_err(dapm->dev,
|
||||
"ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
|
||||
@@ -1079,7 +1091,7 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
|
||||
/* create new dapm dai link control */
|
||||
static int dapm_new_dai_link(struct snd_soc_dapm_widget *w)
|
||||
{
|
||||
- int i;
|
||||
+ int i, ret;
|
||||
struct snd_soc_pcm_runtime *rtd = w->priv;
|
||||
|
||||
/* create control for links with > 1 config */
|
||||
@@ -1089,10 +1101,22 @@ static int dapm_new_dai_link(struct snd_soc_dapm_widget *w)
|
||||
/* add kcontrol */
|
||||
for (i = 0; i < w->num_kcontrols; i++) {
|
||||
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||
- struct snd_card *card = dapm->card->snd_card;
|
||||
+ struct snd_soc_card *card = dapm->card;
|
||||
struct snd_kcontrol *kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
|
||||
w, w->name, NULL);
|
||||
- int ret = snd_ctl_add(card, kcontrol);
|
||||
+
|
||||
+ if (card->filter_controls) {
|
||||
+ ret = card->filter_controls(card, kcontrol);
|
||||
+ if (ret < 0) {
|
||||
+ snd_ctl_free_one(kcontrol);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!ret)
|
||||
+ ret = snd_ctl_add(card->snd_card, kcontrol);
|
||||
+ } else {
|
||||
+ ret = snd_ctl_add(card->snd_card, kcontrol);
|
||||
+ }
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(dapm->dev,
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,29 @@
|
||||
From 3153617d401d69c1d4f52eb3ca69f5b4b8d2086a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Thu, 24 Feb 2022 14:50:34 +0100
|
||||
Subject: [PATCH 078/171] ASoC: Add asoc_pcm_to_rtd utility function
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
include/sound/soc.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/include/sound/soc.h b/include/sound/soc.h
|
||||
index 7ef168a8c759..73cc83d73163 100644
|
||||
--- a/include/sound/soc.h
|
||||
+++ b/include/sound/soc.h
|
||||
@@ -1101,6 +1101,8 @@ struct snd_soc_pcm_runtime {
|
||||
#define asoc_rtd_to_codec(rtd, n) (rtd)->dais[n + (rtd)->num_cpus]
|
||||
#define asoc_substream_to_rtd(substream) \
|
||||
(struct snd_soc_pcm_runtime *)snd_pcm_substream_chip(substream)
|
||||
+#define asoc_pcm_to_rtd(pcm) \
|
||||
+ ((struct snd_soc_pcm_runtime *)pcm->private_data)
|
||||
|
||||
#define for_each_rtd_components(rtd, i, component) \
|
||||
for ((i) = 0, component = NULL; \
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 3a8e536be0711ee4985c227fee67e569aa93f9a7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Thu, 24 Feb 2022 14:51:00 +0100
|
||||
Subject: [PATCH 079/171] HACK: ASoC: Allow an N-cpus-to-M-codecs link
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
sound/soc/soc-pcm.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
|
||||
index a827cc3c158a..542c308df17c 100644
|
||||
--- a/sound/soc/soc-pcm.c
|
||||
+++ b/sound/soc/soc-pcm.c
|
||||
@@ -2811,9 +2811,10 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd,
|
||||
} else if (rtd->num_cpus == rtd->num_codecs) {
|
||||
cpu_dai = asoc_rtd_to_cpu(rtd, i);
|
||||
} else {
|
||||
- dev_err(rtd->card->dev,
|
||||
- "N cpus to M codecs link is not supported yet\n");
|
||||
- return -EINVAL;
|
||||
+ cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
+ //dev_err(rtd->card->dev,
|
||||
+ // "N cpus to M codecs link is not supported yet\n");
|
||||
+ //return -EINVAL;
|
||||
}
|
||||
|
||||
if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,632 @@
|
||||
From 1bd9f82e027617111fd5a1a653dad3880f71ddf7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Sat, 19 Feb 2022 09:49:56 +0100
|
||||
Subject: [PATCH 080/171] ASoC: Add macaudio machine driver
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
sound/soc/apple/Kconfig | 9 +
|
||||
sound/soc/apple/Makefile | 3 +
|
||||
sound/soc/apple/macaudio.c | 579 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 591 insertions(+)
|
||||
create mode 100644 sound/soc/apple/macaudio.c
|
||||
|
||||
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
|
||||
index ebe66d713b96..a3f6a97140e2 100644
|
||||
--- a/sound/soc/apple/Kconfig
|
||||
+++ b/sound/soc/apple/Kconfig
|
||||
@@ -1,3 +1,12 @@
|
||||
+
|
||||
+config SND_SOC_APPLE_SILICON
|
||||
+ tristate "ASoC machine driver for Apple Silicon Macs"
|
||||
+ depends on ARCH_APPLE || COMPILE_TEST
|
||||
+ select SND_SOC_APPLE_MCA
|
||||
+ default ARCH_APPLE
|
||||
+ help
|
||||
+ This option enables an ASoC machine driver for Apple Silicon Macs.
|
||||
+
|
||||
config SND_SOC_APPLE_MCA
|
||||
tristate "Apple Silicon MCA driver"
|
||||
depends on ARCH_APPLE || COMPILE_TEST
|
||||
diff --git a/sound/soc/apple/Makefile b/sound/soc/apple/Makefile
|
||||
index c1e492d57649..a45cf8213c29 100644
|
||||
--- a/sound/soc/apple/Makefile
|
||||
+++ b/sound/soc/apple/Makefile
|
||||
@@ -1,3 +1,6 @@
|
||||
snd-soc-apple-mca-objs := mca.o
|
||||
+snd-soc-apple-silicon-objs := macaudio.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_APPLE_MCA) += snd-soc-apple-mca.o
|
||||
+obj-$(CONFIG_SND_SOC_APPLE_SILICON) += snd-soc-apple-silicon.o
|
||||
+
|
||||
diff --git a/sound/soc/apple/macaudio.c b/sound/soc/apple/macaudio.c
|
||||
new file mode 100644
|
||||
index 000000000000..a1f2b1fcea1f
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/apple/macaudio.c
|
||||
@@ -0,0 +1,579 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * ASoC machine driver for Apple Silicon Macs
|
||||
+ *
|
||||
+ * Copyright (C) The Asahi Linux Contributors
|
||||
+ *
|
||||
+ * Based on sound/soc/qcom/{sc7180.c|common.c}
|
||||
+ *
|
||||
+ * Copyright (c) 2018, Linaro Limited.
|
||||
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <sound/core.h>
|
||||
+#include <sound/jack.h>
|
||||
+#include <sound/pcm.h>
|
||||
+#include <sound/simple_card_utils.h>
|
||||
+#include <sound/soc.h>
|
||||
+#include <uapi/linux/input-event-codes.h>
|
||||
+
|
||||
+#define DRIVER_NAME "snd-soc-apple-macaudio"
|
||||
+
|
||||
+struct macaudio_snd_data {
|
||||
+ struct snd_soc_card card;
|
||||
+ struct snd_soc_jack_pin pin;
|
||||
+ struct snd_soc_jack jack;
|
||||
+
|
||||
+ struct macaudio_link_props {
|
||||
+ unsigned int mclk_fs;
|
||||
+ } *link_props;
|
||||
+
|
||||
+ const struct snd_pcm_chmap_elem *speaker_chmap;
|
||||
+
|
||||
+ unsigned int speaker_nchans_array[2];
|
||||
+ struct snd_pcm_hw_constraint_list speaker_nchans_list;
|
||||
+
|
||||
+ struct list_head hidden_kcontrols;
|
||||
+};
|
||||
+
|
||||
+static int macaudio_parse_of(struct macaudio_snd_data *ma, struct snd_soc_card *card)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+ struct device_node *codec = NULL;
|
||||
+ struct device_node *cpu = NULL;
|
||||
+ struct device *dev = card->dev;
|
||||
+ struct snd_soc_dai_link *link;
|
||||
+ struct macaudio_link_props *link_props;
|
||||
+ int ret, num_links;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ ret = snd_soc_of_parse_card_name(card, "model");
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Error parsing card name: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = asoc_simple_parse_routing(card, NULL);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Populate links */
|
||||
+ num_links = of_get_available_child_count(dev->of_node);
|
||||
+
|
||||
+ /* Allocate the DAI link array */
|
||||
+ card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
|
||||
+ ma->link_props = devm_kcalloc(dev, num_links, sizeof(*ma->link_props), GFP_KERNEL);
|
||||
+ if (!card->dai_link || !ma->link_props)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ card->num_links = num_links;
|
||||
+ link = card->dai_link;
|
||||
+ link_props = ma->link_props;
|
||||
+
|
||||
+ for_each_available_child_of_node(dev->of_node, np) {
|
||||
+ link->id = i++;
|
||||
+
|
||||
+ /* CPU side is bit and frame clock master, I2S with both clocks inverted */
|
||||
+ link->dai_fmt = SND_SOC_DAIFMT_I2S |
|
||||
+ SND_SOC_DAIFMT_CBC_CFC |
|
||||
+ SND_SOC_DAIFMT_GATED |
|
||||
+ SND_SOC_DAIFMT_IB_IF;
|
||||
+
|
||||
+ ret = of_property_read_string(np, "link-name", &link->name);
|
||||
+ if (ret) {
|
||||
+ dev_err(card->dev, "Missing link name\n");
|
||||
+ goto err_put_np;
|
||||
+ }
|
||||
+
|
||||
+ cpu = of_get_child_by_name(np, "cpu");
|
||||
+ codec = of_get_child_by_name(np, "codec");
|
||||
+
|
||||
+ if (!codec || !cpu) {
|
||||
+ dev_err(dev, "Missing DAI specifications for '%s'\n", link->name);
|
||||
+ ret = -EINVAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
|
||||
+ if (ret < 0) {
|
||||
+ if (ret != -EPROBE_DEFER)
|
||||
+ dev_err(card->dev, "%s: codec dai not found: %d\n",
|
||||
+ link->name, ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = snd_soc_of_get_dai_link_cpus(dev, cpu, link);
|
||||
+ if (ret < 0) {
|
||||
+ if (ret != -EPROBE_DEFER)
|
||||
+ dev_err(card->dev, "%s: cpu dai not found: %d\n",
|
||||
+ link->name, ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ link->num_platforms = 1;
|
||||
+ link->platforms = devm_kzalloc(dev, sizeof(*link->platforms),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!link->platforms) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_put_np;
|
||||
+ }
|
||||
+ link->platforms->of_node = link->cpus->of_node;
|
||||
+
|
||||
+ of_property_read_u32(np, "mclk-fs", &link_props->mclk_fs);
|
||||
+
|
||||
+ link->stream_name = link->name;
|
||||
+ link++;
|
||||
+ link_props++;
|
||||
+
|
||||
+ of_node_put(cpu);
|
||||
+ of_node_put(codec);
|
||||
+ }
|
||||
+
|
||||
+ /* TODO: snd_soc_of_get_dai_link_codecs cleanup */
|
||||
+
|
||||
+ return 0;
|
||||
+err:
|
||||
+ of_node_put(cpu);
|
||||
+ of_node_put(codec);
|
||||
+err_put_np:
|
||||
+ of_node_put(np);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int macaudio_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(rtd->card);
|
||||
+ struct macaudio_link_props *props = &ma->link_props[rtd->num];
|
||||
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
+ struct snd_soc_dai *dai;
|
||||
+ int i, mclk;
|
||||
+
|
||||
+ if (props->mclk_fs) {
|
||||
+ mclk = params_rate(params) * props->mclk_fs;
|
||||
+
|
||||
+ for_each_rtd_codec_dais(rtd, i, dai)
|
||||
+ snd_soc_dai_set_sysclk(dai, 0, mclk, SND_SOC_CLOCK_IN);
|
||||
+
|
||||
+ snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, SND_SOC_CLOCK_OUT);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void macaudio_shutdown(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(rtd->card);
|
||||
+ struct macaudio_link_props *props = &ma->link_props[rtd->num];
|
||||
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
+ struct snd_soc_dai *dai;
|
||||
+ int i;
|
||||
+
|
||||
+ if (props->mclk_fs) {
|
||||
+ for_each_rtd_codec_dais(rtd, i, dai)
|
||||
+ snd_soc_dai_set_sysclk(dai, 0, 0, SND_SOC_CLOCK_IN);
|
||||
+
|
||||
+ snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int macaudio_startup(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
+ struct snd_soc_card *card = rtd->card;
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
|
||||
+ struct snd_pcm_hw_constraint_list *nchans_list = &ma->speaker_nchans_list;
|
||||
+ unsigned int *nchans_array = ma->speaker_nchans_array;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!strcmp(rtd->dai_link->name, "Speakers")) {
|
||||
+ if (rtd->num_codecs > 2) {
|
||||
+ nchans_list->count = 2;
|
||||
+ nchans_list->list = nchans_array;
|
||||
+ nchans_array[0] = 2;
|
||||
+ nchans_array[1] = rtd->num_codecs;
|
||||
+
|
||||
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
|
||||
+ SNDRV_PCM_HW_PARAM_CHANNELS, nchans_list);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ } else if (rtd->num_codecs == 2) {
|
||||
+ ret = snd_pcm_hw_constraint_single(substream->runtime,
|
||||
+ SNDRV_PCM_HW_PARAM_CHANNELS, 2);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int macaudio_assign_tdm(struct snd_soc_pcm_runtime *rtd)
|
||||
+{
|
||||
+ struct snd_soc_card *card = rtd->card;
|
||||
+ struct snd_soc_dai *dai, *cpu_dai;
|
||||
+ int ret, i;
|
||||
+ int nchans = 0, nslots = 0, slot_width = 32;
|
||||
+
|
||||
+ nslots = rtd->num_codecs;
|
||||
+
|
||||
+ for_each_rtd_codec_dais(rtd, i, dai) {
|
||||
+ int codec_nchans = 1;
|
||||
+ int mask = ((1 << codec_nchans) - 1) << nchans;
|
||||
+
|
||||
+ ret = snd_soc_dai_set_tdm_slot(dai, mask,
|
||||
+ mask, nslots, slot_width);
|
||||
+ if (ret == -EINVAL)
|
||||
+ /* Try without the RX mask */
|
||||
+ ret = snd_soc_dai_set_tdm_slot(dai, mask,
|
||||
+ 0, nslots, slot_width);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(card->dev, "DAI %s refuses TDM settings: %d",
|
||||
+ dai->name, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ nchans += codec_nchans;
|
||||
+ }
|
||||
+
|
||||
+ cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, (1 << nslots) - 1,
|
||||
+ (1 << nslots) - 1, nslots, slot_width);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(card->dev, "CPU DAI %s refuses TDM settings: %d",
|
||||
+ cpu_dai->name, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int macaudio_init(struct snd_soc_pcm_runtime *rtd)
|
||||
+{
|
||||
+ struct snd_soc_card *card = rtd->card;
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
|
||||
+ struct snd_soc_component *component;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ if (rtd->num_codecs > 1) {
|
||||
+ ret = macaudio_assign_tdm(rtd);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for_each_rtd_components(rtd, i, component)
|
||||
+ snd_soc_component_set_jack(component, &ma->jack, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void macaudio_exit(struct snd_soc_pcm_runtime *rtd)
|
||||
+{
|
||||
+ struct snd_soc_component *component;
|
||||
+ int i;
|
||||
+
|
||||
+ for_each_rtd_components(rtd, i, component)
|
||||
+ snd_soc_component_set_jack(component, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+struct fixed_kctl {
|
||||
+ char *name;
|
||||
+ char *value;
|
||||
+} macaudio_fixed_kctls[] = {
|
||||
+ {"ASI1 Sel", "Left"},
|
||||
+ {"Left ASI1 Sel", "Left"},
|
||||
+ {"Right ASI1 Sel", "Left"},
|
||||
+ {"Left Front ASI1 Sel", "Left"},
|
||||
+ {"Left Rear ASI1 Sel", "Left"},
|
||||
+ {"Right Front ASI1 Sel", "Left"},
|
||||
+ {"Right Rear ASI1 Sel", "Left"},
|
||||
+ {"Left Tweeter ASI1 Sel", "Left"},
|
||||
+ {"Left Woofer 1 ASI1 Sel", "Left"},
|
||||
+ {"Left Woofer 2 ASI1 Sel", "Left"},
|
||||
+ {"Right Tweeter ASI1 Sel", "Left"},
|
||||
+ {"Right Woofer 1 ASI1 Sel", "Left"},
|
||||
+ {"Right Woofer 2 ASI1 Sel", "Left"},
|
||||
+ {"Left ISENSE Switch", "Off"},
|
||||
+ {"Left VSENSE Switch", "Off"},
|
||||
+ {"Right ISENSE Switch", "Off"},
|
||||
+ {"Right VSENSE Switch", "Off"},
|
||||
+ {"Jack Mixer Volume", "63"},
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static struct fixed_kctl *find_fixed_kctl(const char *name)
|
||||
+{
|
||||
+ struct fixed_kctl *fctl;
|
||||
+
|
||||
+ for (fctl = macaudio_fixed_kctls; fctl->name != NULL; fctl++)
|
||||
+ if (!strcmp(fctl->name, name))
|
||||
+ return fctl;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int macaudio_probe(struct snd_soc_card *card)
|
||||
+{
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
|
||||
+ int ret;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&ma->hidden_kcontrols);
|
||||
+
|
||||
+ ma->pin.pin = "Headphones";
|
||||
+ ma->pin.mask = SND_JACK_HEADSET | SND_JACK_HEADPHONE;
|
||||
+ ret = snd_soc_card_jack_new_pins(card, ma->pin.pin,
|
||||
+ SND_JACK_HEADSET |
|
||||
+ SND_JACK_HEADPHONE |
|
||||
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
+ &ma->jack, &ma->pin, 1);
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ dev_err(card->dev, "jack creation failed: %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int macaudio_remove(struct snd_soc_card *card)
|
||||
+{
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
|
||||
+ struct snd_kcontrol *kcontrol;
|
||||
+
|
||||
+ list_for_each_entry(kcontrol, &ma->hidden_kcontrols, list)
|
||||
+ snd_ctl_free_one(kcontrol);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void snd_soc_kcontrol_set_strval(struct snd_soc_card *card,
|
||||
+ struct snd_kcontrol *kcontrol, const char *strvalue)
|
||||
+{
|
||||
+ struct snd_ctl_elem_value value;
|
||||
+ struct snd_ctl_elem_info info;
|
||||
+ int sel, i, ret;
|
||||
+
|
||||
+ ret = kcontrol->info(kcontrol, &info);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(card->dev, "can't obtain info on control '%s': %d",
|
||||
+ kcontrol->id.name, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ switch (info.type) {
|
||||
+ case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
|
||||
+ for (sel = 0; sel < info.value.enumerated.items; sel++) {
|
||||
+ info.value.enumerated.item = sel;
|
||||
+ kcontrol->info(kcontrol, &info);
|
||||
+
|
||||
+ if (!strcmp(strvalue, info.value.enumerated.name))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (sel == info.value.enumerated.items)
|
||||
+ goto not_avail;
|
||||
+
|
||||
+ for (i = 0; i < info.count; i++)
|
||||
+ value.value.enumerated.item[i] = sel;
|
||||
+ break;
|
||||
+
|
||||
+ case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
|
||||
+ sel = !strcmp(strvalue, "On");
|
||||
+
|
||||
+ if (!sel && strcmp(strvalue, "Off"))
|
||||
+ goto not_avail;
|
||||
+
|
||||
+ for (i = 0; i < info.count; i++) /* TODO */
|
||||
+ value.value.integer.value[i] = sel;
|
||||
+ break;
|
||||
+
|
||||
+ case SNDRV_CTL_ELEM_TYPE_INTEGER:
|
||||
+ if (kstrtoint(strvalue, 10, &sel))
|
||||
+ goto not_avail;
|
||||
+
|
||||
+ for (i = 0; i < info.count; i++)
|
||||
+ value.value.integer.value[i] = sel;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(card->dev, "%s: control '%s' has unsupported type %d",
|
||||
+ __func__, kcontrol->id.name, info.type);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ret = kcontrol->put(kcontrol, &value);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(card->dev, "can't set control '%s' to '%s': %d",
|
||||
+ kcontrol->id.name, strvalue, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(card->dev, "set '%s' to '%s'",
|
||||
+ kcontrol->id.name, strvalue);
|
||||
+ return;
|
||||
+
|
||||
+not_avail:
|
||||
+ dev_err(card->dev, "option '%s' on control '%s' not available",
|
||||
+ strvalue, kcontrol->id.name);
|
||||
+ return;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int macaudio_late_probe(struct snd_soc_card *card)
|
||||
+{
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
|
||||
+ struct snd_kcontrol *kcontrol;
|
||||
+ struct snd_soc_pcm_runtime *rtd;
|
||||
+ int ret;
|
||||
+
|
||||
+ list_for_each_entry(kcontrol, &ma->hidden_kcontrols, list) {
|
||||
+ struct fixed_kctl *fctl = find_fixed_kctl(kcontrol->id.name);
|
||||
+
|
||||
+ if (fctl)
|
||||
+ snd_soc_kcontrol_set_strval(card, kcontrol, fctl->value);
|
||||
+ }
|
||||
+
|
||||
+ for_each_card_rtds(card, rtd) {
|
||||
+ bool speakers_link = !strcmp(rtd->dai_link->name, "Speaker")
|
||||
+ || !strcmp(rtd->dai_link->name, "Speakers");
|
||||
+
|
||||
+ if (speakers_link && ma->speaker_chmap) {
|
||||
+ ret = snd_pcm_add_chmap_ctls(rtd->pcm,
|
||||
+ SNDRV_PCM_STREAM_PLAYBACK, ma->speaker_chmap,
|
||||
+ rtd->num_codecs, 0, NULL);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(card->dev, "failed to add channel map on '%s': %d\n",
|
||||
+ rtd->dai_link->name, ret);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int macaudio_filter_controls(struct snd_soc_card *card,
|
||||
+ struct snd_kcontrol *kcontrol)
|
||||
+{
|
||||
+ struct fixed_kctl *fctl = find_fixed_kctl(kcontrol->id.name);
|
||||
+ struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
|
||||
+
|
||||
+ dev_info(card->dev, "visiting control %s, have match %d\n",
|
||||
+ kcontrol->id.name, !!fctl);
|
||||
+
|
||||
+ if (!fctl)
|
||||
+ return 0;
|
||||
+
|
||||
+ list_add_tail(&kcontrol->list, &ma->hidden_kcontrols);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_ops macaudio_ops = {
|
||||
+ .startup = macaudio_startup,
|
||||
+ .shutdown = macaudio_shutdown,
|
||||
+ .hw_params = macaudio_hw_params,
|
||||
+};
|
||||
+
|
||||
+static const struct snd_soc_dapm_widget macaudio_snd_widgets[] = {
|
||||
+ SND_SOC_DAPM_HP("Headphones", NULL),
|
||||
+};
|
||||
+
|
||||
+static const struct snd_pcm_chmap_elem macaudio_j274_chmaps[] = {
|
||||
+ { .channels = 1,
|
||||
+ .map = { SNDRV_CHMAP_MONO } },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static const struct snd_pcm_chmap_elem macaudio_j293_chmaps[] = {
|
||||
+ { .channels = 2,
|
||||
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
|
||||
+ { .channels = 4,
|
||||
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
|
||||
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static const struct snd_pcm_chmap_elem macaudio_j314_chmaps[] = {
|
||||
+ { .channels = 2,
|
||||
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
|
||||
+ { .channels = 6,
|
||||
+ .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR,
|
||||
+ SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
|
||||
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id macaudio_snd_device_id[] = {
|
||||
+ { .compatible = "apple,j274-macaudio", .data = macaudio_j274_chmaps },
|
||||
+ { .compatible = "apple,j293-macaudio", .data = macaudio_j293_chmaps },
|
||||
+ { .compatible = "apple,j314-macaudio", .data = macaudio_j314_chmaps },
|
||||
+ { .compatible = "apple,macaudio", },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, macaudio_snd_device_id);
|
||||
+
|
||||
+static int macaudio_snd_platform_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct snd_soc_card *card;
|
||||
+ struct macaudio_snd_data *data;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct snd_soc_dai_link *link;
|
||||
+ const struct of_device_id *of_id;
|
||||
+ int ret;
|
||||
+ int i;
|
||||
+
|
||||
+ of_id = of_match_device(macaudio_snd_device_id, dev);
|
||||
+ if (!of_id)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Allocate the private data */
|
||||
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data->speaker_chmap = of_id->data;
|
||||
+ card = &data->card;
|
||||
+ snd_soc_card_set_drvdata(card, data);
|
||||
+
|
||||
+ card->owner = THIS_MODULE;
|
||||
+ card->driver_name = DRIVER_NAME;
|
||||
+ card->dev = dev;
|
||||
+ card->dapm_widgets = macaudio_snd_widgets;
|
||||
+ card->num_dapm_widgets = ARRAY_SIZE(macaudio_snd_widgets);
|
||||
+ card->probe = macaudio_probe;
|
||||
+ card->late_probe = macaudio_late_probe;
|
||||
+ card->remove = macaudio_remove;
|
||||
+ card->filter_controls = macaudio_filter_controls;
|
||||
+ card->remove = macaudio_remove;
|
||||
+
|
||||
+ ret = macaudio_parse_of(data, card);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for_each_card_prelinks(card, i, link) {
|
||||
+ link->ops = &macaudio_ops;
|
||||
+ link->init = macaudio_init;
|
||||
+ link->exit = macaudio_exit;
|
||||
+ }
|
||||
+
|
||||
+ return devm_snd_soc_register_card(dev, card);
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver macaudio_snd_driver = {
|
||||
+ .probe = macaudio_snd_platform_probe,
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .of_match_table = macaudio_snd_device_id,
|
||||
+ .pm = &snd_soc_pm_ops,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(macaudio_snd_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
|
||||
+MODULE_DESCRIPTION("Apple Silicon Macs machine sound driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,161 @@
|
||||
From 11d06018fefa454eff591ade9181e20a23acff48 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Fri, 11 Mar 2022 11:55:44 +0100
|
||||
Subject: [PATCH 081/171] ASoC: tas2764: Extend driver to SN012776
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
SN012776 is a speaker amp chip found in Apple's 2021 laptops. It appears
|
||||
similar and more-or-less compatible to TAS2764. Extend the TAS2764
|
||||
driver with some SN012776 specifics and configure the chip assuming
|
||||
it's in one of the Apple machines.
|
||||
|
||||
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
|
||||
---
|
||||
sound/soc/codecs/tas2764.c | 51 ++++++++++++++++++++++++++++++++++----
|
||||
sound/soc/codecs/tas2764.h | 3 +++
|
||||
2 files changed, 49 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
|
||||
index 4cb788f3e5f7..dd36c99e633b 100644
|
||||
--- a/sound/soc/codecs/tas2764.c
|
||||
+++ b/sound/soc/codecs/tas2764.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
+#include <linux/of_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pcm.h>
|
||||
@@ -25,13 +26,20 @@
|
||||
|
||||
#include "tas2764.h"
|
||||
|
||||
+enum tas2764_devid {
|
||||
+ DEVID_TAS2764 = 0,
|
||||
+ DEVID_SN012776 = 1
|
||||
+};
|
||||
+
|
||||
struct tas2764_priv {
|
||||
struct snd_soc_component *component;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct gpio_desc *sdz_gpio;
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
-
|
||||
+
|
||||
+ enum tas2764_devid devid;
|
||||
+
|
||||
int v_sense_slot;
|
||||
int i_sense_slot;
|
||||
};
|
||||
@@ -502,10 +510,16 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+static uint8_t sn012776_bop_presets[] = {
|
||||
+ 0x01, 0x32, 0x02, 0x22, 0x83, 0x2d, 0x80, 0x02, 0x06,
|
||||
+ 0x32, 0x46, 0x30, 0x02, 0x06, 0x38, 0x40, 0x30, 0x02,
|
||||
+ 0x06, 0x3e, 0x37, 0x30, 0xff, 0xe6
|
||||
+};
|
||||
+
|
||||
static int tas2764_codec_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
|
||||
- int ret;
|
||||
+ int ret, i;
|
||||
|
||||
tas2764->component = component;
|
||||
|
||||
@@ -532,6 +546,23 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ if (tas2764->devid == DEVID_SN012776) {
|
||||
+ ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
+ TAS2764_PWR_CTRL_BOP_SRC,
|
||||
+ TAS2764_PWR_CTRL_BOP_SRC);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(sn012776_bop_presets); i++) {
|
||||
+ ret = snd_soc_component_write(component,
|
||||
+ TAS2764_BOP_CFG0 + i,
|
||||
+ sn012776_bop_presets[i]);
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -631,9 +662,12 @@ static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct of_device_id tas2764_of_match[];
|
||||
+
|
||||
static int tas2764_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct tas2764_priv *tas2764;
|
||||
+ const struct of_device_id *of_id = NULL;
|
||||
int result;
|
||||
|
||||
tas2764 = devm_kzalloc(&client->dev, sizeof(struct tas2764_priv),
|
||||
@@ -641,6 +675,14 @@ static int tas2764_i2c_probe(struct i2c_client *client)
|
||||
if (!tas2764)
|
||||
return -ENOMEM;
|
||||
|
||||
+ if (client->dev.of_node)
|
||||
+ of_id = of_match_device(tas2764_of_match, &client->dev);
|
||||
+
|
||||
+ if (of_id)
|
||||
+ tas2764->devid = (enum tas2764_devid) of_id->data;
|
||||
+ else
|
||||
+ tas2764->devid = DEVID_TAS2764;
|
||||
+
|
||||
tas2764->dev = &client->dev;
|
||||
i2c_set_clientdata(client, tas2764);
|
||||
dev_set_drvdata(&client->dev, tas2764);
|
||||
@@ -674,13 +716,12 @@ static const struct i2c_device_id tas2764_i2c_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id);
|
||||
|
||||
-#if defined(CONFIG_OF)
|
||||
static const struct of_device_id tas2764_of_match[] = {
|
||||
- { .compatible = "ti,tas2764" },
|
||||
+ { .compatible = "ti,tas2764", .data = (void*) DEVID_TAS2764 },
|
||||
+ { .compatible = "ti,sn012776", .data = (void*) DEVID_SN012776 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tas2764_of_match);
|
||||
-#endif
|
||||
|
||||
static struct i2c_driver tas2764_i2c_driver = {
|
||||
.driver = {
|
||||
diff --git a/sound/soc/codecs/tas2764.h b/sound/soc/codecs/tas2764.h
|
||||
index f015f22a083b..d7e171a9480c 100644
|
||||
--- a/sound/soc/codecs/tas2764.h
|
||||
+++ b/sound/soc/codecs/tas2764.h
|
||||
@@ -29,6 +29,7 @@
|
||||
#define TAS2764_PWR_CTRL_ACTIVE 0x0
|
||||
#define TAS2764_PWR_CTRL_MUTE BIT(0)
|
||||
#define TAS2764_PWR_CTRL_SHUTDOWN BIT(1)
|
||||
+#define TAS2764_PWR_CTRL_BOP_SRC BIT(7)
|
||||
|
||||
#define TAS2764_VSENSE_POWER_EN 3
|
||||
#define TAS2764_ISENSE_POWER_EN 4
|
||||
@@ -87,4 +88,6 @@
|
||||
#define TAS2764_TDM_CFG6_ISNS_ENABLE BIT(6)
|
||||
#define TAS2764_TDM_CFG6_50_MASK GENMASK(5, 0)
|
||||
|
||||
+#define TAS2764_BOP_CFG0 TAS2764_REG(0X0, 0x1d)
|
||||
+
|
||||
#endif /* __TAS2764__ */
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,147 @@
|
||||
From b94fc3351432c6a0a75962c4af03750d8879d205 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 13 Mar 2022 03:13:08 +0900
|
||||
Subject: [PATCH 082/171] ASoC: tas2764: Add workaround for spurious shutdowns
|
||||
on SN012776
|
||||
|
||||
It seems that on SHUTDOWN -> MUTE transitions, the SN012776 can end up
|
||||
in a borked state raising an overcurrent error.
|
||||
|
||||
Going through the ACTIVE state seems to make it work reliably, so do
|
||||
that.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
sound/soc/codecs/tas2764.c | 65 +++++++++++++++++++++-----------------
|
||||
1 file changed, 36 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
|
||||
index dd36c99e633b..b3c99f470916 100644
|
||||
--- a/sound/soc/codecs/tas2764.c
|
||||
+++ b/sound/soc/codecs/tas2764.c
|
||||
@@ -58,27 +58,47 @@ static void tas2764_reset(struct tas2764_priv *tas2764)
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
+static int tas2764_set_power(struct tas2764_priv *tas2764, u8 mode)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ // TODO: Does this only affect the SN012776 variant?
|
||||
+ if (tas2764->devid == DEVID_SN012776 && mode == TAS2764_PWR_CTRL_MUTE) {
|
||||
+ ret = snd_soc_component_update_bits(tas2764->component,
|
||||
+ TAS2764_PWR_CTRL,
|
||||
+ TAS2764_PWR_CTRL_MASK,
|
||||
+ TAS2764_PWR_CTRL_ACTIVE);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = snd_soc_component_update_bits(tas2764->component,
|
||||
+ TAS2764_PWR_CTRL,
|
||||
+ TAS2764_PWR_CTRL_MASK,
|
||||
+ mode);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int tas2764_set_bias_level(struct snd_soc_component *component,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
|
||||
+ u8 mode;
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
- TAS2764_PWR_CTRL_MASK,
|
||||
- TAS2764_PWR_CTRL_ACTIVE);
|
||||
+ mode = TAS2764_PWR_CTRL_ACTIVE;
|
||||
break;
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
- TAS2764_PWR_CTRL_MASK,
|
||||
- TAS2764_PWR_CTRL_MUTE);
|
||||
+ mode = TAS2764_PWR_CTRL_MUTE;
|
||||
break;
|
||||
case SND_SOC_BIAS_OFF:
|
||||
- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
- TAS2764_PWR_CTRL_MASK,
|
||||
- TAS2764_PWR_CTRL_SHUTDOWN);
|
||||
+ mode = TAS2764_PWR_CTRL_SHUTDOWN;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -87,7 +107,7 @@ static int tas2764_set_bias_level(struct snd_soc_component *component,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return tas2764_set_power(tas2764, mode);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@@ -96,10 +116,7 @@ static int tas2764_codec_suspend(struct snd_soc_component *component)
|
||||
struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
|
||||
int ret;
|
||||
|
||||
- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
- TAS2764_PWR_CTRL_MASK,
|
||||
- TAS2764_PWR_CTRL_SHUTDOWN);
|
||||
-
|
||||
+ ret = tas2764_set_power(tas2764, TAS2764_PWR_CTRL_SHUTDOWN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -122,10 +139,7 @@ static int tas2764_codec_resume(struct snd_soc_component *component)
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
- TAS2764_PWR_CTRL_MASK,
|
||||
- TAS2764_PWR_CTRL_ACTIVE);
|
||||
-
|
||||
+ ret = tas2764_set_power(tas2764, TAS2764_PWR_CTRL_ACTIVE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -154,28 +168,21 @@ static int tas2764_dac_event(struct snd_soc_dapm_widget *w,
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
|
||||
- int ret;
|
||||
+ u8 mode;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
- TAS2764_PWR_CTRL_MASK,
|
||||
- TAS2764_PWR_CTRL_MUTE);
|
||||
+ mode = TAS2764_PWR_CTRL_MUTE;
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
|
||||
- TAS2764_PWR_CTRL_MASK,
|
||||
- TAS2764_PWR_CTRL_SHUTDOWN);
|
||||
+ mode = TAS2764_PWR_CTRL_SHUTDOWN;
|
||||
break;
|
||||
default:
|
||||
dev_err(tas2764->dev, "Unsupported event\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- return 0;
|
||||
+ return tas2764_set_power(tas2764, mode);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new isense_switch =
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 91b1840731bc223fdfa0b86b0d9b1904213e3299 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
||||
Date: Tue, 15 Mar 2022 19:41:05 +0100
|
||||
Subject: [PATCH 083/171] ASoC: macaudio: State missing simple-card-utils
|
||||
dependency
|
||||
|
||||
State that the macaudio module depends on simple-card-utils to fix build
|
||||
errors of the kind:
|
||||
|
||||
ld.lld: error: undefined symbol: asoc_simple_parse_routing
|
||||
>>> referenced by macaudio.c:59 (sound/soc/apple/macaudio.c:59)
|
||||
>>> soc/apple/macaudio.o:(macaudio_snd_platform_probe) in archive
|
||||
---
|
||||
sound/soc/apple/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
|
||||
index a3f6a97140e2..ce6188aa659d 100644
|
||||
--- a/sound/soc/apple/Kconfig
|
||||
+++ b/sound/soc/apple/Kconfig
|
||||
@@ -3,6 +3,7 @@ config SND_SOC_APPLE_SILICON
|
||||
tristate "ASoC machine driver for Apple Silicon Macs"
|
||||
depends on ARCH_APPLE || COMPILE_TEST
|
||||
select SND_SOC_APPLE_MCA
|
||||
+ select SND_SIMPLE_CARD_UTILS
|
||||
default ARCH_APPLE
|
||||
help
|
||||
This option enables an ASoC machine driver for Apple Silicon Macs.
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,25 @@
|
||||
From ddf6983d9229819248d0373854d32b4e4a0e123d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sat, 19 Mar 2022 06:06:20 +0900
|
||||
Subject: [PATCH 084/171] macaudio: Unbork jack volume
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
sound/soc/apple/macaudio.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/sound/soc/apple/macaudio.c b/sound/soc/apple/macaudio.c
|
||||
index a1f2b1fcea1f..d39ef638ea95 100644
|
||||
--- a/sound/soc/apple/macaudio.c
|
||||
+++ b/sound/soc/apple/macaudio.c
|
||||
@@ -305,7 +305,6 @@ struct fixed_kctl {
|
||||
{"Left VSENSE Switch", "Off"},
|
||||
{"Right ISENSE Switch", "Off"},
|
||||
{"Right VSENSE Switch", "Off"},
|
||||
- {"Jack Mixer Volume", "63"},
|
||||
{ }
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,88 @@
|
||||
From 4c5d245b445841af3cff2d861a3b461c645b3b57 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sun, 26 Dec 2021 22:04:09 +0900
|
||||
Subject: [PATCH 085/171] dt-bindings: net: bcm4329-fmac: Add Apple properties
|
||||
& chips
|
||||
|
||||
This binding is currently used for SDIO devices, but these chips are
|
||||
also used as PCIe devices on DT platforms and may be represented in the
|
||||
DT. Re-use the existing binding and add chip compatibles used by Apple
|
||||
T2 and M1 platforms (the T2 ones are not known to be used in DT
|
||||
platforms, but we might as well document them).
|
||||
|
||||
Then, add properties required for firmware selection and calibration on
|
||||
M1 machines.
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../net/wireless/brcm,bcm4329-fmac.yaml | 37 +++++++++++++++++--
|
||||
1 file changed, 34 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
|
||||
index c11f23b20c4c..8b4147c64355 100644
|
||||
--- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
|
||||
@@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/net/wireless/brcm,bcm4329-fmac.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
-title: Broadcom BCM4329 family fullmac wireless SDIO devices
|
||||
+title: Broadcom BCM4329 family fullmac wireless SDIO/PCIE devices
|
||||
|
||||
maintainers:
|
||||
- Arend van Spriel <arend@broadcom.com>
|
||||
@@ -42,10 +42,16 @@ properties:
|
||||
- cypress,cyw43012-fmac
|
||||
- const: brcm,bcm4329-fmac
|
||||
- const: brcm,bcm4329-fmac
|
||||
+ - enum:
|
||||
+ - pci14e4,43dc # BCM4355
|
||||
+ - pci14e4,4464 # BCM4364
|
||||
+ - pci14e4,4488 # BCM4377
|
||||
+ - pci14e4,4425 # BCM4378
|
||||
+ - pci14e4,4433 # BCM4387
|
||||
|
||||
reg:
|
||||
- description: SDIO function number for the device, for most cases
|
||||
- this will be 1.
|
||||
+ description: SDIO function number for the device (for most cases
|
||||
+ this will be 1) or PCI device identifier.
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
@@ -75,6 +81,31 @@ properties:
|
||||
items:
|
||||
pattern: '^[A-Z][A-Z]-[A-Z][0-9A-Z]-[0-9]+$'
|
||||
|
||||
+ brcm,cal-blob:
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
+ description: A per-device calibration blob for the Wi-Fi radio. This
|
||||
+ should be filled in by the bootloader from platform configuration
|
||||
+ data, if necessary, and will be uploaded to the device if present.
|
||||
+
|
||||
+ brcm,board-type:
|
||||
+ $ref: /schemas/types.yaml#/definitions/string
|
||||
+ description: Overrides the board type, which is normally the compatible of
|
||||
+ the root node. This can be used to decouple the overall system board or
|
||||
+ device name from the board type for WiFi purposes, which is used to
|
||||
+ construct firmware and NVRAM configuration filenames, allowing for
|
||||
+ multiple devices that share the same module or characteristics for the
|
||||
+ WiFi subsystem to share the same firmware/NVRAM files. On Apple platforms,
|
||||
+ this should be the Apple module-instance codename prefixed by "apple,",
|
||||
+ e.g. "apple,honshu".
|
||||
+
|
||||
+ apple,antenna-sku:
|
||||
+ $ref: /schemas/types.yaml#/definitions/string
|
||||
+ description: Antenna SKU used to identify a specific antenna configuration
|
||||
+ on Apple platforms. This is use to build firmware filenames, to allow
|
||||
+ platforms with different antenna configs to have different firmware and/or
|
||||
+ NVRAM. This would normally be filled in by the bootloader from platform
|
||||
+ configuration data.
|
||||
+
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,76 @@
|
||||
From 6e3dabd08775a78c7a6ba10779bdb9418852cd1b Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Sat, 18 Dec 2021 20:52:04 +0900
|
||||
Subject: [PATCH 086/171] brcmfmac: firmware: Handle per-board clm_blob files
|
||||
|
||||
Teach brcm_alt_fw_paths to correctly split off variable length
|
||||
extensions, and enable alt firmware lookups for the CLM blob firmware
|
||||
requests.
|
||||
|
||||
Apple platforms have per-board CLM blob files.
|
||||
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/firmware.c | 33 +++++++++++--------
|
||||
1 file changed, 20 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
index dcbe55b56e43..deacd39b3f7b 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
@@ -596,22 +596,29 @@ static int brcmf_fw_complete_request(const struct firmware *fw,
|
||||
|
||||
static char *brcm_alt_fw_path(const char *path, const char *board_type)
|
||||
{
|
||||
- char alt_path[BRCMF_FW_NAME_LEN];
|
||||
- char suffix[5];
|
||||
+ char base[BRCMF_FW_NAME_LEN];
|
||||
+ const char *suffix;
|
||||
+ char *ret;
|
||||
|
||||
- strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
|
||||
- /* At least one character + suffix */
|
||||
- if (strlen(alt_path) < 5)
|
||||
+ if (!board_type)
|
||||
return NULL;
|
||||
|
||||
- /* strip .txt or .bin at the end */
|
||||
- strscpy(suffix, alt_path + strlen(alt_path) - 4, 5);
|
||||
- alt_path[strlen(alt_path) - 4] = 0;
|
||||
- strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
|
||||
- strlcat(alt_path, board_type, BRCMF_FW_NAME_LEN);
|
||||
- strlcat(alt_path, suffix, BRCMF_FW_NAME_LEN);
|
||||
+ suffix = strrchr(path, '.');
|
||||
+ if (!suffix || suffix == path)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* strip extension at the end */
|
||||
+ strscpy(base, path, BRCMF_FW_NAME_LEN);
|
||||
+ base[suffix - path] = 0;
|
||||
+
|
||||
+ ret = kasprintf(GFP_KERNEL, "%s.%s%s", base, board_type, suffix);
|
||||
+ if (!ret)
|
||||
+ brcmf_err("out of memory allocating firmware path for '%s'\n",
|
||||
+ path);
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "FW alt path: %s\n", ret);
|
||||
|
||||
- return kstrdup(alt_path, GFP_KERNEL);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int brcmf_fw_request_firmware(const struct firmware **fw,
|
||||
@@ -621,7 +628,7 @@ static int brcmf_fw_request_firmware(const struct firmware **fw,
|
||||
int ret;
|
||||
|
||||
/* Files can be board-specific, first try a board-specific path */
|
||||
- if (cur->type == BRCMF_FW_TYPE_NVRAM && fwctx->req->board_type) {
|
||||
+ if (fwctx->req->board_type) {
|
||||
char *alt_path;
|
||||
|
||||
alt_path = brcm_alt_fw_path(cur->path, fwctx->req->board_type);
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,376 @@
|
||||
From a0e0f6cebc9a2112a11c56d0f6c55681cf2b120d Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:13:49 +0900
|
||||
Subject: [PATCH 087/171] brcmfmac: pcie/sdio/usb: Get CLM blob via standard
|
||||
firmware mechanism
|
||||
|
||||
Now that the firmware fetcher can handle per-board CLM files, load the
|
||||
CLM blob alongside the other firmware files and change the bus API to
|
||||
just return the existing blob, instead of fetching the filename.
|
||||
|
||||
This enables per-board CLM blobs, which are required on Apple platforms.
|
||||
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/bus.h | 19 ++++++---
|
||||
.../broadcom/brcm80211/brcmfmac/common.c | 12 +-----
|
||||
.../broadcom/brcm80211/brcmfmac/pcie.c | 39 ++++++++++++-------
|
||||
.../broadcom/brcm80211/brcmfmac/sdio.c | 36 ++++++++++-------
|
||||
.../broadcom/brcm80211/brcmfmac/sdio.h | 2 +
|
||||
.../broadcom/brcm80211/brcmfmac/usb.c | 23 +++--------
|
||||
6 files changed, 69 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
index 3f5da3bb6aa5..b13af8f631f3 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
@@ -7,6 +7,8 @@
|
||||
#define BRCMFMAC_BUS_H
|
||||
|
||||
#include "debug.h"
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/firmware.h>
|
||||
|
||||
/* IDs of the 6 default common rings of msgbuf protocol */
|
||||
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
|
||||
@@ -34,6 +36,11 @@ enum brcmf_bus_protocol_type {
|
||||
BRCMF_PROTO_MSGBUF
|
||||
};
|
||||
|
||||
+/* Firmware blobs that may be available */
|
||||
+enum brcmf_blob_type {
|
||||
+ BRCMF_BLOB_CLM,
|
||||
+};
|
||||
+
|
||||
struct brcmf_mp_device;
|
||||
|
||||
struct brcmf_bus_dcmd {
|
||||
@@ -60,7 +67,7 @@ struct brcmf_bus_dcmd {
|
||||
* @wowl_config: specify if dongle is configured for wowl when going to suspend
|
||||
* @get_ramsize: obtain size of device memory.
|
||||
* @get_memdump: obtain device memory dump in provided buffer.
|
||||
- * @get_fwname: obtain firmware name.
|
||||
+ * @get_blob: obtain a firmware blob.
|
||||
*
|
||||
* This structure provides an abstract interface towards the
|
||||
* bus specific driver. For control messages to common driver
|
||||
@@ -77,8 +84,8 @@ struct brcmf_bus_ops {
|
||||
void (*wowl_config)(struct device *dev, bool enabled);
|
||||
size_t (*get_ramsize)(struct device *dev);
|
||||
int (*get_memdump)(struct device *dev, void *data, size_t len);
|
||||
- int (*get_fwname)(struct device *dev, const char *ext,
|
||||
- unsigned char *fw_name);
|
||||
+ int (*get_blob)(struct device *dev, const struct firmware **fw,
|
||||
+ enum brcmf_blob_type type);
|
||||
void (*debugfs_create)(struct device *dev);
|
||||
int (*reset)(struct device *dev);
|
||||
};
|
||||
@@ -220,10 +227,10 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
|
||||
}
|
||||
|
||||
static inline
|
||||
-int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext,
|
||||
- unsigned char *fw_name)
|
||||
+int brcmf_bus_get_blob(struct brcmf_bus *bus, const struct firmware **fw,
|
||||
+ enum brcmf_blob_type type)
|
||||
{
|
||||
- return bus->ops->get_fwname(bus->dev, ext, fw_name);
|
||||
+ return bus->ops->get_blob(bus->dev, fw, type);
|
||||
}
|
||||
|
||||
static inline
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
index fe01da9e620d..95d4c133efdd 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -123,7 +123,6 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
|
||||
struct brcmf_bus *bus = drvr->bus_if;
|
||||
struct brcmf_dload_data_le *chunk_buf;
|
||||
const struct firmware *clm = NULL;
|
||||
- u8 clm_name[BRCMF_FW_NAME_LEN];
|
||||
u32 chunk_len;
|
||||
u32 datalen;
|
||||
u32 cumulative_len;
|
||||
@@ -133,15 +132,8 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
- memset(clm_name, 0, sizeof(clm_name));
|
||||
- err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name);
|
||||
- if (err) {
|
||||
- bphy_err(drvr, "get CLM blob file name failed (%d)\n", err);
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- err = firmware_request_nowarn(&clm, clm_name, bus->dev);
|
||||
- if (err) {
|
||||
+ err = brcmf_bus_get_blob(bus, &clm, BRCMF_BLOB_CLM);
|
||||
+ if (err || !clm) {
|
||||
brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n",
|
||||
err);
|
||||
return 0;
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index 97f0f13dfe50..ec73d2620ec9 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -66,6 +66,7 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txt");
|
||||
|
||||
/* per-board firmware binaries */
|
||||
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.bin");
|
||||
+MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.clm_blob");
|
||||
|
||||
static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
|
||||
@@ -261,6 +262,8 @@ struct brcmf_pciedev_info {
|
||||
struct pci_dev *pdev;
|
||||
char fw_name[BRCMF_FW_NAME_LEN];
|
||||
char nvram_name[BRCMF_FW_NAME_LEN];
|
||||
+ char clm_name[BRCMF_FW_NAME_LEN];
|
||||
+ const struct firmware *clm_fw;
|
||||
void __iomem *regs;
|
||||
void __iomem *tcm;
|
||||
u32 ram_base;
|
||||
@@ -1382,23 +1385,25 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static
|
||||
-int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
|
||||
+static int brcmf_pcie_get_blob(struct device *dev, const struct firmware **fw,
|
||||
+ enum brcmf_blob_type type)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
- struct brcmf_fw_request *fwreq;
|
||||
- struct brcmf_fw_name fwnames[] = {
|
||||
- { ext, fw_name },
|
||||
- };
|
||||
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
|
||||
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
|
||||
|
||||
- fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
|
||||
- brcmf_pcie_fwnames,
|
||||
- ARRAY_SIZE(brcmf_pcie_fwnames),
|
||||
- fwnames, ARRAY_SIZE(fwnames));
|
||||
- if (!fwreq)
|
||||
- return -ENOMEM;
|
||||
+ switch (type) {
|
||||
+ case BRCMF_BLOB_CLM:
|
||||
+ *fw = devinfo->clm_fw;
|
||||
+ devinfo->clm_fw = NULL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ if (!*fw)
|
||||
+ return -ENOENT;
|
||||
|
||||
- kfree(fwreq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1445,7 +1450,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
|
||||
.wowl_config = brcmf_pcie_wowl_config,
|
||||
.get_ramsize = brcmf_pcie_get_ramsize,
|
||||
.get_memdump = brcmf_pcie_get_memdump,
|
||||
- .get_fwname = brcmf_pcie_get_fwname,
|
||||
+ .get_blob = brcmf_pcie_get_blob,
|
||||
.reset = brcmf_pcie_reset,
|
||||
};
|
||||
|
||||
@@ -1731,6 +1736,7 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
|
||||
|
||||
#define BRCMF_PCIE_FW_CODE 0
|
||||
#define BRCMF_PCIE_FW_NVRAM 1
|
||||
+#define BRCMF_PCIE_FW_CLM 2
|
||||
|
||||
static void brcmf_pcie_setup(struct device *dev, int ret,
|
||||
struct brcmf_fw_request *fwreq)
|
||||
@@ -1755,6 +1761,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
|
||||
fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary;
|
||||
nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data;
|
||||
nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len;
|
||||
+ devinfo->clm_fw = fwreq->items[BRCMF_PCIE_FW_CLM].binary;
|
||||
kfree(fwreq);
|
||||
|
||||
ret = brcmf_chip_get_raminfo(devinfo->ci);
|
||||
@@ -1830,6 +1837,7 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
|
||||
struct brcmf_fw_name fwnames[] = {
|
||||
{ ".bin", devinfo->fw_name },
|
||||
{ ".txt", devinfo->nvram_name },
|
||||
+ { ".clm_blob", devinfo->clm_name },
|
||||
};
|
||||
|
||||
fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev,
|
||||
@@ -1842,6 +1850,8 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
|
||||
fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
|
||||
fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
|
||||
fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
|
||||
+ fwreq->items[BRCMF_PCIE_FW_CLM].type = BRCMF_FW_TYPE_BINARY;
|
||||
+ fwreq->items[BRCMF_PCIE_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL;
|
||||
fwreq->board_type = devinfo->settings->board_type;
|
||||
/* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */
|
||||
fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1;
|
||||
@@ -1981,6 +1991,7 @@ brcmf_pcie_remove(struct pci_dev *pdev)
|
||||
brcmf_pcie_release_ringbuffers(devinfo);
|
||||
brcmf_pcie_reset_device(devinfo);
|
||||
brcmf_pcie_release_resource(devinfo);
|
||||
+ release_firmware(devinfo->clm_fw);
|
||||
|
||||
if (devinfo->ci)
|
||||
brcmf_chip_detach(devinfo->ci);
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
index 212fbbe1cd7e..27dc8ed29ac8 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -4130,23 +4130,24 @@ brcmf_sdio_watchdog(struct timer_list *t)
|
||||
}
|
||||
}
|
||||
|
||||
-static
|
||||
-int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
|
||||
+static int brcmf_sdio_get_blob(struct device *dev, const struct firmware **fw,
|
||||
+ enum brcmf_blob_type type)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
- struct brcmf_fw_request *fwreq;
|
||||
- struct brcmf_fw_name fwnames[] = {
|
||||
- { ext, fw_name },
|
||||
- };
|
||||
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
|
||||
- fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
|
||||
- brcmf_sdio_fwnames,
|
||||
- ARRAY_SIZE(brcmf_sdio_fwnames),
|
||||
- fwnames, ARRAY_SIZE(fwnames));
|
||||
- if (!fwreq)
|
||||
- return -ENOMEM;
|
||||
+ switch (type) {
|
||||
+ case BRCMF_BLOB_CLM:
|
||||
+ *fw = sdiodev->clm_fw;
|
||||
+ sdiodev->clm_fw = NULL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ if (!*fw)
|
||||
+ return -ENOENT;
|
||||
|
||||
- kfree(fwreq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4189,13 +4190,14 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
|
||||
.wowl_config = brcmf_sdio_wowl_config,
|
||||
.get_ramsize = brcmf_sdio_bus_get_ramsize,
|
||||
.get_memdump = brcmf_sdio_bus_get_memdump,
|
||||
- .get_fwname = brcmf_sdio_get_fwname,
|
||||
+ .get_blob = brcmf_sdio_get_blob,
|
||||
.debugfs_create = brcmf_sdio_debugfs_create,
|
||||
.reset = brcmf_sdio_bus_reset
|
||||
};
|
||||
|
||||
#define BRCMF_SDIO_FW_CODE 0
|
||||
#define BRCMF_SDIO_FW_NVRAM 1
|
||||
+#define BRCMF_SDIO_FW_CLM 2
|
||||
|
||||
static void brcmf_sdio_firmware_callback(struct device *dev, int err,
|
||||
struct brcmf_fw_request *fwreq)
|
||||
@@ -4218,6 +4220,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
|
||||
code = fwreq->items[BRCMF_SDIO_FW_CODE].binary;
|
||||
nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data;
|
||||
nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len;
|
||||
+ sdiod->clm_fw = fwreq->items[BRCMF_SDIO_FW_CLM].binary;
|
||||
kfree(fwreq);
|
||||
|
||||
/* try to download image and nvram to the dongle */
|
||||
@@ -4416,6 +4419,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
|
||||
struct brcmf_fw_name fwnames[] = {
|
||||
{ ".bin", bus->sdiodev->fw_name },
|
||||
{ ".txt", bus->sdiodev->nvram_name },
|
||||
+ { ".clm_blob", bus->sdiodev->clm_name },
|
||||
};
|
||||
|
||||
fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev,
|
||||
@@ -4427,6 +4431,8 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
|
||||
|
||||
fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
|
||||
fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
|
||||
+ fwreq->items[BRCMF_SDIO_FW_CLM].type = BRCMF_FW_TYPE_BINARY;
|
||||
+ fwreq->items[BRCMF_SDIO_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL;
|
||||
fwreq->board_type = bus->sdiodev->settings->board_type;
|
||||
|
||||
return fwreq;
|
||||
@@ -4583,6 +4589,8 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
|
||||
if (bus->sdiodev->settings)
|
||||
brcmf_release_module_param(bus->sdiodev->settings);
|
||||
|
||||
+ release_firmware(bus->sdiodev->clm_fw);
|
||||
+ bus->sdiodev->clm_fw = NULL;
|
||||
kfree(bus->rxbuf);
|
||||
kfree(bus->hdrbuf);
|
||||
kfree(bus);
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
index 15d2c02fa3ec..7b74c295e4c9 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -186,9 +186,11 @@ struct brcmf_sdio_dev {
|
||||
struct sg_table sgtable;
|
||||
char fw_name[BRCMF_FW_NAME_LEN];
|
||||
char nvram_name[BRCMF_FW_NAME_LEN];
|
||||
+ char clm_name[BRCMF_FW_NAME_LEN];
|
||||
bool wowl_enabled;
|
||||
enum brcmf_sdiod_state state;
|
||||
struct brcmf_sdiod_freezer *freezer;
|
||||
+ const struct firmware *clm_fw;
|
||||
};
|
||||
|
||||
/* sdio core registers */
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
index 9fb68c2dc7e3..85e18fb9c497 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -1154,24 +1154,11 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static
|
||||
-int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
|
||||
+static int brcmf_usb_get_blob(struct device *dev, const struct firmware **fw,
|
||||
+ enum brcmf_blob_type type)
|
||||
{
|
||||
- struct brcmf_bus *bus = dev_get_drvdata(dev);
|
||||
- struct brcmf_fw_request *fwreq;
|
||||
- struct brcmf_fw_name fwnames[] = {
|
||||
- { ext, fw_name },
|
||||
- };
|
||||
-
|
||||
- fwreq = brcmf_fw_alloc_request(bus->chip, bus->chiprev,
|
||||
- brcmf_usb_fwnames,
|
||||
- ARRAY_SIZE(brcmf_usb_fwnames),
|
||||
- fwnames, ARRAY_SIZE(fwnames));
|
||||
- if (!fwreq)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- kfree(fwreq);
|
||||
- return 0;
|
||||
+ /* No blobs for USB devices... */
|
||||
+ return -ENOENT;
|
||||
}
|
||||
|
||||
static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
|
||||
@@ -1180,7 +1167,7 @@ static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
|
||||
.txdata = brcmf_usb_tx,
|
||||
.txctl = brcmf_usb_tx_ctlpkt,
|
||||
.rxctl = brcmf_usb_rx_ctlpkt,
|
||||
- .get_fwname = brcmf_usb_get_fwname,
|
||||
+ .get_blob = brcmf_usb_get_blob,
|
||||
};
|
||||
|
||||
#define BRCMF_USB_FW_CODE 0
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,181 @@
|
||||
From 95500b48e476af858b0a3ae6c96d9fe8ab92cb61 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Fri, 7 Jan 2022 11:14:44 +0900
|
||||
Subject: [PATCH 088/171] brcmfmac: firmware: Support passing in multiple
|
||||
board_types
|
||||
|
||||
Apple platforms have firmware and config files identified with multiple
|
||||
dimensions. We want to be able to find the most specific firmware
|
||||
available for any given platform, progressively trying more general
|
||||
firmwares.
|
||||
|
||||
To do this, first add support for passing in multiple board_types,
|
||||
which will be tried in sequence.
|
||||
|
||||
Since this will cause more log spam due to missing firmwares, also
|
||||
switch the secondary firmware fecthes to use the _nowarn variant, which
|
||||
will not log if the firmware is not found.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/firmware.c | 53 +++++++++++++++----
|
||||
.../broadcom/brcm80211/brcmfmac/firmware.h | 4 +-
|
||||
.../broadcom/brcm80211/brcmfmac/pcie.c | 4 +-
|
||||
.../broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
|
||||
4 files changed, 49 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
index deacd39b3f7b..d04a59cf4a1e 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
@@ -430,6 +430,7 @@ struct brcmf_fw {
|
||||
struct device *dev;
|
||||
struct brcmf_fw_request *req;
|
||||
u32 curpos;
|
||||
+ unsigned int board_index;
|
||||
void (*done)(struct device *dev, int err, struct brcmf_fw_request *req);
|
||||
};
|
||||
|
||||
@@ -625,17 +626,21 @@ static int brcmf_fw_request_firmware(const struct firmware **fw,
|
||||
struct brcmf_fw *fwctx)
|
||||
{
|
||||
struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos];
|
||||
+ unsigned int i;
|
||||
int ret;
|
||||
|
||||
- /* Files can be board-specific, first try a board-specific path */
|
||||
- if (fwctx->req->board_type) {
|
||||
+ /* Files can be board-specific, first try board-specific paths */
|
||||
+ for (i = 0; i < ARRAY_SIZE(fwctx->req->board_types); i++) {
|
||||
char *alt_path;
|
||||
|
||||
- alt_path = brcm_alt_fw_path(cur->path, fwctx->req->board_type);
|
||||
+ if (!fwctx->req->board_types[i])
|
||||
+ goto fallback;
|
||||
+ alt_path = brcm_alt_fw_path(cur->path,
|
||||
+ fwctx->req->board_types[i]);
|
||||
if (!alt_path)
|
||||
goto fallback;
|
||||
|
||||
- ret = request_firmware(fw, alt_path, fwctx->dev);
|
||||
+ ret = firmware_request_nowarn(fw, alt_path, fwctx->dev);
|
||||
kfree(alt_path);
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
@@ -669,15 +674,40 @@ static void brcmf_fw_request_done_alt_path(const struct firmware *fw, void *ctx)
|
||||
{
|
||||
struct brcmf_fw *fwctx = ctx;
|
||||
struct brcmf_fw_item *first = &fwctx->req->items[0];
|
||||
+ const char *board_type, *alt_path;
|
||||
int ret = 0;
|
||||
|
||||
- /* Fall back to canonical path if board firmware not found */
|
||||
- if (!fw)
|
||||
- ret = request_firmware_nowait(THIS_MODULE, true, first->path,
|
||||
+ if (fw) {
|
||||
+ brcmf_fw_request_done(fw, ctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Try next board firmware */
|
||||
+ if (fwctx->board_index < ARRAY_SIZE(fwctx->req->board_types)) {
|
||||
+ board_type = fwctx->req->board_types[fwctx->board_index++];
|
||||
+ if (!board_type)
|
||||
+ goto fallback;
|
||||
+ alt_path = brcm_alt_fw_path(first->path, board_type);
|
||||
+ if (!alt_path)
|
||||
+ goto fallback;
|
||||
+
|
||||
+ ret = request_firmware_nowait(THIS_MODULE, true, alt_path,
|
||||
fwctx->dev, GFP_KERNEL, fwctx,
|
||||
- brcmf_fw_request_done);
|
||||
+ brcmf_fw_request_done_alt_path);
|
||||
+ kfree(alt_path);
|
||||
|
||||
- if (fw || ret < 0)
|
||||
+ if (ret < 0)
|
||||
+ brcmf_fw_request_done(fw, ctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+fallback:
|
||||
+ /* Fall back to canonical path if board firmware not found */
|
||||
+ ret = request_firmware_nowait(THIS_MODULE, true, first->path,
|
||||
+ fwctx->dev, GFP_KERNEL, fwctx,
|
||||
+ brcmf_fw_request_done);
|
||||
+
|
||||
+ if (ret < 0)
|
||||
brcmf_fw_request_done(fw, ctx);
|
||||
}
|
||||
|
||||
@@ -721,10 +751,11 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
|
||||
fwctx->done = fw_cb;
|
||||
|
||||
/* First try alternative board-specific path if any */
|
||||
- if (fwctx->req->board_type)
|
||||
+ if (fwctx->req->board_types[0])
|
||||
alt_path = brcm_alt_fw_path(first->path,
|
||||
- fwctx->req->board_type);
|
||||
+ fwctx->req->board_types[0]);
|
||||
if (alt_path) {
|
||||
+ fwctx->board_index++;
|
||||
ret = request_firmware_nowait(THIS_MODULE, true, alt_path,
|
||||
fwctx->dev, GFP_KERNEL, fwctx,
|
||||
brcmf_fw_request_done_alt_path);
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
|
||||
index e290dec9c53d..1266cbaee072 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#define BRCMF_FW_DEFAULT_PATH "brcm/"
|
||||
|
||||
+#define BRCMF_FW_MAX_BOARD_TYPES 8
|
||||
+
|
||||
/**
|
||||
* struct brcmf_firmware_mapping - Used to map chipid/revmask to firmware
|
||||
* filename and nvram filename. Each bus type implementation should create
|
||||
@@ -66,7 +68,7 @@ struct brcmf_fw_request {
|
||||
u16 domain_nr;
|
||||
u16 bus_nr;
|
||||
u32 n_items;
|
||||
- const char *board_type;
|
||||
+ const char *board_types[BRCMF_FW_MAX_BOARD_TYPES];
|
||||
struct brcmf_fw_item items[];
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index ec73d2620ec9..2a74c9d8d46a 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -1852,11 +1852,13 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
|
||||
fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
|
||||
fwreq->items[BRCMF_PCIE_FW_CLM].type = BRCMF_FW_TYPE_BINARY;
|
||||
fwreq->items[BRCMF_PCIE_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL;
|
||||
- fwreq->board_type = devinfo->settings->board_type;
|
||||
/* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */
|
||||
fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1;
|
||||
fwreq->bus_nr = devinfo->pdev->bus->number;
|
||||
|
||||
+ brcmf_dbg(PCIE, "Board: %s\n", devinfo->settings->board_type);
|
||||
+ fwreq->board_types[0] = devinfo->settings->board_type;
|
||||
+
|
||||
return fwreq;
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
index 27dc8ed29ac8..2b71991f7d9b 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -4433,7 +4433,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
|
||||
fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
|
||||
fwreq->items[BRCMF_SDIO_FW_CLM].type = BRCMF_FW_TYPE_BINARY;
|
||||
fwreq->items[BRCMF_SDIO_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL;
|
||||
- fwreq->board_type = bus->sdiodev->settings->board_type;
|
||||
+ fwreq->board_types[0] = bus->sdiodev->settings->board_type;
|
||||
|
||||
return fwreq;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,299 @@
|
||||
From e5b8ff4d315b814e2d81e40838a6df7164f61a77 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:26:34 +0900
|
||||
Subject: [PATCH 089/171] brcmfmac: pcie: Read Apple OTP information
|
||||
|
||||
On Apple platforms, the One Time Programmable ROM in the Broadcom chips
|
||||
contains information about the specific board design (module, vendor,
|
||||
version) that is required to select the correct NVRAM file. Parse this
|
||||
OTP ROM and extract the required strings.
|
||||
|
||||
Note that the user OTP offset/size is per-chip. This patch does not add
|
||||
any chips yet.
|
||||
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/pcie.c | 218 ++++++++++++++++++
|
||||
include/linux/bcma/bcma_driver_chipcommon.h | 1 +
|
||||
2 files changed, 219 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index 2a74c9d8d46a..17d0353e9105 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -256,6 +256,15 @@ struct brcmf_pcie_core_info {
|
||||
u32 wrapbase;
|
||||
};
|
||||
|
||||
+#define BRCMF_OTP_MAX_PARAM_LEN 16
|
||||
+
|
||||
+struct brcmf_otp_params {
|
||||
+ char module[BRCMF_OTP_MAX_PARAM_LEN];
|
||||
+ char vendor[BRCMF_OTP_MAX_PARAM_LEN];
|
||||
+ char version[BRCMF_OTP_MAX_PARAM_LEN];
|
||||
+ bool valid;
|
||||
+};
|
||||
+
|
||||
struct brcmf_pciedev_info {
|
||||
enum brcmf_pcie_state state;
|
||||
bool in_irq;
|
||||
@@ -283,6 +292,7 @@ struct brcmf_pciedev_info {
|
||||
void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
|
||||
u16 value);
|
||||
struct brcmf_mp_device *settings;
|
||||
+ struct brcmf_otp_params otp;
|
||||
};
|
||||
|
||||
struct brcmf_pcie_ringbuf {
|
||||
@@ -354,6 +364,14 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
|
||||
static struct brcmf_fw_request *
|
||||
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo);
|
||||
|
||||
+static u16
|
||||
+brcmf_pcie_read_reg16(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
|
||||
+{
|
||||
+ void __iomem *address = devinfo->regs + reg_offset;
|
||||
+
|
||||
+ return ioread16(address);
|
||||
+}
|
||||
+
|
||||
static u32
|
||||
brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
|
||||
{
|
||||
@@ -499,6 +517,8 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
|
||||
}
|
||||
|
||||
|
||||
+#define READCC32(devinfo, reg) brcmf_pcie_read_reg32(devinfo, \
|
||||
+ CHIPCREGOFFS(reg))
|
||||
#define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \
|
||||
CHIPCREGOFFS(reg), value)
|
||||
|
||||
@@ -1734,6 +1754,198 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
|
||||
.write32 = brcmf_pcie_buscore_write32,
|
||||
};
|
||||
|
||||
+#define BRCMF_OTP_SYS_VENDOR 0x15
|
||||
+#define BRCMF_OTP_BRCM_CIS 0x80
|
||||
+
|
||||
+#define BRCMF_OTP_VENDOR_HDR 0x00000008
|
||||
+
|
||||
+static int
|
||||
+brcmf_pcie_parse_otp_sys_vendor(struct brcmf_pciedev_info *devinfo,
|
||||
+ u8 *data, size_t size)
|
||||
+{
|
||||
+ int idx = 4;
|
||||
+ const char *chip_params;
|
||||
+ const char *board_params;
|
||||
+ const char *p;
|
||||
+
|
||||
+ /* 4-byte header and two empty strings */
|
||||
+ if (size < 6)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (get_unaligned_le32(data) != BRCMF_OTP_VENDOR_HDR)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ chip_params = &data[idx];
|
||||
+
|
||||
+ /* Skip first string, including terminator */
|
||||
+ idx += strnlen(chip_params, size - idx) + 1;
|
||||
+ if (idx >= size)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ board_params = &data[idx];
|
||||
+
|
||||
+ /* Skip to terminator of second string */
|
||||
+ idx += strnlen(board_params, size - idx);
|
||||
+ if (idx >= size)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* At this point both strings are guaranteed NUL-terminated */
|
||||
+ brcmf_dbg(PCIE, "OTP: chip_params='%s' board_params='%s'\n",
|
||||
+ chip_params, board_params);
|
||||
+
|
||||
+ p = skip_spaces(board_params);
|
||||
+ while (*p) {
|
||||
+ char tag = *p++;
|
||||
+ const char *end;
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (*p++ != '=') /* implicit NUL check */
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* *p might be NUL here, if so end == p and len == 0 */
|
||||
+ end = strchrnul(p, ' ');
|
||||
+ len = end - p;
|
||||
+
|
||||
+ /* leave 1 byte for NUL in destination string */
|
||||
+ if (len > (BRCMF_OTP_MAX_PARAM_LEN - 1))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Copy len characters plus a NUL terminator */
|
||||
+ switch (tag) {
|
||||
+ case 'M':
|
||||
+ strscpy(devinfo->otp.module, p, len + 1);
|
||||
+ break;
|
||||
+ case 'V':
|
||||
+ strscpy(devinfo->otp.vendor, p, len + 1);
|
||||
+ break;
|
||||
+ case 'm':
|
||||
+ strscpy(devinfo->otp.version, p, len + 1);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Skip to next arg, if any */
|
||||
+ p = skip_spaces(end);
|
||||
+ }
|
||||
+
|
||||
+ brcmf_dbg(PCIE, "OTP: module=%s vendor=%s version=%s\n",
|
||||
+ devinfo->otp.module, devinfo->otp.vendor,
|
||||
+ devinfo->otp.version);
|
||||
+
|
||||
+ if (!devinfo->otp.module[0] ||
|
||||
+ !devinfo->otp.vendor[0] ||
|
||||
+ !devinfo->otp.version[0])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ devinfo->otp.valid = true;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+brcmf_pcie_parse_otp(struct brcmf_pciedev_info *devinfo, u8 *otp, size_t size)
|
||||
+{
|
||||
+ int p = 0;
|
||||
+ int ret = -EINVAL;
|
||||
+
|
||||
+ brcmf_dbg(PCIE, "parse_otp size=%ld\n", size);
|
||||
+
|
||||
+ while (p < (size - 1)) {
|
||||
+ u8 type = otp[p];
|
||||
+ u8 length = otp[p + 1];
|
||||
+
|
||||
+ if (type == 0)
|
||||
+ break;
|
||||
+
|
||||
+ if ((p + 2 + length) > size)
|
||||
+ break;
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case BRCMF_OTP_SYS_VENDOR:
|
||||
+ brcmf_dbg(PCIE, "OTP @ 0x%x (%d): SYS_VENDOR\n",
|
||||
+ p, length);
|
||||
+ ret = brcmf_pcie_parse_otp_sys_vendor(devinfo,
|
||||
+ &otp[p + 2],
|
||||
+ length);
|
||||
+ break;
|
||||
+ case BRCMF_OTP_BRCM_CIS:
|
||||
+ brcmf_dbg(PCIE, "OTP @ 0x%x (%d): BRCM_CIS\n",
|
||||
+ p, length);
|
||||
+ break;
|
||||
+ default:
|
||||
+ brcmf_dbg(PCIE, "OTP @ 0x%x (%d): Unknown type 0x%x\n",
|
||||
+ p, length, type);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ p += 2 + length;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
|
||||
+{
|
||||
+ const struct pci_dev *pdev = devinfo->pdev;
|
||||
+ struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
|
||||
+ u32 coreid, base, words, idx, sromctl;
|
||||
+ u16 *otp;
|
||||
+ struct brcmf_core *core;
|
||||
+ int ret;
|
||||
+
|
||||
+ switch (devinfo->ci->chip) {
|
||||
+ default:
|
||||
+ /* OTP not supported on this chip */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ core = brcmf_chip_get_core(devinfo->ci, coreid);
|
||||
+ if (!core) {
|
||||
+ brcmf_err(bus, "No OTP core\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ if (coreid == BCMA_CORE_CHIPCOMMON) {
|
||||
+ /* Chips with OTP accessed via ChipCommon need additional
|
||||
+ * handling to access the OTP
|
||||
+ */
|
||||
+ brcmf_pcie_select_core(devinfo, coreid);
|
||||
+ sromctl = READCC32(devinfo, sromcontrol);
|
||||
+
|
||||
+ if (!(sromctl & BCMA_CC_SROM_CONTROL_OTP_PRESENT)) {
|
||||
+ /* Chip lacks OTP, try without it... */
|
||||
+ brcmf_err(bus,
|
||||
+ "OTP unavailable, using default firmware\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Map OTP to shadow area */
|
||||
+ WRITECC32(devinfo, sromcontrol,
|
||||
+ sromctl | BCMA_CC_SROM_CONTROL_OTPSEL);
|
||||
+ }
|
||||
+
|
||||
+ otp = kcalloc(words, sizeof(u16), GFP_KERNEL);
|
||||
+ if (!otp)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Map bus window to SROM/OTP shadow area in core */
|
||||
+ base = brcmf_pcie_buscore_prep_addr(devinfo->pdev, base + core->base);
|
||||
+
|
||||
+ brcmf_dbg(PCIE, "OTP data:\n");
|
||||
+ for (idx = 0; idx < words; idx++) {
|
||||
+ otp[idx] = brcmf_pcie_read_reg16(devinfo, base + 2 * idx);
|
||||
+ brcmf_dbg(PCIE, "[%8x] 0x%04x\n", base + 2 * idx, otp[idx]);
|
||||
+ }
|
||||
+
|
||||
+ if (coreid == BCMA_CORE_CHIPCOMMON) {
|
||||
+ brcmf_pcie_select_core(devinfo, coreid);
|
||||
+ WRITECC32(devinfo, sromcontrol, sromctl);
|
||||
+ }
|
||||
+
|
||||
+ ret = brcmf_pcie_parse_otp(devinfo, (u8 *)otp, 2 * words);
|
||||
+ kfree(otp);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#define BRCMF_PCIE_FW_CODE 0
|
||||
#define BRCMF_PCIE_FW_NVRAM 1
|
||||
#define BRCMF_PCIE_FW_CLM 2
|
||||
@@ -1930,6 +2142,12 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (ret)
|
||||
goto fail_bus;
|
||||
|
||||
+ ret = brcmf_pcie_read_otp(devinfo);
|
||||
+ if (ret) {
|
||||
+ brcmf_err(bus, "failed to parse OTP\n");
|
||||
+ goto fail_brcmf;
|
||||
+ }
|
||||
+
|
||||
fwreq = brcmf_pcie_prepare_fw_request(devinfo);
|
||||
if (!fwreq) {
|
||||
ret = -ENOMEM;
|
||||
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
|
||||
index e3314f746bfa..2d94c30ed439 100644
|
||||
--- a/include/linux/bcma/bcma_driver_chipcommon.h
|
||||
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
|
||||
@@ -271,6 +271,7 @@
|
||||
#define BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
|
||||
#define BCMA_CC_SROM_CONTROL_OP_WREN 0x60000000
|
||||
#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010
|
||||
+#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020
|
||||
#define BCMA_CC_SROM_CONTROL_LOCK 0x00000008
|
||||
#define BCMA_CC_SROM_CONTROL_SIZE_MASK 0x00000006
|
||||
#define BCMA_CC_SROM_CONTROL_SIZE_1K 0x00000000
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,68 @@
|
||||
From 59a447e856db9a2c8312d617a6a4f89a629d1bff Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:27:19 +0900
|
||||
Subject: [PATCH 090/171] brcmfmac: of: Fetch Apple properties
|
||||
|
||||
On Apple ARM64 platforms, firmware selection requires two properties
|
||||
that come from system firmware: the module-instance (aka "island", a
|
||||
codename representing a given hardware platform) and the antenna-sku.
|
||||
We map Apple's module codenames to board_types in the form
|
||||
"apple,<module-instance>".
|
||||
|
||||
The mapped board_type is added to the DTS file in that form, while the
|
||||
antenna-sku is forwarded by our bootloader from the Apple Device Tree
|
||||
into the FDT. Grab them from the DT so firmware selection can use
|
||||
them.
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/common.h | 1 +
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/of.c | 12 +++++++++++-
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
index 15accc88d5c0..1f678bbd87aa 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -51,6 +51,7 @@ struct brcmf_mp_device {
|
||||
struct brcmfmac_pd_cc *country_codes;
|
||||
const char *board_type;
|
||||
unsigned char mac[ETH_ALEN];
|
||||
+ const char *antenna_sku;
|
||||
union {
|
||||
struct brcmfmac_sdio_pd sdio;
|
||||
} bus;
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
index 083ac58f466d..644cc48eae40 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
@@ -64,14 +64,24 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
{
|
||||
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
|
||||
struct device_node *root, *np = dev->of_node;
|
||||
+ const char *prop;
|
||||
int irq;
|
||||
int err;
|
||||
u32 irqf;
|
||||
u32 val;
|
||||
|
||||
+ /* Apple ARM64 platforms have their own idea of board type, passed in
|
||||
+ * via the device tree. They also have an antenna SKU parameter
|
||||
+ */
|
||||
+ if (!of_property_read_string(np, "brcm,board-type", &prop))
|
||||
+ settings->board_type = prop;
|
||||
+
|
||||
+ if (!of_property_read_string(np, "apple,antenna-sku", &prop))
|
||||
+ settings->antenna_sku = prop;
|
||||
+
|
||||
/* Set board-type to the first string of the machine compatible prop */
|
||||
root = of_find_node_by_path("/");
|
||||
- if (root) {
|
||||
+ if (root && !settings->board_type) {
|
||||
int i;
|
||||
char *board_type;
|
||||
const char *tmp;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,134 @@
|
||||
From 608e39fd3521d26bfc846383626f4605d7b273a7 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:45:21 +0900
|
||||
Subject: [PATCH 091/171] brcmfmac: pcie: Perform firmware selection for Apple
|
||||
platforms
|
||||
|
||||
On Apple platforms, firmware selection uses the following elements:
|
||||
|
||||
Property Example Source
|
||||
============== ======= ========================
|
||||
* Chip name 4378 Device ID
|
||||
* Chip revision B1 OTP
|
||||
* Platform shikoku DT (ARM64) or ACPI (x86)
|
||||
* Module type RASP OTP
|
||||
* Module vendor m OTP
|
||||
* Module version 6.11 OTP
|
||||
* Antenna SKU X3 DT (ARM64) or ACPI (x86)
|
||||
|
||||
In macOS, these firmwares are stored using filenames in this format
|
||||
under /usr/share/firmware/wifi:
|
||||
|
||||
C-4378__s-B1/P-shikoku-X3_M-RASP_V-m__m-6.11.txt
|
||||
|
||||
To prepare firmwares for Linux, we rename these to a scheme following
|
||||
the existing brcmfmac convention:
|
||||
|
||||
brcmfmac<chip><lower(rev)>-pcie.apple,<platform>-<mod_type>-\
|
||||
<mod_vendor>-<mod_version>-<antenna_sku>.txt
|
||||
|
||||
The NVRAM uses all the components, while the firmware and CLM blob only
|
||||
use the chip/revision/platform/antenna_sku:
|
||||
|
||||
brcmfmac<chip><lower(rev)>-pcie.apple,<platform>-<antenna_sku>.bin
|
||||
|
||||
e.g.
|
||||
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11-X3.txt
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-X3.bin
|
||||
|
||||
In addition, since there are over 1000 files in total, many of which are
|
||||
symlinks or outright duplicates, we deduplicate and prune the firmware
|
||||
tree to reduce firmware filenames to fewer dimensions. For example, the
|
||||
shikoku platform (MacBook Air M1 2020) simplifies to just 4 files:
|
||||
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku.clm_blob
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku.bin
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.txt
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-u.txt
|
||||
|
||||
This reduces the total file count to around 170, of which 75 are
|
||||
symlinks and 95 are regular files: 7 firmware blobs, 27 CLM blobs, and
|
||||
61 NVRAM config files. We also slightly process NVRAM files to correct
|
||||
some formatting issues.
|
||||
|
||||
To handle this, the driver must try the following path formats when
|
||||
looking for firmware files:
|
||||
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11-X3.txt
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11.txt
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.txt
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP.txt
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku-X3.txt *
|
||||
brcm/brcmfmac4378b1-pcie.apple,shikoku.txt
|
||||
|
||||
* Not relevant for NVRAM, only for firmware/CLM.
|
||||
|
||||
The chip revision nominally comes from OTP on Apple platforms, but it
|
||||
can be mapped to the PCI revision number, so we ignore the OTP revision
|
||||
and continue to use the existing PCI revision mechanism to identify chip
|
||||
revisions, as the driver already does for other chips. Unfortunately,
|
||||
the mapping is not consistent between different chip types, so this has
|
||||
to be determined experimentally.
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/pcie.c | 41 ++++++++++++++++++-
|
||||
1 file changed, 39 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index 17d0353e9105..86807d990cc7 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -2068,8 +2068,45 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
|
||||
fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1;
|
||||
fwreq->bus_nr = devinfo->pdev->bus->number;
|
||||
|
||||
- brcmf_dbg(PCIE, "Board: %s\n", devinfo->settings->board_type);
|
||||
- fwreq->board_types[0] = devinfo->settings->board_type;
|
||||
+ /* Apple platforms with fancy firmware/NVRAM selection */
|
||||
+ if (devinfo->settings->board_type &&
|
||||
+ devinfo->settings->antenna_sku &&
|
||||
+ devinfo->otp.valid) {
|
||||
+ const struct brcmf_otp_params *otp = &devinfo->otp;
|
||||
+ struct device *dev = &devinfo->pdev->dev;
|
||||
+ const char **bt = fwreq->board_types;
|
||||
+
|
||||
+ brcmf_dbg(PCIE, "Apple board: %s\n",
|
||||
+ devinfo->settings->board_type);
|
||||
+
|
||||
+ /* Example: apple,shikoku-RASP-m-6.11-X3 */
|
||||
+ bt[0] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%s-%s-%s",
|
||||
+ devinfo->settings->board_type,
|
||||
+ otp->module, otp->vendor, otp->version,
|
||||
+ devinfo->settings->antenna_sku);
|
||||
+ bt[1] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%s-%s",
|
||||
+ devinfo->settings->board_type,
|
||||
+ otp->module, otp->vendor, otp->version);
|
||||
+ bt[2] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%s",
|
||||
+ devinfo->settings->board_type,
|
||||
+ otp->module, otp->vendor);
|
||||
+ bt[3] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s",
|
||||
+ devinfo->settings->board_type,
|
||||
+ otp->module);
|
||||
+ bt[4] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s",
|
||||
+ devinfo->settings->board_type,
|
||||
+ devinfo->settings->antenna_sku);
|
||||
+ bt[5] = devinfo->settings->board_type;
|
||||
+
|
||||
+ if (!bt[0] || !bt[1] || !bt[2] || !bt[3] || !bt[4]) {
|
||||
+ kfree(fwreq);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ brcmf_dbg(PCIE, "Board: %s\n", devinfo->settings->board_type);
|
||||
+ fwreq->board_types[0] = devinfo->settings->board_type;
|
||||
+ }
|
||||
|
||||
return fwreq;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,125 @@
|
||||
From 76efd4b5d7adea522c649c6b44d7379e981141b5 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 23 Dec 2021 22:32:08 +0900
|
||||
Subject: [PATCH 092/171] brcmfmac: firmware: Allow platform to override
|
||||
macaddr
|
||||
|
||||
On Device Tree platforms, it is customary to be able to set the MAC
|
||||
address via the Device Tree, as it is often stored in system firmware.
|
||||
This is particularly relevant for Apple ARM64 platforms, where this
|
||||
information comes from system configuration and passed through by the
|
||||
bootloader into the DT.
|
||||
|
||||
Implement support for this by fetching the platform MAC address and
|
||||
adding or replacing the macaddr= property in nvram. This becomes the
|
||||
dongle's default MAC address.
|
||||
|
||||
On platforms with an SROM MAC address, this overrides it. On platforms
|
||||
without one, such as Apple ARM64 devices, this is required for the
|
||||
firmware to boot (it will fail if it does not have a valid MAC at all).
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/firmware.c | 28 +++++++++++++++++--
|
||||
1 file changed, 26 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
index d04a59cf4a1e..fbfc9458d240 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
||||
@@ -21,6 +21,8 @@
|
||||
#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */
|
||||
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */
|
||||
#define BRCMF_FW_DEFAULT_BOARDREV "boardrev=0xff"
|
||||
+#define BRCMF_FW_MACADDR_FMT "macaddr=%pM"
|
||||
+#define BRCMF_FW_MACADDR_LEN (7 + ETH_ALEN * 3)
|
||||
|
||||
enum nvram_parser_state {
|
||||
IDLE,
|
||||
@@ -57,6 +59,7 @@ struct nvram_parser {
|
||||
bool multi_dev_v1;
|
||||
bool multi_dev_v2;
|
||||
bool boardrev_found;
|
||||
+ bool strip_mac;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -121,6 +124,10 @@ static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
|
||||
nvp->multi_dev_v2 = true;
|
||||
if (strncmp(&nvp->data[nvp->entry], "boardrev", 8) == 0)
|
||||
nvp->boardrev_found = true;
|
||||
+ /* strip macaddr if platform MAC overrides */
|
||||
+ if (nvp->strip_mac &&
|
||||
+ strncmp(&nvp->data[nvp->entry], "macaddr", 7) == 0)
|
||||
+ st = COMMENT;
|
||||
} else if (!is_nvram_char(c) || c == ' ') {
|
||||
brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
|
||||
nvp->line, nvp->column);
|
||||
@@ -209,6 +216,7 @@ static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
|
||||
size = data_len;
|
||||
/* Add space for properties we may add */
|
||||
size += strlen(BRCMF_FW_DEFAULT_BOARDREV) + 1;
|
||||
+ size += BRCMF_FW_MACADDR_LEN + 1;
|
||||
/* Alloc for extra 0 byte + roundup by 4 + length field */
|
||||
size += 1 + 3 + sizeof(u32);
|
||||
nvp->nvram = kzalloc(size, GFP_KERNEL);
|
||||
@@ -368,22 +376,34 @@ static void brcmf_fw_add_defaults(struct nvram_parser *nvp)
|
||||
nvp->nvram_len++;
|
||||
}
|
||||
|
||||
+static void brcmf_fw_add_macaddr(struct nvram_parser *nvp, u8 *mac)
|
||||
+{
|
||||
+ BUG_ON(snprintf(&nvp->nvram[nvp->nvram_len], BRCMF_FW_MACADDR_LEN + 1,
|
||||
+ BRCMF_FW_MACADDR_FMT, mac) != BRCMF_FW_MACADDR_LEN);
|
||||
+ nvp->nvram_len += BRCMF_FW_MACADDR_LEN + 1;
|
||||
+}
|
||||
+
|
||||
/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
|
||||
* and ending in a NUL. Removes carriage returns, empty lines, comment lines,
|
||||
* and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
|
||||
* End of buffer is completed with token identifying length of buffer.
|
||||
*/
|
||||
static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,
|
||||
- u32 *new_length, u16 domain_nr, u16 bus_nr)
|
||||
+ u32 *new_length, u16 domain_nr, u16 bus_nr,
|
||||
+ struct device *dev)
|
||||
{
|
||||
struct nvram_parser nvp;
|
||||
u32 pad;
|
||||
u32 token;
|
||||
__le32 token_le;
|
||||
+ u8 mac[ETH_ALEN];
|
||||
|
||||
if (brcmf_init_nvram_parser(&nvp, data, data_len) < 0)
|
||||
return NULL;
|
||||
|
||||
+ if (eth_platform_get_mac_address(dev, mac) == 0)
|
||||
+ nvp.strip_mac = true;
|
||||
+
|
||||
while (nvp.pos < data_len) {
|
||||
nvp.state = nv_parser_states[nvp.state](&nvp);
|
||||
if (nvp.state == END)
|
||||
@@ -404,6 +424,9 @@ static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,
|
||||
|
||||
brcmf_fw_add_defaults(&nvp);
|
||||
|
||||
+ if (nvp.strip_mac)
|
||||
+ brcmf_fw_add_macaddr(&nvp, mac);
|
||||
+
|
||||
pad = nvp.nvram_len;
|
||||
*new_length = roundup(nvp.nvram_len + 1, 4);
|
||||
while (pad != *new_length) {
|
||||
@@ -547,7 +570,8 @@ static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
|
||||
if (data)
|
||||
nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
|
||||
fwctx->req->domain_nr,
|
||||
- fwctx->req->bus_nr);
|
||||
+ fwctx->req->bus_nr,
|
||||
+ fwctx->dev);
|
||||
|
||||
if (free_bcm47xx_nvram)
|
||||
bcm47xx_nvram_release_contents(data);
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 9fd60252c13e93ca8ff245f63faf248da6c390f4 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:39:04 +0900
|
||||
Subject: [PATCH 093/171] brcmfmac: msgbuf: Increase RX ring sizes to 1024
|
||||
|
||||
Newer chips used on Apple platforms have a max_rxbufpost greater than
|
||||
512, which causes warnings when brcmf_msgbuf_rxbuf_data_fill tries to
|
||||
put more entries in the ring than will fit. Increase the ring sizes
|
||||
to 1024.
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
|
||||
index 2e322edbb907..6a849f4a94dd 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
|
||||
@@ -8,10 +8,10 @@
|
||||
#ifdef CONFIG_BRCMFMAC_PROTO_MSGBUF
|
||||
|
||||
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 64
|
||||
-#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 512
|
||||
+#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 1024
|
||||
#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM 64
|
||||
#define BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM 1024
|
||||
-#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 512
|
||||
+#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 1024
|
||||
#define BRCMF_H2D_TXFLOWRING_MAX_ITEM 512
|
||||
|
||||
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,265 @@
|
||||
From aa48c835720f5e04ebbe14e3f6b053c8415fb6d9 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:25:35 +0900
|
||||
Subject: [PATCH 094/171] brcmfmac: pcie: Support PCIe core revisions >= 64
|
||||
|
||||
These newer PCIe core revisions include new sets of registers that must
|
||||
be used instead of the legacy ones. Introduce a brcmf_pcie_reginfo to
|
||||
hold the specific register offsets and values to use for a given
|
||||
platform, and change all the register accesses to indirect through it.
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/pcie.c | 125 +++++++++++++++---
|
||||
1 file changed, 105 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index 86807d990cc7..a2ef3de834f6 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -119,6 +119,12 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140
|
||||
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 0x144
|
||||
|
||||
+#define BRCMF_PCIE_64_PCIE2REG_INTMASK 0xC14
|
||||
+#define BRCMF_PCIE_64_PCIE2REG_MAILBOXINT 0xC30
|
||||
+#define BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK 0xC34
|
||||
+#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0 0xA20
|
||||
+#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1 0xA24
|
||||
+
|
||||
#define BRCMF_PCIE2_INTA 0x01
|
||||
#define BRCMF_PCIE2_INTB 0x02
|
||||
|
||||
@@ -138,6 +144,8 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
#define BRCMF_PCIE_MB_INT_D2H3_DB0 0x400000
|
||||
#define BRCMF_PCIE_MB_INT_D2H3_DB1 0x800000
|
||||
|
||||
+#define BRCMF_PCIE_MB_INT_FN0 (BRCMF_PCIE_MB_INT_FN0_0 | \
|
||||
+ BRCMF_PCIE_MB_INT_FN0_1)
|
||||
#define BRCMF_PCIE_MB_INT_D2H_DB (BRCMF_PCIE_MB_INT_D2H0_DB0 | \
|
||||
BRCMF_PCIE_MB_INT_D2H0_DB1 | \
|
||||
BRCMF_PCIE_MB_INT_D2H1_DB0 | \
|
||||
@@ -147,6 +155,40 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
BRCMF_PCIE_MB_INT_D2H3_DB0 | \
|
||||
BRCMF_PCIE_MB_INT_D2H3_DB1)
|
||||
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H0_DB0 0x1
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H0_DB1 0x2
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H1_DB0 0x4
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H1_DB1 0x8
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H2_DB0 0x10
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H2_DB1 0x20
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H3_DB0 0x40
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H3_DB1 0x80
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H4_DB0 0x100
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H4_DB1 0x200
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H5_DB0 0x400
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H5_DB1 0x800
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H6_DB0 0x1000
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H6_DB1 0x2000
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H7_DB0 0x4000
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H7_DB1 0x8000
|
||||
+
|
||||
+#define BRCMF_PCIE_64_MB_INT_D2H_DB (BRCMF_PCIE_64_MB_INT_D2H0_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H0_DB1 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H1_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H1_DB1 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H2_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H2_DB1 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H3_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H3_DB1 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H4_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H4_DB1 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H5_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H5_DB1 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H6_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H6_DB1 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H7_DB0 | \
|
||||
+ BRCMF_PCIE_64_MB_INT_D2H7_DB1)
|
||||
+
|
||||
#define BRCMF_PCIE_SHARED_VERSION_7 7
|
||||
#define BRCMF_PCIE_MIN_SHARED_VERSION 5
|
||||
#define BRCMF_PCIE_MAX_SHARED_VERSION BRCMF_PCIE_SHARED_VERSION_7
|
||||
@@ -273,6 +315,7 @@ struct brcmf_pciedev_info {
|
||||
char nvram_name[BRCMF_FW_NAME_LEN];
|
||||
char clm_name[BRCMF_FW_NAME_LEN];
|
||||
const struct firmware *clm_fw;
|
||||
+ const struct brcmf_pcie_reginfo *reginfo;
|
||||
void __iomem *regs;
|
||||
void __iomem *tcm;
|
||||
u32 ram_base;
|
||||
@@ -359,6 +402,36 @@ static const u32 brcmf_ring_itemsize[BRCMF_NROF_COMMON_MSGRINGS] = {
|
||||
BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE
|
||||
};
|
||||
|
||||
+struct brcmf_pcie_reginfo {
|
||||
+ u32 intmask;
|
||||
+ u32 mailboxint;
|
||||
+ u32 mailboxmask;
|
||||
+ u32 h2d_mailbox_0;
|
||||
+ u32 h2d_mailbox_1;
|
||||
+ u32 int_d2h_db;
|
||||
+ u32 int_fn0;
|
||||
+};
|
||||
+
|
||||
+static const struct brcmf_pcie_reginfo brcmf_reginfo_default = {
|
||||
+ .intmask = BRCMF_PCIE_PCIE2REG_INTMASK,
|
||||
+ .mailboxint = BRCMF_PCIE_PCIE2REG_MAILBOXINT,
|
||||
+ .mailboxmask = BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
|
||||
+ .h2d_mailbox_0 = BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0,
|
||||
+ .h2d_mailbox_1 = BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1,
|
||||
+ .int_d2h_db = BRCMF_PCIE_MB_INT_D2H_DB,
|
||||
+ .int_fn0 = BRCMF_PCIE_MB_INT_FN0,
|
||||
+};
|
||||
+
|
||||
+static const struct brcmf_pcie_reginfo brcmf_reginfo_64 = {
|
||||
+ .intmask = BRCMF_PCIE_64_PCIE2REG_INTMASK,
|
||||
+ .mailboxint = BRCMF_PCIE_64_PCIE2REG_MAILBOXINT,
|
||||
+ .mailboxmask = BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK,
|
||||
+ .h2d_mailbox_0 = BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0,
|
||||
+ .h2d_mailbox_1 = BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1,
|
||||
+ .int_d2h_db = BRCMF_PCIE_64_MB_INT_D2H_DB,
|
||||
+ .int_fn0 = 0,
|
||||
+};
|
||||
+
|
||||
static void brcmf_pcie_setup(struct device *dev, int ret,
|
||||
struct brcmf_fw_request *fwreq);
|
||||
static struct brcmf_fw_request *
|
||||
@@ -802,30 +875,29 @@ static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo,
|
||||
|
||||
static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0);
|
||||
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxmask, 0);
|
||||
}
|
||||
|
||||
|
||||
static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
|
||||
- BRCMF_PCIE_MB_INT_D2H_DB |
|
||||
- BRCMF_PCIE_MB_INT_FN0_0 |
|
||||
- BRCMF_PCIE_MB_INT_FN0_1);
|
||||
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxmask,
|
||||
+ devinfo->reginfo->int_d2h_db |
|
||||
+ devinfo->reginfo->int_fn0);
|
||||
}
|
||||
|
||||
static void brcmf_pcie_hostready(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
if (devinfo->shared.flags & BRCMF_PCIE_SHARED_HOSTRDY_DB1)
|
||||
brcmf_pcie_write_reg32(devinfo,
|
||||
- BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1, 1);
|
||||
+ devinfo->reginfo->h2d_mailbox_1, 1);
|
||||
}
|
||||
|
||||
static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg)
|
||||
{
|
||||
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
|
||||
|
||||
- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)) {
|
||||
+ if (brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint)) {
|
||||
brcmf_pcie_intr_disable(devinfo);
|
||||
brcmf_dbg(PCIE, "Enter\n");
|
||||
return IRQ_WAKE_THREAD;
|
||||
@@ -840,15 +912,14 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
|
||||
u32 status;
|
||||
|
||||
devinfo->in_irq = true;
|
||||
- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
|
||||
+ status = brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint);
|
||||
brcmf_dbg(PCIE, "Enter %x\n", status);
|
||||
if (status) {
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
|
||||
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxint,
|
||||
status);
|
||||
- if (status & (BRCMF_PCIE_MB_INT_FN0_0 |
|
||||
- BRCMF_PCIE_MB_INT_FN0_1))
|
||||
+ if (status & devinfo->reginfo->int_fn0)
|
||||
brcmf_pcie_handle_mb_data(devinfo);
|
||||
- if (status & BRCMF_PCIE_MB_INT_D2H_DB) {
|
||||
+ if (status & devinfo->reginfo->int_d2h_db) {
|
||||
if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
|
||||
brcmf_proto_msgbuf_rx_trigger(
|
||||
&devinfo->pdev->dev);
|
||||
@@ -907,8 +978,8 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
|
||||
if (devinfo->in_irq)
|
||||
brcmf_err(bus, "Still in IRQ (processing) !!!\n");
|
||||
|
||||
- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status);
|
||||
+ status = brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint);
|
||||
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxint, status);
|
||||
|
||||
devinfo->irq_allocated = false;
|
||||
}
|
||||
@@ -960,7 +1031,7 @@ static int brcmf_pcie_ring_mb_ring_bell(void *ctx)
|
||||
|
||||
brcmf_dbg(PCIE, "RING !\n");
|
||||
/* Any arbitrary value will do, lets use 1 */
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, 1);
|
||||
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->h2d_mailbox_0, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1723,15 +1794,22 @@ static int brcmf_pcie_buscoreprep(void *ctx)
|
||||
static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip)
|
||||
{
|
||||
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
|
||||
- u32 val;
|
||||
+ struct brcmf_core *core;
|
||||
+ u32 val, reg;
|
||||
|
||||
devinfo->ci = chip;
|
||||
brcmf_pcie_reset_device(devinfo);
|
||||
|
||||
- val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
|
||||
+ /* reginfo is not ready yet */
|
||||
+ core = brcmf_chip_get_core(chip, BCMA_CORE_PCIE2);
|
||||
+ if (core->rev >= 64)
|
||||
+ reg = BRCMF_PCIE_64_PCIE2REG_MAILBOXINT;
|
||||
+ else
|
||||
+ reg = BRCMF_PCIE_PCIE2REG_MAILBOXINT;
|
||||
+
|
||||
+ val = brcmf_pcie_read_reg32(devinfo, reg);
|
||||
if (val != 0xffffffff)
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
|
||||
- val);
|
||||
+ brcmf_pcie_write_reg32(devinfo, reg, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2119,6 +2197,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
struct brcmf_pciedev_info *devinfo;
|
||||
struct brcmf_pciedev *pcie_bus_dev;
|
||||
struct brcmf_bus *bus;
|
||||
+ struct brcmf_core *core;
|
||||
|
||||
brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
|
||||
|
||||
@@ -2137,6 +2216,12 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2);
|
||||
+ if (core->rev >= 64)
|
||||
+ devinfo->reginfo = &brcmf_reginfo_64;
|
||||
+ else
|
||||
+ devinfo->reginfo = &brcmf_reginfo_default;
|
||||
+
|
||||
pcie_bus_dev = kzalloc(sizeof(*pcie_bus_dev), GFP_KERNEL);
|
||||
if (pcie_bus_dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
@@ -2306,7 +2391,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
|
||||
brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus);
|
||||
|
||||
/* Check if device is still up and running, if so we are ready */
|
||||
- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
|
||||
+ if (brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->intmask) != 0) {
|
||||
brcmf_dbg(PCIE, "Try to wakeup device....\n");
|
||||
if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM))
|
||||
goto cleanup;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,97 @@
|
||||
From 54af2b6f4ba6a6a477d9739d24fafe447b1235a3 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 21 Dec 2021 17:46:40 +0900
|
||||
Subject: [PATCH 095/171] brcmfmac: pcie: Add IDs/properties for BCM4378
|
||||
|
||||
This chip is present on Apple M1 (t8103) platforms:
|
||||
|
||||
* atlantisb (apple,j274): Mac mini (M1, 2020)
|
||||
* honshu (apple,j293): MacBook Pro (13-inch, M1, 2020)
|
||||
* shikoku (apple,j313): MacBook Air (M1, 2020)
|
||||
* capri (apple,j456): iMac (24-inch, 4x USB-C, M1, 2020)
|
||||
* santorini (apple,j457): iMac (24-inch, 2x USB-C, M1, 2020)
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 2 ++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++++++
|
||||
.../net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
|
||||
3 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
index 4ec7773b6906..7f1d6cea2141 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
@@ -732,6 +732,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
|
||||
return 0x160000;
|
||||
case CY_CC_43752_CHIP_ID:
|
||||
return 0x170000;
|
||||
+ case BRCM_CC_4378_CHIP_ID:
|
||||
+ return 0x352000;
|
||||
default:
|
||||
brcmf_err("unknown chip: %s\n", ci->pub.name);
|
||||
break;
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index a2ef3de834f6..2ca2c4b603cf 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -59,6 +59,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
|
||||
BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
|
||||
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
|
||||
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
|
||||
+BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie");
|
||||
|
||||
/* firmware config files */
|
||||
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
|
||||
@@ -88,6 +89,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
|
||||
+ BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFFF, 4378B1), /* 3 */
|
||||
};
|
||||
|
||||
#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
|
||||
@@ -1970,6 +1972,11 @@ static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
|
||||
int ret;
|
||||
|
||||
switch (devinfo->ci->chip) {
|
||||
+ case BRCM_CC_4378_CHIP_ID:
|
||||
+ coreid = BCMA_CORE_GCI;
|
||||
+ base = 0x1120;
|
||||
+ words = 0x170;
|
||||
+ break;
|
||||
default:
|
||||
/* OTP not supported on this chip */
|
||||
return 0;
|
||||
@@ -2458,6 +2465,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID),
|
||||
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID),
|
||||
{ /* end: all zeroes */ }
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
index ed0b707f0cdf..43158a404652 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
@@ -51,6 +51,7 @@
|
||||
#define BRCM_CC_43664_CHIP_ID 43664
|
||||
#define BRCM_CC_43666_CHIP_ID 43666
|
||||
#define BRCM_CC_4371_CHIP_ID 0x4371
|
||||
+#define BRCM_CC_4378_CHIP_ID 0x4378
|
||||
#define CY_CC_4373_CHIP_ID 0x4373
|
||||
#define CY_CC_43012_CHIP_ID 43012
|
||||
#define CY_CC_43752_CHIP_ID 43752
|
||||
@@ -87,6 +88,7 @@
|
||||
#define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4
|
||||
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
|
||||
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
|
||||
+#define BRCM_PCIE_4378_DEVICE_ID 0x4425
|
||||
|
||||
|
||||
/* brcmsmac IDs */
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 7107b9724f933acdb31a3cc87dc80ce7a7484bd5 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 23 Dec 2021 19:51:11 +0900
|
||||
Subject: [PATCH 096/171] ACPI / property: Support strings in Apple _DSM props
|
||||
|
||||
The Wi-Fi module in Apple machines has a "module-instance" device
|
||||
property that specifies the platform type and is used for firmware
|
||||
selection. Its value is a string, so add support for string values in
|
||||
acpi_extract_apple_properties().
|
||||
|
||||
Reviewed-by: Lukas Wunner <lukas@wunner.de>
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
drivers/acpi/x86/apple.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/acpi/x86/apple.c b/drivers/acpi/x86/apple.c
|
||||
index c285c91a5e9c..71b8f103ab0f 100644
|
||||
--- a/drivers/acpi/x86/apple.c
|
||||
+++ b/drivers/acpi/x86/apple.c
|
||||
@@ -70,13 +70,16 @@ void acpi_extract_apple_properties(struct acpi_device *adev)
|
||||
|
||||
if ( key->type != ACPI_TYPE_STRING ||
|
||||
(val->type != ACPI_TYPE_INTEGER &&
|
||||
- val->type != ACPI_TYPE_BUFFER))
|
||||
+ val->type != ACPI_TYPE_BUFFER &&
|
||||
+ val->type != ACPI_TYPE_STRING))
|
||||
continue; /* skip invalid properties */
|
||||
|
||||
__set_bit(i, valid);
|
||||
newsize += key->string.length + 1;
|
||||
if ( val->type == ACPI_TYPE_BUFFER)
|
||||
newsize += val->buffer.length;
|
||||
+ else if (val->type == ACPI_TYPE_STRING)
|
||||
+ newsize += val->string.length + 1;
|
||||
}
|
||||
|
||||
numvalid = bitmap_weight(valid, numprops);
|
||||
@@ -118,6 +121,12 @@ void acpi_extract_apple_properties(struct acpi_device *adev)
|
||||
newprops[v].type = val->type;
|
||||
if (val->type == ACPI_TYPE_INTEGER) {
|
||||
newprops[v].integer.value = val->integer.value;
|
||||
+ } else if (val->type == ACPI_TYPE_STRING) {
|
||||
+ newprops[v].string.length = val->string.length;
|
||||
+ newprops[v].string.pointer = free_space;
|
||||
+ memcpy(free_space, val->string.pointer,
|
||||
+ val->string.length);
|
||||
+ free_space += val->string.length + 1;
|
||||
} else {
|
||||
newprops[v].buffer.length = val->buffer.length;
|
||||
newprops[v].buffer.pointer = free_space;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,127 @@
|
||||
From 30cf50137a081ece01ac609de4131e20b8cccc1c Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 23 Dec 2021 19:51:36 +0900
|
||||
Subject: [PATCH 097/171] brcmfmac: acpi: Add support for fetching Apple ACPI
|
||||
properties
|
||||
|
||||
On DT platforms, the module-instance and antenna-sku-info properties
|
||||
are passed in the DT. On ACPI platforms, module-instance is passed via
|
||||
the analogous Apple device property mechanism, while the antenna SKU
|
||||
info is instead obtained via an ACPI method that grabs it from
|
||||
non-volatile storage.
|
||||
|
||||
Add support for this, to allow proper firmware selection on Apple
|
||||
platforms.
|
||||
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/Makefile | 2 +
|
||||
.../broadcom/brcm80211/brcmfmac/acpi.c | 52 +++++++++++++++++++
|
||||
.../broadcom/brcm80211/brcmfmac/common.c | 1 +
|
||||
.../broadcom/brcm80211/brcmfmac/common.h | 9 ++++
|
||||
4 files changed, 64 insertions(+)
|
||||
create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
|
||||
index 13c13504a6e8..19009eb9db93 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
|
||||
@@ -47,3 +47,5 @@ brcmfmac-$(CONFIG_OF) += \
|
||||
of.o
|
||||
brcmfmac-$(CONFIG_DMI) += \
|
||||
dmi.o
|
||||
+brcmfmac-$(CONFIG_ACPI) += \
|
||||
+ acpi.o
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c
|
||||
new file mode 100644
|
||||
index 000000000000..dec6a83d13b1
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c
|
||||
@@ -0,0 +1,52 @@
|
||||
+// SPDX-License-Identifier: ISC
|
||||
+/*
|
||||
+ * Copyright The Asahi Linux Contributors
|
||||
+ */
|
||||
+
|
||||
+#include <linux/acpi.h>
|
||||
+#include "debug.h"
|
||||
+#include "core.h"
|
||||
+#include "common.h"
|
||||
+
|
||||
+void brcmf_acpi_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
+ struct brcmf_mp_device *settings)
|
||||
+{
|
||||
+ acpi_status status;
|
||||
+ const union acpi_object *o;
|
||||
+ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
+ struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
+
|
||||
+ if (!adev)
|
||||
+ return;
|
||||
+
|
||||
+ if (!ACPI_FAILURE(acpi_dev_get_property(adev, "module-instance",
|
||||
+ ACPI_TYPE_STRING, &o))) {
|
||||
+ brcmf_dbg(INFO, "ACPI module-instance=%s\n", o->string.pointer);
|
||||
+ settings->board_type = devm_kasprintf(dev, GFP_KERNEL,
|
||||
+ "apple,%s",
|
||||
+ o->string.pointer);
|
||||
+ } else {
|
||||
+ brcmf_dbg(INFO, "No ACPI module-instance\n");
|
||||
+ }
|
||||
+
|
||||
+ status = acpi_evaluate_object(adev->handle, "RWCV", NULL, &buf);
|
||||
+ o = buf.pointer;
|
||||
+ if (!ACPI_FAILURE(status) && o && o->type == ACPI_TYPE_BUFFER &&
|
||||
+ o->buffer.length >= 2) {
|
||||
+ char *antenna_sku = devm_kzalloc(dev, 3, GFP_KERNEL);
|
||||
+
|
||||
+ if (!antenna_sku) {
|
||||
+ brcmf_err("Failed to allocate antenna-sku");
|
||||
+ } else {
|
||||
+ memcpy(antenna_sku, o->buffer.pointer, 2);
|
||||
+ brcmf_dbg(INFO, "ACPI RWCV data=%*phN antenna-sku=%s\n",
|
||||
+ (int)o->buffer.length, o->buffer.pointer,
|
||||
+ antenna_sku);
|
||||
+ settings->antenna_sku = antenna_sku;
|
||||
+ }
|
||||
+
|
||||
+ kfree(buf.pointer);
|
||||
+ } else {
|
||||
+ brcmf_dbg(INFO, "No ACPI antenna-sku\n");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
index 95d4c133efdd..ea2475bfc2d7 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -448,6 +448,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
|
||||
/* No platform data for this device, try OF and DMI data */
|
||||
brcmf_dmi_probe(settings, chip, chiprev);
|
||||
brcmf_of_probe(dev, bus_type, settings);
|
||||
+ brcmf_acpi_probe(dev, bus_type, settings);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
index 1f678bbd87aa..960b1042a7c2 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -74,6 +74,15 @@ static inline void
|
||||
brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev) {}
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_ACPI
|
||||
+void brcmf_acpi_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
+ struct brcmf_mp_device *settings);
|
||||
+#else
|
||||
+static inline void brcmf_acpi_probe(struct device *dev,
|
||||
+ enum brcmf_bus_type bus_type,
|
||||
+ struct brcmf_mp_device *settings) {}
|
||||
+#endif
|
||||
+
|
||||
u8 brcmf_map_prio_to_prec(void *cfg, u8 prio);
|
||||
|
||||
u8 brcmf_map_prio_to_aci(void *cfg, u8 prio);
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,82 @@
|
||||
From b696ea7c641c2172aff67297e9c0f13d8d46620f Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Thu, 23 Dec 2021 19:30:17 +0900
|
||||
Subject: [PATCH 098/171] brcmfmac: pcie: Provide a buffer of random bytes to
|
||||
the device
|
||||
|
||||
Newer Apple firmwares on chipsets without a hardware RNG require the
|
||||
host to provide a buffer of 256 random bytes to the device on
|
||||
initialization. This buffer is present immediately before NVRAM,
|
||||
suffixed by a footer containing a magic number and the buffer length.
|
||||
|
||||
This won't affect chips/firmwares that do not use this feature, so do it
|
||||
unconditionally.
|
||||
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/pcie.c | 29 +++++++++++++++++++
|
||||
1 file changed, 29 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index 2ca2c4b603cf..1e2afca5a60b 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/io.h>
|
||||
+#include <linux/random.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <soc.h>
|
||||
@@ -1625,6 +1626,13 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct brcmf_random_seed_footer {
|
||||
+ __le32 length;
|
||||
+ __le32 magic;
|
||||
+};
|
||||
+
|
||||
+#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
|
||||
+#define BRCMF_RANDOM_SEED_LENGTH 0x100
|
||||
|
||||
static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
|
||||
const struct firmware *fw, void *nvram,
|
||||
@@ -1656,11 +1664,32 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
|
||||
brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0);
|
||||
|
||||
if (nvram) {
|
||||
+ size_t rand_len = BRCMF_RANDOM_SEED_LENGTH;
|
||||
+ struct brcmf_random_seed_footer footer = {
|
||||
+ .length = cpu_to_le32(rand_len),
|
||||
+ .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC),
|
||||
+ };
|
||||
+ void *randbuf;
|
||||
+
|
||||
brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name);
|
||||
address = devinfo->ci->rambase + devinfo->ci->ramsize -
|
||||
nvram_len;
|
||||
memcpy_toio(devinfo->tcm + address, nvram, nvram_len);
|
||||
brcmf_fw_nvram_free(nvram);
|
||||
+
|
||||
+ /* Some Apple chips/firmwares expect a buffer of random data
|
||||
+ * to be present before NVRAM
|
||||
+ */
|
||||
+ brcmf_dbg(PCIE, "Download random seed\n");
|
||||
+
|
||||
+ address -= sizeof(footer);
|
||||
+ memcpy_toio(devinfo->tcm + address, &footer, sizeof(footer));
|
||||
+
|
||||
+ address -= rand_len;
|
||||
+ randbuf = kzalloc(rand_len, GFP_KERNEL);
|
||||
+ get_random_bytes(randbuf, rand_len);
|
||||
+ memcpy_toio(devinfo->tcm + address, randbuf, rand_len);
|
||||
+ kfree(randbuf);
|
||||
} else {
|
||||
brcmf_dbg(PCIE, "No matching NVRAM file found %s\n",
|
||||
devinfo->nvram_name);
|
||||
--
|
||||
2.34.1
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user