layerscape: drop kernel 4.9 support

This patch is to drop kernel 4.9 support.

Signed-off-by: Biwen Li <biwen.li@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
This commit is contained in:
Biwen Li 2018-12-12 09:56:18 +08:00 committed by Hauke Mehrtens
parent 328530c6e7
commit 68904cb8fd
38 changed files with 0 additions and 275972 deletions

View File

@ -1,952 +0,0 @@
CONFIG_ABX500_CORE=y
CONFIG_AD525X_DPOT=y
CONFIG_AD525X_DPOT_I2C=y
# CONFIG_AD525X_DPOT_SPI is not set
CONFIG_AHCI_IMX=y
CONFIG_AHCI_QORIQ=y
CONFIG_AK8975=y
CONFIG_ALIGNMENT_TRAP=y
CONFIG_APDS9802ALS=y
CONFIG_AQUANTIA_PHY=y
# CONFIG_ARCH_AXXIA is not set
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
CONFIG_ARCH_HAS_SG_CHAIN=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MULTIPLATFORM=y
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_MXC=y
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ARM=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
CONFIG_ARM_CPUIDLE=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_CRYPTO=y
CONFIG_ARM_ERRATA_430973=y
CONFIG_ARM_ERRATA_643719=y
CONFIG_ARM_ERRATA_720789=y
CONFIG_ARM_ERRATA_754322=y
CONFIG_ARM_ERRATA_754327=y
CONFIG_ARM_ERRATA_764369=y
CONFIG_ARM_ERRATA_775420=y
CONFIG_ARM_ERRATA_798181=y
CONFIG_ARM_GIC=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_ARM_HEAVY_MB=y
# CONFIG_ARM_HIGHBANK_CPUIDLE is not set
CONFIG_ARM_IMX6Q_CPUFREQ=y
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_L1_CACHE_SHIFT_6=y
CONFIG_ARM_LPAE=y
CONFIG_ARM_PATCH_IDIV=y
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_ARM_PMU=y
CONFIG_ARM_PSCI=y
CONFIG_ARM_PSCI_FW=y
# CONFIG_ARM_SMMU is not set
CONFIG_ARM_THUMB=y
CONFIG_ARM_THUMBEE=y
CONFIG_ARM_TIMER_SP804=y
CONFIG_ARM_UNWIND=y
CONFIG_ARM_VIRT_EXT=y
CONFIG_ASSOCIATIVE_ARRAY=y
CONFIG_AT803X_PHY=y
CONFIG_ATA=y
CONFIG_ATAGS=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_AUTOFS4_FS=y
CONFIG_AUTO_ZRELADDR=y
# CONFIG_AXP20X_POWER is not set
CONFIG_BATTERY_ACT8945A=y
CONFIG_BATTERY_SBS=y
CONFIG_BCM_NET_PHYLIB=y
# CONFIG_BLK_CGROUP is not set
CONFIG_BLK_CMDLINE_PARSER=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=262144
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_BLK_MQ_PCI=y
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
CONFIG_BOUNCE=y
# CONFIG_BPF_SYSCALL is not set
CONFIG_BRCMSTB_GISB_ARB=y
CONFIG_BROADCOM_PHY=y
CONFIG_BUILD_BIN2C=y
CONFIG_CACHE_L2X0=y
# CONFIG_CACHE_L2X0_PMU is not set
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_CFS_BANDWIDTH is not set
CONFIG_CGROUPS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_FREEZER=y
# CONFIG_CGROUP_PERF is not set
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_SCHED=y
# CONFIG_CHARGER_MAX14577 is not set
CONFIG_CHARGER_TPS65090=y
# CONFIG_CHARGER_TPS65217 is not set
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_CHROME_PLATFORMS=y
CONFIG_CHR_DEV_SG=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_IMX_GPT=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLKSRC_OF=y
CONFIG_CLKSRC_PROBE=y
CONFIG_CLKSRC_VERSATILE=y
CONFIG_CLK_QORIQ=y
CONFIG_CLONE_BACKWARDS=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=64
# 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_CMDLINE_PARTITION=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_MAX77686=y
# CONFIG_COMMON_CLK_PALMAS is not set
# CONFIG_COMMON_CLK_RK808 is not set
# CONFIG_COMMON_CLK_S2MPS11 is not set
CONFIG_COMPAT_BRK=y
CONFIG_CONFIGFS_FS=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_COREDUMP=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
# CONFIG_CORTINA_PHY is not set
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPUSETS=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
# CONFIG_CPU_BIG_ENDIAN is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_HAS_ASID=y
# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
# CONFIG_CPU_ICACHE_DISABLE is not set
CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_PM=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_THERMAL=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_V7=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
# CONFIG_CRYPTO_AES_ARM_CE is not set
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_GHASH_ARM_CE is not set
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_NULL2=y
# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_RNG2=y
# CONFIG_CRYPTO_SHA1_ARM_CE is not set
# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
# CONFIG_CRYPTO_SHA256_ARM is not set
# CONFIG_CRYPTO_SHA2_ARM_CE is not set
# CONFIG_CRYPTO_SHA512_ARM is not set
# CONFIG_CRYPTO_TLS is not set
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_ALIGN_RODATA=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_IMX_UART_PORT=1
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
CONFIG_DEBUG_RODATA=y
# CONFIG_DEBUG_UART_8250 is not set
# CONFIG_DEBUG_USER is not set
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_DEVFREQ_GOV_PASSIVE is not set
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
# CONFIG_DEVFREQ_GOV_USERSPACE is not set
# CONFIG_DEVFREQ_THERMAL is not set
CONFIG_DEVKMEM=y
CONFIG_DEVMEM=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMADEVICES=y
CONFIG_DMA_CMA=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DNOTIFY=y
CONFIG_DNS_RESOLVER=y
CONFIG_DTC=y
CONFIG_DT_IDLE_STATES=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_DW_DMAC=y
CONFIG_DW_DMAC_CORE=y
CONFIG_DW_WATCHDOG=y
CONFIG_EDAC=y
CONFIG_EDAC_ATOMIC_SCRUB=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_LEGACY_SYSFS=y
# CONFIG_EDAC_MM_EDAC is not set
CONFIG_EDAC_SUPPORT=y
CONFIG_EEPROM_93CX6=y
CONFIG_EEPROM_AT24=y
CONFIG_EFI=y
# CONFIG_EFIVAR_FS is not set
CONFIG_EFI_ARMSTUB=y
# CONFIG_EFI_CAPSULE_LOADER is not set
CONFIG_EFI_ESRT=y
CONFIG_EFI_PARAMS_FROM_FDT=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_STUB=y
# CONFIG_EFI_TEST is not set
# CONFIG_EFI_VARS is not set
CONFIG_ELF_CORE=y
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_EXPORTFS=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
# CONFIG_EXTCON_MAX14577 is not set
# CONFIG_EXTCON_MAX8997 is not set
# CONFIG_EXTCON_PALMAS is not set
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_FAT_FS=y
# CONFIG_FEC is not set
CONFIG_FHANDLE=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FORCE_MAX_ZONEORDER=12
CONFIG_FREEZER=y
CONFIG_FSL_EDMA=y
CONFIG_FSL_GUTS=y
CONFIG_FSL_IFC=y
# CONFIG_FSL_PPFE is not set
CONFIG_FSL_PQ_MDIO=y
# CONFIG_FSL_QDMA is not set
# CONFIG_FSL_SDK_DPA is not set
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_MBCACHE=y
CONFIG_FS_POSIX_ACL=y
CONFIG_FTM_ALARM=y
CONFIG_FTRACE=y
# CONFIG_FTRACE_SYSCALLS is not set
CONFIG_FUSE_FS=y
# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_CHIP=y
# CONFIG_GENERIC_IRQ_DEBUGFS is not set
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_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_GIANFAR=y
CONFIG_GLOB=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_IRQCHIP=y
# CONFIG_GPIO_AXP209 is not set
CONFIG_GPIO_DWAPB=y
CONFIG_GPIO_EM=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_MXC=y
CONFIG_GPIO_PALMAS=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PCF857X=y
# CONFIG_GPIO_STMPE is not set
CONFIG_GPIO_SYSCON=y
# CONFIG_GPIO_TPS65218 is not set
CONFIG_GPIO_TPS6586X=y
CONFIG_GPIO_TPS65910=y
CONFIG_GPIO_TWL4030=y
CONFIG_GPIO_XILINX=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_HAVE_ARCH_BITREVERSE=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARM_ARCH_TIMER=y
CONFIG_HAVE_ARM_SMCCC=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_HAVE_CBPF_JIT=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_GENERIC_RCU_GUP=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IMX_SRC=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y
CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
CONFIG_HAVE_KVM_EVENTFD=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_IRQFD=y
CONFIG_HAVE_KVM_IRQ_ROUTING=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_HAVE_RCU_TABLE_FREE=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_SMP=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_UID16=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HID=y
CONFIG_HID_GENERIC=y
CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
CONFIG_HOTPLUG_CPU=y
# CONFIG_HUGETLBFS is not set
CONFIG_HVC_DRIVER=y
CONFIG_HWMON=y
CONFIG_HW_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_HZ_FIXED=0
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_DEMUX_PINCTRL=y
CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_IMX=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
CONFIG_I2C_MUX_PINCTRL=y
CONFIG_I2C_RK3X=y
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=y
CONFIG_I2C_XILINX=y
CONFIG_ICPLUS_PHY=y
CONFIG_ICS932S401=y
CONFIG_IIO=y
CONFIG_IIO_BUFFER=y
CONFIG_IIO_CONFIGFS=y
CONFIG_IIO_HRTIMER_TRIGGER=y
CONFIG_IIO_KFIFO_BUF=y
CONFIG_IIO_SW_TRIGGER=y
# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set
CONFIG_IIO_TRIGGER=y
CONFIG_IIO_TRIGGERED_BUFFER=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_IMX2_WDT=y
CONFIG_IMX_DMA=y
CONFIG_IMX_SDMA=y
# CONFIG_IMX_WEIM is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INPUT=y
# CONFIG_INPUT_MISC is not set
CONFIG_IOMMU_HELPER=y
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
CONFIG_IOMMU_SUPPORT=y
CONFIG_IOSCHED_CFQ=y
CONFIG_IPC_NS=y
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_DEBUG=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
# CONFIG_ISDN is not set
CONFIG_ISL29003=y
CONFIG_JBD2=y
CONFIG_KALLSYMS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_KEXEC=y
CONFIG_KEXEC_CORE=y
CONFIG_KEYS=y
CONFIG_KVM=y
CONFIG_KVM_ARM_HOST=y
CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
CONFIG_KVM_MMIO=y
CONFIG_KVM_VFIO=y
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_MAX8997 is not set
CONFIG_LEDS_PWM=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LS_SCFG_MSI=y
CONFIG_LS_SOC_DRIVERS=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MACVLAN=y
CONFIG_MACVTAP=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAILBOX=y
# CONFIG_MAILBOX_TEST is not set
CONFIG_MANDATORY_FILE_LOCKING=y
CONFIG_MARVELL_PHY=y
CONFIG_MCPM=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_BOARDINFO=y
# CONFIG_MDIO_FSL_BACKPLANE is not set
# CONFIG_MDIO_GPIO is not set
CONFIG_MEMCG=y
# CONFIG_MEMCG_SWAP is not set
CONFIG_MEMORY=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_MFD_ACT8945A=y
CONFIG_MFD_AS3711=y
CONFIG_MFD_AS3722=y
CONFIG_MFD_ATMEL_FLEXCOM=y
CONFIG_MFD_AXP20X=y
CONFIG_MFD_AXP20X_I2C=y
CONFIG_MFD_BCM590XX=y
CONFIG_MFD_CORE=y
CONFIG_MFD_MAX14577=y
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX8907=y
CONFIG_MFD_MAX8997=y
CONFIG_MFD_MAX8998=y
CONFIG_MFD_PALMAS=y
CONFIG_MFD_RK808=y
CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_STMPE=y
CONFIG_MFD_SYSCON=y
CONFIG_MFD_TPS65090=y
CONFIG_MFD_TPS65217=y
CONFIG_MFD_TPS65218=y
CONFIG_MFD_TPS6586X=y
CONFIG_MFD_TPS65910=y
# CONFIG_MFD_TWL4030_AUDIO is not set
CONFIG_MFD_VEXPRESS_SYSREG=y
CONFIG_MICREL_PHY=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_MIGHT_HAVE_PCI=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=16
# CONFIG_MMC_MXC is not set
CONFIG_MMC_SDHCI=y
# CONFIG_MMC_SDHCI_ESDHC_IMX is not set
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_OF_ESDHC=y
# CONFIG_MMC_SDHCI_PCI is not set
CONFIG_MMC_SDHCI_PLTFM=y
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MMU_NOTIFIER=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MSDOS_FS=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_DATAFLASH=y
# CONFIG_MTD_DATAFLASH_OTP is not set
# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
CONFIG_MTD_M25P80=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_BRCMNAND=y
CONFIG_MTD_NAND_DENALI=y
CONFIG_MTD_NAND_DENALI_DT=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_FSL_IFC=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
CONFIG_MTD_SST25L=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
# CONFIG_MTD_UBI_BLOCK is not set
# CONFIG_MTD_UBI_FASTMAP is not set
# CONFIG_MTD_UBI_GLUEBI is not set
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_MX3_IPU=y
CONFIG_MX3_IPU_IRQS=4
CONFIG_NAMESPACES=y
CONFIG_NATIONAL_PHY=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEON=y
# CONFIG_NET_CLS_CGROUP is not set
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_NS=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_NO_BOOTMEM=y
CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=16
CONFIG_NTFS_FS=y
CONFIG_NVMEM=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_ADDRESS_PCI=y
CONFIG_OF_DYNAMIC=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OUTER_CACHE=y
CONFIG_OUTER_CACHE_SYNC=y
CONFIG_PACKET_DIAG=y
CONFIG_PAGE_COUNTER=y
CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
# CONFIG_PCIEASPM_DEBUG is not set
CONFIG_PCIEASPM_DEFAULT=y
# CONFIG_PCIEASPM_PERFORMANCE is not set
# CONFIG_PCIEASPM_POWERSAVE is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_DW=y
CONFIG_PCIE_PME=y
CONFIG_PCI_BUS_ADDR_T_64BIT=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_ECAM=y
CONFIG_PCI_HOST_COMMON=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCI_LAYERSCAPE=y
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYLIB=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PID_NS=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AS3722=y
CONFIG_PINCTRL_PALMAS=y
CONFIG_PL310_ERRATA_588369=y
CONFIG_PL310_ERRATA_727915=y
CONFIG_PL310_ERRATA_753970=y
CONFIG_PL310_ERRATA_769419=y
CONFIG_PM=y
CONFIG_PM_CLK=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_DEVFREQ=y
# CONFIG_PM_DEVFREQ_EVENT is not set
CONFIG_PM_OPP=y
CONFIG_PM_SLEEP=y
CONFIG_PM_SLEEP_SMP=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_BRCMKONA=y
CONFIG_POWER_RESET_BRCMSTB=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_POWER_RESET_VEXPRESS=y
CONFIG_POWER_SUPPLY=y
CONFIG_PPS=y
CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_PRINTK_TIME=y
# CONFIG_PROBE_EVENTS is not set
CONFIG_PROC_CHILDREN=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PROC_PID_CPUSET=y
CONFIG_PSTORE=y
CONFIG_PSTORE_CONSOLE=y
# CONFIG_PSTORE_LZ4_COMPRESS is not set
# CONFIG_PSTORE_LZO_COMPRESS is not set
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_RAM=y
CONFIG_PSTORE_ZLIB_COMPRESS=y
CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_GIANFAR=y
CONFIG_PWM=y
# CONFIG_PWM_IMX is not set
# CONFIG_PWM_STMPE is not set
CONFIG_PWM_SYSFS=y
# CONFIG_PWM_TWL is not set
# CONFIG_PWM_TWL_LED is not set
CONFIG_QORIQ_CPUFREQ=y
# CONFIG_QUICC_ENGINE is not set
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_EXPERT is not set
CONFIG_RCU_STALL_COMMON=y
CONFIG_RD_BZIP2=y
CONFIG_RD_GZIP=y
CONFIG_RD_LZMA=y
CONFIG_RD_LZO=y
CONFIG_RD_XZ=y
CONFIG_REALTEK_PHY=y
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_DEC8=y
CONFIG_REED_SOLOMON_ENC8=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_IRQ=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_SPI=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_ACT8865=y
CONFIG_REGULATOR_ACT8945A=y
CONFIG_REGULATOR_ANATOP=y
CONFIG_REGULATOR_AS3711=y
CONFIG_REGULATOR_AS3722=y
CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_BCM590XX=y
CONFIG_REGULATOR_DA9210=y
CONFIG_REGULATOR_FAN53555=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_LP872X=y
# CONFIG_REGULATOR_MAX14577 is not set
CONFIG_REGULATOR_MAX77686=y
# CONFIG_REGULATOR_MAX77802 is not set
CONFIG_REGULATOR_MAX8907=y
CONFIG_REGULATOR_MAX8973=y
# CONFIG_REGULATOR_MAX8997 is not set
# CONFIG_REGULATOR_MAX8998 is not set
CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PWM=y
# CONFIG_REGULATOR_QCOM_SPMI is not set
CONFIG_REGULATOR_RK808=y
# CONFIG_REGULATOR_S2MPA01 is not set
CONFIG_REGULATOR_S2MPS11=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_REGULATOR_TPS51632=y
CONFIG_REGULATOR_TPS62360=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_REGULATOR_TPS65217=y
CONFIG_REGULATOR_TPS65218=y
CONFIG_REGULATOR_TPS6586X=y
CONFIG_REGULATOR_TPS65910=y
CONFIG_REGULATOR_TWL4030=y
CONFIG_REGULATOR_VEXPRESS=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_AS3722=y
# CONFIG_RTC_DRV_CMOS is not set
CONFIG_RTC_DRV_DS1307=y
CONFIG_RTC_DRV_DS1307_HWMON=y
CONFIG_RTC_DRV_DS3232=y
# CONFIG_RTC_DRV_EFI is not set
CONFIG_RTC_DRV_EM3027=y
# CONFIG_RTC_DRV_IMXDI is not set
CONFIG_RTC_DRV_MAX77686=y
CONFIG_RTC_DRV_MAX8907=y
# CONFIG_RTC_DRV_MAX8997 is not set
# CONFIG_RTC_DRV_MAX8998 is not set
# CONFIG_RTC_DRV_MXC is not set
CONFIG_RTC_DRV_PALMAS=y
CONFIG_RTC_DRV_PCF2127=y
CONFIG_RTC_DRV_PCF85263=y
# CONFIG_RTC_DRV_RK808 is not set
# CONFIG_RTC_DRV_S5M is not set
CONFIG_RTC_DRV_TPS6586X=y
CONFIG_RTC_DRV_TPS65910=y
CONFIG_RTC_DRV_TWL4030=y
CONFIG_RTC_I2C_AND_SPI=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_SATA_PMP=y
CONFIG_SATA_SIL24=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHED_INFO is not set
CONFIG_SCSI=y
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
# CONFIG_SECURITY_DMESG_RESTRICT is not set
CONFIG_SENSORS_IIO_HWMON=y
CONFIG_SENSORS_ISL29018=y
CONFIG_SENSORS_ISL29028=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_LM95245=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_EM=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_BCM63XX=y
CONFIG_SERIAL_BCM63XX_CONSOLE=y
CONFIG_SERIAL_CONEXANT_DIGICOLOR=y
CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y
CONFIG_SERIAL_FSL_LPUART=y
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_IMX=y
CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
CONFIG_SG_POOL=y
CONFIG_SLUB_DEBUG=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
CONFIG_SMSC_PHY=y
CONFIG_SOCK_DIAG=y
CONFIG_SOC_BRCMSTB=y
CONFIG_SOC_BUS=y
# CONFIG_SOC_IMX50 is not set
# CONFIG_SOC_IMX51 is not set
# CONFIG_SOC_IMX53 is not set
# CONFIG_SOC_IMX6Q is not set
# CONFIG_SOC_IMX6SL is not set
# CONFIG_SOC_IMX6SX is not set
# CONFIG_SOC_IMX6UL is not set
# CONFIG_SOC_IMX7D is not set
CONFIG_SOC_LS1021A=y
# CONFIG_SOC_VF610 is not set
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_CADENCE=y
# CONFIG_SPI_FSL_QUADSPI is not set
# CONFIG_SPI_IMX is not set
CONFIG_SPI_MASTER=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_XILINX=y
CONFIG_SPMI=y
# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
CONFIG_SQUASHFS_DECOMP_SINGLE=y
CONFIG_SQUASHFS_FILE_CACHE=y
# CONFIG_SQUASHFS_FILE_DIRECT is not set
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_ZLIB=y
CONFIG_SRAM=y
CONFIG_SRCU=y
CONFIG_STAGING_BOARD=y
CONFIG_STMPE_I2C=y
# CONFIG_STMPE_SPI is not set
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SWIOTLB=y
CONFIG_SWPHY=y
CONFIG_SWP_EMULATE=y
# CONFIG_SW_SYNC is not set
CONFIG_SYNC_FILE=y
# CONFIG_SYN_COOKIES is not set
CONFIG_SYSFS_SYSCALL=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_OF=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACING_EVENTS_GPIO=y
CONFIG_TREE_RCU=y
CONFIG_TUN=y
CONFIG_TWL4030_CORE=y
CONFIG_TWL4030_POWER=y
# CONFIG_TWL4030_WATCHDOG is not set
CONFIG_UBIFS_FS=y
# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UCS2_STRING=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNIX_DIAG=y
CONFIG_USB_SUPPORT=y
CONFIG_USER_NS=y
CONFIG_USE_OF=y
CONFIG_UTS_NS=y
CONFIG_VDSO=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_VETH=y
CONFIG_VEXPRESS_CONFIG=y
CONFIG_VEXPRESS_SYSCFG=y
CONFIG_VFAT_FS=y
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_VHOST=y
CONFIG_VHOST_NET=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_VIRTIO_MMIO=y
# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
CONFIG_VIRTIO_NET=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTUALIZATION=y
CONFIG_VITESSE_PHY=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
CONFIG_XILINX_WATCHDOG=y
CONFIG_XPS=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_IA64=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_X86=y
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,374 +0,0 @@
From 0774b97305507af18f8c43efb69aa00e6c57ae90 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Fri, 6 Jul 2018 15:31:14 +0800
Subject: [PATCH] config: support layerscape
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is an integrated patch for layerscape config/makefile support.
Signed-off-by: Yuantian Tang <andy.tang@nxp.com>
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
arch/arm/mach-imx/Kconfig | 1 +
drivers/base/Kconfig | 1 +
drivers/crypto/Makefile | 2 +-
drivers/net/ethernet/freescale/Kconfig | 4 +-
drivers/net/ethernet/freescale/Makefile | 2 +
drivers/ptp/Kconfig | 29 +++++++++++
drivers/rtc/Kconfig | 8 +++
drivers/rtc/Makefile | 1 +
drivers/soc/Kconfig | 3 +-
drivers/soc/fsl/Kconfig | 30 ++++++++++++
drivers/soc/fsl/Kconfig.arm | 16 ++++++
drivers/soc/fsl/Makefile | 5 ++
drivers/soc/fsl/layerscape/Kconfig | 10 ++++
drivers/soc/fsl/layerscape/Makefile | 1 +
drivers/staging/Kconfig | 6 +++
drivers/staging/Makefile | 3 ++
drivers/staging/fsl-dpaa2/Kconfig | 65 +++++++++++++++++++++++++
drivers/staging/fsl-dpaa2/Makefile | 9 ++++
18 files changed, 192 insertions(+), 4 deletions(-)
create mode 100644 drivers/soc/fsl/Kconfig
create mode 100644 drivers/soc/fsl/Kconfig.arm
create mode 100644 drivers/soc/fsl/layerscape/Kconfig
create mode 100644 drivers/soc/fsl/layerscape/Makefile
create mode 100644 drivers/staging/fsl-dpaa2/Kconfig
create mode 100644 drivers/staging/fsl-dpaa2/Makefile
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -1,6 +1,7 @@
menuconfig ARCH_MXC
bool "Freescale i.MX family"
depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_SUPPORTS_BIG_ENDIAN
select CLKSRC_IMX_GPT
select GENERIC_IRQ_CHIP
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -240,6 +240,7 @@ config GENERIC_CPU_VULNERABILITIES
config SOC_BUS
bool
+ select GLOB
source "drivers/base/regmap/Kconfig"
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_CRYPTO_DEV_ATMEL_SHA) += at
obj-$(CONFIG_CRYPTO_DEV_ATMEL_TDES) += atmel-tdes.o
obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o
obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/
-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON) += caam/
obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -5,7 +5,7 @@
config NET_VENDOR_FREESCALE
bool "Freescale devices"
default y
- depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
+ depends on FSL_SOC || (QUICC_ENGINE && PPC32) || CPM1 || CPM2 || PPC_MPC512x || \
M523x || M527x || M5272 || M528x || M520x || M532x || \
ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
ARCH_LAYERSCAPE
@@ -93,4 +93,6 @@ config GIANFAR
and MPC86xx family of chips, the eTSEC on LS1021A and the FEC
on the 8540.
+source "drivers/net/ethernet/freescale/sdk_fman/Kconfig"
+source "drivers/net/ethernet/freescale/sdk_dpaa/Kconfig"
endif # NET_VENDOR_FREESCALE
--- a/drivers/net/ethernet/freescale/Makefile
+++ b/drivers/net/ethernet/freescale/Makefile
@@ -21,4 +21,6 @@ gianfar_driver-objs := gianfar.o \
obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
+obj-$(if $(CONFIG_FSL_SDK_FMAN),y) += sdk_fman/
+obj-$(if $(CONFIG_FSL_SDK_DPAA_ETH),y) += sdk_dpaa/
obj-$(CONFIG_FSL_FMAN) += fman/
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -39,6 +39,35 @@ config PTP_1588_CLOCK_GIANFAR
To compile this driver as a module, choose M here: the module
will be called gianfar_ptp.
+config PTP_1588_CLOCK_DPAA
+ tristate "Freescale DPAA as PTP clock"
+ depends on FSL_SDK_DPAA_ETH
+ select PTP_1588_CLOCK
+ select FSL_DPAA_TS
+ default n
+ help
+ This driver adds support for using the DPAA 1588 timer module
+ as a PTP clock. This clock is only useful if your PTP programs are
+ getting hardware time stamps on the PTP Ethernet packets
+ using the SO_TIMESTAMPING API.
+
+ To compile this driver as a module, choose M here: the module
+ will be called dpaa_ptp.
+
+config PTP_1588_CLOCK_DPAA2
+ tristate "Freescale DPAA2 as PTP clock"
+ depends on FSL_DPAA2_ETH
+ select PTP_1588_CLOCK
+ default y
+ help
+ This driver adds support for using the DPAA2 1588 timer module
+ as a PTP clock. This clock is only useful if your PTP programs are
+ getting hardware time stamps on the PTP Ethernet packets
+ using the SO_TIMESTAMPING API.
+
+ To compile this driver as a module, choose M here: the module
+ will be called dpaa2-rtc.
+
config PTP_1588_CLOCK_IXP46X
tristate "Intel IXP46x as PTP clock"
depends on IXP4XX_ETH
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -414,6 +414,14 @@ config RTC_DRV_PCF85063
This driver can also be built as a module. If so, the module
will be called rtc-pcf85063.
+config RTC_DRV_PCF85263
+ tristate "NXP PCF85263"
+ help
+ If you say yes here you get support for the PCF85263 RTC chip
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-pcf85263.
+
config RTC_DRV_PCF8563
tristate "Philips PCF8563/Epson RTC8564"
help
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
+obj-$(CONFIG_RTC_DRV_PCF85263) += rtc-pcf85263.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PIC32) += rtc-pic32.o
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,8 +1,7 @@
menu "SOC (System On Chip) specific Drivers"
source "drivers/soc/bcm/Kconfig"
-source "drivers/soc/fsl/qbman/Kconfig"
-source "drivers/soc/fsl/qe/Kconfig"
+source "drivers/soc/fsl/Kconfig"
source "drivers/soc/mediatek/Kconfig"
source "drivers/soc/qcom/Kconfig"
source "drivers/soc/rockchip/Kconfig"
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,30 @@
+#
+# Freescale SOC drivers
+#
+
+source "drivers/soc/fsl/qbman/Kconfig"
+source "drivers/soc/fsl/qe/Kconfig"
+source "drivers/soc/fsl/ls2-console/Kconfig"
+
+config FSL_GUTS
+ bool
+ select SOC_BUS
+ help
+ The global utilities block controls power management, I/O device
+ enabling, power-onreset(POR) configuration monitoring, alternate
+ function selection for multiplexed signals,and clock control.
+ This driver is to manage and access global utilities block.
+ Initially only reading SVR and registering soc device are supported.
+ Other guts accesses, such as reading RCW, should eventually be moved
+ into this driver as well.
+
+config FSL_SLEEP_FSM
+ bool
+ help
+ This driver configures a hardware FSM (Finite State Machine) for deep sleep.
+ The FSM is used to finish clean-ups at the last stage of system entering deep
+ sleep, and also wakes up system when a wake up event happens.
+
+if ARM || ARM64
+source "drivers/soc/fsl/Kconfig.arm"
+endif
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig.arm
@@ -0,0 +1,16 @@
+#
+# Freescale ARM SOC Drivers
+#
+
+config LS_SOC_DRIVERS
+ bool "Layerscape Soc Drivers"
+ depends on ARCH_LAYERSCAPE || SOC_LS1021A
+ default n
+ help
+ Say y here to enable Freescale Layerscape Soc Device Drivers support.
+ The Soc Drivers provides the device driver that is a specific block
+ or feature on Layerscape platform.
+
+if LS_SOC_DRIVERS
+ source "drivers/soc/fsl/layerscape/Kconfig"
+endif
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -5,3 +5,8 @@
obj-$(CONFIG_FSL_DPAA) += qbman/
obj-$(CONFIG_QUICC_ENGINE) += qe/
obj-$(CONFIG_CPM) += qe/
+obj-$(CONFIG_FSL_GUTS) += guts.o
+obj-$(CONFIG_FSL_LS2_CONSOLE) += ls2-console/
+obj-$(CONFIG_SUSPEND) += rcpm.o
+obj-$(CONFIG_LS_SOC_DRIVERS) += layerscape/
+obj-$(CONFIG_FSL_SLEEP_FSM) += sleep_fsm.o
--- /dev/null
+++ b/drivers/soc/fsl/layerscape/Kconfig
@@ -0,0 +1,10 @@
+#
+# Layerscape Soc drivers
+#
+config FTM_ALARM
+ bool "FTM alarm driver"
+ default n
+ help
+ Say y here to enable FTM alarm support. The FTM alarm provides
+ alarm functions for wakeup system from deep sleep. There is only
+ one FTM can be used in ALARM(FTM 0).
--- /dev/null
+++ b/drivers/soc/fsl/layerscape/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -94,6 +94,8 @@ source "drivers/staging/fbtft/Kconfig"
source "drivers/staging/fsl-mc/Kconfig"
+source "drivers/staging/fsl-dpaa2/Kconfig"
+
source "drivers/staging/wilc1000/Kconfig"
source "drivers/staging/most/Kconfig"
@@ -106,4 +108,8 @@ source "drivers/staging/greybus/Kconfig"
source "drivers/staging/vc04_services/Kconfig"
+source "drivers/staging/fsl_qbman/Kconfig"
+
+source "drivers/staging/fsl_ppfe/Kconfig"
+
endif # STAGING
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -36,9 +36,12 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/
obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/
obj-$(CONFIG_FB_TFT) += fbtft/
obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/
+obj-$(CONFIG_FSL_DPAA2) += fsl-dpaa2/
obj-$(CONFIG_WILC1000) += wilc1000/
obj-$(CONFIG_MOST) += most/
obj-$(CONFIG_ISDN_I4L) += i4l/
obj-$(CONFIG_KS7010) += ks7010/
obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2708_VCHIQ) += vc04_services/
+obj-$(CONFIG_FSL_SDK_DPA) += fsl_qbman/
+obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/
--- /dev/null
+++ b/drivers/staging/fsl-dpaa2/Kconfig
@@ -0,0 +1,65 @@
+#
+# Freescale DataPath Acceleration Architecture Gen2 (DPAA2) drivers
+#
+
+config FSL_DPAA2
+ bool "Freescale DPAA2 devices"
+ depends on FSL_MC_BUS
+ ---help---
+ Build drivers for Freescale DataPath Acceleration
+ Architecture (DPAA2) family of SoCs.
+
+config FSL_DPAA2_ETH
+ tristate "Freescale DPAA2 Ethernet"
+ depends on FSL_DPAA2 && FSL_MC_DPIO
+ ---help---
+ Ethernet driver for Freescale DPAA2 SoCs, using the
+ Freescale MC bus driver
+
+if FSL_DPAA2_ETH
+config FSL_DPAA2_ETH_USE_ERR_QUEUE
+ bool "Enable Rx error queue"
+ default n
+ ---help---
+ Allow Rx error frames to be enqueued on an error queue
+ and processed by the driver (by default they are dropped
+ in hardware).
+ This may impact performance, recommended for debugging
+ purposes only.
+
+# QBMAN_DEBUG requires some additional DPIO APIs
+config FSL_DPAA2_ETH_DEBUGFS
+ depends on DEBUG_FS
+ bool "Enable debugfs support"
+ default n
+ ---help---
+ Enable advanced statistics through debugfs interface.
+
+config FSL_DPAA2_ETH_DCB
+ bool "Data Center Bridging (DCB) Support"
+ default n
+ depends on DCB
+ ---help---
+ Say Y here if you want to use Data Center Bridging (DCB) features
+ (PFC) in the driver.
+
+ If unsure, say N.
+
+config FSL_DPAA2_ETH_CEETM
+ depends on NET_SCHED
+ bool "DPAA2 Ethernet CEETM QoS"
+ default n
+ ---help---
+ Enable QoS offloading support through the CEETM hardware block.
+endif
+
+source "drivers/staging/fsl-dpaa2/mac/Kconfig"
+source "drivers/staging/fsl-dpaa2/evb/Kconfig"
+
+config FSL_DPAA2_ETHSW
+ tristate "Freescale DPAA2 Ethernet Switch"
+ depends on FSL_DPAA2
+ depends on NET_SWITCHDEV
+ ---help---
+ Driver for Freescale DPAA2 Ethernet Switch. Select
+ BRIDGE to have support for bridge tools.
--- /dev/null
+++ b/drivers/staging/fsl-dpaa2/Makefile
@@ -0,0 +1,9 @@
+#
+# Freescale DataPath Acceleration Architecture Gen2 (DPAA2) drivers
+#
+
+obj-$(CONFIG_FSL_DPAA2_ETH) += ethernet/
+obj-$(CONFIG_FSL_DPAA2_MAC) += mac/
+obj-$(CONFIG_FSL_DPAA2_EVB) += evb/
+obj-$(CONFIG_PTP_1588_CLOCK_DPAA2) += rtc/
+obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/

View File

@ -1,517 +0,0 @@
From 2f2a0ab9e4b3186be981f7151a4f4f794d4b6caa Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Thu, 5 Jul 2018 16:18:37 +0800
Subject: [PATCH 03/32] arch: support layerscape
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is an integrated patch for layerscape arch support.
Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Signed-off-by: Zhao Qiang <B45475@freescale.com>
Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
Signed-off-by: Pan Jiafei <Jiafei.Pan@nxp.com>
Signed-off-by: Po Liu <po.liu@nxp.com>
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Jianhua Xie <jianhua.xie@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
arch/arm/include/asm/delay.h | 16 +++++++
arch/arm/include/asm/dma-mapping.h | 6 ---
arch/arm/include/asm/io.h | 31 +++++++++++++
arch/arm/include/asm/mach/map.h | 4 +-
arch/arm/include/asm/pgtable.h | 7 +++
arch/arm/kernel/bios32.c | 43 ++++++++++++++++++
arch/arm/mm/dma-mapping.c | 1 +
arch/arm/mm/ioremap.c | 7 +++
arch/arm/mm/mmu.c | 9 ++++
arch/arm64/include/asm/cache.h | 2 +-
arch/arm64/include/asm/io.h | 30 +++++++++++++
arch/arm64/include/asm/pci.h | 4 ++
arch/arm64/include/asm/pgtable-prot.h | 2 +
arch/arm64/include/asm/pgtable.h | 5 +++
arch/arm64/kernel/pci.c | 62 ++++++++++++++++++++++++++
arch/arm64/mm/dma-mapping.c | 6 +++
arch/powerpc/include/asm/dma-mapping.h | 5 ---
arch/tile/include/asm/dma-mapping.h | 5 ---
18 files changed, 226 insertions(+), 19 deletions(-)
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -57,6 +57,22 @@ extern void __bad_udelay(void);
__const_udelay((n) * UDELAY_MULT)) : \
__udelay(n))
+#define spin_event_timeout(condition, timeout, delay) \
+({ \
+ typeof(condition) __ret; \
+ int i = 0; \
+ while (!(__ret = (condition)) && (i++ < timeout)) { \
+ if (delay) \
+ udelay(delay); \
+ else \
+ cpu_relax(); \
+ udelay(1); \
+ } \
+ if (!__ret) \
+ __ret = (condition); \
+ __ret; \
+})
+
/* Loop-based definitions for assembly code. */
extern void __loop_delay(unsigned long loops);
extern void __loop_udelay(unsigned long usecs);
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -31,12 +31,6 @@ static inline struct dma_map_ops *get_dm
return __generic_dma_ops(dev);
}
-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
-{
- BUG_ON(!dev);
- dev->archdata.dma_ops = ops;
-}
-
#define HAVE_ARCH_DMA_SUPPORTED 1
extern int dma_supported(struct device *dev, u64 mask);
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -129,6 +129,7 @@ static inline u32 __raw_readl(const vola
#define MT_DEVICE_NONSHARED 1
#define MT_DEVICE_CACHED 2
#define MT_DEVICE_WC 3
+#define MT_MEMORY_RW_NS 4
/*
* types 4 onwards can be found in asm/mach/map.h and are undefined
* for ioremap
@@ -220,6 +221,34 @@ extern int pci_ioremap_io(unsigned int o
#endif
#endif
+/* access ports */
+#define setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr))
+#define clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
+
+#define setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr))
+#define clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr))
+
+#define setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr))
+#define clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr))
+
+/* Clear and set bits in one shot. These macros can be used to clear and
+ * set multiple bits in a register using a single read-modify-write. These
+ * macros can also be used to set a multiple-bit bit pattern using a mask,
+ * by specifying the mask in the 'clear' parameter and the new bit pattern
+ * in the 'set' parameter.
+ */
+
+#define clrsetbits_be32(addr, clear, set) \
+ iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_le32(addr, clear, set) \
+ iowrite32le((ioread32le(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_be16(addr, clear, set) \
+ iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_le16(addr, clear, set) \
+ iowrite16le((ioread16le(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_8(addr, clear, set) \
+ iowrite8((ioread8(addr) & ~(clear)) | (set), (addr))
+
/*
* IO port access primitives
* -------------------------
@@ -408,6 +437,8 @@ void __iomem *ioremap_wc(resource_size_t
#define ioremap_wc ioremap_wc
#define ioremap_wt ioremap_wc
+void __iomem *ioremap_cache_ns(resource_size_t res_cookie, size_t size);
+
void iounmap(volatile void __iomem *iomem_cookie);
#define iounmap iounmap
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -21,9 +21,9 @@ struct map_desc {
unsigned int type;
};
-/* types 0-3 are defined in asm/io.h */
+/* types 0-4 are defined in asm/io.h */
enum {
- MT_UNCACHED = 4,
+ MT_UNCACHED = 5,
MT_CACHECLEAN,
MT_MINICLEAN,
MT_LOW_VECTORS,
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -118,6 +118,13 @@ extern pgprot_t pgprot_s2_device;
#define pgprot_noncached(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
+#define pgprot_cached(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_DEV_CACHED)
+
+#define pgprot_cached_ns(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_DEV_CACHED | \
+ L_PTE_MT_DEV_NONSHARED)
+
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -11,6 +11,8 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/of_irq.h>
+#include <linux/pcieport_if.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -64,6 +66,47 @@ void pcibios_report_status(u_int status_
}
/*
+ * Check device tree if the service interrupts are there
+ */
+int pcibios_check_service_irqs(struct pci_dev *dev, int *irqs, int mask)
+{
+ int ret, count = 0;
+ struct device_node *np = NULL;
+
+ if (dev->bus->dev.of_node)
+ np = dev->bus->dev.of_node;
+
+ if (np == NULL)
+ return 0;
+
+ if (!IS_ENABLED(CONFIG_OF_IRQ))
+ return 0;
+
+ /* If root port doesn't support MSI/MSI-X/INTx in RC mode,
+ * request irq for aer
+ */
+ if (mask & PCIE_PORT_SERVICE_AER) {
+ ret = of_irq_get_byname(np, "aer");
+ if (ret > 0) {
+ irqs[PCIE_PORT_SERVICE_AER_SHIFT] = ret;
+ count++;
+ }
+ }
+
+ if (mask & PCIE_PORT_SERVICE_PME) {
+ ret = of_irq_get_byname(np, "pme");
+ if (ret > 0) {
+ irqs[PCIE_PORT_SERVICE_PME_SHIFT] = ret;
+ count++;
+ }
+ }
+
+ /* TODO: add more service interrupts if there it is in the device tree*/
+
+ return count;
+}
+
+/*
* We don't use this to fix the device, but initialisation of it.
* It's not the correct use for this, but it works.
* Note that the arbiter/ISA bridge appears to be buggy, specifically in
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2410,6 +2410,7 @@ void arch_setup_dma_ops(struct device *d
set_dma_ops(dev, dma_ops);
}
+EXPORT_SYMBOL(arch_setup_dma_ops);
void arch_teardown_dma_ops(struct device *dev)
{
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -398,6 +398,13 @@ void __iomem *ioremap_wc(resource_size_t
}
EXPORT_SYMBOL(ioremap_wc);
+void __iomem *ioremap_cache_ns(resource_size_t res_cookie, size_t size)
+{
+ return arch_ioremap_caller(res_cookie, size, MT_MEMORY_RW_NS,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(ioremap_cache_ns);
+
/*
* Remap an arbitrary physical address space into the kernel virtual
* address space as memory. Needed when the kernel wants to execute
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -313,6 +313,13 @@ static struct mem_type mem_types[] __ro_
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
+ [MT_MEMORY_RW_NS] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_XN,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_XN,
+ .domain = DOMAIN_KERNEL,
+ },
[MT_ROM] = {
.prot_sect = PMD_TYPE_SECT,
.domain = DOMAIN_KERNEL,
@@ -644,6 +651,7 @@ static void __init build_mem_type_table(
}
kern_pgprot |= PTE_EXT_AF;
vecs_pgprot |= PTE_EXT_AF;
+ mem_types[MT_MEMORY_RW_NS].prot_pte |= PTE_EXT_AF | cp->pte;
/*
* Set PXN for user mappings
@@ -672,6 +680,7 @@ static void __init build_mem_type_table(
mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_RW_NS].prot_sect |= ecc_mask | cp->pmd;
mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
mem_types[MT_ROM].prot_sect |= cp->pmd;
--- a/arch/arm64/include/asm/cache.h
+++ b/arch/arm64/include/asm/cache.h
@@ -18,7 +18,7 @@
#include <asm/cachetype.h>
-#define L1_CACHE_SHIFT 7
+#define L1_CACHE_SHIFT 6
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/*
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -171,6 +171,8 @@ extern void __iomem *ioremap_cache(phys_
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
#define ioremap_wt(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
+#define ioremap_cache_ns(addr, size) __ioremap((addr), (size), \
+ __pgprot(PROT_NORMAL_NS))
#define iounmap __iounmap
/*
@@ -184,6 +186,34 @@ extern void __iomem *ioremap_cache(phys_
#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
#define iowrite64be(v,p) ({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
+/* access ports */
+#define setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr))
+#define clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
+
+#define setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr))
+#define clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr))
+
+#define setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr))
+#define clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr))
+
+/* Clear and set bits in one shot. These macros can be used to clear and
+ * set multiple bits in a register using a single read-modify-write. These
+ * macros can also be used to set a multiple-bit bit pattern using a mask,
+ * by specifying the mask in the 'clear' parameter and the new bit pattern
+ * in the 'set' parameter.
+ */
+
+#define clrsetbits_be32(addr, clear, set) \
+ iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_le32(addr, clear, set) \
+ iowrite32le((ioread32le(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_be16(addr, clear, set) \
+ iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_le16(addr, clear, set) \
+ iowrite16le((ioread16le(addr) & ~(clear)) | (set), (addr))
+#define clrsetbits_8(addr, clear, set) \
+ iowrite8((ioread8(addr) & ~(clear)) | (set), (addr))
+
#include <asm-generic/io.h>
/*
--- a/arch/arm64/include/asm/pci.h
+++ b/arch/arm64/include/asm/pci.h
@@ -31,6 +31,10 @@ static inline int pci_get_legacy_ide_irq
return -ENODEV;
}
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state,
+ int write_combine);
static inline int pci_proc_domain(struct pci_bus *bus)
{
return 1;
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -48,6 +48,7 @@
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
+#define PROT_NORMAL_NS (PTE_TYPE_PAGE | PTE_AF | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
@@ -68,6 +69,7 @@
#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
#define PAGE_S2 __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
+#define PAGE_S2_NS __pgprot(PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDWR | PTE_TYPE_PAGE | PTE_AF)
#define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_NG | PTE_PXN | PTE_UXN)
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -370,6 +370,11 @@ static inline int pmd_protnone(pmd_t pmd
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+#define pgprot_cached(prot) \
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL) | \
+ PTE_PXN | PTE_UXN)
+#define pgprot_cached_ns(prot) \
+ __pgprot(pgprot_val(pgprot_cached(prot)) ^ PTE_SHARED)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
#define __HAVE_PHYS_MEM_ACCESS_PROT
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -17,6 +17,8 @@
#include <linux/mm.h>
#include <linux/of_pci.h>
#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/pcieport_if.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/pci-ecam.h>
@@ -53,6 +55,66 @@ int pcibios_alloc_irq(struct pci_dev *de
return 0;
}
+
+/*
+ * Check device tree if the service interrupts are there
+ */
+int pcibios_check_service_irqs(struct pci_dev *dev, int *irqs, int mask)
+{
+ int ret, count = 0;
+ struct device_node *np = NULL;
+
+ if (dev->bus->dev.of_node)
+ np = dev->bus->dev.of_node;
+
+ if (np == NULL)
+ return 0;
+
+ if (!IS_ENABLED(CONFIG_OF_IRQ))
+ return 0;
+
+ /* If root port doesn't support MSI/MSI-X/INTx in RC mode,
+ * request irq for aer
+ */
+ if (mask & PCIE_PORT_SERVICE_AER) {
+ ret = of_irq_get_byname(np, "aer");
+ if (ret > 0) {
+ irqs[PCIE_PORT_SERVICE_AER_SHIFT] = ret;
+ count++;
+ }
+ }
+
+ if (mask & PCIE_PORT_SERVICE_PME) {
+ ret = of_irq_get_byname(np, "pme");
+ if (ret > 0) {
+ irqs[PCIE_PORT_SERVICE_PME_SHIFT] = ret;
+ count++;
+ }
+ }
+
+ /* TODO: add more service interrupts if there it is in the device tree*/
+
+ return count;
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine)
+{
+ if (mmap_state == pci_mmap_io)
+ return -EINVAL;
+
+ /*
+ * Mark this as IO
+ */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
/*
* raw_pci_read/write - Platform-specific PCI config space access.
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -30,6 +30,7 @@
#include <linux/swiotlb.h>
#include <asm/cacheflush.h>
+#include <linux/fsl/mc.h>
static int swiotlb __ro_after_init;
@@ -925,6 +926,10 @@ static int __init __iommu_dma_init(void)
if (!ret)
ret = register_iommu_dma_ops_notifier(&pci_bus_type);
#endif
+#ifdef CONFIG_FSL_MC_BUS
+ if (!ret)
+ ret = register_iommu_dma_ops_notifier(&fsl_mc_bus_type);
+#endif
return ret;
}
arch_initcall(__iommu_dma_init);
@@ -978,3 +983,4 @@ void arch_setup_dma_ops(struct device *d
dev->archdata.dma_coherent = coherent;
__iommu_setup_dma_ops(dev, dma_base, size, iommu);
}
+EXPORT_SYMBOL(arch_setup_dma_ops);
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -91,11 +91,6 @@ static inline struct dma_map_ops *get_dm
return dev->archdata.dma_ops;
}
-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
-{
- dev->archdata.dma_ops = ops;
-}
-
/*
* get_dma_offset()
*
--- a/arch/tile/include/asm/dma-mapping.h
+++ b/arch/tile/include/asm/dma-mapping.h
@@ -59,11 +59,6 @@ static inline phys_addr_t dma_to_phys(st
static inline void dma_mark_clean(void *addr, size_t size) {}
-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
-{
- dev->archdata.dma_ops = ops;
-}
-
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)

View File

@ -1,95 +0,0 @@
From c0612164b379ebc8964da6bc6f6ced9736dce488 Mon Sep 17 00:00:00 2001
From: Mathew McBride <matt@traverse.com.au>
Date: Tue, 17 Apr 2018 10:01:03 +1000
Subject: [PATCH] add DTS for Traverse LS1043 Boards
Signed-off-by: Mathew McBride <matt@traverse.com.au>
---
arch/arm64/boot/dts/freescale/Makefile | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/boot/dts/freescale/traverse-ls1043v.dts
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -21,7 +21,10 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
-
+
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += traverse-ls1043v.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += traverse-ls1043s.dtb
+
always := $(dtb-y)
subdir-y := $(dts-dirs)
clean-files := *.dtb
--- a/arch/arm64/boot/dts/freescale/traverse-ls1043s.dts
+++ b/arch/arm64/boot/dts/freescale/traverse-ls1043s.dts
@@ -330,3 +330,32 @@
&sata {
status = "disabled";
};
+
+/* Additions for Layerscape SDK (4.4/4.9) Kernel only
+ * These kernels need additional setup for FMan/QMan DMA shared memory
+ */
+
+#include "qoriq-qman-portals-sdk.dtsi"
+#include "qoriq-bman-portals-sdk.dtsi"
+
+&bman_fbpr {
+ compatible = "fsl,bman-fbpr";
+ alloc-ranges = <0 0 0x10000 0>;
+};
+&qman_fqd {
+ compatible = "fsl,qman-fqd";
+ alloc-ranges = <0 0 0x10000 0>;
+};
+&qman_pfdr {
+ compatible = "fsl,qman-pfdr";
+ alloc-ranges = <0 0 0x10000 0>;
+};
+
+&soc {
+#include "qoriq-dpaa-eth.dtsi"
+#include "qoriq-fman3-0-6oh.dtsi"
+};
+
+&fman0 {
+ compatible = "fsl,fman", "simple-bus";
+};
--- a/arch/arm64/boot/dts/freescale/traverse-ls1043v.dts
+++ b/arch/arm64/boot/dts/freescale/traverse-ls1043v.dts
@@ -251,3 +251,32 @@
&sata {
status = "disabled";
};
+
+/* Additions for Layerscape SDK (4.4/4.9) Kernel only
+ * These kernels need additional setup for FMan/QMan DMA shared memory
+ */
+
+#include "qoriq-qman-portals-sdk.dtsi"
+#include "qoriq-bman-portals-sdk.dtsi"
+
+&bman_fbpr {
+ compatible = "fsl,bman-fbpr";
+ alloc-ranges = <0 0 0x10000 0>;
+};
+&qman_fqd {
+ compatible = "fsl,qman-fqd";
+ alloc-ranges = <0 0 0x10000 0>;
+};
+&qman_pfdr {
+ compatible = "fsl,qman-pfdr";
+ alloc-ranges = <0 0 0x10000 0>;
+};
+
+&soc {
+#include "qoriq-dpaa-eth.dtsi"
+#include "qoriq-fman3-0-6oh.dtsi"
+};
+
+&fman0 {
+ compatible = "fsl,fman", "simple-bus";
+};

View File

@ -1,993 +0,0 @@
From c03c545e064a81515fe109ddcc4ecb3895528e58 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Fri, 6 Jul 2018 15:32:05 +0800
Subject: [PATCH] mtd: spi-nor: support layerscape
This is an integrated patch for layerscape qspi support.
Signed-off-by: Suresh Gupta <suresh.gupta@nxp.com>
Signed-off-by: Yunhui Cui <B56489@freescale.com>
Signed-off-by: mar.krzeminski <mar.krzeminski@gmail.com>
Signed-off-by: Alison Wang <b18965@freescale.com>
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
Signed-off-by: Alexander Kurz <akurz@blala.de>
Signed-off-by: L. D. Pinney <ldpinney@gmail.com>
Signed-off-by: Ash Benz <ash.benz@bk.ru>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/mtd/devices/m25p80.c | 3 +-
drivers/mtd/mtdchar.c | 2 +-
drivers/mtd/spi-nor/fsl-quadspi.c | 327 ++++++++++++++++++++++++------
drivers/mtd/spi-nor/spi-nor.c | 141 ++++++++++++-
include/linux/mtd/spi-nor.h | 14 +-
5 files changed, 416 insertions(+), 71 deletions(-)
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -455,7 +455,7 @@ static int mtdchar_readoob(struct file *
* data. For our userspace tools it is important to dump areas
* with ECC errors!
* For kernel internal usage it also might return -EUCLEAN
- * to signal the caller that a bitflip has occured and has
+ * to signal the caller that a bitflip has occurred and has
* been corrected by the ECC algorithm.
*
* Note: currently the standard NAND function, nand_read_oob_std,
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -41,6 +41,8 @@
#define QUADSPI_QUIRK_TKT253890 (1 << 2)
/* Controller cannot wake up from wait mode, TKT245618 */
#define QUADSPI_QUIRK_TKT245618 (1 << 3)
+/* QSPI_AMBA_BASE is internally added by SOC design */
+#define QUADSPI_AMBA_BASE_INTERNAL (0x10000)
/* The registers */
#define QUADSPI_MCR 0x00
@@ -193,7 +195,7 @@
#define QUADSPI_LUT_NUM 64
/* SEQID -- we can have 16 seqids at most. */
-#define SEQID_QUAD_READ 0
+#define SEQID_READ 0
#define SEQID_WREN 1
#define SEQID_WRDI 2
#define SEQID_RDSR 3
@@ -205,15 +207,22 @@
#define SEQID_RDCR 9
#define SEQID_EN4B 10
#define SEQID_BRWR 11
+#define SEQID_RDAR_OR_RD_EVCR 12
+#define SEQID_WRAR 13
+#define SEQID_WD_EVCR 14
#define QUADSPI_MIN_IOMAP SZ_4M
+#define FLASH_VENDOR_SPANSION_FS "s25fs"
+#define SPANSION_S25FS_FAMILY (1 << 1)
+
enum fsl_qspi_devtype {
FSL_QUADSPI_VYBRID,
FSL_QUADSPI_IMX6SX,
FSL_QUADSPI_IMX7D,
FSL_QUADSPI_IMX6UL,
FSL_QUADSPI_LS1021A,
+ FSL_QUADSPI_LS2080A,
};
struct fsl_qspi_devtype_data {
@@ -224,7 +233,7 @@ struct fsl_qspi_devtype_data {
int driver_data;
};
-static struct fsl_qspi_devtype_data vybrid_data = {
+static const struct fsl_qspi_devtype_data vybrid_data = {
.devtype = FSL_QUADSPI_VYBRID,
.rxfifo = 128,
.txfifo = 64,
@@ -232,7 +241,7 @@ static struct fsl_qspi_devtype_data vybr
.driver_data = QUADSPI_QUIRK_SWAP_ENDIAN,
};
-static struct fsl_qspi_devtype_data imx6sx_data = {
+static const struct fsl_qspi_devtype_data imx6sx_data = {
.devtype = FSL_QUADSPI_IMX6SX,
.rxfifo = 128,
.txfifo = 512,
@@ -241,7 +250,7 @@ static struct fsl_qspi_devtype_data imx6
| QUADSPI_QUIRK_TKT245618,
};
-static struct fsl_qspi_devtype_data imx7d_data = {
+static const struct fsl_qspi_devtype_data imx7d_data = {
.devtype = FSL_QUADSPI_IMX7D,
.rxfifo = 512,
.txfifo = 512,
@@ -250,7 +259,7 @@ static struct fsl_qspi_devtype_data imx7
| QUADSPI_QUIRK_4X_INT_CLK,
};
-static struct fsl_qspi_devtype_data imx6ul_data = {
+static const struct fsl_qspi_devtype_data imx6ul_data = {
.devtype = FSL_QUADSPI_IMX6UL,
.rxfifo = 128,
.txfifo = 512,
@@ -267,6 +276,14 @@ static struct fsl_qspi_devtype_data ls10
.driver_data = 0,
};
+static struct fsl_qspi_devtype_data ls2080a_data = {
+ .devtype = FSL_QUADSPI_LS2080A,
+ .rxfifo = 128,
+ .txfifo = 64,
+ .ahb_buf_size = 1024,
+ .driver_data = QUADSPI_AMBA_BASE_INTERNAL | QUADSPI_QUIRK_TKT253890,
+};
+
#define FSL_QSPI_MAX_CHIP 4
struct fsl_qspi {
struct spi_nor nor[FSL_QSPI_MAX_CHIP];
@@ -282,6 +299,7 @@ struct fsl_qspi {
u32 nor_size;
u32 nor_num;
u32 clk_rate;
+ u32 ddr_smp;
unsigned int chip_base_addr; /* We may support two chips. */
bool has_second_chip;
bool big_endian;
@@ -309,6 +327,23 @@ static inline int needs_wakeup_wait_mode
return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618;
}
+static inline int has_added_amba_base_internal(struct fsl_qspi *q)
+{
+ return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
+}
+
+static u32 fsl_get_nor_vendor(struct spi_nor *nor)
+{
+ u32 vendor_id;
+
+ if (nor->vendor) {
+ if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS,
+ sizeof(FLASH_VENDOR_SPANSION_FS) - 1))
+ vendor_id = SPANSION_S25FS_FAMILY;
+ }
+ return vendor_id;
+}
+
/*
* R/W functions for big- or little-endian registers:
* The qSPI controller's endian is independent of the CPU core's endian.
@@ -331,6 +366,31 @@ static u32 qspi_readl(struct fsl_qspi *q
return ioread32(addr);
}
+static inline u32 *u8tou32(u32 *dest, const u8 *src, size_t n)
+{
+ size_t i;
+ *dest = 0;
+
+ n = n > 4 ? 4 : n;
+ for (i = 0; i < n; i++)
+ *dest |= *src++ << i * 8;
+
+ return dest;
+
+}
+
+static inline u8 *u32tou8(u8 *dest, const u32 *src, size_t n)
+{
+ size_t i;
+ u8 *xdest = dest;
+
+ n = n > 4 ? 4 : n;
+ for (i = 0; i < n; i++)
+ *xdest++ = *src >> i * 8;
+
+ return dest;
+}
+
/*
* An IC bug makes us to re-arrange the 32-bit data.
* The following chips, such as IMX6SLX, have fixed this bug.
@@ -373,8 +433,15 @@ static void fsl_qspi_init_lut(struct fsl
void __iomem *base = q->iobase;
int rxfifo = q->devtype_data->rxfifo;
u32 lut_base;
- u8 cmd, addrlen, dummy;
int i;
+ u32 vendor;
+
+ struct spi_nor *nor = &q->nor[0];
+ u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+ u8 read_op = nor->read_opcode;
+ u8 read_dm = nor->read_dummy;
+
+ vendor = fsl_get_nor_vendor(nor);
fsl_qspi_unlock_lut(q);
@@ -382,24 +449,50 @@ static void fsl_qspi_init_lut(struct fsl
for (i = 0; i < QUADSPI_LUT_NUM; i++)
qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
- /* Quad Read */
- lut_base = SEQID_QUAD_READ * 4;
+ /* Read */
+ lut_base = SEQID_READ * 4;
- if (q->nor_size <= SZ_16M) {
- cmd = SPINOR_OP_READ_1_1_4;
- addrlen = ADDR24BIT;
- dummy = 8;
- } else {
- /* use the 4-byte address */
- cmd = SPINOR_OP_READ_1_1_4;
- addrlen = ADDR32BIT;
- dummy = 8;
- }
-
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ if (nor->flash_read == SPI_NOR_FAST) {
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
+ LUT1(ADDR, PAD1, addrlen),
+ base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
+ LUT1(FSL_READ, PAD1, rxfifo),
+ base + QUADSPI_LUT(lut_base + 1));
+ } else if (nor->flash_read == SPI_NOR_QUAD) {
+ if (q->nor_size == 0x4000000) {
+ read_op = 0xEC;
+ qspi_writel(q,
+ LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen),
base + QUADSPI_LUT(lut_base));
- qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo),
+ qspi_writel(q,
+ LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm),
base + QUADSPI_LUT(lut_base + 1));
+ qspi_writel(q,
+ LUT0(FSL_READ, PAD4, rxfifo),
+ base + QUADSPI_LUT(lut_base + 2));
+ } else {
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
+ LUT1(ADDR, PAD1, addrlen),
+ base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
+ LUT1(FSL_READ, PAD4, rxfifo),
+ base + QUADSPI_LUT(lut_base + 1));
+ }
+ } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
+ /* read mode : 1-4-4, such as Spansion s25fl128s. */
+ qspi_writel(q, LUT0(CMD, PAD1, read_op)
+ | LUT1(ADDR_DDR, PAD4, addrlen),
+ base + QUADSPI_LUT(lut_base));
+
+ qspi_writel(q, LUT0(MODE_DDR, PAD4, 0xff)
+ | LUT1(DUMMY, PAD1, read_dm),
+ base + QUADSPI_LUT(lut_base + 1));
+
+ qspi_writel(q, LUT0(FSL_READ_DDR, PAD4, rxfifo)
+ | LUT1(JMP_ON_CS, PAD1, 0),
+ base + QUADSPI_LUT(lut_base + 2));
+ }
/* Write enable */
lut_base = SEQID_WREN * 4;
@@ -409,16 +502,8 @@ static void fsl_qspi_init_lut(struct fsl
/* Page Program */
lut_base = SEQID_PP * 4;
- if (q->nor_size <= SZ_16M) {
- cmd = SPINOR_OP_PP;
- addrlen = ADDR24BIT;
- } else {
- /* use the 4-byte address */
- cmd = SPINOR_OP_PP;
- addrlen = ADDR32BIT;
- }
-
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
+ LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
base + QUADSPI_LUT(lut_base + 1));
@@ -432,10 +517,8 @@ static void fsl_qspi_init_lut(struct fsl
/* Erase a sector */
lut_base = SEQID_SE * 4;
- cmd = q->nor[0].erase_opcode;
- addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT;
-
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
+ LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
/* Erase the whole chip */
@@ -476,6 +559,44 @@ static void fsl_qspi_init_lut(struct fsl
qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
base + QUADSPI_LUT(lut_base));
+
+ /*
+ * Flash Micron and Spansion command confilict
+ * use the same value 0x65. But it indicates different meaning.
+ */
+ lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
+
+ if (vendor == SPANSION_S25FS_FAMILY) {
+ /*
+ * Read any device register.
+ * Used for Spansion S25FS-S family flash only.
+ */
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_RDAR) |
+ LUT1(ADDR, PAD1, ADDR24BIT),
+ base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(DUMMY, PAD1, 8) | LUT1(FSL_READ, PAD1, 1),
+ base + QUADSPI_LUT(lut_base + 1));
+ } else {
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RD_EVCR),
+ base + QUADSPI_LUT(lut_base));
+ }
+
+ /*
+ * Write any device register.
+ * Used for Spansion S25FS-S family flash only.
+ */
+ lut_base = SEQID_WRAR * 4;
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_WRAR) |
+ LUT1(ADDR, PAD1, ADDR24BIT),
+ base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(FSL_WRITE, PAD1, 1),
+ base + QUADSPI_LUT(lut_base + 1));
+
+ /* Write EVCR register */
+ lut_base = SEQID_WD_EVCR * 4;
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WD_EVCR),
+ base + QUADSPI_LUT(lut_base));
+
fsl_qspi_lock_lut(q);
}
@@ -483,8 +604,24 @@ static void fsl_qspi_init_lut(struct fsl
static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
{
switch (cmd) {
+ case SPINOR_OP_READ_1_4_4_D:
+ case SPINOR_OP_READ4_1_4_4_D:
+ case SPINOR_OP_READ4_1_1_4:
case SPINOR_OP_READ_1_1_4:
- return SEQID_QUAD_READ;
+ case SPINOR_OP_READ_FAST:
+ case SPINOR_OP_READ4_FAST:
+ return SEQID_READ;
+ /*
+ * Spansion & Micron use the same command value 0x65
+ * Spansion: SPINOR_OP_SPANSION_RDAR, read any register.
+ * Micron: SPINOR_OP_RD_EVCR,
+ * read enhanced volatile configuration register.
+ * case SPINOR_OP_RD_EVCR:
+ */
+ case SPINOR_OP_SPANSION_RDAR:
+ return SEQID_RDAR_OR_RD_EVCR;
+ case SPINOR_OP_SPANSION_WRAR:
+ return SEQID_WRAR;
case SPINOR_OP_WREN:
return SEQID_WREN;
case SPINOR_OP_WRDI:
@@ -496,6 +633,7 @@ static int fsl_qspi_get_seqid(struct fsl
case SPINOR_OP_CHIP_ERASE:
return SEQID_CHIP_ERASE;
case SPINOR_OP_PP:
+ case SPINOR_OP_PP_4B:
return SEQID_PP;
case SPINOR_OP_RDID:
return SEQID_RDID;
@@ -507,6 +645,8 @@ static int fsl_qspi_get_seqid(struct fsl
return SEQID_EN4B;
case SPINOR_OP_BRWR:
return SEQID_BRWR;
+ case SPINOR_OP_WD_EVCR:
+ return SEQID_WD_EVCR;
default:
if (cmd == q->nor[0].erase_opcode)
return SEQID_SE;
@@ -531,8 +671,11 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
/* save the reg */
reg = qspi_readl(q, base + QUADSPI_MCR);
- qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
- base + QUADSPI_SFAR);
+ if (has_added_amba_base_internal(q))
+ qspi_writel(q, q->chip_base_addr + addr, base + QUADSPI_SFAR);
+ else
+ qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
+ base + QUADSPI_SFAR);
qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
base + QUADSPI_RBCT);
qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
@@ -582,10 +725,10 @@ static void fsl_qspi_read_data(struct fs
q->chip_base_addr, tmp);
if (len >= 4) {
- *((u32 *)rxbuf) = tmp;
+ u32tou8(rxbuf, &tmp, 4);
rxbuf += 4;
} else {
- memcpy(rxbuf, &tmp, len);
+ u32tou8(rxbuf, &tmp, len);
break;
}
@@ -619,11 +762,12 @@ static inline void fsl_qspi_invalid(stru
}
static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
- u8 opcode, unsigned int to, u32 *txbuf,
+ u8 opcode, unsigned int to, u8 *txbuf,
unsigned count)
{
int ret, i, j;
u32 tmp;
+ u8 byts;
dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len : %d\n",
q->chip_base_addr, to, count);
@@ -633,10 +777,13 @@ static ssize_t fsl_qspi_nor_write(struct
qspi_writel(q, tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
/* fill the TX data to the FIFO */
+ byts = count;
for (j = 0, i = ((count + 3) / 4); j < i; j++) {
- tmp = fsl_qspi_endian_xchg(q, *txbuf);
+ u8tou32(&tmp, txbuf, byts);
+ tmp = fsl_qspi_endian_xchg(q, tmp);
qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
- txbuf++;
+ txbuf += 4;
+ byts -= 4;
}
/* fill the TXFIFO upto 16 bytes for i.MX7d */
@@ -657,11 +804,43 @@ static void fsl_qspi_set_map_addr(struct
{
int nor_size = q->nor_size;
void __iomem *base = q->iobase;
+ u32 mem_base;
+
+ if (has_added_amba_base_internal(q))
+ mem_base = 0x0;
+ else
+ mem_base = q->memmap_phy;
+
+ qspi_writel(q, nor_size + mem_base, base + QUADSPI_SFA1AD);
+ qspi_writel(q, nor_size * 2 + mem_base, base + QUADSPI_SFA2AD);
+ qspi_writel(q, nor_size * 3 + mem_base, base + QUADSPI_SFB1AD);
+ qspi_writel(q, nor_size * 4 + mem_base, base + QUADSPI_SFB2AD);
+}
+
+/*
+ * enable controller ddr quad mode to support different
+ * vender flashes ddr quad mode.
+ */
+static void set_ddr_quad_mode(struct fsl_qspi *q)
+{
+ u32 reg, reg2;
+
+ reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
+
+ /* Firstly, disable the module */
+ qspi_writel(q, reg | QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+
+ /* Set the Sampling Register for DDR */
+ reg2 = qspi_readl(q, q->iobase + QUADSPI_SMPR);
+ reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
+ reg2 |= (((q->ddr_smp) << QUADSPI_SMPR_DDRSMP_SHIFT) &
+ QUADSPI_SMPR_DDRSMP_MASK);
+ qspi_writel(q, reg2, q->iobase + QUADSPI_SMPR);
+
+ /* Enable the module again (enable the DDR too) */
+ reg |= QUADSPI_MCR_DDR_EN_MASK;
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
- qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
- qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
- qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
- qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
}
/*
@@ -704,6 +883,11 @@ static void fsl_qspi_init_abh_read(struc
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
q->iobase + QUADSPI_BFGENCR);
+
+ /* enable the DDR quad read */
+ if (q->nor->flash_read == SPI_NOR_DDR_QUAD)
+ set_ddr_quad_mode(q);
+
}
/* This function was used to prepare and enable QSPI clock */
@@ -822,6 +1006,7 @@ static const struct of_device_id fsl_qsp
{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
+ { .compatible = "fsl,ls2080a-qspi", .data = (void *)&ls2080a_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
@@ -835,8 +1020,12 @@ static int fsl_qspi_read_reg(struct spi_
{
int ret;
struct fsl_qspi *q = nor->priv;
+ u32 to = 0;
- ret = fsl_qspi_runcmd(q, opcode, 0, len);
+ if (opcode == SPINOR_OP_SPANSION_RDAR)
+ u8tou32(&to, nor->cmd_buf, 4);
+
+ ret = fsl_qspi_runcmd(q, opcode, to, len);
if (ret)
return ret;
@@ -848,9 +1037,13 @@ static int fsl_qspi_write_reg(struct spi
{
struct fsl_qspi *q = nor->priv;
int ret;
+ u32 to = 0;
+
+ if (opcode == SPINOR_OP_SPANSION_WRAR)
+ u8tou32(&to, nor->cmd_buf, 4);
if (!buf) {
- ret = fsl_qspi_runcmd(q, opcode, 0, 1);
+ ret = fsl_qspi_runcmd(q, opcode, to, 1);
if (ret)
return ret;
@@ -859,7 +1052,7 @@ static int fsl_qspi_write_reg(struct spi
} else if (len > 0) {
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
- (u32 *)buf, len);
+ buf, len);
if (ret > 0)
return 0;
} else {
@@ -875,7 +1068,7 @@ static ssize_t fsl_qspi_write(struct spi
{
struct fsl_qspi *q = nor->priv;
ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
- (u32 *)buf, len);
+ (u8 *)buf, len);
/* invalid the data in the AHB buffer. */
fsl_qspi_invalid(q);
@@ -922,7 +1115,7 @@ static ssize_t fsl_qspi_read(struct spi_
len);
/* Read out the data directly from the AHB buffer.*/
- memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
+ memcpy_toio(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
len);
return len;
@@ -980,6 +1173,8 @@ static int fsl_qspi_probe(struct platfor
struct spi_nor *nor;
struct mtd_info *mtd;
int ret, i = 0;
+ int find_node;
+ enum read_mode mode = SPI_NOR_QUAD;
q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
if (!q)
@@ -1027,6 +1222,12 @@ static int fsl_qspi_probe(struct platfor
goto clk_failed;
}
+ /* find ddrsmp value */
+ ret = of_property_read_u32(dev->of_node, "fsl,ddr-sampling-point",
+ &q->ddr_smp);
+ if (ret)
+ q->ddr_smp = 0;
+
/* find the irq */
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
@@ -1050,6 +1251,7 @@ static int fsl_qspi_probe(struct platfor
mutex_init(&q->lock);
+ find_node = 0;
/* iterate the subnodes. */
for_each_available_child_of_node(dev->of_node, np) {
/* skip the holes */
@@ -1076,18 +1278,25 @@ static int fsl_qspi_probe(struct platfor
ret = of_property_read_u32(np, "spi-max-frequency",
&q->clk_rate);
if (ret < 0)
- goto mutex_failed;
+ continue;
/* set the chip address for READID */
fsl_qspi_set_base_addr(q, nor);
- ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
+ ret = of_property_read_bool(np, "m25p,fast-read");
+ mode = (ret) ? SPI_NOR_FAST : SPI_NOR_QUAD;
+ /* Can we enable the DDR Quad Read? */
+ ret = of_property_read_bool(np, "ddr-quad-read");
if (ret)
- goto mutex_failed;
+ mode = SPI_NOR_DDR_QUAD;
+
+ ret = spi_nor_scan(nor, NULL, mode);
+ if (ret)
+ continue;
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
- goto mutex_failed;
+ continue;
/* Set the correct NOR size now. */
if (q->nor_size == 0) {
@@ -1110,8 +1319,12 @@ static int fsl_qspi_probe(struct platfor
nor->page_size = q->devtype_data->txfifo;
i++;
+ find_node++;
}
+ if (find_node == 0)
+ goto mutex_failed;
+
/* finish the rest init. */
ret = fsl_qspi_nor_setup_last(q);
if (ret)
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -40,6 +40,13 @@
#define SPI_NOR_MAX_ID_LEN 6
#define SPI_NOR_MAX_ADDR_WIDTH 4
+#define SPI_NOR_MICRON_WRITE_ENABLE 0x7f
+/* Added for S25FS-S family flash */
+#define SPINOR_CONFIG_REG3_OFFSET 0x800004
+#define CR3V_4KB_ERASE_UNABLE 0x8
+#define SPINOR_S25FS_FAMILY_ID 0x81
+
+
struct flash_info {
char *name;
@@ -68,7 +75,8 @@ struct flash_info {
#define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works uniformly */
#define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */
#define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */
-#define USE_FSR BIT(7) /* use flag status register */
+#define USE_FSR BIT(13) /* use flag status register */
+#define SPI_NOR_DDR_QUAD_READ BIT(7) /* Flash supports DDR Quad Read */
#define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR */
#define SPI_NOR_HAS_TB BIT(9) /*
* Flash SR has Top/Bottom (TB) protect
@@ -85,9 +93,11 @@ struct flash_info {
* Use dedicated 4byte address op codes
* to support memory size above 128Mib.
*/
+#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */
};
#define JEDEC_MFR(info) ((info)->id[0])
+#define EXT_ID(info) ((info)->id[5])
static const struct flash_info *spi_nor_match_id(const char *name);
@@ -132,7 +142,7 @@ static int read_fsr(struct spi_nor *nor)
/*
* Read configuration register, returning its value in the
* location. Return the configuration register value.
- * Returns negative if error occured.
+ * Returns negative if error occurred.
*/
static int read_cr(struct spi_nor *nor)
{
@@ -160,6 +170,8 @@ static inline int spi_nor_read_dummy_cyc
case SPI_NOR_DUAL:
case SPI_NOR_QUAD:
return 8;
+ case SPI_NOR_DDR_QUAD:
+ return 6;
case SPI_NOR_NORMAL:
return 0;
}
@@ -962,6 +974,8 @@ static const struct flash_info spi_nor_i
/* ESMT */
{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
+ { "f25l32qa", INFO(0x8c4116, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
+ { "f25l64qa", INFO(0x8c4117, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_LOCK) },
/* Everspin */
{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
@@ -1021,12 +1035,15 @@ static const struct flash_info spi_nor_i
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) },
{ "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
+ { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) },
+ { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) },
+ { "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16, SECT_4K) },
{ "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64, 0) },
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
- { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
+ { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) },
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
@@ -1040,10 +1057,11 @@ static const struct flash_info spi_nor_i
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
+ { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
- { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
+ { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
/* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
@@ -1061,8 +1079,11 @@ static const struct flash_info spi_nor_i
{ "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
- { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
+ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ
+ | SPI_NOR_DDR_QUAD_READ) },
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)},
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
{ "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) },
@@ -1136,7 +1157,15 @@ static const struct flash_info spi_nor_i
{ "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) },
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
+ {
+ "w25q16dw", INFO(0xef6015, 0, 64 * 1024, 32,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
+ { "w25q20cl", INFO(0xef4012, 0, 64 * 1024, 4, SECT_4K) },
+ { "w25q20bw", INFO(0xef5012, 0, 64 * 1024, 4, SECT_4K) },
+ { "w25q20ew", INFO(0xef6012, 0, 64 * 1024, 4, SECT_4K) },
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
{
"w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64,
@@ -1208,6 +1237,53 @@ static const struct flash_info *spi_nor_
id[0], id[1], id[2]);
return ERR_PTR(-ENODEV);
}
+/*
+ * The S25FS-S family physical sectors may be configured as a
+ * hybrid combination of eight 4-kB parameter sectors
+ * at the top or bottom of the address space with all
+ * but one of the remaining sectors being uniform size.
+ * The Parameter Sector Erase commands (20h or 21h) must
+ * be used to erase the 4-kB parameter sectors individually.
+ * The Sector (uniform sector) Erase commands (D8h or DCh)
+ * must be used to erase any of the remaining
+ * sectors, including the portion of highest or lowest address
+ * sector that is not overlaid by the parameter sectors.
+ * The uniform sector erase command has no effect on parameter sectors.
+ */
+static int spansion_s25fs_disable_4kb_erase(struct spi_nor *nor)
+{
+ struct fsl_qspi *q;
+ u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
+ u8 cr3v = 0x0;
+ int ret = 0x0;
+
+ q = nor->priv;
+
+ nor->cmd_buf[2] = cr3v_addr >> 16;
+ nor->cmd_buf[1] = cr3v_addr >> 8;
+ nor->cmd_buf[0] = cr3v_addr >> 0;
+
+ ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
+ if (ret)
+ return ret;
+ if (cr3v & CR3V_4KB_ERASE_UNABLE)
+ return 0;
+ ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
+ if (ret)
+ return ret;
+ cr3v = CR3V_4KB_ERASE_UNABLE;
+ nor->program_opcode = SPINOR_OP_SPANSION_WRAR;
+ nor->write(nor, cr3v_addr, 1, &cr3v);
+
+ ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
+ if (ret)
+ return ret;
+ if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
+ return -EPERM;
+
+ return 0;
+}
+
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
@@ -1427,7 +1503,7 @@ static int macronix_quad_enable(struct s
* Write status Register and configuration register with 2 bytes
* The first byte will be written to the status register, while the
* second byte will be written to the configuration register.
- * Return negative if error occured.
+ * Return negative if error occurred.
*/
static int write_sr_cr(struct spi_nor *nor, u16 val)
{
@@ -1475,6 +1551,24 @@ static int spansion_quad_enable(struct s
return 0;
}
+static int set_ddr_quad_mode(struct spi_nor *nor, const struct flash_info *info)
+{
+ int status;
+
+ switch (JEDEC_MFR(info)) {
+ case SNOR_MFR_SPANSION:
+ status = spansion_quad_enable(nor);
+ if (status) {
+ dev_err(nor->dev, "Spansion DDR quad-read not enabled\n");
+ return status;
+ }
+ return status;
+ default:
+ return -EINVAL;
+ }
+}
+
+
static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
{
int status;
@@ -1621,9 +1715,25 @@ int spi_nor_scan(struct spi_nor *nor, co
write_sr(nor, 0);
spi_nor_wait_till_ready(nor);
}
+ if (JEDEC_MFR(info) == SNOR_MFR_MICRON) {
+ ret = read_sr(nor);
+ ret &= SPI_NOR_MICRON_WRITE_ENABLE;
+
+ write_enable(nor);
+ write_sr(nor, ret);
+ }
+
+ if (EXT_ID(info) == SPINOR_S25FS_FAMILY_ID) {
+ ret = spansion_s25fs_disable_4kb_erase(nor);
+ if (ret)
+ return ret;
+ }
+
if (!mtd->name)
mtd->name = dev_name(dev);
+ if (info->name)
+ nor->vendor = info->name;
mtd->priv = nor;
mtd->type = MTD_NORFLASH;
mtd->writesize = 1;
@@ -1657,6 +1767,8 @@ int spi_nor_scan(struct spi_nor *nor, co
nor->flags |= SNOR_F_USE_FSR;
if (info->flags & SPI_NOR_HAS_TB)
nor->flags |= SNOR_F_HAS_SR_TB;
+ if (info->flags & NO_CHIP_ERASE)
+ nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
/* prefer "small sector" erase if possible */
@@ -1696,9 +1808,15 @@ int spi_nor_scan(struct spi_nor *nor, co
/* Some devices cannot do fast-read, no matter what DT tells us */
if (info->flags & SPI_NOR_NO_FR)
nor->flash_read = SPI_NOR_NORMAL;
-
- /* Quad/Dual-read mode takes precedence over fast/normal */
- if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
+ /* DDR Quad/Quad/Dual-read mode takes precedence over fast/normal */
+ if (mode == SPI_NOR_DDR_QUAD && info->flags & SPI_NOR_DDR_QUAD_READ) {
+ ret = set_ddr_quad_mode(nor, info);
+ if (ret) {
+ dev_err(dev, "DDR quad mode not supported\n");
+ return ret;
+ }
+ nor->flash_read = SPI_NOR_DDR_QUAD;
+ } else if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
ret = set_quad_mode(nor, info);
if (ret) {
dev_err(dev, "quad mode not supported\n");
@@ -1711,6 +1829,9 @@ int spi_nor_scan(struct spi_nor *nor, co
/* Default commands */
switch (nor->flash_read) {
+ case SPI_NOR_DDR_QUAD:
+ nor->read_opcode = SPINOR_OP_READ4_1_4_4_D;
+ break;
case SPI_NOR_QUAD:
nor->read_opcode = SPINOR_OP_READ_1_1_4;
break;
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -31,10 +31,10 @@
/*
* Note on opcode nomenclature: some opcodes have a format like
- * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
+ * SPINOR_OP_FUNCTION{4,}_x_y_z{_D}. The numbers x, y,and z stand for the number
* of I/O lines used for the opcode, address, and data (respectively). The
* FUNCTION has an optional suffix of '4', to represent an opcode which
- * requires a 4-byte (32-bit) address.
+ * requires a 4-byte (32-bit) address. The suffix of 'D' stands for the
*/
/* Flash opcodes. */
@@ -46,7 +46,9 @@
#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */
#define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */
#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */
+#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */
#define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */
+#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */
#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
#define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */
#define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */
@@ -62,9 +64,11 @@
/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
#define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */
#define SPINOR_OP_READ_FAST_4B 0x0c /* Read data bytes (high frequency) */
+#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
#define SPINOR_OP_READ_1_1_2_4B 0x3c /* Read data bytes (Dual Output SPI) */
#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */
#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */
+#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */
#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */
@@ -94,6 +98,10 @@
/* Used for Spansion flashes only. */
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
+/* Used for Spansion S25FS-S family flash only. */
+#define SPINOR_OP_SPANSION_RDAR 0x65 /* Read any device register */
+#define SPINOR_OP_SPANSION_WRAR 0x71 /* Write any device register */
+
/* Used for Micron flashes only. */
#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
@@ -124,6 +132,7 @@ enum read_mode {
SPI_NOR_FAST,
SPI_NOR_DUAL,
SPI_NOR_QUAD,
+ SPI_NOR_DDR_QUAD,
};
#define SPI_NOR_MAX_CMD_SIZE 8
@@ -189,6 +198,7 @@ struct spi_nor {
bool sst_write_second;
u32 flags;
u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
+ char *vendor;
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);

View File

@ -1,392 +0,0 @@
From d9d0181f74146507026c31cccd52dda27ec3d966 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 14:57:31 +0800
Subject: [PATCH 06/30] mtd: support layerscape
This is an integrated patch for layerscape ifc-nor-nand support.
Signed-off-by: Alison Wang <b18965@freescale.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/memory/Kconfig | 2 +-
drivers/memory/fsl_ifc.c | 263 ++++++++++++++++++++++++++++++++++++++++
drivers/mtd/maps/physmap_of.c | 4 +
drivers/mtd/nand/Kconfig | 2 +-
drivers/mtd/nand/fsl_ifc_nand.c | 5 +-
include/linux/fsl_ifc.h | 7 ++
6 files changed, 280 insertions(+), 3 deletions(-)
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -115,7 +115,7 @@ config FSL_CORENET_CF
config FSL_IFC
bool
- depends on FSL_SOC || ARCH_LAYERSCAPE
+ depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
config JZ4780_NEMC
bool "Ingenic JZ4780 SoC NEMC driver"
--- a/drivers/memory/fsl_ifc.c
+++ b/drivers/memory/fsl_ifc.c
@@ -24,6 +24,7 @@
#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/delay.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/io.h>
@@ -37,6 +38,8 @@
struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev;
EXPORT_SYMBOL(fsl_ifc_ctrl_dev);
+#define FSL_IFC_V1_3_0 0x01030000
+#define IFC_TIMEOUT_MSECS 1000 /* 1000ms */
/*
* convert_ifc_address - convert the base address
@@ -311,6 +314,261 @@ err:
return ret;
}
+#ifdef CONFIG_PM_SLEEP
+/* save ifc registers */
+static int fsl_ifc_suspend(struct device *dev)
+{
+ struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev);
+ struct fsl_ifc_global __iomem *fcm = ctrl->gregs;
+ struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs;
+ __be32 nand_evter_intr_en, cm_evter_intr_en, nor_evter_intr_en,
+ gpcm_evter_intr_en;
+ uint32_t ifc_bank, i;
+
+ ctrl->saved_gregs = kzalloc(sizeof(struct fsl_ifc_global), GFP_KERNEL);
+ if (!ctrl->saved_gregs)
+ return -ENOMEM;
+ ctrl->saved_rregs = kzalloc(sizeof(struct fsl_ifc_runtime), GFP_KERNEL);
+ if (!ctrl->saved_rregs)
+ return -ENOMEM;
+
+ cm_evter_intr_en = ifc_in32(&fcm->cm_evter_intr_en);
+ nand_evter_intr_en = ifc_in32(&runtime->ifc_nand.nand_evter_intr_en);
+ nor_evter_intr_en = ifc_in32(&runtime->ifc_nor.nor_evter_intr_en);
+ gpcm_evter_intr_en = ifc_in32(&runtime->ifc_gpcm.gpcm_evter_intr_en);
+
+/* IFC interrupts disabled */
+
+ ifc_out32(0x0, &fcm->cm_evter_intr_en);
+ ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en);
+ ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en);
+ ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en);
+
+ if (ctrl->saved_gregs) {
+ for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) {
+ ctrl->saved_gregs->cspr_cs[ifc_bank].cspr_ext =
+ ifc_in32(&fcm->cspr_cs[ifc_bank].cspr_ext);
+ ctrl->saved_gregs->cspr_cs[ifc_bank].cspr =
+ ifc_in32(&fcm->cspr_cs[ifc_bank].cspr);
+ ctrl->saved_gregs->amask_cs[ifc_bank].amask =
+ ifc_in32(&fcm->amask_cs[ifc_bank].amask);
+ ctrl->saved_gregs->csor_cs[ifc_bank].csor_ext =
+ ifc_in32(&fcm->csor_cs[ifc_bank].csor_ext);
+ ctrl->saved_gregs->csor_cs[ifc_bank].csor =
+ ifc_in32(&fcm->csor_cs[ifc_bank].csor);
+ for (i = 0; i < 4; i++) {
+ ctrl->saved_gregs->ftim_cs[ifc_bank].ftim[i] =
+ ifc_in32(
+ &fcm->ftim_cs[ifc_bank].ftim[i]);
+ }
+ }
+
+ ctrl->saved_gregs->rb_map = ifc_in32(&fcm->rb_map);
+ ctrl->saved_gregs->wb_map = ifc_in32(&fcm->wb_map);
+ ctrl->saved_gregs->ifc_gcr = ifc_in32(&fcm->ifc_gcr);
+ ctrl->saved_gregs->ddr_ccr_low = ifc_in32(&fcm->ddr_ccr_low);
+ ctrl->saved_gregs->cm_evter_en = ifc_in32(&fcm->cm_evter_en);
+ }
+
+ if (ctrl->saved_rregs) {
+ /* IFC controller NAND machine registers */
+ ctrl->saved_rregs->ifc_nand.ncfgr =
+ ifc_in32(&runtime->ifc_nand.ncfgr);
+ ctrl->saved_rregs->ifc_nand.nand_fcr0 =
+ ifc_in32(&runtime->ifc_nand.nand_fcr0);
+ ctrl->saved_rregs->ifc_nand.nand_fcr1 =
+ ifc_in32(&runtime->ifc_nand.nand_fcr1);
+ ctrl->saved_rregs->ifc_nand.row0 =
+ ifc_in32(&runtime->ifc_nand.row0);
+ ctrl->saved_rregs->ifc_nand.row1 =
+ ifc_in32(&runtime->ifc_nand.row1);
+ ctrl->saved_rregs->ifc_nand.col0 =
+ ifc_in32(&runtime->ifc_nand.col0);
+ ctrl->saved_rregs->ifc_nand.col1 =
+ ifc_in32(&runtime->ifc_nand.col1);
+ ctrl->saved_rregs->ifc_nand.row2 =
+ ifc_in32(&runtime->ifc_nand.row2);
+ ctrl->saved_rregs->ifc_nand.col2 =
+ ifc_in32(&runtime->ifc_nand.col2);
+ ctrl->saved_rregs->ifc_nand.row3 =
+ ifc_in32(&runtime->ifc_nand.row3);
+ ctrl->saved_rregs->ifc_nand.col3 =
+ ifc_in32(&runtime->ifc_nand.col3);
+
+ ctrl->saved_rregs->ifc_nand.nand_fbcr =
+ ifc_in32(&runtime->ifc_nand.nand_fbcr);
+ ctrl->saved_rregs->ifc_nand.nand_fir0 =
+ ifc_in32(&runtime->ifc_nand.nand_fir0);
+ ctrl->saved_rregs->ifc_nand.nand_fir1 =
+ ifc_in32(&runtime->ifc_nand.nand_fir1);
+ ctrl->saved_rregs->ifc_nand.nand_fir2 =
+ ifc_in32(&runtime->ifc_nand.nand_fir2);
+ ctrl->saved_rregs->ifc_nand.nand_csel =
+ ifc_in32(&runtime->ifc_nand.nand_csel);
+ ctrl->saved_rregs->ifc_nand.nandseq_strt =
+ ifc_in32(
+ &runtime->ifc_nand.nandseq_strt);
+ ctrl->saved_rregs->ifc_nand.nand_evter_en =
+ ifc_in32(
+ &runtime->ifc_nand.nand_evter_en);
+ ctrl->saved_rregs->ifc_nand.nanndcr =
+ ifc_in32(&runtime->ifc_nand.nanndcr);
+ ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg0 =
+ ifc_in32(
+ &runtime->ifc_nand.nand_dll_lowcfg0);
+ ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg1 =
+ ifc_in32(
+ &runtime->ifc_nand.nand_dll_lowcfg1);
+
+ /* IFC controller NOR machine registers */
+ ctrl->saved_rregs->ifc_nor.nor_evter_en =
+ ifc_in32(
+ &runtime->ifc_nor.nor_evter_en);
+ ctrl->saved_rregs->ifc_nor.norcr =
+ ifc_in32(&runtime->ifc_nor.norcr);
+
+ /* IFC controller GPCM Machine registers */
+ ctrl->saved_rregs->ifc_gpcm.gpcm_evter_en =
+ ifc_in32(
+ &runtime->ifc_gpcm.gpcm_evter_en);
+ }
+
+/* save the interrupt values */
+ ctrl->saved_gregs->cm_evter_intr_en = cm_evter_intr_en;
+ ctrl->saved_rregs->ifc_nand.nand_evter_intr_en = nand_evter_intr_en;
+ ctrl->saved_rregs->ifc_nor.nor_evter_intr_en = nor_evter_intr_en;
+ ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en = gpcm_evter_intr_en;
+
+ return 0;
+}
+
+/* restore ifc registers */
+static int fsl_ifc_resume(struct device *dev)
+{
+ struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev);
+ struct fsl_ifc_global __iomem *fcm = ctrl->gregs;
+ struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs;
+ struct fsl_ifc_global *savd_gregs = ctrl->saved_gregs;
+ struct fsl_ifc_runtime *savd_rregs = ctrl->saved_rregs;
+ uint32_t ver = 0, ncfgr, timeout, ifc_bank, i;
+
+/*
+ * IFC interrupts disabled
+ */
+ ifc_out32(0x0, &fcm->cm_evter_intr_en);
+ ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en);
+ ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en);
+ ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en);
+
+
+ if (ctrl->saved_gregs) {
+ for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) {
+ ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr_ext,
+ &fcm->cspr_cs[ifc_bank].cspr_ext);
+ ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr,
+ &fcm->cspr_cs[ifc_bank].cspr);
+ ifc_out32(savd_gregs->amask_cs[ifc_bank].amask,
+ &fcm->amask_cs[ifc_bank].amask);
+ ifc_out32(savd_gregs->csor_cs[ifc_bank].csor_ext,
+ &fcm->csor_cs[ifc_bank].csor_ext);
+ ifc_out32(savd_gregs->csor_cs[ifc_bank].csor,
+ &fcm->csor_cs[ifc_bank].csor);
+ for (i = 0; i < 4; i++) {
+ ifc_out32(savd_gregs->ftim_cs[ifc_bank].ftim[i],
+ &fcm->ftim_cs[ifc_bank].ftim[i]);
+ }
+ }
+ ifc_out32(savd_gregs->rb_map, &fcm->rb_map);
+ ifc_out32(savd_gregs->wb_map, &fcm->wb_map);
+ ifc_out32(savd_gregs->ifc_gcr, &fcm->ifc_gcr);
+ ifc_out32(savd_gregs->ddr_ccr_low, &fcm->ddr_ccr_low);
+ ifc_out32(savd_gregs->cm_evter_en, &fcm->cm_evter_en);
+ }
+
+ if (ctrl->saved_rregs) {
+ /* IFC controller NAND machine registers */
+ ifc_out32(savd_rregs->ifc_nand.ncfgr,
+ &runtime->ifc_nand.ncfgr);
+ ifc_out32(savd_rregs->ifc_nand.nand_fcr0,
+ &runtime->ifc_nand.nand_fcr0);
+ ifc_out32(savd_rregs->ifc_nand.nand_fcr1,
+ &runtime->ifc_nand.nand_fcr1);
+ ifc_out32(savd_rregs->ifc_nand.row0, &runtime->ifc_nand.row0);
+ ifc_out32(savd_rregs->ifc_nand.row1, &runtime->ifc_nand.row1);
+ ifc_out32(savd_rregs->ifc_nand.col0, &runtime->ifc_nand.col0);
+ ifc_out32(savd_rregs->ifc_nand.col1, &runtime->ifc_nand.col1);
+ ifc_out32(savd_rregs->ifc_nand.row2, &runtime->ifc_nand.row2);
+ ifc_out32(savd_rregs->ifc_nand.col2, &runtime->ifc_nand.col2);
+ ifc_out32(savd_rregs->ifc_nand.row3, &runtime->ifc_nand.row3);
+ ifc_out32(savd_rregs->ifc_nand.col3, &runtime->ifc_nand.col3);
+ ifc_out32(savd_rregs->ifc_nand.nand_fbcr,
+ &runtime->ifc_nand.nand_fbcr);
+ ifc_out32(savd_rregs->ifc_nand.nand_fir0,
+ &runtime->ifc_nand.nand_fir0);
+ ifc_out32(savd_rregs->ifc_nand.nand_fir1,
+ &runtime->ifc_nand.nand_fir1);
+ ifc_out32(savd_rregs->ifc_nand.nand_fir2,
+ &runtime->ifc_nand.nand_fir2);
+ ifc_out32(savd_rregs->ifc_nand.nand_csel,
+ &runtime->ifc_nand.nand_csel);
+ ifc_out32(savd_rregs->ifc_nand.nandseq_strt,
+ &runtime->ifc_nand.nandseq_strt);
+ ifc_out32(savd_rregs->ifc_nand.nand_evter_en,
+ &runtime->ifc_nand.nand_evter_en);
+ ifc_out32(savd_rregs->ifc_nand.nanndcr,
+ &runtime->ifc_nand.nanndcr);
+ ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg0,
+ &runtime->ifc_nand.nand_dll_lowcfg0);
+ ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg1,
+ &runtime->ifc_nand.nand_dll_lowcfg1);
+
+ /* IFC controller NOR machine registers */
+ ifc_out32(savd_rregs->ifc_nor.nor_evter_en,
+ &runtime->ifc_nor.nor_evter_en);
+ ifc_out32(savd_rregs->ifc_nor.norcr, &runtime->ifc_nor.norcr);
+
+ /* IFC controller GPCM Machine registers */
+ ifc_out32(savd_rregs->ifc_gpcm.gpcm_evter_en,
+ &runtime->ifc_gpcm.gpcm_evter_en);
+
+ /* IFC interrupts enabled */
+ ifc_out32(ctrl->saved_gregs->cm_evter_intr_en,
+ &fcm->cm_evter_intr_en);
+ ifc_out32(ctrl->saved_rregs->ifc_nand.nand_evter_intr_en,
+ &runtime->ifc_nand.nand_evter_intr_en);
+ ifc_out32(ctrl->saved_rregs->ifc_nor.nor_evter_intr_en,
+ &runtime->ifc_nor.nor_evter_intr_en);
+ ifc_out32(ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en,
+ &runtime->ifc_gpcm.gpcm_evter_intr_en);
+
+ kfree(ctrl->saved_gregs);
+ kfree(ctrl->saved_rregs);
+ ctrl->saved_gregs = NULL;
+ ctrl->saved_rregs = NULL;
+ }
+
+ ver = ifc_in32(&fcm->ifc_rev);
+ ncfgr = ifc_in32(&runtime->ifc_nand.ncfgr);
+ if (ver >= FSL_IFC_V1_3_0) {
+
+ ifc_out32(ncfgr | IFC_NAND_SRAM_INIT_EN,
+ &runtime->ifc_nand.ncfgr);
+ /* wait for SRAM_INIT bit to be clear or timeout */
+ timeout = 10;
+ while ((ifc_in32(&runtime->ifc_nand.ncfgr) &
+ IFC_NAND_SRAM_INIT_EN) && timeout) {
+ mdelay(IFC_TIMEOUT_MSECS);
+ timeout--;
+ }
+
+ if (!timeout)
+ dev_err(ctrl->dev, "Timeout waiting for IFC SRAM INIT");
+ }
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
static const struct of_device_id fsl_ifc_match[] = {
{
.compatible = "fsl,ifc",
@@ -318,10 +576,15 @@ static const struct of_device_id fsl_ifc
{},
};
+static const struct dev_pm_ops ifc_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_ifc_suspend, fsl_ifc_resume)
+};
+
static struct platform_driver fsl_ifc_ctrl_driver = {
.driver = {
.name = "fsl-ifc",
.of_match_table = fsl_ifc_match,
+ .pm = &ifc_pm_ops,
},
.probe = fsl_ifc_ctrl_probe,
.remove = fsl_ifc_ctrl_remove,
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -20,6 +20,7 @@
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
+#include <linux/mtd/cfi_endian.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
@@ -209,6 +210,9 @@ static int of_flash_probe(struct platfor
return err;
}
+ if (of_property_read_bool(dp->parent, "big-endian"))
+ info->list[i].map.swap = CFI_BIG_ENDIAN;
+
err = -ENOMEM;
info->list[i].map.virt = ioremap(info->list[i].map.phys,
info->list[i].map.size);
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -438,7 +438,7 @@ config MTD_NAND_FSL_ELBC
config MTD_NAND_FSL_IFC
tristate "NAND support for Freescale IFC controller"
- depends on FSL_SOC || ARCH_LAYERSCAPE
+ depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
select FSL_IFC
select MEMORY
help
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -901,7 +901,7 @@ static int fsl_ifc_chip_init(struct fsl_
chip->ecc.algo = NAND_ECC_HAMMING;
}
- if (ctrl->version == FSL_IFC_VERSION_1_1_0)
+ if (ctrl->version >= FSL_IFC_VERSION_1_1_0)
fsl_ifc_sram_init(priv);
/*
--- a/include/linux/fsl_ifc.h
+++ b/include/linux/fsl_ifc.h
@@ -274,6 +274,8 @@
*/
/* Auto Boot Mode */
#define IFC_NAND_NCFGR_BOOT 0x80000000
+/* SRAM INIT EN */
+#define IFC_NAND_SRAM_INIT_EN 0x20000000
/* Addressing Mode-ROW0+n/COL0 */
#define IFC_NAND_NCFGR_ADDR_MODE_RC0 0x00000000
/* Addressing Mode-ROW0+n/COL0+n */
@@ -857,6 +859,11 @@ struct fsl_ifc_ctrl {
u32 nand_stat;
wait_queue_head_t nand_wait;
bool little_endian;
+#ifdef CONFIG_PM_SLEEP
+ /*save regs when system goes to deep sleep*/
+ struct fsl_ifc_global *saved_gregs;
+ struct fsl_ifc_runtime *saved_rregs;
+#endif
};
extern struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev;

View File

@ -1,144 +0,0 @@
From 4c3979602db05bca439bfc98db88dc14a8663db0 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:14:57 +0800
Subject: [PATCH 13/30] ata: support layerscape
This is an integrated patch for layerscape sata support.
Signed-off-by: Tang Yuantian <Yuantian.Tang@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/ata/ahci_qoriq.c | 63 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 56 insertions(+), 7 deletions(-)
--- a/drivers/ata/ahci_qoriq.c
+++ b/drivers/ata/ahci_qoriq.c
@@ -1,7 +1,7 @@
/*
* Freescale QorIQ AHCI SATA platform driver
*
- * Copyright 2015 Freescale, Inc.
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
* Tang Yuantian <Yuantian.Tang@freescale.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -46,23 +46,32 @@
#define LS1021A_AXICC_ADDR 0xC0
#define SATA_ECC_DISABLE 0x00020000
+#define ECC_DIS_ARMV8_CH2 0x80000000
+#define ECC_DIS_LS1088A 0x40000000
enum ahci_qoriq_type {
AHCI_LS1021A,
AHCI_LS1043A,
AHCI_LS2080A,
+ AHCI_LS1046A,
+ AHCI_LS1088A,
+ AHCI_LS2088A,
};
struct ahci_qoriq_priv {
struct ccsr_ahci *reg_base;
enum ahci_qoriq_type type;
void __iomem *ecc_addr;
+ bool is_dmacoherent;
};
static const struct of_device_id ahci_qoriq_of_match[] = {
{ .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
{ .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
{ .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
+ { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
+ { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
+ { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
{},
};
MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
@@ -154,6 +163,8 @@ static int ahci_qoriq_phy_init(struct ah
switch (qpriv->type) {
case AHCI_LS1021A:
+ if (!qpriv->ecc_addr)
+ return -EINVAL;
writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
@@ -161,19 +172,56 @@ static int ahci_qoriq_phy_init(struct ah
writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
- writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG,
+ reg_base + LS1021A_AXICC_ADDR);
break;
case AHCI_LS1043A:
+ if (!qpriv->ecc_addr)
+ return -EINVAL;
+ writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
+ qpriv->ecc_addr);
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
- writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
case AHCI_LS2080A:
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
- writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ break;
+
+ case AHCI_LS1046A:
+ if (!qpriv->ecc_addr)
+ return -EINVAL;
+ writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
+ qpriv->ecc_addr);
+ writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
+ writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ break;
+
+ case AHCI_LS1088A:
+ if (!qpriv->ecc_addr)
+ return -EINVAL;
+ writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A,
+ qpriv->ecc_addr);
+ writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
+ writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ break;
+
+ case AHCI_LS2088A:
+ writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
+ writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
}
@@ -204,13 +252,14 @@ static int ahci_qoriq_probe(struct platf
qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
- if (qoriq_priv->type == AHCI_LS1021A) {
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "sata-ecc");
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "sata-ecc");
+ if (res) {
qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res);
if (IS_ERR(qoriq_priv->ecc_addr))
return PTR_ERR(qoriq_priv->ecc_addr);
}
+ qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
rc = ahci_platform_enable_resources(hpriv);
if (rc)

View File

@ -1,323 +0,0 @@
From 82a391a067491f4c46b75d0dfe2bf9e5a11aca8e Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:15:44 +0800
Subject: [PATCH 14/30] clk: support layerscape
This is an integrated patch for layerscape clock support.
Signed-off-by: Yuantian Tang <andy.tang@nxp.com>
Signed-off-by: Mingkai Hu <mingkai.hu@nxp.com>
Signed-off-by: Scott Wood <oss@buserror.net>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/clk/clk-qoriq.c | 179 ++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 164 insertions(+), 15 deletions(-)
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
#include <linux/fsl/guts.h>
#include <linux/io.h>
#include <linux/kernel.h>
@@ -40,7 +41,7 @@ struct clockgen_pll_div {
};
struct clockgen_pll {
- struct clockgen_pll_div div[4];
+ struct clockgen_pll_div div[8];
};
#define CLKSEL_VALID 1
@@ -87,7 +88,7 @@ struct clockgen {
struct device_node *node;
void __iomem *regs;
struct clockgen_chipinfo info; /* mutable copy */
- struct clk *sysclk;
+ struct clk *sysclk, *coreclk;
struct clockgen_pll pll[6];
struct clk *cmux[NUM_CMUX];
struct clk *hwaccel[NUM_HWACCEL];
@@ -266,6 +267,39 @@ static const struct clockgen_muxinfo ls1
},
};
+static const struct clockgen_muxinfo ls1046a_hwa1 = {
+ {
+ {},
+ {},
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+ { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+ },
+};
+
+static const struct clockgen_muxinfo ls1046a_hwa2 = {
+ {
+ {},
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+ {},
+ {},
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+ },
+};
+
+static const struct clockgen_muxinfo ls1012a_cmux = {
+ {
+ [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+ {},
+ [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+ }
+};
+
static const struct clockgen_muxinfo t1023_hwa1 = {
{
{},
@@ -489,6 +523,42 @@ static const struct clockgen_chipinfo ch
.flags = CG_PLL_8BIT,
},
{
+ .compat = "fsl,ls1046a-clockgen",
+ .init_periph = t2080_init_periph,
+ .cmux_groups = {
+ &t1040_cmux
+ },
+ .hwaccel = {
+ &ls1046a_hwa1, &ls1046a_hwa2
+ },
+ .cmux_to_group = {
+ 0, -1
+ },
+ .pll_mask = 0x07,
+ .flags = CG_PLL_8BIT,
+ },
+ {
+ .compat = "fsl,ls1088a-clockgen",
+ .cmux_groups = {
+ &clockgen2_cmux_cga12
+ },
+ .cmux_to_group = {
+ 0, 0, -1
+ },
+ .pll_mask = 0x07,
+ .flags = CG_VER3 | CG_LITTLE_ENDIAN,
+ },
+ {
+ .compat = "fsl,ls1012a-clockgen",
+ .cmux_groups = {
+ &ls1012a_cmux
+ },
+ .cmux_to_group = {
+ 0, -1
+ },
+ .pll_mask = 0x03,
+ },
+ {
.compat = "fsl,ls2080a-clockgen",
.cmux_groups = {
&clockgen2_cmux_cga12, &clockgen2_cmux_cgb
@@ -846,7 +916,12 @@ static void __init create_muxes(struct c
static void __init clockgen_init(struct device_node *np);
-/* Legacy nodes may get probed before the parent clockgen node */
+/*
+ * Legacy nodes may get probed before the parent clockgen node.
+ * It is assumed that device trees with legacy nodes will not
+ * contain a "clocks" property -- otherwise the input clocks may
+ * not be initialized at this point.
+ */
static void __init legacy_init_clockgen(struct device_node *np)
{
if (!clockgen.node)
@@ -887,18 +962,13 @@ static struct clk __init
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
}
-static struct clk *sysclk_from_parent(const char *name)
+static struct clk __init *input_clock(const char *name, struct clk *clk)
{
- struct clk *clk;
- const char *parent_name;
-
- clk = of_clk_get(clockgen.node, 0);
- if (IS_ERR(clk))
- return clk;
+ const char *input_name;
/* Register the input clock under the desired name. */
- parent_name = __clk_get_name(clk);
- clk = clk_register_fixed_factor(NULL, name, parent_name,
+ input_name = __clk_get_name(clk);
+ clk = clk_register_fixed_factor(NULL, name, input_name,
0, 1, 1);
if (IS_ERR(clk))
pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
@@ -907,6 +977,29 @@ static struct clk *sysclk_from_parent(co
return clk;
}
+static struct clk __init *input_clock_by_name(const char *name,
+ const char *dtname)
+{
+ struct clk *clk;
+
+ clk = of_clk_get_by_name(clockgen.node, dtname);
+ if (IS_ERR(clk))
+ return clk;
+
+ return input_clock(name, clk);
+}
+
+static struct clk __init *input_clock_by_index(const char *name, int idx)
+{
+ struct clk *clk;
+
+ clk = of_clk_get(clockgen.node, 0);
+ if (IS_ERR(clk))
+ return clk;
+
+ return input_clock(name, clk);
+}
+
static struct clk * __init create_sysclk(const char *name)
{
struct device_node *sysclk;
@@ -916,7 +1009,11 @@ static struct clk * __init create_sysclk
if (!IS_ERR(clk))
return clk;
- clk = sysclk_from_parent(name);
+ clk = input_clock_by_name(name, "sysclk");
+ if (!IS_ERR(clk))
+ return clk;
+
+ clk = input_clock_by_index(name, 0);
if (!IS_ERR(clk))
return clk;
@@ -927,7 +1024,27 @@ static struct clk * __init create_sysclk
return clk;
}
- pr_err("%s: No input clock\n", __func__);
+ pr_err("%s: No input sysclk\n", __func__);
+ return NULL;
+}
+
+static struct clk * __init create_coreclk(const char *name)
+{
+ struct clk *clk;
+
+ clk = input_clock_by_name(name, "coreclk");
+ if (!IS_ERR(clk))
+ return clk;
+
+ /*
+ * This indicates a mix of legacy nodes with the new coreclk
+ * mechanism, which should never happen. If this error occurs,
+ * don't use the wrong input clock just because coreclk isn't
+ * ready yet.
+ */
+ if (WARN_ON(PTR_ERR(clk) == -EPROBE_DEFER))
+ return clk;
+
return NULL;
}
@@ -950,11 +1067,19 @@ static void __init create_one_pll(struct
u32 __iomem *reg;
u32 mult;
struct clockgen_pll *pll = &cg->pll[idx];
+ const char *input = "cg-sysclk";
int i;
if (!(cg->info.pll_mask & (1 << idx)))
return;
+ if (cg->coreclk && idx != PLATFORM_PLL) {
+ if (IS_ERR(cg->coreclk))
+ return;
+
+ input = "cg-coreclk";
+ }
+
if (cg->info.flags & CG_VER3) {
switch (idx) {
case PLATFORM_PLL:
@@ -1000,12 +1125,20 @@ static void __init create_one_pll(struct
for (i = 0; i < ARRAY_SIZE(pll->div); i++) {
struct clk *clk;
+ int ret;
+
+ /*
+ * For platform PLL, there are 8 divider clocks.
+ * For core PLL, there are 4 divider clocks at most.
+ */
+ if (idx != 0 && i >= 4)
+ break;
snprintf(pll->div[i].name, sizeof(pll->div[i].name),
"cg-pll%d-div%d", idx, i + 1);
clk = clk_register_fixed_factor(NULL,
- pll->div[i].name, "cg-sysclk", 0, mult, i + 1);
+ pll->div[i].name, input, 0, mult, i + 1);
if (IS_ERR(clk)) {
pr_err("%s: %s: register failed %ld\n",
__func__, pll->div[i].name, PTR_ERR(clk));
@@ -1013,6 +1146,11 @@ static void __init create_one_pll(struct
}
pll->div[i].clk = clk;
+ ret = clk_register_clkdev(clk, pll->div[i].name, NULL);
+ if (ret != 0)
+ pr_err("%s: %s: register to lookup table failed %ld\n",
+ __func__, pll->div[i].name, PTR_ERR(clk));
+
}
}
@@ -1142,6 +1280,13 @@ static struct clk *clockgen_clk_get(stru
goto bad_args;
clk = pll->div[idx].clk;
break;
+ case 5:
+ if (idx != 0)
+ goto bad_args;
+ clk = cg->coreclk;
+ if (IS_ERR(clk))
+ clk = NULL;
+ break;
default:
goto bad_args;
}
@@ -1253,6 +1398,7 @@ static void __init clockgen_init(struct
clockgen.info.flags |= CG_CMUX_GE_PLAT;
clockgen.sysclk = create_sysclk("cg-sysclk");
+ clockgen.coreclk = create_coreclk("cg-coreclk");
create_plls(&clockgen);
create_muxes(&clockgen);
@@ -1273,8 +1419,11 @@ err:
CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init);
CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
/* Legacy nodes */

View File

@ -1,404 +0,0 @@
From b92e223750a07b28f175eae97d5ce3978df41be8 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:32:05 +0800
Subject: [PATCH 18/30] flextimer: support layerscape
This is an integrated patch for layerscape flextimer support.
Signed-off-by: Wang Dongsheng <dongsheng.wang@nxp.com>
Signed-off-by: Meng Yi <meng.yi@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/clocksource/fsl_ftm_timer.c | 8 +-
drivers/soc/fsl/layerscape/ftm_alarm.c | 367 +++++++++++++++++++++++++++++++++
2 files changed, 371 insertions(+), 4 deletions(-)
create mode 100644 drivers/soc/fsl/layerscape/ftm_alarm.c
--- a/drivers/clocksource/fsl_ftm_timer.c
+++ b/drivers/clocksource/fsl_ftm_timer.c
@@ -83,11 +83,11 @@ static inline void ftm_counter_disable(v
static inline void ftm_irq_acknowledge(void __iomem *base)
{
- u32 val;
+ unsigned int timeout = 100;
- val = ftm_readl(base + FTM_SC);
- val &= ~FTM_SC_TOF;
- ftm_writel(val, base + FTM_SC);
+ while ((FTM_SC_TOF & ftm_readl(base + FTM_SC)) && timeout--)
+ ftm_writel(ftm_readl(base + FTM_SC) & (~FTM_SC_TOF),
+ base + FTM_SC);
}
static inline void ftm_irq_enable(void __iomem *base)
--- /dev/null
+++ b/drivers/soc/fsl/layerscape/ftm_alarm.c
@@ -0,0 +1,367 @@
+/*
+ * Freescale FlexTimer Module (FTM) Alarm driver.
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/libata.h>
+#include <linux/module.h>
+
+#define FTM_SC 0x00
+#define FTM_SC_CLK_SHIFT 3
+#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
+#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
+#define FTM_SC_PS_MASK 0x7
+#define FTM_SC_TOIE BIT(6)
+#define FTM_SC_TOF BIT(7)
+
+#define FTM_SC_CLKS_FIXED_FREQ 0x02
+
+#define FTM_CNT 0x04
+#define FTM_MOD 0x08
+#define FTM_CNTIN 0x4C
+
+#define FIXED_FREQ_CLK 32000
+#define MAX_FREQ_DIV (1 << FTM_SC_PS_MASK)
+#define MAX_COUNT_VAL 0xffff
+
+static void __iomem *ftm1_base;
+static void __iomem *rcpm_ftm_addr;
+static u32 alarm_freq;
+static bool big_endian;
+
+enum pmu_endian_type {
+ BIG_ENDIAN,
+ LITTLE_ENDIAN,
+};
+
+struct rcpm_cfg {
+ enum pmu_endian_type big_endian; /* Big/Little endian of PMU module */
+ u32 flextimer_set_bit; /* FlexTimer1 is not powerdown during device LPM20 */
+};
+
+static struct rcpm_cfg ls1012a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1021a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1043a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1046a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1088a_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static struct rcpm_cfg ls208xa_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static const struct of_device_id ippdexpcr_of_match[] = {
+ { .compatible = "fsl,ls1012a-ftm", .data = &ls1012a_rcpm_cfg},
+ { .compatible = "fsl,ls1021a-ftm", .data = &ls1021a_rcpm_cfg},
+ { .compatible = "fsl,ls1043a-ftm", .data = &ls1043a_rcpm_cfg},
+ { .compatible = "fsl,ls1046a-ftm", .data = &ls1046a_rcpm_cfg},
+ { .compatible = "fsl,ls1088a-ftm", .data = &ls1088a_rcpm_cfg},
+ { .compatible = "fsl,ls208xa-ftm", .data = &ls208xa_rcpm_cfg},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ippdexpcr_of_match);
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+ if (big_endian)
+ return ioread32be(addr);
+
+ return ioread32(addr);
+}
+
+static inline void ftm_writel(u32 val, void __iomem *addr)
+{
+ if (big_endian)
+ iowrite32be(val, addr);
+ else
+ iowrite32(val, addr);
+}
+
+static inline void ftm_counter_enable(void __iomem *base)
+{
+ u32 val;
+
+ /* select and enable counter clock source */
+ val = ftm_readl(base + FTM_SC);
+ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+ val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+ ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_counter_disable(void __iomem *base)
+{
+ u32 val;
+
+ /* disable counter clock source */
+ val = ftm_readl(base + FTM_SC);
+ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+ ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_acknowledge(void __iomem *base)
+{
+ unsigned int timeout = 100;
+
+ while ((FTM_SC_TOF & ftm_readl(base + FTM_SC)) && timeout--)
+ ftm_writel(ftm_readl(base + FTM_SC) & (~FTM_SC_TOF),
+ base + FTM_SC);
+}
+
+static inline void ftm_irq_enable(void __iomem *base)
+{
+ u32 val;
+
+ val = ftm_readl(base + FTM_SC);
+ val |= FTM_SC_TOIE;
+ ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_disable(void __iomem *base)
+{
+ u32 val;
+
+ val = ftm_readl(base + FTM_SC);
+ val &= ~FTM_SC_TOIE;
+ ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_reset_counter(void __iomem *base)
+{
+ /*
+ * The CNT register contains the FTM counter value.
+ * Reset clears the CNT register. Writing any value to COUNT
+ * updates the counter with its initial value, CNTIN.
+ */
+ ftm_writel(0x00, base + FTM_CNT);
+}
+
+static u32 time_to_cycle(unsigned long time)
+{
+ u32 cycle;
+
+ cycle = time * alarm_freq;
+ if (cycle > MAX_COUNT_VAL) {
+ pr_err("Out of alarm range.\n");
+ cycle = 0;
+ }
+
+ return cycle;
+}
+
+static u32 cycle_to_time(u32 cycle)
+{
+ return cycle / alarm_freq + 1;
+}
+
+static void ftm_clean_alarm(void)
+{
+ ftm_counter_disable(ftm1_base);
+
+ ftm_writel(0x00, ftm1_base + FTM_CNTIN);
+ ftm_writel(~0U, ftm1_base + FTM_MOD);
+
+ ftm_reset_counter(ftm1_base);
+}
+
+static int ftm_set_alarm(u64 cycle)
+{
+ ftm_irq_disable(ftm1_base);
+
+ /*
+ * The counter increments until the value of MOD is reached,
+ * at which point the counter is reloaded with the value of CNTIN.
+ * The TOF (the overflow flag) bit is set when the FTM counter
+ * changes from MOD to CNTIN. So we should using the cycle - 1.
+ */
+ ftm_writel(cycle - 1, ftm1_base + FTM_MOD);
+
+ ftm_counter_enable(ftm1_base);
+
+ ftm_irq_enable(ftm1_base);
+
+ return 0;
+}
+
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
+{
+ ftm_irq_acknowledge(ftm1_base);
+ ftm_irq_disable(ftm1_base);
+ ftm_clean_alarm();
+
+ return IRQ_HANDLED;
+}
+
+static ssize_t ftm_alarm_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u32 count, val;
+
+ count = ftm_readl(ftm1_base + FTM_MOD);
+ val = ftm_readl(ftm1_base + FTM_CNT);
+ val = (count & MAX_COUNT_VAL) - val;
+ val = cycle_to_time(val);
+
+ return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ftm_alarm_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 cycle;
+ unsigned long time;
+
+ if (kstrtoul(buf, 0, &time))
+ return -EINVAL;
+
+ ftm_clean_alarm();
+
+ cycle = time_to_cycle(time);
+ if (!cycle)
+ return -EINVAL;
+
+ ftm_set_alarm(cycle);
+
+ return count;
+}
+
+static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
+ ftm_alarm_show, ftm_alarm_store);
+
+static int ftm_alarm_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *r;
+ int irq;
+ int ret;
+ struct rcpm_cfg *rcpm_cfg;
+ u32 ippdexpcr, flextimer;
+ const struct of_device_id *of_id;
+ enum pmu_endian_type endian;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -ENODEV;
+
+ ftm1_base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(ftm1_base))
+ return PTR_ERR(ftm1_base);
+
+ of_id = of_match_node(ippdexpcr_of_match, np);
+ if (!of_id)
+ return -ENODEV;
+
+ rcpm_cfg = devm_kzalloc(&pdev->dev, sizeof(*rcpm_cfg), GFP_KERNEL);
+ if (!rcpm_cfg)
+ return -ENOMEM;
+
+ rcpm_cfg = (struct rcpm_cfg*)of_id->data;
+ endian = rcpm_cfg->big_endian;
+ flextimer = rcpm_cfg->flextimer_set_bit;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "FlexTimer1");
+ if (r) {
+ rcpm_ftm_addr = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(rcpm_ftm_addr))
+ return PTR_ERR(rcpm_ftm_addr);
+ if (endian == BIG_ENDIAN)
+ ippdexpcr = ioread32be(rcpm_ftm_addr);
+ else
+ ippdexpcr = ioread32(rcpm_ftm_addr);
+ ippdexpcr |= flextimer;
+ if (endian == BIG_ENDIAN)
+ iowrite32be(ippdexpcr, rcpm_ftm_addr);
+ else
+ iowrite32(ippdexpcr, rcpm_ftm_addr);
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq <= 0) {
+ pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
+ return -EINVAL;
+ }
+
+ big_endian = of_property_read_bool(np, "big-endian");
+
+ ret = devm_request_irq(&pdev->dev, irq, ftm_alarm_interrupt,
+ IRQF_NO_SUSPEND, dev_name(&pdev->dev), NULL);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ return ret;
+ }
+
+ ret = device_create_file(&pdev->dev, &ftm_alarm_attributes);
+ if (ret) {
+ dev_err(&pdev->dev, "create sysfs fail.\n");
+ return ret;
+ }
+
+ alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+
+ ftm_clean_alarm();
+
+ device_init_wakeup(&pdev->dev, true);
+
+ return ret;
+}
+
+static const struct of_device_id ftm_alarm_match[] = {
+ { .compatible = "fsl,ls1012a-ftm", },
+ { .compatible = "fsl,ls1021a-ftm", },
+ { .compatible = "fsl,ls1043a-ftm", },
+ { .compatible = "fsl,ls1046a-ftm", },
+ { .compatible = "fsl,ls1088a-ftm", },
+ { .compatible = "fsl,ls208xa-ftm", },
+ { .compatible = "fsl,ftm-timer", },
+ { },
+};
+
+static struct platform_driver ftm_alarm_driver = {
+ .probe = ftm_alarm_probe,
+ .driver = {
+ .name = "ftm-alarm",
+ .owner = THIS_MODULE,
+ .of_match_table = ftm_alarm_match,
+ },
+};
+
+static int __init ftm_alarm_init(void)
+{
+ return platform_driver_register(&ftm_alarm_driver);
+}
+device_initcall(ftm_alarm_init);

View File

@ -1,58 +0,0 @@
From 177f92a14d8177124f37db0fafc11182e2dcdd62 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:33:05 +0800
Subject: [PATCH 19/30] gpu: support layerscape
This is an integrated patch for layerscape dcu support.
Signed-off-by: Alison Wang <b18965@freescale.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -225,7 +225,6 @@ static int fsl_dcu_drm_pm_suspend(struct
if (!fsl_dev)
return 0;
- disable_irq(fsl_dev->irq);
drm_kms_helper_poll_disable(fsl_dev->drm);
console_lock();
@@ -243,6 +242,8 @@ static int fsl_dcu_drm_pm_suspend(struct
return PTR_ERR(fsl_dev->state);
}
+ disable_irq(fsl_dev->irq);
+
clk_disable_unprepare(fsl_dev->clk);
return 0;
@@ -262,6 +263,12 @@ static int fsl_dcu_drm_pm_resume(struct
return ret;
}
+ ret = clk_prepare_enable(fsl_dev->pix_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable dcu pix clk\n");
+ return ret;
+ }
+
if (fsl_dev->tcon)
fsl_tcon_bypass_enable(fsl_dev->tcon);
fsl_dcu_drm_init_planes(fsl_dev->drm);
@@ -388,6 +395,12 @@ static int fsl_dcu_drm_probe(struct plat
goto disable_clk;
}
+ ret = clk_prepare_enable(fsl_dev->pix_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable dcu pix clk\n");
+ return ret;
+ }
+
fsl_dev->tcon = fsl_tcon_init(dev);
drm = drm_dev_alloc(driver, dev);

View File

@ -1,421 +0,0 @@
From 45b0e1589b25ea3106a8c8d18bf653fde95baa9f Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:34:22 +0800
Subject: [PATCH 20/30] guts: support layerscape
This is an integrated patch for layerscape guts support.
Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Amrita Kumari <amrita.kumari@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/soc/fsl/guts.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fsl/guts.h | 125 +++++++++++++++----------
2 files changed, 315 insertions(+), 48 deletions(-)
create mode 100644 drivers/soc/fsl/guts.c
--- /dev/null
+++ b/drivers/soc/fsl/guts.c
@@ -0,0 +1,238 @@
+/*
+ * Freescale QorIQ Platforms GUTS Driver
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/fsl/guts.h>
+
+struct guts {
+ struct ccsr_guts __iomem *regs;
+ bool little_endian;
+};
+
+struct fsl_soc_die_attr {
+ char *die;
+ u32 svr;
+ u32 mask;
+};
+
+static struct guts *guts;
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+
+/* SoC die attribute definition for QorIQ platform */
+static const struct fsl_soc_die_attr fsl_soc_die[] = {
+ /*
+ * Power Architecture-based SoCs T Series
+ */
+
+ /* Die: T4240, SoC: T4240/T4160/T4080 */
+ { .die = "T4240",
+ .svr = 0x82400000,
+ .mask = 0xfff00000,
+ },
+ /* Die: T1040, SoC: T1040/T1020/T1042/T1022 */
+ { .die = "T1040",
+ .svr = 0x85200000,
+ .mask = 0xfff00000,
+ },
+ /* Die: T2080, SoC: T2080/T2081 */
+ { .die = "T2080",
+ .svr = 0x85300000,
+ .mask = 0xfff00000,
+ },
+ /* Die: T1024, SoC: T1024/T1014/T1023/T1013 */
+ { .die = "T1024",
+ .svr = 0x85400000,
+ .mask = 0xfff00000,
+ },
+
+ /*
+ * ARM-based SoCs LS Series
+ */
+
+ /* Die: LS1043A, SoC: LS1043A/LS1023A */
+ { .die = "LS1043A",
+ .svr = 0x87920000,
+ .mask = 0xffff0000,
+ },
+ /* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */
+ { .die = "LS2080A",
+ .svr = 0x87010000,
+ .mask = 0xff3f0000,
+ },
+ /* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */
+ { .die = "LS1088A",
+ .svr = 0x87030000,
+ .mask = 0xff3f0000,
+ },
+ /* Die: LS1012A, SoC: LS1012A */
+ { .die = "LS1012A",
+ .svr = 0x87040000,
+ .mask = 0xffff0000,
+ },
+ /* Die: LS1046A, SoC: LS1046A/LS1026A */
+ { .die = "LS1046A",
+ .svr = 0x87070000,
+ .mask = 0xffff0000,
+ },
+ /* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */
+ { .die = "LS2088A",
+ .svr = 0x87090000,
+ .mask = 0xff3f0000,
+ },
+ /* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A */
+ { .die = "LS1021A",
+ .svr = 0x87000000,
+ .mask = 0xfff70000,
+ },
+ { },
+};
+
+static const struct fsl_soc_die_attr *fsl_soc_die_match(
+ u32 svr, const struct fsl_soc_die_attr *matches)
+{
+ while (matches->svr) {
+ if (matches->svr == (svr & matches->mask))
+ return matches;
+ matches++;
+ };
+ return NULL;
+}
+
+u32 fsl_guts_get_svr(void)
+{
+ u32 svr = 0;
+
+ if (!guts || !guts->regs)
+ return svr;
+
+ if (guts->little_endian)
+ svr = ioread32(&guts->regs->svr);
+ else
+ svr = ioread32be(&guts->regs->svr);
+
+ return svr;
+}
+EXPORT_SYMBOL(fsl_guts_get_svr);
+
+static int fsl_guts_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ const struct fsl_soc_die_attr *soc_die;
+ const char *machine;
+ u32 svr;
+
+ /* Initialize guts */
+ guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+ if (!guts)
+ return -ENOMEM;
+
+ guts->little_endian = of_property_read_bool(np, "little-endian");
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ guts->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(guts->regs))
+ return PTR_ERR(guts->regs);
+
+ /* Register soc device */
+ machine = of_flat_dt_get_machine_name();
+ if (machine)
+ soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+ svr = fsl_guts_get_svr();
+ soc_die = fsl_soc_die_match(svr, fsl_soc_die);
+ if (soc_die) {
+ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+ "QorIQ %s", soc_die->die);
+ } else {
+ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ");
+ }
+ soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+ "svr:0x%08x", svr);
+ soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+ (svr >> 4) & 0xf, svr & 0xf);
+
+ soc_dev = soc_device_register(&soc_dev_attr);
+ if (IS_ERR(soc_dev))
+ return PTR_ERR(soc_dev);
+
+ pr_info("Machine: %s\n", soc_dev_attr.machine);
+ pr_info("SoC family: %s\n", soc_dev_attr.family);
+ pr_info("SoC ID: %s, Revision: %s\n",
+ soc_dev_attr.soc_id, soc_dev_attr.revision);
+ return 0;
+}
+
+static int fsl_guts_remove(struct platform_device *dev)
+{
+ soc_device_unregister(soc_dev);
+ return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Freescale QorIQ SOCs.
+ */
+static const struct of_device_id fsl_guts_of_match[] = {
+ { .compatible = "fsl,qoriq-device-config-1.0", },
+ { .compatible = "fsl,qoriq-device-config-2.0", },
+ { .compatible = "fsl,p1010-guts", },
+ { .compatible = "fsl,p1020-guts", },
+ { .compatible = "fsl,p1021-guts", },
+ { .compatible = "fsl,p1022-guts", },
+ { .compatible = "fsl,p1023-guts", },
+ { .compatible = "fsl,p2020-guts", },
+ { .compatible = "fsl,bsc9131-guts", },
+ { .compatible = "fsl,bsc9132-guts", },
+ { .compatible = "fsl,mpc8536-guts", },
+ { .compatible = "fsl,mpc8544-guts", },
+ { .compatible = "fsl,mpc8548-guts", },
+ { .compatible = "fsl,mpc8568-guts", },
+ { .compatible = "fsl,mpc8569-guts", },
+ { .compatible = "fsl,mpc8572-guts", },
+ { .compatible = "fsl,ls1021a-dcfg", },
+ { .compatible = "fsl,ls1043a-dcfg", },
+ { .compatible = "fsl,ls1046a-dcfg", },
+ { .compatible = "fsl,ls2080a-dcfg", },
+ { .compatible = "fsl,ls1088a-dcfg", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_guts_of_match);
+
+static struct platform_driver fsl_guts_driver = {
+ .driver = {
+ .name = "fsl-guts",
+ .of_match_table = fsl_guts_of_match,
+ },
+ .probe = fsl_guts_probe,
+ .remove = fsl_guts_remove,
+};
+
+static int __init fsl_guts_init(void)
+{
+ return platform_driver_register(&fsl_guts_driver);
+}
+core_initcall(fsl_guts_init);
+
+static void __exit fsl_guts_exit(void)
+{
+ platform_driver_unregister(&fsl_guts_driver);
+}
+module_exit(fsl_guts_exit);
--- a/include/linux/fsl/guts.h
+++ b/include/linux/fsl/guts.h
@@ -30,83 +30,112 @@
* #ifdefs.
*/
struct ccsr_guts {
- __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
- __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
- __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
- __be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
- __be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
- __be32 pordevsr2; /* 0x.0014 - POR device status register 2 */
+ u32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
+ u32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
+ u32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and
+ * Control Register
+ */
+ u32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
+ u32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
+ u32 pordevsr2; /* 0x.0014 - POR device status register 2 */
u8 res018[0x20 - 0x18];
- __be32 porcir; /* 0x.0020 - POR Configuration Information Register */
+ u32 porcir; /* 0x.0020 - POR Configuration Information
+ * Register
+ */
u8 res024[0x30 - 0x24];
- __be32 gpiocr; /* 0x.0030 - GPIO Control Register */
+ u32 gpiocr; /* 0x.0030 - GPIO Control Register */
u8 res034[0x40 - 0x34];
- __be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
+ u32 gpoutdr; /* 0x.0040 - General-Purpose Output Data
+ * Register
+ */
u8 res044[0x50 - 0x44];
- __be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */
+ u32 gpindr; /* 0x.0050 - General-Purpose Input Data
+ * Register
+ */
u8 res054[0x60 - 0x54];
- __be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
- __be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */
- __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
+ u32 pmuxcr; /* 0x.0060 - Alternate Function Signal
+ * Multiplex Control
+ */
+ u32 pmuxcr2; /* 0x.0064 - Alternate function signal
+ * multiplex control 2
+ */
+ u32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
u8 res06c[0x70 - 0x6c];
- __be32 devdisr; /* 0x.0070 - Device Disable Control */
+ u32 devdisr; /* 0x.0070 - Device Disable Control */
#define CCSR_GUTS_DEVDISR_TB1 0x00001000
#define CCSR_GUTS_DEVDISR_TB0 0x00004000
- __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
+ u32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
u8 res078[0x7c - 0x78];
- __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */
- __be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
- __be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */
- __be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */
- __be32 pmcdr; /* 0x.008c - 4Power management clock disable register */
- __be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
- __be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */
- __be32 ectrstcr; /* 0x.0098 - Exception reset control register */
- __be32 autorstsr; /* 0x.009c - Automatic reset status register */
- __be32 pvr; /* 0x.00a0 - Processor Version Register */
- __be32 svr; /* 0x.00a4 - System Version Register */
+ u32 pmjcr; /* 0x.007c - 4 Power Management Jog Control
+ * Register
+ */
+ u32 powmgtcsr; /* 0x.0080 - Power Management Status and
+ * Control Register
+ */
+ u32 pmrccr; /* 0x.0084 - Power Management Reset Counter
+ * Configuration Register
+ */
+ u32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter
+ * Configuration Register
+ */
+ u32 pmcdr; /* 0x.008c - 4Power management clock disable
+ * register
+ */
+ u32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
+ u32 rstrscr; /* 0x.0094 - Reset Request Status and
+ * Control Register
+ */
+ u32 ectrstcr; /* 0x.0098 - Exception reset control register */
+ u32 autorstsr; /* 0x.009c - Automatic reset status register */
+ u32 pvr; /* 0x.00a0 - Processor Version Register */
+ u32 svr; /* 0x.00a4 - System Version Register */
u8 res0a8[0xb0 - 0xa8];
- __be32 rstcr; /* 0x.00b0 - Reset Control Register */
+ u32 rstcr; /* 0x.00b0 - Reset Control Register */
u8 res0b4[0xc0 - 0xb4];
- __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register
+ u32 iovselsr; /* 0x.00c0 - I/O voltage select status register
Called 'elbcvselcr' on 86xx SOCs */
u8 res0c4[0x100 - 0xc4];
- __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
+ u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
There are 16 registers */
u8 res140[0x224 - 0x140];
- __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
- __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
+ u32 iodelay1; /* 0x.0224 - IO delay control register 1 */
+ u32 iodelay2; /* 0x.0228 - IO delay control register 2 */
u8 res22c[0x604 - 0x22c];
- __be32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
+ u32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
u8 res608[0x800 - 0x608];
- __be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
+ u32 clkdvdr; /* 0x.0800 - Clock Divide Register */
u8 res804[0x900 - 0x804];
- __be32 ircr; /* 0x.0900 - Infrared Control Register */
+ u32 ircr; /* 0x.0900 - Infrared Control Register */
u8 res904[0x908 - 0x904];
- __be32 dmacr; /* 0x.0908 - DMA Control Register */
+ u32 dmacr; /* 0x.0908 - DMA Control Register */
u8 res90c[0x914 - 0x90c];
- __be32 elbccr; /* 0x.0914 - eLBC Control Register */
+ u32 elbccr; /* 0x.0914 - eLBC Control Register */
u8 res918[0xb20 - 0x918];
- __be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
- __be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
- __be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
+ u32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
+ u32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
+ u32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
u8 resb2c[0xe00 - 0xb2c];
- __be32 clkocr; /* 0x.0e00 - Clock Out Select Register */
+ u32 clkocr; /* 0x.0e00 - Clock Out Select Register */
u8 rese04[0xe10 - 0xe04];
- __be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
+ u32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
u8 rese14[0xe20 - 0xe14];
- __be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
- __be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */
+ u32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
+ u32 cpfor; /* 0x.0e24 - L2 charge pump fuse override
+ * register
+ */
u8 rese28[0xf04 - 0xe28];
- __be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
- __be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
+ u32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
+ u32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
u8 resf0c[0xf2c - 0xf0c];
- __be32 itcr; /* 0x.0f2c - Internal transaction control register */
+ u32 itcr; /* 0x.0f2c - Internal transaction control
+ * register
+ */
u8 resf30[0xf40 - 0xf30];
- __be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
- __be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
+ u32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
+ u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
} __attribute__ ((packed));
+u32 fsl_guts_get_svr(void);
/* Alternate function signal multiplex control */
#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))

View File

@ -1,360 +0,0 @@
From 659aa30c59fb188b533a7edcb9bd38ac007a2739 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:35:11 +0800
Subject: [PATCH 21/30] i2c: support layerscape
This is an integrated patch for layerscape i2c support.
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Signed-off-by: Priyanka Jain <Priyanka.Jain@freescale.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/i2c/busses/i2c-imx.c | 195 +++++++++++++++++++++++++++++++++++-
drivers/i2c/muxes/i2c-mux-pca954x.c | 43 ++++++++
2 files changed, 237 insertions(+), 1 deletion(-)
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -53,6 +53,11 @@
#include <linux/pm_runtime.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/libata.h>
/* This will be the driver name the kernel reports */
#define DRIVER_NAME "imx-i2c"
@@ -117,6 +122,54 @@
#define I2C_PM_TIMEOUT 10 /* ms */
+enum pinmux_endian_type {
+ BIG_ENDIAN,
+ LITTLE_ENDIAN,
+};
+
+struct pinmux_cfg {
+ enum pinmux_endian_type endian; /* endian of RCWPMUXCR0 */
+ u32 pmuxcr_offset;
+ u32 pmuxcr_set_bit; /* pin mux of RCWPMUXCR0 */
+};
+
+static struct pinmux_cfg ls1012a_pinmux_cfg = {
+ .endian = BIG_ENDIAN,
+ .pmuxcr_offset = 0x430,
+ .pmuxcr_set_bit = 0x10,
+};
+
+static struct pinmux_cfg ls1043a_pinmux_cfg = {
+ .endian = BIG_ENDIAN,
+ .pmuxcr_offset = 0x40C,
+ .pmuxcr_set_bit = 0x10,
+};
+
+static struct pinmux_cfg ls1046a_pinmux_cfg = {
+ .endian = BIG_ENDIAN,
+ .pmuxcr_offset = 0x40C,
+ .pmuxcr_set_bit = 0x80000000,
+};
+
+static const struct of_device_id pinmux_of_match[] = {
+ { .compatible = "fsl,ls1012a-vf610-i2c", .data = &ls1012a_pinmux_cfg},
+ { .compatible = "fsl,ls1043a-vf610-i2c", .data = &ls1043a_pinmux_cfg},
+ { .compatible = "fsl,ls1046a-vf610-i2c", .data = &ls1046a_pinmux_cfg},
+ {},
+};
+MODULE_DEVICE_TABLE(of, pinmux_of_match);
+
+/* The SCFG, Supplemental Configuration Unit, provides SoC specific
+ * configuration and status registers for the device. There is a
+ * SDHC IO VSEL control register on SCFG for some platforms. It's
+ * used to support SDHC IO voltage switching.
+ */
+static const struct of_device_id scfg_device_ids[] = {
+ { .compatible = "fsl,ls1012a-scfg", },
+ { .compatible = "fsl,ls1043a-scfg", },
+ { .compatible = "fsl,ls1046a-scfg", },
+ {}
+};
/*
* sorted list of clock divider, register value pairs
* taken from table 26-5, p.26-9, Freescale i.MX
@@ -210,6 +263,12 @@ struct imx_i2c_struct {
struct pinctrl_state *pinctrl_pins_gpio;
struct imx_i2c_dma *dma;
+ int layerscape_bus_recover;
+ int gpio;
+ int need_set_pmuxcr;
+ int pmuxcr_set;
+ int pmuxcr_endian;
+ void __iomem *pmuxcr_addr;
};
static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
@@ -878,6 +937,78 @@ static int i2c_imx_read(struct imx_i2c_s
return 0;
}
+/*
+ * Based on the I2C specification, if the data line (SDA) is
+ * stuck low, the master should send nine * clock pulses.
+ * The I2C slave device that held the bus low should release it
+ * sometime within * those nine clocks. Due to this erratum,
+ * the I2C controller cannot generate nine clock pulses.
+ */
+static int i2c_imx_recovery_for_layerscape(struct imx_i2c_struct *i2c_imx)
+{
+ u32 pmuxcr = 0;
+ int ret;
+ unsigned int i, temp;
+
+ /* configure IICx_SCL/GPIO pin as a GPIO */
+ if (i2c_imx->need_set_pmuxcr == 1) {
+ pmuxcr = ioread32be(i2c_imx->pmuxcr_addr);
+ if (i2c_imx->pmuxcr_endian == BIG_ENDIAN)
+ iowrite32be(i2c_imx->pmuxcr_set|pmuxcr,
+ i2c_imx->pmuxcr_addr);
+ else
+ iowrite32(i2c_imx->pmuxcr_set|pmuxcr,
+ i2c_imx->pmuxcr_addr);
+ }
+
+ ret = gpio_request(i2c_imx->gpio, i2c_imx->adapter.name);
+ if (ret) {
+ dev_err(&i2c_imx->adapter.dev,
+ "can't get gpio: %d\n", ret);
+ return ret;
+ }
+
+ /* Configure GPIO pin as an output and open drain. */
+ gpio_direction_output(i2c_imx->gpio, 1);
+ udelay(10);
+
+ /* Write data to generate 9 pulses */
+ for (i = 0; i < 9; i++) {
+ gpio_set_value(i2c_imx->gpio, 1);
+ udelay(10);
+ gpio_set_value(i2c_imx->gpio, 0);
+ udelay(10);
+ }
+ /* ensure that the last level sent is always high */
+ gpio_set_value(i2c_imx->gpio, 1);
+
+ /*
+ * Set I2Cx_IBCR = 0h00 to generate a STOP and then
+ * set I2Cx_IBCR = 0h80 to reset
+ */
+ temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+ temp &= ~(I2CR_MSTA | I2CR_MTX);
+ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+ /* Restore the saved value of the register SCFG_RCWPMUXCR0 */
+ if (i2c_imx->need_set_pmuxcr == 1) {
+ if (i2c_imx->pmuxcr_endian == BIG_ENDIAN)
+ iowrite32be(pmuxcr, i2c_imx->pmuxcr_addr);
+ else
+ iowrite32(pmuxcr, i2c_imx->pmuxcr_addr);
+ }
+ /*
+ * Set I2C_IBSR[IBAL] to clear the IBAL bit if-
+ * I2C_IBSR[IBAL] = 1
+ */
+ temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
+ if (temp & I2SR_IAL) {
+ temp &= ~I2SR_IAL;
+ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
+ }
+ return 0;
+}
+
static int i2c_imx_xfer(struct i2c_adapter *adapter,
struct i2c_msg *msgs, int num)
{
@@ -888,6 +1019,19 @@ static int i2c_imx_xfer(struct i2c_adapt
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+ /*
+ * workround for ERR010027: ensure that the I2C BUS is idle
+ * before switching to master mode and attempting a Start cycle
+ */
+ result = i2c_imx_bus_busy(i2c_imx, 0);
+ if (result) {
+ /* timeout */
+ if ((result == -ETIMEDOUT) && (i2c_imx->layerscape_bus_recover == 1))
+ i2c_imx_recovery_for_layerscape(i2c_imx);
+ else
+ goto out;
+ }
+
result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
if (result < 0)
goto out;
@@ -1030,6 +1174,50 @@ static int i2c_imx_init_recovery_info(st
return 0;
}
+/*
+ * switch SCL and SDA to their GPIO function and do some bitbanging
+ * for bus recovery.
+ * There are platforms such as Layerscape that don't support pinctrl, so add
+ * workaround for layerscape, it has no effect for other platforms.
+ */
+static int i2c_imx_init_recovery_for_layerscape(
+ struct imx_i2c_struct *i2c_imx,
+ struct platform_device *pdev)
+{
+ const struct of_device_id *of_id;
+ struct device_node *np = pdev->dev.of_node;
+ struct pinmux_cfg *pinmux_cfg;
+ struct device_node *scfg_node;
+ void __iomem *scfg_base = NULL;
+
+ i2c_imx->gpio = of_get_named_gpio(np, "fsl-scl-gpio", 0);
+ if (!gpio_is_valid(i2c_imx->gpio)) {
+ dev_info(&pdev->dev, "fsl-scl-gpio not found\n");
+ return 0;
+ }
+ pinmux_cfg = devm_kzalloc(&pdev->dev, sizeof(*pinmux_cfg), GFP_KERNEL);
+ if (!pinmux_cfg)
+ return -ENOMEM;
+
+ i2c_imx->need_set_pmuxcr = 0;
+ of_id = of_match_node(pinmux_of_match, np);
+ if (of_id) {
+ pinmux_cfg = (struct pinmux_cfg *)of_id->data;
+ i2c_imx->pmuxcr_endian = pinmux_cfg->endian;
+ i2c_imx->pmuxcr_set = pinmux_cfg->pmuxcr_set_bit;
+ scfg_node = of_find_matching_node(NULL, scfg_device_ids);
+ if (scfg_node) {
+ scfg_base = of_iomap(scfg_node, 0);
+ if (scfg_base) {
+ i2c_imx->pmuxcr_addr = scfg_base + pinmux_cfg->pmuxcr_offset;
+ i2c_imx->need_set_pmuxcr = 1;
+ }
+ }
+ }
+ i2c_imx->layerscape_bus_recover = 1;
+ return 0;
+}
+
static u32 i2c_imx_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
@@ -1085,6 +1273,11 @@ static int i2c_imx_probe(struct platform
i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
i2c_imx->base = base;
+ /* Init optional bus recovery for layerscape */
+ ret = i2c_imx_init_recovery_for_layerscape(i2c_imx, pdev);
+ if (ret)
+ return ret;
+
/* Get I2C clock */
i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c_imx->clk)) {
@@ -1099,7 +1292,7 @@ static int i2c_imx_probe(struct platform
}
/* Request IRQ */
- ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
+ ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED,
pdev->name, i2c_imx);
if (ret) {
dev_err(&pdev->dev, "can't claim irq %d\n", irq);
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -74,6 +74,7 @@ struct pca954x {
u8 last_chan; /* last register value */
u8 deselect;
struct i2c_client *client;
+ u8 disable_mux; /* do not disable mux if val not 0 */
};
/* Provide specs for the PCA954x types we know about */
@@ -196,6 +197,13 @@ static int pca954x_deselect_mux(struct i
if (!(data->deselect & (1 << chan)))
return 0;
+#ifdef CONFIG_ARCH_LAYERSCAPE
+ if (data->disable_mux != 0)
+ data->last_chan = data->chip->nchans;
+ else
+ data->last_chan = 0;
+ return pca954x_reg_write(muxc->parent, client, data->disable_mux);
+#endif
/* Deselect active channel */
data->last_chan = 0;
return pca954x_reg_write(muxc->parent, client, data->last_chan);
@@ -228,6 +236,28 @@ static int pca954x_probe(struct i2c_clie
return -ENOMEM;
data = i2c_mux_priv(muxc);
+#ifdef CONFIG_ARCH_LAYERSCAPE
+ /* The point here is that you must not disable a mux if there
+ * are no pullups on the input or you mess up the I2C. This
+ * needs to be put into the DTS really as the kernel cannot
+ * know this otherwise.
+ */
+ match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);
+ if (match)
+ data->chip = of_device_get_match_data(&client->dev);
+ else
+ data->chip = &chips[id->driver_data];
+
+ data->disable_mux = of_node &&
+ of_property_read_bool(of_node, "i2c-mux-never-disable") &&
+ data->chip->muxtype == pca954x_ismux ?
+ data->chip->enable : 0;
+ /* force the first selection */
+ if (data->disable_mux != 0)
+ data->last_chan = data->chip->nchans;
+ else
+ data->last_chan = 0;
+#endif
i2c_set_clientdata(client, muxc);
data->client = client;
@@ -240,11 +270,16 @@ static int pca954x_probe(struct i2c_clie
* that the mux is in fact present. This also
* initializes the mux to disconnected state.
*/
+#ifdef CONFIG_ARCH_LAYERSCAPE
+ if (i2c_smbus_write_byte(client, data->disable_mux) < 0) {
+#else
if (i2c_smbus_write_byte(client, 0) < 0) {
+#endif
dev_warn(&client->dev, "probe failed\n");
return -ENODEV;
}
+#ifndef CONFIG_ARCH_LAYERSCAPE
match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);
if (match)
data->chip = of_device_get_match_data(&client->dev);
@@ -252,6 +287,7 @@ static int pca954x_probe(struct i2c_clie
data->chip = &chips[id->driver_data];
data->last_chan = 0; /* force the first selection */
+#endif
idle_disconnect_dt = of_node &&
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
@@ -312,6 +348,13 @@ static int pca954x_resume(struct device
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct pca954x *data = i2c_mux_priv(muxc);
+#ifdef CONFIG_ARCH_LAYERSCAPE
+ if (data->disable_mux != 0)
+ data->last_chan = data->chip->nchans;
+ else
+ data->last_chan = 0;
+ return i2c_smbus_write_byte(client, data->disable_mux);
+#endif
data->last_chan = 0;
return i2c_smbus_write_byte(client, 0);
}

View File

@ -1,182 +0,0 @@
From dab02a7cc54494740e849cd51b554d100eb5541d Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Thu, 5 Jul 2018 17:36:09 +0800
Subject: [PATCH 23/32] irqchip: support layerscape
This is an integrated patch for layerscape gic support.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-gic-v3-its.c | 1 +
include/linux/irqchip/arm-gic-v3.h | 3 +++
include/linux/irqdomain.h | 36 +++++++++++++++++++++++++++
kernel/irq/irqdomain.c | 39 ++++++++++++++++++++++++++++++
kernel/irq/msi.c | 4 +--
6 files changed, 82 insertions(+), 2 deletions(-)
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -75,3 +75,4 @@ obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scf
obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o
obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o
+obj-$(CONFIG_QUICC_ENGINE) += irq-qeic.o
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1658,6 +1658,7 @@ static int its_init_domain(struct fwnode
inner_domain->parent = its_parent;
inner_domain->bus_token = DOMAIN_BUS_NEXUS;
+ inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
info->ops = &its_msi_domain_ops;
info->data = its;
inner_domain->host_data = info;
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -133,6 +133,9 @@
#define GIC_BASER_SHAREABILITY(reg, type) \
(GIC_BASER_##type << reg##_SHAREABILITY_SHIFT)
+/* encode a size field of width @w containing @n - 1 units */
+#define GIC_ENCODE_SZ(n, w) (((unsigned long)(n) - 1) & GENMASK_ULL(((w) - 1), 0))
+
#define GICR_PROPBASER_SHAREABILITY_SHIFT (10)
#define GICR_PROPBASER_INNER_CACHEABILITY_SHIFT (7)
#define GICR_PROPBASER_OUTER_CACHEABILITY_SHIFT (56)
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -187,6 +187,12 @@ enum {
/* Irq domain is an IPI domain with single virq */
IRQ_DOMAIN_FLAG_IPI_SINGLE = (1 << 3),
+ /* Irq domain implements MSIs */
+ IRQ_DOMAIN_FLAG_MSI = (1 << 4),
+
+ /* Irq domain implements MSI remapping */
+ IRQ_DOMAIN_FLAG_MSI_REMAP = (1 << 5),
+
/*
* Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
* for implementation specific purposes and ignored by the
@@ -220,6 +226,7 @@ struct irq_domain *irq_domain_add_legacy
void *host_data);
extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
enum irq_domain_bus_token bus_token);
+extern bool irq_domain_check_msi_remap(void);
extern void irq_set_default_host(struct irq_domain *host);
extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
irq_hw_number_t hwirq, int node,
@@ -453,6 +460,19 @@ static inline bool irq_domain_is_ipi_sin
{
return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
}
+
+static inline bool irq_domain_is_msi(struct irq_domain *domain)
+{
+ return domain->flags & IRQ_DOMAIN_FLAG_MSI;
+}
+
+static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
+{
+ return domain->flags & IRQ_DOMAIN_FLAG_MSI_REMAP;
+}
+
+extern bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain);
+
#else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
static inline void irq_domain_activate_irq(struct irq_data *data) { }
static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
@@ -484,6 +504,22 @@ static inline bool irq_domain_is_ipi_sin
{
return false;
}
+
+static inline bool irq_domain_is_msi(struct irq_domain *domain)
+{
+ return false;
+}
+
+static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
+{
+ return false;
+}
+
+static inline bool
+irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
+{
+ return false;
+}
#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
#else /* CONFIG_IRQ_DOMAIN */
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -319,6 +319,31 @@ struct irq_domain *irq_find_matching_fws
EXPORT_SYMBOL_GPL(irq_find_matching_fwspec);
/**
+ * irq_domain_check_msi_remap - Check whether all MSI irq domains implement
+ * IRQ remapping
+ *
+ * Return: false if any MSI irq domain does not support IRQ remapping,
+ * true otherwise (including if there is no MSI irq domain)
+ */
+bool irq_domain_check_msi_remap(void)
+{
+ struct irq_domain *h;
+ bool ret = true;
+
+ mutex_lock(&irq_domain_mutex);
+ list_for_each_entry(h, &irq_domain_list, link) {
+ if (irq_domain_is_msi(h) &&
+ !irq_domain_hierarchical_is_msi_remap(h)) {
+ ret = false;
+ break;
+ }
+ }
+ mutex_unlock(&irq_domain_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(irq_domain_check_msi_remap);
+
+/**
* irq_set_default_host() - Set a "default" irq domain
* @domain: default domain pointer
*
@@ -1420,6 +1445,20 @@ static void irq_domain_check_hierarchy(s
if (domain->ops->alloc)
domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY;
}
+
+/**
+ * irq_domain_hierarchical_is_msi_remap - Check if the domain or any
+ * parent has MSI remapping support
+ * @domain: domain pointer
+ */
+bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
+{
+ for (; domain; domain = domain->parent) {
+ if (irq_domain_is_msi_remap(domain))
+ return true;
+ }
+ return false;
+}
#else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
/**
* irq_domain_get_irq_data - Get irq_data associated with @virq and @domain
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -272,8 +272,8 @@ struct irq_domain *msi_create_irq_domain
if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
msi_domain_update_chip_ops(info);
- return irq_domain_create_hierarchy(parent, 0, 0, fwnode,
- &msi_domain_ops, info);
+ return irq_domain_create_hierarchy(parent, IRQ_DOMAIN_FLAG_MSI, 0,
+ fwnode, &msi_domain_ops, info);
}
int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,

View File

@ -1,594 +0,0 @@
From 4215d5757595e7ec7ca146c2b901beb177f415d8 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:37:13 +0800
Subject: [PATCH 24/30] mmc: layerscape support
This is an integrated patch for layerscape mmc support.
Adrian Hunter <adrian.hunter@intel.com>
Jaehoon Chung <jh80.chung@samsung.com>
Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-esdhc.h | 52 +++++---
drivers/mmc/host/sdhci-of-esdhc.c | 265 ++++++++++++++++++++++++++++++++++++--
drivers/mmc/host/sdhci.c | 45 ++++---
drivers/mmc/host/sdhci.h | 3 +
5 files changed, 320 insertions(+), 46 deletions(-)
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -144,6 +144,7 @@ config MMC_SDHCI_OF_ESDHC
depends on MMC_SDHCI_PLTFM
depends on PPC || ARCH_MXC || ARCH_LAYERSCAPE
select MMC_SDHCI_IO_ACCESSORS
+ select FSL_GUTS
help
This selects the Freescale eSDHC controller support.
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -24,30 +24,46 @@
SDHCI_QUIRK_PIO_NEEDS_DELAY | \
SDHCI_QUIRK_NO_HISPD_BIT)
-#define ESDHC_PROCTL 0x28
-
-#define ESDHC_SYSTEM_CONTROL 0x2c
-#define ESDHC_CLOCK_MASK 0x0000fff0
-#define ESDHC_PREDIV_SHIFT 8
-#define ESDHC_DIVIDER_SHIFT 4
-#define ESDHC_CLOCK_PEREN 0x00000004
-#define ESDHC_CLOCK_HCKEN 0x00000002
-#define ESDHC_CLOCK_IPGEN 0x00000001
-
/* pltfm-specific */
#define ESDHC_HOST_CONTROL_LE 0x20
/*
- * P2020 interpretation of the SDHCI_HOST_CONTROL register
+ * eSDHC register definition
*/
-#define ESDHC_CTRL_4BITBUS (0x1 << 1)
-#define ESDHC_CTRL_8BITBUS (0x2 << 1)
-#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
-
-/* OF-specific */
-#define ESDHC_DMA_SYSCTL 0x40c
-#define ESDHC_DMA_SNOOP 0x00000040
-#define ESDHC_HOST_CONTROL_RES 0x01
+/* Present State Register */
+#define ESDHC_PRSSTAT 0x24
+#define ESDHC_CLOCK_STABLE 0x00000008
+
+/* Protocol Control Register */
+#define ESDHC_PROCTL 0x28
+#define ESDHC_VOLT_SEL 0x00000400
+#define ESDHC_CTRL_4BITBUS (0x1 << 1)
+#define ESDHC_CTRL_8BITBUS (0x2 << 1)
+#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
+#define ESDHC_HOST_CONTROL_RES 0x01
+
+/* System Control Register */
+#define ESDHC_SYSTEM_CONTROL 0x2c
+#define ESDHC_CLOCK_MASK 0x0000fff0
+#define ESDHC_PREDIV_SHIFT 8
+#define ESDHC_DIVIDER_SHIFT 4
+#define ESDHC_CLOCK_SDCLKEN 0x00000008
+#define ESDHC_CLOCK_PEREN 0x00000004
+#define ESDHC_CLOCK_HCKEN 0x00000002
+#define ESDHC_CLOCK_IPGEN 0x00000001
+
+/* Host Controller Capabilities Register 2 */
+#define ESDHC_CAPABILITIES_1 0x114
+
+/* Tuning Block Control Register */
+#define ESDHC_TBCTL 0x120
+#define ESDHC_TB_EN 0x00000004
+
+/* Control Register for DMA transfer */
+#define ESDHC_DMA_SYSCTL 0x40c
+#define ESDHC_PERIPHERAL_CLK_SEL 0x00080000
+#define ESDHC_FLUSH_ASYNC_FIFO 0x00040000
+#define ESDHC_DMA_SNOOP 0x00000040
#endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -16,8 +16,12 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/sys_soc.h>
+#include <linux/clk.h>
+#include <linux/ktime.h>
#include <linux/mmc/host.h>
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
@@ -28,8 +32,12 @@
struct sdhci_esdhc {
u8 vendor_ver;
u8 spec_ver;
+ bool quirk_incorrect_hostver;
+ unsigned int peripheral_clock;
};
+static void esdhc_clock_enable(struct sdhci_host *host, bool enable);
+
/**
* esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register
* to make it compatible with SD spec.
@@ -80,6 +88,17 @@ static u32 esdhc_readl_fixup(struct sdhc
return ret;
}
+ /*
+ * DTS properties of mmc host are used to enable each speed mode
+ * according to soc and board capability. So clean up
+ * SDR50/SDR104/DDR50 support bits here.
+ */
+ if (spec_reg == SDHCI_CAPABILITIES_1) {
+ ret = value & (~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
+ SDHCI_SUPPORT_DDR50));
+ return ret;
+ }
+
ret = value;
return ret;
}
@@ -87,6 +106,8 @@ static u32 esdhc_readl_fixup(struct sdhc
static u16 esdhc_readw_fixup(struct sdhci_host *host,
int spec_reg, u32 value)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
u16 ret;
int shift = (spec_reg & 0x2) * 8;
@@ -94,6 +115,12 @@ static u16 esdhc_readw_fixup(struct sdhc
ret = value & 0xffff;
else
ret = (value >> shift) & 0xffff;
+ /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect
+ * vendor version and spec version information.
+ */
+ if ((spec_reg == SDHCI_HOST_VERSION) &&
+ (esdhc->quirk_incorrect_hostver))
+ ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200;
return ret;
}
@@ -235,7 +262,11 @@ static u32 esdhc_be_readl(struct sdhci_h
u32 ret;
u32 value;
- value = ioread32be(host->ioaddr + reg);
+ if (reg == SDHCI_CAPABILITIES_1)
+ value = ioread32be(host->ioaddr + ESDHC_CAPABILITIES_1);
+ else
+ value = ioread32be(host->ioaddr + reg);
+
ret = esdhc_readl_fixup(host, reg, value);
return ret;
@@ -246,7 +277,11 @@ static u32 esdhc_le_readl(struct sdhci_h
u32 ret;
u32 value;
- value = ioread32(host->ioaddr + reg);
+ if (reg == SDHCI_CAPABILITIES_1)
+ value = ioread32(host->ioaddr + ESDHC_CAPABILITIES_1);
+ else
+ value = ioread32(host->ioaddr + reg);
+
ret = esdhc_readl_fixup(host, reg, value);
return ret;
@@ -404,15 +439,25 @@ static int esdhc_of_enable_dma(struct sd
static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
- return pltfm_host->clock;
+ if (esdhc->peripheral_clock)
+ return esdhc->peripheral_clock;
+ else
+ return pltfm_host->clock;
}
static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
+ unsigned int clock;
- return pltfm_host->clock / 256 / 16;
+ if (esdhc->peripheral_clock)
+ clock = esdhc->peripheral_clock;
+ else
+ clock = pltfm_host->clock;
+ return clock / 256 / 16;
}
static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
@@ -421,12 +466,15 @@ static void esdhc_of_set_clock(struct sd
struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
int pre_div = 1;
int div = 1;
+ ktime_t timeout;
u32 temp;
host->mmc->actual_clock = 0;
- if (clock == 0)
+ if (clock == 0) {
+ esdhc_clock_enable(host, false);
return;
+ }
/* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
if (esdhc->vendor_ver < VENDOR_V_23)
@@ -454,9 +502,15 @@ static void esdhc_of_set_clock(struct sd
clock -= 5000000;
}
+ /* Workaround to reduce the clock frequency for ls1021a esdhc */
+ if (of_find_compatible_node(NULL, NULL, "fsl,ls1021a-esdhc")) {
+ if (clock == 50000000)
+ clock = 46500000;
+ }
+
temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
- temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
- | ESDHC_CLOCK_MASK);
+ temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
+ ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
@@ -476,7 +530,20 @@ static void esdhc_of_set_clock(struct sd
| (div << ESDHC_DIVIDER_SHIFT)
| (pre_div << ESDHC_PREDIV_SHIFT));
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
- mdelay(1);
+
+ /* Wait max 20 ms */
+ timeout = ktime_add_ms(ktime_get(), 20);
+ while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
+ if (ktime_after(ktime_get(), timeout)) {
+ pr_err("%s: Internal clock never stabilised.\n",
+ mmc_hostname(host->mmc));
+ return;
+ }
+ udelay(10);
+ }
+
+ temp |= ESDHC_CLOCK_SDCLKEN;
+ sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
}
static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
@@ -501,12 +568,136 @@ static void esdhc_pltfm_set_bus_width(st
sdhci_writel(host, ctrl, ESDHC_PROCTL);
}
+static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
+{
+ u32 val;
+ ktime_t timeout;
+
+ val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+
+ if (enable)
+ val |= ESDHC_CLOCK_SDCLKEN;
+ else
+ val &= ~ESDHC_CLOCK_SDCLKEN;
+
+ sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
+
+ /* Wait max 20 ms */
+ timeout = ktime_add_ms(ktime_get(), 20);
+ val = ESDHC_CLOCK_STABLE;
+ while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
+ if (ktime_after(ktime_get(), timeout)) {
+ pr_err("%s: Internal clock never stabilised.\n",
+ mmc_hostname(host->mmc));
+ break;
+ }
+ udelay(10);
+ }
+}
+
static void esdhc_reset(struct sdhci_host *host, u8 mask)
{
+ u32 val;
+
sdhci_reset(host, mask);
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+
+ if (mask & SDHCI_RESET_ALL) {
+ val = sdhci_readl(host, ESDHC_TBCTL);
+ val &= ~ESDHC_TB_EN;
+ sdhci_writel(host, val, ESDHC_TBCTL);
+ }
+}
+
+/* The SCFG, Supplemental Configuration Unit, provides SoC specific
+ * configuration and status registers for the device. There is a
+ * SDHC IO VSEL control register on SCFG for some platforms. It's
+ * used to support SDHC IO voltage switching.
+ */
+static const struct of_device_id scfg_device_ids[] = {
+ { .compatible = "fsl,t1040-scfg", },
+ { .compatible = "fsl,ls1012a-scfg", },
+ { .compatible = "fsl,ls1046a-scfg", },
+ {}
+};
+
+/* SDHC IO VSEL control register definition */
+#define SCFG_SDHCIOVSELCR 0x408
+#define SDHCIOVSELCR_TGLEN 0x80000000
+#define SDHCIOVSELCR_VSELVAL 0x60000000
+#define SDHCIOVSELCR_SDHC_VS 0x00000001
+
+static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
+ struct mmc_ios *ios)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ struct device_node *scfg_node;
+ void __iomem *scfg_base = NULL;
+ u32 sdhciovselcr;
+ u32 val;
+
+ /*
+ * Signal Voltage Switching is only applicable for Host Controllers
+ * v3.00 and above.
+ */
+ if (host->version < SDHCI_SPEC_300)
+ return 0;
+
+ val = sdhci_readl(host, ESDHC_PROCTL);
+
+ switch (ios->signal_voltage) {
+ case MMC_SIGNAL_VOLTAGE_330:
+ val &= ~ESDHC_VOLT_SEL;
+ sdhci_writel(host, val, ESDHC_PROCTL);
+ return 0;
+ case MMC_SIGNAL_VOLTAGE_180:
+ scfg_node = of_find_matching_node(NULL, scfg_device_ids);
+ if (scfg_node)
+ scfg_base = of_iomap(scfg_node, 0);
+ if (scfg_base) {
+ sdhciovselcr = SDHCIOVSELCR_TGLEN |
+ SDHCIOVSELCR_VSELVAL;
+ iowrite32be(sdhciovselcr,
+ scfg_base + SCFG_SDHCIOVSELCR);
+
+ val |= ESDHC_VOLT_SEL;
+ sdhci_writel(host, val, ESDHC_PROCTL);
+ mdelay(5);
+
+ sdhciovselcr = SDHCIOVSELCR_TGLEN |
+ SDHCIOVSELCR_SDHC_VS;
+ iowrite32be(sdhciovselcr,
+ scfg_base + SCFG_SDHCIOVSELCR);
+ iounmap(scfg_base);
+ } else {
+ val |= ESDHC_VOLT_SEL;
+ sdhci_writel(host, val, ESDHC_PROCTL);
+ }
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ u32 val;
+
+ /* Use tuning block for tuning procedure */
+ esdhc_clock_enable(host, false);
+ val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+ val |= ESDHC_FLUSH_ASYNC_FIFO;
+ sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
+
+ val = sdhci_readl(host, ESDHC_TBCTL);
+ val |= ESDHC_TB_EN;
+ sdhci_writel(host, val, ESDHC_TBCTL);
+ esdhc_clock_enable(host, true);
+
+ return sdhci_execute_tuning(mmc, opcode);
}
#ifdef CONFIG_PM_SLEEP
@@ -589,10 +780,19 @@ static const struct sdhci_pltfm_data sdh
.ops = &sdhci_esdhc_le_ops,
};
+static struct soc_device_attribute soc_incorrect_hostver[] = {
+ { .family = "QorIQ T4240", .revision = "1.0", },
+ { .family = "QorIQ T4240", .revision = "2.0", },
+ { },
+};
+
static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_esdhc *esdhc;
+ struct device_node *np;
+ struct clk *clk;
+ u32 val;
u16 host_ver;
pltfm_host = sdhci_priv(host);
@@ -602,6 +802,36 @@ static void esdhc_init(struct platform_d
esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
SDHCI_VENDOR_VER_SHIFT;
esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
+ if (soc_device_match(soc_incorrect_hostver))
+ esdhc->quirk_incorrect_hostver = true;
+ else
+ esdhc->quirk_incorrect_hostver = false;
+
+ np = pdev->dev.of_node;
+ clk = of_clk_get(np, 0);
+ if (!IS_ERR(clk)) {
+ /*
+ * esdhc->peripheral_clock would be assigned with a value
+ * which is eSDHC base clock when use periperal clock.
+ * For ls1046a, the clock value got by common clk API is
+ * peripheral clock while the eSDHC base clock is 1/2
+ * peripheral clock.
+ */
+ if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
+ esdhc->peripheral_clock = clk_get_rate(clk) / 2;
+ else
+ esdhc->peripheral_clock = clk_get_rate(clk);
+
+ clk_put(clk);
+ }
+
+ if (esdhc->peripheral_clock) {
+ esdhc_clock_enable(host, false);
+ val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+ val |= ESDHC_PERIPHERAL_CLK_SEL;
+ sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
+ esdhc_clock_enable(host, true);
+ }
}
static int sdhci_esdhc_probe(struct platform_device *pdev)
@@ -624,6 +854,11 @@ static int sdhci_esdhc_probe(struct plat
if (IS_ERR(host))
return PTR_ERR(host);
+ host->mmc_host_ops.start_signal_voltage_switch =
+ esdhc_signal_voltage_switch;
+ host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
+ host->tuning_delay = 1;
+
esdhc_init(pdev, host);
sdhci_get_of_property(pdev);
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1631,26 +1631,24 @@ static void sdhci_set_ios(struct mmc_hos
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
- if ((ios->timing == MMC_TIMING_SD_HS ||
- ios->timing == MMC_TIMING_MMC_HS)
- && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
- ctrl |= SDHCI_CTRL_HISPD;
- else
- ctrl &= ~SDHCI_CTRL_HISPD;
+ if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) {
+ if ((ios->timing == MMC_TIMING_SD_HS ||
+ ios->timing == MMC_TIMING_MMC_HS ||
+ ios->timing == MMC_TIMING_MMC_HS400 ||
+ ios->timing == MMC_TIMING_MMC_HS200 ||
+ ios->timing == MMC_TIMING_MMC_DDR52 ||
+ ios->timing == MMC_TIMING_UHS_SDR50 ||
+ ios->timing == MMC_TIMING_UHS_SDR104 ||
+ ios->timing == MMC_TIMING_UHS_DDR50 ||
+ ios->timing == MMC_TIMING_UHS_SDR25))
+ ctrl |= SDHCI_CTRL_HISPD;
+ else
+ ctrl &= ~SDHCI_CTRL_HISPD;
+ }
if (host->version >= SDHCI_SPEC_300) {
u16 clk, ctrl_2;
- /* In case of UHS-I modes, set High Speed Enable */
- if ((ios->timing == MMC_TIMING_MMC_HS400) ||
- (ios->timing == MMC_TIMING_MMC_HS200) ||
- (ios->timing == MMC_TIMING_MMC_DDR52) ||
- (ios->timing == MMC_TIMING_UHS_SDR50) ||
- (ios->timing == MMC_TIMING_UHS_SDR104) ||
- (ios->timing == MMC_TIMING_UHS_DDR50) ||
- (ios->timing == MMC_TIMING_UHS_SDR25))
- ctrl |= SDHCI_CTRL_HISPD;
-
if (!host->preset_enabled) {
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/*
@@ -1963,7 +1961,7 @@ static int sdhci_prepare_hs400_tuning(st
return 0;
}
-static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
+int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct sdhci_host *host = mmc_priv(mmc);
u16 ctrl;
@@ -2022,6 +2020,9 @@ static int sdhci_execute_tuning(struct m
return err;
}
+ if (host->tuning_delay < 0)
+ host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK;
+
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
ctrl |= SDHCI_CTRL_EXEC_TUNING;
if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND)
@@ -2134,9 +2135,10 @@ static int sdhci_execute_tuning(struct m
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- /* eMMC spec does not require a delay between tuning cycles */
- if (opcode == MMC_SEND_TUNING_BLOCK)
- mdelay(1);
+ /* Spec does not require a delay between tuning cycles */
+ if (host->tuning_delay > 0)
+ mdelay(host->tuning_delay);
+
} while (ctrl & SDHCI_CTRL_EXEC_TUNING);
/*
@@ -2172,6 +2174,7 @@ out_unlock:
spin_unlock_irqrestore(&host->lock, flags);
return err;
}
+EXPORT_SYMBOL_GPL(sdhci_execute_tuning);
static int sdhci_select_drive_strength(struct mmc_card *card,
unsigned int max_dtr, int host_drv,
@@ -3004,6 +3007,8 @@ struct sdhci_host *sdhci_alloc_host(stru
host->flags = SDHCI_SIGNALING_330;
+ host->tuning_delay = -1;
+
return host;
}
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -524,6 +524,8 @@ struct sdhci_host {
#define SDHCI_TUNING_MODE_1 0
#define SDHCI_TUNING_MODE_2 1
#define SDHCI_TUNING_MODE_3 2
+ /* Delay (ms) between tuning commands */
+ int tuning_delay;
unsigned long private[0] ____cacheline_aligned;
};
@@ -689,6 +691,7 @@ void sdhci_set_power_noreg(struct sdhci_
void sdhci_set_bus_width(struct sdhci_host *host, int width);
void sdhci_reset(struct sdhci_host *host, u8 mask);
void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
+int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
#ifdef CONFIG_PM
extern int sdhci_suspend_host(struct sdhci_host *host);

View File

@ -1,682 +0,0 @@
From bda12381598c3df43f4e60362a8cd4af58b7f5b0 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:38:54 +0800
Subject: [PATCH 26/30] rtc: support layerscape
This is an integrated patch for layerscape rtc support.
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/rtc/rtc-pcf85263.c | 665 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 665 insertions(+)
create mode 100644 drivers/rtc/rtc-pcf85263.c
--- /dev/null
+++ b/drivers/rtc/rtc-pcf85263.c
@@ -0,0 +1,665 @@
+/*
+ * rtc-pcf85263 Driver for the NXP PCF85263 RTC
+ * Copyright 2016 Parkeon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/rtc.h>
+#include <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+
+#define DRV_NAME "rtc-pcf85263"
+
+/* Quartz capacitance */
+#define PCF85263_QUARTZCAP_7pF 0
+#define PCF85263_QUARTZCAP_6pF 1
+#define PCF85263_QUARTZCAP_12p5pF 2
+
+/* Quartz drive strength */
+#define PCF85263_QUARTZDRIVE_NORMAL 0
+#define PCF85263_QUARTZDRIVE_LOW 1
+#define PCF85263_QUARTZDRIVE_HIGH 2
+
+
+#define PCF85263_REG_RTC_SC 0x01 /* Seconds */
+#define PCF85263_REG_RTC_SC_OS BIT(7) /* Oscilator stopped flag */
+
+#define PCF85263_REG_RTC_MN 0x02 /* Minutes */
+#define PCF85263_REG_RTC_HR 0x03 /* Hours */
+#define PCF85263_REG_RTC_DT 0x04 /* Day of month 1-31 */
+#define PCF85263_REG_RTC_DW 0x05 /* Day of week 0-6 */
+#define PCF85263_REG_RTC_MO 0x06 /* Month 1-12 */
+#define PCF85263_REG_RTC_YR 0x07 /* Year 0-99 */
+
+#define PCF85263_REG_ALM1_SC 0x08 /* Seconds */
+#define PCF85263_REG_ALM1_MN 0x09 /* Minutes */
+#define PCF85263_REG_ALM1_HR 0x0a /* Hours */
+#define PCF85263_REG_ALM1_DT 0x0b /* Day of month 1-31 */
+#define PCF85263_REG_ALM1_MO 0x0c /* Month 1-12 */
+
+#define PCF85263_REG_ALM_CTL 0x10
+#define PCF85263_REG_ALM_CTL_ALL_A1E 0x1f /* sec,min,hr,day,mon alarm 1 */
+
+#define PCF85263_REG_OSC 0x25
+#define PCF85263_REG_OSC_CL_MASK (BIT(0) | BIT(1))
+#define PCF85263_REG_OSC_CL_SHIFT 0
+#define PCF85263_REG_OSC_OSCD_MASK (BIT(2) | BIT(3))
+#define PCF85263_REG_OSC_OSCD_SHIFT 2
+#define PCF85263_REG_OSC_LOWJ BIT(4)
+#define PCF85263_REG_OSC_12H BIT(5)
+
+#define PCF85263_REG_PINIO 0x27
+#define PCF85263_REG_PINIO_INTAPM_MASK (BIT(0) | BIT(1))
+#define PCF85263_REG_PINIO_INTAPM_SHIFT 0
+#define PCF85263_INTAPM_INTA (0x2 << PCF85263_REG_PINIO_INTAPM_SHIFT)
+#define PCF85263_INTAPM_HIGHZ (0x3 << PCF85263_REG_PINIO_INTAPM_SHIFT)
+#define PCF85263_REG_PINIO_TSPM_MASK (BIT(2) | BIT(3))
+#define PCF85263_REG_PINIO_TSPM_SHIFT 2
+#define PCF85263_TSPM_DISABLED (0x0 << PCF85263_REG_PINIO_TSPM_SHIFT)
+#define PCF85263_TSPM_INTB (0x1 << PCF85263_REG_PINIO_TSPM_SHIFT)
+#define PCF85263_REG_PINIO_CLKDISABLE BIT(7)
+
+#define PCF85263_REG_FUNCTION 0x28
+#define PCF85263_REG_FUNCTION_COF_MASK 0x7
+#define PCF85263_REG_FUNCTION_COF_OFF 0x7 /* No clock output */
+
+#define PCF85263_REG_INTA_CTL 0x29
+#define PCF85263_REG_INTB_CTL 0x2A
+#define PCF85263_REG_INTx_CTL_A1E BIT(4) /* Alarm 1 */
+#define PCF85263_REG_INTx_CTL_ILP BIT(7) /* 0=pulse, 1=level */
+
+#define PCF85263_REG_FLAGS 0x2B
+#define PCF85263_REG_FLAGS_A1F BIT(5)
+
+#define PCF85263_REG_RAM_BYTE 0x2c
+
+#define PCF85263_REG_STOPENABLE 0x2e
+#define PCF85263_REG_STOPENABLE_STOP BIT(0)
+
+#define PCF85263_REG_RESET 0x2f /* Reset command */
+#define PCF85263_REG_RESET_CMD_CPR 0xa4 /* Clear prescaler */
+
+#define PCF85263_MAX_REG 0x2f
+
+#define PCF85263_HR_PM BIT(5)
+
+enum pcf85263_irqpin {
+ PCF85263_IRQPIN_NONE,
+ PCF85263_IRQPIN_INTA,
+ PCF85263_IRQPIN_INTB
+};
+
+static const char *const pcf85263_irqpin_names[] = {
+ [PCF85263_IRQPIN_NONE] = "None",
+ [PCF85263_IRQPIN_INTA] = "INTA",
+ [PCF85263_IRQPIN_INTB] = "INTB"
+};
+
+struct pcf85263 {
+ struct device *dev;
+ struct rtc_device *rtc;
+ struct regmap *regmap;
+ enum pcf85263_irqpin irq_pin;
+ int irq;
+ bool mode_12h;
+};
+
+/*
+ * Helpers to convert 12h to 24h and vice versa.
+ * Values in register are stored in BCD with a PM flag in bit 5
+ *
+ * 23:00 <=> 11PM <=> 0x31
+ * 00:00 <=> 12AM <=> 0x12
+ * 01:00 <=> 1AM <=> 0x01
+ * 12:00 <=> 12PM <=> 0x32
+ * 13:00 <=> 1PM <=> 0x21
+ */
+static int pcf85263_bcd12h_to_bin24h(int regval)
+{
+ int hr = bcd2bin(regval & 0x1f);
+ bool pm = regval & PCF85263_HR_PM;
+
+ if (hr == 12)
+ return pm ? 12 : 0;
+
+ return pm ? hr + 12 : hr;
+}
+
+static int pcf85263_bin24h_to_bcd12h(int hr24)
+{
+ bool pm = hr24 >= 12;
+ int hr12 = hr24 % 12;
+
+ if (!hr12)
+ hr12++;
+
+ return bin2bcd(hr12) | pm ? 0 : PCF85263_HR_PM;
+}
+
+static int pcf85263_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+ const int first = PCF85263_REG_RTC_SC;
+ const int last = PCF85263_REG_RTC_YR;
+ const int len = last - first + 1;
+ u8 regs[len];
+ u8 hr_reg;
+ int ret;
+
+ ret = regmap_bulk_read(pcf85263->regmap, first, regs, len);
+ if (ret)
+ return ret;
+
+ if (regs[PCF85263_REG_RTC_SC - first] & PCF85263_REG_RTC_SC_OS) {
+ dev_warn(dev, "Oscillator stop detected, date/time is not reliable.\n");
+ return -EINVAL;
+ }
+
+ tm->tm_sec = bcd2bin(regs[PCF85263_REG_RTC_SC - first] & 0x7f);
+ tm->tm_min = bcd2bin(regs[PCF85263_REG_RTC_MN - first] & 0x7f);
+
+ hr_reg = regs[PCF85263_REG_RTC_HR - first];
+ if (pcf85263->mode_12h)
+ tm->tm_hour = pcf85263_bcd12h_to_bin24h(hr_reg);
+ else
+ tm->tm_hour = bcd2bin(hr_reg & 0x3f);
+
+ tm->tm_mday = bcd2bin(regs[PCF85263_REG_RTC_DT - first]);
+ tm->tm_wday = bcd2bin(regs[PCF85263_REG_RTC_DW - first]);
+ tm->tm_mon = bcd2bin(regs[PCF85263_REG_RTC_MO - first]) - 1;
+ tm->tm_year = bcd2bin(regs[PCF85263_REG_RTC_YR - first]);
+
+ tm->tm_year += 100; /* Assume 21st century */
+
+ return 0;
+}
+
+static int pcf85263_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+
+ /*
+ * Before setting time need to stop RTC and disable prescaler
+ * Do this all in a single I2C transaction exploiting wraparound
+ * as described in data sheet.
+ * This means that the array below must be in register order
+ */
+ u8 regs[] = {
+ PCF85263_REG_STOPENABLE_STOP, /* STOP */
+ PCF85263_REG_RESET_CMD_CPR, /* Disable prescaler */
+ /* Wrap around to register 0 (1/100s) */
+ 0, /* 1/100s always zero. */
+ bin2bcd(tm->tm_sec),
+ bin2bcd(tm->tm_min),
+ bin2bcd(tm->tm_hour), /* 24-hour */
+ bin2bcd(tm->tm_mday),
+ bin2bcd(tm->tm_wday + 1),
+ bin2bcd(tm->tm_mon + 1),
+ bin2bcd(tm->tm_year % 100)
+ };
+ int ret;
+
+ ret = regmap_bulk_write(pcf85263->regmap, PCF85263_REG_STOPENABLE,
+ regs, sizeof(regs));
+ if (ret)
+ return ret;
+
+ /* As we have set the time in 24H update the hardware for that */
+ if (pcf85263->mode_12h) {
+ pcf85263->mode_12h = false;
+ ret = regmap_update_bits(pcf85263->regmap, PCF85263_REG_OSC,
+ PCF85263_REG_OSC_12H, 0);
+ if (ret)
+ return ret;
+ }
+
+ /* Start it again */
+ return regmap_write(pcf85263->regmap, PCF85263_REG_STOPENABLE, 0);
+}
+
+static int pcf85263_enable_alarm(struct pcf85263 *pcf85263, bool enable)
+{
+ int reg;
+ int ret;
+
+ ret = regmap_update_bits(pcf85263->regmap, PCF85263_REG_ALM_CTL,
+ PCF85263_REG_ALM_CTL_ALL_A1E,
+ enable ? PCF85263_REG_ALM_CTL_ALL_A1E : 0);
+ if (ret)
+ return ret;
+
+ switch (pcf85263->irq_pin) {
+ case PCF85263_IRQPIN_NONE:
+ return 0;
+
+ case PCF85263_IRQPIN_INTA:
+ reg = PCF85263_REG_INTA_CTL;
+ break;
+
+ case PCF85263_IRQPIN_INTB:
+ reg = PCF85263_REG_INTB_CTL;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return regmap_update_bits(pcf85263->regmap, reg,
+ PCF85263_REG_INTx_CTL_A1E,
+ enable ? PCF85263_REG_INTx_CTL_A1E : 0);
+}
+
+static int pcf85263_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+ struct rtc_time *tm = &alarm->time;
+ const int first = PCF85263_REG_ALM1_SC;
+ const int last = PCF85263_REG_ALM1_MO;
+ const int len = last - first + 1;
+ u8 regs[len];
+ u8 hr_reg;
+ unsigned int regval;
+ int ret;
+
+ ret = regmap_bulk_read(pcf85263->regmap, first, regs, len);
+ if (ret)
+ return ret;
+
+ tm->tm_sec = bcd2bin(regs[PCF85263_REG_ALM1_SC - first] & 0x7f);
+ tm->tm_min = bcd2bin(regs[PCF85263_REG_ALM1_MN - first] & 0x7f);
+
+ hr_reg = regs[PCF85263_REG_ALM1_HR - first];
+ if (pcf85263->mode_12h)
+ tm->tm_hour = pcf85263_bcd12h_to_bin24h(hr_reg);
+ else
+ tm->tm_hour = bcd2bin(hr_reg & 0x3f);
+
+ tm->tm_mday = bcd2bin(regs[PCF85263_REG_ALM1_DT - first]);
+ tm->tm_mon = bcd2bin(regs[PCF85263_REG_ALM1_MO - first]) - 1;
+ tm->tm_year = -1;
+ tm->tm_wday = -1;
+
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_ALM_CTL, &regval);
+ if (ret)
+ return ret;
+ alarm->enabled = !!(regval & PCF85263_REG_ALM_CTL_ALL_A1E);
+
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_FLAGS, &regval);
+ if (ret)
+ return ret;
+ alarm->pending = !!(regval & PCF85263_REG_FLAGS_A1F);
+
+ return 0;
+}
+
+static int pcf85263_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+ struct rtc_time *tm = &alarm->time;
+ const int first = PCF85263_REG_ALM1_SC;
+ const int last = PCF85263_REG_ALM1_MO;
+ const int len = last - first + 1;
+ u8 regs[len];
+ int ret;
+
+ /* Disable alarm comparison during update */
+ ret = pcf85263_enable_alarm(pcf85263, false);
+ if (ret)
+ return ret;
+
+ /* Clear any pending alarm (write 0=>clr, 1=>no change) */
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_FLAGS,
+ (unsigned int)(~PCF85263_REG_FLAGS_A1F));
+ if (ret)
+ return ret;
+
+ /* Set the alarm time registers */
+ regs[PCF85263_REG_ALM1_SC - first] = bin2bcd(tm->tm_sec);
+ regs[PCF85263_REG_ALM1_MN - first] = bin2bcd(tm->tm_min);
+ regs[PCF85263_REG_ALM1_HR - first] = pcf85263->mode_12h ?
+ pcf85263_bin24h_to_bcd12h(tm->tm_hour) :
+ bin2bcd(tm->tm_hour);
+ regs[PCF85263_REG_ALM1_DT - first] = bin2bcd(tm->tm_mday);
+ regs[PCF85263_REG_ALM1_MO - first] = bin2bcd(tm->tm_mon + 1);
+
+ ret = regmap_bulk_write(pcf85263->regmap, first, regs, sizeof(regs));
+ if (ret)
+ return ret;
+
+ if (alarm->enabled)
+ ret = pcf85263_enable_alarm(pcf85263, true);
+
+ return ret;
+}
+
+static int pcf85263_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+
+ return pcf85263_enable_alarm(pcf85263, !!enable);
+}
+
+static irqreturn_t pcf85263_irq(int irq, void *data)
+{
+ struct pcf85263 *pcf85263 = data;
+ unsigned int regval;
+ int ret;
+
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_FLAGS, &regval);
+ if (ret)
+ return IRQ_NONE;
+
+ if (regval & PCF85263_REG_FLAGS_A1F) {
+ regmap_write(pcf85263->regmap, PCF85263_REG_FLAGS,
+ (unsigned int)(~PCF85263_REG_FLAGS_A1F));
+
+ rtc_update_irq(pcf85263->rtc, 1, RTC_IRQF | RTC_AF);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int pcf85263_check_osc_stopped(struct pcf85263 *pcf85263)
+{
+ unsigned int regval;
+ int ret;
+
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_RTC_SC, &regval);
+ if (ret)
+ return ret;
+
+ ret = regval & PCF85263_REG_RTC_SC_OS ? 1 : 0;
+ if (ret)
+ dev_warn(pcf85263->dev, "Oscillator stop detected, date/time is not reliable.\n");
+
+ return ret;
+}
+
+#ifdef CONFIG_RTC_INTF_DEV
+static int pcf85263_ioctl(struct device *dev,
+ unsigned int cmd, unsigned long arg)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+ int ret;
+
+ switch (cmd) {
+ case RTC_VL_READ:
+ ret = pcf85263_check_osc_stopped(pcf85263);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
+ return -EFAULT;
+ return 0;
+
+ case RTC_VL_CLR:
+ return regmap_update_bits(pcf85263->regmap,
+ PCF85263_REG_RTC_SC,
+ PCF85263_REG_RTC_SC_OS, 0);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+#else
+#define pcf85263_ioctl NULL
+#endif
+
+static int pcf85263_init_hw(struct pcf85263 *pcf85263)
+{
+ struct device_node *np = pcf85263->dev->of_node;
+ unsigned int regval;
+ u32 propval;
+ int ret;
+
+ /* Determine if oscilator has been stopped (probably low power) */
+ ret = pcf85263_check_osc_stopped(pcf85263);
+ if (ret < 0) {
+ /* Log here since this is the first hw access on probe */
+ dev_err(pcf85263->dev, "Unable to read register\n");
+
+ return ret;
+ }
+
+ /* Determine 12/24H mode */
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_OSC, &regval);
+ if (ret)
+ return ret;
+ pcf85263->mode_12h = !!(regval & PCF85263_REG_OSC_12H);
+
+ /* Set oscilator register */
+ regval &= ~PCF85263_REG_OSC_12H; /* keep current 12/24 h setting */
+
+ propval = PCF85263_QUARTZCAP_12p5pF;
+ of_property_read_u32(np, "quartz-load-capacitance", &propval);
+ regval |= ((propval << PCF85263_REG_OSC_CL_SHIFT)
+ & PCF85263_REG_OSC_CL_MASK);
+
+ propval = PCF85263_QUARTZDRIVE_NORMAL;
+ of_property_read_u32(np, "quartz-drive-strength", &propval);
+ regval |= ((propval << PCF85263_REG_OSC_OSCD_SHIFT)
+ & PCF85263_REG_OSC_OSCD_MASK);
+
+ if (of_property_read_bool(np, "quartz-low-jitter"))
+ regval |= PCF85263_REG_OSC_LOWJ;
+
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_OSC, regval);
+ if (ret)
+ return ret;
+
+ /* Set function register (RTC mode, 1s tick, clock output static) */
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_FUNCTION,
+ PCF85263_REG_FUNCTION_COF_OFF);
+ if (ret)
+ return ret;
+
+ /* Set all interrupts to disabled, level mode */
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_INTA_CTL,
+ PCF85263_REG_INTx_CTL_ILP);
+ if (ret)
+ return ret;
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_INTB_CTL,
+ PCF85263_REG_INTx_CTL_ILP);
+ if (ret)
+ return ret;
+
+ /* Setup IO pin config register */
+ regval = PCF85263_REG_PINIO_CLKDISABLE;
+ switch (pcf85263->irq_pin) {
+ case PCF85263_IRQPIN_INTA:
+ regval |= (PCF85263_INTAPM_INTA | PCF85263_TSPM_DISABLED);
+ break;
+ case PCF85263_IRQPIN_INTB:
+ regval |= (PCF85263_INTAPM_HIGHZ | PCF85263_TSPM_INTB);
+ break;
+ case PCF85263_IRQPIN_NONE:
+ regval |= (PCF85263_INTAPM_HIGHZ | PCF85263_TSPM_DISABLED);
+ break;
+ }
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_PINIO, regval);
+
+ return ret;
+}
+
+static const struct rtc_class_ops rtc_ops = {
+ .ioctl = pcf85263_ioctl,
+ .read_time = pcf85263_read_time,
+ .set_time = pcf85263_set_time,
+ .read_alarm = pcf85263_read_alarm,
+ .set_alarm = pcf85263_set_alarm,
+ .alarm_irq_enable = pcf85263_alarm_irq_enable,
+};
+
+static const struct regmap_config pcf85263_regmap_cfg = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = PCF85263_MAX_REG,
+};
+
+/*
+ * On some boards the interrupt line may not be wired to the CPU but only to
+ * a power supply circuit.
+ * In that case no interrupt will be specified in the device tree but the
+ * wakeup-source DT property may be used to enable wakeup programming in
+ * sysfs
+ */
+static bool pcf85263_can_wakeup_machine(struct pcf85263 *pcf85263)
+{
+ return pcf85263->irq ||
+ of_property_read_bool(pcf85263->dev->of_node, "wakeup-source");
+}
+
+static int pcf85263_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct pcf85263 *pcf85263;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+ I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -ENODEV;
+
+ pcf85263 = devm_kzalloc(dev, sizeof(*pcf85263), GFP_KERNEL);
+ if (!pcf85263)
+ return -ENOMEM;
+
+ pcf85263->dev = dev;
+ pcf85263->irq = client->irq;
+ dev_set_drvdata(dev, pcf85263);
+
+ pcf85263->regmap = devm_regmap_init_i2c(client, &pcf85263_regmap_cfg);
+ if (IS_ERR(pcf85263->regmap)) {
+ ret = PTR_ERR(pcf85263->regmap);
+ dev_err(dev, "regmap allocation failed (%d)\n", ret);
+
+ return ret;
+ }
+
+ /* Determine which interrupt pin the board uses */
+ if (pcf85263_can_wakeup_machine(pcf85263)) {
+ if (of_property_match_string(dev->of_node,
+ "interrupt-names", "INTB") >= 0)
+ pcf85263->irq_pin = PCF85263_IRQPIN_INTB;
+ else
+ pcf85263->irq_pin = PCF85263_IRQPIN_INTA;
+ } else {
+ pcf85263->irq_pin = PCF85263_IRQPIN_NONE;
+ }
+
+ ret = pcf85263_init_hw(pcf85263);
+ if (ret)
+ return ret;
+
+ if (pcf85263->irq) {
+ ret = devm_request_threaded_irq(dev, pcf85263->irq, NULL,
+ pcf85263_irq,
+ IRQF_ONESHOT,
+ dev->driver->name, pcf85263);
+ if (ret) {
+ dev_err(dev, "irq %d unavailable (%d)\n",
+ pcf85263->irq, ret);
+ pcf85263->irq = 0;
+ }
+ }
+
+ if (pcf85263_can_wakeup_machine(pcf85263))
+ device_init_wakeup(dev, true);
+
+ pcf85263->rtc = devm_rtc_device_register(dev, dev->driver->name,
+ &rtc_ops, THIS_MODULE);
+ ret = PTR_ERR_OR_ZERO(pcf85263->rtc);
+ if (ret)
+ return ret;
+
+ /* We cannot support UIE mode if we do not have an IRQ line */
+ if (!pcf85263->irq)
+ pcf85263->rtc->uie_unsupported = 1;
+
+ dev_info(pcf85263->dev,
+ "PCF85263 RTC (irqpin=%s irq=%d)\n",
+ pcf85263_irqpin_names[pcf85263->irq_pin],
+ pcf85263->irq);
+
+ return 0;
+}
+
+static int pcf85263_remove(struct i2c_client *client)
+{
+ struct pcf85263 *pcf85263 = i2c_get_clientdata(client);
+
+ if (pcf85263_can_wakeup_machine(pcf85263))
+ device_init_wakeup(pcf85263->dev, false);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pcf85263_suspend(struct device *dev)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (device_may_wakeup(dev))
+ ret = enable_irq_wake(pcf85263->irq);
+
+ return ret;
+}
+
+static int pcf85263_resume(struct device *dev)
+{
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (device_may_wakeup(dev))
+ ret = disable_irq_wake(pcf85263->irq);
+
+ return ret;
+}
+
+#endif
+
+static const struct i2c_device_id pcf85263_id[] = {
+ { "pcf85263", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, pcf85263_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id pcf85263_of_match[] = {
+ { .compatible = "nxp,pcf85263" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, pcf85263_of_match);
+#endif
+
+static SIMPLE_DEV_PM_OPS(pcf85263_pm_ops, pcf85263_suspend, pcf85263_resume);
+
+static struct i2c_driver pcf85263_driver = {
+ .driver = {
+ .name = "rtc-pcf85263",
+ .of_match_table = of_match_ptr(pcf85263_of_match),
+ .pm = &pcf85263_pm_ops,
+ },
+ .probe = pcf85263_probe,
+ .remove = pcf85263_remove,
+ .id_table = pcf85263_id,
+};
+
+module_i2c_driver(pcf85263_driver);
+
+MODULE_AUTHOR("Martin Fuzzey <mfuzzey@parkeon.com>");
+MODULE_DESCRIPTION("PCF85263 RTC Driver");
+MODULE_LICENSE("GPL");
+

View File

@ -1,427 +0,0 @@
From 027b679f248f15dea36c6cd6782d6643e2151057 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:39:43 +0800
Subject: [PATCH 27/30] spi: support layerscape
This is an integrated patch for layerscape dspi support.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/spi/spi-fsl-dspi.c | 309 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 304 insertions(+), 5 deletions(-)
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
@@ -40,6 +42,7 @@
#define TRAN_STATE_WORD_ODD_NUM 0x04
#define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024)
#define SPI_MCR 0x00
#define SPI_MCR_MASTER (1 << 31)
@@ -72,6 +75,11 @@
#define SPI_SR_TCFQF 0x80000000
#define SPI_SR_CLEAR 0xdaad0000
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
#define SPI_RSER 0x30
#define SPI_RSER_EOQFE 0x10000000
#define SPI_RSER_TCFQE 0x80000000
@@ -109,6 +117,8 @@
#define SPI_TCR_TCNT_MAX 0x10000
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -118,6 +128,7 @@ struct chip_data {
enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+ DSPI_DMA_MODE,
};
struct fsl_dspi_devtype_data {
@@ -126,7 +137,7 @@ struct fsl_dspi_devtype_data {
};
static const struct fsl_dspi_devtype_data vf610_data = {
- .trans_mode = DSPI_EOQ_MODE,
+ .trans_mode = DSPI_DMA_MODE,
.max_clock_factor = 2,
};
@@ -140,6 +151,23 @@ static const struct fsl_dspi_devtype_dat
.max_clock_factor = 8,
};
+struct fsl_dspi_dma {
+ /* Length of transfer in words of DSPI_FIFO_SIZE */
+ u32 curr_xfer_len;
+
+ u32 *tx_dma_buf;
+ struct dma_chan *chan_tx;
+ dma_addr_t tx_dma_phys;
+ struct completion cmd_tx_complete;
+ struct dma_async_tx_descriptor *tx_desc;
+
+ u32 *rx_dma_buf;
+ struct dma_chan *chan_rx;
+ dma_addr_t rx_dma_phys;
+ struct completion cmd_rx_complete;
+ struct dma_async_tx_descriptor *rx_desc;
+};
+
struct fsl_dspi {
struct spi_master *master;
struct platform_device *pdev;
@@ -166,8 +194,11 @@ struct fsl_dspi {
u32 waitflags;
u32 spi_tcnt;
+ struct fsl_dspi_dma *dma;
};
+static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word);
+
static inline int is_double_byte_mode(struct fsl_dspi *dspi)
{
unsigned int val;
@@ -177,6 +208,255 @@ static inline int is_double_byte_mode(st
return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
}
+static void dspi_tx_dma_callback(void *arg)
+{
+ struct fsl_dspi *dspi = arg;
+ struct fsl_dspi_dma *dma = dspi->dma;
+
+ complete(&dma->cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+ struct fsl_dspi *dspi = arg;
+ struct fsl_dspi_dma *dma = dspi->dma;
+ int rx_word;
+ int i;
+ u16 d;
+
+ rx_word = is_double_byte_mode(dspi);
+
+ if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+ for (i = 0; i < dma->curr_xfer_len; i++) {
+ d = dspi->dma->rx_dma_buf[i];
+ rx_word ? (*(u16 *)dspi->rx = d) :
+ (*(u8 *)dspi->rx = d);
+ dspi->rx += rx_word + 1;
+ }
+ }
+
+ complete(&dma->cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+ struct fsl_dspi_dma *dma = dspi->dma;
+ struct device *dev = &dspi->pdev->dev;
+ int time_left;
+ int tx_word;
+ int i;
+
+ tx_word = is_double_byte_mode(dspi);
+
+ for (i = 0; i < dma->curr_xfer_len; i++) {
+ dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word);
+ if ((dspi->cs_change) && (!dspi->len))
+ dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT;
+ }
+
+ dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
+ dma->tx_dma_phys,
+ dma->curr_xfer_len *
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma->tx_desc) {
+ dev_err(dev, "Not able to get desc for DMA xfer\n");
+ return -EIO;
+ }
+
+ dma->tx_desc->callback = dspi_tx_dma_callback;
+ dma->tx_desc->callback_param = dspi;
+ if (dma_submit_error(dmaengine_submit(dma->tx_desc))) {
+ dev_err(dev, "DMA submit failed\n");
+ return -EINVAL;
+ }
+
+ dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
+ dma->rx_dma_phys,
+ dma->curr_xfer_len *
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
+ DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma->rx_desc) {
+ dev_err(dev, "Not able to get desc for DMA xfer\n");
+ return -EIO;
+ }
+
+ dma->rx_desc->callback = dspi_rx_dma_callback;
+ dma->rx_desc->callback_param = dspi;
+ if (dma_submit_error(dmaengine_submit(dma->rx_desc))) {
+ dev_err(dev, "DMA submit failed\n");
+ return -EINVAL;
+ }
+
+ reinit_completion(&dspi->dma->cmd_rx_complete);
+ reinit_completion(&dspi->dma->cmd_tx_complete);
+
+ dma_async_issue_pending(dma->chan_rx);
+ dma_async_issue_pending(dma->chan_tx);
+
+ time_left = wait_for_completion_timeout(&dspi->dma->cmd_tx_complete,
+ DMA_COMPLETION_TIMEOUT);
+ if (time_left == 0) {
+ dev_err(dev, "DMA tx timeout\n");
+ dmaengine_terminate_all(dma->chan_tx);
+ dmaengine_terminate_all(dma->chan_rx);
+ return -ETIMEDOUT;
+ }
+
+ time_left = wait_for_completion_timeout(&dspi->dma->cmd_rx_complete,
+ DMA_COMPLETION_TIMEOUT);
+ if (time_left == 0) {
+ dev_err(dev, "DMA rx timeout\n");
+ dmaengine_terminate_all(dma->chan_tx);
+ dmaengine_terminate_all(dma->chan_rx);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int dspi_dma_xfer(struct fsl_dspi *dspi)
+{
+ struct fsl_dspi_dma *dma = dspi->dma;
+ struct device *dev = &dspi->pdev->dev;
+ int curr_remaining_bytes;
+ int bytes_per_buffer;
+ int word = 1;
+ int ret = 0;
+
+ if (is_double_byte_mode(dspi))
+ word = 2;
+ curr_remaining_bytes = dspi->len;
+ bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
+ while (curr_remaining_bytes) {
+ /* Check if current transfer fits the DMA buffer */
+ dma->curr_xfer_len = curr_remaining_bytes / word;
+ if (dma->curr_xfer_len > bytes_per_buffer)
+ dma->curr_xfer_len = bytes_per_buffer;
+
+ ret = dspi_next_xfer_dma_submit(dspi);
+ if (ret) {
+ dev_err(dev, "DMA transfer failed\n");
+ goto exit;
+
+ } else {
+ curr_remaining_bytes -= dma->curr_xfer_len * word;
+ if (curr_remaining_bytes < 0)
+ curr_remaining_bytes = 0;
+ }
+ }
+
+exit:
+ return ret;
+}
+
+static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
+{
+ struct fsl_dspi_dma *dma;
+ struct dma_slave_config cfg;
+ struct device *dev = &dspi->pdev->dev;
+ int ret;
+
+ dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
+ if (!dma)
+ return -ENOMEM;
+
+ dma->chan_rx = dma_request_slave_channel(dev, "rx");
+ if (!dma->chan_rx) {
+ dev_err(dev, "rx dma channel not available\n");
+ ret = -ENODEV;
+ return ret;
+ }
+
+ dma->chan_tx = dma_request_slave_channel(dev, "tx");
+ if (!dma->chan_tx) {
+ dev_err(dev, "tx dma channel not available\n");
+ ret = -ENODEV;
+ goto err_tx_channel;
+ }
+
+ dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
+ &dma->tx_dma_phys, GFP_KERNEL);
+ if (!dma->tx_dma_buf) {
+ ret = -ENOMEM;
+ goto err_tx_dma_buf;
+ }
+
+ dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
+ &dma->rx_dma_phys, GFP_KERNEL);
+ if (!dma->rx_dma_buf) {
+ ret = -ENOMEM;
+ goto err_rx_dma_buf;
+ }
+
+ cfg.src_addr = phy_addr + SPI_POPR;
+ cfg.dst_addr = phy_addr + SPI_PUSHR;
+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ cfg.src_maxburst = 1;
+ cfg.dst_maxburst = 1;
+
+ cfg.direction = DMA_DEV_TO_MEM;
+ ret = dmaengine_slave_config(dma->chan_rx, &cfg);
+ if (ret) {
+ dev_err(dev, "can't configure rx dma channel\n");
+ ret = -EINVAL;
+ goto err_slave_config;
+ }
+
+ cfg.direction = DMA_MEM_TO_DEV;
+ ret = dmaengine_slave_config(dma->chan_tx, &cfg);
+ if (ret) {
+ dev_err(dev, "can't configure tx dma channel\n");
+ ret = -EINVAL;
+ goto err_slave_config;
+ }
+
+ dspi->dma = dma;
+ init_completion(&dma->cmd_tx_complete);
+ init_completion(&dma->cmd_rx_complete);
+
+ return 0;
+
+err_slave_config:
+ dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+ dma->rx_dma_buf, dma->rx_dma_phys);
+err_rx_dma_buf:
+ dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+ dma->tx_dma_buf, dma->tx_dma_phys);
+err_tx_dma_buf:
+ dma_release_channel(dma->chan_tx);
+err_tx_channel:
+ dma_release_channel(dma->chan_rx);
+
+ devm_kfree(dev, dma);
+ dspi->dma = NULL;
+
+ return ret;
+}
+
+static void dspi_release_dma(struct fsl_dspi *dspi)
+{
+ struct fsl_dspi_dma *dma = dspi->dma;
+ struct device *dev = &dspi->pdev->dev;
+
+ if (dma) {
+ if (dma->chan_tx) {
+ dma_unmap_single(dev, dma->tx_dma_phys,
+ DSPI_DMA_BUFSIZE, DMA_TO_DEVICE);
+ dma_release_channel(dma->chan_tx);
+ }
+
+ if (dma->chan_rx) {
+ dma_unmap_single(dev, dma->rx_dma_phys,
+ DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE);
+ dma_release_channel(dma->chan_rx);
+ }
+ }
+}
+
static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
unsigned long clkrate)
{
@@ -425,6 +705,12 @@ static int dspi_transfer_one_message(str
regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE);
dspi_tcfq_write(dspi);
break;
+ case DSPI_DMA_MODE:
+ regmap_write(dspi->regmap, SPI_RSER,
+ SPI_RSER_TFFFE | SPI_RSER_TFFFD |
+ SPI_RSER_RFDFE | SPI_RSER_RFDFD);
+ status = dspi_dma_xfer(dspi);
+ break;
default:
dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n",
trans_mode);
@@ -432,9 +718,13 @@ static int dspi_transfer_one_message(str
goto out;
}
- if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
- dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n");
- dspi->waitflags = 0;
+ if (trans_mode != DSPI_DMA_MODE) {
+ if (wait_event_interruptible(dspi->waitq,
+ dspi->waitflags))
+ dev_err(&dspi->pdev->dev,
+ "wait transfer complete fail!\n");
+ dspi->waitflags = 0;
+ }
if (transfer->delay_usecs)
udelay(transfer->delay_usecs);
@@ -712,7 +1002,8 @@ static int dspi_probe(struct platform_de
if (IS_ERR(dspi->regmap)) {
dev_err(&pdev->dev, "failed to init regmap: %ld\n",
PTR_ERR(dspi->regmap));
- return PTR_ERR(dspi->regmap);
+ ret = PTR_ERR(dspi->regmap);
+ goto out_master_put;
}
dspi->clk = devm_clk_get(&pdev->dev, "dspi");
@@ -740,6 +1031,13 @@ static int dspi_probe(struct platform_de
goto out_clk_put;
}
+ if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
+ if (dspi_request_dma(dspi, res->start)) {
+ dev_err(&pdev->dev, "can't get dma channels\n");
+ goto out_clk_put;
+ }
+ }
+
master->max_speed_hz =
clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor;
@@ -768,6 +1066,7 @@ static int dspi_remove(struct platform_d
struct fsl_dspi *dspi = spi_master_get_devdata(master);
/* Disconnect from the SPI framework */
+ dspi_release_dma(dspi);
clk_disable_unprepare(dspi->clk);
spi_unregister_master(dspi->master);

View File

@ -1,162 +0,0 @@
From c35aec61e5bb0faafb2847a0d750ebd7345a4b0f Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 17 Jan 2018 15:40:24 +0800
Subject: [PATCH 28/30] tty: serial: support layerscape
This is an integrated patch for layerscape uart support.
Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/tty/serial/fsl_lpuart.c | 66 ++++++++++++++++++++++++++++-------------
1 file changed, 46 insertions(+), 20 deletions(-)
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -231,6 +231,8 @@
#define DEV_NAME "ttyLP"
#define UART_NR 6
+static DECLARE_BITMAP(linemap, UART_NR);
+
struct lpuart_port {
struct uart_port port;
struct clk *clk;
@@ -1349,6 +1351,18 @@ lpuart_set_termios(struct uart_port *por
/* ask the core to calculate the divisor */
baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
+ /*
+ * Need to update the Ring buffer length according to the selected
+ * baud rate and restart Rx DMA path.
+ *
+ * Since timer function acqures sport->port.lock, need to stop before
+ * acquring same lock because otherwise del_timer_sync() can deadlock.
+ */
+ if (old && sport->lpuart_dma_rx_use) {
+ del_timer_sync(&sport->lpuart_timer);
+ lpuart_dma_rx_free(&sport->port);
+ }
+
spin_lock_irqsave(&sport->port.lock, flags);
sport->port.read_status_mask = 0;
@@ -1398,22 +1412,11 @@ lpuart_set_termios(struct uart_port *por
/* restore control register */
writeb(old_cr2, sport->port.membase + UARTCR2);
- /*
- * If new baud rate is set, we will also need to update the Ring buffer
- * length according to the selected baud rate and restart Rx DMA path.
- */
- if (old) {
- if (sport->lpuart_dma_rx_use) {
- del_timer_sync(&sport->lpuart_timer);
- lpuart_dma_rx_free(&sport->port);
- }
-
- if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
- sport->lpuart_dma_rx_use = true;
+ if (old && sport->lpuart_dma_rx_use) {
+ if (!lpuart_start_rx_dma(sport))
rx_dma_timer_init(sport);
- } else {
+ else
sport->lpuart_dma_rx_use = false;
- }
}
spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1641,6 +1644,13 @@ lpuart_console_write(struct console *co,
{
struct lpuart_port *sport = lpuart_ports[co->index];
unsigned char old_cr2, cr2;
+ unsigned long flags;
+ int locked = 1;
+
+ if (sport->port.sysrq || oops_in_progress)
+ locked = spin_trylock_irqsave(&sport->port.lock, flags);
+ else
+ spin_lock_irqsave(&sport->port.lock, flags);
/* first save CR2 and then disable interrupts */
cr2 = old_cr2 = readb(sport->port.membase + UARTCR2);
@@ -1655,6 +1665,9 @@ lpuart_console_write(struct console *co,
barrier();
writeb(old_cr2, sport->port.membase + UARTCR2);
+
+ if (locked)
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
static void
@@ -1662,6 +1675,13 @@ lpuart32_console_write(struct console *c
{
struct lpuart_port *sport = lpuart_ports[co->index];
unsigned long old_cr, cr;
+ unsigned long flags;
+ int locked = 1;
+
+ if (sport->port.sysrq || oops_in_progress)
+ locked = spin_trylock_irqsave(&sport->port.lock, flags);
+ else
+ spin_lock_irqsave(&sport->port.lock, flags);
/* first save CR2 and then disable interrupts */
cr = old_cr = lpuart32_read(sport->port.membase + UARTCTRL);
@@ -1676,6 +1696,9 @@ lpuart32_console_write(struct console *c
barrier();
lpuart32_write(old_cr, sport->port.membase + UARTCTRL);
+
+ if (locked)
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
@@ -1900,13 +1923,13 @@ static int lpuart_probe(struct platform_
ret = of_alias_get_id(np, "serial");
if (ret < 0) {
- dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
- return ret;
- }
- if (ret >= ARRAY_SIZE(lpuart_ports)) {
- dev_err(&pdev->dev, "serial%d out of range\n", ret);
- return -EINVAL;
+ ret = find_first_zero_bit(linemap, UART_NR);
+ if (ret >= UART_NR) {
+ dev_err(&pdev->dev, "port line is full, add device failed\n");
+ return ret;
+ }
}
+ set_bit(ret, linemap);
sport->port.line = ret;
sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart");
@@ -1988,6 +2011,7 @@ static int lpuart_remove(struct platform
struct lpuart_port *sport = platform_get_drvdata(pdev);
uart_remove_one_port(&lpuart_reg, &sport->port);
+ clear_bit(sport->port.line, linemap);
clk_disable_unprepare(sport->clk);
@@ -2072,12 +2096,10 @@ static int lpuart_resume(struct device *
if (sport->lpuart_dma_rx_use) {
if (sport->port.irq_wake) {
- if (!lpuart_start_rx_dma(sport)) {
- sport->lpuart_dma_rx_use = true;
+ if (!lpuart_start_rx_dma(sport))
rx_dma_timer_init(sport);
- } else {
+ else
sport->lpuart_dma_rx_use = false;
- }
}
}

View File

@ -1,542 +0,0 @@
From 2887442bd13bc8be687afc7172cb01c2b7f0dd3b Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Thu, 5 Jul 2018 17:41:14 +0800
Subject: [PATCH 31/32] flexcan: support layerscape
This is an integrated patch for layerscape flexcan support.
Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/net/can/flexcan.c | 212 ++++++++++++++++++++++----------------
1 file changed, 123 insertions(+), 89 deletions(-)
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -184,6 +184,7 @@
* MX53 FlexCAN2 03.00.00.00 yes no no no
* MX6s FlexCAN3 10.00.12.00 yes yes no yes
* VF610 FlexCAN3 ? no yes yes yes?
+ * LS1021A FlexCAN2 03.00.04.00 no yes no yes
*
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
*/
@@ -260,6 +261,10 @@ struct flexcan_priv {
struct flexcan_platform_data *pdata;
const struct flexcan_devtype_data *devtype_data;
struct regulator *reg_xceiver;
+
+ /* Read and Write APIs */
+ u32 (*read)(void __iomem *addr);
+ void (*write)(u32 val, void __iomem *addr);
};
static struct flexcan_devtype_data fsl_p1010_devtype_data = {
@@ -276,6 +281,10 @@ static struct flexcan_devtype_data fsl_v
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
};
+static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
+};
+
static const struct can_bittiming_const flexcan_bittiming_const = {
.name = DRV_NAME,
.tseg1_min = 4,
@@ -288,32 +297,38 @@ static const struct can_bittiming_const
.brp_inc = 1,
};
-/* Abstract off the read/write for arm versus ppc. This
- * assumes that PPC uses big-endian registers and everything
- * else uses little-endian registers, independent of CPU
- * endianness.
+/* FlexCAN module is essentially modelled as a little-endian IP in most
+ * SoCs, i.e the registers as well as the message buffer areas are
+ * implemented in a little-endian fashion.
+ *
+ * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
+ * module in a big-endian fashion (i.e the registers as well as the
+ * message buffer areas are implemented in a big-endian way).
+ *
+ * In addition, the FlexCAN module can be found on SoCs having ARM or
+ * PPC cores. So, we need to abstract off the register read/write
+ * functions, ensuring that these cater to all the combinations of module
+ * endianness and underlying CPU endianness.
*/
-#if defined(CONFIG_PPC)
-static inline u32 flexcan_read(void __iomem *addr)
+static inline u32 flexcan_read_be(void __iomem *addr)
{
- return in_be32(addr);
+ return ioread32be(addr);
}
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_be(u32 val, void __iomem *addr)
{
- out_be32(addr, val);
+ iowrite32be(val, addr);
}
-#else
-static inline u32 flexcan_read(void __iomem *addr)
+
+static inline u32 flexcan_read_le(void __iomem *addr)
{
- return readl(addr);
+ return ioread32(addr);
}
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_le(u32 val, void __iomem *addr)
{
- writel(val, addr);
+ iowrite32(val, addr);
}
-#endif
static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
{
@@ -344,14 +359,14 @@ static int flexcan_chip_enable(struct fl
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
u32 reg;
- reg = flexcan_read(&regs->mcr);
+ reg = priv->read(&regs->mcr);
reg &= ~FLEXCAN_MCR_MDIS;
- flexcan_write(reg, &regs->mcr);
+ priv->write(reg, &regs->mcr);
- while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+ while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
udelay(10);
- if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
+ if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
return -ETIMEDOUT;
return 0;
@@ -363,14 +378,14 @@ static int flexcan_chip_disable(struct f
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
u32 reg;
- reg = flexcan_read(&regs->mcr);
+ reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_MDIS;
- flexcan_write(reg, &regs->mcr);
+ priv->write(reg, &regs->mcr);
- while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+ while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
udelay(10);
- if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+ if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
return -ETIMEDOUT;
return 0;
@@ -382,14 +397,14 @@ static int flexcan_chip_freeze(struct fl
unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
u32 reg;
- reg = flexcan_read(&regs->mcr);
+ reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_HALT;
- flexcan_write(reg, &regs->mcr);
+ priv->write(reg, &regs->mcr);
- while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
udelay(100);
- if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
return -ETIMEDOUT;
return 0;
@@ -401,14 +416,14 @@ static int flexcan_chip_unfreeze(struct
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
u32 reg;
- reg = flexcan_read(&regs->mcr);
+ reg = priv->read(&regs->mcr);
reg &= ~FLEXCAN_MCR_HALT;
- flexcan_write(reg, &regs->mcr);
+ priv->write(reg, &regs->mcr);
- while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
udelay(10);
- if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
+ if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
return -ETIMEDOUT;
return 0;
@@ -419,11 +434,11 @@ static int flexcan_chip_softreset(struct
struct flexcan_regs __iomem *regs = priv->regs;
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
- flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
- while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
+ priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
+ while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
udelay(10);
- if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
+ if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
return -ETIMEDOUT;
return 0;
@@ -434,7 +449,7 @@ static int __flexcan_get_berr_counter(co
{
const struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->regs;
- u32 reg = flexcan_read(&regs->ecr);
+ u32 reg = priv->read(&regs->ecr);
bec->txerr = (reg >> 0) & 0xff;
bec->rxerr = (reg >> 8) & 0xff;
@@ -491,24 +506,24 @@ static int flexcan_start_xmit(struct sk_
if (cf->can_dlc > 0) {
data = be32_to_cpup((__be32 *)&cf->data[0]);
- flexcan_write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[0]);
+ priv->write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[0]);
}
if (cf->can_dlc > 4) {
data = be32_to_cpup((__be32 *)&cf->data[4]);
- flexcan_write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[1]);
+ priv->write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[1]);
}
can_put_echo_skb(skb, dev, 0);
- flexcan_write(can_id, &regs->mb[FLEXCAN_TX_BUF_ID].can_id);
- flexcan_write(ctrl, &regs->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
+ priv->write(can_id, &regs->mb[FLEXCAN_TX_BUF_ID].can_id);
+ priv->write(ctrl, &regs->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
/* Errata ERR005829 step8:
* Write twice INACTIVE(0x8) code to first MB.
*/
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&regs->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&regs->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
return NETDEV_TX_OK;
@@ -632,8 +647,8 @@ static void flexcan_read_fifo(const stru
struct flexcan_mb __iomem *mb = &regs->mb[0];
u32 reg_ctrl, reg_id;
- reg_ctrl = flexcan_read(&mb->can_ctrl);
- reg_id = flexcan_read(&mb->can_id);
+ reg_ctrl = priv->read(&mb->can_ctrl);
+ reg_id = priv->read(&mb->can_id);
if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
else
@@ -643,12 +658,12 @@ static void flexcan_read_fifo(const stru
cf->can_id |= CAN_RTR_FLAG;
cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
- *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
- *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
+ *(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
+ *(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
/* mark as read */
- flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
- flexcan_read(&regs->timer);
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
+ priv->read(&regs->timer);
}
static int flexcan_read_frame(struct net_device *dev)
@@ -685,17 +700,17 @@ static int flexcan_poll(struct napi_stru
/* The error bits are cleared on read,
* use saved value from irq handler.
*/
- reg_esr = flexcan_read(&regs->esr) | priv->reg_esr;
+ reg_esr = priv->read(&regs->esr) | priv->reg_esr;
/* handle state changes */
work_done += flexcan_poll_state(dev, reg_esr);
/* handle RX-FIFO */
- reg_iflag1 = flexcan_read(&regs->iflag1);
+ reg_iflag1 = priv->read(&regs->iflag1);
while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
work_done < quota) {
work_done += flexcan_read_frame(dev);
- reg_iflag1 = flexcan_read(&regs->iflag1);
+ reg_iflag1 = priv->read(&regs->iflag1);
}
/* report bus errors */
@@ -705,8 +720,8 @@ static int flexcan_poll(struct napi_stru
if (work_done < quota) {
napi_complete_done(napi, work_done);
/* enable IRQs */
- flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
- flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
+ priv->write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
+ priv->write(priv->reg_ctrl_default, &regs->ctrl);
}
return work_done;
@@ -720,12 +735,12 @@ static irqreturn_t flexcan_irq(int irq,
struct flexcan_regs __iomem *regs = priv->regs;
u32 reg_iflag1, reg_esr;
- reg_iflag1 = flexcan_read(&regs->iflag1);
- reg_esr = flexcan_read(&regs->esr);
+ reg_iflag1 = priv->read(&regs->iflag1);
+ reg_esr = priv->read(&regs->esr);
/* ACK all bus error and state change IRQ sources */
if (reg_esr & FLEXCAN_ESR_ALL_INT)
- flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
+ priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
/* schedule NAPI in case of:
* - rx IRQ
@@ -739,16 +754,16 @@ static irqreturn_t flexcan_irq(int irq,
* save them for later use.
*/
priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
- flexcan_write(FLEXCAN_IFLAG_DEFAULT &
+ priv->write(FLEXCAN_IFLAG_DEFAULT &
~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->imask1);
- flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+ priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
&regs->ctrl);
napi_schedule(&priv->napi);
}
/* FIFO overflow */
if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
- flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
dev->stats.rx_over_errors++;
dev->stats.rx_errors++;
}
@@ -760,9 +775,9 @@ static irqreturn_t flexcan_irq(int irq,
can_led_event(dev, CAN_LED_EVENT_TX);
/* after sending a RTR frame MB is in RX mode */
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&regs->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
- flexcan_write((1 << FLEXCAN_TX_BUF_ID), &regs->iflag1);
+ priv->write((1 << FLEXCAN_TX_BUF_ID), &regs->iflag1);
netif_wake_queue(dev);
}
@@ -776,7 +791,7 @@ static void flexcan_set_bittiming(struct
struct flexcan_regs __iomem *regs = priv->regs;
u32 reg;
- reg = flexcan_read(&regs->ctrl);
+ reg = priv->read(&regs->ctrl);
reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
FLEXCAN_CTRL_RJW(0x3) |
FLEXCAN_CTRL_PSEG1(0x7) |
@@ -800,11 +815,11 @@ static void flexcan_set_bittiming(struct
reg |= FLEXCAN_CTRL_SMP;
netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
- flexcan_write(reg, &regs->ctrl);
+ priv->write(reg, &regs->ctrl);
/* print chip status */
netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
- flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+ priv->read(&regs->mcr), priv->read(&regs->ctrl));
}
/* flexcan_chip_start
@@ -842,13 +857,13 @@ static int flexcan_chip_start(struct net
* choose format C
* set max mailbox number
*/
- reg_mcr = flexcan_read(&regs->mcr);
+ reg_mcr = priv->read(&regs->mcr);
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS |
FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
- flexcan_write(reg_mcr, &regs->mcr);
+ priv->write(reg_mcr, &regs->mcr);
/* CTRL
*
@@ -861,7 +876,7 @@ static int flexcan_chip_start(struct net
* enable bus off interrupt
* (== FLEXCAN_CTRL_ERR_STATE)
*/
- reg_ctrl = flexcan_read(&regs->ctrl);
+ reg_ctrl = priv->read(&regs->ctrl);
reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
FLEXCAN_CTRL_ERR_STATE;
@@ -881,29 +896,29 @@ static int flexcan_chip_start(struct net
/* leave interrupts disabled for now */
reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
- flexcan_write(reg_ctrl, &regs->ctrl);
+ priv->write(reg_ctrl, &regs->ctrl);
/* clear and invalidate all mailboxes first */
for (i = FLEXCAN_TX_BUF_ID; i < ARRAY_SIZE(regs->mb); i++) {
- flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
+ priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
&regs->mb[i].can_ctrl);
}
/* Errata ERR005829: mark first TX mailbox as INACTIVE */
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&regs->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
/* mark TX mailbox as INACTIVE */
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&regs->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
/* acceptance mask/acceptance code (accept everything) */
- flexcan_write(0x0, &regs->rxgmask);
- flexcan_write(0x0, &regs->rx14mask);
- flexcan_write(0x0, &regs->rx15mask);
+ priv->write(0x0, &regs->rxgmask);
+ priv->write(0x0, &regs->rx14mask);
+ priv->write(0x0, &regs->rx15mask);
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
- flexcan_write(0x0, &regs->rxfgmask);
+ priv->write(0x0, &regs->rxfgmask);
/* On Vybrid, disable memory error detection interrupts
* and freeze mode.
@@ -916,16 +931,16 @@ static int flexcan_chip_start(struct net
* and Correction of Memory Errors" to write to
* MECR register
*/
- reg_ctrl2 = flexcan_read(&regs->ctrl2);
+ reg_ctrl2 = priv->read(&regs->ctrl2);
reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
- flexcan_write(reg_ctrl2, &regs->ctrl2);
+ priv->write(reg_ctrl2, &regs->ctrl2);
- reg_mecr = flexcan_read(&regs->mecr);
+ reg_mecr = priv->read(&regs->mecr);
reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
- flexcan_write(reg_mecr, &regs->mecr);
+ priv->write(reg_mecr, &regs->mecr);
reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
FLEXCAN_MECR_FANCEI_MSK);
- flexcan_write(reg_mecr, &regs->mecr);
+ priv->write(reg_mecr, &regs->mecr);
}
err = flexcan_transceiver_enable(priv);
@@ -941,13 +956,13 @@ static int flexcan_chip_start(struct net
/* enable interrupts atomically */
disable_irq(dev->irq);
- flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
- flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
+ priv->write(priv->reg_ctrl_default, &regs->ctrl);
+ priv->write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
enable_irq(dev->irq);
/* print chip status */
netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
- flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+ priv->read(&regs->mcr), priv->read(&regs->ctrl));
return 0;
@@ -972,8 +987,8 @@ static void flexcan_chip_stop(struct net
flexcan_chip_disable(priv);
/* Disable all interrupts */
- flexcan_write(0, &regs->imask1);
- flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+ priv->write(0, &regs->imask1);
+ priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
&regs->ctrl);
flexcan_transceiver_disable(priv);
@@ -1089,25 +1104,25 @@ static int register_flexcandev(struct ne
err = flexcan_chip_disable(priv);
if (err)
goto out_disable_per;
- reg = flexcan_read(&regs->ctrl);
+ reg = priv->read(&regs->ctrl);
reg |= FLEXCAN_CTRL_CLK_SRC;
- flexcan_write(reg, &regs->ctrl);
+ priv->write(reg, &regs->ctrl);
err = flexcan_chip_enable(priv);
if (err)
goto out_chip_disable;
/* set freeze, halt and activate FIFO, restrict register access */
- reg = flexcan_read(&regs->mcr);
+ reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
- flexcan_write(reg, &regs->mcr);
+ priv->write(reg, &regs->mcr);
/* Currently we only support newer versions of this core
* featuring a RX FIFO. Older cores found on some Coldfire
* derivates are not yet supported.
*/
- reg = flexcan_read(&regs->mcr);
+ reg = priv->read(&regs->mcr);
if (!(reg & FLEXCAN_MCR_FEN)) {
netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
err = -ENODEV;
@@ -1135,8 +1150,12 @@ static void unregister_flexcandev(struct
static const struct of_device_id flexcan_of_match[] = {
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
+ { .compatible = "fsl,imx53-flexcan", .data = &fsl_p1010_devtype_data, },
+ { .compatible = "fsl,imx35-flexcan", .data = &fsl_p1010_devtype_data, },
+ { .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, },
{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
+ { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, flexcan_of_match);
@@ -1213,6 +1232,21 @@ static int flexcan_probe(struct platform
dev->flags |= IFF_ECHO;
priv = netdev_priv(dev);
+
+ if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
+ priv->read = flexcan_read_be;
+ priv->write = flexcan_write_be;
+ } else {
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "fsl,p1010-flexcan")) {
+ priv->read = flexcan_read_be;
+ priv->write = flexcan_write_be;
+ } else {
+ priv->read = flexcan_read_le;
+ priv->write = flexcan_write_le;
+ }
+ }
+
priv->can.clock.freq = clock_freq;
priv->can.bittiming_const = &flexcan_bittiming_const;
priv->can.do_set_mode = flexcan_set_mode;

View File

@ -1,239 +0,0 @@
From fe22151c95c02c6bb145ea6c3685941e8fb09d60 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Thu, 5 Jul 2018 17:43:16 +0800
Subject: [PATCH 32/32] kvm: support layerscape
This is an integrated patch for layerscape kvm support.
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
arch/arm/include/asm/kvm_mmu.h | 3 +-
arch/arm/kvm/mmu.c | 56 ++++++++++++++++++++++++++++++--
arch/arm64/include/asm/kvm_mmu.h | 14 ++++++--
virt/kvm/arm/vgic/vgic-its.c | 24 +++++++++++---
virt/kvm/arm/vgic/vgic-v2.c | 3 +-
5 files changed, 88 insertions(+), 12 deletions(-)
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -55,7 +55,8 @@ void stage2_unmap_vm(struct kvm *kvm);
int kvm_alloc_stage2_pgd(struct kvm *kvm);
void kvm_free_stage2_pgd(struct kvm *kvm);
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
- phys_addr_t pa, unsigned long size, bool writable);
+ phys_addr_t pa, unsigned long size, bool writable,
+ pgprot_t prot);
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1020,9 +1020,11 @@ static int stage2_pmdp_test_and_clear_yo
* @guest_ipa: The IPA at which to insert the mapping
* @pa: The physical address of the device
* @size: The size of the mapping
+ * @prot: S2 page translation bits
*/
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
- phys_addr_t pa, unsigned long size, bool writable)
+ phys_addr_t pa, unsigned long size, bool writable,
+ pgprot_t prot)
{
phys_addr_t addr, end;
int ret = 0;
@@ -1033,7 +1035,7 @@ int kvm_phys_addr_ioremap(struct kvm *kv
pfn = __phys_to_pfn(pa);
for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) {
- pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE);
+ pte_t pte = pfn_pte(pfn, prot);
if (writable)
pte = kvm_s2pte_mkwrite(pte);
@@ -1057,6 +1059,30 @@ out:
return ret;
}
+#ifdef CONFIG_ARM64
+static pgprot_t stage1_to_stage2_pgprot(pgprot_t prot)
+{
+ switch (pgprot_val(prot) & PTE_ATTRINDX_MASK) {
+ case PTE_ATTRINDX(MT_DEVICE_nGnRE):
+ case PTE_ATTRINDX(MT_DEVICE_nGnRnE):
+ case PTE_ATTRINDX(MT_DEVICE_GRE):
+ return PAGE_S2_DEVICE;
+ case PTE_ATTRINDX(MT_NORMAL_NC):
+ case PTE_ATTRINDX(MT_NORMAL):
+ return (pgprot_val(prot) & PTE_SHARED)
+ ? PAGE_S2
+ : PAGE_S2_NS;
+ }
+
+ return PAGE_S2_DEVICE;
+}
+#else
+static pgprot_t stage1_to_stage2_pgprot(pgprot_t prot)
+{
+ return PAGE_S2_DEVICE;
+}
+#endif
+
static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
{
kvm_pfn_t pfn = *pfnp;
@@ -1308,6 +1334,19 @@ static int user_mem_abort(struct kvm_vcp
hugetlb = true;
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
} else {
+ if (!is_vm_hugetlb_page(vma)) {
+ pte_t *pte;
+ spinlock_t *ptl;
+ pgprot_t prot;
+
+ pte = get_locked_pte(current->mm, memslot->userspace_addr, &ptl);
+ prot = stage1_to_stage2_pgprot(__pgprot(pte_val(*pte)));
+ pte_unmap_unlock(pte, ptl);
+#ifdef CONFIG_ARM64
+ if (pgprot_val(prot) == pgprot_val(PAGE_S2_NS))
+ mem_type = PAGE_S2_NS;
+#endif
+ }
/*
* Pages belonging to memslots that don't have the same
* alignment for userspace and IPA cannot be mapped using
@@ -1345,6 +1384,11 @@ static int user_mem_abort(struct kvm_vcp
if (is_error_noslot_pfn(pfn))
return -EFAULT;
+#ifdef CONFIG_ARM64
+ if (pgprot_val(mem_type) == pgprot_val(PAGE_S2_NS)) {
+ flags |= KVM_S2PTE_FLAG_IS_IOMAP;
+ } else
+#endif
if (kvm_is_device_pfn(pfn)) {
mem_type = PAGE_S2_DEVICE;
flags |= KVM_S2PTE_FLAG_IS_IOMAP;
@@ -1882,6 +1926,9 @@ int kvm_arch_prepare_memory_region(struc
gpa_t gpa = mem->guest_phys_addr +
(vm_start - mem->userspace_addr);
phys_addr_t pa;
+ pgprot_t prot;
+ pte_t *pte;
+ spinlock_t *ptl;
pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
pa += vm_start - vma->vm_start;
@@ -1891,10 +1938,13 @@ int kvm_arch_prepare_memory_region(struc
ret = -EINVAL;
goto out;
}
+ pte = get_locked_pte(current->mm, mem->userspace_addr, &ptl);
+ prot = stage1_to_stage2_pgprot(__pgprot(pte_val(*pte)));
+ pte_unmap_unlock(pte, ptl);
ret = kvm_phys_addr_ioremap(kvm, gpa, pa,
vm_end - vm_start,
- writable);
+ writable, prot);
if (ret)
break;
}
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -167,7 +167,8 @@ void stage2_unmap_vm(struct kvm *kvm);
int kvm_alloc_stage2_pgd(struct kvm *kvm);
void kvm_free_stage2_pgd(struct kvm *kvm);
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
- phys_addr_t pa, unsigned long size, bool writable);
+ phys_addr_t pa, unsigned long size, bool writable,
+ pgprot_t prot);
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
@@ -274,8 +275,15 @@ static inline void __coherent_cache_gues
static inline void __kvm_flush_dcache_pte(pte_t pte)
{
- struct page *page = pte_page(pte);
- kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
+ if (pfn_valid(pte_pfn(pte))) {
+ struct page *page = pte_page(pte);
+ kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
+ } else {
+ void __iomem *va = ioremap_cache_ns(pte_pfn(pte) << PAGE_SHIFT, PAGE_SIZE);
+
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+ iounmap(va);
+ }
}
static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -176,6 +176,8 @@ static struct its_itte *find_itte(struct
#define GIC_LPI_OFFSET 8192
+#define VITS_TYPER_DEVBITS 17
+
/*
* Finds and returns a collection in the ITS collection table.
* Must be called with the its_lock mutex held.
@@ -375,7 +377,7 @@ static unsigned long vgic_mmio_read_its_
* To avoid memory waste in the guest, we keep the number of IDBits and
* DevBits low - as least for the time being.
*/
- reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT;
+ reg |= GIC_ENCODE_SZ(VITS_TYPER_DEVBITS, 5) << GITS_TYPER_DEVBITS_SHIFT;
reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT;
return extract_bytes(reg, addr & 7, len);
@@ -601,16 +603,30 @@ static int vgic_its_cmd_handle_movi(stru
* Check whether an ID can be stored into the corresponding guest table.
* For a direct table this is pretty easy, but gets a bit nasty for
* indirect tables. We check whether the resulting guest physical address
- * is actually valid (covered by a memslot and guest accessbible).
+ * is actually valid (covered by a memslot and guest accessible).
* For this we have to read the respective first level entry.
*/
-static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
+static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id)
{
int l1_tbl_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
+ u64 indirect_ptr, type = GITS_BASER_TYPE(baser);
int index;
- u64 indirect_ptr;
gfn_t gfn;
+ switch (type) {
+ case GITS_BASER_TYPE_DEVICE:
+ if (id >= BIT_ULL(VITS_TYPER_DEVBITS))
+ return false;
+ break;
+ case GITS_BASER_TYPE_COLLECTION:
+ /* as GITS_TYPER.CIL == 0, ITS supports 16-bit collection ID */
+ if (id >= BIT_ULL(16))
+ return false;
+ break;
+ default:
+ return false;
+ }
+
if (!(baser & GITS_BASER_INDIRECT)) {
phys_addr_t addr;
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -290,7 +290,8 @@ int vgic_v2_map_resources(struct kvm *kv
if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) {
ret = kvm_phys_addr_ioremap(kvm, dist->vgic_cpu_base,
kvm_vgic_global_state.vcpu_base,
- KVM_VGIC_V2_CPU_SIZE, true);
+ KVM_VGIC_V2_CPU_SIZE, true,
+ PAGE_S2_DEVICE);
if (ret) {
kvm_err("Unable to remap VGIC CPU to VCPU\n");
goto out;

View File

@ -1,10 +0,0 @@
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -619,6 +619,7 @@ static void esdhc_reset(struct sdhci_hos
static const struct of_device_id scfg_device_ids[] = {
{ .compatible = "fsl,t1040-scfg", },
{ .compatible = "fsl,ls1012a-scfg", },
+ { .compatible = "fsl,ls1043a-scfg", },
{ .compatible = "fsl,ls1046a-scfg", },
{}
};

View File

@ -1,62 +0,0 @@
From f27ef8941ca29b2d10428754be51e8ee06bb1263 Mon Sep 17 00:00:00 2001
From: Mathew McBride <matt@traverse.com.au>
Date: Mon, 7 Aug 2017 10:19:48 +1000
Subject: [PATCH] Recognize when an RGMII Link is set as fixed (in the device
tree) and set up the MAC accordingly
---
drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 1
drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 13 ++++++++++
2 files changed, 14 insertions(+)
--- a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
@@ -386,6 +386,7 @@ static int __cold mac_probe(struct platf
mac_dev->fixed_link->duplex = phy->duplex;
mac_dev->fixed_link->pause = phy->pause;
mac_dev->fixed_link->asym_pause = phy->asym_pause;
+ printk(KERN_INFO "Setting up fixed link, speed %d duplex %d\n", mac_dev->fixed_link->speed, mac_dev->fixed_link->duplex);
}
_errno = mac_dev->init(mac_dev);
--- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
@@ -36,6 +36,8 @@
@Description FM mEMAC driver
*//***************************************************************************/
+#include <../../../../sdk_dpaa/mac.h>
+#include <linux/phy_fixed.h>
#include "std_ext.h"
#include "string_ext.h"
@@ -48,6 +50,8 @@
#include "memac.h"
+static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex);
+
/*****************************************************************************/
/* Internal routines */
/*****************************************************************************/
@@ -276,11 +280,20 @@ static t_Error MemacEnable(t_Handle h_Me
{
t_Memac *p_Memac = (t_Memac *)h_Memac;
+ struct mac_device *mac_dev = (struct mac_device *)p_Memac->h_App;
+
SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
+ if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_RGMII) {
+ if (mac_dev->fixed_link) {
+ printk(KERN_INFO "This is a fixed-link, forcing speed %d duplex %d\n",mac_dev->fixed_link->speed,mac_dev->fixed_link->duplex);
+ MemacAdjustLink(h_Memac,mac_dev->fixed_link->speed,mac_dev->fixed_link->duplex);
+ }
+ }
+
return E_OK;
}